Commit: 59286ddcf80c391094d64dcbbb94640bf73bd0d9
Author: Germano
Date:   Mon Jul 23 11:04:58 2018 -0300
Branches: blender2.8
https://developer.blender.org/rB59286ddcf80c391094d64dcbbb94640bf73bd0d9

transform_snap_object: Better bvhtree creation management for editing multiple 
objects.

- Use the object referenced in `BMEditMesh` as the `ghash` key to save the 
bvhtrees in cache;
- Create a boundbox around edit_mesh to test the snap before creating bvhtree;
- Save the `edit_mesh`s bvhtree in the mesh bvh_cache;

This is a part of the D3504.

===================================================================

M       source/blender/blenkernel/BKE_bvhutils.h
M       source/blender/blenkernel/intern/bvhutils.c
M       source/blender/editors/transform/transform_snap_object.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_bvhutils.h 
b/source/blender/blenkernel/BKE_bvhutils.h
index d79a7eae53e..a0780a5be54 100644
--- a/source/blender/blenkernel/BKE_bvhutils.h
+++ b/source/blender/blenkernel/BKE_bvhutils.h
@@ -102,7 +102,7 @@ typedef struct BVHTreeFromMesh {
  */
 BVHTree *bvhtree_from_editmesh_verts(
         BVHTreeFromEditMesh *data, struct BMEditMesh *em,
-        float epsilon, int tree_type, int axis);
+        float epsilon, int tree_type, int axis, BVHCache **bvh_cache);
 BVHTree *bvhtree_from_editmesh_verts_ex(
         BVHTreeFromEditMesh *data, struct BMEditMesh *em,
         const BLI_bitmap *mask, int verts_num_active,
@@ -115,7 +115,7 @@ BVHTree *bvhtree_from_mesh_verts_ex(
 
 BVHTree *bvhtree_from_editmesh_edges(
         BVHTreeFromEditMesh *data, struct BMEditMesh *em,
-        float epsilon, int tree_type, int axis);
+        float epsilon, int tree_type, int axis, BVHCache **bvh_cache);
 BVHTree *bvhtree_from_editmesh_edges_ex(
         BVHTreeFromEditMesh *data, struct BMEditMesh *em,
         const BLI_bitmap *edges_mask, int edges_num_active,
@@ -190,7 +190,9 @@ enum {
        BVHTREE_FROM_LOOSEVERTS      = 4,
        BVHTREE_FROM_LOOSEEDGES      = 5,
 
-       BVHTREE_FROM_EM_LOOPTRI      = 6,
+       BVHTREE_FROM_EM_VERTS        = 6,
+       BVHTREE_FROM_EM_EDGES        = 7,
+       BVHTREE_FROM_EM_LOOPTRI      = 8,
 };
 
 
diff --git a/source/blender/blenkernel/intern/bvhutils.c 
b/source/blender/blenkernel/intern/bvhutils.c
index 1a7c4e2a4a0..19ac81b4bb7 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -495,12 +495,39 @@ BVHTree *bvhtree_from_editmesh_verts_ex(
 
 BVHTree *bvhtree_from_editmesh_verts(
         BVHTreeFromEditMesh *data, BMEditMesh *em,
-        float epsilon, int tree_type, int axis)
+        float epsilon, int tree_type, int axis, BVHCache **bvh_cache)
 {
-       return bvhtree_from_editmesh_verts_ex(
-               data, em,
-               NULL, -1,
-               epsilon, tree_type, axis);
+       if (bvh_cache) {
+               BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
+               data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_VERTS, 
&data->tree);
+               BLI_rw_mutex_unlock(&cache_rwlock);
+
+               if (data->cached == false) {
+                       BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+                       data->cached = bvhcache_find(
+                               *bvh_cache, BVHTREE_FROM_EM_VERTS, &data->tree);
+                       if (data->cached == false) {
+                               data->tree = bvhtree_from_editmesh_verts_ex(
+                                       data, em,
+                                       NULL, -1,
+                                       epsilon, tree_type, axis);
+
+                               /* Save on cache for later use */
+                               /* printf("BVHTree built and saved on 
cache\n"); */
+                               bvhcache_insert(
+                                       bvh_cache, data->tree, 
BVHTREE_FROM_EM_VERTS);
+                       }
+                       BLI_rw_mutex_unlock(&cache_rwlock);
+               }
+       }
+       else {
+               data->tree = bvhtree_from_editmesh_verts_ex(
+                       data, em,
+                       NULL, -1,
+                       epsilon, tree_type, axis);
+       }
+
+       return data->tree;
 }
 
 /**
@@ -649,12 +676,39 @@ BVHTree *bvhtree_from_editmesh_edges_ex(
 
 BVHTree *bvhtree_from_editmesh_edges(
         BVHTreeFromEditMesh *data, BMEditMesh *em,
-        float epsilon, int tree_type, int axis)
+        float epsilon, int tree_type, int axis, BVHCache **bvh_cache)
 {
-       return bvhtree_from_editmesh_edges_ex(
-               data, em,
-               NULL, -1,
-               epsilon, tree_type, axis);
+       if (bvh_cache) {
+               BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
+               data->cached = bvhcache_find(*bvh_cache, BVHTREE_FROM_EM_EDGES, 
&data->tree);
+               BLI_rw_mutex_unlock(&cache_rwlock);
+
+               if (data->cached == false) {
+                       BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_WRITE);
+                       data->cached = bvhcache_find(
+                               *bvh_cache, BVHTREE_FROM_EM_EDGES, &data->tree);
+                       if (data->cached == false) {
+                               data->tree = bvhtree_from_editmesh_edges_ex(
+                                       data, em,
+                                       NULL, -1,
+                                       epsilon, tree_type, axis);
+
+                               /* Save on cache for later use */
+                               /* printf("BVHTree built and saved on 
cache\n"); */
+                               bvhcache_insert(
+                                       bvh_cache, data->tree, 
BVHTREE_FROM_EM_EDGES);
+                       }
+                       BLI_rw_mutex_unlock(&cache_rwlock);
+               }
+       }
+       else {
+               data->tree = bvhtree_from_editmesh_edges_ex(
+                       data, em,
+                       NULL, -1,
+                       epsilon, tree_type, axis);
+       }
+
+       return data->tree;
 }
 
 /**
@@ -1407,6 +1461,11 @@ BVHTree *BKE_bvhtree_from_mesh_get(
                                BLI_rw_mutex_unlock(&cache_rwlock);
                        }
                        break;
+               case BVHTREE_FROM_EM_VERTS:
+               case BVHTREE_FROM_EM_EDGES:
+               case BVHTREE_FROM_EM_LOOPTRI:
+                       BLI_assert(false);
+                       break;
        }
 
        if (data_cp.tree != NULL) {
diff --git a/source/blender/editors/transform/transform_snap_object.c 
b/source/blender/editors/transform/transform_snap_object.c
index e19320fa220..b826e72acaf 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -111,6 +111,10 @@ typedef struct SnapObjectData_EditMesh {
        SnapObjectData sd;
        BVHTreeFromEditMesh *bvh_trees[3];
 
+        /* It's like a boundbox. It is tested first to avoid
+         * to create a bvhtree for all the edited objects. */
+       float min[3], max[3];
+
 } SnapObjectData_EditMesh;
 
 struct SnapObjectContext {
@@ -156,6 +160,19 @@ struct SnapObjectContext {
 
 typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, 
Object *ob, float obmat[4][4], void *data);
 
+static void min_max_from_bmesh(
+        BMesh *bm, float r_min[3], float r_max[3])
+{
+       BMIter iter;
+       BMVert *eve;
+
+       INIT_MINMAX(r_min, r_max);
+       BM_ITER_MESH(eve, &iter, bm, BM_VERTS_OF_MESH) {
+               minmax_v3v3_v3(r_min, r_max, eve->co);
+       }
+}
+
+
 /**
  * Walks through all objects in the scene to create the list of objets to snap.
  *
@@ -170,8 +187,8 @@ static void iter_snap_objects(
         void *data)
 {
        ViewLayer *view_layer = DEG_get_evaluated_view_layer(sctx->depsgraph);
-       Object *obedit = params->use_object_edit_cage ? 
OBEDIT_FROM_VIEW_LAYER(view_layer) : NULL;
        const eSnapSelect snap_select = params->snap_select;
+       const bool use_object_edit_cage = params->use_object_edit_cage;
 
        Base *base_act = view_layer->basact;
        for (Base *base = view_layer->object_bases.first; base != NULL; base = 
base->next) {
@@ -179,20 +196,17 @@ static void iter_snap_objects(
                    !((snap_select == SNAP_NOT_SELECTED && ((base->flag & 
BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) ||
                      (snap_select == SNAP_NOT_ACTIVE && base == base_act)))
                {
-                       bool use_obedit;
                        Object *obj = base->object;
                        if (obj->transflag & OB_DUPLI) {
                                DupliObject *dupli_ob;
                                ListBase *lb = 
object_duplilist(sctx->depsgraph, sctx->scene, obj);
                                for (dupli_ob = lb->first; dupli_ob; dupli_ob = 
dupli_ob->next) {
-                                       use_obedit = obedit && 
dupli_ob->ob->data == obedit->data;
-                                       sob_callback(sctx, use_obedit, 
use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data);
+                                       sob_callback(sctx, 
use_object_edit_cage, dupli_ob->ob, dupli_ob->mat, data);
                                }
                                free_object_duplilist(lb);
                        }
 
-                       use_obedit = obedit && obj->data == obedit->data;
-                       sob_callback(sctx, use_obedit, use_obedit ? obedit : 
obj, obj->obmat, data);
+                       sob_callback(sctx, use_object_edit_cage, obj, 
obj->obmat, data);
                }
        }
 }
@@ -378,7 +392,7 @@ static bool raycastMesh(
 
        BVHTreeFromMesh *treedata = &sod->treedata;
 
-       /* The tree is owned by the DM and may have been freed since we last 
used. */
+       /* 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)) {
@@ -502,14 +516,30 @@ static bool raycastEditMesh(
 
        SnapObjectData_EditMesh *sod = NULL;
        BVHTreeFromEditMesh *treedata = NULL;
+       Object *em_ob = em->ob;
 
        void **sod_p;
-       if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
+       /* Use `em->ob` as the key in ghash since the editmesh is used
+        * to create bvhtree and is the same for each linked object. */
+       if (BLI_ghash_ensure_p(sctx->cache.object_map, em_ob, &sod_p)) {
                sod = *sod_p;
        }
        else {
                sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, 
sizeof(*sod));
                sod->sd.type = SNAP_EDIT_MESH;
+               min_max_from_bmesh(em->bm, sod->min, sod->max);
+       }
+
+       {
+               float min[3], max[3];
+               mul_v3_m4v3(min, obmat, sod->min);
+               mul_v3_m4v3(max, obmat, sod->max);
+
+               if (!isect_ray_aabb_v3_simple(
+                       ray_start, ray_dir, min, max, NULL, NULL))
+               {
+                       return retval;
+               }
        }
 
        if (sod->bvh_trees[2] == NULL) {
@@ -517,7 +547,17 @@ static bool raycastEditMesh(
        }
        treedata = sod->bvh_trees[2];
 
+       BVHCache *em_bvh_cache = ((Mesh *)em_ob->data)->runtime.bvh_cache;
+
+       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 (!bvhcache_has_tree(em_bvh_cache, treedata->tree)) {
+                       free_bvhtree_from_editmesh(treedata);
+               }
+       }
+
        if (treedata->tree == NULL) {
+               BVHCache **bvh_cache = NULL;
                BLI_bitmap *elem_mask = NULL;
                int looptri_num_active = -1;
 
@@ -527,7 +567,15 @@ static bool raycastEditMesh(
                                em->bm, elem_mask,
                                sctx->callbacks.edit_mesh.test_face_fn, 
sctx->callbacks.edit_mesh.user_data);
                }
-               bvhtree_from_editmesh_looptri_ex(treedata, em, elem_mask, 
looptri_num_active, 0.0f, 4, 6, NULL);
+               else {
+                       /* Only cache if bvhtree is created without a mask.
+                        * This helps keep a standardized bvhtree in cache. */
+                       bvh_cache = &em_bvh_cache;
+               }
+
+               bvhtree_from_editmesh_looptri_ex(
+                       treedata, em, elem_mask, looptri_num_active,
+                       0.0f, 4, 6, bvh_cache);
 
                if (elem_mask) {
                        MEM_freeN(elem_mask);
@@ -669,7 +717,7 @@ static bool raycastObj(
 
        switch (ob->type) {
                case OB_MESH:
-                       if (use_obedit) {
+                       if (use_obedit && BKE_object_is_in_editmode(ob)) {
                                BMEditMesh *em = BKE_editmesh_from_object(ob);
                                retval = raycastEditMesh(
                                        sctx,
@@ -718,7 +766,7 @@ struct RaycastObjUserData {
        bool ret;
 };
 
-static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object 
*ob, float obmat[4][4], void *data)
+static void raycast_obj_cb(SnapObjectContext *sctx, bool use_obedit, Object 
*ob, float obmat[4][4], void *data)
 {
        struct RaycastObjUserData 

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to