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:
authorSergey Sharybin <sergey@blender.org>2021-07-29 13:06:07 +0300
committerSergey Sharybin <sergey@blender.org>2021-07-29 13:28:46 +0300
commit5116b7a4c222c6f80da00afa05925a36476d4d44 (patch)
tree27343eaa7ca08c720425095ced2a3cdedb1bf0ce /intern
parent0491052a9697a706b4cd14a1f478180ad6fb8c75 (diff)
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.
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_mesh.cpp41
-rw-r--r--intern/cycles/render/attribute.cpp3
2 files changed, 42 insertions, 2 deletions
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;