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.
This commit is contained in:
Sergey Sharybin 2021-07-29 12:06:07 +02:00
parent 0491052a96
commit 5116b7a4c2
Notes: blender-bot 2023-02-14 07:17:43 +01:00
Referenced by issue #90315, Blender 2.90.0, 2.92.0, 2.93.1, 3.0.0-alpha master and 2.80 crashes when Cycles Render Devices is set to OpenCL
2 changed files with 42 additions and 2 deletions

View File

@ -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);

View File

@ -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;