diff --git a/intern/cycles/scene/light_tree.h b/intern/cycles/scene/light_tree.h index 156c14e9637..70b81b88f9d 100644 --- a/intern/cycles/scene/light_tree.h +++ b/intern/cycles/scene/light_tree.h @@ -157,6 +157,12 @@ struct LightTreeLightLink { void add(const LightTreeLightLink &other) { + /* other.set_membership is zero when expanding with an empty bucket: in this case there is no + * need to mark node as not shareable. */ + if (other.set_membership == 0) { + return; + } + if (set_membership == 0) { set_membership = other.set_membership; shareable = other.shareable; @@ -418,7 +424,7 @@ class LightTree { return make_unique(measure, bit_trial); } - size_t num_emitters() + size_t num_emitters() const { return emitters_.size(); } diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt index 8c7ac879f28..0d98480defd 100644 --- a/intern/cycles/test/CMakeLists.txt +++ b/intern/cycles/test/CMakeLists.txt @@ -33,6 +33,7 @@ set(SRC kernel_camera_projection_test.cpp render_graph_finalize_test.cpp util_aligned_malloc_test.cpp + util_boundbox_test.cpp util_ies_test.cpp util_math_test.cpp util_math_fast_test.cpp diff --git a/intern/cycles/test/util_boundbox_test.cpp b/intern/cycles/test/util_boundbox_test.cpp new file mode 100644 index 00000000000..221d9ef65de --- /dev/null +++ b/intern/cycles/test/util_boundbox_test.cpp @@ -0,0 +1,30 @@ +/* SPDX-FileCopyrightText: 2011-2025 Blender Foundation + * + * SPDX-License-Identifier: Apache-2.0 */ + +#include "util/boundbox.h" + +#include "testing/testing.h" + +#include "util/transform.h" + +CCL_NAMESPACE_BEGIN + +TEST(BoundBox, transformed) +{ + { + const Transform tfm = transform_translate(make_float3(1, 2, 3)); + const BoundBox orig_bounds(make_float3(-2, -3, -4), make_float3(3, 4, 5)); + const BoundBox transformed_bounds = orig_bounds.transformed(&tfm); + EXPECT_LE(len(transformed_bounds.min - make_float3(-1, -1, -1)), 1e-6f); + EXPECT_LE(len(transformed_bounds.max - make_float3(4, 6, 8)), 1e-6f); + } + + /* Non-valid boundbox should result in non-valid after transform. */ + { + const Transform tfm = transform_scale(make_float3(1, 1, 1)); + EXPECT_FALSE(BoundBox(BoundBox::empty).transformed(&tfm).valid()); + } +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/util/boundbox.h b/intern/cycles/util/boundbox.h index 1cfa5f0f939..2b5ec9e362d 100644 --- a/intern/cycles/util/boundbox.h +++ b/intern/cycles/util/boundbox.h @@ -135,6 +135,12 @@ class BoundBox { { BoundBox result = BoundBox::empty; + /* Avoid transforming empty bounding box since the code below performs per-corner transform + * which will convert non-valid bounds to valid. */ + if (!valid()) { + return result; + } + for (int i = 0; i < 8; i++) { float3 p;