Fix cycles crash when voxel attributes changed
authorPhilipp Oeser <info@graphics-engineer.com>
Wed, 14 Aug 2019 08:48:25 +0000 (10:48 +0200)
committerPhilipp Oeser <info@graphics-engineer.com>
Wed, 14 Aug 2019 08:54:28 +0000 (10:54 +0200)
This could happen e.g. when changing smoke type from flow to domain or
connecting a volume shader with to a domain without an actual flow type
around.

Fixes T58569, T68359

Reviewers: brecht

Maniphest Tasks: T58569, T68359

Differential Revision: https://developer.blender.org/D5478

intern/cycles/blender/blender_mesh.cpp
intern/cycles/render/mesh.cpp
intern/cycles/render/mesh.h

index c672bc9f3e222cbec25ebb816d12437a29b981d3..551866f7fced1d7c01e5caf702aa14119a56408a 100644 (file)
@@ -1002,6 +1002,9 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph,
   oldcurve_keys.steal_data(mesh->curve_keys);
   oldcurve_radius.steal_data(mesh->curve_radius);
 
+  /* ensure bvh rebuild (instead of refit) if has_voxel_attributes() changed */
+  bool oldhas_voxel_attributes = mesh->has_voxel_attributes();
+
   mesh->clear();
   mesh->used_shaders = used_shaders;
   mesh->name = ustring(b_ob_data.name().c_str());
@@ -1050,7 +1053,8 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph,
   /* tag update */
   bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) ||
                  (oldsubd_face_corners != mesh->subd_face_corners) ||
-                 (oldcurve_keys != mesh->curve_keys) || (oldcurve_radius != mesh->curve_radius);
+                 (oldcurve_keys != mesh->curve_keys) || (oldcurve_radius != mesh->curve_radius) ||
+                 (oldhas_voxel_attributes != mesh->has_voxel_attributes());
 
   mesh->tag_update(scene, rebuild);
 
index 91c3a772537b81e8c62e73df113bc817bd1702c2..6ac6666185909205db7220033e78605141acfe04 100644 (file)
@@ -1091,6 +1091,17 @@ bool Mesh::has_true_displacement() const
   return false;
 }
 
+bool Mesh::has_voxel_attributes() const
+{
+  foreach (const Attribute &attr, attributes.attributes) {
+    if (attr.element == ATTR_ELEMENT_VOXEL) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 float Mesh::motion_time(int step) const
 {
   return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f;
@@ -2020,15 +2031,7 @@ void MeshManager::device_update_preprocess(Device *device, Scene *scene, Progres
 
     if (need_update && mesh->has_volume) {
       /* Create volume meshes if there is voxel data. */
-      bool has_voxel_attributes = false;
-
-      foreach (Attribute &attr, mesh->attributes.attributes) {
-        if (attr.element == ATTR_ELEMENT_VOXEL) {
-          has_voxel_attributes = true;
-        }
-      }
-
-      if (has_voxel_attributes) {
+      if (mesh->has_voxel_attributes()) {
         if (!volume_images_updated) {
           progress.set_status("Updating Meshes Volume Bounds");
           device_update_volume_images(device, scene, progress);
index 05c67ccb3b751a2d2ac97a514627cd00ef767363..5bb6ab328b753862a8e90ab5a502caf108cadefb 100644 (file)
@@ -318,6 +318,7 @@ class Mesh : public Node {
 
   bool has_motion_blur() const;
   bool has_true_displacement() const;
+  bool has_voxel_attributes() const;
 
   /* Convert between normalized -1..1 motion time and index
    * in the VERTEX_MOTION attribute. */