Commit: 5bceb00a61f1cd98c049cc11931550acf08426c7
Author: Campbell Barton
Date:   Thu Mar 13 01:36:24 2014 +1100
https://developer.blender.org/rB5bceb00a61f1cd98c049cc11931550acf08426c7

Mesh API: replace octree mirror with kdtree

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

M       source/blender/editors/include/ED_mesh.h
M       source/blender/editors/mesh/meshtools.c
M       source/blenderplayer/bad_level_call_stubs/stubs.c

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

diff --git a/source/blender/editors/include/ED_mesh.h 
b/source/blender/editors/include/ED_mesh.h
index 04f8dfc..2d7e558 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -300,7 +300,8 @@ void EDBM_redo_state_free(struct BMBackup *, struct 
BMEditMesh *em, int recalcte
 int         join_mesh_exec(struct bContext *C, struct wmOperator *op);
 int         join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op);
 
-intptr_t    mesh_octree_table(struct Object *ob, struct BMEditMesh *em, const 
float co[3], char mode);
+/* mirror lookup api */
+int         mesh_octree_table(struct Object *ob, struct BMEditMesh *em, const 
float co[3], char mode);
 int         mesh_mirrtopo_table(struct Object *ob, char mode);
 
 /* retrieves mirrored cache vert, or NULL if there isn't one.
diff --git a/source/blender/editors/mesh/meshtools.c 
b/source/blender/editors/mesh/meshtools.c
index 1d47d4c..8047959 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -47,6 +47,7 @@
 #include "BLI_blenlib.h"
 
 
+#include "BLI_kdtree.h"
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_deform.h"
@@ -657,245 +658,101 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-/* ********************* MESH VERTEX OCTREE LOOKUP ************* */
+/* -------------------------------------------------------------------- */
+/* Mesh Mirror (Spatial) */
 
-/* important note; this is unfinished, needs better API for editmode, and 
custom threshold */
+/** \name Mesh Spatial Mirror API
+ * \{ */
 
-#define MOC_RES         8
-#define MOC_NODE_RES    8
-#define MOC_THRESH      0.00002f
+#define KD_THRESH      0.00002f
 
-typedef struct MocNode {
-       struct MocNode *next;
-       intptr_t index[MOC_NODE_RES];
-} MocNode;
-
-static int mesh_octree_get_base_offs(const float co[3], const float offs[3], 
const float div[3])
-{
-       int vx, vy, vz;
-       
-       vx = floor((co[0] - offs[0]) / div[0]);
-       vy = floor((co[1] - offs[1]) / div[1]);
-       vz = floor((co[2] - offs[2]) / div[2]);
-
-       CLAMP(vx, 0, MOC_RES - 1);
-       CLAMP(vy, 0, MOC_RES - 1);
-       CLAMP(vz, 0, MOC_RES - 1);
-
-       return (vx * MOC_RES * MOC_RES) + vy * MOC_RES + vz;
-}
-
-static void mesh_octree_add_node(MocNode **bt, intptr_t index)
-{
-       if (*bt == NULL) {
-               *bt = MEM_callocN(sizeof(MocNode), "MocNode");
-               (*bt)->index[0] = index;
-       }
-       else {
-               int a;
-               for (a = 0; a < MOC_NODE_RES; a++) {
-                       if ((*bt)->index[a] == index)
-                               return;
-                       else if ((*bt)->index[a] == 0) {
-                               (*bt)->index[a] = index;
-                               return;
-                       }
-               }
-               mesh_octree_add_node(&(*bt)->next, index);
-       }
-}
-
-static void mesh_octree_free_node(MocNode **bt)
-{
-       if ( (*bt)->next) {
-               mesh_octree_free_node(&(*bt)->next);
-       }
-       MEM_freeN(*bt);
-}
-
-
-/* temporal define, just to make nicer code below */
-#define MOC_INDEX(vx, vy, vz)  (((vx) * MOC_RES * MOC_RES) + (vy) * MOC_RES + 
(vz))
-
-static void mesh_octree_add_nodes(MocNode **basetable, const float co[3], 
const float offs[3],
-                                  const float div[3], intptr_t index)
-{
-       float fx, fy, fz;
-       int vx, vy, vz;
-       
-       if ((finite(co[0]) == false) ||
-           (finite(co[1]) == false) ||
-           (finite(co[2]) == false))
-       {
-               return;
-       }
-       
-       fx = (co[0] - offs[0]) / div[0];
-       fy = (co[1] - offs[1]) / div[1];
-       fz = (co[2] - offs[2]) / div[2];
-       CLAMP(fx, 0.0f, MOC_RES - MOC_THRESH);
-       CLAMP(fy, 0.0f, MOC_RES - MOC_THRESH);
-       CLAMP(fz, 0.0f, MOC_RES - MOC_THRESH);
-
-       vx = (int)floorf(fx);
-       vy = (int)floorf(fy);
-       vz = (int)floorf(fz);
-
-       mesh_octree_add_node(basetable + MOC_INDEX(vx, vy, vz), index);
-
-       if (vx > 0)
-               if (fx - ((float)vx) - MOC_THRESH < 0.0f)
-                       mesh_octree_add_node(basetable + MOC_INDEX(vx - 1, vy, 
vz), index);
-       if (vx < MOC_RES - 2)
-               if (fx - ((float)vx) + MOC_THRESH > 1.0f)
-                       mesh_octree_add_node(basetable + MOC_INDEX(vx + 1, vy, 
vz), index);
-
-       if (vy > 0)
-               if (fy - ((float)vy) - MOC_THRESH < 0.0f)
-                       mesh_octree_add_node(basetable + MOC_INDEX(vx, vy - 1, 
vz), index);
-       if (vy < MOC_RES - 2)
-               if (fy - ((float)vy) + MOC_THRESH > 1.0f)
-                       mesh_octree_add_node(basetable + MOC_INDEX(vx, vy + 1, 
vz), index);
-
-       if (vz > 0)
-               if (fz - ((float)vz) - MOC_THRESH < 0.0f)
-                       mesh_octree_add_node(basetable + MOC_INDEX(vx, vy, vz - 
1), index);
-       if (vz < MOC_RES - 2)
-               if (fz - ((float)vz) + MOC_THRESH > 1.0f)
-                       mesh_octree_add_node(basetable + MOC_INDEX(vx, vy, vz + 
1), index);
-
-}
-
-static intptr_t mesh_octree_find_index(MocNode **bt, MVert *mvert, const float 
co[3])
-{
-       float *vec;
-       int a;
-       
-       if (*bt == NULL)
-               return -1;
-       
-       for (a = 0; a < MOC_NODE_RES; a++) {
-               if ((*bt)->index[a]) {
-                       /* does mesh verts and editmode, code looks potential 
dangerous, octree should really be filled OK! */
-                       if (mvert) {
-                               vec = (mvert + (*bt)->index[a] - 1)->co;
-                               if (compare_v3v3(vec, co, MOC_THRESH))
-                                       return (*bt)->index[a] - 1;
-                       }
-                       else {
-                               BMVert *eve = (BMVert *)((*bt)->index[a]);
-                               if (compare_v3v3(eve->co, co, MOC_THRESH))
-                                       return (*bt)->index[a];
-                       }
-               }
-               else {
-                       return -1;
-               }
-       }
-       if ( (*bt)->next)
-               return mesh_octree_find_index(&(*bt)->next, mvert, co);
-       
-       return -1;
-}
-
-static struct {
-       MocNode **table;
-       float offs[3], div[3];
-} MeshOctree = {NULL, {0, 0, 0}, {0, 0, 0}};
+static struct { void *tree; } MirrKdStore = {NULL};
 
 /* mode is 's' start, or 'e' end, or 'u' use */
 /* if end, ob can be NULL */
-intptr_t mesh_octree_table(Object *ob, BMEditMesh *em, const float co[3], char 
mode)
+int mesh_octree_table(Object *ob, BMEditMesh *em, const float co[3], char mode)
 {
-       MocNode **bt;
-       
        if (mode == 'u') {        /* use table */
-               if (MeshOctree.table == NULL)
+               if (MirrKdStore.tree == NULL)
                        mesh_octree_table(ob, em, NULL, 's');
 
-               if (MeshOctree.table) {
-                       Mesh *me = ob->data;
-                       bt = MeshOctree.table + mesh_octree_get_base_offs(co, 
MeshOctree.offs, MeshOctree.div);
-                       if (em)
-                               return mesh_octree_find_index(bt, NULL, co);
-                       else
-                               return mesh_octree_find_index(bt, me->mvert, 
co);
+               if (MirrKdStore.tree) {
+                       KDTreeNearest nearest;
+
+                       int i;
+
+                       i = BLI_kdtree_find_nearest(MirrKdStore.tree, co, NULL, 
&nearest);
+
+                       if (i != -1) {
+                               if (nearest.dist < KD_THRESH) {
+                                       return i;
+                               }
+                       }
                }
                return -1;
        }
        else if (mode == 's') {   /* start table */
                Mesh *me = ob->data;
-               float min[3], max[3];
+               int totvert;
 
-               /* we compute own bounding box and don't reuse ob->bb because
-                * we are using the undeformed coordinates*/
-               INIT_MINMAX(min, max);
+               if (MirrKdStore.tree) /* happens when entering this call 
without ending it */
+                       mesh_octree_table(ob, em, co, 'e');
 
                if (em && me->edit_btmesh == em) {
-                       BMIter iter;
-                       BMVert *eve;
-                       
-                       BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
-                               minmax_v3v3_v3(min, max, eve->co);
-                       }
+                       totvert = em->bm->totvert;
                }
                else {
-                       MVert *mvert;
-                       int a;
-                       
-                       for (a = 0, mvert = me->mvert; a < me->totvert; a++, 
mvert++)
-                               minmax_v3v3_v3(min, max, mvert->co);
+                       totvert = me->totvert;
                }
-               
-               /* for quick unit coordinate calculus */
-               copy_v3_v3(MeshOctree.offs, min);
-               /* we offset it 1 threshold unit extra */
-               add_v3_fl(MeshOctree.offs, -MOC_THRESH);
-               
-               sub_v3_v3v3(MeshOctree.div, max, min);
-               /* and divide with 2 threshold unit more extra (try 8x8 unit 
grid on paint) */
-               add_v3_fl(MeshOctree.div, 2.0f * MOC_THRESH);
-
-               mul_v3_fl(MeshOctree.div, 1.0f / MOC_RES);
-               if (MeshOctree.div[0] == 0.0f) MeshOctree.div[0] = 1.0f;
-               if (MeshOctree.div[1] == 0.0f) MeshOctree.div[1] = 1.0f;
-               if (MeshOctree.div[2] == 0.0f) MeshOctree.div[2] = 1.0f;
-                       
-               if (MeshOctree.table) /* happens when entering this call 
without ending it */
-                       mesh_octree_table(ob, em, co, 'e');
-               
-               MeshOctree.table = MEM_callocN(MOC_RES * MOC_RES * MOC_RES * 
sizeof(void *), "sym table");
-               
+
+               MirrKdStore.tree = BLI_kdtree_new(totvert);
+
                if (em && me->edit_btmesh == em) {
+
                        BMVert *eve;
                        BMIter iter;
+                       int i;
+
+                       /* this needs to be valid for index lookups later 
(callers need) */
+                       BM_mesh_elem_table_ensure(em->bm, BM_VERT);
 
-                       BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
-                               mesh_octree_add_nodes(MeshOctree.table, 
eve->co, MeshOctree.offs, MeshOctree.div, (intptr_t)(eve));
+                       BM_ITER_MESH_INDEX (eve, &iter, em->bm, 
BM_VERTS_OF_MESH, i) {
+                               BLI_kdtree_insert(MirrKdStore.tree, i, eve->co, 
NULL);
                        }
                }
                else {
                        MVert *mvert;
-                       int a;
+                       int i;
                        
-                       for (a = 0, mvert = me->mvert; a < me->totvert; a++, 
mvert++)
-                               mesh_octree_add_nodes(MeshOctree.table, 
mvert->co, MeshOctree.offs, MeshOctree.div, a + 1);
+                       for (i = 0, mvert = me->mvert; i < me->totvert; i++, 
mvert++) {
+                               BLI_kdtree_insert(MirrKdStore.tree, i, 
mvert->co, NULL);
+                       }
                }
+
+               BLI_kdtree_balance(MirrKdStore.tree);
        }
        else if (mode == 'e') { /* end table */
-               if (MeshOctree.table) {
-                       int a;
-                       
-                       for (a = 0, bt = MeshOctree.table; a < MOC_RES * 
MOC_RES * MOC_RES; a++, bt++) {
-                               if (*bt) mesh_octree_free_node(bt);
-                       }
-                       MEM_freeN(MeshOctree.table);
-                       MeshOctree.table = NULL;
+               if (MirrKdStore.tree) {
+                       BLI_kdtree_free(MirrKdStore.tree);
+                       MirrKdStore.tree = NULL;
                }
        }
+       else {
+               BLI_assert(0);
+       }
+
        return 0;
 }
 
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/* Mesh Mirror (Topology) */
+
+/** \name Mesh Topology Mirror API
+ * \{ */
+
 static MirrTopoStore_t mesh_topo_store = {NULL, -1. - 1, -1};
 
 /* mode is 's' start, or 'e' end, or 'u' use */
@@ -914,9 +771,16 @@ int mesh_mirrtopo_table(Object *ob, char mode)
        else if (mode == 'e') { /* end table */
                ED_mesh_mirrtopo_free(&mesh_topo_store);
        }
+       else {
+               BLI_assert(0);
+       }
+
        return 0;
 }
 
+/** \} */
+
+
 static int mesh_get_x_mirror_vert_spatial(Object *ob, int index)
 {
        Mesh *me = ob->data;
@@ -952,7 +816,7 @@ int mesh_get_x_mirror_vert(Object *ob, int index, const 
bool use_topology)
 static BMVert *editbmesh_get_x_mirror_vert_spatial(Object *ob, BMEditMesh *em, 
const float co[3])
 {
        float vec[3];
-       intptr_t poinval;
+       int i;
        
        /* ignore nan verts */
        if ((finite(co[0]) == false) ||
@@ -

@@ Diff output truncated at 10240 characters. @@

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

Reply via email to