Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2020-11-11 20:40:46 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-11-12 21:48:59 +0300
commit5c01ecd2bf5d0dc0d42f90aba2a3d9f948d16bb8 (patch)
tree91b8996dcb0eeb18c30114a1ee4b1052a711d44f /intern
parentf17dfd575ce23c2e9fd383f0c87676d524a1124b (diff)
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.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_volume.cpp25
-rw-r--r--intern/cycles/render/volume.cpp60
2 files changed, 33 insertions, 52 deletions
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]);