[Bf-blender-cvs] [5116b7a4c22] master: Fix Cycles crash with fluid object motion blur disabled

Sergey Sharybin noreply at git.blender.org
Thu Jul 29 12:32:54 CEST 2021


Commit: 5116b7a4c222c6f80da00afa05925a36476d4d44
Author: Sergey Sharybin
Date:   Thu Jul 29 12:06:07 2021 +0200
Branches: master
https://developer.blender.org/rB5116b7a4c222c6f80da00afa05925a36476d4d44

Fix Cycles crash with fluid object motion blur disabled

Motion attributes expects mesh to have non-zero number of motion steps,
which was violated in the case when fluid mesh had motion blur disabled.

This is a bit of annoying fix, because of the order of updates. More
ideal solution would be to handle cached and fluid velocities in the
sync_mesh_motion() which ensures all the dependencies between settings.

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

M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/render/attribute.cpp

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

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 11158532738..c3c6c623144 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -1055,10 +1055,45 @@ static BL::MeshSequenceCacheModifier object_mesh_cache_find(BL::Object &b_ob)
   return BL::MeshSequenceCacheModifier(PointerRNA_NULL);
 }
 
+/* Check whether some of "built-in" motion-related attributes are needed to be exported (includes
+ * things like velocity from cache modifier, fluid simulation).
+ *
+ * NOTE: This code is run prior to object motion blur initialization. so can not access properties
+ * set by `sync_object_motion_init()`. */
+static bool mesh_need_motion_attribute(BL::Object &b_ob, Scene *scene)
+{
+  const Scene::MotionType need_motion = scene->need_motion();
+  if (need_motion == Scene::MOTION_NONE) {
+    /* Simple case: neither motion pass nor motion blur is needed, no need in the motion related
+     * attributes. */
+    return false;
+  }
+
+  if (need_motion == Scene::MOTION_BLUR) {
+    /* A bit tricky and implicit case:
+     * - Motion blur is enabled in the scene, which implies specific number of time steps for
+     *   objects.
+     * - If the object has motion blur disabled on it, it will have 0 time steps.
+     * - Motion attribute expects non-zero time steps.
+     *
+     * Avoid adding motion attributes if the motion blur will enforce 0 motion steps. */
+    PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles");
+    const bool use_motion = get_boolean(cobject, "use_motion_blur");
+    if (!use_motion) {
+      return false;
+    }
+  }
+
+  /* Motion pass which implies 3 motion steps, or motion blur which is not disabled on object
+   * level. */
+  return true;
+}
+
 static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *mesh)
 {
-  if (scene->need_motion() == Scene::MOTION_NONE)
+  if (!mesh_need_motion_attribute(b_ob, scene)) {
     return;
+  }
 
   BL::MeshSequenceCacheModifier b_mesh_cache = object_mesh_cache_find(b_ob);
 
@@ -1102,8 +1137,10 @@ static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *me
 
 static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh)
 {
-  if (scene->need_motion() == Scene::MOTION_NONE)
+  LOG(INFO) << b_ob.name();
+  if (!mesh_need_motion_attribute(b_ob, scene)) {
     return;
+  }
 
   BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob);
 
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index bf9d69cb47e..ea5a5f50f2d 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -20,6 +20,7 @@
 #include "render/mesh.h"
 
 #include "util/util_foreach.h"
+#include "util/util_logging.h"
 #include "util/util_transform.h"
 
 CCL_NAMESPACE_BEGIN
@@ -208,6 +209,7 @@ size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const
     case ATTR_ELEMENT_VERTEX_MOTION:
       if (geom->geometry_type == Geometry::MESH) {
         Mesh *mesh = static_cast<Mesh *>(geom);
+        DCHECK_GT(mesh->get_motion_steps(), 0);
         size = (mesh->get_verts().size() + mesh->get_num_ngons()) * (mesh->get_motion_steps() - 1);
         if (prim == ATTR_PRIM_SUBD) {
           size -= mesh->get_num_subd_verts() * (mesh->get_motion_steps() - 1);
@@ -252,6 +254,7 @@ size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const
     case ATTR_ELEMENT_CURVE_KEY_MOTION:
       if (geom->geometry_type == Geometry::HAIR) {
         Hair *hair = static_cast<Hair *>(geom);
+        DCHECK_GT(hair->get_motion_steps(), 0);
         size = hair->get_curve_keys().size() * (hair->get_motion_steps() - 1);
       }
       break;



More information about the Bf-blender-cvs mailing list