From 3bbce154979d2dc8785448a7b1d49adc738af4ec Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Thu, 28 Aug 2025 10:40:37 +0200 Subject: [PATCH] Fix: Cycles: Some volume octree nodes randomly disappearing The function `recursive_build()` can change the `shared_ptr` by making it an internal node. If `root_` is modified, it could happen that when the children are accessing `root_->bbox.min` that memory is already freed. Storing `bbox_min` separately seems to fix the issue. No error is seen after running the tests repeatedly for 2000 times. Pull Request: https://projects.blender.org/blender/blender/pulls/145239 --- intern/cycles/bvh/octree.cpp | 5 +++-- intern/cycles/bvh/octree.h | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/intern/cycles/bvh/octree.cpp b/intern/cycles/bvh/octree.cpp index be51f1cd071..4e2e7f75cd2 100644 --- a/intern/cycles/bvh/octree.cpp +++ b/intern/cycles/bvh/octree.cpp @@ -50,7 +50,7 @@ Extrema Octree::get_extrema(const int3 index_min, const int3 index_max) c __forceinline float3 Octree::position_to_index(const float3 p) const { - return (p - root_->bbox.min) * position_to_index_scale_; + return (p - bbox_min) * position_to_index_scale_; } int3 Octree::position_to_floor_index(const float3 p) const @@ -71,7 +71,7 @@ int3 Octree::position_to_ceil_index(const float3 p) const __forceinline float3 Octree::index_to_position(int x, int y, int z) const { - return root_->bbox.min + make_float3(x, y, z) * index_to_position_scale_; + return bbox_min + make_float3(x, y, z) * index_to_position_scale_; } __forceinline float3 Octree::voxel_size() const @@ -380,6 +380,7 @@ void Octree::build(Device *device, Octree::Octree(const BoundBox &bbox) { + bbox_min = bbox.min; root_ = std::make_shared(bbox, 0); is_built_ = false; is_flattened_ = false; diff --git a/intern/cycles/bvh/octree.h b/intern/cycles/bvh/octree.h index 7826c4ff008..993468b95f9 100644 --- a/intern/cycles/bvh/octree.h +++ b/intern/cycles/bvh/octree.h @@ -123,6 +123,9 @@ class Octree { /* Root node. */ std::shared_ptr root_; + /* Bounding box min of the octree, used for computing the indices. */ + float3 bbox_min; + /* Whether the octree is already built. */ bool is_built_;