Merge branch 'master' into refactor-mesh-selection-generic
This commit is contained in:
commit
b1fd951c59
|
@ -273,5 +273,5 @@ StatementMacros:
|
|||
- PyObject_VAR_HEAD
|
||||
- ccl_gpu_kernel_postfix
|
||||
|
||||
MacroBlockBegin: "^BSDF_CLOSURE_CLASS_BEGIN$"
|
||||
MacroBlockEnd: "^BSDF_CLOSURE_CLASS_END$"
|
||||
MacroBlockBegin: "^OSL_CLOSURE_STRUCT_BEGIN$"
|
||||
MacroBlockEnd: "^OSL_CLOSURE_STRUCT_END$"
|
||||
|
|
|
@ -888,7 +888,11 @@ endif()
|
|||
if(WITH_CYCLES AND WITH_CYCLES_DEVICE_CUDA AND NOT WITH_CUDA_DYNLOAD)
|
||||
find_package(CUDA)
|
||||
if(NOT CUDA_FOUND)
|
||||
message(STATUS "CUDA toolkit not found, using dynamic runtime loading of libraries (WITH_CUDA_DYNLOAD) instead")
|
||||
message(
|
||||
STATUS
|
||||
"CUDA toolkit not found, "
|
||||
"using dynamic runtime loading of libraries (WITH_CUDA_DYNLOAD) instead"
|
||||
)
|
||||
set(WITH_CUDA_DYNLOAD ON)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -905,7 +909,8 @@ if(WITH_INTERNATIONAL)
|
|||
file(GLOB RESULT "${CMAKE_SOURCE_DIR}/release/datafiles/locale")
|
||||
list(LENGTH RESULT DIR_LEN)
|
||||
if(DIR_LEN EQUAL 0)
|
||||
message(WARNING
|
||||
message(
|
||||
WARNING
|
||||
"Translation path '${CMAKE_SOURCE_DIR}/release/datafiles/locale' is missing, "
|
||||
"This is a 'git submodule', which are known not to work with bridges to other version "
|
||||
"control systems, disabling 'WITH_INTERNATIONAL'."
|
||||
|
@ -923,13 +928,17 @@ if(WITH_PYTHON)
|
|||
# because UNIX will search for the old Python paths which may not exist.
|
||||
# giving errors about missing paths before this case is met.
|
||||
if(DEFINED PYTHON_VERSION AND "${PYTHON_VERSION}" VERSION_LESS "3.10")
|
||||
message(FATAL_ERROR "At least Python 3.10 is required to build, but found Python ${PYTHON_VERSION}")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"At least Python 3.10 is required to build, but found Python ${PYTHON_VERSION}"
|
||||
)
|
||||
endif()
|
||||
|
||||
file(GLOB RESULT "${CMAKE_SOURCE_DIR}/release/scripts/addons")
|
||||
list(LENGTH RESULT DIR_LEN)
|
||||
if(DIR_LEN EQUAL 0)
|
||||
message(WARNING
|
||||
message(
|
||||
WARNING
|
||||
"Addons path '${CMAKE_SOURCE_DIR}/release/scripts/addons' is missing, "
|
||||
"This is a 'git submodule', which are known not to work with bridges to other version "
|
||||
"control systems: * CONTINUING WITHOUT ADDONS *"
|
||||
|
@ -1037,13 +1046,15 @@ endif()
|
|||
|
||||
if(WITH_CYCLES)
|
||||
if(NOT WITH_OPENIMAGEIO)
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Cycles requires WITH_OPENIMAGEIO, the library may not have been found. "
|
||||
"Configure OIIO or disable WITH_CYCLES"
|
||||
)
|
||||
endif()
|
||||
if(NOT WITH_BOOST)
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Cycles requires WITH_BOOST, the library may not have been found. "
|
||||
"Configure BOOST or disable WITH_CYCLES"
|
||||
)
|
||||
|
@ -1051,7 +1062,8 @@ if(WITH_CYCLES)
|
|||
|
||||
if(WITH_CYCLES_OSL)
|
||||
if(NOT WITH_LLVM)
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Cycles OSL requires WITH_LLVM, the library may not have been found. "
|
||||
"Configure LLVM or disable WITH_CYCLES_OSL"
|
||||
)
|
||||
|
@ -1061,7 +1073,8 @@ endif()
|
|||
|
||||
if(WITH_INTERNATIONAL)
|
||||
if(NOT WITH_BOOST)
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Internationalization requires WITH_BOOST, the library may not have been found. "
|
||||
"Configure BOOST or disable WITH_INTERNATIONAL"
|
||||
)
|
||||
|
@ -1606,7 +1619,8 @@ endif()
|
|||
# be most problematic.
|
||||
if(WITH_PYTHON)
|
||||
if(NOT EXISTS "${PYTHON_INCLUDE_DIR}/Python.h")
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Missing: \"${PYTHON_INCLUDE_DIR}/Python.h\",\n"
|
||||
"Set the cache entry 'PYTHON_INCLUDE_DIR' to point "
|
||||
"to a valid python include path. Containing "
|
||||
|
@ -1675,9 +1689,11 @@ if(WITH_COMPILER_SHORT_FILE_MACRO)
|
|||
if(XCODE AND ${XCODE_VERSION} VERSION_LESS 12.0)
|
||||
# Developers may have say LLVM Clang-10.0.1 toolchain (which supports the flag)
|
||||
# with Xcode-11 (the Clang of which doesn't support the flag).
|
||||
message(WARNING
|
||||
message(
|
||||
WARNING
|
||||
"-fmacro-prefix-map flag is NOT supported by Clang shipped with Xcode-${XCODE_VERSION}."
|
||||
" Some Xcode functionality in Product menu may not work. Disabling WITH_COMPILER_SHORT_FILE_MACRO."
|
||||
" Some Xcode functionality in Product menu may not work. "
|
||||
"Disabling WITH_COMPILER_SHORT_FILE_MACRO."
|
||||
)
|
||||
set(WITH_COMPILER_SHORT_FILE_MACRO OFF)
|
||||
endif()
|
||||
|
@ -1693,7 +1709,8 @@ if(WITH_COMPILER_SHORT_FILE_MACRO)
|
|||
unset(_bin_dir)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING
|
||||
message(
|
||||
WARNING
|
||||
"-fmacro-prefix-map flag is NOT supported by C/C++ compiler."
|
||||
" Disabling WITH_COMPILER_SHORT_FILE_MACRO."
|
||||
)
|
||||
|
|
12
GNUmakefile
12
GNUmakefile
|
@ -162,6 +162,7 @@ CPU:=$(shell uname -m)
|
|||
# Source and Build DIR's
|
||||
BLENDER_DIR:=$(shell pwd -P)
|
||||
BUILD_TYPE:=Release
|
||||
BLENDER_IS_PYTHON_MODULE:=
|
||||
|
||||
# CMake arguments, assigned to local variable to make it mutable.
|
||||
CMAKE_CONFIG_ARGS := $(BUILD_CMAKE_ARGS)
|
||||
|
@ -259,6 +260,7 @@ endif
|
|||
ifneq "$(findstring bpy, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_bpy
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/bpy_module.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
BLENDER_IS_PYTHON_MODULE:=1
|
||||
endif
|
||||
|
||||
ifneq "$(findstring developer, $(MAKECMDGOALS))" ""
|
||||
|
@ -297,8 +299,10 @@ endif
|
|||
# use the default build path can still use utility helpers.
|
||||
ifeq ($(OS), Darwin)
|
||||
BLENDER_BIN?="$(BUILD_DIR)/bin/Blender.app/Contents/MacOS/Blender"
|
||||
BLENDER_BIN_DIR?="$(BUILD_DIR)/bin/Blender.app/Contents/MacOS/Blender"
|
||||
else
|
||||
BLENDER_BIN?="$(BUILD_DIR)/bin/blender"
|
||||
BLENDER_BIN_DIR?="$(BUILD_DIR)/bin"
|
||||
endif
|
||||
|
||||
|
||||
|
@ -355,8 +359,12 @@ all: .FORCE
|
|||
@echo Building Blender ...
|
||||
$(BUILD_COMMAND) -C "$(BUILD_DIR)" -j $(NPROCS) install
|
||||
@echo
|
||||
@echo edit build configuration with: "$(BUILD_DIR)/CMakeCache.txt" run make again to rebuild.
|
||||
@echo Blender successfully built, run from: $(BLENDER_BIN)
|
||||
@echo Edit build configuration with: \"$(BUILD_DIR)/CMakeCache.txt\" run make again to rebuild.
|
||||
@if test "$(BLENDER_IS_PYTHON_MODULE)" == ""; then \
|
||||
echo Blender successfully built, run from: $(BLENDER_BIN); \
|
||||
else \
|
||||
echo Blender successfully built as a Python module, \"bpy\" can be imported from: $(BLENDER_BIN_DIR); \
|
||||
fi
|
||||
@echo
|
||||
|
||||
debug: all
|
||||
|
|
|
@ -136,7 +136,7 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
|
|||
Build and install the OpenImageDenoise libraries.
|
||||
|
||||
--with-nanovdb
|
||||
Build and install the NanoVDB branch of OpenVDB (instead of official release of OpenVDB).
|
||||
Build and install NanoVDB together with OpenVDB.
|
||||
|
||||
--with-jack
|
||||
Install the jack libraries.
|
||||
|
@ -385,7 +385,7 @@ CLANG_FORMAT_VERSION="10.0"
|
|||
CLANG_FORMAT_VERSION_MIN="6.0"
|
||||
CLANG_FORMAT_VERSION_MEX="14.0"
|
||||
|
||||
PYTHON_VERSION="3.10.2"
|
||||
PYTHON_VERSION="3.10.6"
|
||||
PYTHON_VERSION_SHORT="3.10"
|
||||
PYTHON_VERSION_MIN="3.10"
|
||||
PYTHON_VERSION_MEX="3.12"
|
||||
|
@ -425,7 +425,7 @@ PYTHON_ZSTANDARD_VERSION_MIN="0.15.2"
|
|||
PYTHON_ZSTANDARD_VERSION_MEX="0.20.0"
|
||||
PYTHON_ZSTANDARD_NAME="zstandard"
|
||||
|
||||
PYTHON_NUMPY_VERSION="1.22.0"
|
||||
PYTHON_NUMPY_VERSION="1.23.2"
|
||||
PYTHON_NUMPY_VERSION_MIN="1.14"
|
||||
PYTHON_NUMPY_VERSION_MEX="2.0"
|
||||
PYTHON_NUMPY_NAME="numpy"
|
||||
|
@ -453,8 +453,8 @@ PYTHON_MODULES_PIP=(
|
|||
)
|
||||
|
||||
|
||||
BOOST_VERSION="1.78.0"
|
||||
BOOST_VERSION_SHORT="1.78"
|
||||
BOOST_VERSION="1.80.0"
|
||||
BOOST_VERSION_SHORT="1.80"
|
||||
BOOST_VERSION_MIN="1.49"
|
||||
BOOST_VERSION_MEX="2.0"
|
||||
BOOST_FORCE_BUILD=false
|
||||
|
@ -496,7 +496,7 @@ OPENEXR_FORCE_REBUILD=false
|
|||
OPENEXR_SKIP=false
|
||||
_with_built_openexr=false
|
||||
|
||||
OIIO_VERSION="2.3.13.0"
|
||||
OIIO_VERSION="2.3.18.0"
|
||||
OIIO_VERSION_SHORT="2.3"
|
||||
OIIO_VERSION_MIN="2.1.12"
|
||||
OIIO_VERSION_MEX="2.4.0"
|
||||
|
@ -534,10 +534,10 @@ OSD_SKIP=false
|
|||
# OpenVDB needs to be compiled for now
|
||||
OPENVDB_BLOSC_VERSION="1.21.1"
|
||||
|
||||
OPENVDB_VERSION="9.0.0"
|
||||
OPENVDB_VERSION_SHORT="9.0"
|
||||
OPENVDB_VERSION="9.1.0"
|
||||
OPENVDB_VERSION_SHORT="9.1"
|
||||
OPENVDB_VERSION_MIN="9.0"
|
||||
OPENVDB_VERSION_MEX="9.1"
|
||||
OPENVDB_VERSION_MEX="9.2"
|
||||
OPENVDB_FORCE_BUILD=false
|
||||
OPENVDB_FORCE_REBUILD=false
|
||||
OPENVDB_SKIP=false
|
||||
|
@ -2919,6 +2919,10 @@ compile_OPENVDB() {
|
|||
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
|
||||
cmake_d="$cmake_d -D USE_STATIC_DEPENDENCIES=OFF"
|
||||
cmake_d="$cmake_d -D OPENVDB_BUILD_BINARIES=OFF"
|
||||
# Unfortunately OpenVDB currently forces using recent oneTBB over older versions when it finds it,
|
||||
# even when TBB_ROOT is specified. So have to prevent any check for system library -
|
||||
# in the hope it will not break in some other cases.
|
||||
cmake_d="$cmake_d -D DISABLE_CMAKE_SEARCH_PATHS=ON"
|
||||
|
||||
if [ "$WITH_NANOVDB" = true ]; then
|
||||
cmake_d="$cmake_d -D USE_NANOVDB=ON"
|
||||
|
@ -2931,7 +2935,6 @@ compile_OPENVDB() {
|
|||
cmake_d="$cmake_d -D Boost_USE_MULTITHREADED=ON"
|
||||
cmake_d="$cmake_d -D Boost_NO_SYSTEM_PATHS=ON"
|
||||
cmake_d="$cmake_d -D Boost_NO_BOOST_CMAKE=ON"
|
||||
cmake_d="$cmake_d -D Boost_NO_BOOST_CMAKE=ON"
|
||||
fi
|
||||
if [ -d $INST/tbb ]; then
|
||||
cmake_d="$cmake_d -D TBB_ROOT=$INST/tbb"
|
||||
|
@ -3195,7 +3198,7 @@ _init_opencollada() {
|
|||
_inst_shortcut=$INST/opencollada
|
||||
}
|
||||
|
||||
_update_deps_collada() {
|
||||
_update_deps_opencollada() {
|
||||
:
|
||||
}
|
||||
|
||||
|
@ -6215,7 +6218,7 @@ print_info() {
|
|||
fi
|
||||
if [ -d $INST/nanovdb ]; then
|
||||
_1="-D WITH_NANOVDB=ON"
|
||||
_2="-D NANOVDB_ROOT_DIR=$INST/nanovdb"
|
||||
_2="-D NANOVDB_ROOT_DIR=$INST/openvdb"
|
||||
PRINT " $_1"
|
||||
PRINT " $_2"
|
||||
_buildargs="$_buildargs $_1 $_2"
|
||||
|
|
|
@ -30,6 +30,8 @@ from typing import (
|
|||
cast,
|
||||
)
|
||||
|
||||
import shlex
|
||||
|
||||
|
||||
SOURCE_DIR = join(dirname(__file__), "..", "..")
|
||||
SOURCE_DIR = normpath(SOURCE_DIR)
|
||||
|
@ -160,7 +162,7 @@ def build_info(
|
|||
|
||||
for c in compilers:
|
||||
args = args.replace(c, fake_compiler)
|
||||
args = args.split()
|
||||
args = shlex.split(args)
|
||||
# end
|
||||
|
||||
# remove compiler
|
||||
|
|
|
@ -704,7 +704,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
|
|||
buffer_params.window_width = bake_width;
|
||||
buffer_params.window_height = bake_height;
|
||||
/* Unique layer name for multi-image baking. */
|
||||
buffer_params.layer = string_printf("bake_%d\n", (int)full_buffer_files_.size());
|
||||
buffer_params.layer = string_printf("bake_%d\n", bake_id++);
|
||||
|
||||
/* Update session. */
|
||||
session->reset(session_params, buffer_params);
|
||||
|
|
|
@ -146,6 +146,8 @@ class BlenderSession {
|
|||
BlenderDisplayDriver *display_driver_ = nullptr;
|
||||
|
||||
vector<string> full_buffer_files_;
|
||||
|
||||
int bake_id = 0;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -59,39 +59,10 @@ ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *
|
|||
* we will not allocate new closure. */
|
||||
if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
|
||||
ccl_private ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
|
||||
if (sc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sc->sample_weight = sample_weight;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef __OSL__
|
||||
ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
|
||||
int size,
|
||||
Spectrum weight,
|
||||
void *data)
|
||||
{
|
||||
kernel_assert(isfinite_safe(weight));
|
||||
|
||||
const float sample_weight = fabsf(average(weight));
|
||||
|
||||
/* Use comparison this way to help dealing with non-finite weight: if the average is not finite
|
||||
* we will not allocate new closure. */
|
||||
if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
|
||||
ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
|
||||
if (!sc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy((void *)sc, data, size);
|
||||
|
||||
sc->weight = weight;
|
||||
sc->sample_weight = sample_weight;
|
||||
|
||||
return sc;
|
||||
|
@ -99,6 +70,5 @@ ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -16,14 +16,14 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
/* Patch index for triangle, -1 if not subdivision triangle */
|
||||
|
||||
ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||
ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, int prim)
|
||||
{
|
||||
return (sd->prim != PRIM_NONE) ? kernel_data_fetch(tri_patch, sd->prim) : ~0;
|
||||
return (prim != PRIM_NONE) ? kernel_data_fetch(tri_patch, prim) : ~0;
|
||||
}
|
||||
|
||||
ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||
ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, int prim, int type)
|
||||
{
|
||||
if ((sd->type & PRIMITIVE_TRIANGLE) && subd_triangle_patch(kg, sd) != ~0) {
|
||||
if ((type & PRIMITIVE_TRIANGLE) && subd_triangle_patch(kg, prim) != ~0) {
|
||||
return ATTR_PRIM_SUBD;
|
||||
}
|
||||
else {
|
||||
|
@ -45,17 +45,16 @@ ccl_device_inline uint object_attribute_map_offset(KernelGlobals kg, int object)
|
|||
return kernel_data_fetch(objects, object).attribute_map_offset;
|
||||
}
|
||||
|
||||
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
uint id)
|
||||
ccl_device_inline AttributeDescriptor
|
||||
find_attribute(KernelGlobals kg, int object, int prim, int type, uint64_t id)
|
||||
{
|
||||
if (sd->object == OBJECT_NONE) {
|
||||
if (object == OBJECT_NONE) {
|
||||
return attribute_not_found();
|
||||
}
|
||||
|
||||
/* for SVM, find attribute by unique id */
|
||||
uint attr_offset = object_attribute_map_offset(kg, sd->object);
|
||||
attr_offset += attribute_primitive_type(kg, sd);
|
||||
uint attr_offset = object_attribute_map_offset(kg, object);
|
||||
attr_offset += attribute_primitive_type(kg, prim, type);
|
||||
AttributeMap attr_map = kernel_data_fetch(attributes_map, attr_offset);
|
||||
|
||||
while (attr_map.id != id) {
|
||||
|
@ -77,7 +76,7 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
|
|||
AttributeDescriptor desc;
|
||||
desc.element = (AttributeElement)attr_map.element;
|
||||
|
||||
if (sd->prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
|
||||
if (prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
|
||||
desc.element != ATTR_ELEMENT_VOXEL && desc.element != ATTR_ELEMENT_OBJECT) {
|
||||
return attribute_not_found();
|
||||
}
|
||||
|
@ -91,11 +90,16 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
|
|||
return desc;
|
||||
}
|
||||
|
||||
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
uint64_t id)
|
||||
{
|
||||
return find_attribute(kg, sd->object, sd->prim, sd->type, id);
|
||||
}
|
||||
|
||||
/* Transform matrix attribute on meshes */
|
||||
|
||||
ccl_device Transform primitive_attribute_matrix(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
const AttributeDescriptor desc)
|
||||
ccl_device Transform primitive_attribute_matrix(KernelGlobals kg, const AttributeDescriptor desc)
|
||||
{
|
||||
Transform tfm;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg,
|
|||
ccl_private float *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0)
|
||||
return triangle_attribute_float(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
|
||||
|
@ -56,7 +56,7 @@ ccl_device_forceinline float2 primitive_surface_attribute_float2(KernelGlobals k
|
|||
ccl_private float2 *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0)
|
||||
return triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
|
@ -87,7 +87,7 @@ ccl_device_forceinline float3 primitive_surface_attribute_float3(KernelGlobals k
|
|||
ccl_private float3 *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0)
|
||||
return triangle_attribute_float3(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
|
||||
|
@ -118,7 +118,7 @@ ccl_device_forceinline float4 primitive_surface_attribute_float4(KernelGlobals k
|
|||
ccl_private float4 *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0)
|
||||
return triangle_attribute_float4(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float4(kg, sd, desc, dx, dy);
|
||||
|
@ -320,7 +320,7 @@ ccl_device_forceinline float4 primitive_motion_vector(KernelGlobals kg,
|
|||
#endif
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
/* Triangle */
|
||||
if (subd_triangle_patch(kg, sd) == ~0) {
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0) {
|
||||
motion_pre = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
desc.offset += numverts;
|
||||
motion_post = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
|
|
|
@ -87,7 +87,7 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
|
|||
ccl_private float *dx,
|
||||
ccl_private float *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if (desc.flags & ATTR_SUBDIVIDED) {
|
||||
|
@ -226,7 +226,7 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
|
|||
ccl_private float2 *dx,
|
||||
ccl_private float2 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if (desc.flags & ATTR_SUBDIVIDED) {
|
||||
|
@ -368,7 +368,7 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
|||
ccl_private float3 *dx,
|
||||
ccl_private float3 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if (desc.flags & ATTR_SUBDIVIDED) {
|
||||
|
@ -509,7 +509,7 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
|||
ccl_private float4 *dx,
|
||||
ccl_private float4 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if (desc.flags & ATTR_SUBDIVIDED) {
|
||||
|
|
|
@ -29,7 +29,7 @@ ccl_device_inline float3 volume_normalized_position(KernelGlobals kg,
|
|||
object_inverse_position_transform(kg, sd, &P);
|
||||
|
||||
if (desc.offset != ATTR_STD_NOT_FOUND) {
|
||||
Transform tfm = primitive_attribute_matrix(kg, sd, desc);
|
||||
Transform tfm = primitive_attribute_matrix(kg, desc);
|
||||
P = transform_point(&tfm, P);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,8 +62,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
|
|||
/* multiple importance sampling, get regular light pdf,
|
||||
* and compute weight with respect to BSDF pdf */
|
||||
const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
|
||||
const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
|
||||
light_eval *= mis_weight;
|
||||
mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
|
||||
}
|
||||
|
||||
/* Write to render buffer. */
|
||||
|
|
|
@ -10,18 +10,14 @@ set(INC_SYS
|
|||
)
|
||||
|
||||
set(SRC
|
||||
background.cpp
|
||||
bsdf_diffuse_ramp.cpp
|
||||
bsdf_phong_ramp.cpp
|
||||
emissive.cpp
|
||||
bssrdf.cpp
|
||||
closures.cpp
|
||||
services.cpp
|
||||
shader.cpp
|
||||
)
|
||||
|
||||
set(HEADER_SRC
|
||||
closures.h
|
||||
closures_setup.h
|
||||
closures_template.h
|
||||
globals.h
|
||||
services.h
|
||||
shader.h
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/emissive.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
/// Generic background closure
|
||||
///
|
||||
/// We only have a background closure for the shaders
|
||||
/// to return a color in background shaders. No methods,
|
||||
/// only the weight is taking into account
|
||||
///
|
||||
class GenericBackgroundClosure : public CClosurePrimitive {
|
||||
public:
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
background_setup(sd, rgb_to_spectrum(weight));
|
||||
}
|
||||
};
|
||||
|
||||
/// Holdout closure
|
||||
///
|
||||
/// This will be used by the shader to mark the
|
||||
/// amount of holdout for the current shading
|
||||
/// point. No parameters, only the weight will be
|
||||
/// used
|
||||
///
|
||||
class HoldoutClosure : CClosurePrimitive {
|
||||
public:
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, rgb_to_spectrum(weight));
|
||||
sd->flag |= SD_HOLDOUT;
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_background_params()
|
||||
{
|
||||
static ClosureParam params[] = {
|
||||
CLOSURE_STRING_KEYPARAM(GenericBackgroundClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(GenericBackgroundClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_background_prepare, GenericBackgroundClosure)
|
||||
|
||||
ClosureParam *closure_holdout_params()
|
||||
{
|
||||
static ClosureParam params[] = {CLOSURE_FINISH_PARAM(HoldoutClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -1,68 +0,0 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/bsdf_diffuse_ramp.h"
|
||||
#include "kernel/closure/bsdf_util.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
class DiffuseRampClosure : public CBSDFClosure {
|
||||
public:
|
||||
DiffuseRampBsdf params;
|
||||
Color3 colors[8];
|
||||
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
|
||||
|
||||
DiffuseRampBsdf *bsdf = (DiffuseRampBsdf *)bsdf_alloc_osl(
|
||||
sd, sizeof(DiffuseRampBsdf), rgb_to_spectrum(weight), ¶ms);
|
||||
|
||||
if (bsdf) {
|
||||
bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
|
||||
|
||||
if (bsdf->colors) {
|
||||
for (int i = 0; i < 8; i++)
|
||||
bsdf->colors[i] = TO_FLOAT3(colors[i]);
|
||||
|
||||
sd->flag |= bsdf_diffuse_ramp_setup(bsdf);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_bsdf_diffuse_ramp_params()
|
||||
{
|
||||
static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, params.N),
|
||||
CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
|
||||
CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(DiffuseRampClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_bsdf_diffuse_ramp_prepare, DiffuseRampClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -1,69 +0,0 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/bsdf_phong_ramp.h"
|
||||
#include "kernel/closure/bsdf_util.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
class PhongRampClosure : public CBSDFClosure {
|
||||
public:
|
||||
PhongRampBsdf params;
|
||||
Color3 colors[8];
|
||||
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
|
||||
|
||||
PhongRampBsdf *bsdf = (PhongRampBsdf *)bsdf_alloc_osl(
|
||||
sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight), ¶ms);
|
||||
|
||||
if (bsdf) {
|
||||
bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
|
||||
|
||||
if (bsdf->colors) {
|
||||
for (int i = 0; i < 8; i++)
|
||||
bsdf->colors[i] = TO_FLOAT3(colors[i]);
|
||||
|
||||
sd->flag |= bsdf_phong_ramp_setup(bsdf);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_bsdf_phong_ramp_params()
|
||||
{
|
||||
static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PhongRampClosure, params.N),
|
||||
CLOSURE_FLOAT_PARAM(PhongRampClosure, params.exponent),
|
||||
CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
|
||||
CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(PhongRampClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_bsdf_phong_ramp_prepare, PhongRampClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -1,105 +0,0 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/bsdf_util.h"
|
||||
#include "kernel/closure/bsdf_diffuse.h"
|
||||
#include "kernel/closure/bsdf_principled_diffuse.h"
|
||||
#include "kernel/closure/bssrdf.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
static ustring u_burley("burley");
|
||||
static ustring u_random_walk_fixed_radius("random_walk_fixed_radius");
|
||||
static ustring u_random_walk("random_walk");
|
||||
|
||||
class CBSSRDFClosure : public CClosurePrimitive {
|
||||
public:
|
||||
Bssrdf params;
|
||||
float ior;
|
||||
ustring method;
|
||||
|
||||
CBSSRDFClosure()
|
||||
{
|
||||
params.roughness = FLT_MAX;
|
||||
params.anisotropy = 1.0f;
|
||||
ior = 1.4f;
|
||||
}
|
||||
|
||||
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
|
||||
{
|
||||
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
|
||||
|
||||
if (method == u_burley) {
|
||||
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_BURLEY_ID);
|
||||
}
|
||||
else if (method == u_random_walk_fixed_radius) {
|
||||
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
|
||||
}
|
||||
else if (method == u_random_walk) {
|
||||
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_ID);
|
||||
}
|
||||
}
|
||||
|
||||
void alloc(ShaderData *sd, uint32_t path_flag, float3 weight, ClosureType type)
|
||||
{
|
||||
Bssrdf *bssrdf = bssrdf_alloc(sd, rgb_to_spectrum(weight));
|
||||
|
||||
if (bssrdf) {
|
||||
/* disable in case of diffuse ancestor, can't see it well then and
|
||||
* adds considerably noise due to probabilities of continuing path
|
||||
* getting lower and lower */
|
||||
if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
|
||||
params.radius = zero_spectrum();
|
||||
}
|
||||
|
||||
/* create one closure per color channel */
|
||||
bssrdf->radius = params.radius;
|
||||
bssrdf->albedo = params.albedo;
|
||||
bssrdf->N = params.N;
|
||||
bssrdf->roughness = params.roughness;
|
||||
bssrdf->anisotropy = clamp(params.anisotropy, 0.0f, 0.9f);
|
||||
sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type, clamp(ior, 1.01f, 3.8f));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_bssrdf_params()
|
||||
{
|
||||
static ClosureParam params[] = {
|
||||
CLOSURE_STRING_PARAM(CBSSRDFClosure, method),
|
||||
CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.N),
|
||||
CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.radius),
|
||||
CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.albedo),
|
||||
CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.roughness, "roughness"),
|
||||
CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, ior, "ior"),
|
||||
CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.anisotropy, "anisotropy"),
|
||||
CLOSURE_STRING_KEYPARAM(CBSSRDFClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(CBSSRDFClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_bssrdf_prepare, CBSSRDFClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
File diff suppressed because it is too large
Load Diff
|
@ -1,142 +0,0 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#ifndef __OSL_CLOSURES_H__
|
||||
#define __OSL_CLOSURES_H__
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "util/types.h"
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
#include <OSL/oslclosure.h>
|
||||
#include <OSL/oslexec.h>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
OSL::ClosureParam *closure_emission_params();
|
||||
OSL::ClosureParam *closure_background_params();
|
||||
OSL::ClosureParam *closure_holdout_params();
|
||||
OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
|
||||
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
|
||||
OSL::ClosureParam *closure_bsdf_transparent_params();
|
||||
OSL::ClosureParam *closure_bssrdf_params();
|
||||
OSL::ClosureParam *closure_absorption_params();
|
||||
OSL::ClosureParam *closure_henyey_greenstein_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_principled_clearcoat_params();
|
||||
|
||||
void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_background_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bssrdf_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_absorption_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_henyey_greenstein_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_glass_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_aniso_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_ggx_aniso_fresnel_prepare(OSL::RendererServices *,
|
||||
int id,
|
||||
void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *,
|
||||
int id,
|
||||
void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *,
|
||||
int id,
|
||||
void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *,
|
||||
int id,
|
||||
void *data);
|
||||
void closure_bsdf_principled_clearcoat_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_principled_hair_prepare(OSL::RendererServices *, int id, void *data);
|
||||
|
||||
#define CCLOSURE_PREPARE(name, classname) \
|
||||
void name(RendererServices *, int id, void *data) \
|
||||
{ \
|
||||
memset(data, 0, sizeof(classname)); \
|
||||
new (data) classname(); \
|
||||
}
|
||||
|
||||
#define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname)
|
||||
|
||||
#define CLOSURE_FLOAT3_PARAM(st, fld) \
|
||||
{ \
|
||||
TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) \
|
||||
}
|
||||
|
||||
#define BSDF_CLOSURE_FLOAT_PARAM(st, fld) CLOSURE_FLOAT_PARAM(st, fld),
|
||||
#define BSDF_CLOSURE_FLOAT3_PARAM(st, fld) CLOSURE_FLOAT3_PARAM(st, fld),
|
||||
|
||||
#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
|
||||
#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z)
|
||||
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
|
||||
|
||||
/* Closure */
|
||||
|
||||
class CClosurePrimitive {
|
||||
public:
|
||||
virtual void setup(ShaderData *sd, uint32_t path_flag, float3 weight) = 0;
|
||||
|
||||
OSL::ustring label;
|
||||
};
|
||||
|
||||
/* BSDF */
|
||||
|
||||
class CBSDFClosure : public CClosurePrimitive {
|
||||
public:
|
||||
bool skip(const ShaderData *sd, uint32_t path_flag, int scattering);
|
||||
};
|
||||
|
||||
#define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, structname, TYPE) \
|
||||
\
|
||||
class Upper##Closure : public CBSDFClosure { \
|
||||
public: \
|
||||
structname params; \
|
||||
float3 unused; \
|
||||
\
|
||||
void setup(ShaderData *sd, uint32_t path_flag, float3 weight) \
|
||||
{ \
|
||||
if (!skip(sd, path_flag, TYPE)) { \
|
||||
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); \
|
||||
structname *bsdf = (structname *)bsdf_alloc_osl( \
|
||||
sd, sizeof(structname), rgb_to_spectrum(weight), ¶ms); \
|
||||
sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \
|
||||
} \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
static ClosureParam *bsdf_##lower##_params() \
|
||||
{ \
|
||||
static ClosureParam params[] = {
|
||||
|
||||
/* parameters */
|
||||
|
||||
#define BSDF_CLOSURE_CLASS_END(Upper, lower) \
|
||||
CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), CLOSURE_FINISH_PARAM(Upper##Closure) \
|
||||
} \
|
||||
; \
|
||||
return params; \
|
||||
} \
|
||||
\
|
||||
CCLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure)
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __OSL_CLOSURES_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,258 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#ifndef OSL_CLOSURE_STRUCT_BEGIN
|
||||
# define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower)
|
||||
#endif
|
||||
#ifndef OSL_CLOSURE_STRUCT_END
|
||||
# define OSL_CLOSURE_STRUCT_END(Upper, lower)
|
||||
#endif
|
||||
#ifndef OSL_CLOSURE_STRUCT_MEMBER
|
||||
# define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key)
|
||||
#endif
|
||||
#ifndef OSL_CLOSURE_STRUCT_ARRAY_MEMBER
|
||||
# define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size)
|
||||
#endif
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Diffuse, diffuse)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Diffuse, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Diffuse, diffuse)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(OrenNayar, oren_nayar)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(OrenNayar, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(OrenNayar, FLOAT, float, roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(OrenNayar, oren_nayar)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Translucent, translucent)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Translucent, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Translucent, translucent)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Reflection, reflection)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Reflection, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Reflection, reflection)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Refraction, refraction)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Refraction, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Refraction, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Refraction, refraction)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Transparent, transparent)
|
||||
OSL_CLOSURE_STRUCT_END(Transparent, transparent)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Microfacet, microfacet)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, STRING, ustring, distribution, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, INT, int, refract, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Microfacet, microfacet)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXIsotropic, microfacet_ggx)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGXIsotropic, microfacet_ggx)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGX, microfacet_ggx_aniso)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGX, microfacet_ggx_aniso)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGX, microfacet_multi_ggx)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGX, microfacet_multi_ggx)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXFresnel, microfacet_ggx_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGXFresnel, microfacet_ggx_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannIsotropic, microfacet_beckmann)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannIsotropic, microfacet_beckmann)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmann, microfacet_beckmann_aniso)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetBeckmann, microfacet_beckmann_aniso)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(AshikhminShirley, ashikhmin_shirley)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(AshikhminShirley, ashikhmin_shirley)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(AshikhminVelvet, ashikhmin_velvet)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, FLOAT, float, sigma, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(AshikhminVelvet, ashikhmin_velvet)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(DiffuseToon, diffuse_toon)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, FLOAT, float, size, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, FLOAT, float, smooth, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(DiffuseToon, diffuse_toon)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(GlossyToon, glossy_toon)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, FLOAT, float, size, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, FLOAT, float, smooth, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(GlossyToon, glossy_toon)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PrincipledDiffuse, principled_diffuse)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, FLOAT, float, roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(PrincipledDiffuse, principled_diffuse)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PrincipledSheen, principled_sheen)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledSheen, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(PrincipledSheen, principled_sheen)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PrincipledClearcoat, principled_clearcoat)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, FLOAT, float, clearcoat, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, FLOAT, float, clearcoat_roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(PrincipledClearcoat, principled_clearcoat)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(GenericEmissive, emission)
|
||||
OSL_CLOSURE_STRUCT_END(GenericEmissive, emission)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(GenericBackground, background)
|
||||
OSL_CLOSURE_STRUCT_END(GenericBackground, background)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Holdout, holdout)
|
||||
OSL_CLOSURE_STRUCT_END(Holdout, holdout)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(DiffuseRamp, diffuse_ramp)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(DiffuseRamp, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_ARRAY_MEMBER(DiffuseRamp, COLOR, packed_float3, colors, NULL, 8)
|
||||
OSL_CLOSURE_STRUCT_END(DiffuseRamp, diffuse_ramp)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PhongRamp, phong_ramp)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PhongRamp, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PhongRamp, FLOAT, float, exponent, NULL)
|
||||
OSL_CLOSURE_STRUCT_ARRAY_MEMBER(PhongRamp, COLOR, packed_float3, colors, NULL, 8)
|
||||
OSL_CLOSURE_STRUCT_END(PhongRamp, phong_ramp)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(BSSRDF, bssrdf)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, STRING, ustring, method, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, radius, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, albedo, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, roughness, "roughness")
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, ior, "ior")
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, anisotropy, "anisotropy")
|
||||
OSL_CLOSURE_STRUCT_END(BSSRDF, bssrdf)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(HairReflection, hair_reflection)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, roughness1, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, roughness2, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, offset, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(HairReflection, hair_reflection)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(HairTransmission, hair_transmission)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, FLOAT, float, roughness1, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, FLOAT, float, roughness2, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, offset, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(HairTransmission, hair_transmission)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PrincipledHair, principled_hair)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, sigma, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, v, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, s, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, m0_roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, alpha, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, eta, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(PrincipledHair, principled_hair)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(VolumeAbsorption, absorption)
|
||||
OSL_CLOSURE_STRUCT_END(VolumeAbsorption, absorption)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(VolumeHenyeyGreenstein, FLOAT, float, g, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(VolumeHenyeyGreenstein, henyey_greenstein)
|
||||
|
||||
#undef OSL_CLOSURE_STRUCT_BEGIN
|
||||
#undef OSL_CLOSURE_STRUCT_END
|
||||
#undef OSL_CLOSURE_STRUCT_MEMBER
|
||||
#undef OSL_CLOSURE_STRUCT_ARRAY_MEMBER
|
|
@ -1,54 +0,0 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/emissive.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
/// Variable cone emissive closure
|
||||
///
|
||||
/// This primitive emits in a cone having a configurable
|
||||
/// penumbra area where the light decays to 0 reaching the
|
||||
/// outer_angle limit. It can also behave as a lambertian emitter
|
||||
/// if the provided angles are PI/2, which is the default
|
||||
///
|
||||
class GenericEmissiveClosure : public CClosurePrimitive {
|
||||
public:
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
emission_setup(sd, rgb_to_spectrum(weight));
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_emission_params()
|
||||
{
|
||||
static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(GenericEmissiveClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -56,16 +56,8 @@ struct OSLGlobals {
|
|||
OSL::ShaderGroupRef background_state;
|
||||
|
||||
/* attributes */
|
||||
struct Attribute {
|
||||
TypeDesc type;
|
||||
AttributeDescriptor desc;
|
||||
ParamValue value;
|
||||
};
|
||||
|
||||
typedef unordered_map<ustring, Attribute, ustringHash> AttributeMap;
|
||||
typedef unordered_map<ustring, int, ustringHash> ObjectNameMap;
|
||||
|
||||
vector<AttributeMap> attribute_map;
|
||||
ObjectNameMap object_name_map;
|
||||
vector<ustring> object_names;
|
||||
};
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "scene/pointcloud.h"
|
||||
#include "scene/scene.h"
|
||||
|
||||
#include "kernel/osl/closures.h"
|
||||
#include "kernel/osl/globals.h"
|
||||
#include "kernel/osl/services.h"
|
||||
#include "kernel/osl/shader.h"
|
||||
|
@ -740,115 +739,76 @@ static bool set_attribute_matrix(const Transform &tfm, TypeDesc type, void *val)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool get_primitive_attribute(const KernelGlobalsCPU *kg,
|
||||
const ShaderData *sd,
|
||||
const OSLGlobals::Attribute &attr,
|
||||
const TypeDesc &type,
|
||||
bool derivatives,
|
||||
void *val)
|
||||
{
|
||||
if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
|
||||
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
|
||||
float3 fval[3];
|
||||
if (primitive_is_volume_attribute(sd, attr.desc)) {
|
||||
fval[0] = primitive_volume_attribute_float3(kg, sd, attr.desc);
|
||||
}
|
||||
else {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_surface_attribute_float3(
|
||||
kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float3(fval, type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeFloat2) {
|
||||
if (primitive_is_volume_attribute(sd, attr.desc)) {
|
||||
assert(!"Float2 attribute not support for volumes");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
float2 fval[3];
|
||||
fval[0] = primitive_surface_attribute_float2(
|
||||
kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
return set_attribute_float2(fval, type, derivatives, val);
|
||||
}
|
||||
}
|
||||
else if (attr.type == TypeDesc::TypeFloat) {
|
||||
float fval[3];
|
||||
if (primitive_is_volume_attribute(sd, attr.desc)) {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_volume_attribute_float(kg, sd, attr.desc);
|
||||
}
|
||||
else {
|
||||
fval[0] = primitive_surface_attribute_float(
|
||||
kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float(fval, type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeDesc::TypeFloat4 || attr.type == TypeRGBA) {
|
||||
float4 fval[3];
|
||||
if (primitive_is_volume_attribute(sd, attr.desc)) {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_volume_attribute_float4(kg, sd, attr.desc);
|
||||
}
|
||||
else {
|
||||
fval[0] = primitive_surface_attribute_float4(
|
||||
kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float4(fval, type, derivatives, val);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool get_mesh_attribute(const KernelGlobalsCPU *kg,
|
||||
const ShaderData *sd,
|
||||
const OSLGlobals::Attribute &attr,
|
||||
const TypeDesc &type,
|
||||
bool derivatives,
|
||||
void *val)
|
||||
{
|
||||
if (attr.type == TypeDesc::TypeMatrix) {
|
||||
Transform tfm = primitive_attribute_matrix(kg, sd, attr.desc);
|
||||
return set_attribute_matrix(tfm, type, val);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool get_object_attribute(const OSLGlobals::Attribute &attr,
|
||||
TypeDesc type,
|
||||
static bool get_object_attribute(const KernelGlobalsCPU *kg,
|
||||
ShaderData *sd,
|
||||
const AttributeDescriptor &desc,
|
||||
const TypeDesc &type,
|
||||
bool derivatives,
|
||||
void *val)
|
||||
{
|
||||
if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
|
||||
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
|
||||
const float *data = (const float *)attr.value.data();
|
||||
return set_attribute_float3(make_float3(data[0], data[1], data[2]), type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeFloat2) {
|
||||
const float *data = (const float *)attr.value.data();
|
||||
return set_attribute_float2(make_float2(data[0], data[1]), type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeDesc::TypeFloat) {
|
||||
const float *data = (const float *)attr.value.data();
|
||||
return set_attribute_float(data[0], type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeRGBA || attr.type == TypeDesc::TypeFloat4) {
|
||||
const float *data = (const float *)attr.value.data();
|
||||
return set_attribute_float4(
|
||||
make_float4(data[0], data[1], data[2], data[3]), type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == type) {
|
||||
size_t datasize = attr.value.datasize();
|
||||
|
||||
memcpy(val, attr.value.data(), datasize);
|
||||
if (derivatives) {
|
||||
memset((char *)val + datasize, 0, datasize * 2);
|
||||
if (desc.type == NODE_ATTR_FLOAT3) {
|
||||
float3 fval[3];
|
||||
#ifdef __VOLUME__
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
fval[0] = primitive_volume_attribute_float3(kg, sd, desc);
|
||||
}
|
||||
|
||||
return true;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_surface_attribute_float3(
|
||||
kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float3(fval, type, derivatives, val);
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
#ifdef __VOLUME__
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
assert(!"Float2 attribute not support for volumes");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
float2 fval[3];
|
||||
fval[0] = primitive_surface_attribute_float2(
|
||||
kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
return set_attribute_float2(fval, type, derivatives, val);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float fval[3];
|
||||
#ifdef __VOLUME__
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_volume_attribute_float(kg, sd, desc);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fval[0] = primitive_surface_attribute_float(
|
||||
kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float(fval, type, derivatives, val);
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 fval[3];
|
||||
#ifdef __VOLUME__
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_volume_attribute_float4(kg, sd, desc);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fval[0] = primitive_surface_attribute_float4(
|
||||
kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float4(fval, type, derivatives, val);
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_MATRIX) {
|
||||
Transform tfm = primitive_attribute_matrix(kg, desc);
|
||||
return set_attribute_matrix(tfm, type, val);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
@ -979,6 +939,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
|||
float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
|
||||
return set_attribute_float(f, type, derivatives, val);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
/* Hair Attributes */
|
||||
else if (name == u_is_curve) {
|
||||
float f = (sd->type & PRIMITIVE_CURVE) != 0;
|
||||
|
@ -996,6 +957,8 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
|||
float f = curve_random(kg, sd);
|
||||
return set_attribute_float(f, type, derivatives, val);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
/* point attributes */
|
||||
else if (name == u_is_point) {
|
||||
float f = (sd->type & PRIMITIVE_POINT) != 0;
|
||||
|
@ -1013,6 +976,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
|||
float f = point_random(kg, sd);
|
||||
return set_attribute_float(f, type, derivatives, val);
|
||||
}
|
||||
#endif
|
||||
else if (name == u_normal_map_normal) {
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
|
||||
|
@ -1023,7 +987,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
|||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1131,7 +1095,6 @@ bool OSLRenderServices::get_attribute(
|
|||
ShaderData *sd, bool derivatives, ustring object_name, TypeDesc type, ustring name, void *val)
|
||||
{
|
||||
const KernelGlobalsCPU *kg = sd->osl_globals;
|
||||
int prim_type = 0;
|
||||
int object;
|
||||
|
||||
/* lookup of attribute on another object */
|
||||
|
@ -1145,44 +1108,18 @@ bool OSLRenderServices::get_attribute(
|
|||
}
|
||||
else {
|
||||
object = sd->object;
|
||||
prim_type = attribute_primitive_type(kg, sd);
|
||||
|
||||
if (object == OBJECT_NONE)
|
||||
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
||||
}
|
||||
|
||||
/* find attribute on object */
|
||||
object = object * ATTR_PRIM_TYPES + prim_type;
|
||||
OSLGlobals::AttributeMap &attribute_map = kg->osl->attribute_map[object];
|
||||
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
|
||||
|
||||
if (it != attribute_map.end()) {
|
||||
const OSLGlobals::Attribute &attr = it->second;
|
||||
|
||||
if (attr.desc.element != ATTR_ELEMENT_OBJECT) {
|
||||
/* triangle and vertex attributes */
|
||||
if (get_primitive_attribute(kg, sd, attr, type, derivatives, val))
|
||||
return true;
|
||||
else
|
||||
return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
|
||||
}
|
||||
else {
|
||||
/* object attribute */
|
||||
return get_object_attribute(attr, type, derivatives, val);
|
||||
}
|
||||
const AttributeDescriptor desc = find_attribute(
|
||||
kg, object, sd->prim, object == sd->object ? sd->type : PRIMITIVE_NONE, name.hash());
|
||||
if (desc.offset != ATTR_STD_NOT_FOUND) {
|
||||
return get_object_attribute(kg, sd, desc, type, derivatives, val);
|
||||
}
|
||||
else {
|
||||
/* not found in attribute, check standard object info */
|
||||
bool is_std_object_attribute = get_object_standard_attribute(
|
||||
kg, sd, name, type, derivatives, val);
|
||||
|
||||
if (is_std_object_attribute)
|
||||
return true;
|
||||
|
||||
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
||||
return get_object_standard_attribute(kg, sd, name, type, derivatives, val);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OSLRenderServices::get_userdata(
|
||||
|
@ -1667,8 +1604,8 @@ bool OSLRenderServices::trace(TraceOpt &options,
|
|||
/* setup ray */
|
||||
Ray ray;
|
||||
|
||||
ray.P = TO_FLOAT3(P);
|
||||
ray.D = TO_FLOAT3(R);
|
||||
ray.P = make_float3(P.x, P.y, P.z);
|
||||
ray.D = make_float3(R.x, R.y, R.z);
|
||||
ray.tmin = 0.0f;
|
||||
ray.tmax = (options.maxdist == 1.0e30f) ? FLT_MAX : options.maxdist - options.mindist;
|
||||
ray.time = sd->time;
|
||||
|
@ -1691,12 +1628,12 @@ bool OSLRenderServices::trace(TraceOpt &options,
|
|||
|
||||
/* ray differentials */
|
||||
differential3 dP;
|
||||
dP.dx = TO_FLOAT3(dPdx);
|
||||
dP.dy = TO_FLOAT3(dPdy);
|
||||
dP.dx = make_float3(dPdx.x, dPdx.y, dPdx.z);
|
||||
dP.dy = make_float3(dPdy.x, dPdy.y, dPdy.z);
|
||||
ray.dP = differential_make_compact(dP);
|
||||
differential3 dD;
|
||||
dD.dx = TO_FLOAT3(dRdx);
|
||||
dD.dy = TO_FLOAT3(dRdy);
|
||||
dD.dx = make_float3(dRdx.x, dRdx.y, dRdx.z);
|
||||
dD.dy = make_float3(dRdy.x, dRdy.y, dRdy.z);
|
||||
ray.dD = differential_make_compact(dD);
|
||||
|
||||
/* allocate trace data */
|
||||
|
|
|
@ -76,6 +76,8 @@ class OSLRenderServices : public OSL::RendererServices {
|
|||
OSLRenderServices(OSL::TextureSystem *texture_system);
|
||||
~OSLRenderServices();
|
||||
|
||||
static void register_closures(OSL::ShadingSystem *ss);
|
||||
|
||||
bool get_matrix(OSL::ShaderGlobals *sg,
|
||||
OSL::Matrix44 &result,
|
||||
OSL::TransformationPtr xform,
|
||||
|
|
|
@ -13,15 +13,18 @@
|
|||
|
||||
#include "kernel/integrator/state.h"
|
||||
|
||||
#include "kernel/osl/closures.h"
|
||||
#include "kernel/osl/globals.h"
|
||||
#include "kernel/osl/services.h"
|
||||
#include "kernel/osl/shader.h"
|
||||
|
||||
#include "kernel/osl/types.h"
|
||||
#include "kernel/osl/closures_setup.h"
|
||||
|
||||
#include "kernel/util/differential.h"
|
||||
// clang-format on
|
||||
|
||||
#include "scene/attribute.h"
|
||||
#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
|
||||
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@ -135,7 +138,8 @@ static void shaderdata_to_shaderglobals(const KernelGlobalsCPU *kg,
|
|||
|
||||
/* Surface */
|
||||
|
||||
static void flatten_surface_closure_tree(ShaderData *sd,
|
||||
static void flatten_surface_closure_tree(const KernelGlobalsCPU *kg,
|
||||
ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
const OSL::ClosureColor *closure,
|
||||
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
|
||||
|
@ -146,27 +150,30 @@ static void flatten_surface_closure_tree(ShaderData *sd,
|
|||
switch (closure->id) {
|
||||
case OSL::ClosureColor::MUL: {
|
||||
OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
|
||||
flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
|
||||
flatten_surface_closure_tree(kg, sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
|
||||
break;
|
||||
}
|
||||
case OSL::ClosureColor::ADD: {
|
||||
OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
|
||||
flatten_surface_closure_tree(sd, path_flag, add->closureA, weight);
|
||||
flatten_surface_closure_tree(sd, path_flag, add->closureB, weight);
|
||||
flatten_surface_closure_tree(kg, sd, path_flag, add->closureA, weight);
|
||||
flatten_surface_closure_tree(kg, sd, path_flag, add->closureB, weight);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
|
||||
CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
|
||||
|
||||
if (prim) {
|
||||
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
|
||||
weight = weight * TO_FLOAT3(comp->w);
|
||||
#endif
|
||||
prim->setup(sd, path_flag, weight);
|
||||
}
|
||||
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
|
||||
case OSL_CLOSURE_##Upper##_ID: { \
|
||||
const OSL::ClosureComponent *comp = \
|
||||
reinterpret_cast<const OSL::ClosureComponent *>(closure); \
|
||||
weight *= TO_FLOAT3(comp->w); \
|
||||
osl_closure_##lower##_setup(kg, \
|
||||
sd, \
|
||||
path_flag, \
|
||||
weight, \
|
||||
reinterpret_cast<const Upper##Closure *>(comp + 1)); \
|
||||
break; \
|
||||
}
|
||||
#include "closures_template.h"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,12 +247,13 @@ void OSLShader::eval_surface(const KernelGlobalsCPU *kg,
|
|||
|
||||
/* flatten closure tree */
|
||||
if (globals->Ci)
|
||||
flatten_surface_closure_tree(sd, path_flag, globals->Ci);
|
||||
flatten_surface_closure_tree(kg, sd, path_flag, globals->Ci);
|
||||
}
|
||||
|
||||
/* Background */
|
||||
|
||||
static void flatten_background_closure_tree(ShaderData *sd,
|
||||
static void flatten_background_closure_tree(const KernelGlobalsCPU *kg,
|
||||
ShaderData *sd,
|
||||
const OSL::ClosureColor *closure,
|
||||
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
|
||||
{
|
||||
|
@ -256,28 +264,27 @@ static void flatten_background_closure_tree(ShaderData *sd,
|
|||
switch (closure->id) {
|
||||
case OSL::ClosureColor::MUL: {
|
||||
OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
|
||||
flatten_background_closure_tree(sd, mul->closure, weight * TO_FLOAT3(mul->weight));
|
||||
flatten_background_closure_tree(kg, sd, mul->closure, weight * TO_FLOAT3(mul->weight));
|
||||
break;
|
||||
}
|
||||
case OSL::ClosureColor::ADD: {
|
||||
OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
|
||||
|
||||
flatten_background_closure_tree(sd, add->closureA, weight);
|
||||
flatten_background_closure_tree(sd, add->closureB, weight);
|
||||
flatten_background_closure_tree(kg, sd, add->closureA, weight);
|
||||
flatten_background_closure_tree(kg, sd, add->closureB, weight);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
|
||||
CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
|
||||
|
||||
if (prim) {
|
||||
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
|
||||
weight = weight * TO_FLOAT3(comp->w);
|
||||
#endif
|
||||
prim->setup(sd, 0, weight);
|
||||
}
|
||||
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
|
||||
case OSL_CLOSURE_##Upper##_ID: { \
|
||||
const OSL::ClosureComponent *comp = reinterpret_cast<const OSL::ClosureComponent *>(closure); \
|
||||
weight *= TO_FLOAT3(comp->w); \
|
||||
osl_closure_##lower##_setup( \
|
||||
kg, sd, 0, weight, reinterpret_cast<const Upper##Closure *>(comp + 1)); \
|
||||
break; \
|
||||
}
|
||||
#include "closures_template.h"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,12 +308,13 @@ void OSLShader::eval_background(const KernelGlobalsCPU *kg,
|
|||
|
||||
/* return background color immediately */
|
||||
if (globals->Ci)
|
||||
flatten_background_closure_tree(sd, globals->Ci);
|
||||
flatten_background_closure_tree(kg, sd, globals->Ci);
|
||||
}
|
||||
|
||||
/* Volume */
|
||||
|
||||
static void flatten_volume_closure_tree(ShaderData *sd,
|
||||
static void flatten_volume_closure_tree(const KernelGlobalsCPU *kg,
|
||||
ShaderData *sd,
|
||||
const OSL::ClosureColor *closure,
|
||||
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
|
||||
{
|
||||
|
@ -316,26 +324,26 @@ static void flatten_volume_closure_tree(ShaderData *sd,
|
|||
switch (closure->id) {
|
||||
case OSL::ClosureColor::MUL: {
|
||||
OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
|
||||
flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
|
||||
flatten_volume_closure_tree(kg, sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
|
||||
break;
|
||||
}
|
||||
case OSL::ClosureColor::ADD: {
|
||||
OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
|
||||
flatten_volume_closure_tree(sd, add->closureA, weight);
|
||||
flatten_volume_closure_tree(sd, add->closureB, weight);
|
||||
flatten_volume_closure_tree(kg, sd, add->closureA, weight);
|
||||
flatten_volume_closure_tree(kg, sd, add->closureB, weight);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
|
||||
CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
|
||||
|
||||
if (prim) {
|
||||
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
|
||||
weight = weight * TO_FLOAT3(comp->w);
|
||||
#endif
|
||||
prim->setup(sd, 0, weight);
|
||||
}
|
||||
}
|
||||
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) \
|
||||
case OSL_CLOSURE_##Upper##_ID: { \
|
||||
const OSL::ClosureComponent *comp = reinterpret_cast<const OSL::ClosureComponent *>(closure); \
|
||||
weight *= TO_FLOAT3(comp->w); \
|
||||
osl_closure_##lower##_setup( \
|
||||
kg, sd, 0, weight, reinterpret_cast<const Upper##Closure *>(comp + 1)); \
|
||||
break; \
|
||||
}
|
||||
#include "closures_template.h"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,7 +368,7 @@ void OSLShader::eval_volume(const KernelGlobalsCPU *kg,
|
|||
|
||||
/* flatten closure tree */
|
||||
if (globals->Ci)
|
||||
flatten_volume_closure_tree(sd, globals->Ci);
|
||||
flatten_volume_closure_tree(kg, sd, globals->Ci);
|
||||
}
|
||||
|
||||
/* Displacement */
|
||||
|
@ -386,40 +394,4 @@ void OSLShader::eval_displacement(const KernelGlobalsCPU *kg, const void *state,
|
|||
sd->P = TO_FLOAT3(globals->P);
|
||||
}
|
||||
|
||||
/* Attributes */
|
||||
|
||||
int OSLShader::find_attribute(const KernelGlobalsCPU *kg,
|
||||
const ShaderData *sd,
|
||||
uint id,
|
||||
AttributeDescriptor *desc)
|
||||
{
|
||||
/* for OSL, a hash map is used to lookup the attribute by name. */
|
||||
int object = sd->object * ATTR_PRIM_TYPES;
|
||||
|
||||
OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
|
||||
ustring stdname(std::string("geom:") +
|
||||
std::string(Attribute::standard_name((AttributeStandard)id)));
|
||||
OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
|
||||
|
||||
if (it != attr_map.end()) {
|
||||
const OSLGlobals::Attribute &osl_attr = it->second;
|
||||
*desc = osl_attr.desc;
|
||||
|
||||
if (sd->prim == PRIM_NONE && (AttributeElement)osl_attr.desc.element != ATTR_ELEMENT_MESH) {
|
||||
desc->offset = ATTR_STD_NOT_FOUND;
|
||||
return ATTR_STD_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* return result */
|
||||
if (osl_attr.desc.element == ATTR_ELEMENT_NONE) {
|
||||
desc->offset = ATTR_STD_NOT_FOUND;
|
||||
}
|
||||
return desc->offset;
|
||||
}
|
||||
else {
|
||||
desc->offset = ATTR_STD_NOT_FOUND;
|
||||
return (int)ATTR_STD_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -33,9 +33,6 @@ struct OSLShadingSystem;
|
|||
|
||||
class OSLShader {
|
||||
public:
|
||||
/* init */
|
||||
static void register_closures(OSLShadingSystem *ss);
|
||||
|
||||
/* per thread data */
|
||||
static void thread_init(KernelGlobalsCPU *kg, OSLGlobals *osl_globals);
|
||||
static void thread_free(KernelGlobalsCPU *kg);
|
||||
|
@ -54,12 +51,6 @@ class OSLShader {
|
|||
ShaderData *sd,
|
||||
uint32_t path_flag);
|
||||
static void eval_displacement(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd);
|
||||
|
||||
/* attributes */
|
||||
static int find_attribute(const KernelGlobalsCPU *kg,
|
||||
const ShaderData *sd,
|
||||
uint id,
|
||||
AttributeDescriptor *desc);
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Closure */
|
||||
|
||||
enum ClosureTypeOSL {
|
||||
OSL_CLOSURE_MUL_ID = -1,
|
||||
OSL_CLOSURE_ADD_ID = -2,
|
||||
|
||||
OSL_CLOSURE_NONE_ID = 0,
|
||||
|
||||
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) OSL_CLOSURE_##Upper##_ID,
|
||||
#include "closures_template.h"
|
||||
};
|
||||
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -655,12 +655,11 @@ typedef struct AttributeDescriptor {
|
|||
|
||||
/* For looking up attributes on objects and geometry. */
|
||||
typedef struct AttributeMap {
|
||||
uint id; /* Global unique identifier. */
|
||||
uint element; /* AttributeElement. */
|
||||
int offset; /* Offset into __attributes global arrays. */
|
||||
uint8_t type; /* NodeAttributeType. */
|
||||
uint8_t flags; /* AttributeFlag. */
|
||||
uint8_t pad[2];
|
||||
uint64_t id; /* Global unique identifier. */
|
||||
int offset; /* Offset into __attributes global arrays. */
|
||||
uint16_t element; /* AttributeElement. */
|
||||
uint8_t type; /* NodeAttributeType. */
|
||||
uint8_t flags; /* AttributeFlag. */
|
||||
} AttributeMap;
|
||||
|
||||
/* Closure data */
|
||||
|
|
|
@ -302,111 +302,32 @@ GeometryManager::~GeometryManager()
|
|||
{
|
||||
}
|
||||
|
||||
void GeometryManager::update_osl_attributes(Device *device,
|
||||
Scene *scene,
|
||||
vector<AttributeRequestSet> &geom_attributes)
|
||||
void GeometryManager::update_osl_globals(Device *device, Scene *scene)
|
||||
{
|
||||
#ifdef WITH_OSL
|
||||
/* for OSL, a hash map is used to lookup the attribute by name. */
|
||||
OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
|
||||
|
||||
og->object_name_map.clear();
|
||||
og->attribute_map.clear();
|
||||
og->object_names.clear();
|
||||
|
||||
og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES);
|
||||
|
||||
for (size_t i = 0; i < scene->objects.size(); i++) {
|
||||
/* set object name to object index map */
|
||||
Object *object = scene->objects[i];
|
||||
og->object_name_map[object->name] = i;
|
||||
og->object_names.push_back(object->name);
|
||||
|
||||
/* set object attributes */
|
||||
foreach (ParamValue &attr, object->attributes) {
|
||||
OSLGlobals::Attribute osl_attr;
|
||||
|
||||
osl_attr.type = attr.type();
|
||||
osl_attr.desc.element = ATTR_ELEMENT_OBJECT;
|
||||
osl_attr.value = attr;
|
||||
osl_attr.desc.offset = 0;
|
||||
osl_attr.desc.flags = 0;
|
||||
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][attr.name()] = osl_attr;
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr;
|
||||
}
|
||||
|
||||
/* find geometry attributes */
|
||||
size_t j = object->geometry->index;
|
||||
assert(j < scene->geometry.size() && scene->geometry[j] == object->geometry);
|
||||
|
||||
AttributeRequestSet &attributes = geom_attributes[j];
|
||||
|
||||
/* set mesh attributes */
|
||||
foreach (AttributeRequest &req, attributes.requests) {
|
||||
OSLGlobals::Attribute osl_attr;
|
||||
|
||||
if (req.desc.element != ATTR_ELEMENT_NONE) {
|
||||
osl_attr.desc = req.desc;
|
||||
|
||||
if (req.type == TypeDesc::TypeFloat)
|
||||
osl_attr.type = TypeDesc::TypeFloat;
|
||||
else if (req.type == TypeDesc::TypeMatrix)
|
||||
osl_attr.type = TypeDesc::TypeMatrix;
|
||||
else if (req.type == TypeFloat2)
|
||||
osl_attr.type = TypeFloat2;
|
||||
else if (req.type == TypeRGBA)
|
||||
osl_attr.type = TypeRGBA;
|
||||
else
|
||||
osl_attr.type = TypeDesc::TypeColor;
|
||||
|
||||
if (req.std != ATTR_STD_NONE) {
|
||||
/* if standard attribute, add lookup by geom: name convention */
|
||||
ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][stdname] = osl_attr;
|
||||
}
|
||||
else if (req.name != ustring()) {
|
||||
/* add lookup by geometry attribute name */
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][req.name] = osl_attr;
|
||||
}
|
||||
}
|
||||
|
||||
if (req.subd_desc.element != ATTR_ELEMENT_NONE) {
|
||||
osl_attr.desc = req.subd_desc;
|
||||
|
||||
if (req.subd_type == TypeDesc::TypeFloat)
|
||||
osl_attr.type = TypeDesc::TypeFloat;
|
||||
else if (req.subd_type == TypeDesc::TypeMatrix)
|
||||
osl_attr.type = TypeDesc::TypeMatrix;
|
||||
else if (req.subd_type == TypeFloat2)
|
||||
osl_attr.type = TypeFloat2;
|
||||
else if (req.subd_type == TypeRGBA)
|
||||
osl_attr.type = TypeRGBA;
|
||||
else
|
||||
osl_attr.type = TypeDesc::TypeColor;
|
||||
|
||||
if (req.std != ATTR_STD_NONE) {
|
||||
/* if standard attribute, add lookup by geom: name convention */
|
||||
ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr;
|
||||
}
|
||||
else if (req.name != ustring()) {
|
||||
/* add lookup by geometry attribute name */
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)device;
|
||||
(void)scene;
|
||||
(void)geom_attributes;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Generate a normal attribute map entry from an attribute descriptor. */
|
||||
static void emit_attribute_map_entry(
|
||||
AttributeMap *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
|
||||
static void emit_attribute_map_entry(AttributeMap *attr_map,
|
||||
size_t index,
|
||||
uint64_t id,
|
||||
TypeDesc type,
|
||||
const AttributeDescriptor &desc)
|
||||
{
|
||||
attr_map[index].id = id;
|
||||
attr_map[index].element = desc.element;
|
||||
|
@ -431,7 +352,7 @@ static void emit_attribute_map_entry(
|
|||
/* Generate an attribute map end marker, optionally including a link to another map.
|
||||
* Links are used to connect object attribute maps to mesh attribute maps. */
|
||||
static void emit_attribute_map_terminator(AttributeMap *attr_map,
|
||||
int index,
|
||||
size_t index,
|
||||
bool chain,
|
||||
uint chain_link)
|
||||
{
|
||||
|
@ -446,15 +367,8 @@ static void emit_attribute_map_terminator(AttributeMap *attr_map,
|
|||
|
||||
/* Generate all necessary attribute map entries from the attribute request. */
|
||||
static void emit_attribute_mapping(
|
||||
AttributeMap *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
|
||||
AttributeMap *attr_map, size_t index, uint64_t id, AttributeRequest &req, Geometry *geom)
|
||||
{
|
||||
uint id;
|
||||
|
||||
if (req.std == ATTR_STD_NONE)
|
||||
id = scene->shader_manager->get_attribute_id(req.name);
|
||||
else
|
||||
id = scene->shader_manager->get_attribute_id(req.std);
|
||||
|
||||
emit_attribute_map_entry(attr_map, index, id, req.type, req.desc);
|
||||
|
||||
if (geom->is_mesh()) {
|
||||
|
@ -475,12 +389,26 @@ void GeometryManager::update_svm_attributes(Device *,
|
|||
* attribute, based on a unique shader attribute id. */
|
||||
|
||||
/* compute array stride */
|
||||
int attr_map_size = 0;
|
||||
size_t attr_map_size = 0;
|
||||
|
||||
for (size_t i = 0; i < scene->geometry.size(); i++) {
|
||||
Geometry *geom = scene->geometry[i];
|
||||
geom->attr_map_offset = attr_map_size;
|
||||
attr_map_size += (geom_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
|
||||
|
||||
#ifdef WITH_OSL
|
||||
size_t attr_count = 0;
|
||||
foreach (AttributeRequest &req, geom_attributes[i].requests) {
|
||||
if (req.std != ATTR_STD_NONE &&
|
||||
scene->shader_manager->get_attribute_id(req.std) != (uint64_t)req.std)
|
||||
attr_count += 2;
|
||||
else
|
||||
attr_count += 1;
|
||||
}
|
||||
#else
|
||||
const size_t attr_count = geom_attributes[i].size();
|
||||
#endif
|
||||
|
||||
attr_map_size += (attr_count + 1) * ATTR_PRIM_TYPES;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < scene->objects.size(); i++) {
|
||||
|
@ -512,11 +440,26 @@ void GeometryManager::update_svm_attributes(Device *,
|
|||
AttributeRequestSet &attributes = geom_attributes[i];
|
||||
|
||||
/* set geometry attributes */
|
||||
int index = geom->attr_map_offset;
|
||||
size_t index = geom->attr_map_offset;
|
||||
|
||||
foreach (AttributeRequest &req, attributes.requests) {
|
||||
emit_attribute_mapping(attr_map, index, scene, req, geom);
|
||||
uint64_t id;
|
||||
if (req.std == ATTR_STD_NONE)
|
||||
id = scene->shader_manager->get_attribute_id(req.name);
|
||||
else
|
||||
id = scene->shader_manager->get_attribute_id(req.std);
|
||||
|
||||
emit_attribute_mapping(attr_map, index, id, req, geom);
|
||||
index += ATTR_PRIM_TYPES;
|
||||
|
||||
#ifdef WITH_OSL
|
||||
/* Some standard attributes are explicitly referenced via their standard ID, so add those
|
||||
* again in case they were added under a different attribute ID. */
|
||||
if (req.std != ATTR_STD_NONE && id != (uint64_t)req.std) {
|
||||
emit_attribute_mapping(attr_map, index, (uint64_t)req.std, req, geom);
|
||||
index += ATTR_PRIM_TYPES;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
emit_attribute_map_terminator(attr_map, index, false, 0);
|
||||
|
@ -528,10 +471,16 @@ void GeometryManager::update_svm_attributes(Device *,
|
|||
|
||||
/* set object attributes */
|
||||
if (attributes.size() > 0) {
|
||||
int index = object->attr_map_offset;
|
||||
size_t index = object->attr_map_offset;
|
||||
|
||||
foreach (AttributeRequest &req, attributes.requests) {
|
||||
emit_attribute_mapping(attr_map, index, scene, req, object->geometry);
|
||||
uint64_t id;
|
||||
if (req.std == ATTR_STD_NONE)
|
||||
id = scene->shader_manager->get_attribute_id(req.name);
|
||||
else
|
||||
id = scene->shader_manager->get_attribute_id(req.std);
|
||||
|
||||
emit_attribute_mapping(attr_map, index, id, req, object->geometry);
|
||||
index += ATTR_PRIM_TYPES;
|
||||
}
|
||||
|
||||
|
@ -982,7 +931,7 @@ void GeometryManager::device_update_attributes(Device *device,
|
|||
|
||||
/* create attribute lookup maps */
|
||||
if (scene->shader_manager->use_osl())
|
||||
update_osl_attributes(device, scene, geom_attributes);
|
||||
update_osl_globals(device, scene);
|
||||
|
||||
update_svm_attributes(device, dscene, scene, geom_attributes, object_attributes);
|
||||
|
||||
|
@ -2188,7 +2137,6 @@ void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool forc
|
|||
|
||||
if (og) {
|
||||
og->object_name_map.clear();
|
||||
og->attribute_map.clear();
|
||||
og->object_names.clear();
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -219,9 +219,7 @@ class GeometryManager {
|
|||
void create_volume_mesh(const Scene *scene, Volume *volume, Progress &progress);
|
||||
|
||||
/* Attributes */
|
||||
void update_osl_attributes(Device *device,
|
||||
Scene *scene,
|
||||
vector<AttributeRequestSet> &geom_attributes);
|
||||
void update_osl_globals(Device *device, Scene *scene);
|
||||
void update_svm_attributes(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
|
|
|
@ -78,6 +78,18 @@ void OSLShaderManager::reset(Scene * /*scene*/)
|
|||
shading_system_init();
|
||||
}
|
||||
|
||||
uint64_t OSLShaderManager::get_attribute_id(ustring name)
|
||||
{
|
||||
return name.hash();
|
||||
}
|
||||
|
||||
uint64_t OSLShaderManager::get_attribute_id(AttributeStandard std)
|
||||
{
|
||||
/* if standard attribute, use geom: name convention */
|
||||
ustring stdname(string("geom:") + string(Attribute::standard_name(std)));
|
||||
return stdname.hash();
|
||||
}
|
||||
|
||||
void OSLShaderManager::device_update_specific(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
|
@ -286,7 +298,7 @@ void OSLShaderManager::shading_system_init()
|
|||
const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]);
|
||||
ss_shared->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
|
||||
|
||||
OSLShader::register_closures((OSLShadingSystem *)ss_shared);
|
||||
OSLRenderServices::register_closures(ss_shared);
|
||||
|
||||
loaded_shaders.clear();
|
||||
}
|
||||
|
|
|
@ -66,6 +66,9 @@ class OSLShaderManager : public ShaderManager {
|
|||
return true;
|
||||
}
|
||||
|
||||
uint64_t get_attribute_id(ustring name) override;
|
||||
uint64_t get_attribute_id(AttributeStandard std) override;
|
||||
|
||||
void device_update_specific(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
|
|
|
@ -414,7 +414,7 @@ ShaderManager *ShaderManager::create(int shadingsystem)
|
|||
return manager;
|
||||
}
|
||||
|
||||
uint ShaderManager::get_attribute_id(ustring name)
|
||||
uint64_t ShaderManager::get_attribute_id(ustring name)
|
||||
{
|
||||
thread_scoped_spin_lock lock(attribute_lock_);
|
||||
|
||||
|
@ -424,14 +424,14 @@ uint ShaderManager::get_attribute_id(ustring name)
|
|||
if (it != unique_attribute_id.end())
|
||||
return it->second;
|
||||
|
||||
uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
|
||||
uint64_t id = ATTR_STD_NUM + unique_attribute_id.size();
|
||||
unique_attribute_id[name] = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
uint ShaderManager::get_attribute_id(AttributeStandard std)
|
||||
uint64_t ShaderManager::get_attribute_id(AttributeStandard std)
|
||||
{
|
||||
return (uint)std;
|
||||
return (uint64_t)std;
|
||||
}
|
||||
|
||||
int ShaderManager::get_shader_id(Shader *shader, bool smooth)
|
||||
|
|
|
@ -192,8 +192,8 @@ class ShaderManager {
|
|||
void device_free_common(Device *device, DeviceScene *dscene, Scene *scene);
|
||||
|
||||
/* get globally unique id for a type of attribute */
|
||||
uint get_attribute_id(ustring name);
|
||||
uint get_attribute_id(AttributeStandard std);
|
||||
virtual uint64_t get_attribute_id(ustring name);
|
||||
virtual uint64_t get_attribute_id(AttributeStandard std);
|
||||
|
||||
/* get shader id for mesh faces */
|
||||
int get_shader_id(Shader *shader, bool smooth = false);
|
||||
|
@ -223,7 +223,7 @@ class ShaderManager {
|
|||
|
||||
uint32_t update_flags;
|
||||
|
||||
typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
|
||||
typedef unordered_map<ustring, uint64_t, ustringHash> AttributeIDMap;
|
||||
AttributeIDMap unique_attribute_id;
|
||||
|
||||
static thread_mutex lookup_table_mutex;
|
||||
|
|
|
@ -108,7 +108,7 @@ void radixsort(std::vector<T> &data, std::vector<T> &data2, KeyGetter getKey)
|
|||
static_assert(datasize % 2 == 0);
|
||||
static_assert(std::is_integral<key_t>::value);
|
||||
|
||||
uint bins[datasize][257] = {0};
|
||||
uint bins[datasize][257] = {{0}};
|
||||
|
||||
/* Count number of elements per bin. */
|
||||
for (const T &item : data) {
|
||||
|
|
|
@ -493,11 +493,19 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
|
|||
else:
|
||||
col.operator("mesh.customdata_custom_splitnormals_add", icon='ADD')
|
||||
|
||||
if me.has_bevel_weight_edge:
|
||||
col.operator("mesh.customdata_bevel_weight_edge_clear", icon='X')
|
||||
else:
|
||||
col.operator("mesh.customdata_bevel_weight_edge_add", icon='ADD')
|
||||
|
||||
if me.has_bevel_weight_vertex:
|
||||
col.operator("mesh.customdata_bevel_weight_vertex_clear", icon='X')
|
||||
else:
|
||||
col.operator("mesh.customdata_bevel_weight_vertex_add", icon='ADD')
|
||||
|
||||
col = layout.column(heading="Store")
|
||||
|
||||
col.enabled = obj is not None and obj.mode != 'EDIT'
|
||||
col.prop(me, "use_customdata_vertex_bevel", text="Vertex Bevel Weight")
|
||||
col.prop(me, "use_customdata_edge_bevel", text="Edge Bevel Weight")
|
||||
col.prop(me, "use_customdata_vertex_crease", text="Vertex Crease")
|
||||
col.prop(me, "use_customdata_edge_crease", text="Edge Crease")
|
||||
|
||||
|
|
|
@ -30,8 +30,15 @@ class OUTLINER_HT_header(Header):
|
|||
|
||||
layout.separator_spacer()
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(space, "filter_text", icon='VIEWZOOM', text="")
|
||||
filter_text_supported = True
|
||||
# No text filtering for library override hierarchies. The tree is lazy built to avoid
|
||||
# performance issues in complex files.
|
||||
if display_mode == 'LIBRARY_OVERRIDES' and space.lib_override_view_mode == 'HIERARCHIES':
|
||||
filter_text_supported = False
|
||||
|
||||
if filter_text_supported:
|
||||
row = layout.row(align=True)
|
||||
row.prop(space, "filter_text", icon='VIEWZOOM', text="")
|
||||
|
||||
layout.separator_spacer()
|
||||
|
||||
|
@ -46,11 +53,8 @@ class OUTLINER_HT_header(Header):
|
|||
text="",
|
||||
icon='FILTER',
|
||||
)
|
||||
if display_mode == 'LIBRARY_OVERRIDES' and space.lib_override_view_mode == 'HIERARCHIES':
|
||||
# Don't add ID type filter for library overrides hierarchies mode. Point of it is to see a hierarchy that is
|
||||
# usually constructed out of different ID types.
|
||||
pass
|
||||
elif display_mode in {'LIBRARIES', 'LIBRARY_OVERRIDES', 'ORPHAN_DATA'}:
|
||||
|
||||
if display_mode in {'LIBRARIES' 'ORPHAN_DATA'}:
|
||||
row.prop(space, "use_filter_id_type", text="", icon='FILTER')
|
||||
sub = row.row(align=True)
|
||||
sub.active = space.use_filter_id_type
|
||||
|
@ -319,9 +323,21 @@ class OUTLINER_MT_object(Menu):
|
|||
OUTLINER_MT_context_menu.draw_common_operators(layout)
|
||||
|
||||
|
||||
def has_selected_ids_in_context(context):
|
||||
if hasattr(context, "id"):
|
||||
return True
|
||||
if len(context.selected_ids) > 0:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
class OUTLINER_MT_asset(Menu):
|
||||
bl_label = "Assets"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return has_selected_ids_in_context(context)
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
|
@ -333,6 +349,10 @@ class OUTLINER_MT_asset(Menu):
|
|||
class OUTLINER_MT_liboverride(Menu):
|
||||
bl_label = "Library Override"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return has_selected_ids_in_context(context)
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
|
@ -394,14 +414,19 @@ class OUTLINER_PT_filter(Panel):
|
|||
row.prop(space, "show_mode_column", text="Show Mode Column")
|
||||
layout.separator()
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Search")
|
||||
col.prop(space, "use_filter_complete", text="Exact Match")
|
||||
col.prop(space, "use_filter_case_sensitive", text="Case Sensitive")
|
||||
filter_text_supported = True
|
||||
# Same exception for library overrides as in OUTLINER_HT_header.
|
||||
if display_mode == 'LIBRARY_OVERRIDES' and space.lib_override_view_mode == 'HIERARCHIES':
|
||||
filter_text_supported = False
|
||||
|
||||
if filter_text_supported:
|
||||
col = layout.column(align=True)
|
||||
col.label(text="Search")
|
||||
col.prop(space, "use_filter_complete", text="Exact Match")
|
||||
col.prop(space, "use_filter_case_sensitive", text="Case Sensitive")
|
||||
|
||||
if display_mode == 'LIBRARY_OVERRIDES' and space.lib_override_view_mode == 'PROPERTIES' and bpy.data.libraries:
|
||||
col.separator()
|
||||
row = col.row()
|
||||
row = layout.row()
|
||||
row.label(icon='LIBRARY_DATA_OVERRIDE')
|
||||
row.prop(space, "use_filter_lib_override_system", text="System Overrides")
|
||||
|
||||
|
|
|
@ -640,7 +640,6 @@ enum {
|
|||
CD_FAKE_CREASE = CD_FAKE | CD_CREASE, /* *sigh*. */
|
||||
|
||||
/* Multiple types of mesh elements... */
|
||||
CD_FAKE_BWEIGHT = CD_FAKE | CD_BWEIGHT, /* *sigh*. */
|
||||
CD_FAKE_UV = CD_FAKE |
|
||||
CD_MLOOPUV, /* UV flag, because we handle both loop's UVs and poly's textures. */
|
||||
|
||||
|
|
|
@ -52,14 +52,22 @@ struct bDeformGroup *BKE_object_defgroup_find_name(const struct Object *ob, cons
|
|||
/**
|
||||
* \note caller must free.
|
||||
*/
|
||||
int *BKE_object_defgroup_flip_map(const struct Object *ob, int *flip_map_len, bool use_default);
|
||||
int *BKE_object_defgroup_flip_map(const struct Object *ob, bool use_default, int *r_flip_map_num);
|
||||
|
||||
/**
|
||||
* Returns flip map for only unlocked defgroups.
|
||||
* \note caller must free.
|
||||
*/
|
||||
int *BKE_object_defgroup_flip_map_unlocked(const struct Object *ob,
|
||||
bool use_default,
|
||||
int *r_flip_map_num);
|
||||
/**
|
||||
* \note caller must free.
|
||||
*/
|
||||
int *BKE_object_defgroup_flip_map_single(const struct Object *ob,
|
||||
int *flip_map_len,
|
||||
bool use_default,
|
||||
int defgroup);
|
||||
int defgroup,
|
||||
int *r_flip_map_num);
|
||||
int BKE_object_defgroup_flip_index(const struct Object *ob, int index, bool use_default);
|
||||
int BKE_object_defgroup_name_index(const struct Object *ob, const char *name);
|
||||
void BKE_object_defgroup_unique_name(struct bDeformGroup *dg, struct Object *ob);
|
||||
|
@ -112,7 +120,7 @@ float BKE_defvert_array_find_weight_safe(const struct MDeformVert *dvert, int in
|
|||
* \return The total weight in all groups marked in the selection mask.
|
||||
*/
|
||||
float BKE_defvert_total_selected_weight(const struct MDeformVert *dv,
|
||||
int defbase_tot,
|
||||
int defbase_num,
|
||||
const bool *defbase_sel);
|
||||
|
||||
/**
|
||||
|
@ -124,9 +132,9 @@ float BKE_defvert_total_selected_weight(const struct MDeformVert *dv,
|
|||
* commutative with the collective weight function.
|
||||
*/
|
||||
float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv,
|
||||
int defbase_tot,
|
||||
int defbase_num,
|
||||
const bool *defbase_sel,
|
||||
int defbase_tot_sel,
|
||||
int defbase_sel_num,
|
||||
bool is_normalized);
|
||||
|
||||
/* This much unlocked weight is considered equivalent to none. */
|
||||
|
@ -147,7 +155,7 @@ float BKE_defvert_calc_lock_relative_weight(float weight,
|
|||
*/
|
||||
float BKE_defvert_lock_relative_weight(float weight,
|
||||
const struct MDeformVert *dv,
|
||||
int defbase_tot,
|
||||
int defbase_num,
|
||||
const bool *defbase_locked,
|
||||
const bool *defbase_unlocked);
|
||||
|
||||
|
@ -160,7 +168,7 @@ void BKE_defvert_copy(struct MDeformVert *dvert_dst, const struct MDeformVert *d
|
|||
void BKE_defvert_copy_subset(struct MDeformVert *dvert_dst,
|
||||
const struct MDeformVert *dvert_src,
|
||||
const bool *vgroup_subset,
|
||||
int vgroup_tot);
|
||||
int vgroup_num);
|
||||
/**
|
||||
* Overwrite weights filtered by vgroup_subset and with mirroring specified by the flip map
|
||||
* - do nothing if neither are set.
|
||||
|
@ -169,9 +177,9 @@ void BKE_defvert_copy_subset(struct MDeformVert *dvert_dst,
|
|||
void BKE_defvert_mirror_subset(struct MDeformVert *dvert_dst,
|
||||
const struct MDeformVert *dvert_src,
|
||||
const bool *vgroup_subset,
|
||||
int vgroup_tot,
|
||||
int vgroup_num,
|
||||
const int *flip_map,
|
||||
int flip_map_len);
|
||||
int flip_map_num);
|
||||
/**
|
||||
* Copy an index from one #MDeformVert to another.
|
||||
* - do nothing if neither are set.
|
||||
|
@ -194,43 +202,43 @@ void BKE_defvert_sync(struct MDeformVert *dvert_dst,
|
|||
void BKE_defvert_sync_mapped(struct MDeformVert *dvert_dst,
|
||||
const struct MDeformVert *dvert_src,
|
||||
const int *flip_map,
|
||||
int flip_map_len,
|
||||
int flip_map_num,
|
||||
bool use_ensure);
|
||||
/**
|
||||
* be sure all flip_map values are valid
|
||||
*/
|
||||
void BKE_defvert_remap(struct MDeformVert *dvert, const int *map, int map_len);
|
||||
void BKE_defvert_flip(struct MDeformVert *dvert, const int *flip_map, int flip_map_len);
|
||||
void BKE_defvert_flip_merged(struct MDeformVert *dvert, const int *flip_map, int flip_map_len);
|
||||
void BKE_defvert_flip(struct MDeformVert *dvert, const int *flip_map, int flip_map_num);
|
||||
void BKE_defvert_flip_merged(struct MDeformVert *dvert, const int *flip_map, int flip_map_num);
|
||||
void BKE_defvert_normalize(struct MDeformVert *dvert);
|
||||
/**
|
||||
* Same as #BKE_defvert_normalize but takes a bool array.
|
||||
*/
|
||||
void BKE_defvert_normalize_subset(struct MDeformVert *dvert,
|
||||
const bool *vgroup_subset,
|
||||
int vgroup_tot);
|
||||
int vgroup_num);
|
||||
/**
|
||||
* Same as BKE_defvert_normalize() if the locked vgroup is not a member of the subset
|
||||
*/
|
||||
void BKE_defvert_normalize_lock_single(struct MDeformVert *dvert,
|
||||
const bool *vgroup_subset,
|
||||
int vgroup_tot,
|
||||
int vgroup_num,
|
||||
uint def_nr_lock);
|
||||
/**
|
||||
* Same as BKE_defvert_normalize() if no locked vgroup is a member of the subset
|
||||
*/
|
||||
void BKE_defvert_normalize_lock_map(struct MDeformVert *dvert,
|
||||
const bool *vgroup_subset,
|
||||
int vgroup_tot,
|
||||
int vgroup_num,
|
||||
const bool *lock_flags,
|
||||
int defbase_tot);
|
||||
int defbase_num);
|
||||
|
||||
/* Utilities to 'extract' a given vgroup into a simple float array,
|
||||
* for verts, but also edges/polys/loops. */
|
||||
|
||||
void BKE_defvert_extract_vgroup_to_vertweights(const struct MDeformVert *dvert,
|
||||
int defgroup,
|
||||
int num_verts,
|
||||
int verts_num,
|
||||
bool invert_vgroup,
|
||||
float *r_weights);
|
||||
/**
|
||||
|
@ -239,25 +247,25 @@ void BKE_defvert_extract_vgroup_to_vertweights(const struct MDeformVert *dvert,
|
|||
*/
|
||||
void BKE_defvert_extract_vgroup_to_edgeweights(const struct MDeformVert *dvert,
|
||||
int defgroup,
|
||||
int num_verts,
|
||||
int verts_num,
|
||||
const struct MEdge *edges,
|
||||
int num_edges,
|
||||
int edges_num,
|
||||
bool invert_vgroup,
|
||||
float *r_weights);
|
||||
void BKE_defvert_extract_vgroup_to_loopweights(const struct MDeformVert *dvert,
|
||||
int defgroup,
|
||||
int num_verts,
|
||||
int verts_num,
|
||||
const struct MLoop *loops,
|
||||
int num_loops,
|
||||
int loops_num,
|
||||
bool invert_vgroup,
|
||||
float *r_weights);
|
||||
void BKE_defvert_extract_vgroup_to_polyweights(const struct MDeformVert *dvert,
|
||||
int defgroup,
|
||||
int num_verts,
|
||||
int verts_num,
|
||||
const struct MLoop *loops,
|
||||
int num_loops,
|
||||
int loops_num,
|
||||
const struct MPoly *polys,
|
||||
int num_polys,
|
||||
int polys_num,
|
||||
bool invert_vgroup,
|
||||
float *r_weights);
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ typedef void (*IDTypeForeachCacheFunction)(struct ID *id,
|
|||
|
||||
typedef void (*IDTypeForeachPathFunction)(struct ID *id, struct BPathForeachPathData *bpath_data);
|
||||
|
||||
typedef struct ID *(*IDTypeEmbeddedOwnerGetFunction)(struct ID *id);
|
||||
typedef struct ID **(*IDTypeEmbeddedOwnerPointerGetFunction)(struct ID *id);
|
||||
|
||||
typedef void (*IDTypeBlendWriteFunction)(struct BlendWriter *writer,
|
||||
struct ID *id,
|
||||
|
@ -180,9 +180,9 @@ typedef struct IDTypeInfo {
|
|||
IDTypeForeachPathFunction foreach_path;
|
||||
|
||||
/**
|
||||
* For embedded IDs, return their owner ID.
|
||||
* For embedded IDs, return the address of the pointer to their owner ID.
|
||||
*/
|
||||
IDTypeEmbeddedOwnerGetFunction owner_get;
|
||||
IDTypeEmbeddedOwnerPointerGetFunction owner_pointer_get;
|
||||
|
||||
/* ********** Callbacks for reading and writing .blend files. ********** */
|
||||
|
||||
|
|
|
@ -95,6 +95,9 @@ struct KeyBlock *BKE_keyblock_from_key(struct Key *key, int index);
|
|||
* Get the appropriate #KeyBlock given a name to search for.
|
||||
*/
|
||||
struct KeyBlock *BKE_keyblock_find_name(struct Key *key, const char name[]);
|
||||
|
||||
struct KeyBlock *BKE_keyblock_find_uid(struct Key *key, int uid);
|
||||
|
||||
/**
|
||||
* \brief copy shape-key attributes, but not key data or name/UID.
|
||||
*/
|
||||
|
|
|
@ -245,8 +245,8 @@ void BKE_layer_collection_set_flag(struct LayerCollection *lc, int flag, bool va
|
|||
|
||||
/**
|
||||
* Applies object's restrict flags on top of flags coming from the collection
|
||||
* and stores those in `base->flag`. #BASE_VISIBLE_DEPSGRAPH ignores viewport flags visibility
|
||||
* (i.e., restriction and local collection).
|
||||
* and stores those in `base->flag`. #BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT ignores viewport
|
||||
* flags visibility (i.e., restriction and local collection).
|
||||
*/
|
||||
void BKE_base_eval_flags(struct Base *base);
|
||||
|
||||
|
|
|
@ -620,6 +620,13 @@ bool BKE_id_is_in_global_main(struct ID *id);
|
|||
|
||||
bool BKE_id_can_be_asset(const struct ID *id);
|
||||
|
||||
/**
|
||||
* Return the owner ID of the given `id`, if any.
|
||||
*
|
||||
* \note This will only return non-NULL for embedded IDs (master collections etc.), and shape-keys.
|
||||
*/
|
||||
struct ID *BKE_id_owner_get(struct ID *id);
|
||||
|
||||
/** Check if that ID can be considered as editable from a high-level (editor) perspective.
|
||||
*
|
||||
* NOTE: This used to be done with a check on whether ID was linked or not, but now with system
|
||||
|
|
|
@ -292,13 +292,10 @@ struct Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
|
|||
bool build_shapekey_layers);
|
||||
|
||||
/**
|
||||
* Copies a nomain-Mesh into an existing Mesh.
|
||||
* Move data from a mesh outside of the main data-base into a mesh in the data-base.
|
||||
* Takes ownership of the source mesh.
|
||||
*/
|
||||
void BKE_mesh_nomain_to_mesh(struct Mesh *mesh_src,
|
||||
struct Mesh *mesh_dst,
|
||||
struct Object *ob,
|
||||
const struct CustomData_MeshMasks *mask,
|
||||
bool take_ownership);
|
||||
void BKE_mesh_nomain_to_mesh(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct Object *ob);
|
||||
void BKE_mesh_nomain_to_meshkey(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct KeyBlock *kb);
|
||||
|
||||
/* vertex level transformations & checks (no derived mesh) */
|
||||
|
|
|
@ -17,6 +17,15 @@ struct CustomData;
|
|||
struct Mesh;
|
||||
struct MFace;
|
||||
|
||||
/**
|
||||
* Copy bevel weights from separate layers into vertices and edges.
|
||||
*/
|
||||
void BKE_mesh_legacy_bevel_weight_from_layers(struct Mesh *mesh);
|
||||
/**
|
||||
* Copy bevel weights from vertices and edges to separate layers.
|
||||
*/
|
||||
void BKE_mesh_legacy_bevel_weight_to_layers(struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Convert the hidden element attributes to the old flag format for writing.
|
||||
*/
|
||||
|
|
|
@ -1337,15 +1337,6 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
|
|||
#define CMP_CHAN_RGB 1
|
||||
#define CMP_CHAN_A 2
|
||||
|
||||
/* scale node type, in custom1 */
|
||||
#define CMP_SCALE_RELATIVE 0
|
||||
#define CMP_SCALE_ABSOLUTE 1
|
||||
#define CMP_SCALE_SCENEPERCENT 2
|
||||
#define CMP_SCALE_RENDERPERCENT 3
|
||||
/* custom2 */
|
||||
#define CMP_SCALE_RENDERSIZE_FRAME_ASPECT (1 << 0)
|
||||
#define CMP_SCALE_RENDERSIZE_FRAME_CROP (1 << 1)
|
||||
|
||||
/* track position node, in custom1 */
|
||||
#define CMP_TRACKPOS_ABSOLUTE 0
|
||||
#define CMP_TRACKPOS_RELATIVE_START 1
|
||||
|
|
|
@ -14,7 +14,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct Mesh;
|
||||
struct MeshElemMap;
|
||||
struct MEdge;
|
||||
struct MVert;
|
||||
struct Subdiv;
|
||||
|
||||
typedef struct SubdivToMeshSettings {
|
||||
|
@ -37,8 +39,10 @@ struct Mesh *BKE_subdiv_to_mesh(struct Subdiv *subdiv,
|
|||
/* Interpolate a position along the `coarse_edge` at the relative `u` coordinate. If `is_simple` is
|
||||
* false, this will perform a B-Spline interpolation using the edge neighbors, otherwise a linear
|
||||
* interpolation will be done base on the edge vertices. */
|
||||
void BKE_subdiv_mesh_interpolate_position_on_edge(const struct Mesh *coarse_mesh,
|
||||
const struct MEdge *coarse_edge,
|
||||
void BKE_subdiv_mesh_interpolate_position_on_edge(const struct MVert *coarse_verts,
|
||||
const struct MEdge *coarse_edges,
|
||||
const struct MeshElemMap *vert_to_edge_map,
|
||||
int coarse_edge_index,
|
||||
bool is_simple,
|
||||
float u,
|
||||
float pos_r[3]);
|
||||
|
|
|
@ -659,6 +659,10 @@ if(WITH_PYTHON)
|
|||
)
|
||||
add_definitions(-DWITH_PYTHON)
|
||||
|
||||
if(WITH_PYTHON_MODULE)
|
||||
add_definitions(-DWITH_PYTHON_MODULE)
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON_SAFETY)
|
||||
add_definitions(-DWITH_PYTHON_SAFETY)
|
||||
endif()
|
||||
|
|
|
@ -315,7 +315,7 @@ IDTypeInfo IDType_ID_AC = {
|
|||
.foreach_id = action_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = action_blend_write,
|
||||
.blend_read_data = action_blend_read_data,
|
||||
|
|
|
@ -374,7 +374,7 @@ static bool get_path_local_ex(char *targetpath,
|
|||
/* Try `{g_app.program_dirname}/2.xx/{folder_name}` the default directory
|
||||
* for a portable distribution. See `WITH_INSTALL_PORTABLE` build-option. */
|
||||
const char *path_base = g_app.program_dirname;
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
|
||||
/* Due new code-sign situation in OSX > 10.9.5
|
||||
* we must move the blender_version dir with contents to Resources. */
|
||||
char osx_resourses[FILE_MAX];
|
||||
|
@ -782,6 +782,7 @@ const char *BKE_appdir_folder_id_version(const int folder_id,
|
|||
* Access locations of Blender & Python.
|
||||
* \{ */
|
||||
|
||||
#ifndef WITH_PYTHON_MODULE
|
||||
/**
|
||||
* Checks if name is a fully qualified filename to an executable.
|
||||
* If not it searches `$PATH` for the file. On Windows it also
|
||||
|
@ -796,7 +797,7 @@ const char *BKE_appdir_folder_id_version(const int folder_id,
|
|||
*/
|
||||
static void where_am_i(char *fullname, const size_t maxlen, const char *name)
|
||||
{
|
||||
#ifdef WITH_BINRELOC
|
||||
# ifdef WITH_BINRELOC
|
||||
/* Linux uses `binreloc` since `argv[0]` is not reliable, call `br_init(NULL)` first. */
|
||||
{
|
||||
const char *path = NULL;
|
||||
|
@ -807,9 +808,9 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef _WIN32
|
||||
{
|
||||
wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath");
|
||||
if (GetModuleFileNameW(0, fullname_16, maxlen)) {
|
||||
|
@ -825,7 +826,7 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name)
|
|||
|
||||
MEM_freeN(fullname_16);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
/* Unix and non Linux. */
|
||||
if (name && name[0]) {
|
||||
|
@ -833,16 +834,16 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name)
|
|||
BLI_strncpy(fullname, name, maxlen);
|
||||
if (name[0] == '.') {
|
||||
BLI_path_abs_from_cwd(fullname, maxlen);
|
||||
#ifdef _WIN32
|
||||
# ifdef _WIN32
|
||||
BLI_path_program_extensions_add_win32(fullname, maxlen);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
else if (BLI_path_slash_rfind(name)) {
|
||||
/* Full path. */
|
||||
BLI_strncpy(fullname, name, maxlen);
|
||||
#ifdef _WIN32
|
||||
# ifdef _WIN32
|
||||
BLI_path_program_extensions_add_win32(fullname, maxlen);
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
else {
|
||||
BLI_path_program_search(fullname, maxlen, name);
|
||||
|
@ -850,23 +851,43 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name)
|
|||
/* Remove "/./" and "/../" so string comparisons can be used on the path. */
|
||||
BLI_path_normalize(NULL, fullname);
|
||||
|
||||
#if defined(DEBUG)
|
||||
# if defined(DEBUG)
|
||||
if (!STREQ(name, fullname)) {
|
||||
CLOG_INFO(&LOG, 2, "guessing '%s' == '%s'", name, fullname);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
}
|
||||
#endif /* WITH_PYTHON_MODULE */
|
||||
|
||||
void BKE_appdir_program_path_init(const char *argv0)
|
||||
{
|
||||
#ifdef WITH_PYTHON_MODULE
|
||||
/* NOTE(@campbellbarton): Always use `argv[0]` as is, when building as a Python module.
|
||||
* Otherwise other methods of detecting the binary that override this argument
|
||||
* which must point to the Python module for data-files to be detected. */
|
||||
STRNCPY(g_app.program_filepath, argv0);
|
||||
BLI_path_abs_from_cwd(g_app.program_filepath, sizeof(g_app.program_filepath));
|
||||
BLI_path_normalize(NULL, g_app.program_filepath);
|
||||
|
||||
if (g_app.program_dirname[0] == '\0') {
|
||||
/* First time initializing, the file binary path isn't valid from a Python module.
|
||||
* Calling again must set the `filepath` and leave the directory as-is. */
|
||||
BLI_split_dir_part(
|
||||
g_app.program_filepath, g_app.program_dirname, sizeof(g_app.program_dirname));
|
||||
g_app.program_filepath[0] = '\0';
|
||||
}
|
||||
#else
|
||||
where_am_i(g_app.program_filepath, sizeof(g_app.program_filepath), argv0);
|
||||
BLI_split_dir_part(g_app.program_filepath, g_app.program_dirname, sizeof(g_app.program_dirname));
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *BKE_appdir_program_path(void)
|
||||
{
|
||||
#ifndef WITH_PYTHON_MODULE /* Default's to empty when building as as Python module. */
|
||||
BLI_assert(g_app.program_filepath[0]);
|
||||
#endif
|
||||
return g_app.program_filepath;
|
||||
}
|
||||
|
||||
|
|
|
@ -313,7 +313,7 @@ IDTypeInfo IDType_ID_AR = {
|
|||
.foreach_id = armature_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = armature_blend_write,
|
||||
.blend_read_data = armature_blend_read_data,
|
||||
|
|
|
@ -413,7 +413,7 @@ IDTypeInfo IDType_ID_BR = {
|
|||
/* foreach_id */ brush_foreach_id,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ brush_foreach_path,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ brush_blend_write,
|
||||
/* blend_read_data */ brush_blend_read_data,
|
||||
|
|
|
@ -146,7 +146,7 @@ IDTypeInfo IDType_ID_CF = {
|
|||
.foreach_id = NULL,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = cache_file_foreach_path,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = cache_file_blend_write,
|
||||
.blend_read_data = cache_file_blend_read_data,
|
||||
|
|
|
@ -186,7 +186,7 @@ IDTypeInfo IDType_ID_CA = {
|
|||
.foreach_id = camera_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = camera_blend_write,
|
||||
.blend_read_data = camera_blend_read_data,
|
||||
|
|
|
@ -169,10 +169,10 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data)
|
|||
}
|
||||
}
|
||||
|
||||
static ID *collection_owner_get(ID *id)
|
||||
static ID **collection_owner_pointer_get(ID *id)
|
||||
{
|
||||
if ((id->flag & LIB_EMBEDDED_DATA) == 0) {
|
||||
return id;
|
||||
return NULL;
|
||||
}
|
||||
BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0);
|
||||
|
||||
|
@ -182,7 +182,7 @@ static ID *collection_owner_get(ID *id)
|
|||
BLI_assert(GS(master_collection->owner_id->name) == ID_SCE);
|
||||
BLI_assert(((Scene *)master_collection->owner_id)->master_collection == master_collection);
|
||||
|
||||
return master_collection->owner_id;
|
||||
return &master_collection->owner_id;
|
||||
}
|
||||
|
||||
void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection)
|
||||
|
@ -234,8 +234,13 @@ void BKE_collection_compat_blend_read_data(BlendDataReader *reader, SceneCollect
|
|||
void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collection, ID *owner_id)
|
||||
{
|
||||
/* Special case for this pointer, do not rely on regular `lib_link` process here. Avoids needs
|
||||
* for do_versioning, and ensures coherence of data in any case. */
|
||||
BLI_assert((collection->id.flag & LIB_EMBEDDED_DATA) != 0 || owner_id == NULL);
|
||||
* for do_versioning, and ensures coherence of data in any case.
|
||||
*
|
||||
* NOTE: Old versions are very often 'broken' here, just fix it silently in these cases.
|
||||
*/
|
||||
if (BLO_read_fileversion_get(reader) > 300) {
|
||||
BLI_assert((collection->id.flag & LIB_EMBEDDED_DATA) != 0 || owner_id == NULL);
|
||||
}
|
||||
BLI_assert(owner_id == NULL || owner_id->lib == collection->id.lib);
|
||||
if (owner_id != NULL && (collection->id.flag & LIB_EMBEDDED_DATA) == 0) {
|
||||
/* This is unfortunate, but currently a lot of existing files (including startup ones) have
|
||||
|
@ -244,11 +249,13 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
|
|||
* NOTE: Using do_version is not a solution here, since this code will be called before any
|
||||
* do_version takes place. Keeping it here also ensures future (or unknown existing) similar
|
||||
* bugs won't go easily unnoticed. */
|
||||
CLOG_WARN(&LOG,
|
||||
"Fixing root node tree '%s' owned by '%s' missing EMBEDDED tag, please consider "
|
||||
"re-saving your (startup) file",
|
||||
collection->id.name,
|
||||
owner_id->name);
|
||||
if (BLO_read_fileversion_get(reader) > 300) {
|
||||
CLOG_WARN(&LOG,
|
||||
"Fixing root node tree '%s' owned by '%s' missing EMBEDDED tag, please consider "
|
||||
"re-saving your (startup) file",
|
||||
collection->id.name,
|
||||
owner_id->name);
|
||||
}
|
||||
collection->id.flag |= LIB_EMBEDDED_DATA;
|
||||
}
|
||||
collection->owner_id = owner_id;
|
||||
|
@ -393,7 +400,7 @@ IDTypeInfo IDType_ID_GR = {
|
|||
.foreach_id = collection_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = collection_owner_get,
|
||||
.owner_pointer_get = collection_owner_pointer_get,
|
||||
|
||||
.blend_write = collection_blend_write,
|
||||
.blend_read_data = collection_blend_read_data,
|
||||
|
|
|
@ -321,7 +321,7 @@ IDTypeInfo IDType_ID_CU_LEGACY = {
|
|||
/* foreach_id */ curve_foreach_id,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ nullptr,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ curve_blend_write,
|
||||
/* blend_read_data */ curve_blend_read_data,
|
||||
|
|
|
@ -216,7 +216,7 @@ IDTypeInfo IDType_ID_CV = {
|
|||
/* foreach_id */ curves_foreach_id,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ nullptr,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ curves_blend_write,
|
||||
/* blend_read_data */ curves_blend_read_data,
|
||||
|
|
|
@ -1867,7 +1867,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
|||
/* 28: CD_SHAPEKEY */
|
||||
{sizeof(float[3]), "", 0, N_("ShapeKey"), nullptr, nullptr, layerInterp_shapekey},
|
||||
/* 29: CD_BWEIGHT */
|
||||
{sizeof(float), "", 0, N_("BevelWeight"), nullptr, nullptr, layerInterp_bweight},
|
||||
{sizeof(MFloatProperty), "MFloatProperty", 1, nullptr, nullptr, nullptr, layerInterp_bweight},
|
||||
/* 30: CD_CREASE */
|
||||
/* NOTE: we do not interpolate crease data as it should be either inherited for subdivided
|
||||
* edges, or for vertex creases, only present on the original vertex. */
|
||||
|
@ -2108,23 +2108,23 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
|
|||
};
|
||||
|
||||
const CustomData_MeshMasks CD_MASK_BAREMESH = {
|
||||
/* vmask */ CD_MASK_MVERT | CD_MASK_BWEIGHT,
|
||||
/* emask */ CD_MASK_MEDGE | CD_MASK_BWEIGHT,
|
||||
/* vmask */ CD_MASK_MVERT,
|
||||
/* emask */ CD_MASK_MEDGE,
|
||||
/* fmask */ 0,
|
||||
/* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP,
|
||||
/* lmask */ CD_MASK_MLOOP,
|
||||
};
|
||||
const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = {
|
||||
/* vmask */ CD_MASK_MVERT | CD_MASK_BWEIGHT | CD_MASK_ORIGINDEX,
|
||||
/* emask */ CD_MASK_MEDGE | CD_MASK_BWEIGHT | CD_MASK_ORIGINDEX,
|
||||
/* vmask */ CD_MASK_MVERT | CD_MASK_ORIGINDEX,
|
||||
/* emask */ CD_MASK_MEDGE | CD_MASK_ORIGINDEX,
|
||||
/* fmask */ 0,
|
||||
/* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_ORIGINDEX,
|
||||
/* lmask */ CD_MASK_MLOOP,
|
||||
};
|
||||
const CustomData_MeshMasks CD_MASK_MESH = {
|
||||
/* vmask */ (CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK |
|
||||
CD_MASK_PROP_ALL | CD_MASK_CREASE),
|
||||
/* emask */ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL),
|
||||
CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_BWEIGHT),
|
||||
/* emask */ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_BWEIGHT),
|
||||
/* fmask */ 0,
|
||||
/* pmask */
|
||||
(CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL |
|
||||
|
@ -2136,8 +2136,8 @@ const CustomData_MeshMasks CD_MASK_MESH = {
|
|||
const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
|
||||
/* vmask */ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN |
|
||||
CD_MASK_PAINT_MASK | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL |
|
||||
CD_MASK_CREASE),
|
||||
/* emask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL),
|
||||
CD_MASK_CREASE | CD_MASK_BWEIGHT),
|
||||
/* emask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_BWEIGHT | CD_MASK_PROP_ALL),
|
||||
/* fmask */ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT),
|
||||
/* pmask */
|
||||
(CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL |
|
||||
|
@ -2353,8 +2353,16 @@ bool CustomData_merge(const CustomData *source,
|
|||
changed = true;
|
||||
|
||||
if (layer->anonymous_id != nullptr) {
|
||||
BKE_anonymous_attribute_id_increment_weak(layer->anonymous_id);
|
||||
newlayer->anonymous_id = layer->anonymous_id;
|
||||
if (alloctype == CD_ASSIGN) {
|
||||
layer->anonymous_id = nullptr;
|
||||
}
|
||||
else {
|
||||
BKE_anonymous_attribute_id_increment_weak(layer->anonymous_id);
|
||||
}
|
||||
}
|
||||
if (alloctype == CD_ASSIGN) {
|
||||
layer->data = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5174,7 +5182,7 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap,
|
|||
else {
|
||||
const LayerTypeInfo *type_info = layerType_getInfo(data_type);
|
||||
|
||||
/* NOTE: we can use 'fake' CDLayers, like e.g. for crease, bweight, etc. :/. */
|
||||
/* NOTE: we can use 'fake' CDLayers for crease :/. */
|
||||
data_size = (size_t)type_info->size;
|
||||
data_step = laymap->elem_size ? laymap->elem_size : data_size;
|
||||
data_offset = laymap->data_offset;
|
||||
|
|
|
@ -192,7 +192,7 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
|
|||
case DT_TYPE_SKIN:
|
||||
return CD_MVERT_SKIN;
|
||||
case DT_TYPE_BWEIGHT_VERT:
|
||||
return CD_FAKE_BWEIGHT;
|
||||
return CD_BWEIGHT;
|
||||
|
||||
case DT_TYPE_SHARP_EDGE:
|
||||
return CD_FAKE_SHARP;
|
||||
|
@ -201,7 +201,7 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
|
|||
case DT_TYPE_CREASE:
|
||||
return CD_FAKE_CREASE;
|
||||
case DT_TYPE_BWEIGHT_EDGE:
|
||||
return CD_FAKE_BWEIGHT;
|
||||
return CD_BWEIGHT;
|
||||
case DT_TYPE_FREESTYLE_EDGE:
|
||||
return CD_FREESTYLE_EDGE;
|
||||
|
||||
|
@ -928,38 +928,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
|
|||
}
|
||||
return true;
|
||||
}
|
||||
if (cddata_type == CD_FAKE_BWEIGHT) {
|
||||
const size_t elem_size = sizeof(*((MVert *)NULL));
|
||||
const size_t data_size = sizeof(((MVert *)NULL)->bweight);
|
||||
const size_t data_offset = offsetof(MVert, bweight);
|
||||
const uint64_t data_flag = 0;
|
||||
|
||||
if (!(me_src->cd_flag & ME_CDFLAG_VERT_BWEIGHT)) {
|
||||
if (use_delete) {
|
||||
me_dst->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
me_dst->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
|
||||
if (r_map) {
|
||||
data_transfer_layersmapping_add_item(r_map,
|
||||
cddata_type,
|
||||
mix_mode,
|
||||
mix_factor,
|
||||
mix_weights,
|
||||
BKE_mesh_verts(me_src),
|
||||
BKE_mesh_verts_for_write(me_dst),
|
||||
me_src->totvert,
|
||||
me_dst->totvert,
|
||||
elem_size,
|
||||
data_size,
|
||||
data_offset,
|
||||
data_flag,
|
||||
data_transfer_interp_char,
|
||||
interp_data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (cddata_type == CD_FAKE_MDEFORMVERT) {
|
||||
bool ret;
|
||||
|
||||
|
@ -1045,38 +1013,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
|
|||
}
|
||||
return true;
|
||||
}
|
||||
if (cddata_type == CD_FAKE_BWEIGHT) {
|
||||
const size_t elem_size = sizeof(*((MEdge *)NULL));
|
||||
const size_t data_size = sizeof(((MEdge *)NULL)->bweight);
|
||||
const size_t data_offset = offsetof(MEdge, bweight);
|
||||
const uint64_t data_flag = 0;
|
||||
|
||||
if (!(me_src->cd_flag & ME_CDFLAG_EDGE_BWEIGHT)) {
|
||||
if (use_delete) {
|
||||
me_dst->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
me_dst->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
|
||||
if (r_map) {
|
||||
data_transfer_layersmapping_add_item(r_map,
|
||||
cddata_type,
|
||||
mix_mode,
|
||||
mix_factor,
|
||||
mix_weights,
|
||||
BKE_mesh_edges(me_src),
|
||||
BKE_mesh_edges_for_write(me_dst),
|
||||
me_src->totedge,
|
||||
me_dst->totedge,
|
||||
elem_size,
|
||||
data_size,
|
||||
data_offset,
|
||||
data_flag,
|
||||
data_transfer_interp_char,
|
||||
interp_data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) {
|
||||
const size_t elem_size = sizeof(*((MEdge *)NULL));
|
||||
const size_t data_size = sizeof(((MEdge *)NULL)->flag);
|
||||
|
|
|
@ -94,10 +94,10 @@ bDeformGroup *BKE_defgroup_duplicate(const bDeformGroup *ingroup)
|
|||
void BKE_defvert_copy_subset(MDeformVert *dvert_dst,
|
||||
const MDeformVert *dvert_src,
|
||||
const bool *vgroup_subset,
|
||||
const int vgroup_tot)
|
||||
const int vgroup_num)
|
||||
{
|
||||
int defgroup;
|
||||
for (defgroup = 0; defgroup < vgroup_tot; defgroup++) {
|
||||
for (defgroup = 0; defgroup < vgroup_num; defgroup++) {
|
||||
if (vgroup_subset[defgroup]) {
|
||||
BKE_defvert_copy_index(dvert_dst, defgroup, dvert_src, defgroup);
|
||||
}
|
||||
|
@ -107,12 +107,12 @@ void BKE_defvert_copy_subset(MDeformVert *dvert_dst,
|
|||
void BKE_defvert_mirror_subset(MDeformVert *dvert_dst,
|
||||
const MDeformVert *dvert_src,
|
||||
const bool *vgroup_subset,
|
||||
const int vgroup_tot,
|
||||
const int vgroup_num,
|
||||
const int *flip_map,
|
||||
const int flip_map_len)
|
||||
const int flip_map_num)
|
||||
{
|
||||
int defgroup;
|
||||
for (defgroup = 0; defgroup < vgroup_tot && defgroup < flip_map_len; defgroup++) {
|
||||
for (defgroup = 0; defgroup < vgroup_num && defgroup < flip_map_num; defgroup++) {
|
||||
if (vgroup_subset[defgroup] && (dvert_dst != dvert_src || flip_map[defgroup] != defgroup)) {
|
||||
BKE_defvert_copy_index(dvert_dst, flip_map[defgroup], dvert_src, defgroup);
|
||||
}
|
||||
|
@ -189,13 +189,13 @@ void BKE_defvert_sync(MDeformVert *dvert_dst, const MDeformVert *dvert_src, cons
|
|||
void BKE_defvert_sync_mapped(MDeformVert *dvert_dst,
|
||||
const MDeformVert *dvert_src,
|
||||
const int *flip_map,
|
||||
const int flip_map_len,
|
||||
const int flip_map_num,
|
||||
const bool use_ensure)
|
||||
{
|
||||
if (dvert_src->totweight && dvert_dst->totweight) {
|
||||
MDeformWeight *dw_src = dvert_src->dw;
|
||||
for (int i = 0; i < dvert_src->totweight; i++, dw_src++) {
|
||||
if (dw_src->def_nr < flip_map_len) {
|
||||
if (dw_src->def_nr < flip_map_num) {
|
||||
MDeformWeight *dw_dst;
|
||||
if (use_ensure) {
|
||||
dw_dst = BKE_defvert_ensure_index(dvert_dst, flip_map[dw_src->def_nr]);
|
||||
|
@ -226,14 +226,14 @@ void BKE_defvert_remap(MDeformVert *dvert, const int *map, const int map_len)
|
|||
|
||||
void BKE_defvert_normalize_subset(MDeformVert *dvert,
|
||||
const bool *vgroup_subset,
|
||||
const int vgroup_tot)
|
||||
const int vgroup_num)
|
||||
{
|
||||
if (dvert->totweight == 0) {
|
||||
/* nothing */
|
||||
}
|
||||
else if (dvert->totweight == 1) {
|
||||
MDeformWeight *dw = dvert->dw;
|
||||
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < vgroup_num) && vgroup_subset[dw->def_nr]) {
|
||||
dw->weight = 1.0f;
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ void BKE_defvert_normalize_subset(MDeformVert *dvert,
|
|||
MDeformWeight *dw = dvert->dw;
|
||||
float tot_weight = 0.0f;
|
||||
for (int i = dvert->totweight; i != 0; i--, dw++) {
|
||||
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < vgroup_num) && vgroup_subset[dw->def_nr]) {
|
||||
tot_weight += dw->weight;
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ void BKE_defvert_normalize_subset(MDeformVert *dvert,
|
|||
float scalar = 1.0f / tot_weight;
|
||||
dw = dvert->dw;
|
||||
for (int i = dvert->totweight; i != 0; i--, dw++) {
|
||||
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < vgroup_num) && vgroup_subset[dw->def_nr]) {
|
||||
dw->weight *= scalar;
|
||||
|
||||
/* in case of division errors with very low weights */
|
||||
|
@ -292,7 +292,7 @@ void BKE_defvert_normalize(MDeformVert *dvert)
|
|||
|
||||
void BKE_defvert_normalize_lock_single(MDeformVert *dvert,
|
||||
const bool *vgroup_subset,
|
||||
const int vgroup_tot,
|
||||
const int vgroup_num,
|
||||
const uint def_nr_lock)
|
||||
{
|
||||
if (dvert->totweight == 0) {
|
||||
|
@ -300,7 +300,7 @@ void BKE_defvert_normalize_lock_single(MDeformVert *dvert,
|
|||
}
|
||||
else if (dvert->totweight == 1) {
|
||||
MDeformWeight *dw = dvert->dw;
|
||||
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < vgroup_num) && vgroup_subset[dw->def_nr]) {
|
||||
if (def_nr_lock != dw->def_nr) {
|
||||
dw->weight = 1.0f;
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ void BKE_defvert_normalize_lock_single(MDeformVert *dvert,
|
|||
float lock_iweight = 1.0f;
|
||||
|
||||
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
|
||||
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < vgroup_num) && vgroup_subset[dw->def_nr]) {
|
||||
if (dw->def_nr != def_nr_lock) {
|
||||
tot_weight += dw->weight;
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ void BKE_defvert_normalize_lock_single(MDeformVert *dvert,
|
|||
|
||||
float scalar = (1.0f / tot_weight) * lock_iweight;
|
||||
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
|
||||
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < vgroup_num) && vgroup_subset[dw->def_nr]) {
|
||||
if (dw != dw_lock) {
|
||||
dw->weight *= scalar;
|
||||
|
||||
|
@ -346,17 +346,17 @@ void BKE_defvert_normalize_lock_single(MDeformVert *dvert,
|
|||
|
||||
void BKE_defvert_normalize_lock_map(MDeformVert *dvert,
|
||||
const bool *vgroup_subset,
|
||||
const int vgroup_tot,
|
||||
const int vgroup_num,
|
||||
const bool *lock_flags,
|
||||
const int defbase_tot)
|
||||
const int defbase_num)
|
||||
{
|
||||
if (dvert->totweight == 0) {
|
||||
/* nothing */
|
||||
}
|
||||
else if (dvert->totweight == 1) {
|
||||
MDeformWeight *dw = dvert->dw;
|
||||
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
|
||||
if ((dw->def_nr < vgroup_num) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < defbase_num) && (lock_flags[dw->def_nr] == false)) {
|
||||
dw->weight = 1.0f;
|
||||
}
|
||||
}
|
||||
|
@ -368,8 +368,8 @@ void BKE_defvert_normalize_lock_map(MDeformVert *dvert,
|
|||
float lock_iweight = 0.0f;
|
||||
|
||||
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
|
||||
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
|
||||
if ((dw->def_nr < vgroup_num) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < defbase_num) && (lock_flags[dw->def_nr] == false)) {
|
||||
tot_weight += dw->weight;
|
||||
}
|
||||
else {
|
||||
|
@ -386,8 +386,8 @@ void BKE_defvert_normalize_lock_map(MDeformVert *dvert,
|
|||
|
||||
float scalar = (1.0f / tot_weight) * lock_iweight;
|
||||
for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
|
||||
if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == false)) {
|
||||
if ((dw->def_nr < vgroup_num) && vgroup_subset[dw->def_nr]) {
|
||||
if ((dw->def_nr < defbase_num) && (lock_flags[dw->def_nr] == false)) {
|
||||
dw->weight *= scalar;
|
||||
|
||||
/* in case of division errors with very low weights */
|
||||
|
@ -399,13 +399,13 @@ void BKE_defvert_normalize_lock_map(MDeformVert *dvert,
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
|
||||
void BKE_defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_num)
|
||||
{
|
||||
MDeformWeight *dw;
|
||||
int i;
|
||||
|
||||
for (dw = dvert->dw, i = 0; i < dvert->totweight; dw++, i++) {
|
||||
if (dw->def_nr < flip_map_len) {
|
||||
if (dw->def_nr < flip_map_num) {
|
||||
if (flip_map[dw->def_nr] >= 0) {
|
||||
dw->def_nr = flip_map[dw->def_nr];
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ void BKE_defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_ma
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
|
||||
void BKE_defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip_map_num)
|
||||
{
|
||||
MDeformWeight *dw, *dw_cpy;
|
||||
float weight;
|
||||
|
@ -421,7 +421,7 @@ void BKE_defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int
|
|||
|
||||
/* copy weights */
|
||||
for (dw = dvert->dw, i = 0; i < totweight; dw++, i++) {
|
||||
if (dw->def_nr < flip_map_len) {
|
||||
if (dw->def_nr < flip_map_num) {
|
||||
if (flip_map[dw->def_nr] >= 0) {
|
||||
/* error checkers complain of this but we'll never get NULL return */
|
||||
dw_cpy = BKE_defvert_ensure_index(dvert, flip_map[dw->def_nr]);
|
||||
|
@ -572,20 +572,25 @@ void BKE_object_defgroup_active_index_set(Object *ob, const int new_index)
|
|||
*index = new_index;
|
||||
}
|
||||
|
||||
int *BKE_object_defgroup_flip_map(const Object *ob, int *flip_map_len, const bool use_default)
|
||||
static int *object_defgroup_unlocked_flip_map_ex(const Object *ob,
|
||||
const bool use_default,
|
||||
const bool use_only_unlocked,
|
||||
int *r_flip_map_num)
|
||||
{
|
||||
const ListBase *defbase = BKE_object_defgroup_list(ob);
|
||||
int defbase_tot = *flip_map_len = BLI_listbase_count(defbase);
|
||||
const int defbase_num = BLI_listbase_count(defbase);
|
||||
*r_flip_map_num = defbase_num;
|
||||
|
||||
if (defbase_tot == 0) {
|
||||
if (defbase_num == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bDeformGroup *dg;
|
||||
char name_flip[sizeof(dg->name)];
|
||||
int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
|
||||
int i, flip_num;
|
||||
int *map = MEM_mallocN(defbase_num * sizeof(int), __func__);
|
||||
|
||||
for (i = 0; i < defbase_tot; i++) {
|
||||
for (i = 0; i < defbase_num; i++) {
|
||||
map[i] = -1;
|
||||
}
|
||||
|
||||
|
@ -597,11 +602,15 @@ int *BKE_object_defgroup_flip_map(const Object *ob, int *flip_map_len, const boo
|
|||
map[i] = i;
|
||||
}
|
||||
|
||||
if (use_only_unlocked && (dg->flag & DG_LOCK_WEIGHT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
|
||||
|
||||
if (!STREQ(name_flip, dg->name)) {
|
||||
flip_num = BKE_object_defgroup_name_index(ob, name_flip);
|
||||
if (flip_num >= 0) {
|
||||
if (flip_num != -1) {
|
||||
map[i] = flip_num;
|
||||
map[flip_num] = i; /* save an extra lookup */
|
||||
}
|
||||
|
@ -611,23 +620,36 @@ int *BKE_object_defgroup_flip_map(const Object *ob, int *flip_map_len, const boo
|
|||
return map;
|
||||
}
|
||||
|
||||
int *BKE_object_defgroup_flip_map(const Object *ob, const bool use_default, int *r_flip_map_num)
|
||||
{
|
||||
return object_defgroup_unlocked_flip_map_ex(ob, use_default, false, r_flip_map_num);
|
||||
}
|
||||
|
||||
int *BKE_object_defgroup_flip_map_unlocked(const Object *ob,
|
||||
const bool use_default,
|
||||
int *r_flip_map_num)
|
||||
{
|
||||
return object_defgroup_unlocked_flip_map_ex(ob, use_default, true, r_flip_map_num);
|
||||
}
|
||||
|
||||
int *BKE_object_defgroup_flip_map_single(const Object *ob,
|
||||
int *flip_map_len,
|
||||
const bool use_default,
|
||||
int defgroup)
|
||||
const int defgroup,
|
||||
int *r_flip_map_num)
|
||||
{
|
||||
const ListBase *defbase = BKE_object_defgroup_list(ob);
|
||||
int defbase_tot = *flip_map_len = BLI_listbase_count(defbase);
|
||||
const int defbase_num = BLI_listbase_count(defbase);
|
||||
*r_flip_map_num = defbase_num;
|
||||
|
||||
if (defbase_tot == 0) {
|
||||
if (defbase_num == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bDeformGroup *dg;
|
||||
char name_flip[sizeof(dg->name)];
|
||||
int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
|
||||
int i, flip_num, *map = MEM_mallocN(defbase_num * sizeof(int), __func__);
|
||||
|
||||
for (i = 0; i < defbase_tot; i++) {
|
||||
for (i = 0; i < defbase_num; i++) {
|
||||
map[i] = use_default ? i : -1;
|
||||
}
|
||||
|
||||
|
@ -776,7 +798,7 @@ MDeformWeight *BKE_defvert_ensure_index(MDeformVert *dvert, const int defgroup)
|
|||
return dw_new;
|
||||
}
|
||||
|
||||
void BKE_defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weight)
|
||||
void BKE_defvert_add_index_notest(MDeformVert *dvert, const int defgroup, const float weight)
|
||||
{
|
||||
/* TODO: merge with #BKE_defvert_ensure_index! */
|
||||
|
||||
|
@ -870,7 +892,7 @@ bool BKE_defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgr
|
|||
}
|
||||
|
||||
float BKE_defvert_total_selected_weight(const struct MDeformVert *dv,
|
||||
int defbase_tot,
|
||||
int defbase_num,
|
||||
const bool *defbase_sel)
|
||||
{
|
||||
float total = 0.0f;
|
||||
|
@ -881,7 +903,7 @@ float BKE_defvert_total_selected_weight(const struct MDeformVert *dv,
|
|||
}
|
||||
|
||||
for (int i = dv->totweight; i != 0; i--, dw++) {
|
||||
if (dw->def_nr < defbase_tot) {
|
||||
if (dw->def_nr < defbase_num) {
|
||||
if (defbase_sel[dw->def_nr]) {
|
||||
total += dw->weight;
|
||||
}
|
||||
|
@ -892,17 +914,17 @@ float BKE_defvert_total_selected_weight(const struct MDeformVert *dv,
|
|||
}
|
||||
|
||||
float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv,
|
||||
int defbase_tot,
|
||||
const int defbase_num,
|
||||
const bool *defbase_sel,
|
||||
int defbase_tot_sel,
|
||||
bool is_normalized)
|
||||
const int defbase_sel_num,
|
||||
const bool is_normalized)
|
||||
{
|
||||
float total = BKE_defvert_total_selected_weight(dv, defbase_tot, defbase_sel);
|
||||
float total = BKE_defvert_total_selected_weight(dv, defbase_num, defbase_sel);
|
||||
|
||||
/* in multipaint, get the average if auto normalize is inactive
|
||||
* get the sum if it is active */
|
||||
if (!is_normalized) {
|
||||
total /= defbase_tot_sel;
|
||||
total /= defbase_sel_num;
|
||||
}
|
||||
|
||||
return total;
|
||||
|
@ -936,19 +958,19 @@ float BKE_defvert_calc_lock_relative_weight(float weight,
|
|||
return weight / (1.0f - locked_weight);
|
||||
}
|
||||
|
||||
float BKE_defvert_lock_relative_weight(float weight,
|
||||
float BKE_defvert_lock_relative_weight(const float weight,
|
||||
const struct MDeformVert *dv,
|
||||
int defbase_tot,
|
||||
const int defbase_num,
|
||||
const bool *defbase_locked,
|
||||
const bool *defbase_unlocked)
|
||||
{
|
||||
float unlocked = BKE_defvert_total_selected_weight(dv, defbase_tot, defbase_unlocked);
|
||||
float unlocked = BKE_defvert_total_selected_weight(dv, defbase_num, defbase_unlocked);
|
||||
|
||||
if (unlocked > 0.0f) {
|
||||
return weight / unlocked;
|
||||
}
|
||||
|
||||
float locked = BKE_defvert_total_selected_weight(dv, defbase_tot, defbase_locked);
|
||||
float locked = BKE_defvert_total_selected_weight(dv, defbase_num, defbase_locked);
|
||||
|
||||
return BKE_defvert_calc_lock_relative_weight(weight, locked, unlocked);
|
||||
}
|
||||
|
@ -1010,12 +1032,12 @@ void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
|
|||
|
||||
void BKE_defvert_extract_vgroup_to_vertweights(const MDeformVert *dvert,
|
||||
const int defgroup,
|
||||
const int num_verts,
|
||||
const int verts_num,
|
||||
const bool invert_vgroup,
|
||||
float *r_weights)
|
||||
{
|
||||
if (dvert && defgroup != -1) {
|
||||
int i = num_verts;
|
||||
int i = verts_num;
|
||||
|
||||
while (i--) {
|
||||
const float w = BKE_defvert_find_weight(&dvert[i], defgroup);
|
||||
|
@ -1023,24 +1045,24 @@ void BKE_defvert_extract_vgroup_to_vertweights(const MDeformVert *dvert,
|
|||
}
|
||||
}
|
||||
else {
|
||||
copy_vn_fl(r_weights, num_verts, invert_vgroup ? 1.0f : 0.0f);
|
||||
copy_vn_fl(r_weights, verts_num, invert_vgroup ? 1.0f : 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
|
||||
const int defgroup,
|
||||
const int num_verts,
|
||||
const int verts_num,
|
||||
const MEdge *edges,
|
||||
const int num_edges,
|
||||
const int edges_num,
|
||||
const bool invert_vgroup,
|
||||
float *r_weights)
|
||||
{
|
||||
if (dvert && defgroup != -1) {
|
||||
int i = num_edges;
|
||||
float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
|
||||
int i = edges_num;
|
||||
float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__);
|
||||
|
||||
BKE_defvert_extract_vgroup_to_vertweights(
|
||||
dvert, defgroup, num_verts, invert_vgroup, tmp_weights);
|
||||
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
|
||||
|
||||
while (i--) {
|
||||
const MEdge *me = &edges[i];
|
||||
|
@ -1051,24 +1073,24 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
|
|||
MEM_freeN(tmp_weights);
|
||||
}
|
||||
else {
|
||||
copy_vn_fl(r_weights, num_edges, 0.0f);
|
||||
copy_vn_fl(r_weights, edges_num, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
|
||||
const int defgroup,
|
||||
const int num_verts,
|
||||
const int verts_num,
|
||||
const MLoop *loops,
|
||||
const int num_loops,
|
||||
const int loops_num,
|
||||
const bool invert_vgroup,
|
||||
float *r_weights)
|
||||
{
|
||||
if (dvert && defgroup != -1) {
|
||||
int i = num_loops;
|
||||
float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
|
||||
int i = loops_num;
|
||||
float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__);
|
||||
|
||||
BKE_defvert_extract_vgroup_to_vertweights(
|
||||
dvert, defgroup, num_verts, invert_vgroup, tmp_weights);
|
||||
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
|
||||
|
||||
while (i--) {
|
||||
const MLoop *ml = &loops[i];
|
||||
|
@ -1079,26 +1101,26 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
|
|||
MEM_freeN(tmp_weights);
|
||||
}
|
||||
else {
|
||||
copy_vn_fl(r_weights, num_loops, 0.0f);
|
||||
copy_vn_fl(r_weights, loops_num, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert,
|
||||
const int defgroup,
|
||||
const int num_verts,
|
||||
const int verts_num,
|
||||
const MLoop *loops,
|
||||
const int UNUSED(num_loops),
|
||||
const int UNUSED(loops_num),
|
||||
const MPoly *polys,
|
||||
const int num_polys,
|
||||
const int polys_num,
|
||||
const bool invert_vgroup,
|
||||
float *r_weights)
|
||||
{
|
||||
if (dvert && defgroup != -1) {
|
||||
int i = num_polys;
|
||||
float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)num_verts, __func__);
|
||||
int i = polys_num;
|
||||
float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__);
|
||||
|
||||
BKE_defvert_extract_vgroup_to_vertweights(
|
||||
dvert, defgroup, num_verts, invert_vgroup, tmp_weights);
|
||||
dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
|
||||
|
||||
while (i--) {
|
||||
const MPoly *mp = &polys[i];
|
||||
|
@ -1115,7 +1137,7 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert,
|
|||
MEM_freeN(tmp_weights);
|
||||
}
|
||||
else {
|
||||
copy_vn_fl(r_weights, num_polys, 0.0f);
|
||||
copy_vn_fl(r_weights, polys_num, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1207,7 +1229,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
|
|||
const ListBase *src_list = BKE_object_defgroup_list(ob_src);
|
||||
ListBase *dst_defbase = BKE_object_defgroup_list_mutable(ob_dst);
|
||||
|
||||
int tot_dst = BLI_listbase_count(dst_defbase);
|
||||
const int tot_dst = BLI_listbase_count(dst_defbase);
|
||||
|
||||
const size_t elem_size = sizeof(*((MDeformVert *)NULL));
|
||||
|
||||
|
|
|
@ -314,7 +314,7 @@ IDTypeInfo IDType_ID_GD = {
|
|||
.foreach_id = greasepencil_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = greasepencil_blend_write,
|
||||
.blend_read_data = greasepencil_blend_read_data,
|
||||
|
|
|
@ -442,7 +442,7 @@ constexpr IDTypeInfo get_type_info()
|
|||
info.foreach_id = nullptr;
|
||||
info.foreach_cache = image_foreach_cache;
|
||||
info.foreach_path = image_foreach_path;
|
||||
info.owner_get = nullptr;
|
||||
info.owner_pointer_get = nullptr;
|
||||
|
||||
info.blend_write = image_blend_write;
|
||||
info.blend_read_data = image_blend_read_data;
|
||||
|
|
|
@ -178,7 +178,7 @@ IDTypeInfo IDType_ID_IP = {
|
|||
.foreach_id = NULL,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = NULL,
|
||||
.blend_read_data = ipo_blend_read_data,
|
||||
|
|
|
@ -91,14 +91,14 @@ static void shapekey_foreach_id(ID *id, LibraryForeachIDData *data)
|
|||
BKE_LIB_FOREACHID_PROCESS_ID(data, key->from, IDWALK_CB_LOOPBACK);
|
||||
}
|
||||
|
||||
static ID *shapekey_owner_get(ID *id)
|
||||
static ID **shapekey_owner_pointer_get(ID *id)
|
||||
{
|
||||
Key *key = (Key *)id;
|
||||
|
||||
BLI_assert(key->from != NULL);
|
||||
BLI_assert(BKE_key_from_id(key->from) == key);
|
||||
|
||||
return key->from;
|
||||
return &key->from;
|
||||
}
|
||||
|
||||
static void shapekey_blend_write(BlendWriter *writer, ID *id, const void *id_address)
|
||||
|
@ -215,7 +215,7 @@ IDTypeInfo IDType_ID_KE = {
|
|||
.foreach_path = NULL,
|
||||
/* A bit weird, due to shape-keys not being strictly speaking embedded data... But they also
|
||||
* share a lot with those (non linkable, only ever used by one owner ID, etc.). */
|
||||
.owner_get = shapekey_owner_get,
|
||||
.owner_pointer_get = shapekey_owner_pointer_get,
|
||||
|
||||
.blend_write = shapekey_blend_write,
|
||||
.blend_read_data = shapekey_blend_read_data,
|
||||
|
@ -1938,6 +1938,16 @@ KeyBlock *BKE_keyblock_find_name(Key *key, const char name[])
|
|||
return BLI_findstring(&key->block, name, offsetof(KeyBlock, name));
|
||||
}
|
||||
|
||||
KeyBlock *BKE_keyblock_find_uid(Key *key, const int uid)
|
||||
{
|
||||
LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
|
||||
if (kb->uid == uid) {
|
||||
return kb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void BKE_keyblock_copy_settings(KeyBlock *kb_dst, const KeyBlock *kb_src)
|
||||
{
|
||||
kb_dst->pos = kb_src->pos;
|
||||
|
|
|
@ -190,7 +190,7 @@ IDTypeInfo IDType_ID_LT = {
|
|||
.foreach_id = lattice_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = lattice_blend_write,
|
||||
.blend_read_data = lattice_blend_read_data,
|
||||
|
|
|
@ -56,7 +56,8 @@
|
|||
static CLG_LogRef LOG = {"bke.layercollection"};
|
||||
|
||||
/* Set of flags which are dependent on a collection settings. */
|
||||
static const short g_base_collection_flags = (BASE_VISIBLE_DEPSGRAPH | BASE_VISIBLE_VIEWLAYER |
|
||||
static const short g_base_collection_flags = (BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT |
|
||||
BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT |
|
||||
BASE_SELECTABLE | BASE_ENABLED_VIEWPORT |
|
||||
BASE_ENABLED_RENDER | BASE_HOLDOUT |
|
||||
BASE_INDIRECT_ONLY);
|
||||
|
@ -998,9 +999,10 @@ static void layer_collection_objects_sync(ViewLayer *view_layer,
|
|||
}
|
||||
|
||||
if ((collection_restrict & COLLECTION_HIDE_VIEWPORT) == 0) {
|
||||
base->flag_from_collection |= (BASE_ENABLED_VIEWPORT | BASE_VISIBLE_DEPSGRAPH);
|
||||
base->flag_from_collection |= (BASE_ENABLED_VIEWPORT |
|
||||
BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT);
|
||||
if ((layer_restrict & LAYER_COLLECTION_HIDE) == 0) {
|
||||
base->flag_from_collection |= BASE_VISIBLE_VIEWLAYER;
|
||||
base->flag_from_collection |= BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT;
|
||||
}
|
||||
if (((collection_restrict & COLLECTION_HIDE_SELECT) == 0)) {
|
||||
base->flag_from_collection |= BASE_SELECTABLE;
|
||||
|
@ -1452,7 +1454,8 @@ bool BKE_layer_collection_has_selected_objects(ViewLayer *view_layer, LayerColle
|
|||
LISTBASE_FOREACH (CollectionObject *, cob, &lc->collection->gobject) {
|
||||
Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
|
||||
|
||||
if (base && (base->flag & BASE_SELECTED) && (base->flag & BASE_VISIBLE_DEPSGRAPH)) {
|
||||
if (base && (base->flag & BASE_SELECTED) &&
|
||||
(base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1508,12 +1511,12 @@ void BKE_base_set_visible(Scene *scene, ViewLayer *view_layer, Base *base, bool
|
|||
|
||||
bool BKE_base_is_visible(const View3D *v3d, const Base *base)
|
||||
{
|
||||
if ((base->flag & BASE_VISIBLE_DEPSGRAPH) == 0) {
|
||||
if ((base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (v3d == NULL) {
|
||||
return base->flag & BASE_VISIBLE_VIEWLAYER;
|
||||
return base->flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT;
|
||||
}
|
||||
|
||||
if ((v3d->localvd) && ((v3d->local_view_uuid & base->local_view_bits) == 0)) {
|
||||
|
@ -1528,7 +1531,7 @@ bool BKE_base_is_visible(const View3D *v3d, const Base *base)
|
|||
return (v3d->local_collections_uuid & base->local_collections_bits) != 0;
|
||||
}
|
||||
|
||||
return base->flag & BASE_VISIBLE_VIEWLAYER;
|
||||
return base->flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT;
|
||||
}
|
||||
|
||||
bool BKE_object_is_visible_in_viewport(const View3D *v3d, const struct Object *ob)
|
||||
|
@ -1554,7 +1557,7 @@ bool BKE_object_is_visible_in_viewport(const View3D *v3d, const struct Object *o
|
|||
|
||||
/* If not using local collection the object may still be in a hidden collection. */
|
||||
if ((v3d->flag & V3D_LOCAL_COLLECTIONS) == 0) {
|
||||
return (ob->base_flag & BASE_VISIBLE_VIEWLAYER) != 0;
|
||||
return (ob->base_flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT) != 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2011,12 +2014,13 @@ static void objects_iterator_end(BLI_Iterator *iter)
|
|||
|
||||
void BKE_view_layer_selected_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
|
||||
{
|
||||
objects_iterator_begin(iter, data_in, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
|
||||
objects_iterator_begin(
|
||||
iter, data_in, BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_SELECTED);
|
||||
}
|
||||
|
||||
void BKE_view_layer_selected_objects_iterator_next(BLI_Iterator *iter)
|
||||
{
|
||||
objects_iterator_next(iter, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
|
||||
objects_iterator_next(iter, BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_SELECTED);
|
||||
}
|
||||
|
||||
void BKE_view_layer_selected_objects_iterator_end(BLI_Iterator *iter)
|
||||
|
@ -2053,7 +2057,8 @@ void BKE_view_layer_visible_objects_iterator_end(BLI_Iterator *iter)
|
|||
|
||||
void BKE_view_layer_selected_editable_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
|
||||
{
|
||||
objects_iterator_begin(iter, data_in, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
|
||||
objects_iterator_begin(
|
||||
iter, data_in, BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_SELECTED);
|
||||
if (iter->valid) {
|
||||
if (BKE_object_is_libdata((Object *)iter->current) == false) {
|
||||
/* First object is valid (selectable and not libdata) -> all good. */
|
||||
|
@ -2070,7 +2075,7 @@ void BKE_view_layer_selected_editable_objects_iterator_next(BLI_Iterator *iter)
|
|||
/* Search while there are objects and the one we have is not editable (editable = not libdata).
|
||||
*/
|
||||
do {
|
||||
objects_iterator_next(iter, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
|
||||
objects_iterator_next(iter, BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_SELECTED);
|
||||
} while (iter->valid && BKE_object_is_libdata((Object *)iter->current) != false);
|
||||
}
|
||||
|
||||
|
@ -2087,12 +2092,13 @@ void BKE_view_layer_selected_editable_objects_iterator_end(BLI_Iterator *iter)
|
|||
|
||||
void BKE_view_layer_selected_bases_iterator_begin(BLI_Iterator *iter, void *data_in)
|
||||
{
|
||||
objects_iterator_begin(iter, data_in, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
|
||||
objects_iterator_begin(
|
||||
iter, data_in, BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_SELECTED);
|
||||
}
|
||||
|
||||
void BKE_view_layer_selected_bases_iterator_next(BLI_Iterator *iter)
|
||||
{
|
||||
object_bases_iterator_next(iter, BASE_VISIBLE_DEPSGRAPH | BASE_SELECTED);
|
||||
object_bases_iterator_next(iter, BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_SELECTED);
|
||||
}
|
||||
|
||||
void BKE_view_layer_selected_bases_iterator_end(BLI_Iterator *iter)
|
||||
|
@ -2219,7 +2225,8 @@ void BKE_base_eval_flags(Base *base)
|
|||
* can change these again, but for tools we always want the viewport
|
||||
* visibility to be in sync regardless if depsgraph was evaluated. */
|
||||
if (!(base->flag & BASE_ENABLED_VIEWPORT) || (base->flag & BASE_HIDDEN)) {
|
||||
base->flag &= ~(BASE_VISIBLE_DEPSGRAPH | BASE_VISIBLE_VIEWLAYER | BASE_SELECTABLE);
|
||||
base->flag &= ~(BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT |
|
||||
BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT | BASE_SELECTABLE);
|
||||
}
|
||||
|
||||
/* Deselect unselectable objects. */
|
||||
|
|
|
@ -93,7 +93,7 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = {
|
|||
.foreach_id = NULL,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = NULL,
|
||||
.blend_read_data = NULL,
|
||||
|
@ -1965,6 +1965,18 @@ bool BKE_id_can_be_asset(const ID *id)
|
|||
BKE_idtype_idcode_is_linkable(GS(id->name));
|
||||
}
|
||||
|
||||
ID *BKE_id_owner_get(ID *id)
|
||||
{
|
||||
const IDTypeInfo *idtype = BKE_idtype_get_info_from_id(id);
|
||||
if (idtype->owner_pointer_get != NULL) {
|
||||
ID **owner_id_pointer = idtype->owner_pointer_get(id);
|
||||
if (owner_id_pointer != NULL) {
|
||||
return *owner_id_pointer;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool BKE_id_is_editable(const Main *bmain, const ID *id)
|
||||
{
|
||||
return !(ID_IS_LINKED(id) || BKE_lib_override_library_is_system_defined(bmain, id));
|
||||
|
|
|
@ -97,22 +97,18 @@ BLI_INLINE const IDOverrideLibrary *BKE_lib_override_library_get(const Main * /*
|
|||
const ID * /*owner_id_hint*/,
|
||||
const ID **r_owner_id)
|
||||
{
|
||||
if (id->flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE) {
|
||||
const ID *owner_id = BKE_id_owner_get(const_cast<ID *>(id));
|
||||
BLI_assert_msg(owner_id != nullptr, "Liboverride-embedded ID with no owner");
|
||||
if (r_owner_id != nullptr) {
|
||||
*r_owner_id = owner_id;
|
||||
}
|
||||
return owner_id->override_library;
|
||||
}
|
||||
|
||||
if (r_owner_id != nullptr) {
|
||||
*r_owner_id = id;
|
||||
}
|
||||
if (id->flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE) {
|
||||
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
|
||||
if (id_type->owner_get != nullptr) {
|
||||
/* The #IDTypeInfo::owner_get callback should not modify the arguments, so casting away const
|
||||
* is okay. */
|
||||
const ID *owner_id = id_type->owner_get(const_cast<ID *>(id));
|
||||
if (r_owner_id != nullptr) {
|
||||
*r_owner_id = owner_id;
|
||||
}
|
||||
return owner_id->override_library;
|
||||
}
|
||||
BLI_assert_msg(0, "IDTypeInfo of liboverride-embedded ID with no owner getter");
|
||||
}
|
||||
return id->override_library;
|
||||
}
|
||||
|
||||
|
@ -2211,9 +2207,9 @@ static bool lib_override_resync_id_lib_level_is_valid(ID *id,
|
|||
static ID *lib_override_library_main_resync_root_get(Main * /*bmain*/, ID *id)
|
||||
{
|
||||
if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
|
||||
const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
|
||||
if (id_type->owner_get != nullptr) {
|
||||
id = id_type->owner_get(id);
|
||||
ID *id_owner = BKE_id_owner_get(id);
|
||||
if (id_owner != nullptr) {
|
||||
id = id_owner;
|
||||
}
|
||||
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id));
|
||||
}
|
||||
|
|
|
@ -711,9 +711,8 @@ static void lib_query_unused_ids_tag_recurse(Main *bmain,
|
|||
ID *id_from = id_from_item->id_pointer.from;
|
||||
if ((id_from->flag & LIB_EMBEDDED_DATA) != 0) {
|
||||
/* Directly 'by-pass' to actual real ID owner. */
|
||||
const IDTypeInfo *type_info_from = BKE_idtype_get_info_from_id(id_from);
|
||||
BLI_assert(type_info_from->owner_get != NULL);
|
||||
id_from = type_info_from->owner_get(id_from);
|
||||
id_from = BKE_id_owner_get(id_from);
|
||||
BLI_assert(id_from != NULL);
|
||||
}
|
||||
|
||||
lib_query_unused_ids_tag_recurse(
|
||||
|
|
|
@ -97,7 +97,7 @@ IDTypeInfo IDType_ID_LI = {
|
|||
.foreach_id = library_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = library_foreach_path,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = NULL,
|
||||
.blend_read_data = library_blend_read_data,
|
||||
|
|
|
@ -189,7 +189,7 @@ IDTypeInfo IDType_ID_LA = {
|
|||
.foreach_id = light_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = light_blend_write,
|
||||
.blend_read_data = light_blend_read_data,
|
||||
|
|
|
@ -85,7 +85,7 @@ IDTypeInfo IDType_ID_LP = {
|
|||
.foreach_id = lightprobe_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = lightprobe_blend_write,
|
||||
.blend_read_data = lightprobe_blend_read_data,
|
||||
|
|
|
@ -749,7 +749,7 @@ IDTypeInfo IDType_ID_LS = {
|
|||
.foreach_id = linestyle_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = linestyle_blend_write,
|
||||
.blend_read_data = linestyle_blend_read_data,
|
||||
|
|
|
@ -249,7 +249,7 @@ IDTypeInfo IDType_ID_MSK = {
|
|||
.foreach_id = mask_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = mask_blend_write,
|
||||
.blend_read_data = mask_blend_read_data,
|
||||
|
|
|
@ -256,7 +256,7 @@ IDTypeInfo IDType_ID_MA = {
|
|||
.foreach_id = material_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = material_blend_write,
|
||||
.blend_read_data = material_blend_read_data,
|
||||
|
|
|
@ -180,7 +180,7 @@ IDTypeInfo IDType_ID_MB = {
|
|||
/* foreach_id */ metaball_foreach_id,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ nullptr,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ metaball_blend_write,
|
||||
/* blend_read_data */ metaball_blend_read_data,
|
||||
|
|
|
@ -1447,7 +1447,6 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
|
|||
MVert *mvert = CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CONSTRUCT, NULL, mesh->totvert);
|
||||
for (int i = 0; i < mesh->totvert; i++) {
|
||||
copy_v3_v3(mvert[i].co, process.co[i]);
|
||||
mvert->bweight = 0;
|
||||
}
|
||||
MEM_freeN(process.co);
|
||||
|
||||
|
|
|
@ -252,10 +252,12 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
|
|||
if (!BLO_write_is_undo(writer)) {
|
||||
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
|
||||
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh);
|
||||
BKE_mesh_legacy_bevel_weight_from_layers(mesh);
|
||||
/* When converting to the old mesh format, don't save redundant attributes. */
|
||||
names_to_skip.add_multiple_new({".hide_vert",
|
||||
".hide_edge",
|
||||
".hide_poly",
|
||||
"material_index",
|
||||
".selection_vert",
|
||||
".selection_edge",
|
||||
".selection_poly"});
|
||||
|
@ -355,6 +357,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
BKE_mesh_legacy_convert_flags_to_selection_layers(mesh);
|
||||
BKE_mesh_legacy_convert_flags_to_hide_layers(mesh);
|
||||
BKE_mesh_legacy_convert_mpoly_to_material_indices(mesh);
|
||||
BKE_mesh_legacy_bevel_weight_to_layers(mesh);
|
||||
}
|
||||
|
||||
/* We don't expect to load normals from files, since they are derived data. */
|
||||
|
@ -409,7 +412,7 @@ IDTypeInfo IDType_ID_ME = {
|
|||
/* foreach_id */ mesh_foreach_id,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ mesh_foreach_path,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ mesh_blend_write,
|
||||
/* blend_read_data */ mesh_blend_read_data,
|
||||
|
@ -892,11 +895,12 @@ static void mesh_clear_geometry(Mesh *mesh)
|
|||
mesh->totpoly = 0;
|
||||
mesh->act_face = -1;
|
||||
mesh->totselect = 0;
|
||||
|
||||
BLI_freelistN(&mesh->vertex_group_names);
|
||||
}
|
||||
|
||||
void BKE_mesh_clear_geometry(Mesh *mesh)
|
||||
{
|
||||
BKE_animdata_free(&mesh->id, false);
|
||||
BKE_mesh_runtime_clear_cache(mesh);
|
||||
mesh_clear_geometry(mesh);
|
||||
}
|
||||
|
@ -986,6 +990,7 @@ void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src)
|
|||
copy_v3_v3(me_dst->size, me_src->size);
|
||||
|
||||
me_dst->vertex_group_active_index = me_src->vertex_group_active_index;
|
||||
me_dst->attributes_active_index = me_src->attributes_active_index;
|
||||
}
|
||||
|
||||
void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
|
||||
|
|
|
@ -381,8 +381,6 @@ static void copy_vert_attributes(Mesh *dest_mesh,
|
|||
int mv_index,
|
||||
int index_in_orig_me)
|
||||
{
|
||||
mv->bweight = orig_mv->bweight;
|
||||
|
||||
/* For all layers in the orig mesh, copy the layer information. */
|
||||
CustomData *target_cd = &dest_mesh->vdata;
|
||||
const CustomData *source_cd = &orig_me->vdata;
|
||||
|
@ -449,7 +447,6 @@ static void copy_edge_attributes(Mesh *dest_mesh,
|
|||
int medge_index,
|
||||
int index_in_orig_me)
|
||||
{
|
||||
medge->bweight = orig_medge->bweight;
|
||||
medge->crease = orig_medge->crease;
|
||||
medge->flag = orig_medge->flag;
|
||||
CustomData *target_cd = &dest_mesh->edata;
|
||||
|
|
|
@ -54,9 +54,11 @@
|
|||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
using blender::float3;
|
||||
using blender::IndexRange;
|
||||
using blender::MutableSpan;
|
||||
using blender::Span;
|
||||
using blender::StringRefNull;
|
||||
|
||||
/* Define for cases when you want extra validation of mesh
|
||||
* after certain modifications.
|
||||
|
@ -116,7 +118,7 @@ static void make_edges_mdata_extend(Mesh &mesh)
|
|||
BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
|
||||
BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index));
|
||||
|
||||
medge->crease = medge->bweight = 0;
|
||||
medge->crease = 0;
|
||||
medge->flag = ME_EDGEDRAW | ME_EDGERENDER;
|
||||
}
|
||||
BLI_edgehashIterator_free(ehi);
|
||||
|
@ -1081,7 +1083,7 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
|
|||
mesh_in_bmain->smoothresh = mesh->smoothresh;
|
||||
mesh->mat = nullptr;
|
||||
|
||||
BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, nullptr, &CD_MASK_MESH, true);
|
||||
BKE_mesh_nomain_to_mesh(mesh, mesh_in_bmain, nullptr);
|
||||
|
||||
/* Anonymous attributes shouldn't exist on original data. */
|
||||
mesh_in_bmain->attributes_for_write().remove_anonymous();
|
||||
|
@ -1235,239 +1237,113 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
|
|||
return result;
|
||||
}
|
||||
|
||||
/* This is a Mesh-based copy of the same function in DerivedMesh.cc */
|
||||
static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int actshape_uid)
|
||||
static KeyBlock *keyblock_ensure_from_uid(Key &key, const int uid, const StringRefNull name)
|
||||
{
|
||||
KeyBlock *kb;
|
||||
int i, j, tot;
|
||||
|
||||
if (!mesh_dst->key) {
|
||||
return;
|
||||
if (KeyBlock *kb = BKE_keyblock_find_uid(&key, uid)) {
|
||||
return kb;
|
||||
}
|
||||
KeyBlock *kb = BKE_keyblock_add(&key, name.c_str());
|
||||
kb->uid = uid;
|
||||
return kb;
|
||||
}
|
||||
|
||||
tot = CustomData_number_of_layers(&mesh_src->vdata, CD_SHAPEKEY);
|
||||
for (i = 0; i < tot; i++) {
|
||||
CustomDataLayer *layer =
|
||||
&mesh_src->vdata.layers[CustomData_get_layer_index_n(&mesh_src->vdata, CD_SHAPEKEY, i)];
|
||||
float(*kbcos)[3];
|
||||
static int find_object_active_key_uid(const Key &key, const Object &object)
|
||||
{
|
||||
const int active_kb_index = object.shapenr - 1;
|
||||
const KeyBlock *kb = (const KeyBlock *)BLI_findlink(&key.block, active_kb_index);
|
||||
if (!kb) {
|
||||
CLOG_ERROR(&LOG, "Could not find object's active shapekey %d", active_kb_index);
|
||||
return -1;
|
||||
}
|
||||
return kb->uid;
|
||||
}
|
||||
|
||||
for (kb = (KeyBlock *)mesh_dst->key->block.first; kb; kb = kb->next) {
|
||||
if (kb->uid == layer->uid) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void move_shapekey_layers_to_keyblocks(Mesh &mesh, Key &key_dst, const int actshape_uid)
|
||||
{
|
||||
using namespace blender::bke;
|
||||
for (const int i : IndexRange(CustomData_number_of_layers(&mesh.vdata, CD_SHAPEKEY))) {
|
||||
const int layer_index = CustomData_get_layer_index_n(&mesh.vdata, CD_SHAPEKEY, i);
|
||||
CustomDataLayer &layer = mesh.vdata.layers[layer_index];
|
||||
|
||||
if (!kb) {
|
||||
kb = BKE_keyblock_add(mesh_dst->key, layer->name);
|
||||
kb->uid = layer->uid;
|
||||
}
|
||||
KeyBlock *kb = keyblock_ensure_from_uid(key_dst, layer.uid, layer.name);
|
||||
MEM_SAFE_FREE(kb->data);
|
||||
|
||||
if (kb->data) {
|
||||
MEM_freeN(kb->data);
|
||||
}
|
||||
kb->totelem = mesh.totvert;
|
||||
|
||||
const float(*cos)[3] = (const float(*)[3])CustomData_get_layer_n(
|
||||
&mesh_src->vdata, CD_SHAPEKEY, i);
|
||||
kb->totelem = mesh_src->totvert;
|
||||
|
||||
kb->data = kbcos = (float(*)[3])MEM_malloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
|
||||
if (kb->uid == actshape_uid) {
|
||||
const Span<MVert> verts = mesh_src->verts();
|
||||
for (j = 0; j < mesh_src->totvert; j++, kbcos++) {
|
||||
copy_v3_v3(*kbcos, verts[j].co);
|
||||
}
|
||||
kb->data = MEM_malloc_arrayN(kb->totelem, sizeof(float3), __func__);
|
||||
MutableSpan<float3> kb_coords(static_cast<float3 *>(kb->data), kb->totelem);
|
||||
mesh.attributes().lookup<float3>("position").materialize(kb_coords);
|
||||
}
|
||||
else {
|
||||
for (j = 0; j < kb->totelem; j++, cos++, kbcos++) {
|
||||
copy_v3_v3(*kbcos, *cos);
|
||||
}
|
||||
kb->data = layer.data;
|
||||
layer.data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (kb = (KeyBlock *)mesh_dst->key->block.first; kb; kb = kb->next) {
|
||||
if (kb->totelem != mesh_src->totvert) {
|
||||
if (kb->data) {
|
||||
MEM_freeN(kb->data);
|
||||
}
|
||||
|
||||
kb->totelem = mesh_src->totvert;
|
||||
kb->data = MEM_calloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
|
||||
CLOG_ERROR(&LOG, "lost a shapekey layer: '%s'! (bmesh internal error)", kb->name);
|
||||
LISTBASE_FOREACH (KeyBlock *, kb, &key_dst.block) {
|
||||
if (kb->totelem != mesh.totvert) {
|
||||
MEM_SAFE_FREE(kb->data);
|
||||
}
|
||||
kb->totelem = mesh.totvert;
|
||||
kb->data = MEM_cnew_array<float3>(kb->totelem, __func__);
|
||||
CLOG_ERROR(&LOG, "Data for shape key '%s' on mesh missing from evaluated mesh ", kb->name);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
|
||||
Mesh *mesh_dst,
|
||||
Object *ob,
|
||||
const CustomData_MeshMasks *mask,
|
||||
bool take_ownership)
|
||||
void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
|
||||
{
|
||||
using namespace blender::bke;
|
||||
BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN);
|
||||
|
||||
/* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */
|
||||
/* TODO(Sybren): the above claim came from 2.7x derived-mesh code (DM_to_mesh);
|
||||
* check whether it is still true with Mesh */
|
||||
Mesh tmp = blender::dna::shallow_copy(*mesh_dst);
|
||||
int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly;
|
||||
bool did_shapekeys = false;
|
||||
eCDAllocType alloctype = CD_DUPLICATE;
|
||||
|
||||
if (take_ownership /* && dm->type == DM_TYPE_CDDM && dm->needsFree */) {
|
||||
bool has_any_referenced_layers = CustomData_has_referenced(&mesh_src->vdata) ||
|
||||
CustomData_has_referenced(&mesh_src->edata) ||
|
||||
CustomData_has_referenced(&mesh_src->ldata) ||
|
||||
CustomData_has_referenced(&mesh_src->fdata) ||
|
||||
CustomData_has_referenced(&mesh_src->pdata);
|
||||
if (!has_any_referenced_layers) {
|
||||
alloctype = CD_ASSIGN;
|
||||
}
|
||||
}
|
||||
CustomData_reset(&tmp.vdata);
|
||||
CustomData_reset(&tmp.edata);
|
||||
CustomData_reset(&tmp.fdata);
|
||||
CustomData_reset(&tmp.ldata);
|
||||
CustomData_reset(&tmp.pdata);
|
||||
|
||||
totvert = tmp.totvert = mesh_src->totvert;
|
||||
totedge = tmp.totedge = mesh_src->totedge;
|
||||
totloop = tmp.totloop = mesh_src->totloop;
|
||||
totpoly = tmp.totpoly = mesh_src->totpoly;
|
||||
tmp.totface = 0;
|
||||
|
||||
CustomData_copy(&mesh_src->vdata, &tmp.vdata, mask->vmask, alloctype, totvert);
|
||||
CustomData_copy(&mesh_src->edata, &tmp.edata, mask->emask, alloctype, totedge);
|
||||
CustomData_copy(&mesh_src->ldata, &tmp.ldata, mask->lmask, alloctype, totloop);
|
||||
CustomData_copy(&mesh_src->pdata, &tmp.pdata, mask->pmask, alloctype, totpoly);
|
||||
tmp.cd_flag = mesh_src->cd_flag;
|
||||
tmp.runtime.deformed_only = mesh_src->runtime.deformed_only;
|
||||
|
||||
/* Clear the normals completely, since the new vertex / polygon count might be different. */
|
||||
BKE_mesh_clear_derived_normals(&tmp);
|
||||
|
||||
if (CustomData_has_layer(&mesh_src->vdata, CD_SHAPEKEY)) {
|
||||
KeyBlock *kb;
|
||||
int uid;
|
||||
|
||||
if (ob) {
|
||||
kb = (KeyBlock *)BLI_findlink(&mesh_dst->key->block, ob->shapenr - 1);
|
||||
if (kb) {
|
||||
uid = kb->uid;
|
||||
}
|
||||
else {
|
||||
CLOG_ERROR(&LOG, "could not find active shapekey %d!", ob->shapenr - 1);
|
||||
|
||||
uid = INT_MAX;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* if no object, set to INT_MAX so we don't mess up any shapekey layers */
|
||||
uid = INT_MAX;
|
||||
}
|
||||
|
||||
shapekey_layers_to_keyblocks(mesh_src, mesh_dst, uid);
|
||||
did_shapekeys = true;
|
||||
}
|
||||
|
||||
/* copy texture space */
|
||||
if (ob) {
|
||||
BKE_mesh_texspace_copy_from_object(&tmp, ob);
|
||||
BLI_assert(mesh_dst == ob->data);
|
||||
}
|
||||
|
||||
/* not all DerivedMeshes store their verts/edges/faces in CustomData, so
|
||||
* we set them here in case they are missing */
|
||||
/* TODO(Sybren): we could probably replace CD_ASSIGN with alloctype and
|
||||
* always directly pass mesh_src->mxxx, instead of using a ternary operator. */
|
||||
if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) {
|
||||
CustomData_add_layer(&tmp.vdata,
|
||||
CD_MVERT,
|
||||
CD_ASSIGN,
|
||||
(alloctype == CD_ASSIGN) ? mesh_src->verts_for_write().data() :
|
||||
MEM_dupallocN(mesh_src->verts().data()),
|
||||
totvert);
|
||||
}
|
||||
if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
|
||||
CustomData_add_layer(&tmp.edata,
|
||||
CD_MEDGE,
|
||||
CD_ASSIGN,
|
||||
(alloctype == CD_ASSIGN) ? mesh_src->edges_for_write().data() :
|
||||
MEM_dupallocN(mesh_src->edges().data()),
|
||||
totedge);
|
||||
}
|
||||
if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
|
||||
CustomData_add_layer(&tmp.ldata,
|
||||
CD_MLOOP,
|
||||
CD_ASSIGN,
|
||||
(alloctype == CD_ASSIGN) ? mesh_src->loops_for_write().data() :
|
||||
MEM_dupallocN(mesh_src->loops().data()),
|
||||
tmp.totloop);
|
||||
CustomData_add_layer(&tmp.pdata,
|
||||
CD_MPOLY,
|
||||
CD_ASSIGN,
|
||||
(alloctype == CD_ASSIGN) ? mesh_src->polys_for_write().data() :
|
||||
MEM_dupallocN(mesh_src->polys().data()),
|
||||
tmp.totpoly);
|
||||
}
|
||||
BKE_mesh_clear_geometry(mesh_dst);
|
||||
|
||||
/* object had got displacement layer, should copy this layer to save sculpted data */
|
||||
/* NOTE(nazgul): maybe some other layers should be copied? */
|
||||
if (CustomData_has_layer(&mesh_dst->ldata, CD_MDISPS)) {
|
||||
if (totloop == mesh_dst->totloop) {
|
||||
MDisps *mdisps = (MDisps *)CustomData_get_layer(&mesh_dst->ldata, CD_MDISPS);
|
||||
CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop);
|
||||
if (alloctype == CD_ASSIGN) {
|
||||
/* Assign nullptr to prevent double-free. */
|
||||
CustomData_set_layer(&mesh_dst->ldata, CD_MDISPS, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Make sure referenced layers have a single user so assigning them to the mesh in main doesn't
|
||||
* share them. "Referenced" layers are not expected to be shared between original meshes. */
|
||||
CustomData_duplicate_referenced_layers(&mesh_src->vdata, mesh_src->totvert);
|
||||
CustomData_duplicate_referenced_layers(&mesh_src->edata, mesh_src->totedge);
|
||||
CustomData_duplicate_referenced_layers(&mesh_src->pdata, mesh_src->totpoly);
|
||||
CustomData_duplicate_referenced_layers(&mesh_src->ldata, mesh_src->totloop);
|
||||
|
||||
CustomData_free(&mesh_dst->vdata, mesh_dst->totvert);
|
||||
CustomData_free(&mesh_dst->edata, mesh_dst->totedge);
|
||||
CustomData_free(&mesh_dst->fdata, mesh_dst->totface);
|
||||
CustomData_free(&mesh_dst->ldata, mesh_dst->totloop);
|
||||
CustomData_free(&mesh_dst->pdata, mesh_dst->totpoly);
|
||||
mesh_dst->totvert = mesh_src->totvert;
|
||||
mesh_dst->totedge = mesh_src->totedge;
|
||||
mesh_dst->totpoly = mesh_src->totpoly;
|
||||
mesh_dst->totloop = mesh_src->totloop;
|
||||
|
||||
/* ok, this should now use new CD shapekey data,
|
||||
* which should be fed through the modifier
|
||||
* stack */
|
||||
if (tmp.totvert != mesh_dst->totvert && !did_shapekeys && mesh_dst->key) {
|
||||
CLOG_ERROR(&LOG, "YEEK! this should be recoded! Shape key loss!: ID '%s'", tmp.id.name);
|
||||
if (tmp.key && !(tmp.id.tag & LIB_TAG_NO_MAIN)) {
|
||||
id_us_min(&tmp.key->id);
|
||||
}
|
||||
tmp.key = nullptr;
|
||||
}
|
||||
|
||||
/* Clear selection history */
|
||||
MEM_SAFE_FREE(tmp.mselect);
|
||||
tmp.totselect = 0;
|
||||
tmp.texflag &= ~ME_AUTOSPACE_EVALUATED;
|
||||
|
||||
/* Clear any run-time data.
|
||||
* Even though this mesh won't typically have run-time data, the Python API can for e.g.
|
||||
* create loop-triangle cache here, which is confusing when left in the mesh, see: T81136. */
|
||||
BKE_mesh_runtime_clear_geometry(&tmp);
|
||||
|
||||
/* skip the listbase */
|
||||
MEMCPY_STRUCT_AFTER(mesh_dst, &tmp, id.prev);
|
||||
/* Using #CD_MASK_MESH ensures that only data that should exist in Main meshes is moved. */
|
||||
const CustomData_MeshMasks mask = CD_MASK_MESH;
|
||||
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, CD_ASSIGN, mesh_src->totvert);
|
||||
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, CD_ASSIGN, mesh_src->totedge);
|
||||
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, CD_ASSIGN, mesh_src->totpoly);
|
||||
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, CD_ASSIGN, mesh_src->totloop);
|
||||
|
||||
BLI_freelistN(&mesh_dst->vertex_group_names);
|
||||
BKE_defgroup_copy_list(&mesh_dst->vertex_group_names, &mesh_src->vertex_group_names);
|
||||
mesh_dst->vertex_group_active_index = mesh_src->vertex_group_active_index;
|
||||
mesh_dst->vertex_group_names = mesh_src->vertex_group_names;
|
||||
BLI_listbase_clear(&mesh_src->vertex_group_names);
|
||||
|
||||
if (take_ownership) {
|
||||
if (alloctype == CD_ASSIGN) {
|
||||
CustomData_free_typemask(&mesh_src->vdata, mesh_src->totvert, ~mask->vmask);
|
||||
CustomData_free_typemask(&mesh_src->edata, mesh_src->totedge, ~mask->emask);
|
||||
CustomData_free_typemask(&mesh_src->ldata, mesh_src->totloop, ~mask->lmask);
|
||||
CustomData_free_typemask(&mesh_src->pdata, mesh_src->totpoly, ~mask->pmask);
|
||||
BKE_mesh_copy_parameters(mesh_dst, mesh_src);
|
||||
mesh_dst->cd_flag = mesh_src->cd_flag;
|
||||
|
||||
/* For original meshes, shape key data is stored in the #Key data-block, so it
|
||||
* must be moved from the storage in #CustomData layers used for evaluation. */
|
||||
if (Key *key_dst = mesh_dst->key) {
|
||||
if (CustomData_has_layer(&mesh_src->vdata, CD_SHAPEKEY)) {
|
||||
/* If no object, set to -1 so we don't mess up any shapekey layers. */
|
||||
const int uid_active = ob ? find_object_active_key_uid(*key_dst, *ob) : -1;
|
||||
move_shapekey_layers_to_keyblocks(*mesh_src, *key_dst, uid_active);
|
||||
}
|
||||
else if (mesh_src->totvert != mesh_dst->totvert) {
|
||||
CLOG_ERROR(&LOG, "Mesh in Main '%s' lost shape keys", mesh_src->id.name);
|
||||
if (mesh_src->key) {
|
||||
id_us_min(&mesh_src->key->id);
|
||||
}
|
||||
}
|
||||
BKE_id_free(nullptr, mesh_src);
|
||||
}
|
||||
|
||||
BKE_mesh_assert_normals_dirty_or_calculated(mesh_dst);
|
||||
BKE_id_free(nullptr, mesh_src);
|
||||
}
|
||||
|
||||
void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
|
||||
|
|
|
@ -30,12 +30,6 @@
|
|||
static void mesh_debug_info_from_cd_flag(const Mesh *me, DynStr *dynstr)
|
||||
{
|
||||
BLI_dynstr_append(dynstr, "'cd_flag': {");
|
||||
if (me->cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
|
||||
BLI_dynstr_append(dynstr, "'VERT_BWEIGHT', ");
|
||||
}
|
||||
if (me->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
|
||||
BLI_dynstr_append(dynstr, "'EDGE_BWEIGHT', ");
|
||||
}
|
||||
if (me->cd_flag & ME_CDFLAG_EDGE_CREASE) {
|
||||
BLI_dynstr_append(dynstr, "'EDGE_CREASE', ");
|
||||
}
|
||||
|
|
|
@ -918,6 +918,67 @@ void BKE_mesh_add_mface_layers(CustomData *fdata, CustomData *ldata, int total)
|
|||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Bevel Weight Conversion
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
MutableSpan<MVert> verts = mesh->verts_for_write();
|
||||
if (const float *weights = static_cast<const float *>(
|
||||
CustomData_get_layer(&mesh->vdata, CD_BWEIGHT))) {
|
||||
mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
|
||||
for (const int i : verts.index_range()) {
|
||||
verts[i].bweight = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mesh->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT;
|
||||
for (const int i : verts.index_range()) {
|
||||
verts[i].bweight = 0;
|
||||
}
|
||||
}
|
||||
MutableSpan<MEdge> edges = mesh->edges_for_write();
|
||||
if (const float *weights = static_cast<const float *>(
|
||||
CustomData_get_layer(&mesh->edata, CD_BWEIGHT))) {
|
||||
mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].bweight = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mesh->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT;
|
||||
for (const int i : edges.index_range()) {
|
||||
edges[i].bweight = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
const Span<MVert> verts = mesh->verts();
|
||||
if (mesh->cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
|
||||
float *weights = static_cast<float *>(
|
||||
CustomData_add_layer(&mesh->vdata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, verts.size()));
|
||||
for (const int i : verts.index_range()) {
|
||||
weights[i] = verts[i].bweight / 255.0f;
|
||||
}
|
||||
}
|
||||
|
||||
const Span<MEdge> edges = mesh->edges();
|
||||
if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
|
||||
float *weights = static_cast<float *>(
|
||||
CustomData_add_layer(&mesh->edata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, edges.size()));
|
||||
for (const int i : edges.index_range()) {
|
||||
weights[i] = edges[i].bweight / 255.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Hide Attribute and Legacy Flag Conversion
|
||||
* \{ */
|
||||
|
|
|
@ -208,8 +208,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
|
|||
CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, maxLoops);
|
||||
CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, maxPolys);
|
||||
|
||||
/* Subsurf for eg won't have mesh data in the custom-data arrays.
|
||||
* now add mvert/medge/mpoly layers. */
|
||||
/* Subdivision-surface for eg won't have mesh data in the custom-data arrays.
|
||||
* Now add #MVert/#MEdge/#MPoly layers. */
|
||||
if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) {
|
||||
memcpy(BKE_mesh_verts_for_write(result), BKE_mesh_verts(mesh), sizeof(MVert) * mesh->totvert);
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
|
|||
MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result) + maxVerts;
|
||||
int *flip_map = NULL, flip_map_len = 0;
|
||||
|
||||
flip_map = BKE_object_defgroup_flip_map(ob, &flip_map_len, false);
|
||||
flip_map = BKE_object_defgroup_flip_map(ob, false, &flip_map_len);
|
||||
|
||||
if (flip_map) {
|
||||
for (i = 0; i < maxVerts; dvert++, i++) {
|
||||
|
|
|
@ -68,7 +68,7 @@ struct BKEMeshToTangent {
|
|||
}
|
||||
|
||||
const MPoly *mpolys; /* faces */
|
||||
const MLoop *mloops; /* faces's vertices */
|
||||
const MLoop *mloops; /* faces vertices */
|
||||
const MVert *mverts; /* vertices */
|
||||
const MLoopUV *luvs; /* texture coordinates */
|
||||
const float (*lnors)[3]; /* loops' normals */
|
||||
|
|
|
@ -343,7 +343,7 @@ IDTypeInfo IDType_ID_MC = {
|
|||
.foreach_id = movie_clip_foreach_id,
|
||||
.foreach_cache = movie_clip_foreach_cache,
|
||||
.foreach_path = movie_clip_foreach_path,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = movieclip_blend_write,
|
||||
.blend_read_data = movieclip_blend_read_data,
|
||||
|
|
|
@ -1252,7 +1252,7 @@ int multiresModifier_rebuild_subdiv(struct Depsgraph *depsgraph,
|
|||
}
|
||||
|
||||
/* Copy the new base mesh to the original mesh. */
|
||||
BKE_mesh_nomain_to_mesh(unsubdiv_context.base_mesh, object->data, object, &CD_MASK_MESH, true);
|
||||
BKE_mesh_nomain_to_mesh(unsubdiv_context.base_mesh, object->data, object);
|
||||
Mesh *base_mesh = object->data;
|
||||
multires_create_grids_in_unsubdivided_base_mesh(&unsubdiv_context, base_mesh);
|
||||
|
||||
|
|
|
@ -401,10 +401,10 @@ static void node_foreach_path(ID *id, BPathForeachPathData *bpath_data)
|
|||
}
|
||||
}
|
||||
|
||||
static ID *node_owner_get(ID *id)
|
||||
static ID **node_owner_pointer_get(ID *id)
|
||||
{
|
||||
if ((id->flag & LIB_EMBEDDED_DATA) == 0) {
|
||||
return id;
|
||||
return NULL;
|
||||
}
|
||||
/* TODO: Sort this NO_MAIN or not for embedded node trees. See T86119. */
|
||||
// BLI_assert((id->tag & LIB_TAG_NO_MAIN) == 0);
|
||||
|
@ -413,7 +413,7 @@ static ID *node_owner_get(ID *id)
|
|||
BLI_assert(ntree->owner_id != NULL);
|
||||
BLI_assert(ntreeFromID(ntree->owner_id) == ntree);
|
||||
|
||||
return ntree->owner_id;
|
||||
return &ntree->owner_id;
|
||||
}
|
||||
|
||||
static void write_node_socket_default_value(BlendWriter *writer, bNodeSocket *sock)
|
||||
|
@ -652,8 +652,13 @@ static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock)
|
|||
void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
|
||||
{
|
||||
/* Special case for this pointer, do not rely on regular `lib_link` process here. Avoids needs
|
||||
* for do_versioning, and ensures coherence of data in any case. */
|
||||
BLI_assert((ntree->id.flag & LIB_EMBEDDED_DATA) != 0 || owner_id == nullptr);
|
||||
* for do_versioning, and ensures coherence of data in any case.
|
||||
*
|
||||
* NOTE: Old versions are very often 'broken' here, just fix it silently in these cases.
|
||||
*/
|
||||
if (BLO_read_fileversion_get(reader) > 300) {
|
||||
BLI_assert((ntree->id.flag & LIB_EMBEDDED_DATA) != 0 || owner_id == nullptr);
|
||||
}
|
||||
BLI_assert(owner_id == NULL || owner_id->lib == ntree->id.lib);
|
||||
if (owner_id != nullptr && (ntree->id.flag & LIB_EMBEDDED_DATA) == 0) {
|
||||
/* This is unfortunate, but currently a lot of existing files (including startup ones) have
|
||||
|
@ -662,11 +667,13 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
|
|||
* NOTE: Using do_version is not a solution here, since this code will be called before any
|
||||
* do_version takes place. Keeping it here also ensures future (or unknown existing) similar
|
||||
* bugs won't go easily unnoticed. */
|
||||
CLOG_WARN(&LOG,
|
||||
"Fixing root node tree '%s' owned by '%s' missing EMBEDDED tag, please consider "
|
||||
"re-saving your (startup) file",
|
||||
ntree->id.name,
|
||||
owner_id->name);
|
||||
if (BLO_read_fileversion_get(reader) > 300) {
|
||||
CLOG_WARN(&LOG,
|
||||
"Fixing root node tree '%s' owned by '%s' missing EMBEDDED tag, please consider "
|
||||
"re-saving your (startup) file",
|
||||
ntree->id.name,
|
||||
owner_id->name);
|
||||
}
|
||||
ntree->id.flag |= LIB_EMBEDDED_DATA;
|
||||
}
|
||||
ntree->owner_id = owner_id;
|
||||
|
@ -1036,7 +1043,7 @@ IDTypeInfo IDType_ID_NT = {
|
|||
/* foreach_id */ node_foreach_id,
|
||||
/* foreach_cache */ node_foreach_cache,
|
||||
/* foreach_path */ node_foreach_path,
|
||||
/* owner_get */ node_owner_get,
|
||||
/* owner_pointer_get */ node_owner_pointer_get,
|
||||
|
||||
/* blend_write */ ntree_blend_write,
|
||||
/* blend_read_data */ ntree_blend_read_data,
|
||||
|
@ -1924,6 +1931,9 @@ static void node_socket_free(bNodeSocket *sock, const bool do_id_user)
|
|||
}
|
||||
MEM_freeN(sock->default_value);
|
||||
}
|
||||
if (sock->default_attribute_name) {
|
||||
MEM_freeN(sock->default_attribute_name);
|
||||
}
|
||||
MEM_delete(sock->runtime);
|
||||
}
|
||||
|
||||
|
@ -3008,6 +3018,9 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree),
|
|||
}
|
||||
MEM_freeN(sock->default_value);
|
||||
}
|
||||
if (sock->default_attribute_name) {
|
||||
MEM_freeN(sock->default_attribute_name);
|
||||
}
|
||||
MEM_delete(sock->runtime);
|
||||
}
|
||||
|
||||
|
|
|
@ -258,6 +258,7 @@ static void toposort_from_start_node(const ToposortDirection direction,
|
|||
|
||||
Stack<Item, 64> nodes_to_check;
|
||||
nodes_to_check.push({&start_node});
|
||||
node_states[start_node.runtime->index_in_tree].is_in_stack = true;
|
||||
while (!nodes_to_check.is_empty()) {
|
||||
Item &item = nodes_to_check.peek();
|
||||
bNode &node = *item.node;
|
||||
|
|
|
@ -1239,7 +1239,7 @@ IDTypeInfo IDType_ID_OB = {
|
|||
/* foreach_id */ object_foreach_id,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ object_foreach_path,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ object_blend_write,
|
||||
/* blend_read_data */ object_blend_read_data,
|
||||
|
@ -2040,7 +2040,7 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode)
|
|||
|
||||
int BKE_object_visibility(const Object *ob, const int dag_eval_mode)
|
||||
{
|
||||
if ((ob->base_flag & BASE_VISIBLE_DEPSGRAPH) == 0) {
|
||||
if ((ob->base_flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -407,10 +407,10 @@ void BKE_object_eval_eval_base_flags(Depsgraph *depsgraph,
|
|||
* assumed viewport visibility. Select-ability does not matter here. */
|
||||
if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) {
|
||||
if (base->flag & BASE_ENABLED_RENDER) {
|
||||
base->flag |= BASE_VISIBLE_DEPSGRAPH;
|
||||
base->flag |= BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT;
|
||||
}
|
||||
else {
|
||||
base->flag &= ~BASE_VISIBLE_DEPSGRAPH;
|
||||
base->flag &= ~BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ IDTypeInfo IDType_ID_PAL = {
|
|||
/* foreach_id */ nullptr,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ nullptr,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ palette_blend_write,
|
||||
/* blend_read_data */ palette_blend_read_data,
|
||||
|
@ -207,7 +207,7 @@ IDTypeInfo IDType_ID_PC = {
|
|||
/* foreach_id */ nullptr,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ nullptr,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ paint_curve_blend_write,
|
||||
/* blend_read_data */ paint_curve_blend_read_data,
|
||||
|
|
|
@ -494,7 +494,7 @@ IDTypeInfo IDType_ID_PA = {
|
|||
.foreach_id = particle_settings_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = particle_settings_blend_write,
|
||||
.blend_read_data = particle_settings_blend_read_data,
|
||||
|
|
|
@ -175,7 +175,7 @@ IDTypeInfo IDType_ID_PT = {
|
|||
/* foreach_id */ pointcloud_foreach_id,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ nullptr,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ pointcloud_blend_write,
|
||||
/* blend_read_data */ pointcloud_blend_read_data,
|
||||
|
|
|
@ -1675,7 +1675,7 @@ constexpr IDTypeInfo get_type_info()
|
|||
info.foreach_id = scene_foreach_id;
|
||||
info.foreach_cache = scene_foreach_cache;
|
||||
info.foreach_path = scene_foreach_path;
|
||||
info.owner_get = nullptr;
|
||||
info.owner_pointer_get = nullptr;
|
||||
|
||||
info.blend_write = scene_blend_write;
|
||||
info.blend_read_data = scene_blend_read_data;
|
||||
|
|
|
@ -292,7 +292,7 @@ IDTypeInfo IDType_ID_SCR = {
|
|||
.foreach_id = screen_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = screen_blend_write,
|
||||
/* Cannot be used yet, because #direct_link_screen has a return value. */
|
||||
|
|
|
@ -149,7 +149,7 @@ IDTypeInfo IDType_ID_SIM = {
|
|||
/* foreach_id */ simulation_foreach_id,
|
||||
/* foreach_cache */ nullptr,
|
||||
/* foreach_path */ nullptr,
|
||||
/* owner_get */ nullptr,
|
||||
/* owner_pointer_get */ nullptr,
|
||||
|
||||
/* blend_write */ simulation_blend_write,
|
||||
/* blend_read_data */ simulation_blend_read_data,
|
||||
|
|
|
@ -211,7 +211,7 @@ IDTypeInfo IDType_ID_SO = {
|
|||
.foreach_id = NULL,
|
||||
.foreach_cache = sound_foreach_cache,
|
||||
.foreach_path = sound_foreach_path,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = sound_blend_write,
|
||||
.blend_read_data = sound_blend_read_data,
|
||||
|
|
|
@ -94,7 +94,7 @@ IDTypeInfo IDType_ID_SPK = {
|
|||
.foreach_id = speaker_foreach_id,
|
||||
.foreach_cache = NULL,
|
||||
.foreach_path = NULL,
|
||||
.owner_get = NULL,
|
||||
.owner_pointer_get = NULL,
|
||||
|
||||
.blend_write = speaker_blend_write,
|
||||
.blend_read_data = speaker_blend_read_data,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue