diff options
author | Jacques Lucke <jacques@blender.org> | 2021-11-04 20:32:01 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-11-04 20:32:01 +0300 |
commit | c7fcc50842d85664d2b07c32b181951ea7661440 (patch) | |
tree | f7f79d03c30de2306d74f35d5f9acd49875c4a83 | |
parent | b7260ca4c9f4b7618c9c214f1270e31d6ed9886b (diff) |
Fix T91986: incorrect syncing of geometry instances
The issue was that some geometries were not synced again even when
they changed. This commit adds a map that keeps track of the geometries
that need to be updated when an object has changed.
Differential Revision: https://developer.blender.org/D13020
-rw-r--r-- | intern/cycles/blender/object.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/blender/sync.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/blender/sync.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/makesrna.c | 1 |
4 files changed, 18 insertions, 0 deletions
diff --git a/intern/cycles/blender/object.cpp b/intern/cycles/blender/object.cpp index 9919b9d1836..3800ea0ecd2 100644 --- a/intern/cycles/blender/object.cpp +++ b/intern/cycles/blender/object.cpp @@ -161,6 +161,11 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, if (is_instance) { persistent_id_array = b_instance.persistent_id(); persistent_id = persistent_id_array.data; + if (!b_ob_info.is_real_object_data()) { + /* Remember which object data the geometry is coming from, so that we can sync it when the + * object has changed. */ + instance_geometries_by_object[b_ob_info.real_object.ptr.data].insert(b_ob_info.object_data); + } } /* light is handled separately */ @@ -560,6 +565,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, else { geometry_motion_synced.clear(); } + instance_geometries_by_object.clear(); /* initialize culling */ BlenderObjectCulling culling(scene, b_scene); diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index cf0b77a9b16..ffd1e78b7f8 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -183,6 +183,15 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d (object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE)) { BL::ID key = BKE_object_is_modified(b_ob) ? b_ob : b_ob.data(); geometry_map.set_recalc(key); + + /* Sync all contained geometry instances as well when the object changed.. */ + map<void *, set<BL::ID>>::const_iterator instance_geometries = + instance_geometries_by_object.find(b_ob.ptr.data); + if (instance_geometries != instance_geometries_by_object.end()) { + for (BL::ID geometry : instance_geometries->second) { + geometry_map.set_recalc(geometry); + } + } } if (updated_geometry) { diff --git a/intern/cycles/blender/sync.h b/intern/cycles/blender/sync.h index c2377406876..7e5d0324ca9 100644 --- a/intern/cycles/blender/sync.h +++ b/intern/cycles/blender/sync.h @@ -225,6 +225,8 @@ class BlenderSync { set<Geometry *> geometry_synced; set<Geometry *> geometry_motion_synced; set<Geometry *> geometry_motion_attribute_synced; + /** Remember which geometries come from which objects to be able to sync them after changes. */ + map<void *, set<BL::ID>> instance_geometries_by_object; set<float> motion_times; void *world_map; bool world_recalc; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 36f19907080..f2e87b29c1f 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -4792,6 +4792,7 @@ static const char *cpp_classes = "\n" " bool operator==(const Pointer &other) const { return ptr.data == other.ptr.data; }\n" " bool operator!=(const Pointer &other) const { return ptr.data != other.ptr.data; }\n" + " bool operator<(const Pointer &other) const { return ptr.data < other.ptr.data; }\n" "\n" " PointerRNA ptr;\n" "};\n" |