[Bf-blender-cvs] [5c01ecd2bf5] blender-v2.91-release: Fix T82516: Cycles crash updateding animated volumes after NanoVDB

Brecht Van Lommel noreply at git.blender.org
Thu Nov 12 20:23:39 CET 2020


Commit: 5c01ecd2bf5d0dc0d42f90aba2a3d9f948d16bb8
Author: Brecht Van Lommel
Date:   Wed Nov 11 18:40:46 2020 +0100
Branches: blender-v2.91-release
https://developer.blender.org/rB5c01ecd2bf5d0dc0d42f90aba2a3d9f948d16bb8

Fix T82516: Cycles crash updateding animated volumes after NanoVDB

Two issues:
* Automatic deduplication of OpenVDB grid data was failing when Cycles had
  already cleared the OpenVDB grid, causing an empty grid. Instead rely on
  Blender return the same OpenVDB grid pointer when deduplication is possible.
* The volume bounds mesh was not properly cleared when the OpenVDB grid was
  empty, causing a mismatch between mesh and voxel data.

===================================================================

M	intern/cycles/blender/blender_volume.cpp
M	intern/cycles/render/volume.cpp

===================================================================

diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp
index e039d8a4895..48ae5a2c5ae 100644
--- a/intern/cycles/blender/blender_volume.cpp
+++ b/intern/cycles/blender/blender_volume.cpp
@@ -242,13 +242,6 @@ class BlenderVolumeLoader : public VDBImageLoader {
 #endif
   }
 
-  bool equals(const ImageLoader &other) const override
-  {
-    /* TODO: detect multiple volume datablocks with the same filepath. */
-    const BlenderVolumeLoader &other_loader = (const BlenderVolumeLoader &)other;
-    return b_volume == other_loader.b_volume && grid_name == other_loader.grid_name;
-  }
-
   BL::Volume b_volume;
 };
 
@@ -307,25 +300,10 @@ static void sync_volume_object(BL::BlendData &b_data,
   }
 }
 
-/* If the voxel attributes change, we need to rebuild the bounding mesh. */
-static vector<int> get_voxel_image_slots(Mesh *mesh)
-{
-  vector<int> slots;
-  for (const Attribute &attr : mesh->attributes.attributes) {
-    if (attr.element == ATTR_ELEMENT_VOXEL) {
-      slots.push_back(attr.data_voxel().svm_slot());
-    }
-  }
-
-  return slots;
-}
-
 void BlenderSync::sync_volume(BL::Object &b_ob,
                               Volume *volume,
                               const vector<Shader *> &used_shaders)
 {
-  vector<int> old_voxel_slots = get_voxel_image_slots(volume);
-
   volume->clear();
   volume->used_shaders = used_shaders;
 
@@ -342,8 +320,7 @@ void BlenderSync::sync_volume(BL::Object &b_ob,
   }
 
   /* Tag update. */
-  bool rebuild = (old_voxel_slots != get_voxel_image_slots(volume));
-  volume->tag_update(scene, rebuild);
+  volume->tag_update(scene, true);
 }
 
 CCL_NAMESPACE_END
diff --git a/intern/cycles/render/volume.cpp b/intern/cycles/render/volume.cpp
index fcf33a5e50a..9e633b27cc9 100644
--- a/intern/cycles/render/volume.cpp
+++ b/intern/cycles/render/volume.cpp
@@ -495,6 +495,37 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
   string msg = string_printf("Computing Volume Mesh %s", volume->name.c_str());
   progress.set_status("Updating Mesh", msg);
 
+  /* Find shader and compute padding based on volume shader interpolation settings. */
+  Shader *volume_shader = NULL;
+  int pad_size = 0;
+
+  foreach (Shader *shader, volume->used_shaders) {
+    if (!shader->has_volume) {
+      continue;
+    }
+
+    volume_shader = shader;
+
+    if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) {
+      pad_size = max(1, pad_size);
+    }
+    else if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) {
+      pad_size = max(2, pad_size);
+    }
+
+    break;
+  }
+
+  /* Clear existing volume mesh, done here in case we early out due to
+   * empty grid or missing volume shader. */
+  volume->clear();
+  volume->need_update_rebuild = true;
+
+  if (!volume_shader) {
+    return;
+  }
+
+  /* Create volume mesh builder. */
   VolumeMeshBuilder builder;
 
 #ifdef WITH_OPENVDB
@@ -541,35 +572,11 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
   }
 #endif
 
+  /* If nothing to build, early out. */
   if (builder.empty_grid()) {
     return;
   }
 
-  /* Compute padding. */
-  Shader *volume_shader = NULL;
-  int pad_size = 0;
-
-  foreach (Shader *shader, volume->used_shaders) {
-    if (!shader->has_volume) {
-      continue;
-    }
-
-    volume_shader = shader;
-
-    if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) {
-      pad_size = max(1, pad_size);
-    }
-    else if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) {
-      pad_size = max(2, pad_size);
-    }
-
-    break;
-  }
-
-  if (!volume_shader) {
-    return;
-  }
-
   builder.add_padding(pad_size);
 
   /* Slightly offset vertex coordinates to avoid overlapping faces with other
@@ -585,11 +592,8 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress)
   vector<float3> face_normals;
   builder.create_mesh(vertices, indices, face_normals, face_overlap_avoidance);
 
-  volume->clear();
   volume->reserve_mesh(vertices.size(), indices.size() / 3);
   volume->used_shaders.push_back(volume_shader);
-  volume->need_update = true;
-  volume->need_update_rebuild = true;
 
   for (size_t i = 0; i < vertices.size(); ++i) {
     volume->add_vertex(vertices[i]);



More information about the Bf-blender-cvs mailing list