MaterialX: code improvements shader modes. #35

Merged
307 changed files with 3648 additions and 1703 deletions
Showing only changes of commit 48401e064c - Show all commits

View File

@ -537,12 +537,12 @@ static ShaderNode *add_node(Scene *scene,
case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY: case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY:
subsurface->set_method(CLOSURE_BSSRDF_BURLEY_ID); subsurface->set_method(CLOSURE_BSSRDF_BURLEY_ID);
break; break;
case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK_FIXED_RADIUS:
subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
break;
case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK: case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK:
subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_ID); subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
break; break;
case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK_SKIN:
subsurface->set_method(CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
break;
} }
node = subsurface; node = subsurface;
@ -651,12 +651,12 @@ static ShaderNode *add_node(Scene *scene,
case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY: case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
principled->set_subsurface_method(CLOSURE_BSSRDF_BURLEY_ID); principled->set_subsurface_method(CLOSURE_BSSRDF_BURLEY_ID);
break; break;
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK_FIXED_RADIUS:
principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
break;
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK: case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_ID); principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_ID);
break; break;
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK_SKIN:
principled->set_subsurface_method(CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
break;
} }
node = principled; node = principled;
} }

View File

@ -814,14 +814,14 @@ BVHNode *BVHBuild::build_node(const BVHRange &range,
BVHMixedSplit unaligned_split; BVHMixedSplit unaligned_split;
float unalignedSplitSAH = FLT_MAX; float unalignedSplitSAH = FLT_MAX;
/* float unalignedLeafSAH = FLT_MAX; */ // float unalignedLeafSAH = FLT_MAX;
Transform aligned_space; Transform aligned_space;
bool do_unalinged_split = false; bool do_unalinged_split = false;
if (params.use_unaligned_nodes && splitSAH > params.unaligned_split_threshold * leafSAH) { if (params.use_unaligned_nodes && splitSAH > params.unaligned_split_threshold * leafSAH) {
aligned_space = unaligned_heuristic.compute_aligned_space(range, &references.at(0)); aligned_space = unaligned_heuristic.compute_aligned_space(range, &references.at(0));
unaligned_split = BVHMixedSplit( unaligned_split = BVHMixedSplit(
this, storage, range, references, level, &unaligned_heuristic, &aligned_space); this, storage, range, references, level, &unaligned_heuristic, &aligned_space);
/* unalignedLeafSAH = params.sah_primitive_cost * split.leafSAH; */ // unalignedLeafSAH = params.sah_primitive_cost * split.leafSAH;
unalignedSplitSAH = params.sah_node_cost * unaligned_split.bounds.half_area() + unalignedSplitSAH = params.sah_node_cost * unaligned_split.bounds.half_area() +
params.sah_primitive_cost * unaligned_split.nodeSAH; params.sah_primitive_cost * unaligned_split.nodeSAH;
/* TODO(sergey): Check we can create leaf already. */ /* TODO(sergey): Check we can create leaf already. */

View File

@ -1178,6 +1178,7 @@ bool BVHMetal::build(Progress &progress,
} }
} }
@autoreleasepool {
if (!params.top_level) { if (!params.top_level) {
return build_BLAS(progress, device, queue, refit); return build_BLAS(progress, device, queue, refit);
} }
@ -1185,6 +1186,7 @@ bool BVHMetal::build(Progress &progress,
return build_TLAS(progress, device, queue, refit); return build_TLAS(progress, device, queue, refit);
} }
} }
}
CCL_NAMESPACE_END CCL_NAMESPACE_END

View File

@ -47,6 +47,7 @@ class MetalDevice : public Device {
MetalGPUVendor device_vendor; MetalGPUVendor device_vendor;
uint kernel_features; uint kernel_features;
bool using_nanovdb = false;
MTLResourceOptions default_storage_mode; MTLResourceOptions default_storage_mode;
int max_threads_per_threadgroup; int max_threads_per_threadgroup;

View File

@ -347,7 +347,9 @@ string MetalDevice::preprocess_source(MetalPipelineType pso_type,
case METAL_GPU_APPLE: case METAL_GPU_APPLE:
global_defines += "#define __KERNEL_METAL_APPLE__\n"; global_defines += "#define __KERNEL_METAL_APPLE__\n";
# ifdef WITH_NANOVDB # ifdef WITH_NANOVDB
if (DebugFlags().metal.use_nanovdb) { /* Compiling in NanoVDB results in a marginal drop in render perf, so disable it for
* specialized PSOs when no textures are using it. */
if ((pso_type == PSO_GENERIC || using_nanovdb) && DebugFlags().metal.use_nanovdb) {
global_defines += "#define WITH_NANOVDB\n"; global_defines += "#define WITH_NANOVDB\n";
} }
# endif # endif
@ -1088,6 +1090,14 @@ void MetalDevice::tex_alloc_as_buffer(device_texture &mem)
texture_info[slot].data = *(uint64_t *)((uint64_t)buffer_bindings_1d.contents + offset); texture_info[slot].data = *(uint64_t *)((uint64_t)buffer_bindings_1d.contents + offset);
texture_slot_map[slot] = nil; texture_slot_map[slot] = nil;
need_texture_info = true; need_texture_info = true;
if (mem.info.data_type == IMAGE_DATA_TYPE_NANOVDB_FLOAT ||
mem.info.data_type == IMAGE_DATA_TYPE_NANOVDB_FLOAT3 ||
mem.info.data_type == IMAGE_DATA_TYPE_NANOVDB_FPN ||
mem.info.data_type == IMAGE_DATA_TYPE_NANOVDB_FP16)
{
using_nanovdb = true;
}
} }
void MetalDevice::tex_alloc(device_texture &mem) void MetalDevice::tex_alloc(device_texture &mem)

View File

@ -359,7 +359,7 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg,
case CLOSURE_BSDF_DIFFUSE_ID: case CLOSURE_BSDF_DIFFUSE_ID:
case CLOSURE_BSSRDF_BURLEY_ID: case CLOSURE_BSSRDF_BURLEY_ID:
case CLOSURE_BSSRDF_RANDOM_WALK_ID: case CLOSURE_BSSRDF_RANDOM_WALK_ID:
case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID: case CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID:
label = LABEL_REFLECT | LABEL_DIFFUSE; label = LABEL_REFLECT | LABEL_DIFFUSE;
break; break;
#ifdef __SVM__ #ifdef __SVM__

View File

@ -26,6 +26,7 @@ enum MicrofacetFresnel {
DIELECTRIC_TINT, /* used by the OSL MaterialX closures */ DIELECTRIC_TINT, /* used by the OSL MaterialX closures */
CONDUCTOR, CONDUCTOR,
GENERALIZED_SCHLICK, GENERALIZED_SCHLICK,
F82_TINT,
}; };
typedef struct FresnelDielectricTint { typedef struct FresnelDielectricTint {
@ -46,6 +47,13 @@ typedef struct FresnelGeneralizedSchlick {
float exponent; float exponent;
} FresnelGeneralizedSchlick; } FresnelGeneralizedSchlick;
typedef struct FresnelF82Tint {
/* Perpendicular reflectivity. */
Spectrum f0;
/* Precomputed (1-cos)^6 factor for edge tint. */
Spectrum b;
} FresnelF82Tint;
typedef struct MicrofacetBsdf { typedef struct MicrofacetBsdf {
SHADER_CLOSURE_BASE; SHADER_CLOSURE_BASE;
@ -236,6 +244,17 @@ ccl_device_forceinline void microfacet_fresnel(ccl_private const MicrofacetBsdf
*r_reflectance = fresnel_conductor(cos_theta_i, fresnel->n, fresnel->k); *r_reflectance = fresnel_conductor(cos_theta_i, fresnel->n, fresnel->k);
*r_transmittance = zero_spectrum(); *r_transmittance = zero_spectrum();
} }
else if (bsdf->fresnel_type == MicrofacetFresnel::F82_TINT) {
/* F82-Tint model, described in "Novel aspects of the Adobe Standard Material" by Kutz et al.
* Essentially, this is the usual Schlick Fresnel with an additional cosI*(1-cosI)^6
* term which modulates the reflectivity around acos(1/7) degrees (ca. 82°). */
ccl_private FresnelF82Tint *fresnel = (ccl_private FresnelF82Tint *)bsdf->fresnel;
const float mu = saturatef(1.0f - cos_theta_i);
const float mu5 = sqr(sqr(mu)) * mu;
const Spectrum F_schlick = mix(fresnel->f0, one_spectrum(), mu5);
*r_reflectance = saturate(F_schlick - fresnel->b * cos_theta_i * mu5 * mu);
*r_transmittance = zero_spectrum();
}
else if (bsdf->fresnel_type == MicrofacetFresnel::GENERALIZED_SCHLICK) { else if (bsdf->fresnel_type == MicrofacetFresnel::GENERALIZED_SCHLICK) {
ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *) ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *)
bsdf->fresnel; bsdf->fresnel;
@ -379,6 +398,14 @@ ccl_device Spectrum bsdf_microfacet_estimate_albedo(KernelGlobals kg,
} }
reflectance = mix(fresnel->f0, fresnel->f90, s) * fresnel->reflection_tint; reflectance = mix(fresnel->f0, fresnel->f90, s) * fresnel->reflection_tint;
} }
else if (bsdf->fresnel_type == MicrofacetFresnel::F82_TINT) {
ccl_private FresnelF82Tint *fresnel = (ccl_private FresnelF82Tint *)bsdf->fresnel;
float rough = sqrtf(sqrtf(bsdf->alpha_x * bsdf->alpha_y));
const float s = lookup_table_read_3D(
kg, rough, cos_NI, 0.5f, kernel_data.tables.ggx_gen_schlick_s, 16, 16, 16);
/* TODO: Precompute B factor term and account for it here. */
reflectance = mix(fresnel->f0, one_spectrum(), s);
}
return reflectance + transmittance; return reflectance + transmittance;
} }
@ -738,6 +765,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
ccl_private FresnelGeneralizedSchlick *fresnel, ccl_private FresnelGeneralizedSchlick *fresnel,
const bool preserve_energy) const bool preserve_energy)
{ {
fresnel->f0 = saturate(fresnel->f0);
bsdf->fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK; bsdf->fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK;
bsdf->fresnel = fresnel; bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true)); bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
@ -780,6 +808,40 @@ ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
} }
} }
ccl_device void bsdf_microfacet_setup_fresnel_f82_tint(KernelGlobals kg,
ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd,
ccl_private FresnelF82Tint *fresnel,
const Spectrum f82_tint,
const bool preserve_energy)
{
if (isequal(f82_tint, one_spectrum())) {
fresnel->b = zero_spectrum();
}
else {
/* Precompute the F82 term factor for the Fresnel model.
* In the classic F82 model, the F82 input directly determines the value of the Fresnel
* model at ~82°, similar to F0 and F90.
* With F82-Tint, on the other hand, the value at 82° is the value of the classic Schlick
* model multiplied by the tint input.
* Therefore, the factor follows by setting F82Tint(cosI) = FSchlick(cosI) - b*cosI*(1-cosI)^6
* and F82Tint(acos(1/7)) = FSchlick(acos(1/7)) * f82_tint and solving for b. */
const float f = 6.0f / 7.0f;
const float f5 = sqr(sqr(f)) * f;
const Spectrum F_schlick = mix(fresnel->f0, one_spectrum(), f5);
fresnel->b = F_schlick * (7.0f / (f5 * f)) * (one_spectrum() - f82_tint);
}
bsdf->fresnel_type = MicrofacetFresnel::F82_TINT;
bsdf->fresnel = fresnel;
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
if (preserve_energy) {
Spectrum Fss = mix(fresnel->f0, one_spectrum(), 1.0f / 21.0f) - fresnel->b * (1.0f / 126.0f);
microfacet_ggx_preserve_energy(kg, bsdf, sd, Fss);
}
}
ccl_device void bsdf_microfacet_setup_fresnel_constant(KernelGlobals kg, ccl_device void bsdf_microfacet_setup_fresnel_constant(KernelGlobals kg,
ccl_private MicrofacetBsdf *bsdf, ccl_private MicrofacetBsdf *bsdf,
ccl_private const ShaderData *sd, ccl_private const ShaderData *sd,

View File

@ -59,7 +59,7 @@ ccl_device float bssrdf_dipole_compute_alpha_prime(float rd, float fourthirdA)
ccl_device void bssrdf_setup_radius(ccl_private Bssrdf *bssrdf, const ClosureType type) ccl_device void bssrdf_setup_radius(ccl_private Bssrdf *bssrdf, const ClosureType type)
{ {
if (type == CLOSURE_BSSRDF_BURLEY_ID || type == CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID) { if (type == CLOSURE_BSSRDF_BURLEY_ID || type == CLOSURE_BSSRDF_RANDOM_WALK_ID) {
/* Scale mean free path length so it gives similar looking result to older /* Scale mean free path length so it gives similar looking result to older
* Cubic, Gaussian and Burley models. */ * Cubic, Gaussian and Burley models. */
bssrdf->radius *= 0.25f * M_1_PI_F; bssrdf->radius *= 0.25f * M_1_PI_F;
@ -291,8 +291,8 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd,
int flag = 0; int flag = 0;
if (type == CLOSURE_BSSRDF_RANDOM_WALK_ID) { if (type == CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID) {
/* CLOSURE_BSSRDF_RANDOM_WALK_ID uses a fixed roughness. */ /* CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID uses a fixed roughness. */
bssrdf->alpha = 1.0f; bssrdf->alpha = 1.0f;
} }

View File

@ -31,8 +31,8 @@ ccl_device_inline bool subsurface_entry_bounce(KernelGlobals kg,
{ {
float2 rand_bsdf = path_state_rng_2D(kg, rng_state, PRNG_SUBSURFACE_BSDF); float2 rand_bsdf = path_state_rng_2D(kg, rng_state, PRNG_SUBSURFACE_BSDF);
if (bssrdf->type == CLOSURE_BSSRDF_RANDOM_WALK_ID) { if (bssrdf->type == CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID) {
/* CLOSURE_BSSRDF_RANDOM_WALK_ID has a 50% chance to sample a diffuse entry bounce. /* CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID has a 50% chance to sample a diffuse entry bounce.
* Also, for the refractive entry, it uses a fixed roughness of 1.0. */ * Also, for the refractive entry, it uses a fixed roughness of 1.0. */
if (rand_bsdf.x < 0.5f) { if (rand_bsdf.x < 0.5f) {
rand_bsdf.x *= 2.0f; rand_bsdf.x *= 2.0f;

View File

@ -474,6 +474,53 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
/* Special-purpose Microfacet closures */ /* Special-purpose Microfacet closures */
ccl_device void osl_closure_microfacet_f82_tint_setup(
KernelGlobals kg,
ccl_private ShaderData *sd,
uint32_t path_flag,
float3 weight,
ccl_private const MicrofacetF82TintClosure *closure,
float3 *layer_albedo)
{
if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
return;
}
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight));
if (!bsdf) {
return;
}
ccl_private FresnelF82Tint *fresnel = (ccl_private FresnelF82Tint *)closure_alloc_extra(
sd, sizeof(FresnelF82Tint));
if (!fresnel) {
return;
}
bsdf->N = maybe_ensure_valid_specular_reflection(sd, closure->N);
bsdf->alpha_x = closure->alpha_x;
bsdf->alpha_y = closure->alpha_y;
bsdf->ior = 0.0f;
bsdf->T = closure->T;
bool preserve_energy = false;
/* Beckmann */
if (closure->distribution == make_string("beckmann", 14712237670914973463ull)) {
sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
}
/* GGX (either single- or multi-scattering) */
else {
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
preserve_energy = (closure->distribution == make_string("multi_ggx", 16842698693386468366ull));
}
fresnel->f0 = rgb_to_spectrum(closure->f0);
bsdf_microfacet_setup_fresnel_f82_tint(
kg, bsdf, sd, fresnel, rgb_to_spectrum(closure->f82), preserve_energy);
}
ccl_device void osl_closure_microfacet_multi_ggx_glass_setup( ccl_device void osl_closure_microfacet_multi_ggx_glass_setup(
KernelGlobals kg, KernelGlobals kg,
ccl_private ShaderData *sd, ccl_private ShaderData *sd,
@ -760,12 +807,12 @@ ccl_device void osl_closure_bssrdf_setup(KernelGlobals kg,
if (closure->method == make_string("burley", 186330084368958868ull)) { if (closure->method == make_string("burley", 186330084368958868ull)) {
type = CLOSURE_BSSRDF_BURLEY_ID; type = CLOSURE_BSSRDF_BURLEY_ID;
} }
else if (closure->method == make_string("random_walk_fixed_radius", 5695810351010063150ull)) { else if (closure->method == make_string("random_walk", 5695810351010063150ull)) {
type = CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID;
}
else if (closure->method == make_string("random_walk", 11360609267673527222ull)) {
type = CLOSURE_BSSRDF_RANDOM_WALK_ID; type = CLOSURE_BSSRDF_RANDOM_WALK_ID;
} }
else if (closure->method == make_string("random_walk_skin", 11360609267673527222ull)) {
type = CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID;
}
else { else {
return; return;
} }

View File

@ -84,6 +84,16 @@ OSL_CLOSURE_STRUCT_BEGIN(Microfacet, microfacet)
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, INT, int, refract, NULL) OSL_CLOSURE_STRUCT_MEMBER(Microfacet, INT, int, refract, NULL)
OSL_CLOSURE_STRUCT_END(Microfacet, microfacet) OSL_CLOSURE_STRUCT_END(Microfacet, microfacet)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetF82Tint, microfacet_f82_tint)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetF82Tint, STRING, DeviceString, distribution, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetF82Tint, VECTOR, packed_float3, N, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetF82Tint, VECTOR, packed_float3, T, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetF82Tint, FLOAT, float, alpha_x, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetF82Tint, FLOAT, float, alpha_y, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetF82Tint, VECTOR, packed_float3, f0, NULL)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetF82Tint, VECTOR, packed_float3, f82, NULL)
OSL_CLOSURE_STRUCT_END(MicrofacetF82Tint, microfacet)
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass) OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass)
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, N, NULL) 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, alpha_x, NULL)

View File

@ -73,7 +73,7 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
int layer_stack_level = -1; int layer_stack_level = -1;
float3 layer_albedo = zero_float3(); float3 layer_albedo = zero_float3();
while (closure) { while (true) {
switch (closure->id) { switch (closure->id) {
case OSL_CLOSURE_MUL_ID: { case OSL_CLOSURE_MUL_ID: {
ccl_private const OSLClosureMul *mul = static_cast<ccl_private const OSLClosureMul *>( ccl_private const OSLClosureMul *mul = static_cast<ccl_private const OSLClosureMul *>(
@ -134,7 +134,12 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
break; break;
} }
if (stack_size > 0) { /* Pop the next closure from the stack (or return if we're done). */
do {
if (stack_size == 0) {
return;
}
weight = weight_stack[--stack_size]; weight = weight_stack[--stack_size];
closure = closure_stack[stack_size]; closure = closure_stack[stack_size];
if (stack_size == layer_stack_level) { if (stack_size == layer_stack_level) {
@ -142,22 +147,13 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
* account for the layering. */ * account for the layering. */
weight *= saturatef(1.0f - reduce_max(safe_divide_color(layer_albedo, weight))); weight *= saturatef(1.0f - reduce_max(safe_divide_color(layer_albedo, weight)));
layer_stack_level = -1; layer_stack_level = -1;
if (is_zero(weight)) {
/* If it's fully occluded, skip the base layer we just popped from the stack and grab /* If it's fully occluded, skip the base layer we just popped from the stack and grab
* the next entry instead. */ * the next entry instead. */
if (stack_size > 0) { if (is_zero(weight)) {
weight = weight_stack[--stack_size]; continue;
closure = closure_stack[stack_size];
}
else {
closure = nullptr;
} }
} }
} } while (closure == nullptr);
}
else {
closure = nullptr;
}
} }
} }

View File

@ -42,3 +42,9 @@ float F0_from_ior(float eta)
float f0 = (eta - 1.0) / (eta + 1.0); float f0 = (eta - 1.0) / (eta + 1.0);
return f0 * f0; return f0 * f0;
} }
float ior_from_F0(float f0)
{
float sqrt_f0 = sqrt(clamp(f0, 0.0, 0.99));
return (1.0 + sqrt_f0) / (1.0 - sqrt_f0);
}

View File

@ -8,27 +8,27 @@
shader node_principled_bsdf(string distribution = "multi_ggx", shader node_principled_bsdf(string distribution = "multi_ggx",
string subsurface_method = "random_walk", string subsurface_method = "random_walk",
color BaseColor = color(0.8, 0.8, 0.8), color BaseColor = color(0.8, 0.8, 0.8),
float Subsurface = 0.0, float SubsurfaceWeight = 0.0,
float SubsurfaceScale = 0.1, float SubsurfaceScale = 0.1,
vector SubsurfaceRadius = vector(1.0, 1.0, 1.0), vector SubsurfaceRadius = vector(1.0, 1.0, 1.0),
float SubsurfaceIOR = 1.4, float SubsurfaceIOR = 1.4,
float SubsurfaceAnisotropy = 0.0, float SubsurfaceAnisotropy = 0.0,
float Metallic = 0.0, float Metallic = 0.0,
float Specular = 0.5, float SpecularIORLevel = 0.5,
float SpecularTint = 0.0, color SpecularTint = color(1.0),
float Roughness = 0.5, float Roughness = 0.5,
float Anisotropic = 0.0, float Anisotropic = 0.0,
float AnisotropicRotation = 0.0, float AnisotropicRotation = 0.0,
float Sheen = 0.0, float SheenWeight = 0.0,
float SheenRoughness = 0.5, float SheenRoughness = 0.5,
color SheenTint = 0.5, color SheenTint = 0.5,
float Coat = 0.0, float CoatWeight = 0.0,
float CoatRoughness = 0.03, float CoatRoughness = 0.03,
float CoatIOR = 1.5, float CoatIOR = 1.5,
color CoatTint = color(1.0, 1.0, 1.0), color CoatTint = color(1.0, 1.0, 1.0),
float IOR = 1.45, float IOR = 1.45,
float Transmission = 0.0, float TransmissionWeight = 0.0,
color Emission = 1.0, color EmissionColor = 1.0,
float EmissionStrength = 0.0, float EmissionStrength = 0.0,
float Alpha = 1.0, float Alpha = 1.0,
normal Normal = N, normal Normal = N,
@ -36,7 +36,11 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
normal Tangent = normalize(dPdu), normal Tangent = normalize(dPdu),
output closure color BSDF = 0) output closure color BSDF = 0)
{ {
float r2 = Roughness * Roughness; color specular_tint = max(SpecularTint, color(0.0));
float r2 = clamp(Roughness, 0.0, 1.0);
r2 = r2 * r2;
float alpha_x = r2, alpha_y = r2; float alpha_x = r2, alpha_y = r2;
/* Handle anisotropy. */ /* Handle anisotropy. */
@ -49,11 +53,22 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal); T = rotate(T, AnisotropicRotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
} }
if (Metallic < 1.0 && Transmission < 1.0) { if (Metallic < 1.0 && TransmissionWeight < 1.0) {
float eta = IOR;
float f0 = F0_from_ior(eta);
if (SpecularIORLevel != 0.5) {
f0 *= 2.0 * max(SpecularIORLevel, 0.0);
eta = ior_from_F0(f0);
if (IOR < 1.0) {
eta = 1.0 / eta;
}
}
BSDF = BaseColor * diffuse(Normal); BSDF = BaseColor * diffuse(Normal);
if (Subsurface > 1e-5) { if (SubsurfaceWeight > 1e-5) {
float subsurface_weight = min(SubsurfaceWeight, 1.0);
vector radius = SubsurfaceScale * SubsurfaceRadius; vector radius = SubsurfaceScale * SubsurfaceRadius;
float subsurface_ior = (subsurface_method == "random_walk") ? SubsurfaceIOR : IOR; float subsurface_ior = (subsurface_method == "random_walk_skin") ? SubsurfaceIOR : eta;
closure color SubsurfBSDF = bssrdf(subsurface_method, closure color SubsurfBSDF = bssrdf(subsurface_method,
Normal, Normal,
SubsurfaceScale * SubsurfaceRadius, SubsurfaceScale * SubsurfaceRadius,
@ -64,66 +79,64 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
subsurface_ior, subsurface_ior,
"anisotropy", "anisotropy",
SubsurfaceAnisotropy); SubsurfaceAnisotropy);
BSDF = mix(BSDF, BaseColor * SubsurfBSDF, Subsurface); BSDF = mix(BSDF, BaseColor * SubsurfBSDF, subsurface_weight);
} }
color f0 = color(F0_from_ior(IOR));
color f90 = color(1.0);
/* Apply specular tint */ /* Apply specular tint */
float m_cdlum = luminance(BaseColor); color F0 = f0 * specular_tint;
color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum : color(1.0); color F90 = color(1.0);
color specTint = mix(color(1.0), m_ctint, SpecularTint);
f0 *= (specTint * 2.0 * Specular);
BSDF = layer( BSDF = layer(
generalized_schlick_bsdf( generalized_schlick_bsdf(
Normal, T, color(1.0), color(0.0), alpha_x, alpha_y, f0, f90, -IOR, distribution), Normal, T, color(1.0), color(0.0), alpha_x, alpha_y, F0, F90, -eta, distribution),
BSDF); BSDF);
} }
closure color TransmissionBSDF = 0; closure color TransmissionBSDF = 0;
if (Metallic < 1.0 && Transmission > 0.0) { if (Metallic < 1.0 && TransmissionWeight > 0.0) {
color reflectTint = mix(color(1.0), BaseColor, SpecularTint);
float eta = max(IOR, 1e-5); float eta = max(IOR, 1e-5);
eta = backfacing() ? 1.0 / eta : eta; eta = backfacing() ? 1.0 / eta : eta;
TransmissionBSDF = dielectric_bsdf( color F0 = F0_from_ior(eta) * specular_tint;
Normal, vector(0.0), reflectTint, sqrt(BaseColor), r2, r2, eta, distribution); color F90 = color(1.0);
BSDF = mix(BSDF, TransmissionBSDF, clamp(Transmission, 0.0, 1.0));
TransmissionBSDF = generalized_schlick_bsdf(
Normal, vector(0.0), color(1.0), sqrt(BaseColor), r2, r2, F0, F90, -eta, distribution),
BSDF = mix(BSDF, TransmissionBSDF, clamp(TransmissionWeight, 0.0, 1.0));
} }
closure color MetallicBSDF = 0; closure color MetallicBSDF = 0;
if (Metallic > 0.0) { if (Metallic > 0.0) {
color f0 = BaseColor; color F0 = BaseColor;
color f90 = color(1.0); color F82 = specular_tint;
MetallicBSDF = generalized_schlick_bsdf( MetallicBSDF = microfacet_f82_tint(distribution, Normal, T, alpha_x, alpha_y, F0, F82);
Normal, T, color(1.0), color(0.0), alpha_x, alpha_y, f0, f90, 5.0, distribution);
BSDF = mix(BSDF, MetallicBSDF, clamp(Metallic, 0.0, 1.0)); BSDF = mix(BSDF, MetallicBSDF, clamp(Metallic, 0.0, 1.0));
} }
if (EmissionStrength > 0.0 && Emission != color(0.0)) { if (EmissionStrength > 0.0 && EmissionColor != color(0.0)) {
BSDF += EmissionStrength * Emission * emission(); BSDF += EmissionStrength * EmissionColor * emission();
} }
if (Coat > 1e-5) { if (CoatWeight > 1e-5) {
float coat_ior = max(CoatIOR, 1.0); float coat_ior = max(CoatIOR, 1.0);
if (CoatTint != color(1.0)) { if (CoatTint != color(1.0)) {
float coat_neta = 1.0 / coat_ior; float coat_neta = 1.0 / coat_ior;
float cosNI = dot(I, CoatNormal); float cosNI = dot(I, CoatNormal);
float cosNT = sqrt(1.0 - coat_neta * coat_neta * (1 - cosNI * cosNI)); float cosNT = sqrt(1.0 - coat_neta * coat_neta * (1 - cosNI * cosNI));
BSDF *= pow(CoatTint, Coat / cosNT); BSDF *= pow(CoatTint, CoatWeight / cosNT);
} }
float coat_r2 = CoatRoughness * CoatRoughness; float coat_r2 = clamp(CoatRoughness, 0.0, 1.0);
coat_r2 = coat_r2 * coat_r2;
closure color CoatBSDF = dielectric_bsdf( closure color CoatBSDF = dielectric_bsdf(
CoatNormal, vector(0.0), color(1.0), color(0.0), coat_r2, coat_r2, coat_ior, "ggx"); CoatNormal, vector(0.0), color(1.0), color(0.0), coat_r2, coat_r2, coat_ior, "ggx");
BSDF = layer(Coat * CoatBSDF, BSDF); BSDF = layer(clamp(CoatWeight, 0.0, 1.0) * CoatBSDF, BSDF);
} }
if (Sheen > 1e-5) { if (SheenWeight > 1e-5) {
closure color SheenBSDF = sheen(Normal, SheenRoughness); closure color SheenBSDF = sheen(Normal, clamp(SheenRoughness, 0.0, 1.0));
BSDF = layer(SheenTint * Sheen * SheenBSDF, BSDF); BSDF = layer(clamp(SheenWeight, 0.0, 1.0) * SheenTint * SheenBSDF, BSDF);
} }
BSDF = mix(transparent(), BSDF, Alpha); BSDF = mix(transparent(), BSDF, clamp(Alpha, 0.0, 1.0));
} }

View File

@ -26,6 +26,9 @@ closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
closure color sheen(normal N, float roughness) BUILTIN; closure color sheen(normal N, float roughness) BUILTIN;
closure color ambient_occlusion() BUILTIN; closure color ambient_occlusion() BUILTIN;
closure color microfacet_f82_tint(
string distribution, vector N, vector T, float ax, float ay, color f0, color f82) BUILTIN;
/* Needed to pass along the color for multi-scattering saturation adjustment, /* Needed to pass along the color for multi-scattering saturation adjustment,
* otherwise could be replaced by microfacet() */ * otherwise could be replaced by microfacet() */
closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN; closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN;

View File

@ -128,10 +128,10 @@ ccl_device_inline float3 sample_uniform_cone(const float3 N,
float2 xy = sample_uniform_disk(rand); float2 xy = sample_uniform_disk(rand);
const float r2 = len_squared(xy); const float r2 = len_squared(xy);
/* Equivalent to `mix(cos_angle, 1.0f, 1.0f - r2)` */ /* Equivalent to `mix(cos_angle, 1.0f, 1.0f - r2)`. */
*cos_theta = 1.0f - r2 * one_minus_cos_angle; *cos_theta = 1.0f - r2 * one_minus_cos_angle;
/* Remap disk radius to cone radius, equivalent to `xy *= sin_theta / sqrt(r2); */ /* Remap disk radius to cone radius, equivalent to `xy *= sin_theta / sqrt(r2)`. */
xy *= safe_sqrtf(one_minus_cos_angle * (2.0f - one_minus_cos_angle * r2)); xy *= safe_sqrtf(one_minus_cos_angle * (2.0f - one_minus_cos_angle * r2));
*pdf = M_1_2PI_F / one_minus_cos_angle; *pdf = M_1_2PI_F / one_minus_cos_angle;

View File

@ -74,46 +74,50 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
switch (type) { switch (type) {
case CLOSURE_BSDF_PRINCIPLED_ID: { case CLOSURE_BSDF_PRINCIPLED_ID: {
uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset, uint specular_ior_level_offset, roughness_offset, specular_tint_offset, anisotropic_offset,
sheen_offset, sheen_tint_offset, sheen_roughness_offset, coat_offset, sheen_weight_offset, sheen_tint_offset, sheen_roughness_offset, coat_weight_offset,
coat_roughness_offset, coat_ior_offset, eta_offset, transmission_offset, coat_roughness_offset, coat_ior_offset, eta_offset, transmission_weight_offset,
anisotropic_rotation_offset, coat_tint_offset, coat_normal_offset, dummy, alpha_offset, anisotropic_rotation_offset, coat_tint_offset, coat_normal_offset, dummy, alpha_offset,
emission_strength_offset, emission_offset; emission_strength_offset, emission_offset, unused;
uint4 data_node2 = read_node(kg, &offset); uint4 data_node2 = read_node(kg, &offset);
float3 T = stack_load_float3(stack, data_node.y); float3 T = stack_load_float3(stack, data_node.y);
svm_unpack_node_uchar4(data_node.z, svm_unpack_node_uchar4(data_node.z,
&specular_offset, &specular_ior_level_offset,
&roughness_offset, &roughness_offset,
&specular_tint_offset, &specular_tint_offset,
&anisotropic_offset); &anisotropic_offset);
svm_unpack_node_uchar4( svm_unpack_node_uchar4(
data_node.w, &sheen_offset, &sheen_tint_offset, &sheen_roughness_offset, &dummy); data_node.w, &sheen_weight_offset, &sheen_tint_offset, &sheen_roughness_offset, &unused);
svm_unpack_node_uchar4(data_node2.x, svm_unpack_node_uchar4(data_node2.x,
&eta_offset, &eta_offset,
&transmission_offset, &transmission_weight_offset,
&anisotropic_rotation_offset, &anisotropic_rotation_offset,
&coat_normal_offset); &coat_normal_offset);
svm_unpack_node_uchar4( svm_unpack_node_uchar4(data_node2.w,
data_node2.w, &coat_offset, &coat_roughness_offset, &coat_ior_offset, &coat_tint_offset); &coat_weight_offset,
&coat_roughness_offset,
&coat_ior_offset,
&coat_tint_offset);
// get Disney principled parameters // get Disney principled parameters
float metallic = saturatef(param1); float metallic = saturatef(param1);
float subsurface = param2; float subsurface_weight = saturatef(param2);
float specular = stack_load_float(stack, specular_offset); float specular_ior_level = fmaxf(stack_load_float(stack, specular_ior_level_offset), 0.0f);
float roughness = stack_load_float(stack, roughness_offset); float roughness = saturatef(stack_load_float(stack, roughness_offset));
float specular_tint = stack_load_float(stack, specular_tint_offset); Spectrum specular_tint = rgb_to_spectrum(
float anisotropic = stack_load_float(stack, anisotropic_offset); max(stack_load_float3(stack, specular_tint_offset), zero_float3()));
float sheen = stack_load_float(stack, sheen_offset); float anisotropic = saturatef(stack_load_float(stack, anisotropic_offset));
float sheen_weight = saturatef(stack_load_float(stack, sheen_weight_offset));
float3 sheen_tint = stack_load_float3(stack, sheen_tint_offset); float3 sheen_tint = stack_load_float3(stack, sheen_tint_offset);
float sheen_roughness = stack_load_float(stack, sheen_roughness_offset); float sheen_roughness = saturatef(stack_load_float(stack, sheen_roughness_offset));
float coat = stack_load_float(stack, coat_offset); float coat_weight = saturatef(stack_load_float(stack, coat_weight_offset));
float coat_roughness = stack_load_float(stack, coat_roughness_offset); float coat_roughness = saturatef(stack_load_float(stack, coat_roughness_offset));
float coat_ior = fmaxf(stack_load_float(stack, coat_ior_offset), 1.0f); float coat_ior = fmaxf(stack_load_float(stack, coat_ior_offset), 1.0f);
float3 coat_tint = stack_load_float3(stack, coat_tint_offset); float3 coat_tint = stack_load_float3(stack, coat_tint_offset);
float transmission = saturatef(stack_load_float(stack, transmission_offset)); float transmission_weight = saturatef(stack_load_float(stack, transmission_weight_offset));
float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset); float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f); float ior = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
ClosureType distribution = (ClosureType)data_node2.y; ClosureType distribution = (ClosureType)data_node2.y;
ClosureType subsurface_method = (ClosureType)data_node2.z; ClosureType subsurface_method = (ClosureType)data_node2.z;
@ -139,17 +143,18 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
&dummy); &dummy);
float alpha = stack_valid(alpha_offset) ? stack_load_float(stack, alpha_offset) : float alpha = stack_valid(alpha_offset) ? stack_load_float(stack, alpha_offset) :
__uint_as_float(data_alpha_emission.y); __uint_as_float(data_alpha_emission.y);
float3 emission = stack_load_float3(stack, emission_offset); alpha = saturatef(alpha);
/* Emission strength */
emission *= stack_valid(emission_strength_offset) ? float emission_strength = stack_valid(emission_strength_offset) ?
stack_load_float(stack, emission_strength_offset) : stack_load_float(stack, emission_strength_offset) :
__uint_as_float(data_alpha_emission.z); __uint_as_float(data_alpha_emission.z);
float3 emission = stack_load_float3(stack, emission_offset) * fmaxf(emission_strength, 0.0f);
Spectrum weight = closure_weight * mix_weight; Spectrum weight = closure_weight * mix_weight;
float alpha_x = sqr(roughness), alpha_y = sqr(roughness); float alpha_x = sqr(roughness), alpha_y = sqr(roughness);
if (anisotropic > 0.0f) { if (anisotropic > 0.0f) {
float aspect = sqrtf(1.0f - saturatef(anisotropic) * 0.9f); float aspect = sqrtf(1.0f - anisotropic * 0.9f);
alpha_x /= aspect; alpha_x /= aspect;
alpha_y *= aspect; alpha_y *= aspect;
if (anisotropic_rotation != 0.0f) if (anisotropic_rotation != 0.0f)
@ -174,9 +179,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
} }
/* First layer: Sheen */ /* First layer: Sheen */
if (sheen > CLOSURE_WEIGHT_CUTOFF) { if (sheen_weight > CLOSURE_WEIGHT_CUTOFF) {
ccl_private SheenBsdf *bsdf = (ccl_private SheenBsdf *)bsdf_alloc( ccl_private SheenBsdf *bsdf = (ccl_private SheenBsdf *)bsdf_alloc(
sd, sizeof(SheenBsdf), sheen * rgb_to_spectrum(sheen_tint) * weight); sd, sizeof(SheenBsdf), sheen_weight * rgb_to_spectrum(sheen_tint) * weight);
if (bsdf) { if (bsdf) {
bsdf->N = N; bsdf->N = N;
@ -192,14 +197,14 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
} }
/* Second layer: Coat */ /* Second layer: Coat */
if (coat > CLOSURE_WEIGHT_CUTOFF) { if (coat_weight > CLOSURE_WEIGHT_CUTOFF) {
float3 coat_normal = stack_valid(coat_normal_offset) ? float3 coat_normal = stack_valid(coat_normal_offset) ?
stack_load_float3(stack, coat_normal_offset) : stack_load_float3(stack, coat_normal_offset) :
sd->N; sd->N;
coat_normal = maybe_ensure_valid_specular_reflection(sd, coat_normal); coat_normal = maybe_ensure_valid_specular_reflection(sd, coat_normal);
if (reflective_caustics) { if (reflective_caustics) {
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), coat * weight); sd, sizeof(MicrofacetBsdf), coat_weight * weight);
if (bsdf) { if (bsdf) {
bsdf->N = coat_normal; bsdf->N = coat_normal;
@ -242,7 +247,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
* TIR is no concern here since we're always coming from the outside. */ * TIR is no concern here since we're always coming from the outside. */
float cosNT = sqrtf(1.0f - sqr(1.0f / coat_ior) * (1 - sqr(cosNI))); float cosNT = sqrtf(1.0f - sqr(1.0f / coat_ior) * (1 - sqr(cosNI)));
float optical_depth = 1.0f / cosNT; float optical_depth = 1.0f / cosNT;
weight *= power(rgb_to_spectrum(coat_tint), coat * optical_depth); weight *= power(rgb_to_spectrum(coat_tint), coat_weight * optical_depth);
} }
} }
@ -255,9 +260,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (reflective_caustics && metallic > CLOSURE_WEIGHT_CUTOFF) { if (reflective_caustics && metallic > CLOSURE_WEIGHT_CUTOFF) {
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), metallic * weight); sd, sizeof(MicrofacetBsdf), metallic * weight);
ccl_private FresnelGeneralizedSchlick *fresnel = ccl_private FresnelF82Tint *fresnel =
(bsdf != NULL) ? (ccl_private FresnelGeneralizedSchlick *)closure_alloc_extra( (bsdf != NULL) ?
sd, sizeof(FresnelGeneralizedSchlick)) : (ccl_private FresnelF82Tint *)closure_alloc_extra(sd, sizeof(FresnelF82Tint)) :
NULL; NULL;
if (bsdf && fresnel) { if (bsdf && fresnel) {
@ -268,15 +273,12 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
bsdf->alpha_y = alpha_y; bsdf->alpha_y = alpha_y;
fresnel->f0 = rgb_to_spectrum(base_color); fresnel->f0 = rgb_to_spectrum(base_color);
fresnel->f90 = one_spectrum(); const Spectrum f82 = specular_tint;
fresnel->exponent = 5.0f;
fresnel->reflection_tint = one_spectrum();
fresnel->transmission_tint = zero_spectrum();
/* setup bsdf */ /* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_setup(bsdf); sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx); bsdf_microfacet_setup_fresnel_f82_tint(kg, bsdf, sd, fresnel, f82, is_multiggx);
/* Attenuate other components */ /* Attenuate other components */
weight *= (1.0f - metallic); weight *= (1.0f - metallic);
@ -284,12 +286,12 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
} }
/* Transmission component */ /* Transmission component */
if (glass_caustics && transmission > CLOSURE_WEIGHT_CUTOFF) { if (glass_caustics && transmission_weight > CLOSURE_WEIGHT_CUTOFF) {
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), transmission * weight); sd, sizeof(MicrofacetBsdf), transmission_weight * weight);
ccl_private FresnelDielectricTint *fresnel = ccl_private FresnelGeneralizedSchlick *fresnel =
(bsdf != NULL) ? (ccl_private FresnelDielectricTint *)closure_alloc_extra( (bsdf != NULL) ? (ccl_private FresnelGeneralizedSchlick *)closure_alloc_extra(
sd, sizeof(FresnelDielectricTint)) : sd, sizeof(FresnelGeneralizedSchlick)) :
NULL; NULL;
if (bsdf && fresnel) { if (bsdf && fresnel) {
@ -297,19 +299,21 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
bsdf->T = zero_float3(); bsdf->T = zero_float3();
bsdf->alpha_x = bsdf->alpha_y = sqr(roughness); bsdf->alpha_x = bsdf->alpha_y = sqr(roughness);
bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / ior : ior;
fresnel->reflection_tint = mix( fresnel->f0 = make_float3(F0_from_ior(ior));
one_spectrum(), rgb_to_spectrum(base_color), specular_tint); fresnel->f90 = one_spectrum();
fresnel->exponent = -ior;
fresnel->reflection_tint = one_spectrum();
fresnel->transmission_tint = sqrt(rgb_to_spectrum(base_color)); fresnel->transmission_tint = sqrt(rgb_to_spectrum(base_color));
/* setup bsdf */ /* setup bsdf */
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
bsdf_microfacet_setup_fresnel_dielectric_tint(kg, bsdf, sd, fresnel, is_multiggx); bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
/* Attenuate other components */ /* Attenuate other components */
weight *= (1.0f - transmission); weight *= (1.0f - transmission_weight);
} }
} }
@ -323,17 +327,24 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
NULL; NULL;
if (bsdf && fresnel) { if (bsdf && fresnel) {
/* Apply IOR adjustment */
float eta = ior;
float f0 = F0_from_ior(eta);
if (specular_ior_level != 0.5f) {
f0 *= 2.0f * specular_ior_level;
eta = ior_from_F0(f0);
if (ior < 1.0f) {
eta = 1.0f / eta;
}
}
bsdf->N = valid_reflection_N; bsdf->N = valid_reflection_N;
bsdf->ior = eta; bsdf->ior = eta;
bsdf->T = T; bsdf->T = T;
bsdf->alpha_x = alpha_x; bsdf->alpha_x = alpha_x;
bsdf->alpha_y = alpha_y; bsdf->alpha_y = alpha_y;
float m_cdlum = linear_rgb_to_gray(kg, base_color); fresnel->f0 = f0 * specular_tint;
float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : one_float3();
float3 specTint = mix(one_spectrum(), rgb_to_spectrum(m_ctint), specular_tint);
fresnel->f0 = F0_from_ior(eta) * 2.0f * specular * specTint;
fresnel->f90 = one_spectrum(); fresnel->f90 = one_spectrum();
fresnel->exponent = -eta; fresnel->exponent = -eta;
fresnel->reflection_tint = one_spectrum(); fresnel->reflection_tint = one_spectrum();
@ -352,8 +363,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
/* Diffuse/Subsurface component */ /* Diffuse/Subsurface component */
#ifdef __SUBSURFACE__ #ifdef __SUBSURFACE__
ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, ccl_private Bssrdf *bssrdf = bssrdf_alloc(
rgb_to_spectrum(base_color) * subsurface * weight); sd, rgb_to_spectrum(base_color) * subsurface_weight * weight);
if (bssrdf) { if (bssrdf) {
float3 subsurface_radius = stack_load_float3(stack, data_subsurf.y); float3 subsurface_radius = stack_load_float3(stack, data_subsurf.y);
float subsurface_scale = stack_load_float(stack, data_subsurf.z); float subsurface_scale = stack_load_float(stack, data_subsurf.z);
@ -362,9 +373,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
bssrdf->albedo = rgb_to_spectrum(base_color); bssrdf->albedo = rgb_to_spectrum(base_color);
bssrdf->N = N; bssrdf->N = N;
bssrdf->alpha = sqr(roughness); bssrdf->alpha = sqr(roughness);
bssrdf->ior = eta; bssrdf->ior = ior;
bssrdf->anisotropy = stack_load_float(stack, data_subsurf.w); bssrdf->anisotropy = stack_load_float(stack, data_subsurf.w);
if (subsurface_method == CLOSURE_BSSRDF_RANDOM_WALK_ID) { if (subsurface_method == CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID) {
bssrdf->ior = stack_load_float(stack, data_subsurf.x); bssrdf->ior = stack_load_float(stack, data_subsurf.x);
} }
@ -372,11 +383,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
sd->flag |= bssrdf_setup(sd, bssrdf, path_flag, subsurface_method); sd->flag |= bssrdf_setup(sd, bssrdf, path_flag, subsurface_method);
} }
#else #else
subsurface = 0.0f; subsurface_weight = 0.0f;
#endif #endif
ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc( ccl_private DiffuseBsdf *bsdf = (ccl_private DiffuseBsdf *)bsdf_alloc(
sd, sizeof(DiffuseBsdf), rgb_to_spectrum(base_color) * (1.0f - subsurface) * weight); sd,
sizeof(DiffuseBsdf),
rgb_to_spectrum(base_color) * (1.0f - subsurface_weight) * weight);
if (bsdf) { if (bsdf) {
bsdf->N = N; bsdf->N = N;
@ -804,7 +817,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
#ifdef __SUBSURFACE__ #ifdef __SUBSURFACE__
case CLOSURE_BSSRDF_BURLEY_ID: case CLOSURE_BSSRDF_BURLEY_ID:
case CLOSURE_BSSRDF_RANDOM_WALK_ID: case CLOSURE_BSSRDF_RANDOM_WALK_ID:
case CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID: { case CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID: {
Spectrum weight = closure_weight * mix_weight; Spectrum weight = closure_weight * mix_weight;
ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight); ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight);

View File

@ -453,7 +453,7 @@ typedef enum ClosureType {
/* BSSRDF */ /* BSSRDF */
CLOSURE_BSSRDF_BURLEY_ID, CLOSURE_BSSRDF_BURLEY_ID,
CLOSURE_BSSRDF_RANDOM_WALK_ID, CLOSURE_BSSRDF_RANDOM_WALK_ID,
CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID, CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID,
/* Other */ /* Other */
CLOSURE_HOLDOUT_ID, CLOSURE_HOLDOUT_ID,
@ -490,9 +490,9 @@ typedef enum ClosureType {
(type >= CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID && \ (type >= CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID && \
type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)) type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID))
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) \ #define CLOSURE_IS_BSDF_OR_BSSRDF(type) \
(type != CLOSURE_NONE_ID && type <= CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID) (type != CLOSURE_NONE_ID && type <= CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID)
#define CLOSURE_IS_BSSRDF(type) \ #define CLOSURE_IS_BSSRDF(type) \
(type >= CLOSURE_BSSRDF_BURLEY_ID && type <= CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID) (type >= CLOSURE_BSSRDF_BURLEY_ID && type <= CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID)
#define CLOSURE_IS_VOLUME(type) \ #define CLOSURE_IS_VOLUME(type) \
(type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
#define CLOSURE_IS_VOLUME_SCATTER(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID) #define CLOSURE_IS_VOLUME_SCATTER(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)

View File

@ -69,8 +69,8 @@ ccl_device void differential_dudv(ccl_private differential *du,
* and the same for dudy and dvdy. the denominator is the same for both * and the same for dudy and dvdy. the denominator is the same for both
* solutions, so we compute it only once. * solutions, so we compute it only once.
* *
* dP.dx = dPdu * dudx + dPdv * dvdx; * `dP.dx = dPdu * dudx + dPdv * dvdx;`
* dP.dy = dPdu * dudy + dPdv * dvdy; */ * `dP.dy = dPdu * dudy + dPdv * dvdy;` */
float det = (dPdu.x * dPdv.y - dPdv.x * dPdu.y); float det = (dPdu.x * dPdv.y - dPdv.x * dPdu.y);

View File

@ -138,7 +138,7 @@ static float3 output_estimate_emission(ShaderOutput *output, bool &is_constant)
{ {
const bool is_principled = (node->type == PrincipledBsdfNode::get_node_type()); const bool is_principled = (node->type == PrincipledBsdfNode::get_node_type());
/* Emission and Background node. */ /* Emission and Background node. */
ShaderInput *color_in = node->input(is_principled ? "Emission" : "Color"); ShaderInput *color_in = node->input(is_principled ? "Emission Color" : "Color");
ShaderInput *strength_in = node->input(is_principled ? "Emission Strength" : "Strength"); ShaderInput *strength_in = node->input(is_principled ? "Emission Strength" : "Strength");
if (is_principled) { if (is_principled) {

View File

@ -2690,9 +2690,8 @@ NODE_DEFINE(PrincipledBsdfNode)
static NodeEnum subsurface_method_enum; static NodeEnum subsurface_method_enum;
subsurface_method_enum.insert("burley", CLOSURE_BSSRDF_BURLEY_ID); subsurface_method_enum.insert("burley", CLOSURE_BSSRDF_BURLEY_ID);
subsurface_method_enum.insert("random_walk_fixed_radius",
CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
subsurface_method_enum.insert("random_walk", CLOSURE_BSSRDF_RANDOM_WALK_ID); subsurface_method_enum.insert("random_walk", CLOSURE_BSSRDF_RANDOM_WALK_ID);
subsurface_method_enum.insert("random_walk_skin", CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
SOCKET_ENUM(subsurface_method, SOCKET_ENUM(subsurface_method,
"Subsurface Method", "Subsurface Method",
subsurface_method_enum, subsurface_method_enum,
@ -2700,31 +2699,38 @@ NODE_DEFINE(PrincipledBsdfNode)
SOCKET_IN_COLOR(base_color, "Base Color", make_float3(0.8f, 0.8f, 0.8f)) SOCKET_IN_COLOR(base_color, "Base Color", make_float3(0.8f, 0.8f, 0.8f))
SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f); SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f);
SOCKET_IN_FLOAT(subsurface, "Subsurface", 0.0f); SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
SOCKET_IN_FLOAT(ior, "IOR", 0.0f);
SOCKET_IN_FLOAT(alpha, "Alpha", 1.0f);
SOCKET_IN_NORMAL(normal, "Normal", zero_float3(), SocketType::LINK_NORMAL);
SOCKET_IN_FLOAT(subsurface_weight, "Subsurface Weight", 0.0f);
SOCKET_IN_FLOAT(subsurface_scale, "Subsurface Scale", 0.1f); SOCKET_IN_FLOAT(subsurface_scale, "Subsurface Scale", 0.1f);
SOCKET_IN_VECTOR(subsurface_radius, "Subsurface Radius", make_float3(0.1f, 0.1f, 0.1f)); SOCKET_IN_VECTOR(subsurface_radius, "Subsurface Radius", make_float3(0.1f, 0.1f, 0.1f));
SOCKET_IN_FLOAT(subsurface_ior, "Subsurface IOR", 1.4f); SOCKET_IN_FLOAT(subsurface_ior, "Subsurface IOR", 1.4f);
SOCKET_IN_FLOAT(subsurface_anisotropy, "Subsurface Anisotropy", 0.0f); SOCKET_IN_FLOAT(subsurface_anisotropy, "Subsurface Anisotropy", 0.0f);
SOCKET_IN_FLOAT(specular, "Specular", 0.0f);
SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f); SOCKET_IN_FLOAT(specular_ior_level, "Specular IOR Level", 0.0f);
SOCKET_IN_FLOAT(specular_tint, "Specular Tint", 0.0f); SOCKET_IN_COLOR(specular_tint, "Specular Tint", one_float3());
SOCKET_IN_FLOAT(anisotropic, "Anisotropic", 0.0f); SOCKET_IN_FLOAT(anisotropic, "Anisotropic", 0.0f);
SOCKET_IN_FLOAT(sheen, "Sheen", 0.0f); SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
SOCKET_IN_NORMAL(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT);
SOCKET_IN_FLOAT(transmission_weight, "Transmission Weight", 0.0f);
SOCKET_IN_FLOAT(sheen_weight, "Sheen Weight", 0.0f);
SOCKET_IN_FLOAT(sheen_roughness, "Sheen Roughness", 0.5f); SOCKET_IN_FLOAT(sheen_roughness, "Sheen Roughness", 0.5f);
SOCKET_IN_COLOR(sheen_tint, "Sheen Tint", one_float3()); SOCKET_IN_COLOR(sheen_tint, "Sheen Tint", one_float3());
SOCKET_IN_FLOAT(coat, "Coat", 0.0f);
SOCKET_IN_FLOAT(coat_weight, "Coat Weight", 0.0f);
SOCKET_IN_FLOAT(coat_roughness, "Coat Roughness", 0.03f); SOCKET_IN_FLOAT(coat_roughness, "Coat Roughness", 0.03f);
SOCKET_IN_FLOAT(coat_ior, "Coat IOR", 1.5f); SOCKET_IN_FLOAT(coat_ior, "Coat IOR", 1.5f);
SOCKET_IN_COLOR(coat_tint, "Coat Tint", one_float3()); SOCKET_IN_COLOR(coat_tint, "Coat Tint", one_float3());
SOCKET_IN_FLOAT(ior, "IOR", 0.0f);
SOCKET_IN_FLOAT(transmission, "Transmission", 0.0f);
SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
SOCKET_IN_COLOR(emission, "Emission", one_float3());
SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 0.0f);
SOCKET_IN_FLOAT(alpha, "Alpha", 1.0f);
SOCKET_IN_NORMAL(normal, "Normal", zero_float3(), SocketType::LINK_NORMAL);
SOCKET_IN_NORMAL(coat_normal, "Coat Normal", zero_float3(), SocketType::LINK_NORMAL); SOCKET_IN_NORMAL(coat_normal, "Coat Normal", zero_float3(), SocketType::LINK_NORMAL);
SOCKET_IN_NORMAL(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT);
SOCKET_IN_COLOR(emission_color, "Emission Color", one_float3());
SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 0.0f);
SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL); SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
SOCKET_OUT_CLOSURE(BSDF, "BSDF"); SOCKET_OUT_CLOSURE(BSDF, "BSDF");
@ -2742,7 +2748,7 @@ void PrincipledBsdfNode::simplify_settings(Scene * /* scene */)
{ {
if (!has_surface_emission()) { if (!has_surface_emission()) {
/* Emission will be zero, so optimize away any connected emission input. */ /* Emission will be zero, so optimize away any connected emission input. */
ShaderInput *emission_in = input("Emission"); ShaderInput *emission_in = input("Emission Color");
ShaderInput *strength_in = input("Emission Strength"); ShaderInput *strength_in = input("Emission Strength");
if (emission_in->link) { if (emission_in->link) {
emission_in->disconnect(); emission_in->disconnect();
@ -2761,16 +2767,18 @@ bool PrincipledBsdfNode::has_surface_transparent()
bool PrincipledBsdfNode::has_surface_emission() bool PrincipledBsdfNode::has_surface_emission()
{ {
ShaderInput *emission_in = input("Emission"); ShaderInput *emission_color_in = input("Emission Color");
ShaderInput *emission_strength_in = input("Emission Strength"); ShaderInput *emission_strength_in = input("Emission Strength");
return (emission_in->link != NULL || reduce_max(emission) > CLOSURE_WEIGHT_CUTOFF) && return (emission_color_in->link != NULL || reduce_max(emission_color) > CLOSURE_WEIGHT_CUTOFF) &&
(emission_strength_in->link != NULL || emission_strength > CLOSURE_WEIGHT_CUTOFF); (emission_strength_in->link != NULL || emission_strength > CLOSURE_WEIGHT_CUTOFF);
} }
bool PrincipledBsdfNode::has_surface_bssrdf() bool PrincipledBsdfNode::has_surface_bssrdf()
{ {
ShaderInput *subsurface_in = input("Subsurface"); ShaderInput *subsurface_weight_in = input("Subsurface Weight");
return (subsurface_in->link != NULL || subsurface > CLOSURE_WEIGHT_CUTOFF); ShaderInput *subsurface_scale_in = input("Subsurface Scale");
return (subsurface_weight_in->link != NULL || subsurface_weight > CLOSURE_WEIGHT_CUTOFF) &&
(subsurface_scale_in->link != NULL || subsurface_scale != 0.0f);
} }
void PrincipledBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) void PrincipledBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
@ -2791,7 +2799,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler)
ShaderInput *base_color_in = input("Base Color"); ShaderInput *base_color_in = input("Base Color");
ShaderInput *p_metallic = input("Metallic"); ShaderInput *p_metallic = input("Metallic");
ShaderInput *p_subsurface = input("Subsurface"); ShaderInput *p_subsurface_weight = input("Subsurface Weight");
ShaderInput *emission_strength_in = input("Emission Strength"); ShaderInput *emission_strength_in = input("Emission Strength");
ShaderInput *alpha_in = input("Alpha"); ShaderInput *alpha_in = input("Alpha");
@ -2803,19 +2811,19 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler)
int normal_offset = compiler.stack_assign_if_linked(input("Normal")); int normal_offset = compiler.stack_assign_if_linked(input("Normal"));
int coat_normal_offset = compiler.stack_assign_if_linked(input("Coat Normal")); int coat_normal_offset = compiler.stack_assign_if_linked(input("Coat Normal"));
int tangent_offset = compiler.stack_assign_if_linked(input("Tangent")); int tangent_offset = compiler.stack_assign_if_linked(input("Tangent"));
int specular_offset = compiler.stack_assign(input("Specular")); int specular_ior_level_offset = compiler.stack_assign(input("Specular IOR Level"));
int roughness_offset = compiler.stack_assign(input("Roughness")); int roughness_offset = compiler.stack_assign(input("Roughness"));
int specular_tint_offset = compiler.stack_assign(input("Specular Tint")); int specular_tint_offset = compiler.stack_assign(input("Specular Tint"));
int anisotropic_offset = compiler.stack_assign(input("Anisotropic")); int anisotropic_offset = compiler.stack_assign(input("Anisotropic"));
int sheen_offset = compiler.stack_assign(input("Sheen")); int sheen_weight_offset = compiler.stack_assign(input("Sheen Weight"));
int sheen_roughness_offset = compiler.stack_assign(input("Sheen Roughness")); int sheen_roughness_offset = compiler.stack_assign(input("Sheen Roughness"));
int sheen_tint_offset = compiler.stack_assign(input("Sheen Tint")); int sheen_tint_offset = compiler.stack_assign(input("Sheen Tint"));
int coat_offset = compiler.stack_assign(input("Coat")); int coat_weight_offset = compiler.stack_assign(input("Coat Weight"));
int coat_roughness_offset = compiler.stack_assign(input("Coat Roughness")); int coat_roughness_offset = compiler.stack_assign(input("Coat Roughness"));
int coat_ior_offset = compiler.stack_assign(input("Coat IOR")); int coat_ior_offset = compiler.stack_assign(input("Coat IOR"));
int coat_tint_offset = compiler.stack_assign(input("Coat Tint")); int coat_tint_offset = compiler.stack_assign(input("Coat Tint"));
int ior_offset = compiler.stack_assign(input("IOR")); int ior_offset = compiler.stack_assign(input("IOR"));
int transmission_offset = compiler.stack_assign(input("Transmission")); int transmission_weight_offset = compiler.stack_assign(input("Transmission Weight"));
int anisotropic_rotation_offset = compiler.stack_assign(input("Anisotropic Rotation")); int anisotropic_rotation_offset = compiler.stack_assign(input("Anisotropic Rotation"));
int subsurface_radius_offset = compiler.stack_assign(input("Subsurface Radius")); int subsurface_radius_offset = compiler.stack_assign(input("Subsurface Radius"));
int subsurface_scale_offset = compiler.stack_assign(input("Subsurface Scale")); int subsurface_scale_offset = compiler.stack_assign(input("Subsurface Scale"));
@ -2823,31 +2831,31 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler)
int subsurface_anisotropy_offset = compiler.stack_assign(input("Subsurface Anisotropy")); int subsurface_anisotropy_offset = compiler.stack_assign(input("Subsurface Anisotropy"));
int alpha_offset = compiler.stack_assign_if_linked(alpha_in); int alpha_offset = compiler.stack_assign_if_linked(alpha_in);
int emission_strength_offset = compiler.stack_assign_if_linked(emission_strength_in); int emission_strength_offset = compiler.stack_assign_if_linked(emission_strength_in);
int emission_offset = compiler.stack_assign(input("Emission")); int emission_color_offset = compiler.stack_assign(input("Emission Color"));
compiler.add_node(NODE_CLOSURE_BSDF, compiler.add_node(
NODE_CLOSURE_BSDF,
compiler.encode_uchar4(closure, compiler.encode_uchar4(closure,
compiler.stack_assign(p_metallic), compiler.stack_assign(p_metallic),
compiler.stack_assign(p_subsurface), compiler.stack_assign(p_subsurface_weight),
compiler.closure_mix_weight_offset()), compiler.closure_mix_weight_offset()),
__float_as_int((p_metallic) ? get_float(p_metallic->socket_type) : 0.0f), __float_as_int((p_metallic) ? get_float(p_metallic->socket_type) : 0.0f),
__float_as_int((p_subsurface) ? get_float(p_subsurface->socket_type) : 0.0f)); __float_as_int((p_subsurface_weight) ? get_float(p_subsurface_weight->socket_type) : 0.0f));
compiler.add_node( compiler.add_node(
normal_offset, normal_offset,
tangent_offset, tangent_offset,
compiler.encode_uchar4( compiler.encode_uchar4(
specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset), specular_ior_level_offset, roughness_offset, specular_tint_offset, anisotropic_offset),
compiler.encode_uchar4( compiler.encode_uchar4(sheen_weight_offset, sheen_tint_offset, sheen_roughness_offset));
sheen_offset, sheen_tint_offset, sheen_roughness_offset, SVM_STACK_INVALID));
compiler.add_node( compiler.add_node(
compiler.encode_uchar4( compiler.encode_uchar4(
ior_offset, transmission_offset, anisotropic_rotation_offset, coat_normal_offset), ior_offset, transmission_weight_offset, anisotropic_rotation_offset, coat_normal_offset),
distribution, distribution,
subsurface_method, subsurface_method,
compiler.encode_uchar4( compiler.encode_uchar4(
coat_offset, coat_roughness_offset, coat_ior_offset, coat_tint_offset)); coat_weight_offset, coat_roughness_offset, coat_ior_offset, coat_tint_offset));
float3 bc_default = get_float3(base_color_in->socket_type); float3 bc_default = get_float3(base_color_in->socket_type);
@ -2864,7 +2872,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler)
compiler.add_node( compiler.add_node(
compiler.encode_uchar4( compiler.encode_uchar4(
alpha_offset, emission_strength_offset, emission_offset, SVM_STACK_INVALID), alpha_offset, emission_strength_offset, emission_color_offset, SVM_STACK_INVALID),
__float_as_int(get_float(alpha_in->socket_type)), __float_as_int(get_float(alpha_in->socket_type)),
__float_as_int(get_float(emission_strength_in->socket_type)), __float_as_int(get_float(emission_strength_in->socket_type)),
SVM_STACK_INVALID); SVM_STACK_INVALID);
@ -2953,8 +2961,8 @@ NODE_DEFINE(SubsurfaceScatteringNode)
static NodeEnum method_enum; static NodeEnum method_enum;
method_enum.insert("burley", CLOSURE_BSSRDF_BURLEY_ID); method_enum.insert("burley", CLOSURE_BSSRDF_BURLEY_ID);
method_enum.insert("random_walk_fixed_radius", CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
method_enum.insert("random_walk", CLOSURE_BSSRDF_RANDOM_WALK_ID); method_enum.insert("random_walk", CLOSURE_BSSRDF_RANDOM_WALK_ID);
method_enum.insert("random_walk_skin", CLOSURE_BSSRDF_RANDOM_WALK_SKIN_ID);
SOCKET_ENUM(method, "Method", method_enum, CLOSURE_BSSRDF_RANDOM_WALK_ID); SOCKET_ENUM(method, "Method", method_enum, CLOSURE_BSSRDF_RANDOM_WALK_ID);
SOCKET_IN_FLOAT(scale, "Scale", 0.01f); SOCKET_IN_FLOAT(scale, "Scale", 0.01f);

View File

@ -519,35 +519,35 @@ class PrincipledBsdfNode : public BsdfBaseNode {
void simplify_settings(Scene *scene); void simplify_settings(Scene *scene);
NODE_SOCKET_API(float3, base_color) NODE_SOCKET_API(float3, base_color)
NODE_SOCKET_API(float, metallic)
NODE_SOCKET_API(float, roughness)
NODE_SOCKET_API(float, ior)
NODE_SOCKET_API(float3, normal)
NODE_SOCKET_API(float, alpha)
NODE_SOCKET_API(ClosureType, subsurface_method)
NODE_SOCKET_API(float, subsurface_weight)
NODE_SOCKET_API(float3, subsurface_radius) NODE_SOCKET_API(float3, subsurface_radius)
NODE_SOCKET_API(float, subsurface_scale) NODE_SOCKET_API(float, subsurface_scale)
NODE_SOCKET_API(float, subsurface_ior) NODE_SOCKET_API(float, subsurface_ior)
NODE_SOCKET_API(float, subsurface_anisotropy) NODE_SOCKET_API(float, subsurface_anisotropy)
NODE_SOCKET_API(float, metallic) NODE_SOCKET_API(ClosureType, distribution)
NODE_SOCKET_API(float, subsurface) NODE_SOCKET_API(float, specular_ior_level)
NODE_SOCKET_API(float, specular) NODE_SOCKET_API(float3, specular_tint)
NODE_SOCKET_API(float, roughness)
NODE_SOCKET_API(float, specular_tint)
NODE_SOCKET_API(float, anisotropic) NODE_SOCKET_API(float, anisotropic)
NODE_SOCKET_API(float, sheen) NODE_SOCKET_API(float, anisotropic_rotation)
NODE_SOCKET_API(float3, tangent)
NODE_SOCKET_API(float, transmission_weight)
NODE_SOCKET_API(float, sheen_weight)
NODE_SOCKET_API(float, sheen_roughness) NODE_SOCKET_API(float, sheen_roughness)
NODE_SOCKET_API(float3, sheen_tint) NODE_SOCKET_API(float3, sheen_tint)
NODE_SOCKET_API(float, coat) NODE_SOCKET_API(float, coat_weight)
NODE_SOCKET_API(float, coat_roughness) NODE_SOCKET_API(float, coat_roughness)
NODE_SOCKET_API(float, coat_ior) NODE_SOCKET_API(float, coat_ior)
NODE_SOCKET_API(float3, coat_tint) NODE_SOCKET_API(float3, coat_tint)
NODE_SOCKET_API(float, ior)
NODE_SOCKET_API(float, transmission)
NODE_SOCKET_API(float, anisotropic_rotation)
NODE_SOCKET_API(float3, normal)
NODE_SOCKET_API(float3, coat_normal) NODE_SOCKET_API(float3, coat_normal)
NODE_SOCKET_API(float3, tangent) NODE_SOCKET_API(float3, emission_color)
NODE_SOCKET_API(float, surface_mix_weight)
NODE_SOCKET_API(ClosureType, distribution)
NODE_SOCKET_API(ClosureType, subsurface_method)
NODE_SOCKET_API(float3, emission)
NODE_SOCKET_API(float, emission_strength) NODE_SOCKET_API(float, emission_strength)
NODE_SOCKET_API(float, alpha) NODE_SOCKET_API(float, surface_mix_weight)
public: public:
void attributes(Shader *shader, AttributeRequestSet *attributes); void attributes(Shader *shader, AttributeRequestSet *attributes);

View File

@ -155,7 +155,7 @@ static CPUCapabilities &system_cpu_capabilities()
const bool ssse3 = (result[2] & ((int)1 << 9)) != 0; const bool ssse3 = (result[2] & ((int)1 << 9)) != 0;
const bool sse41 = (result[2] & ((int)1 << 19)) != 0; const bool sse41 = (result[2] & ((int)1 << 19)) != 0;
/* const bool sse42 = (result[2] & ((int)1 << 20)) != 0; */ // const bool sse42 = (result[2] & ((int)1 << 20)) != 0;
const bool fma3 = (result[2] & ((int)1 << 12)) != 0; const bool fma3 = (result[2] & ((int)1 << 12)) != 0;
const bool os_uses_xsave_xrestore = (result[2] & ((int)1 << 27)) != 0; const bool os_uses_xsave_xrestore = (result[2] & ((int)1 << 27)) != 0;

Binary file not shown.

View File

@ -281,27 +281,28 @@ class PrincipledBSDFWrapper(ShaderWrapper):
def specular_get(self): def specular_get(self):
if not self.use_nodes or self.node_principled_bsdf is None: if not self.use_nodes or self.node_principled_bsdf is None:
return self.material.specular_intensity return self.material.specular_intensity
return self.node_principled_bsdf.inputs["Specular"].default_value return self.node_principled_bsdf.inputs["Specular IOR Level"].default_value
@_set_check @_set_check
def specular_set(self, value): def specular_set(self, value):
value = values_clamp(value, 0.0, 1.0) value = values_clamp(value, 0.0, 1.0)
self.material.specular_intensity = value self.material.specular_intensity = value
if self.use_nodes and self.node_principled_bsdf is not None: if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Specular"].default_value = value self.node_principled_bsdf.inputs["Specular IOR Level"].default_value = value
specular = property(specular_get, specular_set) specular = property(specular_get, specular_set)
def specular_tint_get(self): def specular_tint_get(self):
if not self.use_nodes or self.node_principled_bsdf is None: if not self.use_nodes or self.node_principled_bsdf is None:
return 0.0 return Color((0.0, 0.0, 0.0))
return self.node_principled_bsdf.inputs["Specular Tint"].default_value return rgba_to_rgb(self.node_principled_bsdf.inputs["Specular Tint"].default_value)
@_set_check @_set_check
def specular_tint_set(self, value): def specular_tint_set(self, color):
value = values_clamp(value, 0.0, 1.0) color = values_clamp(color, 0.0, 1.0)
color = rgb_to_rgba(color)
if self.use_nodes and self.node_principled_bsdf is not None: if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Specular Tint"].default_value = value self.node_principled_bsdf.inputs["Specular Tint"].default_value = color
specular_tint = property(specular_tint_get, specular_tint_set) specular_tint = property(specular_tint_get, specular_tint_set)
@ -312,7 +313,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
return None return None
return ShaderImageTextureWrapper( return ShaderImageTextureWrapper(
self, self.node_principled_bsdf, self, self.node_principled_bsdf,
self.node_principled_bsdf.inputs["Specular"], self.node_principled_bsdf.inputs["Specular IOR Level"],
grid_row_diff=0, grid_row_diff=0,
colorspace_name='Non-Color', colorspace_name='Non-Color',
) )
@ -411,13 +412,13 @@ class PrincipledBSDFWrapper(ShaderWrapper):
def transmission_get(self): def transmission_get(self):
if not self.use_nodes or self.node_principled_bsdf is None: if not self.use_nodes or self.node_principled_bsdf is None:
return 0.0 return 0.0
return self.node_principled_bsdf.inputs["Transmission"].default_value return self.node_principled_bsdf.inputs["Transmission Weight"].default_value
@_set_check @_set_check
def transmission_set(self, value): def transmission_set(self, value):
value = values_clamp(value, 0.0, 1.0) value = values_clamp(value, 0.0, 1.0)
if self.use_nodes and self.node_principled_bsdf is not None: if self.use_nodes and self.node_principled_bsdf is not None:
self.node_principled_bsdf.inputs["Transmission"].default_value = value self.node_principled_bsdf.inputs["Transmission Weight"].default_value = value
transmission = property(transmission_get, transmission_set) transmission = property(transmission_get, transmission_set)
@ -427,7 +428,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
return None return None
return ShaderImageTextureWrapper( return ShaderImageTextureWrapper(
self, self.node_principled_bsdf, self, self.node_principled_bsdf,
self.node_principled_bsdf.inputs["Transmission"], self.node_principled_bsdf.inputs["Transmission Weight"],
grid_row_diff=-1, grid_row_diff=-1,
colorspace_name='Non-Color', colorspace_name='Non-Color',
) )
@ -467,14 +468,14 @@ class PrincipledBSDFWrapper(ShaderWrapper):
def emission_color_get(self): def emission_color_get(self):
if not self.use_nodes or self.node_principled_bsdf is None: if not self.use_nodes or self.node_principled_bsdf is None:
return Color((0.0, 0.0, 0.0)) return Color((0.0, 0.0, 0.0))
return rgba_to_rgb(self.node_principled_bsdf.inputs["Emission"].default_value) return rgba_to_rgb(self.node_principled_bsdf.inputs["Emission Color"].default_value)
@_set_check @_set_check
def emission_color_set(self, color): def emission_color_set(self, color):
if self.use_nodes and self.node_principled_bsdf is not None: if self.use_nodes and self.node_principled_bsdf is not None:
color = values_clamp(color, 0.0, 1000000.0) color = values_clamp(color, 0.0, 1000000.0)
color = rgb_to_rgba(color) color = rgb_to_rgba(color)
self.node_principled_bsdf.inputs["Emission"].default_value = color self.node_principled_bsdf.inputs["Emission Color"].default_value = color
emission_color = property(emission_color_get, emission_color_set) emission_color = property(emission_color_get, emission_color_set)
@ -483,7 +484,7 @@ class PrincipledBSDFWrapper(ShaderWrapper):
return None return None
return ShaderImageTextureWrapper( return ShaderImageTextureWrapper(
self, self.node_principled_bsdf, self, self.node_principled_bsdf,
self.node_principled_bsdf.inputs["Emission"], self.node_principled_bsdf.inputs["Emission Color"],
grid_row_diff=1, grid_row_diff=1,
) )

View File

@ -36,7 +36,7 @@ def geometry_node_group_empty_new(name):
def geometry_node_group_empty_modifier_new(name): def geometry_node_group_empty_modifier_new(name):
group = geometry_node_group_empty_new(data_("Tool")) group = geometry_node_group_empty_new(data_("Geometry Nodes"))
group.is_modifier = True group.is_modifier = True
return group return group
@ -294,7 +294,7 @@ class NewGeometryNodeTreeAssign(Operator):
class NewGeometryNodeGroupTool(Operator): class NewGeometryNodeGroupTool(Operator):
"""Create a new geometry node group for an tool""" """Create a new geometry node group for a tool"""
bl_idname = "node.new_geometry_node_group_tool" bl_idname = "node.new_geometry_node_group_tool"
bl_label = "New Geometry Node Tool Group" bl_label = "New Geometry Node Tool Group"
bl_options = {'REGISTER', 'UNDO'} bl_options = {'REGISTER', 'UNDO'}

View File

@ -3282,13 +3282,14 @@ class WM_MT_splash(Menu):
if found_recent: if found_recent:
col2_title.label(text="Recent Files") col2_title.label(text="Recent Files")
else: else:
# Links if no recent files.
# Links if no recent files
col2_title.label(text="Getting Started") col2_title.label(text="Getting Started")
col2.operator("wm.url_open_preset", text="Manual", icon='URL').type = 'MANUAL' col2.operator("wm.url_open_preset", text="Manual", icon='URL').type = 'MANUAL'
col2.operator("wm.url_open", text="Tutorials", icon='URL').url = "https://www.blender.org/tutorials/"
col2.operator("wm.url_open", text="Support", icon='URL').url = "https://www.blender.org/support/"
col2.operator("wm.url_open", text="User Communities", icon='URL').url = "https://www.blender.org/community/"
col2.operator("wm.url_open_preset", text="Blender Website", icon='URL').type = 'BLENDER' col2.operator("wm.url_open_preset", text="Blender Website", icon='URL').type = 'BLENDER'
col2.operator("wm.url_open_preset", text="Credits", icon='URL').type = 'CREDITS'
layout.separator() layout.separator()
@ -3302,8 +3303,8 @@ class WM_MT_splash(Menu):
col2 = split.column() col2 = split.column()
col2.operator("wm.url_open_preset", text="Release Notes", icon='URL').type = 'RELEASE_NOTES' col2.operator("wm.url_open_preset", text="Donate", icon='FUND').type = 'FUND'
col2.operator("wm.url_open_preset", text="Development Fund", icon='FUND').type = 'FUND' col2.operator("wm.url_open_preset", text="What's New", icon='URL').type = 'RELEASE_NOTES'
layout.separator() layout.separator()
layout.separator() layout.separator()
@ -3321,7 +3322,7 @@ class WM_MT_splash_about(Menu):
col = split.column(align=True) col = split.column(align=True)
col.scale_y = 0.8 col.scale_y = 0.8
col.label(text=bpy.app.version_string, translate=False) col.label(text=iface_("Version: %s") % bpy.app.version_string, translate=False)
col.separator(factor=2.5) col.separator(factor=2.5)
col.label(text=iface_("Date: %s %s") % (bpy.app.build_commit_date.decode('utf-8', 'replace'), col.label(text=iface_("Date: %s %s") % (bpy.app.build_commit_date.decode('utf-8', 'replace'),
bpy.app.build_commit_time.decode('utf-8', 'replace')), translate=False) bpy.app.build_commit_time.decode('utf-8', 'replace')), translate=False)
@ -3342,12 +3343,13 @@ class WM_MT_splash_about(Menu):
col = split.column(align=True) col = split.column(align=True)
col.emboss = 'PULLDOWN_MENU' col.emboss = 'PULLDOWN_MENU'
col.operator("wm.url_open_preset", text="Release Notes", icon='URL').type = 'RELEASE_NOTES' col.operator("wm.url_open_preset", text="Donate", icon='FUND').type = 'FUND'
col.operator("wm.url_open_preset", text="What's New", icon='URL').type = 'RELEASE_NOTES'
col.separator(factor=2.0)
col.operator("wm.url_open_preset", text="Credits", icon='URL').type = 'CREDITS' col.operator("wm.url_open_preset", text="Credits", icon='URL').type = 'CREDITS'
col.operator("wm.url_open", text="License", icon='URL').url = "https://www.blender.org/about/license/" col.operator("wm.url_open", text="License", icon='URL').url = "https://www.blender.org/about/license/"
col.operator("wm.url_open_preset", text="Blender Website", icon='URL').type = 'BLENDER'
col.operator("wm.url_open", text="Blender Store", icon='URL').url = "https://store.blender.org" col.operator("wm.url_open", text="Blender Store", icon='URL').url = "https://store.blender.org"
col.operator("wm.url_open_preset", text="Development Fund", icon='FUND').type = 'FUND' col.operator("wm.url_open_preset", text="Blender Website", icon='URL').type = 'BLENDER'
class WM_MT_region_toggle_pie(Menu): class WM_MT_region_toggle_pie(Menu):

View File

@ -112,7 +112,7 @@ class CONSOLE_MT_console(Menu):
class CONSOLE_MT_context_menu(Menu): class CONSOLE_MT_context_menu(Menu):
bl_label = "Console Context Menu" bl_label = "Console"
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout

View File

@ -690,7 +690,7 @@ class DOPESHEET_MT_delete(Menu):
class DOPESHEET_MT_context_menu(Menu): class DOPESHEET_MT_context_menu(Menu):
bl_label = "Dope Sheet Context Menu" bl_label = "Dope Sheet"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -733,7 +733,7 @@ class DOPESHEET_MT_context_menu(Menu):
class DOPESHEET_MT_channel_context_menu(Menu): class DOPESHEET_MT_channel_context_menu(Menu):
bl_label = "Dope Sheet Channel Context Menu" bl_label = "Dope Sheet Channel"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout

View File

@ -327,6 +327,15 @@ class FILEBROWSER_PT_bookmarks_favorites(FileBrowserPanel, Panel):
layout.operator("file.bookmark_add", icon='ADD') layout.operator("file.bookmark_add", icon='ADD')
class FILEBROWSER_MT_bookmarks_recents_specials_menu(Menu):
bl_label = "Recent Items Specials"
def draw(self, _context):
layout = self.layout
layout.operator("file.reset_recent", icon='X', text="Clear Recent Items")
class FILEBROWSER_PT_bookmarks_recents(Panel): class FILEBROWSER_PT_bookmarks_recents(Panel):
bl_space_type = 'FILE_BROWSER' bl_space_type = 'FILE_BROWSER'
bl_region_type = 'TOOLS' bl_region_type = 'TOOLS'
@ -351,7 +360,7 @@ class FILEBROWSER_PT_bookmarks_recents(Panel):
space, "recent_folders_active", item_dyntip_propname="path", rows=1, maxrows=10) space, "recent_folders_active", item_dyntip_propname="path", rows=1, maxrows=10)
col = row.column(align=True) col = row.column(align=True)
col.operator("file.reset_recent", icon='X', text="") col.menu("FILEBROWSER_MT_bookmarks_recents_specials_menu", icon='DOWNARROW_HLT', text="")
class FILEBROWSER_PT_advanced_filter(Panel): class FILEBROWSER_PT_advanced_filter(Panel):
@ -529,7 +538,7 @@ class FILEBROWSER_MT_select(FileBrowserMenu, Menu):
class FILEBROWSER_MT_context_menu(FileBrowserMenu, Menu): class FILEBROWSER_MT_context_menu(FileBrowserMenu, Menu):
bl_label = "Files Context Menu" bl_label = "Files"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -818,7 +827,7 @@ class ASSETBROWSER_UL_metadata_tags(UIList):
class ASSETBROWSER_MT_context_menu(AssetBrowserMenu, Menu): class ASSETBROWSER_MT_context_menu(AssetBrowserMenu, Menu):
bl_label = "Assets Context Menu" bl_label = "Assets"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -853,6 +862,7 @@ classes = (
FILEBROWSER_PT_bookmarks_favorites, FILEBROWSER_PT_bookmarks_favorites,
FILEBROWSER_PT_bookmarks_system, FILEBROWSER_PT_bookmarks_system,
FILEBROWSER_PT_bookmarks_volumes, FILEBROWSER_PT_bookmarks_volumes,
FILEBROWSER_MT_bookmarks_recents_specials_menu,
FILEBROWSER_PT_bookmarks_recents, FILEBROWSER_PT_bookmarks_recents,
FILEBROWSER_PT_advanced_filter, FILEBROWSER_PT_advanced_filter,
FILEBROWSER_PT_directory_path, FILEBROWSER_PT_directory_path,

View File

@ -441,7 +441,7 @@ class GRAPH_MT_delete(Menu):
class GRAPH_MT_context_menu(Menu): class GRAPH_MT_context_menu(Menu):
bl_label = "F-Curve Context Menu" bl_label = "F-Curve"
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout
@ -501,7 +501,7 @@ class GRAPH_MT_snap_pie(Menu):
class GRAPH_MT_channel_context_menu(Menu): class GRAPH_MT_channel_context_menu(Menu):
bl_label = "F-Curve Channel Context Menu" bl_label = "F-Curve Channel"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout

View File

@ -509,7 +509,7 @@ class IMAGE_MT_uvs_select_mode(Menu):
class IMAGE_MT_uvs_context_menu(Menu): class IMAGE_MT_uvs_context_menu(Menu):
bl_label = "UV Context Menu" bl_label = "UV"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -905,7 +905,7 @@ class IMAGE_MT_editor_menus(Menu):
class IMAGE_MT_mask_context_menu(Menu): class IMAGE_MT_mask_context_menu(Menu):
bl_label = "Mask Context Menu" bl_label = "Mask"
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):

View File

@ -92,7 +92,7 @@ class INFO_MT_area(Menu):
class INFO_MT_context_menu(Menu): class INFO_MT_context_menu(Menu):
bl_label = "Info Context Menu" bl_label = "Info"
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout

View File

@ -304,7 +304,7 @@ class NLA_MT_view_pie(Menu):
class NLA_MT_context_menu(Menu): class NLA_MT_context_menu(Menu):
bl_label = "NLA Context Menu" bl_label = "NLA"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -348,7 +348,7 @@ class NLA_MT_context_menu(Menu):
class NLA_MT_channel_context_menu(Menu): class NLA_MT_channel_context_menu(Menu):
bl_label = "NLA Channel Context Menu" bl_label = "NLA Channel"
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout

View File

@ -561,7 +561,7 @@ class NODE_MT_context_menu_select_menu(Menu):
class NODE_MT_context_menu(Menu): class NODE_MT_context_menu(Menu):
bl_label = "Node Context Menu" bl_label = "Node"
def draw(self, context): def draw(self, context):
snode = context.space_data snode = context.space_data

View File

@ -100,7 +100,7 @@ class OUTLINER_MT_editor_menus(Menu):
class OUTLINER_MT_context_menu(Menu): class OUTLINER_MT_context_menu(Menu):
bl_label = "Outliner Context Menu" bl_label = "Outliner"
@staticmethod @staticmethod
def draw_common_operators(layout): def draw_common_operators(layout):

View File

@ -1060,7 +1060,7 @@ class SEQUENCER_MT_image_apply(Menu):
class SEQUENCER_MT_context_menu(Menu): class SEQUENCER_MT_context_menu(Menu):
bl_label = "Sequencer Context Menu" bl_label = "Sequencer"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -1162,7 +1162,7 @@ class SEQUENCER_MT_context_menu(Menu):
class SEQUENCER_MT_preview_context_menu(Menu): class SEQUENCER_MT_preview_context_menu(Menu):
bl_label = "Sequencer Preview Context Menu" bl_label = "Sequencer Preview"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout

View File

@ -718,7 +718,7 @@ class TOPBAR_MT_help(Menu):
class TOPBAR_MT_file_context_menu(Menu): class TOPBAR_MT_file_context_menu(Menu):
bl_label = "File Context Menu" bl_label = "File"
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout

View File

@ -216,6 +216,11 @@ class USERPREF_PT_interface_display(InterfacePanel, CenterAlignMixIn, Panel):
sub.active = view.show_tooltips sub.active = view.show_tooltips
sub.prop(view, "show_tooltips_python") sub.prop(view, "show_tooltips_python")
col.separator()
col = layout.column(heading="Search", align=True)
col.prop(prefs, "use_recent_searches", text="Sort by Most Recent")
class USERPREF_PT_interface_text(InterfacePanel, CenterAlignMixIn, Panel): class USERPREF_PT_interface_text(InterfacePanel, CenterAlignMixIn, Panel):
bl_label = "Text Rendering" bl_label = "Text Rendering"

View File

@ -1976,7 +1976,7 @@ class VIEW3D_MT_select_edit_metaball(Menu):
class VIEW3D_MT_edit_lattice_context_menu(Menu): class VIEW3D_MT_edit_lattice_context_menu(Menu):
bl_label = "Lattice Context Menu" bl_label = "Lattice"
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout
@ -2343,7 +2343,7 @@ class VIEW3D_MT_surface_add(Menu):
class VIEW3D_MT_edit_metaball_context_menu(Menu): class VIEW3D_MT_edit_metaball_context_menu(Menu):
bl_label = "Metaball Context Menu" bl_label = "Metaball"
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout
@ -2730,7 +2730,7 @@ class VIEW3D_MT_object_clear(Menu):
class VIEW3D_MT_object_context_menu(Menu): class VIEW3D_MT_object_context_menu(Menu):
bl_label = "Object Context Menu" bl_label = "Object"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -3795,7 +3795,7 @@ class VIEW3D_MT_particle(Menu):
class VIEW3D_MT_particle_context_menu(Menu): class VIEW3D_MT_particle_context_menu(Menu):
bl_label = "Particle Context Menu" bl_label = "Particle"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -4079,7 +4079,7 @@ class VIEW3D_MT_pose_apply(Menu):
class VIEW3D_MT_pose_context_menu(Menu): class VIEW3D_MT_pose_context_menu(Menu):
bl_label = "Pose Context Menu" bl_label = "Pose"
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout
@ -4272,7 +4272,7 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
if is_vert_mode: if is_vert_mode:
col = row.column(align=True) col = row.column(align=True)
col.label(text="Vertex Context Menu", icon='VERTEXSEL') col.label(text="Vertex", icon='VERTEXSEL')
col.separator() col.separator()
# Additive Operators # Additive Operators
@ -4323,7 +4323,7 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
if is_edge_mode: if is_edge_mode:
col = row.column(align=True) col = row.column(align=True)
col.label(text="Edge Context Menu", icon='EDGESEL') col.label(text="Edge", icon='EDGESEL')
col.separator() col.separator()
# Additive Operators # Additive Operators
@ -4397,7 +4397,7 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
col = row.column(align=True) col = row.column(align=True)
col.label(text="Face Context Menu", icon='FACESEL') col.label(text="Face", icon='FACESEL')
col.separator() col.separator()
# Additive Operators # Additive Operators
@ -5034,7 +5034,7 @@ class VIEW3D_MT_edit_curve_clean(Menu):
class VIEW3D_MT_edit_curve_context_menu(Menu): class VIEW3D_MT_edit_curve_context_menu(Menu):
bl_label = "Curve Context Menu" bl_label = "Curve"
def draw(self, _context): def draw(self, _context):
# TODO(campbell): match mesh vertex menu. # TODO(campbell): match mesh vertex menu.
@ -5217,7 +5217,7 @@ class VIEW3D_MT_edit_font(Menu):
class VIEW3D_MT_edit_font_context_menu(Menu): class VIEW3D_MT_edit_font_context_menu(Menu):
bl_label = "Text Context Menu" bl_label = "Text"
def draw(self, _context): def draw(self, _context):
layout = self.layout layout = self.layout
@ -5352,7 +5352,7 @@ class VIEW3D_MT_edit_armature(Menu):
class VIEW3D_MT_armature_context_menu(Menu): class VIEW3D_MT_armature_context_menu(Menu):
bl_label = "Armature Context Menu" bl_label = "Armature"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -7813,7 +7813,7 @@ class VIEW3D_MT_gpencil_edit_context_menu(Menu):
if is_point_mode or is_segment_mode: if is_point_mode or is_segment_mode:
col = row.column(align=True) col = row.column(align=True)
col.label(text="Point Context Menu", icon='GP_SELECT_POINTS') col.label(text="Point", icon='GP_SELECT_POINTS')
col.separator() col.separator()
# Additive Operators # Additive Operators
@ -7864,7 +7864,7 @@ class VIEW3D_MT_gpencil_edit_context_menu(Menu):
if is_stroke_mode: if is_stroke_mode:
col = row.column(align=True) col = row.column(align=True)
col.label(text="Stroke Context Menu", icon='GP_SELECT_STROKES') col.label(text="Stroke", icon='GP_SELECT_STROKES')
col.separator() col.separator()
# Main Strokes Operators # Main Strokes Operators
@ -7964,7 +7964,7 @@ class VIEW3D_PT_gpencil_sculpt_automasking(Panel):
class VIEW3D_PT_gpencil_sculpt_context_menu(Panel): class VIEW3D_PT_gpencil_sculpt_context_menu(Panel):
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_label = "Sculpt Context Menu" bl_label = "Sculpt"
bl_ui_units_x = 12 bl_ui_units_x = 12
def draw(self, context): def draw(self, context):
@ -7984,7 +7984,7 @@ class VIEW3D_PT_gpencil_sculpt_context_menu(Panel):
class VIEW3D_PT_gpencil_weight_context_menu(Panel): class VIEW3D_PT_gpencil_weight_context_menu(Panel):
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_label = "Weight Paint Context Menu" bl_label = "Weight Paint"
bl_ui_units_x = 12 bl_ui_units_x = 12
def draw(self, context): def draw(self, context):
@ -8003,7 +8003,7 @@ class VIEW3D_PT_gpencil_weight_context_menu(Panel):
class VIEW3D_PT_gpencil_draw_context_menu(Panel): class VIEW3D_PT_gpencil_draw_context_menu(Panel):
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_label = "Draw Context Menu" bl_label = "Draw"
bl_ui_units_x = 12 bl_ui_units_x = 12
def draw(self, context): def draw(self, context):
@ -8041,7 +8041,7 @@ class VIEW3D_PT_gpencil_draw_context_menu(Panel):
class VIEW3D_PT_gpencil_vertex_context_menu(Panel): class VIEW3D_PT_gpencil_vertex_context_menu(Panel):
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_label = "Vertex Paint Context Menu" bl_label = "Vertex Paint"
bl_ui_units_x = 12 bl_ui_units_x = 12
def draw(self, context): def draw(self, context):
@ -8080,7 +8080,7 @@ class VIEW3D_PT_paint_vertex_context_menu(Panel):
# Only for popover, these are dummy values. # Only for popover, these are dummy values.
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_label = "Vertex Paint Context Menu" bl_label = "Vertex Paint"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -8118,7 +8118,7 @@ class VIEW3D_PT_paint_texture_context_menu(Panel):
# Only for popover, these are dummy values. # Only for popover, these are dummy values.
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_label = "Texture Paint Context Menu" bl_label = "Texture Paint"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -8157,7 +8157,7 @@ class VIEW3D_PT_paint_weight_context_menu(Panel):
# Only for popover, these are dummy values. # Only for popover, these are dummy values.
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_label = "Weights Context Menu" bl_label = "Weights"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -8267,7 +8267,7 @@ class VIEW3D_PT_sculpt_context_menu(Panel):
# Only for popover, these are dummy values. # Only for popover, these are dummy values.
bl_space_type = 'VIEW_3D' bl_space_type = 'VIEW_3D'
bl_region_type = 'WINDOW' bl_region_type = 'WINDOW'
bl_label = "Sculpt Context Menu" bl_label = "Sculpt"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout

View File

@ -42,6 +42,6 @@ class BoneColor : public ::BoneColor {
* This returns the pose bone's own color, unless it's set to "default", then it defaults to the * This returns the pose bone's own color, unless it's set to "default", then it defaults to the
* armature bone color. * armature bone color.
*/ */
BoneColor &ANIM_bonecolor_posebone_get(struct bPoseChannel *pose_bone); const BoneColor &ANIM_bonecolor_posebone_get(const struct bPoseChannel *pose_bone);
}; // namespace blender::animrig }; // namespace blender::animrig

View File

@ -86,7 +86,7 @@ uint64_t BoneColor::hash() const
return get_default_hash_4(hash_solid, hash_select, hash_active, custom.flag); return get_default_hash_4(hash_solid, hash_select, hash_active, custom.flag);
} }
BoneColor &ANIM_bonecolor_posebone_get(bPoseChannel *pose_bone) const BoneColor &ANIM_bonecolor_posebone_get(const bPoseChannel *pose_bone)
{ {
if (pose_bone->color.palette_index == 0) { if (pose_bone->color.palette_index == 0) {
return pose_bone->bone->color.wrap(); return pose_bone->bone->color.wrap();

View File

@ -188,6 +188,7 @@ enum {
#define BLENDER_QUIT_FILE "quit.blend" #define BLENDER_QUIT_FILE "quit.blend"
#define BLENDER_BOOKMARK_FILE "bookmarks.txt" #define BLENDER_BOOKMARK_FILE "bookmarks.txt"
#define BLENDER_HISTORY_FILE "recent-files.txt" #define BLENDER_HISTORY_FILE "recent-files.txt"
#define BLENDER_RECENT_SEARCHES_FILE "recent-searches.txt"
#define BLENDER_PLATFORM_SUPPORT_FILE "platform_support.txt" #define BLENDER_PLATFORM_SUPPORT_FILE "platform_support.txt"
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -29,7 +29,7 @@ extern "C" {
/* Blender file format version. */ /* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION #define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 24 #define BLENDER_FILE_SUBVERSION 25
/* Minimum Blender version that supports reading file written with the current /* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to * version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@ -121,7 +121,7 @@ struct ClothVertex {
struct ClothSpring { struct ClothSpring {
int ij; /* `Pij` from the paper, one end of the spring. */ int ij; /* `Pij` from the paper, one end of the spring. */
int kl; /* `Pkl` from the paper, one end of the spring. */ int kl; /* `Pkl` from the paper, one end of the spring. */
int mn; /* For hair springs: third vertex index; For bending springs: edge index; */ int mn; /* For hair springs: third vertex index; For bending springs: edge index. */
int *pa; /* Array of vert indices for poly a (for bending springs). */ int *pa; /* Array of vert indices for poly a (for bending springs). */
int *pb; /* Array of vert indices for poly b (for bending springs). */ int *pb; /* Array of vert indices for poly b (for bending springs). */
int la; /* Length of `*pa`. */ int la; /* Length of `*pa`. */

View File

@ -445,6 +445,8 @@ class LayerGroupRuntime {
* A LayerGroup is a grouping of zero or more Layers. * A LayerGroup is a grouping of zero or more Layers.
*/ */
class LayerGroup : public ::GreasePencilLayerTreeGroup { class LayerGroup : public ::GreasePencilLayerTreeGroup {
friend struct ::GreasePencil;
public: public:
LayerGroup(); LayerGroup();
explicit LayerGroup(StringRefNull name); explicit LayerGroup(StringRefNull name);
@ -460,47 +462,6 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
const TreeNode &as_node() const; const TreeNode &as_node() const;
TreeNode &as_node(); TreeNode &as_node();
/**
* Adds a group at the end of this group.
*/
LayerGroup &add_group(LayerGroup *group);
LayerGroup &add_group(StringRefNull name);
/**
* Adds a layer group after \a link and returns it.
*/
LayerGroup &add_group_after(LayerGroup *group, TreeNode *link);
LayerGroup &add_group_after(StringRefNull name, TreeNode *link);
/**
* Adds a layer at the end of this group and returns it.
*/
Layer &add_layer(Layer *layer);
Layer &add_layer(StringRefNull name);
/**
* Adds a layer before \a link and returns it.
*/
Layer &add_layer_before(Layer *layer, TreeNode *link);
Layer &add_layer_before(StringRefNull name, TreeNode *link);
/**
* Adds a layer after \a link and returns it.
*/
Layer &add_layer_after(Layer *layer, TreeNode *link);
Layer &add_layer_after(StringRefNull name, TreeNode *link);
/**
* Move child \a node up/down by \a step.
*/
void move_node_up(TreeNode *node, int step = 1);
void move_node_down(TreeNode *node, int step = 1);
/**
* Move child \a node to the top/bottom.
*/
void move_node_top(TreeNode *node);
void move_node_bottom(TreeNode *node);
/** /**
* Returns the number of direct nodes in this group. * Returns the number of direct nodes in this group.
*/ */
@ -511,12 +472,6 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
*/ */
int64_t num_nodes_total() const; int64_t num_nodes_total() const;
/**
* Tries to unlink the layer from the list of nodes in this group.
* \returns true, if the layer was successfully unlinked.
*/
bool unlink_node(TreeNode *link);
/** /**
* Returns a `Span` of pointers to all the `TreeNode`s in this group. * Returns a `Span` of pointers to all the `TreeNode`s in this group.
*/ */
@ -552,6 +507,46 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
*/ */
void print_nodes(StringRefNull header) const; void print_nodes(StringRefNull header) const;
protected:
/**
* Adds a new layer named \a name at the end of this group and returns it.
*/
Layer &add_layer(StringRefNull name);
/**
* Adds a new group named \a name at the end of this group and returns it.
*/
LayerGroup &add_group(StringRefNull name);
/**
* Adds an existing \a node at the end of this group.
*/
TreeNode &add_node(TreeNode &node);
/**
* Adds an existing \a node before \a link of this group.
*/
void add_node_before(TreeNode &node, TreeNode &link);
/**
* Adds an existing \a node after \a link of this group.
*/
void add_node_after(TreeNode &node, TreeNode &link);
/**
* Move child \a node up/down by \a step.
*/
void move_node_up(TreeNode &node, int step = 1);
void move_node_down(TreeNode &node, int step = 1);
/**
* Move child \a node to the top/bottom.
*/
void move_node_top(TreeNode &node);
void move_node_bottom(TreeNode &node);
/**
* Unlink the node from the list of nodes in this group.
* \returns true, if the node was successfully unlinked.
*/
bool unlink_node(TreeNode &link);
private: private:
void ensure_nodes_cache() const; void ensure_nodes_cache() const;
void tag_nodes_cache_dirty() const; void tag_nodes_cache_dirty() const;

View File

@ -69,6 +69,18 @@ void BKE_light_linking_add_receiver_to_collection(struct Main *bmain,
struct Collection *collection, struct Collection *collection,
struct ID *receiver, struct ID *receiver,
const eCollectionLightLinkingState link_state); const eCollectionLightLinkingState link_state);
void BKE_light_linking_add_receiver_to_collection_before(
struct Main *bmain,
struct Collection *collection,
struct ID *receiver,
const struct ID *before,
const eCollectionLightLinkingState link_state);
void BKE_light_linking_add_receiver_to_collection_after(
struct Main *bmain,
struct Collection *collection,
struct ID *receiver,
const struct ID *after,
const eCollectionLightLinkingState link_state);
/* Remove the given ID from the light or shadow linking collection of the given object. /* Remove the given ID from the light or shadow linking collection of the given object.
* *

View File

@ -110,8 +110,8 @@ struct CCGVert {
CCGEdge **edges; CCGEdge **edges;
CCGFace **faces; CCGFace **faces;
/* byte *levelData; */ // byte *levelData;
/* byte *user_data; */ // byte *user_data;
}; };
struct CCGEdge { struct CCGEdge {
@ -124,8 +124,8 @@ struct CCGEdge {
CCGVert *v0, *v1; CCGVert *v0, *v1;
CCGFace **faces; CCGFace **faces;
/* byte *levelData; */ // byte *levelData;
/* byte *user_data; */ // byte *user_data;
}; };
struct CCGFace { struct CCGFace {
@ -135,11 +135,11 @@ struct CCGFace {
short numVerts, flags; short numVerts, flags;
int osd_index; int osd_index;
/* CCGVert **verts; */ // CCGVert **verts;
/* CCGEdge **edges; */ // CCGEdge **edges;
/* byte *centerData; */ // byte *centerData;
/* byte **gridData; */ // byte **gridData;
/* byte *user_data; */ // byte *user_data;
}; };
typedef enum { typedef enum {

View File

@ -372,12 +372,8 @@ void action_group_colors_sync(bActionGroup *grp, const bActionGroup *ref_grp)
void action_group_colors_set_from_posebone(bActionGroup *grp, const bPoseChannel *pchan) void action_group_colors_set_from_posebone(bActionGroup *grp, const bPoseChannel *pchan)
{ {
if (pchan->color.palette_index == 0) { const BoneColor &color = blender::animrig::ANIM_bonecolor_posebone_get(pchan);
action_group_colors_set(grp, &pchan->bone->color); action_group_colors_set(grp, &color);
}
else {
action_group_colors_set(grp, &pchan->color);
}
} }
void action_group_colors_set(bActionGroup *grp, const BoneColor *color) void action_group_colors_set(bActionGroup *grp, const BoneColor *color)
@ -1168,37 +1164,32 @@ void BKE_pose_channel_copy_data(bPoseChannel *pchan, const bPoseChannel *pchan_f
void BKE_pose_update_constraint_flags(bPose *pose) void BKE_pose_update_constraint_flags(bPose *pose)
{ {
bPoseChannel *parchan;
/* clear */
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
pchan->constflag = 0;
}
pose->flag &= ~POSE_CONSTRAINTS_TIMEDEPEND; pose->flag &= ~POSE_CONSTRAINTS_TIMEDEPEND;
/* detect */
LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) { LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
pchan->constflag = 0;
LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) { LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
if (con->type == CONSTRAINT_TYPE_KINEMATIC) { pchan->constflag |= PCHAN_HAS_CONST;
switch (con->type) {
case CONSTRAINT_TYPE_KINEMATIC: {
bKinematicConstraint *data = (bKinematicConstraint *)con->data; bKinematicConstraint *data = (bKinematicConstraint *)con->data;
pchan->constflag |= PCHAN_HAS_IK; pchan->constflag |= PCHAN_HAS_IK;
if (data->tar == nullptr || (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0)) { if (data->tar == nullptr || (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0))
pchan->constflag |= PCHAN_HAS_TARGET; {
pchan->constflag |= PCHAN_HAS_NO_TARGET;
} }
bPoseChannel *chain_tip = (data->flag & CONSTRAINT_IK_TIP) ? pchan : pchan->parent;
/* negative rootbone = recalc rootbone index. used in do_versions */ /* negative rootbone = recalc rootbone index. used in do_versions */
if (data->rootbone < 0) { if (data->rootbone < 0) {
data->rootbone = 0; data->rootbone = 0;
if (data->flag & CONSTRAINT_IK_TIP) { bPoseChannel *parchan = chain_tip;
parchan = pchan;
}
else {
parchan = pchan->parent;
}
while (parchan) { while (parchan) {
data->rootbone++; data->rootbone++;
if ((parchan->bone->flag & BONE_CONNECTED) == 0) { if ((parchan->bone->flag & BONE_CONNECTED) == 0) {
@ -1207,12 +1198,21 @@ void BKE_pose_update_constraint_flags(bPose *pose)
parchan = parchan->parent; parchan = parchan->parent;
} }
} }
}
else if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) {
bFollowPathConstraint *data = (bFollowPathConstraint *)con->data;
/* for drawing constraint colors when color set allows this */ /* Mark the pose bones in the IK chain as influenced by it. */
pchan->constflag |= PCHAN_HAS_CONST; {
bPoseChannel *chain_bone = chain_tip;
for (short index = 0; chain_bone && (data->rootbone == 0 || index < data->rootbone);
index++) {
chain_bone->constflag |= PCHAN_INFLUENCED_BY_IK;
chain_bone = chain_bone->parent;
}
}
break;
}
case CONSTRAINT_TYPE_FOLLOWPATH: {
bFollowPathConstraint *data = (bFollowPathConstraint *)con->data;
/* if we have a valid target, make sure that this will get updated on frame-change /* if we have a valid target, make sure that this will get updated on frame-change
* (needed for when there is no anim-data for this pose) * (needed for when there is no anim-data for this pose)
@ -1220,15 +1220,19 @@ void BKE_pose_update_constraint_flags(bPose *pose)
if ((data->tar) && (data->tar->type == OB_CURVES_LEGACY)) { if ((data->tar) && (data->tar->type == OB_CURVES_LEGACY)) {
pose->flag |= POSE_CONSTRAINTS_TIMEDEPEND; pose->flag |= POSE_CONSTRAINTS_TIMEDEPEND;
} }
break;
} }
else if (con->type == CONSTRAINT_TYPE_SPLINEIK) {
case CONSTRAINT_TYPE_SPLINEIK:
pchan->constflag |= PCHAN_HAS_SPLINEIK; pchan->constflag |= PCHAN_HAS_SPLINEIK;
} break;
else {
pchan->constflag |= PCHAN_HAS_CONST; default:
break;
} }
} }
} }
pose->flag &= ~POSE_CONSTRAINTS_NEED_UPDATE_FLAGS; pose->flag &= ~POSE_CONSTRAINTS_NEED_UPDATE_FLAGS;
} }

View File

@ -942,6 +942,7 @@ static void pose_channel_flush_to_orig_if_needed(Depsgraph *depsgraph,
copy_v3_v3(pchan_orig->pose_head, pchan->pose_mat[3]); copy_v3_v3(pchan_orig->pose_head, pchan->pose_mat[3]);
copy_m4_m4(pchan_orig->constinv, pchan->constinv); copy_m4_m4(pchan_orig->constinv, pchan->constinv);
copy_v3_v3(pchan_orig->pose_tail, pchan->pose_tail); copy_v3_v3(pchan_orig->pose_tail, pchan->pose_tail);
pchan_orig->constflag = pchan->constflag;
} }
void BKE_pose_bone_done(Depsgraph *depsgraph, Object *object, int pchan_index) void BKE_pose_bone_done(Depsgraph *depsgraph, Object *object, int pchan_index)

View File

@ -738,7 +738,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH; brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
brush->gpencil_settings->draw_angle = 0.0f; brush->gpencil_settings->draw_angle = 0.0f;
brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->draw_angle_factor = 0.0f;
brush->gpencil_settings->hardeness = 0.9f; brush->gpencil_settings->hardness = 0.9f;
copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f); copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f);
brush->gpencil_tool = GPAINT_TOOL_DRAW; brush->gpencil_tool = GPAINT_TOOL_DRAW;
@ -761,7 +761,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH; brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
brush->gpencil_settings->draw_angle = 0.0f; brush->gpencil_settings->draw_angle = 0.0f;
brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->draw_angle_factor = 0.0f;
brush->gpencil_settings->hardeness = 1.0f; brush->gpencil_settings->hardness = 1.0f;
copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f); copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f);
brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
@ -796,7 +796,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH; brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
brush->gpencil_settings->draw_angle = 0.0f; brush->gpencil_settings->draw_angle = 0.0f;
brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->draw_angle_factor = 0.0f;
brush->gpencil_settings->hardeness = 1.0f; brush->gpencil_settings->hardness = 1.0f;
copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f); copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f);
brush->gpencil_settings->flag &= ~GP_BRUSH_GROUP_SETTINGS; brush->gpencil_settings->flag &= ~GP_BRUSH_GROUP_SETTINGS;
@ -833,7 +833,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH; brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
brush->gpencil_settings->draw_angle = 0.0f; brush->gpencil_settings->draw_angle = 0.0f;
brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->draw_angle_factor = 0.0f;
brush->gpencil_settings->hardeness = 1.0f; brush->gpencil_settings->hardness = 1.0f;
copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f); copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f);
brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
@ -870,7 +870,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->active_smooth = 0.3f; brush->gpencil_settings->active_smooth = 0.3f;
brush->gpencil_settings->draw_angle = DEG2RAD(35.0f); brush->gpencil_settings->draw_angle = DEG2RAD(35.0f);
brush->gpencil_settings->draw_angle_factor = 0.5f; brush->gpencil_settings->draw_angle_factor = 0.5f;
brush->gpencil_settings->hardeness = 1.0f; brush->gpencil_settings->hardness = 1.0f;
copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f); copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f);
brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
@ -912,7 +912,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH; brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
brush->gpencil_settings->draw_angle = 0.0f; brush->gpencil_settings->draw_angle = 0.0f;
brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->draw_angle_factor = 0.0f;
brush->gpencil_settings->hardeness = 1.0f; brush->gpencil_settings->hardness = 1.0f;
copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f); copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f);
brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
@ -943,7 +943,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH; brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
brush->gpencil_settings->draw_angle = 0.0f; brush->gpencil_settings->draw_angle = 0.0f;
brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->draw_angle_factor = 0.0f;
brush->gpencil_settings->hardeness = 0.8f; brush->gpencil_settings->hardness = 0.8f;
copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f); copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f);
brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
@ -977,7 +977,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH; brush->gpencil_settings->active_smooth = ACTIVE_SMOOTH;
brush->gpencil_settings->draw_angle = 0.0f; brush->gpencil_settings->draw_angle = 0.0f;
brush->gpencil_settings->draw_angle_factor = 0.0f; brush->gpencil_settings->draw_angle_factor = 0.0f;
brush->gpencil_settings->hardeness = 1.0f; brush->gpencil_settings->hardness = 1.0f;
copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f); copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f);
brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS; brush->gpencil_settings->flag |= GP_BRUSH_GROUP_SETTINGS;
@ -1004,7 +1004,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
brush->gpencil_settings->fill_factor = 1.0f; brush->gpencil_settings->fill_factor = 1.0f;
brush->gpencil_settings->draw_strength = 1.0f; brush->gpencil_settings->draw_strength = 1.0f;
brush->gpencil_settings->hardeness = 1.0f; brush->gpencil_settings->hardness = 1.0f;
copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f); copy_v2_fl(brush->gpencil_settings->aspect_ratio, 1.0f);
brush->gpencil_settings->draw_smoothfac = 0.1f; brush->gpencil_settings->draw_smoothfac = 0.1f;
brush->gpencil_settings->draw_smoothlvl = 1; brush->gpencil_settings->draw_smoothlvl = 1;

View File

@ -1406,7 +1406,7 @@ void BKE_histogram_update_sample_line(Histogram *hist,
hist->channels = 3; hist->channels = 3;
hist->x_resolution = 256; hist->x_resolution = 256;
hist->xmax = 1.0f; hist->xmax = 1.0f;
/* hist->ymax = 1.0f; */ /* now do this on the operator _only_ */ // hist->ymax = 1.0f; /* now do this on the operator _only_ */
if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) { if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) {
return; return;

View File

@ -5476,7 +5476,7 @@ static void constraints_init_typeinfo()
constraintsTypeInfo[14] = &CTI_DISTLIMIT; /* Limit Distance Constraint */ constraintsTypeInfo[14] = &CTI_DISTLIMIT; /* Limit Distance Constraint */
constraintsTypeInfo[15] = &CTI_STRETCHTO; /* StretchTo Constraint */ constraintsTypeInfo[15] = &CTI_STRETCHTO; /* StretchTo Constraint */
constraintsTypeInfo[16] = &CTI_MINMAX; /* Floor Constraint */ constraintsTypeInfo[16] = &CTI_MINMAX; /* Floor Constraint */
/* constraintsTypeInfo[17] = &CTI_RIGIDBODYJOINT; */ /* RigidBody Constraint - Deprecated */ constraintsTypeInfo[17] = nullptr; /* RigidBody Constraint: DEPRECATED. */
constraintsTypeInfo[18] = &CTI_CLAMPTO; /* ClampTo Constraint */ constraintsTypeInfo[18] = &CTI_CLAMPTO; /* ClampTo Constraint */
constraintsTypeInfo[19] = &CTI_TRANSFORM; /* Transformation Constraint */ constraintsTypeInfo[19] = &CTI_TRANSFORM; /* Transformation Constraint */
constraintsTypeInfo[20] = &CTI_SHRINKWRAP; /* Shrinkwrap Constraint */ constraintsTypeInfo[20] = &CTI_SHRINKWRAP; /* Shrinkwrap Constraint */

View File

@ -2154,8 +2154,8 @@ static void bevel_list_smooth(BevList *bl, int smooth_iter)
nr = bl->nr; nr = bl->nr;
if (bl->poly == -1) { /* check its not cyclic */ if (bl->poly == -1) { /* check its not cyclic */
/* skip the first point */ /* Skip the first point. */
/* bevp0 = bevp1; */ // bevp0 = bevp1;
bevp1 = bevp2; bevp1 = bevp2;
bevp2++; bevp2++;
nr--; nr--;
@ -2184,7 +2184,7 @@ static void bevel_list_smooth(BevList *bl, int smooth_iter)
interp_qt_qtqt(bevp1->quat, bevp1->quat, q, 0.5); interp_qt_qtqt(bevp1->quat, bevp1->quat, q, 0.5);
normalize_qt(bevp1->quat); normalize_qt(bevp1->quat);
/* bevp0 = bevp1; */ /* UNUSED */ // bevp0 = bevp1; /* UNUSED */
bevp1 = bevp2; bevp1 = bevp2;
bevp2++; bevp2++;
} }
@ -2385,7 +2385,7 @@ static void make_bevel_list_3D_tangent(BevList *bl)
normalize_v3(cross_tmp); normalize_v3(cross_tmp);
tri_to_quat(bevp1->quat, zero, cross_tmp, bevp1->tan); /* XXX: could be faster. */ tri_to_quat(bevp1->quat, zero, cross_tmp, bevp1->tan); /* XXX: could be faster. */
/* bevp0 = bevp1; */ /* UNUSED */ // bevp0 = bevp1; /* UNUSED */
bevp1 = bevp2; bevp1 = bevp2;
bevp2++; bevp2++;
} }

View File

@ -304,7 +304,7 @@ static void gpencil_convert_spline(Main *bmain,
bGPDstroke *gps = static_cast<bGPDstroke *>(MEM_callocN(sizeof(bGPDstroke), "bGPDstroke")); bGPDstroke *gps = static_cast<bGPDstroke *>(MEM_callocN(sizeof(bGPDstroke), "bGPDstroke"));
gps->thickness = 1.0f; gps->thickness = 1.0f;
gps->fill_opacity_fac = 1.0f; gps->fill_opacity_fac = 1.0f;
gps->hardeness = 1.0f; gps->hardness = 1.0f;
gps->uv_scale = 1.0f; gps->uv_scale = 1.0f;
ARRAY_SET_ITEMS(gps->aspect_ratio, 1.0f, 1.0f); ARRAY_SET_ITEMS(gps->aspect_ratio, 1.0f, 1.0f);

View File

@ -727,7 +727,7 @@ bGPDstroke *BKE_gpencil_stroke_new(int mat_idx, int totpoints, short thickness)
gps->thickness = thickness; gps->thickness = thickness;
gps->fill_opacity_fac = 1.0f; gps->fill_opacity_fac = 1.0f;
gps->hardeness = 1.0f; gps->hardness = 1.0f;
copy_v2_fl(gps->aspect_ratio, 1.0f); copy_v2_fl(gps->aspect_ratio, 1.0f);
gps->uv_scale = 1.0f; gps->uv_scale = 1.0f;
@ -1013,7 +1013,7 @@ void BKE_gpencil_stroke_copy_settings(const bGPDstroke *gps_src, bGPDstroke *gps
gps_dst->inittime = gps_src->inittime; gps_dst->inittime = gps_src->inittime;
gps_dst->mat_nr = gps_src->mat_nr; gps_dst->mat_nr = gps_src->mat_nr;
copy_v2_v2_short(gps_dst->caps, gps_src->caps); copy_v2_v2_short(gps_dst->caps, gps_src->caps);
gps_dst->hardeness = gps_src->hardeness; gps_dst->hardness = gps_src->hardness;
copy_v2_v2(gps_dst->aspect_ratio, gps_src->aspect_ratio); copy_v2_v2(gps_dst->aspect_ratio, gps_src->aspect_ratio);
gps_dst->fill_opacity_fac = gps_dst->fill_opacity_fac; gps_dst->fill_opacity_fac = gps_dst->fill_opacity_fac;
copy_v3_v3(gps_dst->boundbox_min, gps_src->boundbox_min); copy_v3_v3(gps_dst->boundbox_min, gps_src->boundbox_min);

View File

@ -759,13 +759,13 @@ LayerGroup::LayerGroup(const LayerGroup &other) : LayerGroup()
case GP_LAYER_TREE_LEAF: { case GP_LAYER_TREE_LEAF: {
GreasePencilLayer *layer = reinterpret_cast<GreasePencilLayer *>(child); GreasePencilLayer *layer = reinterpret_cast<GreasePencilLayer *>(child);
Layer *dup_layer = MEM_new<Layer>(__func__, layer->wrap()); Layer *dup_layer = MEM_new<Layer>(__func__, layer->wrap());
this->add_layer(dup_layer); this->add_node(dup_layer->as_node());
break; break;
} }
case GP_LAYER_TREE_GROUP: { case GP_LAYER_TREE_GROUP: {
GreasePencilLayerTreeGroup *group = reinterpret_cast<GreasePencilLayerTreeGroup *>(child); GreasePencilLayerTreeGroup *group = reinterpret_cast<GreasePencilLayerTreeGroup *>(child);
LayerGroup *dup_group = MEM_new<LayerGroup>(__func__, group->wrap()); LayerGroup *dup_group = MEM_new<LayerGroup>(__func__, group->wrap());
this->add_group(dup_group); this->add_node(dup_group->as_node());
break; break;
} }
} }
@ -795,107 +795,60 @@ LayerGroup::~LayerGroup()
this->runtime = nullptr; this->runtime = nullptr;
} }
LayerGroup &LayerGroup::add_group(LayerGroup *group) Layer &LayerGroup::add_layer(StringRefNull name)
{ {
BLI_assert(group != nullptr); Layer *new_layer = MEM_new<Layer>(__func__, name);
BLI_addtail(&this->children, reinterpret_cast<GreasePencilLayerTreeNode *>(group)); return this->add_node(new_layer->as_node()).as_layer();
group->base.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
this->tag_nodes_cache_dirty();
return *group;
} }
LayerGroup &LayerGroup::add_group(StringRefNull name) LayerGroup &LayerGroup::add_group(StringRefNull name)
{ {
LayerGroup *new_group = MEM_new<LayerGroup>(__func__, name); LayerGroup *new_group = MEM_new<LayerGroup>(__func__, name);
return this->add_group(new_group); return this->add_node(new_group->as_node()).as_group();
} }
LayerGroup &LayerGroup::add_group_after(LayerGroup *group, TreeNode *link) TreeNode &LayerGroup::add_node(TreeNode &node)
{ {
BLI_assert(group != nullptr && link != nullptr); BLI_addtail(&this->children, &node);
BLI_insertlinkafter(&this->children, node.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
reinterpret_cast<GreasePencilLayerTreeNode *>(link),
reinterpret_cast<GreasePencilLayerTreeNode *>(group));
group->base.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
this->tag_nodes_cache_dirty(); this->tag_nodes_cache_dirty();
return *group; return node;
} }
void LayerGroup::add_node_before(TreeNode &node, TreeNode &link)
LayerGroup &LayerGroup::add_group_after(StringRefNull name, TreeNode *link)
{ {
LayerGroup *new_group = MEM_new<LayerGroup>(__func__, name); BLI_assert(BLI_findindex(&this->children, &link) != -1);
return this->add_group_after(new_group, link); BLI_insertlinkbefore(&this->children, &link, &node);
} node.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
Layer &LayerGroup::add_layer(Layer *layer)
{
BLI_assert(layer != nullptr);
BLI_addtail(&this->children, reinterpret_cast<GreasePencilLayerTreeNode *>(layer));
layer->base.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
this->tag_nodes_cache_dirty();
return *layer;
}
Layer &LayerGroup::add_layer_before(Layer *layer, TreeNode *link)
{
BLI_assert(layer != nullptr && link != nullptr);
BLI_insertlinkbefore(&this->children,
reinterpret_cast<GreasePencilLayerTreeNode *>(link),
reinterpret_cast<GreasePencilLayerTreeNode *>(layer));
layer->base.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
this->tag_nodes_cache_dirty();
return *layer;
}
Layer &LayerGroup::add_layer_after(Layer *layer, TreeNode *link)
{
BLI_assert(layer != nullptr && link != nullptr);
BLI_insertlinkafter(&this->children,
reinterpret_cast<GreasePencilLayerTreeNode *>(link),
reinterpret_cast<GreasePencilLayerTreeNode *>(layer));
layer->base.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
this->tag_nodes_cache_dirty();
return *layer;
}
Layer &LayerGroup::add_layer(StringRefNull name)
{
Layer *new_layer = MEM_new<Layer>(__func__, name);
return this->add_layer(new_layer);
}
Layer &LayerGroup::add_layer_before(StringRefNull name, TreeNode *link)
{
Layer *new_layer = MEM_new<Layer>(__func__, name);
return this->add_layer_before(new_layer, link);
}
Layer &LayerGroup::add_layer_after(StringRefNull name, TreeNode *link)
{
Layer *new_layer = MEM_new<Layer>(__func__, name);
return this->add_layer_after(new_layer, link);
}
void LayerGroup::move_node_up(TreeNode *node, const int step)
{
BLI_listbase_link_move(&this->children, node, step);
this->tag_nodes_cache_dirty(); this->tag_nodes_cache_dirty();
} }
void LayerGroup::move_node_down(TreeNode *node, const int step) void LayerGroup::add_node_after(TreeNode &node, TreeNode &link)
{ {
BLI_listbase_link_move(&this->children, node, -step); BLI_assert(BLI_findindex(&this->children, &link) != -1);
BLI_insertlinkafter(&this->children, &link, &node);
node.parent = reinterpret_cast<GreasePencilLayerTreeGroup *>(this);
this->tag_nodes_cache_dirty(); this->tag_nodes_cache_dirty();
} }
void LayerGroup::move_node_top(TreeNode *node)
void LayerGroup::move_node_up(TreeNode &node, const int step)
{ {
BLI_remlink(&this->children, node); BLI_listbase_link_move(&this->children, &node, step);
BLI_insertlinkafter(&this->children, this->children.last, node);
this->tag_nodes_cache_dirty(); this->tag_nodes_cache_dirty();
} }
void LayerGroup::move_node_bottom(TreeNode *node) void LayerGroup::move_node_down(TreeNode &node, const int step)
{ {
BLI_remlink(&this->children, node); BLI_listbase_link_move(&this->children, &node, -step);
BLI_insertlinkbefore(&this->children, this->children.first, node); this->tag_nodes_cache_dirty();
}
void LayerGroup::move_node_top(TreeNode &node)
{
BLI_remlink(&this->children, &node);
BLI_insertlinkafter(&this->children, this->children.last, &node);
this->tag_nodes_cache_dirty();
}
void LayerGroup::move_node_bottom(TreeNode &node)
{
BLI_remlink(&this->children, &node);
BLI_insertlinkbefore(&this->children, this->children.first, &node);
this->tag_nodes_cache_dirty(); this->tag_nodes_cache_dirty();
} }
@ -910,11 +863,11 @@ int64_t LayerGroup::num_nodes_total() const
return this->runtime->nodes_cache_.size(); return this->runtime->nodes_cache_.size();
} }
bool LayerGroup::unlink_node(TreeNode *link) bool LayerGroup::unlink_node(TreeNode &link)
{ {
if (BLI_remlink_safe(&this->children, link)) { if (BLI_remlink_safe(&this->children, &link)) {
this->tag_nodes_cache_dirty(); this->tag_nodes_cache_dirty();
link->parent = nullptr; link.parent = nullptr;
return true; return true;
} }
return false; return false;
@ -1619,6 +1572,26 @@ void GreasePencil::move_duplicate_frames(
this->remove_drawings_with_no_users(); this->remove_drawings_with_no_users();
} }
const blender::bke::greasepencil::Drawing *GreasePencil::get_drawing_at(
const blender::bke::greasepencil::Layer *layer, const int frame_number) const
{
if (layer == nullptr) {
return nullptr;
}
const int drawing_index = layer->drawing_index_at(frame_number);
if (drawing_index == -1) {
/* No drawing found. */
return nullptr;
}
const GreasePencilDrawingBase *drawing_base = this->drawing(drawing_index);
if (drawing_base->type != GP_DRAWING) {
/* TODO: Get reference drawing. */
return nullptr;
}
const GreasePencilDrawing *drawing = reinterpret_cast<const GreasePencilDrawing *>(drawing_base);
return &drawing->wrap();
}
blender::bke::greasepencil::Drawing *GreasePencil::get_editable_drawing_at( blender::bke::greasepencil::Drawing *GreasePencil::get_editable_drawing_at(
const blender::bke::greasepencil::Layer *layer, const int frame_number) const blender::bke::greasepencil::Layer *layer, const int frame_number)
{ {
@ -1762,12 +1735,6 @@ std::optional<blender::Bounds<blender::float3>> GreasePencil::bounds_min_max() c
return bounds; return bounds;
} }
blender::Span<const blender::bke::greasepencil::TreeNode *> GreasePencil::nodes() const
{
BLI_assert(this->runtime != nullptr);
return this->root_group().nodes();
}
blender::Span<const blender::bke::greasepencil::Layer *> GreasePencil::layers() const blender::Span<const blender::bke::greasepencil::Layer *> GreasePencil::layers() const
{ {
BLI_assert(this->runtime != nullptr); BLI_assert(this->runtime != nullptr);
@ -1780,18 +1747,30 @@ blender::Span<blender::bke::greasepencil::Layer *> GreasePencil::layers_for_writ
return this->root_group().layers_for_write(); return this->root_group().layers_for_write();
} }
blender::Span<const blender::bke::greasepencil::LayerGroup *> GreasePencil::groups() const blender::Span<const blender::bke::greasepencil::LayerGroup *> GreasePencil::layer_groups() const
{ {
BLI_assert(this->runtime != nullptr); BLI_assert(this->runtime != nullptr);
return this->root_group().groups(); return this->root_group().groups();
} }
blender::Span<blender::bke::greasepencil::LayerGroup *> GreasePencil::groups_for_write() blender::Span<blender::bke::greasepencil::LayerGroup *> GreasePencil::layer_groups_for_write()
{ {
BLI_assert(this->runtime != nullptr); BLI_assert(this->runtime != nullptr);
return this->root_group().groups_for_write(); return this->root_group().groups_for_write();
} }
blender::Span<const blender::bke::greasepencil::TreeNode *> GreasePencil::nodes() const
{
BLI_assert(this->runtime != nullptr);
return this->root_group().nodes();
}
blender::Span<blender::bke::greasepencil::TreeNode *> GreasePencil::nodes_for_write()
{
BLI_assert(this->runtime != nullptr);
return this->root_group().nodes_for_write();
}
const blender::bke::greasepencil::Layer *GreasePencil::get_active_layer() const const blender::bke::greasepencil::Layer *GreasePencil::get_active_layer() const
{ {
if (this->active_layer == nullptr) { if (this->active_layer == nullptr) {
@ -1870,68 +1849,71 @@ static std::string unique_layer_group_name(const GreasePencil &grease_pencil,
} }
blender::bke::greasepencil::Layer &GreasePencil::add_layer( blender::bke::greasepencil::Layer &GreasePencil::add_layer(
blender::bke::greasepencil::LayerGroup &group, const blender::StringRefNull name) blender::bke::greasepencil::LayerGroup &parent_group, const blender::StringRefNull name)
{ {
using namespace blender; using namespace blender;
std::string unique_name = unique_layer_name(*this, name); std::string unique_name = unique_layer_name(*this, name);
return group.add_layer(unique_name); return parent_group.add_layer(unique_name);
}
blender::bke::greasepencil::Layer &GreasePencil::add_layer_after(
blender::bke::greasepencil::LayerGroup &group,
blender::bke::greasepencil::TreeNode *link,
const blender::StringRefNull name)
{
using namespace blender;
std::string unique_name = unique_layer_name(*this, name);
return group.add_layer_after(unique_name, link);
}
void GreasePencil::move_layer_up(blender::bke::greasepencil::Layer *layer,
blender::bke::greasepencil::Layer *move_along_layer)
{
layer->parent_group().unlink_node(&layer->as_node());
move_along_layer->parent_group().add_layer_after(layer, &move_along_layer->as_node());
}
void GreasePencil::move_layer_down(blender::Span<blender::bke::greasepencil::Layer *> layers,
blender::bke::greasepencil::Layer *move_along_layer)
{
for (int i = layers.size() - 1; i >= 0; i--) {
using namespace blender::bke::greasepencil;
Layer *layer = layers[i];
layer->parent_group().unlink_node(&layer->as_node());
move_along_layer->parent_group().add_layer_before(layer, &move_along_layer->as_node());
}
}
blender::bke::greasepencil::Layer &GreasePencil::add_layer(const blender::StringRefNull name)
{
return this->add_layer(this->root_group(), name);
} }
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group( blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group(
blender::bke::greasepencil::LayerGroup &group, const blender::StringRefNull name) blender::bke::greasepencil::LayerGroup &parent_group, const blender::StringRefNull name)
{ {
using namespace blender; using namespace blender;
std::string unique_name = unique_layer_group_name(*this, name); std::string unique_name = unique_layer_group_name(*this, name);
return group.add_group(unique_name); return parent_group.add_group(unique_name);
} }
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group_after( void GreasePencil::move_node_up(blender::bke::greasepencil::TreeNode &node, const int step)
blender::bke::greasepencil::LayerGroup &group,
blender::bke::greasepencil::TreeNode *node,
const blender::StringRefNull name)
{ {
using namespace blender; if (node.parent_group()) {
std::string unique_name = unique_layer_group_name(*this, name); node.parent_group()->move_node_up(node, step);
return group.add_group_after(unique_name, node); }
}
void GreasePencil::move_node_down(blender::bke::greasepencil::TreeNode &node, const int step)
{
if (node.parent_group()) {
node.parent_group()->move_node_down(node, step);
}
}
void GreasePencil::move_node_top(blender::bke::greasepencil::TreeNode &node)
{
if (node.parent_group()) {
node.parent_group()->move_node_top(node);
}
}
void GreasePencil::move_node_bottom(blender::bke::greasepencil::TreeNode &node)
{
if (node.parent_group()) {
node.parent_group()->move_node_bottom(node);
}
} }
blender::bke::greasepencil::LayerGroup &GreasePencil::add_layer_group( void GreasePencil::move_node_after(blender::bke::greasepencil::TreeNode &node,
const blender::StringRefNull name) blender::bke::greasepencil::TreeNode &target_node)
{ {
return this->add_layer_group(this->root_group(), name); if (!target_node.parent_group() || !node.parent_group()) {
return;
}
node.parent_group()->unlink_node(node);
target_node.parent_group()->add_node_after(node, target_node);
}
void GreasePencil::move_node_before(blender::bke::greasepencil::TreeNode &node,
blender::bke::greasepencil::TreeNode &target_node)
{
if (!target_node.parent_group() || !node.parent_group()) {
return;
}
node.parent_group()->unlink_node(node);
target_node.parent_group()->add_node_before(node, target_node);
}
void GreasePencil::move_node_into(blender::bke::greasepencil::TreeNode &node,
blender::bke::greasepencil::LayerGroup &parent_group)
{
if (node.parent_group()) {
node.parent_group()->unlink_node(node);
}
parent_group.add_node(node);
} }
const blender::bke::greasepencil::Layer *GreasePencil::find_layer_by_name( const blender::bke::greasepencil::Layer *GreasePencil::find_layer_by_name(
@ -1946,13 +1928,13 @@ blender::bke::greasepencil::Layer *GreasePencil::find_layer_by_name(
return this->root_group().find_layer_by_name(name); return this->root_group().find_layer_by_name(name);
} }
const blender::bke::greasepencil::LayerGroup *GreasePencil::find_group_by_name( const blender::bke::greasepencil::LayerGroup *GreasePencil::find_layer_group_by_name(
blender::StringRefNull name) const blender::StringRefNull name) const
{ {
return this->root_group().find_group_by_name(name); return this->root_group().find_group_by_name(name);
} }
blender::bke::greasepencil::LayerGroup *GreasePencil::find_group_by_name( blender::bke::greasepencil::LayerGroup *GreasePencil::find_layer_group_by_name(
blender::StringRefNull name) blender::StringRefNull name)
{ {
return this->root_group().find_group_by_name(name); return this->root_group().find_group_by_name(name);
@ -1993,7 +1975,7 @@ void GreasePencil::remove_layer(blender::bke::greasepencil::Layer &layer)
} }
/* Unlink the layer from the parent group. */ /* Unlink the layer from the parent group. */
layer.parent_group().unlink_node(&layer.as_node()); layer.parent_group().unlink_node(layer.as_node());
/* Remove drawings. */ /* Remove drawings. */
for (GreasePencilFrame frame : layer.frames_for_write().values()) { for (GreasePencilFrame frame : layer.frames_for_write().values()) {

View File

@ -101,7 +101,7 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
stroke_init_times.span[stroke_i] = float(gps->inittime); stroke_init_times.span[stroke_i] = float(gps->inittime);
stroke_start_caps.span[stroke_i] = int8_t(gps->caps[0]); stroke_start_caps.span[stroke_i] = int8_t(gps->caps[0]);
stroke_end_caps.span[stroke_i] = int8_t(gps->caps[1]); stroke_end_caps.span[stroke_i] = int8_t(gps->caps[1]);
stroke_hardnesses.span[stroke_i] = gps->hardeness; stroke_hardnesses.span[stroke_i] = gps->hardness;
stroke_point_aspect_ratios.span[stroke_i] = gps->aspect_ratio[0] / stroke_point_aspect_ratios.span[stroke_i] = gps->aspect_ratio[0] /
max_ff(gps->aspect_ratio[1], 1e-8); max_ff(gps->aspect_ratio[1], 1e-8);
stroke_fill_translations.span[stroke_i] = float2(gps->uv_translation); stroke_fill_translations.span[stroke_i] = float2(gps->uv_translation);

View File

@ -64,8 +64,8 @@ TEST(greasepencil, remove_drawings)
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(grease_pencil.drawing(1)); GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(grease_pencil.drawing(1));
drawing->wrap().strokes_for_write().resize(0, 10); drawing->wrap().strokes_for_write().resize(0, 10);
Layer &layer1 = grease_pencil.root_group().add_layer("Layer1"); Layer &layer1 = grease_pencil.add_layer(grease_pencil.root_group(), "Layer1");
Layer &layer2 = grease_pencil.root_group().add_layer("Layer2"); Layer &layer2 = grease_pencil.add_layer(grease_pencil.root_group(), "Layer2");
layer1.add_frame(0, 0); layer1.add_frame(0, 0);
layer1.add_frame(10, 1); layer1.add_frame(10, 1);
@ -95,34 +95,47 @@ TEST(greasepencil, remove_drawings)
TEST(greasepencil, layer_tree_empty) TEST(greasepencil, layer_tree_empty)
{ {
LayerGroup root; GreasePencil grease_pencil;
grease_pencil.root_group_ptr = MEM_new<greasepencil::LayerGroup>(__func__);
EXPECT_EQ(grease_pencil.root_group().num_nodes_total(), 0);
MEM_delete(&grease_pencil.root_group());
} }
TEST(greasepencil, layer_tree_build_simple) TEST(greasepencil, layer_tree_build_simple)
{ {
LayerGroup root; GreasePencil grease_pencil;
grease_pencil.root_group_ptr = MEM_new<greasepencil::LayerGroup>(__func__);
LayerGroup &group = root.add_group("Group1"); LayerGroup &group = grease_pencil.add_layer_group(grease_pencil.root_group(), "Group1");
group.add_layer("Layer1"); grease_pencil.add_layer(group, "Layer1");
group.add_layer("Layer2"); grease_pencil.add_layer(group, "Layer2");
EXPECT_EQ(grease_pencil.root_group().num_nodes_total(), 3);
MEM_delete(&grease_pencil.root_group());
} }
struct GreasePencilLayerTreeExample { struct GreasePencilLayerTreeExample {
StringRefNull names[7] = {"Group1", "Layer1", "Layer2", "Group2", "Layer3", "Layer4", "Layer5"}; StringRefNull names[7] = {"Group1", "Layer1", "Layer2", "Group2", "Layer3", "Layer4", "Layer5"};
const bool is_layer[7] = {false, true, true, false, true, true, true}; const bool is_layer[7] = {false, true, true, false, true, true, true};
LayerGroup root; GreasePencil grease_pencil;
GreasePencilLayerTreeExample() GreasePencilLayerTreeExample()
{ {
LayerGroup &group = root.add_group(names[0]); grease_pencil.root_group_ptr = MEM_new<greasepencil::LayerGroup>(__func__);
group.add_layer(names[1]);
group.add_layer(names[2]);
LayerGroup &group2 = group.add_group(names[3]); LayerGroup &group = grease_pencil.add_layer_group(grease_pencil.root_group(), names[0]);
group2.add_layer(names[4]); grease_pencil.add_layer(group, names[1]);
group2.add_layer(names[5]); grease_pencil.add_layer(group, names[2]);
root.add_layer(names[6]); LayerGroup &group2 = grease_pencil.add_layer_group(group, names[3]);
grease_pencil.add_layer(group2, names[4]);
grease_pencil.add_layer(group2, names[5]);
grease_pencil.add_layer(grease_pencil.root_group(), names[6]);
}
~GreasePencilLayerTreeExample()
{
MEM_delete(&grease_pencil.root_group());
} }
}; };
@ -130,7 +143,7 @@ TEST(greasepencil, layer_tree_pre_order_iteration)
{ {
GreasePencilLayerTreeExample ex; GreasePencilLayerTreeExample ex;
Span<const TreeNode *> children = ex.root.nodes(); Span<const TreeNode *> children = ex.grease_pencil.nodes();
for (const int i : children.index_range()) { for (const int i : children.index_range()) {
const TreeNode &child = *children[i]; const TreeNode &child = *children[i];
EXPECT_STREQ(child.name().data(), ex.names[i].data()); EXPECT_STREQ(child.name().data(), ex.names[i].data());
@ -141,7 +154,7 @@ TEST(greasepencil, layer_tree_pre_order_iteration2)
{ {
GreasePencilLayerTreeExample ex; GreasePencilLayerTreeExample ex;
Span<const Layer *> layers = ex.root.layers(); Span<const Layer *> layers = ex.grease_pencil.layers();
char name[64]; char name[64];
for (const int i : layers.index_range()) { for (const int i : layers.index_range()) {
const Layer &layer = *layers[i]; const Layer &layer = *layers[i];
@ -153,13 +166,13 @@ TEST(greasepencil, layer_tree_pre_order_iteration2)
TEST(greasepencil, layer_tree_total_size) TEST(greasepencil, layer_tree_total_size)
{ {
GreasePencilLayerTreeExample ex; GreasePencilLayerTreeExample ex;
EXPECT_EQ(ex.root.num_nodes_total(), 7); EXPECT_EQ(ex.grease_pencil.root_group().num_nodes_total(), 7);
} }
TEST(greasepencil, layer_tree_node_types) TEST(greasepencil, layer_tree_node_types)
{ {
GreasePencilLayerTreeExample ex; GreasePencilLayerTreeExample ex;
Span<const TreeNode *> children = ex.root.nodes(); Span<const TreeNode *> children = ex.grease_pencil.nodes();
for (const int i : children.index_range()) { for (const int i : children.index_range()) {
const TreeNode &child = *children[i]; const TreeNode &child = *children[i];
EXPECT_EQ(child.is_layer(), ex.is_layer[i]); EXPECT_EQ(child.is_layer(), ex.is_layer[i]);

View File

@ -769,13 +769,15 @@ static void gpu_texture_update_from_ibuf(
} }
else { else {
/* Byte image is in original colorspace from the file, and may need conversion. */ /* Byte image is in original colorspace from the file, and may need conversion. */
if (IMB_colormanagement_space_is_data(ibuf->byte_buffer.colorspace)) { if (IMB_colormanagement_space_is_data(ibuf->byte_buffer.colorspace) && !scaled) {
/* Non-color data, just store buffer as is. */ /* Not scaled Non-color data, just store buffer as is. */
} }
else if (IMB_colormanagement_space_is_srgb(ibuf->byte_buffer.colorspace) || else if (IMB_colormanagement_space_is_srgb(ibuf->byte_buffer.colorspace) ||
IMB_colormanagement_space_is_scene_linear(ibuf->byte_buffer.colorspace)) IMB_colormanagement_space_is_scene_linear(ibuf->byte_buffer.colorspace) ||
IMB_colormanagement_space_is_data(ibuf->byte_buffer.colorspace))
{ {
/* sRGB or scene linear, store as byte texture that the GPU can decode directly. */ /* sRGB or scene linear or scaled down non-color data , store as byte texture that the GPU
* can decode directly. */
rect = (uchar *)MEM_mallocN(sizeof(uchar[4]) * w * h, __func__); rect = (uchar *)MEM_mallocN(sizeof(uchar[4]) * w * h, __func__);
if (rect == nullptr) { if (rect == nullptr) {
return; return;

View File

@ -1609,7 +1609,7 @@ static void icu_to_fcurves(ID *id,
if (((icu->blocktype == ID_OB) && ELEM(icu->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) || if (((icu->blocktype == ID_OB) && ELEM(icu->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) ||
((icu->blocktype == ID_PO) && ELEM(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z))) ((icu->blocktype == ID_PO) && ELEM(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z)))
{ {
const float fac = float(M_PI) / 18.0f; /* 10.0f * M_PI/180.0f; */ const float fac = float(M_PI) / 18.0f; /* `10.0f * M_PI/180.0f`. */
dst->vec[0][1] *= fac; dst->vec[0][1] *= fac;
dst->vec[1][1] *= fac; dst->vec[1][1] *= fac;

View File

@ -461,7 +461,11 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
k1 = k[0] = k[1] = k[2] = k[3] = firstkey; k1 = k[0] = k[1] = k[2] = k[3] = firstkey;
t[0] = t[1] = t[2] = t[3] = k1->pos; t[0] = t[1] = t[2] = t[3] = k1->pos;
/* if (fac < 0.0 || fac > 1.0) return 1; */ #if 0
if (fac < 0.0 || fac > 1.0) {
return 1;
}
#endif
if (k1->next == nullptr) { if (k1->next == nullptr) {
return 1; return 1;
@ -479,7 +483,7 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
} }
k1 = k1->next; k1 = k1->next;
} }
/* k1 = k[1]; */ /* UNUSED */ // k1 = k[1]; /* UNUSED */
t[0] = k[0]->pos; t[0] = k[0]->pos;
t[1] += dpos; t[1] += dpos;
t[2] = k[2]->pos + dpos; t[2] = k[2]->pos + dpos;

View File

@ -133,6 +133,29 @@ void BKE_light_linking_collection_assign(Main *bmain,
DEG_relations_tag_update(bmain); DEG_relations_tag_update(bmain);
} }
static CollectionObject *find_collection_object(const Collection *collection, const Object *object)
{
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) {
if (collection_object->ob == object) {
return collection_object;
}
}
return nullptr;
}
static CollectionChild *find_collection_child(const Collection *collection,
const Collection *child)
{
LISTBASE_FOREACH (CollectionChild *, collection_child, &collection->children) {
if (collection_child->collection == child) {
return collection_child;
}
}
return nullptr;
}
/* Add object to the light linking collection and return corresponding CollectionLightLinking /* Add object to the light linking collection and return corresponding CollectionLightLinking
* settings. * settings.
* *
@ -144,17 +167,16 @@ static CollectionLightLinking *light_linking_collection_add_object(Main *bmain,
{ {
BKE_collection_object_add(bmain, collection, object); BKE_collection_object_add(bmain, collection, object);
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) { CollectionObject *collection_object = find_collection_object(collection, object);
if (collection_object->ob == object) {
return &collection_object->light_linking;
}
}
if (!collection_object) {
BLI_assert_msg(0, "Object was not found after added to the light linking collection"); BLI_assert_msg(0, "Object was not found after added to the light linking collection");
return nullptr; return nullptr;
} }
return &collection_object->light_linking;
}
/* Add child collection to the light linking collection and return corresponding /* Add child collection to the light linking collection and return corresponding
* CollectionLightLinking settings. * CollectionLightLinking settings.
* *
@ -166,17 +188,16 @@ static CollectionLightLinking *light_linking_collection_add_collection(Main *bma
{ {
BKE_collection_child_add(bmain, collection, child); BKE_collection_child_add(bmain, collection, child);
LISTBASE_FOREACH (CollectionChild *, collection_child, &collection->children) { CollectionChild *collection_child = find_collection_child(collection, child);
if (collection_child->collection == child) {
return &collection_child->light_linking;
}
}
if (!collection_child) {
BLI_assert_msg(0, "Collection was not found after added to the light linking collection"); BLI_assert_msg(0, "Collection was not found after added to the light linking collection");
return nullptr; return nullptr;
} }
return &collection_child->light_linking;
}
void BKE_light_linking_add_receiver_to_collection(Main *bmain, void BKE_light_linking_add_receiver_to_collection(Main *bmain,
Collection *collection, Collection *collection,
ID *receiver, ID *receiver,
@ -213,6 +234,182 @@ void BKE_light_linking_add_receiver_to_collection(Main *bmain,
DEG_relations_tag_update(bmain); DEG_relations_tag_update(bmain);
} }
static void order_collection_receiver_before(Collection *collection,
Collection *receiver,
const ID *before)
{
CollectionChild *receiver_collection_child = find_collection_child(collection, receiver);
if (!receiver_collection_child) {
BLI_assert_msg(0, "Receiver child was not found after adding collection to light linking");
return;
}
const ID_Type before_id_type = GS(before->name);
if (before_id_type != ID_GR) {
/* Adding before object: move the collection to the very bottom.
* This is as far to the bottom as the receiver can be in the flattened list of the collection.
*/
BLI_remlink(&collection->children, receiver_collection_child);
BLI_addtail(&collection->children, receiver_collection_child);
return;
}
CollectionChild *before_collection_child = find_collection_child(
collection, reinterpret_cast<const Collection *>(before));
if (!before_collection_child) {
BLI_assert_msg(0, "Before child was not found");
return;
}
BLI_remlink(&collection->children, receiver_collection_child);
BLI_insertlinkbefore(&collection->children, before_collection_child, receiver_collection_child);
}
static void order_collection_receiver_after(Collection *collection,
Collection *receiver,
const ID *after)
{
CollectionChild *receiver_collection_child = find_collection_child(collection, receiver);
if (!receiver_collection_child) {
BLI_assert_msg(0, "Receiver child was not found after adding collection to light linking");
return;
}
const ID_Type after_id_type = GS(after->name);
if (after_id_type != ID_GR) {
/* Adding before object: move the collection to the very bottom.
* This is as far to the bottom as the receiver can be in the flattened list of the collection.
*/
BLI_remlink(&collection->children, receiver_collection_child);
BLI_addtail(&collection->children, receiver_collection_child);
return;
}
CollectionChild *after_collection_child = find_collection_child(
collection, reinterpret_cast<const Collection *>(after));
if (!after_collection_child) {
BLI_assert_msg(0, "After child was not found");
return;
}
BLI_remlink(&collection->children, receiver_collection_child);
BLI_insertlinkafter(&collection->children, after_collection_child, receiver_collection_child);
}
static void order_object_receiver_before(Collection *collection,
Object *receiver,
const ID *before)
{
CollectionObject *receiver_collection_object = find_collection_object(collection, receiver);
if (!receiver_collection_object) {
BLI_assert_msg(
0, "Receiver collection object was not found after adding collection to light linking");
return;
}
const ID_Type before_id_type = GS(before->name);
if (before_id_type != ID_OB) {
/* Adding before collection: move the receiver to the very beginning of the child objects list.
* This is as close to the top of the flattened list of the collection content the object can
* possibly be. */
BLI_remlink(&collection->gobject, receiver_collection_object);
BLI_addhead(&collection->gobject, receiver_collection_object);
return;
}
CollectionObject *before_collection_object = find_collection_object(
collection, reinterpret_cast<const Object *>(before));
if (!before_collection_object) {
BLI_assert_msg(0, "Before collection object was not found");
return;
}
BLI_remlink(&collection->gobject, receiver_collection_object);
BLI_insertlinkbefore(&collection->gobject, before_collection_object, receiver_collection_object);
}
static void order_object_receiver_after(Collection *collection, Object *receiver, const ID *after)
{
CollectionObject *receiver_collection_object = find_collection_object(collection, receiver);
if (!receiver_collection_object) {
BLI_assert_msg(
0, "Receiver collection object was not found after adding collection to light linking");
return;
}
const ID_Type after_id_type = GS(after->name);
if (after_id_type != ID_OB) {
/* Adding after collection: move the receiver to the very beginning of the child objects list.
* This is as close to the top of the flattened list of the collection content the object can
* possibly be. */
BLI_remlink(&collection->gobject, receiver_collection_object);
BLI_addhead(&collection->gobject, receiver_collection_object);
return;
}
CollectionObject *after_collection_object = find_collection_object(
collection, reinterpret_cast<const Object *>(after));
if (!after_collection_object) {
BLI_assert_msg(0, "After collection object was not found");
return;
}
BLI_remlink(&collection->gobject, receiver_collection_object);
BLI_insertlinkafter(&collection->gobject, after_collection_object, receiver_collection_object);
}
void BKE_light_linking_add_receiver_to_collection_before(
Main *bmain,
Collection *collection,
ID *receiver,
const ID *before,
const eCollectionLightLinkingState link_state)
{
BLI_assert(before);
BKE_light_linking_add_receiver_to_collection(bmain, collection, receiver, link_state);
if (!before) {
return;
}
const ID_Type id_type = GS(receiver->name);
if (id_type == ID_OB) {
order_object_receiver_before(collection, reinterpret_cast<Object *>(receiver), before);
}
else if (id_type == ID_GR) {
order_collection_receiver_before(collection, reinterpret_cast<Collection *>(receiver), before);
}
}
void BKE_light_linking_add_receiver_to_collection_after(
Main *bmain,
Collection *collection,
ID *receiver,
const ID *after,
const eCollectionLightLinkingState link_state)
{
BLI_assert(after);
BKE_light_linking_add_receiver_to_collection(bmain, collection, receiver, link_state);
if (!after) {
return;
}
const ID_Type id_type = GS(receiver->name);
if (id_type == ID_OB) {
order_object_receiver_after(collection, reinterpret_cast<Object *>(receiver), after);
}
else if (id_type == ID_GR) {
order_collection_receiver_after(collection, reinterpret_cast<Collection *>(receiver), after);
}
}
bool BKE_light_linking_unlink_id_from_collection(Main *bmain, bool BKE_light_linking_unlink_id_from_collection(Main *bmain,
Collection *collection, Collection *collection,
ID *id, ID *id,

View File

@ -1830,7 +1830,7 @@ void BKE_mask_layer_shape_changed_add(MaskLayer *masklay,
const int pi_next = (spline_point_index + 1) % spline->tot_point; const int pi_next = (spline_point_index + 1) % spline->tot_point;
const int index_offset = index - spline_point_index; const int index_offset = index - spline_point_index;
/* const int pi_curr_abs = index; */ // const int pi_curr_abs = index;
const int pi_prev_abs = pi_prev + index_offset; const int pi_prev_abs = pi_prev + index_offset;
const int pi_next_abs = pi_next + index_offset; const int pi_next_abs = pi_next + index_offset;

View File

@ -517,16 +517,16 @@ static float (
point_curr = point_prev + 1; point_curr = point_prev + 1;
while (a--) { while (a--) {
/* BezTriple *bezt_prev; */ /* UNUSED */ // BezTriple *bezt_prev; /* UNUSED */
/* BezTriple *bezt_curr; */ /* UNUSED */ // BezTriple *bezt_curr; /* UNUSED */
int j; int j;
if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC)) { if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC)) {
point_curr = points_array; point_curr = points_array;
} }
/* bezt_prev = &point_prev->bezt; */ // bezt_prev = &point_prev->bezt;
/* bezt_curr = &point_curr->bezt; */ // bezt_curr = &point_curr->bezt;
for (j = 0; j < resol; j++, fp++) { for (j = 0; j < resol; j++, fp++) {
float u = float(j) / resol, weight; float u = float(j) / resol, weight;

View File

@ -279,11 +279,11 @@ static void maskrasterize_spline_differentiate_point_outset(float (*diff_feather
for (k = 0; k < tot_diff_point; k++) { for (k = 0; k < tot_diff_point; k++) {
/* co_prev = diff_points[k_prev]; */ /* precalc */ // co_prev = diff_points[k_prev]; /* Precalculate. */
co_curr = diff_points[k_curr]; co_curr = diff_points[k_curr];
co_next = diff_points[k_next]; co_next = diff_points[k_next];
// sub_v2_v2v2(d_prev, co_prev, co_curr); /* precalc */ // sub_v2_v2v2(d_prev, co_prev, co_curr); /* Precalculate. */
sub_v2_v2v2(d_next, co_curr, co_next); sub_v2_v2v2(d_next, co_curr, co_next);
// normalize_v2(d_prev); /* precalc */ // normalize_v2(d_prev); /* precalc */
@ -303,7 +303,7 @@ static void maskrasterize_spline_differentiate_point_outset(float (*diff_feather
/* use next iter */ /* use next iter */
copy_v2_v2(d_prev, d_next); copy_v2_v2(d_prev, d_next);
/* k_prev = k_curr; */ /* precalc */ // k_prev = k_curr; /* Precalculate. */
k_curr = k_next; k_curr = k_next;
k_next++; k_next++;
} }

View File

@ -508,6 +508,9 @@ static void determine_group_input_states(
if (!is_field_socket_type(type)) { if (!is_field_socket_type(type)) {
new_inferencing_interface.inputs[index] = InputSocketFieldType::None; new_inferencing_interface.inputs[index] = InputSocketFieldType::None;
} }
else if (group_input->flag & NODE_INTERFACE_SOCKET_SINGLE_VALUE_ONLY) {
new_inferencing_interface.inputs[index] = InputSocketFieldType::None;
}
} }
} }
/* Check if group inputs are required to be single values, because they are (indirectly) /* Check if group inputs are required to be single values, because they are (indirectly)

View File

@ -308,7 +308,7 @@ int BKE_packedfile_write_to_file(ReportList *reports,
bool remove_tmp = false; bool remove_tmp = false;
char filepath[FILE_MAX]; char filepath[FILE_MAX];
char filepath_temp[FILE_MAX]; char filepath_temp[FILE_MAX];
/* void *data; */ // void *data;
STRNCPY(filepath, filepath_rel); STRNCPY(filepath, filepath_rel);
BLI_path_abs(filepath, ref_file_name); BLI_path_abs(filepath, ref_file_name);

View File

@ -741,7 +741,7 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i
maxw = BLI_kdtree_3d_find_nearest_n(ctx->tree, orco1, ptn, 3); maxw = BLI_kdtree_3d_find_nearest_n(ctx->tree, orco1, ptn, 3);
maxd = ptn[maxw - 1].dist; maxd = ptn[maxw - 1].dist;
/* mind=ptn[0].dist; */ /* UNUSED */ // mind=ptn[0].dist; /* UNUSED */
/* the weights here could be done better */ /* the weights here could be done better */
for (w = 0; w < maxw; w++) { for (w = 0; w < maxw; w++) {

View File

@ -1189,7 +1189,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
v_tri[0] = v_new; v_tri[0] = v_new;
v_tri[1] = v2; v_tri[1] = v2;
/* v_tri[2] = v_opp; */ /* unchanged */ // v_tri[2] = v_opp; /* Unchanged. */
e_tri[0] = BM_edge_create(pbvh->header.bm, v_tri[0], v_tri[1], nullptr, BM_CREATE_NO_DOUBLE); e_tri[0] = BM_edge_create(pbvh->header.bm, v_tri[0], v_tri[1], nullptr, BM_CREATE_NO_DOUBLE);
e_tri[2] = e_tri[1]; /* switched */ e_tri[2] = e_tri[1]; /* switched */
e_tri[1] = BM_edge_create(pbvh->header.bm, v_tri[1], v_tri[2], nullptr, BM_CREATE_NO_DOUBLE); e_tri[1] = BM_edge_create(pbvh->header.bm, v_tri[1], v_tri[2], nullptr, BM_CREATE_NO_DOUBLE);

View File

@ -2780,7 +2780,7 @@ bool BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
void BKE_ptcache_id_time( void BKE_ptcache_id_time(
PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale) PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
{ {
/* Object *ob; */ /* UNUSED */ // Object *ob; /* UNUSED */
PointCache *cache; PointCache *cache;
/* float offset; unused for now */ /* float offset; unused for now */
float time, nexttime; float time, nexttime;

View File

@ -1831,7 +1831,7 @@ static int sb_deflect_face(Object *ob,
return deflected; return deflected;
} }
/* hiding this for now .. but the jacobian may pop up on other tasks .. so i'd like to keep it */ /* Hiding this for now, but the jacobian may pop up on other tasks - so I'd like to keep it. */
#if 0 #if 0
static void dfdx_spring(int ia, int ic, int op, float dir[3], float L, float len, float factor) static void dfdx_spring(int ia, int ic, int op, float dir[3], float L, float len, float factor)
{ {
@ -2752,7 +2752,7 @@ static void mesh_to_softbody(Object *ob)
add_mesh_quad_diag_springs(ob); add_mesh_quad_diag_springs(ob);
} }
build_bps_springlist(ob); /* scan for springs attached to bodypoints ONCE */ build_bps_springlist(ob); /* Scan for springs attached to body-points *once*. */
/* insert *other second order* springs if desired */ /* insert *other second order* springs if desired */
if (sb->secondspring > 0.0000001f) { if (sb->secondspring > 0.0000001f) {
/* Exploits the first run of `build_bps_springlist(ob)`. */ /* Exploits the first run of `build_bps_springlist(ob)`. */

View File

@ -259,7 +259,7 @@ bSound *BKE_sound_new_file(Main *bmain, const char *filepath)
sound = static_cast<bSound *>(BKE_libblock_alloc(bmain, ID_SO, BLI_path_basename(filepath), 0)); sound = static_cast<bSound *>(BKE_libblock_alloc(bmain, ID_SO, BLI_path_basename(filepath), 0));
STRNCPY(sound->filepath, filepath); STRNCPY(sound->filepath, filepath);
/* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */ // sound->type = SOUND_TYPE_FILE; /* UNUSED. */
/* Extract sound specs for bSound */ /* Extract sound specs for bSound */
SoundInfo info; SoundInfo info;

View File

@ -990,7 +990,7 @@ static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, int *r_face_offsets)
int index; int index;
int totface; int totface;
int gridSize = ccgSubSurf_getGridSize(ss); int gridSize = ccgSubSurf_getGridSize(ss);
/* int edgeSize = ccgSubSurf_getEdgeSize(ss); */ /* UNUSED */ // int edgeSize = ccgSubSurf_getEdgeSize(ss); /* UNUSED. */
int i = 0, k = 0; int i = 0, k = 0;
totface = ccgSubSurf_getNumFaces(ss); totface = ccgSubSurf_getNumFaces(ss);

View File

@ -408,7 +408,7 @@ static void text_from_buf(Text *text, const uchar *buffer, const int len)
cleanup_textline(tmp); cleanup_textline(tmp);
BLI_addtail(&text->lines, tmp); BLI_addtail(&text->lines, tmp);
/* lines_count += 1; */ /* UNUSED */ // lines_count += 1; /* UNUSED. */
} }
text->curl = text->sell = static_cast<TextLine *>(text->lines.first); text->curl = text->sell = static_cast<TextLine *>(text->lines.first);
@ -2221,7 +2221,7 @@ int txt_setcurr_tab_spaces(Text *text, int space)
} }
while (text->curl->line[i] == indent) { while (text->curl->line[i] == indent) {
/* We only count those tabs/spaces that are before any text or before the curs; */ /* We only count those tabs/spaces that are before any text or before the `curs`. */
if (i == text->curc) { if (i == text->curc) {
return i; return i;
} }

View File

@ -354,11 +354,11 @@ VChar *BKE_vfontdata_char_from_freetypefont(VFont *vfont, ulong character)
return nullptr; return nullptr;
} }
/* Init Freetype */ /* Initialize Freetype. */
FT_Library library = nullptr; FT_Library library = nullptr;
FT_Error err = FT_Init_FreeType(&library); FT_Error err = FT_Init_FreeType(&library);
if (err) { if (err) {
/* XXX error("Failed to load the Freetype font library"); */ // error("Failed to load the Freetype font library");
return nullptr; return nullptr;
} }

View File

@ -317,15 +317,15 @@ template<typename T>
QuaternionBase<T> R = q * V * conjugate(q); QuaternionBase<T> R = q * V * conjugate(q);
return {R.x, R.y, R.z}; return {R.x, R.y, R.z};
#else #else
/* `S = q * V` */ /* `S = q * V`. */
QuaternionBase<T> S; QuaternionBase<T> S;
S.w = /* q.w * 0.0 */ -q.x * v.x - q.y * v.y - q.z * v.z; S.w = /* q.w * 0.0 */ -q.x * v.x - q.y * v.y - q.z * v.z;
S.x = q.w * v.x /* + q.x * 0.0 */ + q.y * v.z - q.z * v.y; S.x = q.w * v.x /* + q.x * 0.0 */ + q.y * v.z - q.z * v.y;
S.y = q.w * v.y /* + q.y * 0.0 */ + q.z * v.x - q.x * v.z; S.y = q.w * v.y /* + q.y * 0.0 */ + q.z * v.x - q.x * v.z;
S.z = q.w * v.z /* + q.z * 0.0 */ + q.x * v.y - q.y * v.x; S.z = q.w * v.z /* + q.z * 0.0 */ + q.x * v.y - q.y * v.x;
/* `R = S * conjugate(q)` */ /* `R = S * conjugate(q)`. */
VecBase<T, 3> R; VecBase<T, 3> R;
/* R.w = S.w * q.w + S.x * q.x + S.y * q.y + S.z * q.z = 0.0; */ /* `R.w = S.w * q.w + S.x * q.x + S.y * q.y + S.z * q.z = 0.0`. */
R.x = S.w * -q.x + S.x * q.w - S.y * q.z + S.z * q.y; R.x = S.w * -q.x + S.x * q.w - S.y * q.z + S.z * q.y;
R.y = S.w * -q.y + S.y * q.w - S.z * q.x + S.x * q.z; R.y = S.w * -q.y + S.y * q.w - S.z * q.x + S.x * q.z;
R.z = S.w * -q.z + S.z * q.w - S.x * q.y + S.y * q.x; R.z = S.w * -q.z + S.z * q.w - S.x * q.y + S.y * q.x;

View File

@ -68,7 +68,7 @@ void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t
ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key)
ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT;
/* void BLI_smallhash_print(SmallHash *sh); */ /* UNUSED */ // void BLI_smallhash_print(SmallHash *sh); /* UNUSED. */
#ifdef DEBUG #ifdef DEBUG
/** /**

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include "BLI_linear_allocator.hh" #include "BLI_linear_allocator.hh"
#include "BLI_map.hh"
#include "BLI_span.hh" #include "BLI_span.hh"
#include "BLI_string_ref.hh" #include "BLI_string_ref.hh"
#include "BLI_vector.hh" #include "BLI_vector.hh"
@ -12,10 +13,23 @@
namespace blender::string_search { namespace blender::string_search {
struct SearchItem { struct SearchItem {
void *user_data;
Span<blender::StringRef> normalized_words; Span<blender::StringRef> normalized_words;
int length; int length;
void *user_data;
int weight; int weight;
/**
* This is a logical time stamp, i.e. the greater it is, the more recent the item was used. The
* number is not based on an actual clock.
*/
int recent_time;
};
struct RecentCache {
/**
* Stores a logical time stamp for each previously choosen search item. The higher the time
* stamp, the more recently the item has been selected.
*/
Map<std::string, int> logical_time_by_str;
}; };
/** /**
@ -25,6 +39,7 @@ class StringSearchBase {
protected: protected:
LinearAllocator<> allocator_; LinearAllocator<> allocator_;
Vector<SearchItem> items_; Vector<SearchItem> items_;
const RecentCache *recent_cache_ = nullptr;
protected: protected:
void add_impl(StringRef str, void *user_data, int weight); void add_impl(StringRef str, void *user_data, int weight);
@ -43,6 +58,11 @@ class StringSearchBase {
*/ */
template<typename T> class StringSearch : private StringSearchBase { template<typename T> class StringSearch : private StringSearchBase {
public: public:
StringSearch(const RecentCache *recent_cache = nullptr)
{
this->recent_cache_ = recent_cache;
}
/** /**
* Add a new possible result to the search. * Add a new possible result to the search.
* *

View File

@ -327,9 +327,9 @@ bool _bli_array_iter_spiral_square(const void *arr_v,
bool check_bounds = steps > steps_in; bool check_bounds = steps > steps_in;
/* sign: 0 neg; 1 pos; */ /* Sign: 0=negative 1=positive. */
for (int sign = 2; sign--;) { for (int sign = 2; sign--;) {
/* axis: 0 x; 1 y; */ /* Axis: 0=x; 1=y. */
for (int axis = 2; axis--;) { for (int axis = 2; axis--;) {
int ofs_step = stride[axis]; int ofs_step = stride[axis];
if (!sign) { if (!sign) {

View File

@ -5251,9 +5251,9 @@ void vcloud_estimate_transform_v3(const int list_size,
/* build 'projection' matrix */ /* build 'projection' matrix */
for (a = 0; a < list_size; a++) { for (a = 0; a < list_size; a++) {
sub_v3_v3v3(va, rpos[a], accu_rcom); sub_v3_v3v3(va, rpos[a], accu_rcom);
/* mul_v3_fl(va, bp->mass); mass needs re-normalization here ?? */ // mul_v3_fl(va, bp->mass); /* Mass needs re-normalization here? */
sub_v3_v3v3(vb, pos[a], accu_com); sub_v3_v3v3(vb, pos[a], accu_com);
/* mul_v3_fl(va, rp->mass); */ // mul_v3_fl(va, rp->mass);
m[0][0] += va[0] * vb[0]; m[0][0] += va[0] * vb[0];
m[0][1] += va[0] * vb[1]; m[0][1] += va[0] * vb[1];
m[0][2] += va[0] * vb[2]; m[0][2] += va[0] * vb[2];

View File

@ -513,7 +513,11 @@ static uint scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
sc->vert = eve; sc->vert = eve;
sc->edge_first = sc->edge_last = NULL; sc->edge_first = sc->edge_last = NULL;
/* NOTE: debug print only will work for curve poly-fill, union is in use for mesh. */ /* NOTE: debug print only will work for curve poly-fill, union is in use for mesh. */
/* if (even->tmp.v == NULL) eve->tmp.u = verts; */ #if 0
if (even->tmp.v == NULL) {
eve->tmp.u = verts;
}
#endif
sc++; sc++;
} }
} }
@ -613,9 +617,13 @@ static uint scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
ed1 = sc->edge_first; ed1 = sc->edge_first;
ed2 = ed1->next; ed2 = ed1->next;
/* commented out... the ESC here delivers corrupted memory /* Commented out: the ESC here delivers corrupted memory
* (and doesn't work during grab). */ * (and doesn't work during grab). */
/* if (callLocalInterruptCallBack()) break; */ #if 0
if (callLocalInterruptCallBack()){
break;
}
#endif
if (totface >= maxface) { if (totface >= maxface) {
// printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); // printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts);
a = verts; a = verts;
@ -1094,8 +1102,11 @@ uint BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float n
*pc = c; *pc = c;
pc++; pc++;
} }
/* only for optimize! */ #if 0
/* else if (pf->max_xy[0] < (pflist+c)->min[cox]) break; */ else if (pf->max_xy[0] < (pflist + c)->min[cox]) { /* Only for optimize! */
break;
}
#endif
} }
while (pc != polycache) { while (pc != polycache) {
pc--; pc--;

View File

@ -398,8 +398,14 @@ void StringSearchBase::add_impl(const StringRef str, void *user_data, const int
{ {
Vector<StringRef, 64> words; Vector<StringRef, 64> words;
string_search::extract_normalized_words(str, allocator_, words); string_search::extract_normalized_words(str, allocator_, words);
items_.append( const int recent_time = recent_cache_ ?
{allocator_.construct_array_copy(words.as_span()), int(str.size()), user_data, weight}); recent_cache_->logical_time_by_str.lookup_default(str, -1) :
-1;
items_.append({user_data,
allocator_.construct_array_copy(words.as_span()),
int(str.size()),
weight,
recent_time});
} }
Vector<void *> StringSearchBase::query_impl(const StringRef query) const Vector<void *> StringSearchBase::query_impl(const StringRef query) const
@ -429,10 +435,11 @@ Vector<void *> StringSearchBase::query_impl(const StringRef query) const
Vector<int> sorted_result_indices; Vector<int> sorted_result_indices;
for (const int score : found_scores) { for (const int score : found_scores) {
MutableSpan<int> indices = result_indices_by_score.lookup(score); MutableSpan<int> indices = result_indices_by_score.lookup(score);
if (score == found_scores[0] && !query.is_empty()) { if (score == found_scores[0]) {
if (!query.is_empty()) {
/* Sort items with best score by length. Shorter items are more likely the ones you are /* Sort items with best score by length. Shorter items are more likely the ones you are
* looking for. This also ensures that exact matches will be at the top, even if the query is * looking for. This also ensures that exact matches will be at the top, even if the query
* a sub-string of another item. */ * is a sub-string of another item. */
std::sort(indices.begin(), indices.end(), [&](int a, int b) { std::sort(indices.begin(), indices.end(), [&](int a, int b) {
return items_[a].length < items_[b].length; return items_[a].length < items_[b].length;
}); });
@ -442,6 +449,11 @@ Vector<void *> StringSearchBase::query_impl(const StringRef query) const
return items_[a].weight > items_[b].weight; return items_[a].weight > items_[b].weight;
}); });
} }
/* Prefer items that have been selected recently. */
std::stable_sort(indices.begin(), indices.end(), [&](int a, int b) {
return items_[a].recent_time > items_[b].recent_time;
});
}
sorted_result_indices.extend(indices); sorted_result_indices.extend(indices);
} }

View File

@ -158,7 +158,7 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
BHead *bhead; BHead *bhead;
int tot = 0; int tot = 0;
const int sdna_nr_preview_image = DNA_struct_find(fd->filesdna, "PreviewImage"); const int sdna_nr_preview_image = DNA_struct_find_with_alias(fd->filesdna, "PreviewImage");
for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) { for (bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == BLO_CODE_ENDB) { if (bhead->code == BLO_CODE_ENDB) {
@ -261,7 +261,7 @@ PreviewImage *BLO_blendhandle_get_preview_for_id(BlendHandle *bh,
{ {
FileData *fd = (FileData *)bh; FileData *fd = (FileData *)bh;
bool looking = false; bool looking = false;
const int sdna_preview_image = DNA_struct_find(fd->filesdna, "PreviewImage"); const int sdna_preview_image = DNA_struct_find_with_alias(fd->filesdna, "PreviewImage");
for (BHead *bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) { for (BHead *bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
if (bhead->code == BLO_CODE_DATA) { if (bhead->code == BLO_CODE_DATA) {
@ -331,7 +331,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_
} }
else if (bhead->code == BLO_CODE_DATA) { else if (bhead->code == BLO_CODE_DATA) {
if (looking) { if (looking) {
if (bhead->SDNAnr == DNA_struct_find(fd->filesdna, "PreviewImage")) { if (bhead->SDNAnr == DNA_struct_find_with_alias(fd->filesdna, "PreviewImage")) {
prv = static_cast<PreviewImage *>(BLO_library_read_struct(fd, bhead, "PreviewImage")); prv = static_cast<PreviewImage *>(BLO_library_read_struct(fd, bhead, "PreviewImage"));
if (prv) { if (prv) {

View File

@ -986,19 +986,22 @@ static bool read_file_dna(FileData *fd, const char **r_error_message)
} }
else if (bhead->code == BLO_CODE_DNA1) { else if (bhead->code == BLO_CODE_DNA1) {
const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0; const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
const bool do_alias = false; /* Postpone until after #blo_do_versions_dna runs. */
fd->filesdna = DNA_sdna_from_data( fd->filesdna = DNA_sdna_from_data(
&bhead[1], bhead->len, do_endian_swap, true, r_error_message); &bhead[1], bhead->len, do_endian_swap, true, do_alias, r_error_message);
if (fd->filesdna) { if (fd->filesdna) {
blo_do_versions_dna(fd->filesdna, fd->fileversion, subversion); blo_do_versions_dna(fd->filesdna, fd->fileversion, subversion);
/* Allow aliased lookups (must be after version patching DNA). */
DNA_sdna_alias_data_ensure_structs_map(fd->filesdna);
fd->compflags = DNA_struct_get_compareflags(fd->filesdna, fd->memsdna); fd->compflags = DNA_struct_get_compareflags(fd->filesdna, fd->memsdna);
fd->reconstruct_info = DNA_reconstruct_info_create( fd->reconstruct_info = DNA_reconstruct_info_create(
fd->filesdna, fd->memsdna, fd->compflags); fd->filesdna, fd->memsdna, fd->compflags);
/* used to retrieve ID names from (bhead+1) */ /* used to retrieve ID names from (bhead+1) */
fd->id_name_offset = DNA_struct_member_offset_by_name( fd->id_name_offset = DNA_struct_member_offset_by_name_with_alias(
fd->filesdna, "ID", "char", "name[]"); fd->filesdna, "ID", "char", "name[]");
BLI_assert(fd->id_name_offset != -1); BLI_assert(fd->id_name_offset != -1);
fd->id_asset_data_offset = DNA_struct_member_offset_by_name( fd->id_asset_data_offset = DNA_struct_member_offset_by_name_with_alias(
fd->filesdna, "ID", "AssetMetaData", "*asset_data"); fd->filesdna, "ID", "AssetMetaData", "*asset_data");
return true; return true;
@ -2267,7 +2270,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
lib->filepath_abs); lib->filepath_abs);
change_link_placeholder_to_real_ID_pointer(fd->mainlist, fd, lib, newmain->curlib); change_link_placeholder_to_real_ID_pointer(fd->mainlist, fd, lib, newmain->curlib);
/* change_link_placeholder_to_real_ID_pointer_fd(fd, lib, newmain->curlib); */ // change_link_placeholder_to_real_ID_pointer_fd(fd, lib, newmain->curlib);
BLI_remlink(&main->libraries, lib); BLI_remlink(&main->libraries, lib);
MEM_freeN(lib); MEM_freeN(lib);

View File

@ -12,6 +12,9 @@
/* allow readfile to use deprecated functionality */ /* allow readfile to use deprecated functionality */
#define DNA_DEPRECATED_ALLOW #define DNA_DEPRECATED_ALLOW
/* Define macros in `DNA_genfile.h`. */
#define DNA_GENFILE_VERSIONING_MACROS
#include "DNA_anim_types.h" #include "DNA_anim_types.h"
#include "DNA_brush_types.h" #include "DNA_brush_types.h"
#include "DNA_camera_types.h" #include "DNA_camera_types.h"
@ -36,6 +39,8 @@
#include "DNA_view3d_types.h" #include "DNA_view3d_types.h"
#include "DNA_world_types.h" #include "DNA_world_types.h"
#undef DNA_GENFILE_VERSIONING_MACROS
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "BLI_blenlib.h" #include "BLI_blenlib.h"

View File

@ -15,6 +15,9 @@
/* allow readfile to use deprecated functionality */ /* allow readfile to use deprecated functionality */
#define DNA_DEPRECATED_ALLOW #define DNA_DEPRECATED_ALLOW
/* Define macros in `DNA_genfile.h`. */
#define DNA_GENFILE_VERSIONING_MACROS
#include "DNA_anim_types.h" #include "DNA_anim_types.h"
#include "DNA_armature_types.h" #include "DNA_armature_types.h"
#include "DNA_brush_types.h" #include "DNA_brush_types.h"
@ -41,6 +44,8 @@
#include "DNA_genfile.h" #include "DNA_genfile.h"
#undef DNA_GENFILE_VERSIONING_MACROS
#include "BKE_anim_data.h" #include "BKE_anim_data.h"
#include "BKE_animsys.h" #include "BKE_animsys.h"
#include "BKE_colortools.h" #include "BKE_colortools.h"
@ -1141,12 +1146,12 @@ void blo_do_versions_270(FileData *fd, Library * /*lib*/, Main *bmain)
} }
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 277, 2)) { if (!MAIN_VERSION_FILE_ATLEAST(bmain, 277, 2)) {
if (!DNA_struct_member_exists(fd->filesdna, "Bone", "float", "scaleIn")) { if (!DNA_struct_member_exists(fd->filesdna, "Bone", "float", "scale_in_x")) {
LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) { LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
do_version_bones_super_bbone(&arm->bonebase); do_version_bones_super_bbone(&arm->bonebase);
} }
} }
if (!DNA_struct_member_exists(fd->filesdna, "bPoseChannel", "float", "scaleIn")) { if (!DNA_struct_member_exists(fd->filesdna, "bPoseChannel", "float", "scale_in_x")) {
LISTBASE_FOREACH (Object *, ob, &bmain->objects) { LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
if (ob->pose) { if (ob->pose) {
LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
@ -1603,7 +1608,6 @@ void do_versions_after_linking_270(Main *bmain)
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 279, 2)) { if (!MAIN_VERSION_FILE_ATLEAST(bmain, 279, 2)) {
/* B-Bones (bbone_in/out -> bbone_easein/out) + Stepped FMod Frame Start/End fix */ /* B-Bones (bbone_in/out -> bbone_easein/out) + Stepped FMod Frame Start/End fix */
/* if (!DNA_struct_member_exists(fd->filesdna, "Bone", "float", "bbone_easein")) */
BKE_fcurves_main_cb(bmain, do_version_bbone_easing_fcurve_fix, nullptr); BKE_fcurves_main_cb(bmain, do_version_bbone_easing_fcurve_fix, nullptr);
} }
} }

View File

@ -18,6 +18,9 @@
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
/* Define macros in `DNA_genfile.h`. */
#define DNA_GENFILE_VERSIONING_MACROS
#include "DNA_defaults.h" #include "DNA_defaults.h"
#include "DNA_anim_types.h" #include "DNA_anim_types.h"
@ -54,6 +57,8 @@
#include "DNA_workspace_types.h" #include "DNA_workspace_types.h"
#include "DNA_world_types.h" #include "DNA_world_types.h"
#undef DNA_GENFILE_VERSIONING_MACROS
#include "BKE_animsys.h" #include "BKE_animsys.h"
#include "BKE_blender.h" #include "BKE_blender.h"
#include "BKE_brush.hh" #include "BKE_brush.hh"
@ -1065,7 +1070,7 @@ static void displacement_principled_nodes(bNode *node)
} }
} }
else if (node->type == SH_NODE_BSDF_PRINCIPLED) { else if (node->type == SH_NODE_BSDF_PRINCIPLED) {
if (node->custom2 != SHD_SUBSURFACE_RANDOM_WALK) { if (node->custom2 != SHD_SUBSURFACE_RANDOM_WALK_SKIN) {
node->custom2 = SHD_SUBSURFACE_BURLEY; node->custom2 = SHD_SUBSURFACE_BURLEY;
} }
} }
@ -3023,7 +3028,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
} }
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 2)) { if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 2)) {
if (!DNA_struct_member_exists(fd->filesdna, "Lamp", "float", "cascade_max_dist")) { if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "cascade_max_dist")) {
LISTBASE_FOREACH (Light *, la, &bmain->lights) { LISTBASE_FOREACH (Light *, la, &bmain->lights) {
la->cascade_max_dist = 1000.0f; la->cascade_max_dist = 1000.0f;
la->cascade_count = 4; la->cascade_count = 4;
@ -3032,7 +3037,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
} }
} }
if (!DNA_struct_member_exists(fd->filesdna, "Lamp", "float", "contact_dist")) { if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "contact_dist")) {
LISTBASE_FOREACH (Light *, la, &bmain->lights) { LISTBASE_FOREACH (Light *, la, &bmain->lights) {
la->contact_dist = 0.2f; la->contact_dist = 0.2f;
la->contact_bias = 0.03f; la->contact_bias = 0.03f;
@ -3348,7 +3353,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 13)) { if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 13)) {
/* Initialize specular factor. */ /* Initialize specular factor. */
if (!DNA_struct_member_exists(fd->filesdna, "Lamp", "float", "spec_fac")) { if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "spec_fac")) {
LISTBASE_FOREACH (Light *, la, &bmain->lights) { LISTBASE_FOREACH (Light *, la, &bmain->lights) {
la->spec_fac = 1.0f; la->spec_fac = 1.0f;
} }
@ -4322,7 +4327,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
} }
} }
if (!DNA_struct_member_exists(fd->filesdna, "Lamp", "float", "att_dist")) { if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "att_dist")) {
LISTBASE_FOREACH (Light *, la, &bmain->lights) { LISTBASE_FOREACH (Light *, la, &bmain->lights) {
la->att_dist = la->clipend; la->att_dist = la->clipend;
} }
@ -5036,23 +5041,23 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
} }
/* init grease pencil brush gradients */ /* init grease pencil brush gradients */
if (!DNA_struct_member_exists(fd->filesdna, "BrushGpencilSettings", "float", "hardeness")) { if (!DNA_struct_member_exists(fd->filesdna, "BrushGpencilSettings", "float", "hardness")) {
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) { LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
if (brush->gpencil_settings != nullptr) { if (brush->gpencil_settings != nullptr) {
BrushGpencilSettings *gp = brush->gpencil_settings; BrushGpencilSettings *gp = brush->gpencil_settings;
gp->hardeness = 1.0f; gp->hardness = 1.0f;
copy_v2_fl(gp->aspect_ratio, 1.0f); copy_v2_fl(gp->aspect_ratio, 1.0f);
} }
} }
} }
/* init grease pencil stroke gradients */ /* init grease pencil stroke gradients */
if (!DNA_struct_member_exists(fd->filesdna, "bGPDstroke", "float", "hardeness")) { if (!DNA_struct_member_exists(fd->filesdna, "bGPDstroke", "float", "hardness")) {
LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) { LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
gps->hardeness = 1.0f; gps->hardness = 1.0f;
copy_v2_fl(gps->aspect_ratio, 1.0f); copy_v2_fl(gps->aspect_ratio, 1.0f);
} }
} }
@ -5143,7 +5148,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
} }
/* Split bbone_scalein/bbone_scaleout into x and y fields. */ /* Split bbone_scalein/bbone_scaleout into x and y fields. */
if (!DNA_struct_member_exists(fd->filesdna, "bPoseChannel", "float", "scale_out_y")) { if (!DNA_struct_member_exists(fd->filesdna, "bPoseChannel", "float", "scale_out_z")) {
/* Update armature data and pose channels. */ /* Update armature data and pose channels. */
LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) { LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) {
do_version_bones_split_bbone_scale(&arm->bonebase); do_version_bones_split_bbone_scale(&arm->bonebase);
@ -5248,7 +5253,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
} }
/* Initializes sun lights with the new angular diameter property */ /* Initializes sun lights with the new angular diameter property */
if (!DNA_struct_member_exists(fd->filesdna, "Lamp", "float", "sun_angle")) { if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "sun_angle")) {
LISTBASE_FOREACH (Light *, light, &bmain->lights) { LISTBASE_FOREACH (Light *, light, &bmain->lights) {
light->sun_angle = 2.0f * atanf(light->area_size); light->sun_angle = 2.0f * atanf(light->area_size);
} }

View File

@ -14,6 +14,9 @@
#include "BLI_string.h" #include "BLI_string.h"
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
/* Define macros in `DNA_genfile.h`. */
#define DNA_GENFILE_VERSIONING_MACROS
#include "DNA_anim_types.h" #include "DNA_anim_types.h"
#include "DNA_armature_types.h" #include "DNA_armature_types.h"
#include "DNA_brush_types.h" #include "DNA_brush_types.h"
@ -40,6 +43,8 @@
#include "DNA_tracking_types.h" #include "DNA_tracking_types.h"
#include "DNA_workspace_types.h" #include "DNA_workspace_types.h"
#undef DNA_GENFILE_VERSIONING_MACROS
#include "BKE_animsys.h" #include "BKE_animsys.h"
#include "BKE_armature.h" #include "BKE_armature.h"
#include "BKE_attribute.h" #include "BKE_attribute.h"
@ -1858,7 +1863,7 @@ void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain)
} }
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 14)) { if (!MAIN_VERSION_FILE_ATLEAST(bmain, 293, 14)) {
if (!DNA_struct_member_exists(fd->filesdna, "Lamp", "float", "diff_fac")) { if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "diff_fac")) {
LISTBASE_FOREACH (Light *, light, &bmain->lights) { LISTBASE_FOREACH (Light *, light, &bmain->lights) {
light->diff_fac = 1.0f; light->diff_fac = 1.0f;
light->volume_fac = 1.0f; light->volume_fac = 1.0f;
@ -1916,7 +1921,7 @@ void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain)
} }
/* Initialize the spread parameter for area lights. */ /* Initialize the spread parameter for area lights. */
if (!DNA_struct_member_exists(fd->filesdna, "Lamp", "float", "area_spread")) { if (!DNA_struct_member_exists(fd->filesdna, "Light", "float", "area_spread")) {
LISTBASE_FOREACH (Light *, la, &bmain->lights) { LISTBASE_FOREACH (Light *, la, &bmain->lights) {
la->area_spread = DEG2RADF(180.0f); la->area_spread = DEG2RADF(180.0f);
} }

View File

@ -24,6 +24,9 @@
#include "BLI_string_utils.h" #include "BLI_string_utils.h"
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
/* Define macros in `DNA_genfile.h`. */
#define DNA_GENFILE_VERSIONING_MACROS
#include "DNA_anim_types.h" #include "DNA_anim_types.h"
#include "DNA_armature_types.h" #include "DNA_armature_types.h"
#include "DNA_brush_types.h" #include "DNA_brush_types.h"
@ -47,6 +50,8 @@
#include "DNA_tracking_types.h" #include "DNA_tracking_types.h"
#include "DNA_workspace_types.h" #include "DNA_workspace_types.h"
#undef DNA_GENFILE_VERSIONING_MACROS
#include "BKE_action.h" #include "BKE_action.h"
#include "BKE_anim_data.h" #include "BKE_anim_data.h"
#include "BKE_animsys.h" #include "BKE_animsys.h"
@ -1543,13 +1548,13 @@ static bool seq_meta_channels_ensure(Sequence *seq, void * /*user_data*/)
static void do_version_subsurface_methods(bNode *node) static void do_version_subsurface_methods(bNode *node)
{ {
if (node->type == SH_NODE_SUBSURFACE_SCATTERING) { if (node->type == SH_NODE_SUBSURFACE_SCATTERING) {
if (!ELEM(node->custom1, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) { if (!ELEM(node->custom1, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK_SKIN)) {
node->custom1 = SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS; node->custom1 = SHD_SUBSURFACE_RANDOM_WALK;
} }
} }
else if (node->type == SH_NODE_BSDF_PRINCIPLED) { else if (node->type == SH_NODE_BSDF_PRINCIPLED) {
if (!ELEM(node->custom2, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) { if (!ELEM(node->custom2, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK_SKIN)) {
node->custom2 = SHD_SUBSURFACE_RANDOM_WALK_FIXED_RADIUS; node->custom2 = SHD_SUBSURFACE_RANDOM_WALK;
} }
} }
} }
@ -2632,7 +2637,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 300, 13)) { if (!MAIN_VERSION_FILE_ATLEAST(bmain, 300, 13)) {
/* Convert Surface Deform to sparse-capable bind structure. */ /* Convert Surface Deform to sparse-capable bind structure. */
if (!DNA_struct_member_exists( if (!DNA_struct_member_exists(
fd->filesdna, "SurfaceDeformModifierData", "int", "num_mesh_verts")) { fd->filesdna, "SurfaceDeformModifierData", "int", "mesh_verts_num")) {
LISTBASE_FOREACH (Object *, ob, &bmain->objects) { LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type == eModifierType_SurfaceDeform) { if (md->type == eModifierType_SurfaceDeform) {

View File

@ -12,6 +12,9 @@
#include "CLG_log.h" #include "CLG_log.h"
/* Define macros in `DNA_genfile.h`. */
#define DNA_GENFILE_VERSIONING_MACROS
#include "DNA_brush_types.h" #include "DNA_brush_types.h"
#include "DNA_camera_types.h" #include "DNA_camera_types.h"
#include "DNA_light_types.h" #include "DNA_light_types.h"
@ -25,6 +28,8 @@
#include "DNA_genfile.h" #include "DNA_genfile.h"
#include "DNA_particle_types.h" #include "DNA_particle_types.h"
#undef DNA_GENFILE_VERSIONING_MACROS
#include "BLI_assert.h" #include "BLI_assert.h"
#include "BLI_listbase.h" #include "BLI_listbase.h"
#include "BLI_map.hh" #include "BLI_map.hh"
@ -687,6 +692,19 @@ static void version_principled_bsdf_emission(bNodeTree *ntree)
} }
} }
/* Rename various Principled BSDF sockets. */
static void version_principled_bsdf_rename_sockets(bNodeTree *ntree)
{
version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Emission", "Emission Color");
version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Specular", "Specular IOR Level");
version_node_input_socket_name(
ntree, SH_NODE_BSDF_PRINCIPLED, "Subsurface", "Subsurface Weight");
version_node_input_socket_name(
ntree, SH_NODE_BSDF_PRINCIPLED, "Transmission", "Transmission Weight");
version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Coat", "Coat Weight");
version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Sheen", "Sheen Weight");
}
/* Replace old Principled Hair BSDF as a variant in the new Principled Hair BSDF. */ /* Replace old Principled Hair BSDF as a variant in the new Principled Hair BSDF. */
static void version_replace_principled_hair_model(bNodeTree *ntree) static void version_replace_principled_hair_model(bNodeTree *ntree)
{ {
@ -791,6 +809,65 @@ static void version_principled_bsdf_coat(bNodeTree *ntree)
ntree, SH_NODE_BSDF_PRINCIPLED, "Clearcoat Normal", "Coat Normal"); ntree, SH_NODE_BSDF_PRINCIPLED, "Clearcoat Normal", "Coat Normal");
} }
/* Convert specular tint in Principled BSDF. */
static void version_principled_bsdf_specular_tint(bNodeTree *ntree)
{
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type != SH_NODE_BSDF_PRINCIPLED) {
continue;
}
bNodeSocket *specular_tint_sock = nodeFindSocket(node, SOCK_IN, "Specular Tint");
if (specular_tint_sock->type == SOCK_RGBA) {
/* Node is already updated. */
continue;
}
bNodeSocket *base_color_sock = nodeFindSocket(node, SOCK_IN, "Base Color");
float specular_tint_old = *version_cycles_node_socket_float_value(specular_tint_sock);
float *base_color = version_cycles_node_socket_rgba_value(base_color_sock);
/* Change socket type to Color. */
nodeModifySocketTypeStatic(ntree, node, specular_tint_sock, SOCK_RGBA, 0);
static float one[] = {1.0f, 1.0f, 1.0f, 1.0f};
/* If any of the two inputs is dynamic, we add a Mix node. */
if (base_color_sock->link || specular_tint_sock->link) {
bNode *mix = nodeAddStaticNode(nullptr, ntree, SH_NODE_MIX);
static_cast<NodeShaderMix *>(mix->storage)->data_type = SOCK_RGBA;
mix->locx = node->locx - 170;
mix->locy = node->locy - 120;
bNodeSocket *a_in = nodeFindSocket(mix, SOCK_IN, "A_Color");
bNodeSocket *b_in = nodeFindSocket(mix, SOCK_IN, "B_Color");
bNodeSocket *fac_in = nodeFindSocket(mix, SOCK_IN, "Factor_Float");
bNodeSocket *result_out = nodeFindSocket(mix, SOCK_OUT, "Result_Color");
copy_v4_v4(version_cycles_node_socket_rgba_value(a_in), one);
copy_v4_v4(version_cycles_node_socket_rgba_value(b_in), base_color);
*version_cycles_node_socket_float_value(fac_in) = specular_tint_old;
if (base_color_sock->link) {
nodeAddLink(
ntree, base_color_sock->link->fromnode, base_color_sock->link->fromsock, mix, b_in);
}
if (specular_tint_sock->link) {
nodeAddLink(ntree,
specular_tint_sock->link->fromnode,
specular_tint_sock->link->fromsock,
mix,
fac_in);
nodeRemLink(ntree, specular_tint_sock->link);
}
nodeAddLink(ntree, mix, result_out, node, specular_tint_sock);
}
float *specular_tint = version_cycles_node_socket_rgba_value(specular_tint_sock);
/* Mix the fixed values. */
interp_v4_v4v4(specular_tint, one, base_color, specular_tint_old);
}
}
static void version_copy_socket(bNodeTreeInterfaceSocket &dst, static void version_copy_socket(bNodeTreeInterfaceSocket &dst,
const bNodeTreeInterfaceSocket &src, const bNodeTreeInterfaceSocket &src,
char *identifier) char *identifier)
@ -1354,6 +1431,18 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
FOREACH_NODETREE_END; FOREACH_NODETREE_END;
} }
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 25)) {
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
/* Convert specular tint on the Principled BSDF. */
version_principled_bsdf_specular_tint(ntree);
/* Rename some sockets. */
version_principled_bsdf_rename_sockets(ntree);
}
}
FOREACH_NODETREE_END;
}
/** /**
* Versioning code until next subversion bump goes here. * Versioning code until next subversion bump goes here.
* *

View File

@ -609,7 +609,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
if (node->type == SH_NODE_BSDF_PRINCIPLED) { if (node->type == SH_NODE_BSDF_PRINCIPLED) {
bNodeSocket *roughness_socket = nodeFindSocket(node, SOCK_IN, "Roughness"); bNodeSocket *roughness_socket = nodeFindSocket(node, SOCK_IN, "Roughness");
*version_cycles_node_socket_float_value(roughness_socket) = 0.5f; *version_cycles_node_socket_float_value(roughness_socket) = 0.5f;
bNodeSocket *emission = nodeFindSocket(node, SOCK_IN, "Emission"); bNodeSocket *emission = nodeFindSocket(node, SOCK_IN, "Emission Color");
copy_v4_fl(version_cycles_node_socket_rgba_value(emission), 1.0f); copy_v4_fl(version_cycles_node_socket_rgba_value(emission), 1.0f);
bNodeSocket *emission_strength = nodeFindSocket(node, SOCK_IN, "Emission Strength"); bNodeSocket *emission_strength = nodeFindSocket(node, SOCK_IN, "Emission Strength");
*version_cycles_node_socket_float_value(emission_strength) = 0.0f; *version_cycles_node_socket_float_value(emission_strength) = 0.0f;

View File

@ -26,13 +26,15 @@ void blo_do_versions_dna(SDNA *sdna, const int versionfile, const int subversion
/* Version files created in the 'blender2.8' branch /* Version files created in the 'blender2.8' branch
* between October 2016, and November 2017 (>=280.0 and < 280.2). */ * between October 2016, and November 2017 (>=280.0 and < 280.2). */
if (versionfile >= 280) { if (versionfile >= 280) {
DNA_sdna_patch_struct(sdna, "SceneLayer", "ViewLayer"); DNA_sdna_patch_struct_by_name(sdna, "SceneLayer", "ViewLayer");
DNA_sdna_patch_struct(sdna, "SceneLayerEngineData", "ViewLayerEngineData"); DNA_sdna_patch_struct_by_name(sdna, "SceneLayerEngineData", "ViewLayerEngineData");
DNA_sdna_patch_struct_member(sdna, "FileGlobal", "cur_render_layer", "cur_view_layer"); DNA_sdna_patch_struct_member_by_name(
DNA_sdna_patch_struct_member(sdna, "ParticleEditSettings", "scene_layer", "view_layer"); sdna, "FileGlobal", "cur_render_layer", "cur_view_layer");
DNA_sdna_patch_struct_member(sdna, "Scene", "active_layer", "active_view_layer"); DNA_sdna_patch_struct_member_by_name(
DNA_sdna_patch_struct_member(sdna, "Scene", "render_layers", "view_layers"); sdna, "ParticleEditSettings", "scene_layer", "view_layer");
DNA_sdna_patch_struct_member(sdna, "WorkSpace", "render_layer", "view_layer"); DNA_sdna_patch_struct_member_by_name(sdna, "Scene", "active_layer", "active_view_layer");
DNA_sdna_patch_struct_member_by_name(sdna, "Scene", "render_layers", "view_layers");
DNA_sdna_patch_struct_member_by_name(sdna, "WorkSpace", "render_layer", "view_layer");
} }
} }

View File

@ -461,7 +461,7 @@ void blo_do_versions_userdef(UserDef *userdef)
if (!USER_VERSION_ATLEAST(278, 6)) { if (!USER_VERSION_ATLEAST(278, 6)) {
/* Clear preference flags for re-use. */ /* Clear preference flags for re-use. */
userdef->flag &= ~(USER_FLAG_NUMINPUT_ADVANCED | USER_FLAG_UNUSED_2 | USER_FLAG_UNUSED_3 | userdef->flag &= ~(USER_FLAG_NUMINPUT_ADVANCED | (1 << 2) | USER_FLAG_UNUSED_3 |
USER_FLAG_UNUSED_6 | USER_FLAG_UNUSED_7 | USER_FLAG_UNUSED_9 | USER_FLAG_UNUSED_6 | USER_FLAG_UNUSED_7 | USER_FLAG_UNUSED_9 |
USER_DEVELOPER_UI); USER_DEVELOPER_UI);
userdef->uiflag &= ~(USER_HEADER_BOTTOM); userdef->uiflag &= ~(USER_HEADER_BOTTOM);

View File

@ -745,7 +745,7 @@ static void writelist_id(WriteData *wd, int filecode, const char *structname, co
const Link *link = lb->first; const Link *link = lb->first;
if (link) { if (link) {
const int struct_nr = DNA_struct_find(wd->sdna, structname); const int struct_nr = DNA_struct_find_with_alias(wd->sdna, structname);
if (struct_nr == -1) { if (struct_nr == -1) {
printf("error: can't find SDNA code <%s>\n", structname); printf("error: can't find SDNA code <%s>\n", structname);
return; return;
@ -1745,7 +1745,7 @@ void blo_write_id_struct(BlendWriter *writer, int struct_id, const void *id_addr
int BLO_get_struct_id_by_name(BlendWriter *writer, const char *struct_name) int BLO_get_struct_id_by_name(BlendWriter *writer, const char *struct_name)
{ {
int struct_id = DNA_struct_find(writer->wd->sdna, struct_name); int struct_id = DNA_struct_find_with_alias(writer->wd->sdna, struct_name);
return struct_id; return struct_id;
} }

View File

@ -1853,7 +1853,7 @@ BMVert *bmesh_kernel_join_vert_kill_edge(BMesh *bm,
BM_CHECK_ELEMENT(v_target); BM_CHECK_ELEMENT(v_target);
if (v_target->e && v_kill->e) { if (v_target->e && v_kill->e) {
/* inline BM_vert_splice(bm, v_target, v_kill); */ /* Inline `BM_vert_splice(bm, v_target, v_kill)`. */
BMEdge *e; BMEdge *e;
while ((e = v_kill->e)) { while ((e = v_kill->e)) {
BMEdge *e_target; BMEdge *e_target;

View File

@ -251,7 +251,7 @@ static bool bm_loop_path_build_step(BLI_mempool *vs_pool,
} }
/* Commented because used in a loop, and this flag has already been set. */ /* Commented because used in a loop, and this flag has already been set. */
/* bm->elem_index_dirty |= BM_VERT; */ // bm->elem_index_dirty |= BM_VERT;
/* lb is now full of free'd items, overwrite */ /* lb is now full of free'd items, overwrite */
*lb = lb_tmp; *lb = lb_tmp;

View File

@ -37,7 +37,7 @@ ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE void *BM_iter_step(BMIter *it
ATTR_NONNULL(1) ATTR_NONNULL(1)
BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data) BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data)
{ {
/* int argtype; */ // int argtype;
iter->itype = itype; iter->itype = itype;
/* inlining optimizes out this switch when called with the defined type */ /* inlining optimizes out this switch when called with the defined type */

View File

@ -395,7 +395,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm,
e_new = bmesh_kernel_join_edge_kill_vert( e_new = bmesh_kernel_join_edge_kill_vert(
bm, e_kill, v_kill, do_del, true, kill_degenerate_faces, kill_duplicate_faces); bm, e_kill, v_kill, do_del, true, kill_degenerate_faces, kill_duplicate_faces);
/* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */ // e_new = BM_edge_exists(tv, tv2); /* Same as return above. */
} }
return e_new; return e_new;

View File

@ -264,7 +264,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op) void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
{ {
/* BMOperator fop; */ // BMOperator fop;
BMFace *act_face = bm->act_face; BMFace *act_face = bm->act_face;
BMOIter eiter; BMOIter eiter;
BMIter iter; BMIter iter;

Some files were not shown because too many files have changed in this diff Show More