Page MenuHome

Transform Snap: Clear 'SnapObjectData' after changes in the geometry
ClosedPublic

Authored by Germano Cavalcante (mano-wii) on Feb 24 2020, 11:25 PM.

Details

Summary

With tasks like T73993 and D6678, there is a need to use the snap system in Gizmos.
But for this, it is important to find a way to know if the object's geometry has changed before reusing its SnapObjectData.

The solution is to use the em->mesh_eval_... bvh_cache and clear the SnapObjectData cache when the object mode changes.

Diff Detail

Repository
rB Blender
Branch
master
Build Status
Buildable 6897
Build 6897: arc lint + arc unit

Event Timeline

It does sounds like a hack. Instances don't have DrawData for examples. How does this patch is expected to work in this case?

It does sounds like a hack. Instances don't have DrawData for examples. How does this patch is expected to work in this case?

Yes, the original code always takes the original object instead of the instances. It only takes the reference of their matrices.

This sounds like something to put in Object_Runtime, and free in BKE_object_free_derived_caches.

Such data will only be freed on ID_RECALC_GEOMETRY, see ObjectRuntimeBackup::restore_to_object.

  • Follow brecht sugestion and remove DrawData hack

(Update description to come)

Germano Cavalcante (mano-wii) retitled this revision from Transform Snap: Use the DRW_manager API to detect mesh updates to Transform Snap: Reference snap_cache in objet->runtime.
Campbell Barton (campbellbarton) requested changes to this revision.EditedFeb 27 2020, 8:02 AM

There are bvhcache_has_tree checks, why not clear the BVH tree when the mesh is tagged for updating?

Blender 2.7x did this in BKE_object_free_derived_caches via DM_release. We could add this back e.g:

diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 51d397a44bc..a63e24453ad 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -452,6 +452,11 @@ void BKE_object_free_derived_caches(Object *ob)
   BKE_object_to_mesh_clear(ob);
   BKE_object_free_curve_cache(ob);
 
+  if (ob->type == OB_MESH) {
+    /* Used for edit-mode BVH tree, ensure we don't reuse it. */
+    Mesh *me = ob->data;
+    bvhcache_free(&me->runtime.bvh_cache);
+  }
   /* clear grease pencil data */
   DRW_gpencil_freecache(ob);
 }

If this isn't an option for some reason, I'd still rather not use the method proposed in this patch.

It moves away from having the snap context being a view on objects in the scene, to being part of the objects.

This complicates having different kinds of snapping data, for e.g. one snap context may want to have edit-mesh cage data, another context may want to perform operations on the final meshes.

Having g_snap looks like it would complicate having multiple snap contexts at once too, although I didn't look into this in detail.

If all we need to do is know if the dependency graph tagged the object to be updated, we could have a generic way to handle that. e.g: P1275 (untested) (we could make this more generic - reuse depsgraph so users can check for other kinds of updates).

This revision now requires changes to proceed.Feb 27 2020, 8:02 AM

There are bvhcache_has_tree checks, why not clear the BVH tree when the mesh is tagged for updating?

bvhcache_free is already called in BKE_mesh_runtime_clear_geometry. And bvhcache_has_tree is still called in the snap code (although with this patch it would no longer be necessary).
But not all bvhtrees created are saved in the bvh_cache (as is the case of bvhtrees of EditMeshes with custom callback for selection).

In the bvh_cache code, each type of tree has an identifier (BVHTREE_FROM_VERTS, BVHTREE_FROM_EDGES ...), I cannot use one of these identifiers for these custom trees.
(While typing, I just had an idea to create a BVHTREE_UNDEFINED = -1 identifier, this would allow all trees to be saved in the bvhcache. It would be another way to solve the problem).

In the future we could also cache bvhtrees for other types of objects (like Surface), It would be necessary to think of a solution similar to this patch.

If this isn't an option for some reason, I'd still rather not use the method proposed in this patch.

It moves away from having the snap context being a view on objects in the scene, to being part of the objects.

This complicates having different kinds of snapping data, for e.g. one snap context may want to have edit-mesh cage data, another context may want to perform operations on the final meshes.

For final_meshes not really a problem, each mesh has its own bvh_cache.
But I confirm this problem for custom EditMeshes bvhtrees (I thought of solving this in another way when it really becomes a problem).
On the other hand, using a BVHTREE_UNDEFINED identifier would not solve the problem either, it would double the number of identical bvhtrees if they were created with the same callback. (We could solve this using the callback pointer as an identifier).

Having g_snap looks like it would complicate having multiple snap contexts at once too, although I didn't look into this in detail.

g_snap is just a way to clear all snap_caches when they are no longer used. Releases bvhtrees not referenced in bvh_cache.

If all we need to do is know if the dependency graph tagged the object to be updated, we could have a generic way to handle that. e.g: P1275 (untested) (we could make this more generic - reuse depsgraph so users can check for other kinds of updates).

It seems to be a good solution (it would be somewhat more generic), although it would not solve the problem of identical custom bvhtree that was mentioned.

  • Use the mesh_eval bvh_cache
  • Clear cache when object mode changes

Okay, I found a much simpler solution.
I was having problems before because the mesh in object->data is not updated with changes in edit mode.
The solution is to use the editmesh's mesh_eval bvh_cache, as it is modified.

Germano Cavalcante (mano-wii) retitled this revision from Transform Snap: Reference snap_cache in objet->runtime to Transform Snap: Clear 'SnapObjectData' after changes in the geometry.Feb 28 2020, 12:15 AM
Germano Cavalcante (mano-wii) edited the summary of this revision. (Show Details)

This seems reasonable to me, but would rather @Campbell Barton (campbellbarton) does a final check since I think he understands this better.

Optionally we could add a bvh_cache to the BMEditMesh struct.

This revision is now accepted and ready to land.Mar 3 2020, 12:52 AM
This revision is now accepted and ready to land.Mar 3 2020, 2:42 AM
  • add and use a bvh_cache in the BMEditMesh
  • Check changes to recalculate sod->min and sod->max

The previous solution didn't work and we need to recalculate sod->min and sod->max.

  • Revert all
  • rdo first solution (using mesh_eval)