use modified vertex coords for calculating display thickness and intersections.
authorCampbell Barton <ideasman42@gmail.com>
Thu, 18 Apr 2013 01:20:04 +0000 (01:20 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 18 Apr 2013 01:20:04 +0000 (01:20 +0000)
internal improvement to editmesh_bvh.c

- optionally pass cage-coords as an arg, rather then calculating the coords in BKE_bmbvh_new(),
  since all callers already have coords calculated.
- de-duplicate coords creation function from knife and bmbvhm, move into own generic function: BKE_editmesh_vertexCos_get()

source/blender/blenkernel/BKE_editmesh.h
source/blender/blenkernel/BKE_editmesh_bvh.h
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/editmesh_bvh.c
source/blender/editors/mesh/editmesh_knife.c
source/blender/editors/mesh/editmesh_utils.c
source/blender/editors/transform/transform.c

index 7052cb6012ca85b60793a94fdf9ca3982e9e6902..b18354627abfe6c9b654271a2a09014626187cf1 100644 (file)
@@ -30,6 +30,7 @@ struct BMesh;
 struct BMLoop;
 struct BMFace;
 struct Mesh;
+struct Scene;
 struct DerivedMesh;
 struct MeshStatVis;
 
@@ -87,14 +88,20 @@ typedef struct BMEditMesh {
        int mirror_cdlayer; /* -1 is invalid */
 } BMEditMesh;
 
+/* editmesh.c */
 void        BKE_editmesh_tessface_calc(BMEditMesh *em);
 BMEditMesh *BKE_editmesh_create(BMesh *bm, const bool do_tessellate);
 BMEditMesh *BKE_editmesh_copy(BMEditMesh *em);
 BMEditMesh *BKE_editmesh_from_object(struct Object *ob);
 void        BKE_editmesh_free(BMEditMesh *em);
 void        BKE_editmesh_update_linked_customdata(BMEditMesh *em);
+
+/* editderivedmesh.c */
+/* should really be defined in editmesh.c, but they use 'EditDerivedBMesh' */
 void        BKE_editmesh_statvis_calc(BMEditMesh *em, struct DerivedMesh *dm,
                                       struct MeshStatVis *statvis,
                                       unsigned char (*r_face_colors)[4]);
 
+float (*BKE_editmesh_vertexCos_get(struct BMEditMesh *em, struct Scene *scene, int *r_numVerts))[3];
+
 #endif /* __BKE_EDITMESH_H__ */
index 3ae6c906a87178063df57fb8848a397a194118db..90520c49983f926c26aa48e67393b5712e9e1dd1 100644 (file)
@@ -41,7 +41,7 @@ struct Scene;
 
 typedef struct BMBVHTree BMBVHTree;
 
-BMBVHTree      *BKE_bmbvh_new(struct BMEditMesh *em, int flag, struct Scene *scene);
+BMBVHTree      *BKE_bmbvh_new(struct BMEditMesh *em, int flag, float (*cos_cage)[3], const bool cos_cage_free);
 void            BKE_bmbvh_free(BMBVHTree *tree);
 struct BVHTree *BKE_bmbvh_tree_get(BMBVHTree *tree);
 struct BMFace  *BKE_bmbvh_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3],
@@ -54,10 +54,9 @@ struct BMVert  *BKE_bmbvh_find_vert_closest(BMBVHTree *tree, const float co[3],
 
 /* BKE_bmbvh_new flag parameter */
 enum {
-       BMBVH_USE_CAGE        = 1, /* project geometry onto modifier cage */
-       BMBVH_RETURN_ORIG     = 2, /* use with BMBVH_USE_CAGE, returns hits in relation to original geometry */
-       BMBVH_RESPECT_SELECT  = 4, /* restrict to hidden geometry (overrides BMBVH_RESPECT_HIDDEN) */
-       BMBVH_RESPECT_HIDDEN  = 8  /* omit hidden geometry */
+       BMBVH_RETURN_ORIG     = (1 << 0), /* use with 'cos_cage', returns hits in relation to original geometry */
+       BMBVH_RESPECT_SELECT  = (1 << 1), /* restrict to hidden geometry (overrides BMBVH_RESPECT_HIDDEN) */
+       BMBVH_RESPECT_HIDDEN  = (1 << 2)  /* omit hidden geometry */
 };
 
 #endif  /* __BKE_EDITMESH_BVH_H__ */
index 1f6c99bfaaaa155624a18d0b084efad4fa1e8814..eda8957bb1b4abb63362011967eb8271dbae132d 100644 (file)
@@ -1652,14 +1652,12 @@ static void statvis_calc_thickness(
                }
        }
 
-       (void)vertexCos;
-
        BM_mesh_elem_index_ensure(bm, BM_FACE);
        if (vertexCos) {
                BM_mesh_elem_index_ensure(bm, BM_VERT);
        }
 
-       bmtree = BKE_bmbvh_new(em, 0, NULL);
+       bmtree = BKE_bmbvh_new(em, 0, vertexCos, false);
 
        for (i = 0; i < tottri; i++) {
                BMFace *f_hit;
@@ -1750,14 +1748,12 @@ static void statvis_calc_intersect(
 
        memset(r_face_colors, 64, sizeof(int) * em->bm->totface);
 
-       (void)vertexCos;
-
        BM_mesh_elem_index_ensure(bm, BM_FACE);
        if (vertexCos) {
                BM_mesh_elem_index_ensure(bm, BM_VERT);
        }
 
-       bmtree = BKE_bmbvh_new(em, 0, NULL);
+       bmtree = BKE_bmbvh_new(em, 0, vertexCos, false);
 
        BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
                BMFace *f_hit;
@@ -1839,3 +1835,55 @@ void BKE_editmesh_statvis_calc(BMEditMesh *em, DerivedMesh *dm,
                }
        }
 }
+
+
+
+/* -------------------------------------------------------------------- */
+/* Editmesh Vert Coords */
+
+#include "BLI_bitmap.h"
+struct CageUserData {
+       int totvert;
+       float (*cos_cage)[3];
+       BLI_bitmap visit_bitmap;
+};
+
+static void cage_mapped_verts_callback(void *userData, int index, const float co[3],
+                                       const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
+{
+       struct CageUserData *data = userData;
+
+       if ((index >= 0 && index < data->totvert) && (!BLI_BITMAP_GET(data->visit_bitmap, index))) {
+               BLI_BITMAP_SET(data->visit_bitmap, index);
+               copy_v3_v3(data->cos_cage[index], co);
+       }
+}
+
+float (*BKE_editmesh_vertexCos_get(BMEditMesh *em, Scene *scene, int *r_numVerts))[3]
+{
+       DerivedMesh *cage, *final;
+       BLI_bitmap visit_bitmap;
+       struct CageUserData data;
+       float (*cos_cage)[3];
+
+       cage = editbmesh_get_derived_cage_and_final(scene, em->ob, em, &final, CD_MASK_BAREMESH);
+       cos_cage = MEM_callocN(sizeof(*cos_cage) * em->bm->totvert, "bmbvh cos_cage");
+
+       /* when initializing cage verts, we only want the first cage coordinate for each vertex,
+        * so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate */
+       visit_bitmap = BLI_BITMAP_NEW(em->bm->totvert, __func__);
+
+       data.totvert = em->bm->totvert;
+       data.cos_cage = cos_cage;
+       data.visit_bitmap = visit_bitmap;
+
+       cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data);
+
+       MEM_freeN(visit_bitmap);
+
+       if (r_numVerts) {
+               *r_numVerts = em->bm->totvert;
+       }
+
+       return cos_cage;
+}
index ab5e5373a95a3910d9efa22c8b10ae4f5cd9c68b..2d04ff2071f76a243a31d5cc143d34e3be7f7728 100644 (file)
@@ -34,9 +34,8 @@
 #include "DNA_object_types.h"
 
 #include "BLI_math.h"
-#include "BLI_bitmap.h"
+#include "BLI_kdopbvh.h"
 
-#include "BKE_DerivedMesh.h"
 #include "BKE_editmesh.h"
 
 #include "BKE_editmesh_bvh.h"  /* own include */
@@ -49,46 +48,29 @@ struct BMBVHTree {
        BMesh *bm;
 
        float (*cos_cage)[3];
-       int flag;
-};
+       bool cos_cage_free;
 
-struct CageUserData {
-       int totvert;
-       float (*cos_cage)[3];
-       BLI_bitmap vert_bitmap;
+       int flag;
 };
 
-static void cage_mapped_verts_callback(void *userData, int index, const float co[3],
-                                       const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
-{
-       struct CageUserData *data = userData;
-
-       if ((index >= 0 && index < data->totvert) && (!BLI_BITMAP_GET(data->vert_bitmap, index))) {
-               BLI_BITMAP_SET(data->vert_bitmap, index);
-               copy_v3_v3(data->cos_cage[index], co);
-       }
-}
-
-BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, struct Scene *scene)
+BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, float (*cos_cage)[3], const bool cos_cage_free)
 {
        /* could become argument */
        const float epsilon = FLT_EPSILON * 2.0f;
 
        struct BMLoop *(*looptris)[3] = em->looptris;
        BMBVHTree *bmtree = MEM_callocN(sizeof(*bmtree), "BMBVHTree");
-       DerivedMesh *cage, *final;
-       float cos[3][3], (*cos_cage)[3] = NULL;
+       float cos[3][3];
        int i;
        int tottri;
 
        /* BKE_editmesh_tessface_calc() must be called already */
        BLI_assert(em->tottri != 0 || em->bm->totface == 0);
 
-       /* cage-flag needs scene */
-       BLI_assert(scene || !(flag & BMBVH_USE_CAGE));
-
        bmtree->em = em;
        bmtree->bm = em->bm;
+       bmtree->cos_cage = cos_cage;
+       bmtree->cos_cage_free = cos_cage_free;
        bmtree->flag = flag;
 
        if (flag & (BMBVH_RESPECT_SELECT)) {
@@ -112,29 +94,7 @@ BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, struct Scene *scene)
        }
 
        bmtree->tree = BLI_bvhtree_new(tottri, epsilon, 8, 8);
-       
-       if (flag & BMBVH_USE_CAGE) {
-               BLI_bitmap vert_bitmap;
-               struct CageUserData data;
-
-               cage = editbmesh_get_derived_cage_and_final(scene, em->ob, em, &final, CD_MASK_DERIVEDMESH);
-               cos_cage = MEM_callocN(sizeof(float) * 3 * em->bm->totvert, "bmbvh cos_cage");
-               
-               /* when initializing cage verts, we only want the first cage coordinate for each vertex,
-                * so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate */
-               vert_bitmap = BLI_BITMAP_NEW(em->bm->totvert, __func__);
-
-               data.totvert = em->bm->totvert;
-               data.cos_cage = cos_cage;
-               data.vert_bitmap = vert_bitmap;
-               
-               cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data);
 
-               MEM_freeN(vert_bitmap);
-       }
-       
-       bmtree->cos_cage = cos_cage;
-       
        for (i = 0; i < em->tottri; i++) {
 
                if (flag & BMBVH_RESPECT_SELECT) {
@@ -150,7 +110,7 @@ BMBVHTree *BKE_bmbvh_new(BMEditMesh *em, int flag, struct Scene *scene)
                        }
                }
 
-               if (flag & BMBVH_USE_CAGE) {
+               if (cos_cage) {
                        copy_v3_v3(cos[0], cos_cage[BM_elem_index_get(looptris[i][0]->v)]);
                        copy_v3_v3(cos[1], cos_cage[BM_elem_index_get(looptris[i][1]->v)]);
                        copy_v3_v3(cos[2], cos_cage[BM_elem_index_get(looptris[i][2]->v)]);
@@ -173,8 +133,9 @@ void BKE_bmbvh_free(BMBVHTree *bmtree)
 {
        BLI_bvhtree_free(bmtree->tree);
        
-       if (bmtree->cos_cage)
+       if (bmtree->cos_cage && bmtree->cos_cage_free) {
                MEM_freeN(bmtree->cos_cage);
+       }
        
        MEM_freeN(bmtree);
 }
index 022e753dd40f9c108372c7173a55e207f05f9f46..040a40c470af55560cc166454978007e4fb52967 100644 (file)
@@ -2954,20 +2954,6 @@ static void knifetool_exit(bContext *C, wmOperator *op)
        op->customdata = NULL;
 }
 
-static void cage_mapped_verts_callback(void *userData, int index, const float co[3],
-                                       const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
-{
-       void **data = userData;
-       BMEditMesh *em = data[0];
-       float (*cagecos)[3] = data[1];
-       SmallHash *hash = data[2];
-
-       if (index >= 0 && index < em->bm->totvert && !BLI_smallhash_haskey(hash, index)) {
-               BLI_smallhash_insert(hash, index, NULL);
-               copy_v3_v3(cagecos[index], co);
-       }
-}
-
 static void knifetool_update_mval(KnifeTool_OpData *kcd, const float mval[2])
 {
        knife_recalc_projmat(kcd);
@@ -2990,9 +2976,6 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
 {
        Scene *scene = CTX_data_scene(C);
        Object *obedit = CTX_data_edit_object(C);
-       DerivedMesh *cage, *final;
-       SmallHash shash;
-       void *data[3];
 
        /* assign the drawing handle for drawing preview line... */
        kcd->ob = obedit;
@@ -3004,20 +2987,12 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
 
        BM_mesh_elem_index_ensure(kcd->em->bm, BM_VERT);
 
-       cage = editbmesh_get_derived_cage_and_final(scene, obedit, kcd->em, &final, CD_MASK_DERIVEDMESH);
-       kcd->cagecos = MEM_callocN(sizeof(float) * 3 * kcd->em->bm->totvert, "knife cagecos");
-       data[0] = kcd->em;
-       data[1] = kcd->cagecos;
-       data[2] = &shash;
-
-       BLI_smallhash_init(&shash);
-       cage->foreachMappedVert(cage, cage_mapped_verts_callback, data);
-       BLI_smallhash_release(&shash);
+       kcd->cagecos = BKE_editmesh_vertexCos_get(kcd->em, scene, NULL);
 
        kcd->bmbvh = BKE_bmbvh_new(kcd->em,
-                                 (BMBVH_USE_CAGE | BMBVH_RETURN_ORIG) |
+                                 BMBVH_RETURN_ORIG |
                                  (only_select ? BMBVH_RESPECT_SELECT : BMBVH_RESPECT_HIDDEN),
-                                 scene);
+                                 kcd->cagecos, false);
 
        kcd->arena = BLI_memarena_new(1 << 15, "knife");
        kcd->vthresh = KMAXDIST - 1;
index 01e3ed4f4cb3818dc5793317981032cc3bced9b4..819a8f78e6c86c48d2d572b5532d36b0a6cfdae2 100644 (file)
@@ -1166,7 +1166,7 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_select)
                ED_mesh_mirrtopo_init(me, -1, &mesh_topo_store, true);
        }
        else {
-               tree = BKE_bmbvh_new(em, 0, NULL);
+               tree = BKE_bmbvh_new(em, 0, NULL, false);
        }
 
        BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -1379,6 +1379,8 @@ int EDBM_view3d_poll(bContext *C)
        return 0;
 }
 
+
+
 /* -------------------------------------------------------------------- */
 /* BMBVH functions */
 // XXX
index 487c26aaf546549ba9ed7edb60c91b8f470b5718..ca73405fb168c0c63a06d3445fa71d01e35a5272 100644 (file)
@@ -5176,7 +5176,7 @@ static int createEdgeSlideVerts(TransInfo *t)
        use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE);
 
        if (use_btree_disp) {
-               btree = BKE_bmbvh_new(em, BMBVH_RESPECT_HIDDEN, NULL);
+               btree = BKE_bmbvh_new(em, BMBVH_RESPECT_HIDDEN, NULL, false);
        }
        else {
                btree = NULL;