diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_curves.cpp | 42 | ||||
-rw-r--r-- | intern/cycles/blender/blender_geometry.cpp | 42 | ||||
-rw-r--r-- | intern/cycles/blender/blender_light.cpp | 15 | ||||
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 61 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 26 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 29 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 49 | ||||
-rw-r--r-- | intern/cycles/blender/blender_volume.cpp | 21 |
8 files changed, 165 insertions, 120 deletions
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 85d886fd850..6fe5ea41fff 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -526,8 +526,13 @@ bool BlenderSync::object_has_particle_hair(BL::Object b_ob) /* Old particle hair. */ void BlenderSync::sync_particle_hair( - Hair *hair, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) + Hair *hair, BL::Mesh &b_mesh, BObjectInfo &b_ob_info, bool motion, int motion_step) { + if (!b_ob_info.is_real_object_data()) { + return; + } + BL::Object b_ob = b_ob_info.real_object; + /* obtain general settings */ if (b_ob.mode() == b_ob.mode_PARTICLE_EDIT || b_ob.mode() == b_ob.mode_EDIT) { return; @@ -788,10 +793,10 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st } /* Hair object. */ -void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step) +void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int motion_step) { /* Convert Blender hair to Cycles curves. */ - BL::Hair b_hair(b_ob.data()); + BL::Hair b_hair(b_ob_info.object_data); if (motion) { export_hair_curves_motion(hair, b_hair, motion_step); } @@ -800,16 +805,16 @@ void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motio } } #else -void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step) +void BlenderSync::sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int motion_step) { (void)hair; - (void)b_ob; + (void)b_ob_info; (void)motion; (void)motion_step; } #endif -void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair) +void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Hair *hair) { /* make a copy of the shaders as the caller in the main thread still need them for syncing the * attributes */ @@ -819,19 +824,19 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *ha new_hair.set_used_shaders(used_shaders); if (view_layer.use_hair) { - if (b_ob.type() == BL::Object::type_HAIR) { + if (b_ob_info.object_data.is_a(&RNA_Hair)) { /* Hair object. */ - sync_hair(&new_hair, b_ob, false); + sync_hair(&new_hair, b_ob_info, false); } else { /* Particle hair. */ bool need_undeformed = new_hair.need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( - b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE); + b_data, b_ob_info, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(&new_hair, b_mesh, b_ob, false); - free_object_to_mesh(b_data, b_ob, b_mesh); + sync_particle_hair(&new_hair, b_mesh, b_ob_info, false); + free_object_to_mesh(b_data, b_ob_info, b_mesh); } } } @@ -859,7 +864,7 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *ha } void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, - BL::Object b_ob, + BObjectInfo &b_ob_info, Hair *hair, int motion_step) { @@ -869,18 +874,19 @@ void BlenderSync::sync_hair_motion(BL::Depsgraph b_depsgraph, } /* Export deformed coordinates. */ - if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) { - if (b_ob.type() == BL::Object::type_HAIR) { + if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) { + if (b_ob_info.object_data.is_a(&RNA_Hair)) { /* Hair object. */ - sync_hair(hair, b_ob, true, motion_step); + sync_hair(hair, b_ob_info, true, motion_step); return; } else { /* Particle hair. */ - BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); + BL::Mesh b_mesh = object_to_mesh( + b_data, b_ob_info, b_depsgraph, false, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(hair, b_mesh, b_ob, true, motion_step); - free_object_to_mesh(b_data, b_ob, b_mesh); + sync_particle_hair(hair, b_mesh, b_ob_info, true, motion_step); + free_object_to_mesh(b_data, b_ob_info, b_mesh); return; } } diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp index a009018f357..acc089a286c 100644 --- a/intern/cycles/blender/blender_geometry.cpp +++ b/intern/cycles/blender/blender_geometry.cpp @@ -29,13 +29,15 @@ CCL_NAMESPACE_BEGIN -static Geometry::Type determine_geom_type(BL::Object &b_ob, bool use_particle_hair) +static Geometry::Type determine_geom_type(BObjectInfo &b_ob_info, bool use_particle_hair) { - if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) { + if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) { return Geometry::HAIR; } - if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) { + if (b_ob_info.object_data.is_a(&RNA_Volume) || + (b_ob_info.object_data == b_ob_info.real_object.data() && + object_fluid_gas_domain_find(b_ob_info.real_object))) { return Geometry::VOLUME; } @@ -71,20 +73,17 @@ array<Node *> BlenderSync::find_used_shaders(BL::Object &b_ob) } Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, - BL::Object &b_ob, - BL::Object &b_ob_instance, + BObjectInfo &b_ob_info, bool object_updated, bool use_particle_hair, TaskPool *task_pool) { /* Test if we can instance or if the object is modified. */ - BL::ID b_ob_data = b_ob.data(); - BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; - Geometry::Type geom_type = determine_geom_type(b_ob, use_particle_hair); - GeometryKey key(b_key_id.ptr.data, geom_type); + Geometry::Type geom_type = determine_geom_type(b_ob_info, use_particle_hair); + GeometryKey key(b_ob_info.object_data, geom_type); /* Find shader indices. */ - array<Node *> used_shaders = find_used_shaders(b_ob); + array<Node *> used_shaders = find_used_shaders(b_ob_info.iter_object); /* Ensure we only sync instanced geometry once. */ Geometry *geom = geometry_map.find(key); @@ -111,7 +110,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, } else { /* Test if we need to update existing geometry. */ - sync = geometry_map.update(geom, b_key_id); + sync = geometry_map.update(geom, b_ob_info.object_data); } if (!sync) { @@ -144,7 +143,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, geometry_synced.insert(geom); - geom->name = ustring(b_ob_data.name().c_str()); + geom->name = ustring(b_ob_info.object_data.name().c_str()); /* Store the shaders immediately for the object attribute code. */ geom->set_used_shaders(used_shaders); @@ -153,19 +152,19 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, if (progress.get_cancel()) return; - progress.set_sync_status("Synchronizing object", b_ob.name()); + progress.set_sync_status("Synchronizing object", b_ob_info.real_object.name()); if (geom_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); - sync_hair(b_depsgraph, b_ob, hair); + sync_hair(b_depsgraph, b_ob_info, hair); } else if (geom_type == Geometry::VOLUME) { Volume *volume = static_cast<Volume *>(geom); - sync_volume(b_ob, volume); + sync_volume(b_ob_info, volume); } else { Mesh *mesh = static_cast<Mesh *>(geom); - sync_mesh(b_depsgraph, b_ob, mesh); + sync_mesh(b_depsgraph, b_ob_info, mesh); } }; @@ -181,7 +180,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, } void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, - BL::Object &b_ob, + BObjectInfo &b_ob_info, Object *object, float motion_time, bool use_particle_hair, @@ -210,16 +209,17 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, if (progress.get_cancel()) return; - if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) { + if (b_ob_info.object_data.is_a(&RNA_Hair) || use_particle_hair) { Hair *hair = static_cast<Hair *>(geom); - sync_hair_motion(b_depsgraph, b_ob, hair, motion_step); + sync_hair_motion(b_depsgraph, b_ob_info, hair, motion_step); } - else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) { + else if (b_ob_info.object_data.is_a(&RNA_Volume) || + object_fluid_gas_domain_find(b_ob_info.real_object)) { /* No volume motion blur support yet. */ } else { Mesh *mesh = static_cast<Mesh *>(geom); - sync_mesh_motion(b_depsgraph, b_ob, mesh, motion_step); + sync_mesh_motion(b_depsgraph, b_ob_info, mesh, motion_step); } }; diff --git a/intern/cycles/blender/blender_light.cpp b/intern/cycles/blender/blender_light.cpp index 50cd9e3db5c..542028f4b2f 100644 --- a/intern/cycles/blender/blender_light.cpp +++ b/intern/cycles/blender/blender_light.cpp @@ -27,15 +27,14 @@ CCL_NAMESPACE_BEGIN void BlenderSync::sync_light(BL::Object &b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], - BL::Object &b_ob, - BL::Object &b_ob_instance, + BObjectInfo &b_ob_info, int random_id, Transform &tfm, bool *use_portal) { /* test if we need to sync */ - ObjectKey key(b_parent, persistent_id, b_ob_instance, false); - BL::Light b_light(b_ob.data()); + ObjectKey key(b_parent, persistent_id, b_ob_info.real_object, false); + BL::Light b_light(b_ob_info.object_data); Light *light = light_map.find(key); @@ -44,7 +43,7 @@ void BlenderSync::sync_light(BL::Object &b_parent, const bool tfm_updated = (light && light->get_tfm() != tfm); /* Update if either object or light data changed. */ - if (!light_map.add_or_update(&light, b_ob, b_parent, key) && !tfm_updated) { + if (!light_map.add_or_update(&light, b_ob_info.real_object, b_parent, key) && !tfm_updated) { Shader *shader; if (!shader_map.add_or_update(&shader, b_light)) { if (light->get_is_portal()) @@ -139,11 +138,11 @@ void BlenderSync::sync_light(BL::Object &b_parent, light->set_max_bounces(get_int(clight, "max_bounces")); - if (b_ob != b_ob_instance) { + if (b_ob_info.real_object != b_ob_info.iter_object) { light->set_random_id(random_id); } else { - light->set_random_id(hash_uint2(hash_string(b_ob.name().c_str()), 0)); + light->set_random_id(hash_uint2(hash_string(b_ob_info.real_object.name().c_str()), 0)); } if (light->get_light_type() == LIGHT_AREA) @@ -155,7 +154,7 @@ void BlenderSync::sync_light(BL::Object &b_parent, *use_portal = true; /* visibility */ - uint visibility = object_ray_visibility(b_ob); + uint visibility = object_ray_visibility(b_ob_info.real_object); light->set_use_diffuse((visibility & PATH_RAY_DIFFUSE) != 0); light->set_use_glossy((visibility & PATH_RAY_GLOSSY) != 0); light->set_use_transmission((visibility & PATH_RAY_TRANSMIT) != 0); diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index ebba6981502..9bb3447f56b 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -999,12 +999,14 @@ static void create_mesh(Scene *scene, static void create_subd_mesh(Scene *scene, Mesh *mesh, - BL::Object &b_ob, + BObjectInfo &b_ob_info, BL::Mesh &b_mesh, const array<Node *> &used_shaders, float dicing_rate, int max_subdivisions) { + BL::Object b_ob = b_ob_info.real_object; + BL::SubsurfModifier subsurf_mod(b_ob.modifiers[b_ob.modifiers.length() - 1]); bool subdivide_uvs = subsurf_mod.uv_smooth() != BL::SubsurfModifier::uv_smooth_NONE; @@ -1043,7 +1045,7 @@ static void create_subd_mesh(Scene *scene, * * 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) +static bool mesh_need_motion_attribute(BObjectInfo &b_ob_info, Scene *scene) { const Scene::MotionType need_motion = scene->need_motion(); if (need_motion == Scene::MOTION_NONE) { @@ -1060,7 +1062,7 @@ static bool mesh_need_motion_attribute(BL::Object &b_ob, Scene *scene) * - 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"); + PointerRNA cobject = RNA_pointer_get(&b_ob_info.real_object.ptr, "cycles"); const bool use_motion = get_boolean(cobject, "use_motion_blur"); if (!use_motion) { return false; @@ -1072,12 +1074,13 @@ static bool mesh_need_motion_attribute(BL::Object &b_ob, Scene *scene) return true; } -static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *mesh) +static void sync_mesh_cached_velocities(BObjectInfo &b_ob_info, Scene *scene, Mesh *mesh) { - if (!mesh_need_motion_attribute(b_ob, scene)) { + if (!mesh_need_motion_attribute(b_ob_info, scene)) { return; } + BL::Object b_ob = b_ob_info.real_object; BL::MeshSequenceCacheModifier b_mesh_cache = object_mesh_cache_find(b_ob, true, nullptr); if (!b_mesh_cache) { @@ -1118,12 +1121,16 @@ 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) +static void sync_mesh_fluid_motion(BObjectInfo &b_ob_info, Scene *scene, Mesh *mesh) { - if (!mesh_need_motion_attribute(b_ob, scene)) { + if (!b_ob_info.is_real_object_data()) { + return; + } + if (!mesh_need_motion_attribute(b_ob_info, scene)) { return; } + BL::Object b_ob = b_ob_info.real_object; BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob); if (!b_fluid_domain) @@ -1157,7 +1164,7 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh) } } -void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh) +void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Mesh *mesh) { /* make a copy of the shaders as the caller in the main thread still need them for syncing the * attributes */ @@ -1170,20 +1177,21 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me /* Adaptive subdivision setup. Not for baking since that requires * exact mapping to the Blender mesh. */ if (!scene->bake_manager->get_baking()) { - new_mesh.set_subdivision_type(object_subdivision_type(b_ob, preview, experimental)); + new_mesh.set_subdivision_type( + object_subdivision_type(b_ob_info.real_object, preview, experimental)); } /* For some reason, meshes do not need this... */ bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( - b_data, b_ob, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type()); + b_data, b_ob_info, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type()); if (b_mesh) { /* Sync mesh itself. */ if (new_mesh.get_subdivision_type() != Mesh::SUBDIVISION_NONE) create_subd_mesh(scene, &new_mesh, - b_ob, + b_ob_info, b_mesh, new_mesh.get_used_shaders(), dicing_rate, @@ -1191,15 +1199,15 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me else create_mesh(scene, &new_mesh, b_mesh, new_mesh.get_used_shaders(), false); - free_object_to_mesh(b_data, b_ob, b_mesh); + free_object_to_mesh(b_data, b_ob_info, b_mesh); } } /* cached velocities (e.g. from alembic archive) */ - sync_mesh_cached_velocities(b_ob, scene, &new_mesh); + sync_mesh_cached_velocities(b_ob_info, scene, &new_mesh); /* mesh fluid motion mantaflow */ - sync_mesh_fluid_motion(b_ob, scene, &new_mesh); + sync_mesh_fluid_motion(b_ob_info, scene, &new_mesh); /* update original sockets */ @@ -1230,18 +1238,19 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me } void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, - BL::Object b_ob, + BObjectInfo &b_ob_info, Mesh *mesh, int motion_step) { /* Fluid motion blur already exported. */ - BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob); + BL::FluidDomainSettings b_fluid_domain = object_fluid_liquid_domain_find(b_ob_info.real_object); if (b_fluid_domain) { return; } /* Cached motion blur already exported. */ - BL::MeshSequenceCacheModifier mesh_cache = object_mesh_cache_find(b_ob, true, nullptr); + BL::MeshSequenceCacheModifier mesh_cache = object_mesh_cache_find( + b_ob_info.real_object, true, nullptr); if (mesh_cache) { return; } @@ -1255,11 +1264,13 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, /* Skip objects without deforming modifiers. this is not totally reliable, * would need a more extensive check to see which objects are animated. */ BL::Mesh b_mesh(PointerRNA_NULL); - if (ccl::BKE_object_is_deform_modified(b_ob, b_scene, preview)) { + if (ccl::BKE_object_is_deform_modified(b_ob_info, b_scene, preview)) { /* get derived mesh */ - b_mesh = object_to_mesh(b_data, b_ob, b_depsgraph, false, Mesh::SUBDIVISION_NONE); + b_mesh = object_to_mesh(b_data, b_ob_info, b_depsgraph, false, Mesh::SUBDIVISION_NONE); } + const std::string ob_name = b_ob_info.real_object.name(); + /* TODO(sergey): Perform preliminary check for number of vertices. */ if (b_mesh) { /* Export deformed coordinates. */ @@ -1295,17 +1306,17 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) { /* no motion, remove attributes again */ if (b_mesh.vertices.length() != numverts) { - VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name(); + VLOG(1) << "Topology differs, disabling motion blur for object " << ob_name; } else { - VLOG(1) << "No actual deformation motion for object " << b_ob.name(); + VLOG(1) << "No actual deformation motion for object " << ob_name; } mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mN) mesh->attributes.remove(ATTR_STD_MOTION_VERTEX_NORMAL); } else if (motion_step > 0) { - VLOG(1) << "Filling deformation motion for object " << b_ob.name(); + VLOG(1) << "Filling deformation motion for object " << ob_name; /* motion, fill up previous steps that we might have skipped because * they had no motion, but we need them anyway now */ float3 *P = &mesh->get_verts()[0]; @@ -1319,8 +1330,8 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, } else { if (b_mesh.vertices.length() != numverts) { - VLOG(1) << "Topology differs, discarding motion blur for object " << b_ob.name() - << " at time " << motion_step; + VLOG(1) << "Topology differs, discarding motion blur for object " << ob_name << " at time " + << motion_step; memcpy(mP, &mesh->get_verts()[0], sizeof(float3) * numverts); if (mN != NULL) { memcpy(mN, attr_N->data_float3(), sizeof(float3) * numverts); @@ -1328,7 +1339,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, } } - free_object_to_mesh(b_data, b_ob, b_mesh); + free_object_to_mesh(b_data, b_ob_info, b_mesh); return; } diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 5d98b61b409..2243baca0b2 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -154,7 +154,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, const bool is_instance = b_instance.is_instance(); BL::Object b_ob = b_instance.object(); BL::Object b_parent = is_instance ? b_instance.parent() : b_instance.object(); - BL::Object b_ob_instance = is_instance ? b_instance.instance_object() : b_ob; + BObjectInfo b_ob_info{b_ob, is_instance ? b_instance.instance_object() : b_ob, b_ob.data()}; const bool motion = motion_time != 0.0f; /*const*/ Transform tfm = get_transform(b_ob.matrix_world()); int *persistent_id = NULL; @@ -178,8 +178,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, { sync_light(b_parent, persistent_id, - b_ob, - b_ob_instance, + b_ob_info, is_instance ? b_instance.random_id() : 0, tfm, use_portal); @@ -231,7 +230,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, TaskPool *object_geom_task_pool = (is_instance) ? NULL : geom_task_pool; /* key to lookup object */ - ObjectKey key(b_parent, persistent_id, b_ob_instance, use_particle_hair); + ObjectKey key(b_parent, persistent_id, b_ob_info.real_object, use_particle_hair); Object *object; /* motion vector case */ @@ -249,12 +248,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* mesh deformation */ if (object->get_geometry()) - sync_geometry_motion(b_depsgraph, - b_ob_instance, - object, - motion_time, - use_particle_hair, - object_geom_task_pool); + sync_geometry_motion( + b_depsgraph, b_ob_info, object, motion_time, use_particle_hair, object_geom_task_pool); } return object; @@ -265,15 +260,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, (tfm != object->get_tfm()); /* mesh sync */ - /* b_ob is owned by the iterator and will go out of scope at the end of the block. - * b_ob_instance is the original object and will remain valid for deferred geometry - * sync. */ - Geometry *geometry = sync_geometry(b_depsgraph, - b_ob_instance, - b_ob_instance, - object_updated, - use_particle_hair, - object_geom_task_pool); + Geometry *geometry = sync_geometry( + b_depsgraph, b_ob_info, object_updated, use_particle_hair, object_geom_task_pool); object->set_geometry(geometry); /* special case not tracked by object update flags */ diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 44322dda6b9..76e8f23864c 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -23,6 +23,7 @@ #include "RNA_types.h" #include "blender/blender_id_map.h" +#include "blender/blender_util.h" #include "blender/blender_viewport.h" #include "render/scene.h" @@ -158,18 +159,24 @@ class BlenderSync { bool sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object); /* Volume */ - void sync_volume(BL::Object &b_ob, Volume *volume); + void sync_volume(BObjectInfo &b_ob_info, Volume *volume); /* Mesh */ - void sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh); - void sync_mesh_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step); + void sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Mesh *mesh); + void sync_mesh_motion(BL::Depsgraph b_depsgraph, + BObjectInfo &b_ob_info, + Mesh *mesh, + int motion_step); /* Hair */ - void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair); - void sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair, int motion_step); - void sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step = 0); + void sync_hair(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, Hair *hair); + void sync_hair_motion(BL::Depsgraph b_depsgraph, + BObjectInfo &b_ob_info, + Hair *hair, + int motion_step); + void sync_hair(Hair *hair, BObjectInfo &b_ob_info, bool motion, int motion_step = 0); void sync_particle_hair( - Hair *hair, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); + Hair *hair, BL::Mesh &b_mesh, BObjectInfo &b_ob_info, bool motion, int motion_step = 0); bool object_has_particle_hair(BL::Object b_ob); /* Camera */ @@ -178,14 +185,13 @@ class BlenderSync { /* Geometry */ Geometry *sync_geometry(BL::Depsgraph &b_depsgrpah, - BL::Object &b_ob, - BL::Object &b_ob_instance, + BObjectInfo &b_ob_info, bool object_updated, bool use_particle_hair, TaskPool *task_pool); void sync_geometry_motion(BL::Depsgraph &b_depsgraph, - BL::Object &b_ob, + BObjectInfo &b_ob_info, Object *object, float motion_time, bool use_particle_hair, @@ -194,8 +200,7 @@ class BlenderSync { /* Light */ void sync_light(BL::Object &b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], - BL::Object &b_ob, - BL::Object &b_ob_instance, + BObjectInfo &b_ob_info, int random_id, Transform &tfm, bool *use_portal); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index f6824f31b7b..e69531ea707 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -40,6 +40,28 @@ float *BKE_image_get_float_pixels_for_frame(void *image, int frame, int tile); CCL_NAMESPACE_BEGIN +struct BObjectInfo { + /* Object directly provided by the depsgraph iterator. This object is only valid during one + * iteration and must not be accessed afterwards. Transforms and visibility should be checked on + * this object. */ + BL::Object iter_object; + + /* This object remains alive even after the object iterator is done. It corresponds to one + * original object. It is the object that owns the object data below. */ + BL::Object real_object; + + /* The object-data referenced by the iter object. This is still valid after the depsgraph + * iterator is done. It might have a different type compared to real_object.data(). */ + BL::ID object_data; + + /* True when the current geometry is the data of the referenced object. False when it is a + * geometry instance that does not have a 1-to-1 relationship with an object. */ + bool is_real_object_data() const + { + return const_cast<BL::Object &>(real_object).data() == object_data; + } +}; + typedef BL::ShaderNodeAttribute::attribute_type_enum BlenderAttributeType; BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name); @@ -47,7 +69,7 @@ void python_thread_state_save(void **python_thread_state); void python_thread_state_restore(void **python_thread_state); static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/, - BL::Object &object, + BObjectInfo &b_ob_info, BL::Depsgraph & /*depsgraph*/, bool /*calc_undeformed*/, Mesh::SubdivisionType subdivision_type) @@ -69,9 +91,9 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/, #endif BL::Mesh mesh(PointerRNA_NULL); - if (object.type() == BL::Object::type_MESH) { + if (b_ob_info.object_data.is_a(&RNA_Mesh)) { /* TODO: calc_undeformed is not used. */ - mesh = BL::Mesh(object.data()); + mesh = BL::Mesh(b_ob_info.object_data); /* Make a copy to split faces if we use autosmooth, otherwise not needed. * Also in edit mode do we need to make a copy, to ensure data layers like @@ -79,12 +101,15 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/, if (mesh.is_editmode() || (mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) { BL::Depsgraph depsgraph(PointerRNA_NULL); - mesh = object.to_mesh(false, depsgraph); + assert(b_ob_info.is_real_object_data()); + mesh = b_ob_info.real_object.to_mesh(false, depsgraph); } } else { BL::Depsgraph depsgraph(PointerRNA_NULL); - mesh = object.to_mesh(false, depsgraph); + if (b_ob_info.is_real_object_data()) { + mesh = b_ob_info.real_object.to_mesh(false, depsgraph); + } } #if 0 @@ -108,10 +133,14 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/, } static inline void free_object_to_mesh(BL::BlendData & /*data*/, - BL::Object &object, + BObjectInfo &b_ob_info, BL::Mesh &mesh) { + if (!b_ob_info.is_real_object_data()) { + return; + } /* Free mesh if we didn't just use the existing one. */ + BL::Object object = b_ob_info.real_object; if (object.data().ptr.data != mesh.ptr.data) { object.to_mesh_clear(); } @@ -219,9 +248,13 @@ static inline bool BKE_object_is_modified(BL::Object &self, BL::Scene &scene, bo return self.is_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false; } -static inline bool BKE_object_is_deform_modified(BL::Object &self, BL::Scene &scene, bool preview) +static inline bool BKE_object_is_deform_modified(BObjectInfo &self, BL::Scene &scene, bool preview) { - return self.is_deform_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : false; + if (!self.is_real_object_data()) { + return false; + } + return self.real_object.is_deform_modified(scene, (preview) ? (1 << 0) : (1 << 1)) ? true : + false; } static inline int render_resolution_x(BL::RenderSettings &b_render) diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp index 772ab9f5c8a..0a5b19d7d4c 100644 --- a/intern/cycles/blender/blender_volume.cpp +++ b/intern/cycles/blender/blender_volume.cpp @@ -181,9 +181,12 @@ class BlenderSmokeLoader : public ImageLoader { AttributeStandard attribute; }; -static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Volume *volume, float frame) +static void sync_smoke_volume(Scene *scene, BObjectInfo &b_ob_info, Volume *volume, float frame) { - BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob); + if (!b_ob_info.is_real_object_data()) { + return; + } + BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob_info.real_object); if (!b_domain) { return; } @@ -206,7 +209,7 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Volume *volume, fl Attribute *attr = volume->attributes.add(std); - ImageLoader *loader = new BlenderSmokeLoader(b_ob, std); + ImageLoader *loader = new BlenderSmokeLoader(b_ob_info.real_object, std); ImageParams params; params.frame = frame; @@ -244,11 +247,11 @@ class BlenderVolumeLoader : public VDBImageLoader { }; static void sync_volume_object(BL::BlendData &b_data, - BL::Object &b_ob, + BObjectInfo &b_ob_info, Scene *scene, Volume *volume) { - BL::Volume b_volume(b_ob.data()); + BL::Volume b_volume(b_ob_info.object_data); b_volume.grids.load(b_data.ptr.data); BL::VolumeRender b_render(b_volume.render()); @@ -296,19 +299,19 @@ static void sync_volume_object(BL::BlendData &b_data, } } -void BlenderSync::sync_volume(BL::Object &b_ob, Volume *volume) +void BlenderSync::sync_volume(BObjectInfo &b_ob_info, Volume *volume) { volume->clear(true); if (view_layer.use_volumes) { - if (b_ob.type() == BL::Object::type_VOLUME) { + if (b_ob_info.object_data.is_a(&RNA_Volume)) { /* Volume object. Create only attributes, bounding mesh will then * be automatically generated later. */ - sync_volume_object(b_data, b_ob, scene, volume); + sync_volume_object(b_data, b_ob_info, scene, volume); } else { /* Smoke domain. */ - sync_smoke_volume(scene, b_ob, volume, b_scene.frame_current()); + sync_smoke_volume(scene, b_ob_info, volume, b_scene.frame_current()); } } |