Page Menu
Home
Search
Configure Global Search
Log In
Paste
P1275
Generic API to to check if an object has been updated
Active
Public
Actions
Authored by
Campbell Barton (campbellbarton)
on Feb 27 2020, 8:02 AM.
Edit Paste
Archive Paste
View Raw File
Subscribe
Mute Notifications
Award Token
Tags
None
Subscribers
None
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 9f436db97ee..d5d066e426c 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -39,6 +39,7 @@ struct Mesh;
struct ModifierData;
struct MovieClip;
struct Object;
+struct Object_UpdateTag;
struct RegionView3D;
struct RigidBodyWorld;
struct Scene;
@@ -359,6 +360,10 @@ struct MovieClip *BKE_object_movieclip_get(struct Scene *scene,
void BKE_object_runtime_reset(struct Object *object);
void BKE_object_runtime_reset_on_copy(struct Object *object, const int flag);
+void BKE_object_runtime_update_tag_add(struct Object *ob, struct Object_UpdateTag *update_tag);
+void BKE_object_runtime_update_tag_remove(struct Object *ob, struct Object_UpdateTag *update_tag);
+void BKE_object_runtime_update_tag_set(struct Object *ob, int flag);
+
void BKE_object_batch_cache_dirty_tag(struct Object *ob);
/* this function returns a superset of the scenes selection based on relationships */
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 51d397a44bc..61c82196830 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -454,6 +454,10 @@ void BKE_object_free_derived_caches(Object *ob)
/* clear grease pencil data */
DRW_gpencil_freecache(ob);
+
+ if (ob->runtime.update_links != NULL) {
+ BKE_object_runtime_update_tag_set(ob, OBJECT_UPDATE_FLAG_GEOM);
+ }
}
void BKE_object_free_caches(Object *object)
@@ -3931,6 +3935,45 @@ void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag))
runtime->gpencil_cache = NULL;
}
+void BKE_object_runtime_update_tag_add(struct Object *ob, Object_UpdateTag *update_tag)
+{
+#ifndef NDEBUG
+ {
+ Object_UpdateTag *tag_step = ob->runtime.update_links;
+ while (tag_step != NULL) {
+ BLI_assert(tag_step != update_tag);
+ tag_step = tag_step->next;
+ }
+ }
+#endif
+ update_tag->next = ob->runtime.update_links;
+ ob->runtime.update_links = update_tag;
+}
+
+void BKE_object_runtime_update_tag_remove(struct Object *ob, Object_UpdateTag *update_tag)
+{
+ Object_UpdateTag *tag_step = ob->runtime.update_links;
+ Object_UpdateTag **tag_link = &ob->runtime.update_links;
+ while (tag_step != NULL) {
+ if (tag_step == update_tag) {
+ *tag_link = update_tag->next;
+ break;
+ }
+ tag_link = &tag_step->next;
+ tag_step = tag_step->next;
+ }
+ /* Assert if not found. */
+ BLI_assert(tag_step != NULL);
+}
+
+void BKE_object_runtime_update_tag_set(struct Object *ob, int flag)
+{
+ Object_UpdateTag *tag_step = ob->runtime.update_links;
+ while (tag_step) {
+ tag_step->flag |= flag;
+ }
+}
+
/*
* Find an associated Armature object
*/
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index eb926c51ba9..e2f8ed82c8f 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -48,6 +48,7 @@ typedef unsigned int (*GHashHashFP)(const void *key);
typedef bool (*GHashCmpFP)(const void *a, const void *b);
typedef void (*GHashKeyFreeFP)(void *key);
typedef void (*GHashValFreeFP)(void *val);
+typedef void (*GHashKeyValFreeFP)(void *key, void *val);
typedef void *(*GHashKeyCopyFP)(const void *key);
typedef void *(*GHashValCopyFP)(const void *val);
@@ -90,6 +91,7 @@ GHash *BLI_ghash_copy(GHash *gh,
GHashKeyCopyFP keycopyfp,
GHashValCopyFP valcopyfp) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
+void BLI_ghash_free_pair(GHash *gh, GHashKeyValFreeFP keyval_freefp);
void BLI_ghash_reserve(GHash *gh, const unsigned int nentries_reserve);
void BLI_ghash_insert(GHash *gh, void *key, void *val);
bool BLI_ghash_reinsert(
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 1c518cf1487..c91d73879f0 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -655,6 +655,24 @@ static void ghash_free_cb(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP va
}
}
+static void ghash_free_pair_cb(GHash *gh, GHashKeyValFreeFP keyval_freefp)
+{
+ uint i;
+
+ BLI_assert(keyval_freefp);
+ BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
+ if (keyval_freefp == NULL) {
+ return;
+ }
+
+ for (i = 0; i < gh->nbuckets; i++) {
+ Entry *e;
+ for (e = gh->buckets[i]; e; e = e->next) {
+ keyval_freefp(e->key, ((GHashEntry *)e)->val);
+ }
+ }
+}
+
/**
* Copy the GHash.
*/
@@ -1030,6 +1048,18 @@ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreef
MEM_freeN(gh);
}
+void BLI_ghash_free_pair(GHash *gh, GHashKeyValFreeFP keyval_freefp)
+{
+ BLI_assert((int)gh->nentries == BLI_mempool_len(gh->entrypool));
+ if (keyval_freefp) {
+ ghash_free_pair_cb(gh, keyval_freefp);
+ }
+
+ MEM_freeN(gh->buckets);
+ BLI_mempool_destroy(gh->entrypool);
+ MEM_freeN(gh);
+}
+
/**
* Sets a GHash flag.
*/
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index c4358168adb..7b90e53bd92 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -92,6 +92,7 @@ typedef struct SnapObjectData {
SNAP_MESH = 1,
SNAP_EDIT_MESH,
} type;
+ Object_UpdateTag update_link;
} SnapObjectData;
typedef struct SnapObjectData_Mesh {
@@ -190,6 +191,7 @@ static SnapObjectData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, O
else {
SnapObjectData_Mesh *sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
sod->sd.type = SNAP_MESH;
+ BKE_object_runtime_update_tag_add(ob, &sod->sd.update_link);
/* start assuming that it has each of these element types */
sod->has_looptris = true;
sod->has_loose_edge = true;
@@ -227,6 +229,7 @@ static SnapObjectData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext
SnapObjectData_EditMesh *sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena,
sizeof(*sod));
sod->sd.type = SNAP_EDIT_MESH;
+ BKE_object_runtime_update_tag_add(ob, &sod->sd.update_link);
bm_mesh_minmax(em->bm, sod->min, sod->max);
}
@@ -523,7 +526,8 @@ static bool raycastMesh(SnapObjectContext *sctx,
/* The tree is owned by the Mesh and may have been freed since we last used. */
if (treedata->tree) {
BLI_assert(treedata->cached);
- if (!bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree)) {
+ if (!bvhcache_has_tree(me->runtime.bvh_cache, treedata->tree) ||
+ (sod->sd.update_link.flag & OBJECT_UPDATE_FLAG_GEOM)) {
free_bvhtree_from_mesh(treedata);
}
else {
@@ -544,6 +548,8 @@ static bool raycastMesh(SnapObjectContext *sctx,
}
if (treedata->tree == NULL) {
+ sod->sd.update_link.flag &= ~OBJECT_UPDATE_FLAG_GEOM;
+
if (use_hide) {
BKE_bvhtree_from_mesh_get(treedata, me, BVHTREE_FROM_LOOPTRI_NO_HIDDEN, 4);
}
@@ -700,12 +706,15 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
if (sctx->callbacks.edit_mesh.test_face_fn == NULL) {
/* The tree is owned by the Mesh and may have been freed since we last used! */
- if (treedata->tree && !bvhcache_has_tree(*em_bvh_cache, treedata->tree)) {
+ if ((treedata->tree && !bvhcache_has_tree(*em_bvh_cache, treedata->tree)) &&
+ (sod->sd.update_link.flag & OBJECT_UPDATE_FLAG_GEOM)) {
free_bvhtree_from_editmesh(treedata);
}
}
if (treedata->tree == NULL) {
+ sod->sd.update_link.flag &= ~OBJECT_UPDATE_FLAG_GEOM;
+
/* Get original version of the edit_mesh. */
BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob));
@@ -2792,8 +2801,10 @@ SnapObjectContext *ED_transform_snap_object_context_create_view3d(Main *bmain,
return sctx;
}
-static void snap_object_data_free(void *sod_v)
+static void snap_object_data_free(void *ob_v, void *sod_v)
{
+ BKE_object_runtime_update_tag_remove((Object *)ob_v, &((SnapObjectData *)sod_v)->update_link);
+
switch (((SnapObjectData *)sod_v)->type) {
case SNAP_MESH: {
SnapObjectData_Mesh *sod = sod_v;
@@ -2816,7 +2827,7 @@ static void snap_object_data_free(void *sod_v)
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx)
{
- BLI_ghash_free(sctx->cache.object_map, NULL, snap_object_data_free);
+ BLI_ghash_free_pair(sctx->cache.object_map, snap_object_data_free);
if (sctx->cache.data_to_object_map != NULL) {
BLI_ghash_free(sctx->cache.data_to_object_map, NULL, NULL);
}
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index b142939eaeb..3da77e9da3f 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -118,6 +118,17 @@ typedef struct LodLevel {
int obhysteresis;
} LodLevel;
+#
+#
+typedef struct Object_UpdateTag {
+ struct Object_UpdateTag *next;
+ int flag;
+} Object_UpdateTag;
+
+enum {
+ OBJECT_UPDATE_FLAG_GEOM = (1 << 0),
+};
+
struct CustomData_MeshMasks;
/* Not saved in file! */
@@ -182,6 +193,7 @@ typedef struct Object_Runtime {
char _pad4[4];
/** Runtime grease pencil evaluated data created by modifiers */
struct bGPDframe *gpencil_evaluated_frames;
+ struct Object_UpdateTag *update_links;
unsigned short local_collections_bits;
short _pad2[3];
Event Timeline
Campbell Barton (campbellbarton)
created this paste.
Feb 27 2020, 8:02 AM
Campbell Barton (campbellbarton)
mentioned this in
D6927: Transform Snap: Clear 'SnapObjectData' after changes in the geometry
.
Log In to Comment