Revision: 40870
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40870
Author:   ender79
Date:     2011-10-09 03:05:36 +0000 (Sun, 09 Oct 2011)
Log Message:
-----------
Refactor removedoubles (merge 3 different version of code to find doubles into 
one). Also fixes a minor bug where automerge would merge any two vertices (not 
just selected verts into unselected verts like trunk) and fixes the edge slide 
crash (bug 28688)

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/operators/removedoubles.c
    branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c

Modified: branches/bmesh/blender/source/blender/bmesh/operators/removedoubles.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/operators/removedoubles.c       
2011-10-09 02:24:51 UTC (rev 40869)
+++ branches/bmesh/blender/source/blender/bmesh/operators/removedoubles.c       
2011-10-09 03:05:36 UTC (rev 40870)
@@ -445,76 +445,17 @@
        }
 }
 
-void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op)
+void bmesh_finddoubles_common(BMesh *bm, BMOperator *op, BMOperator *optarget, 
const char *targetmapname)
 {
-       BMOperator weldop;
        BMOIter oiter;
        BMVert *v, *v2;
        BMVert **verts=NULL;
        BLI_array_declare(verts);
-       float dist, distsqr;
-       int i, j, len;
-
-       dist = BMO_Get_Float(op, "dist");
-       distsqr = dist*dist;
-
-       BMO_Init_Op(&weldop, "weldverts");
-       
-       i = 0;
-       BMO_ITER(v, &oiter, bm, op, "verts", BM_VERT) {
-               BLI_array_growone(verts);
-               verts[i++] = v;
-       }
-
-       /*sort by vertex coordinates added together*/
-       qsort(verts, BLI_array_count(verts), sizeof(void*), vergaverco);
-       
-       len = BLI_array_count(verts);
-       for (i=0; i<len; i++) {
-               v = verts[i];
-               if (BMO_TestFlag(bm, v, VERT_TESTED)) continue;
-               
-               BMO_SetFlag(bm, v, VERT_TESTED);
-               for (j=i+1; j<len; j++) {
-                       float vec[3];
-                       
-                       v2 = verts[j];
-                       //if ((v2->co[0]+v2->co[1]+v2->co[2]) - 
(v->co[0]+v->co[1]+v->co[2])
-                       //     > dist) break;
-                       if ((v2->co[0]-v->co[0]) + (v2->co[1]-v->co[1]) + 
(v2->co[2]-v->co[2]) > dist)
-                               break;
-
-                       vec[0] = v->co[0] - v2->co[0];
-                       vec[1] = v->co[1] - v2->co[1];
-                       vec[2] = v->co[2] - v2->co[2];
-                       
-                       if (INPR(vec, vec) < distsqr) {
-                               BMO_SetFlag(bm, v2, VERT_TESTED);
-                               BMO_SetFlag(bm, v2, VERT_DOUBLE);
-                               BMO_SetFlag(bm, v, VERT_TARGET);
-                       
-                               BMO_Insert_MapPointer(bm, &weldop, "targetmap", 
v2, v);
-                       }
-               }
-       }
-
-       BLI_array_free(verts);
-
-       BMO_Exec_Op(bm, &weldop);
-       BMO_Finish_Op(bm, &weldop);
-}
-
-
-void bmesh_finddoubles_exec(BMesh *bm, BMOperator *op)
-{
-       BMOIter oiter;
-       BMVert *v, *v2;
-       BMVert **verts=NULL;
-       BLI_array_declare(verts);
-       float dist;
+       float dist, dist3;
        int i, j, len, keepvert;
 
        dist = BMO_Get_Float(op, "dist");
+       dist3 = dist * 3.0f;
 
        i = 0;
        BMO_ITER(v, &oiter, bm, op, "verts", BM_VERT) {
@@ -536,7 +477,11 @@
                
                for (j=i+1; j<len; j++) {
                        v2 = verts[j];
-                       if ((v2->co[0]+v2->co[1]+v2->co[2]) - 
(v->co[0]+v->co[1]+v->co[2]) > dist)
+
+                       /* Compare sort values of the verts using 3x tolerance 
(allowing for the tolerance
+                          on each of the three axes). This avoids the more 
expensive length comparison
+                          for most vertex pairs. */
+                       if 
((v2->co[0]+v2->co[1]+v2->co[2])-(v->co[0]+v->co[1]+v->co[2]) > dist3)
                                break;
 
                        if (keepvert) {
@@ -545,10 +490,16 @@
                        }
 
                        if (compare_len_v3v3(v->co, v2->co, dist)) {
+
+                               /* If one vert is marked as keep, make sure it 
will be the target */
+                               if (BMO_TestFlag(bm, v2, VERT_KEEP)) {
+                                       SWAP(BMVert *, v, v2);
+                               }
+
                                BMO_SetFlag(bm, v2, VERT_DOUBLE);
                                BMO_SetFlag(bm, v, VERT_TARGET);
                        
-                               BMO_Insert_MapPointer(bm, op, "targetmapout", 
v2, v);
+                               BMO_Insert_MapPointer(bm, optarget, 
targetmapname, v2, v);
                        }
                }
        }
@@ -556,56 +507,49 @@
        BLI_array_free(verts);
 }
 
-void bmesh_automerge_exec(BMesh *bm, BMOperator *op)
+void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op)
 {
-       BMOIter oiter;
        BMOperator weldop;
-       BMVert *v, *v2;
-       BMVert **verts=NULL;
-       BLI_array_declare(verts);
-       float dist;
-       int i, j, len /* , keepvert */;
 
-       dist = BMO_Get_Float(op, "dist");
-
-       i = 0;
-       BMO_ITER(v, &oiter, bm, op, "verts", BM_VERT) {
-               BLI_array_growone(verts);
-               verts[i++] = v;
-       }
-
        BMO_Init_Op(&weldop, "weldverts");
+       bmesh_finddoubles_common(bm, op, &weldop, "targetmap");
+       BMO_Exec_Op(bm, &weldop);
+       BMO_Finish_Op(bm, &weldop);
+}
 
-       /*sort by vertex coordinates added together*/
-       qsort(verts, BLI_array_count(verts), sizeof(void*), vergaverco);
-       
-       BMO_Flag_Buffer(bm, op, "verts", VERT_KEEP, BM_VERT);
 
-       len = BLI_array_count(verts);
-       for (i=0; i<len; i++) {
-               v = verts[i];
-               if (BMO_TestFlag(bm, v, VERT_DOUBLE)) continue;
-               
-               for (j=i+1; j<len; j++) {
-                       v2 = verts[j];
-                       if ((v2->co[0]+v2->co[1]+v2->co[2]) - 
(v->co[0]+v->co[1]+v->co[2])
-                            > dist) break;
-                       
-                       /* only allow unselected -> selected */
-                       if (BMO_TestFlag(bm, v2, VERT_IN))
-                               continue;
+void bmesh_finddoubles_exec(BMesh *bm, BMOperator *op)
+{
+       bmesh_finddoubles_common(bm, op, op, "targetmapout");
+}
 
-                       if (compare_len_v3v3(v->co, v2->co, dist)) {
-                               BMO_SetFlag(bm, v2, VERT_DOUBLE);
-                               BMO_SetFlag(bm, v, VERT_TARGET);
-                       
-                               BMO_Insert_MapPointer(bm, &weldop, "targetmap", 
v2, v);
-                       }
+void bmesh_automerge_exec(BMesh *bm, BMOperator *op)
+{
+       BMOperator findop, weldop;
+       BMIter viter;
+       BMVert *v;
+
+       /* The "verts" input sent to this op is the set of verts that
+          can be merged away into any other verts. Mark all other verts
+          as VERT_KEEP. */
+       BMO_Flag_Buffer(bm, op, "verts", VERT_IN, BM_VERT);
+       BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
+               if (!BMO_TestFlag(bm, v, VERT_IN)) {
+                       BMO_SetFlag(bm, v, VERT_KEEP);
                }
        }
 
+       /* Search for doubles among all vertices, but only merge non-VERT_KEEP
+          vertices into VERT_KEEP vertices. */
+       BMO_InitOpf(bm, &findop, "finddoubles verts=%av keepverts=%fv", 
VERT_KEEP);
+       BMO_CopySlot(op, &findop, "dist", "dist");
+       BMO_Exec_Op(bm, &findop);
+
+       /* weld the vertices */
+       BMO_Init_Op(&weldop, "weldverts");
+       BMO_CopySlot(&findop, &weldop, "targetmapout", "targetmap");
        BMO_Exec_Op(bm, &weldop);
-       BMO_Finish_Op(bm, &weldop);
 
-       BLI_array_free(verts);
+       BMO_Finish_Op(bm, &findop);
+       BMO_Finish_Op(bm, &weldop);
 }

Modified: branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c
===================================================================
--- branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c   
2011-10-09 02:24:51 UTC (rev 40869)
+++ branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c   
2011-10-09 03:05:36 UTC (rev 40870)
@@ -130,7 +130,7 @@
                if (!em)
                        return;
 
-               BMO_CallOpf(em->bm, "automerge verts=%av dist=%f", 
scene->toolsettings->doublimit);
+               BMO_CallOpf(em->bm, "automerge verts=%hv dist=%f", BM_SELECT, 
scene->toolsettings->doublimit);
                if (update) {
                        DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
                }

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

Reply via email to