Merge branch 'master' into refactor-mesh-selection-generic

This commit is contained in:
Hans Goudey 2022-09-10 16:48:49 -05:00
commit b1fd951c59
248 changed files with 4575 additions and 3379 deletions

View File

@ -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$"

View File

@ -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."
)

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -146,6 +146,8 @@ class BlenderSession {
BlenderDisplayDriver *display_driver_ = nullptr;
vector<string> full_buffer_files_;
int bake_id = 0;
};
CCL_NAMESPACE_END

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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);
}

View File

@ -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. */

View File

@ -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

View File

@ -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

View File

@ -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), &params);
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

View File

@ -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), &params);
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

View File

@ -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

View File

@ -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), &params); \
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

View File

@ -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

View File

@ -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

View File

@ -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;
};

View File

@ -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 */

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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,

View File

@ -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();
}

View File

@ -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,

View File

@ -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)

View File

@ -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;

View File

@ -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) {

View File

@ -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")

View File

@ -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")

View File

@ -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. */

View File

@ -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);

View File

@ -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. ********** */

View File

@ -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.
*/

View File

@ -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);

View File

@ -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

View File

@ -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) */

View File

@ -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.
*/

View File

@ -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

View File

@ -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]);

View File

@ -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()

View File

@ -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,

View File

@ -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;
}

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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));

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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. */

View File

@ -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));

View File

@ -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));
}

View File

@ -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(

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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', ");
}

View File

@ -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
* \{ */

View File

@ -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++) {

View File

@ -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 */

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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;

View File

@ -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. */

View File

@ -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,

View File

@ -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,

View File

@ -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