alt-ctrl leftmouse (e.g. current knife) now uses bmesh edge subdivide! wa-hoo! basica...
authorJoseph Eagar <joeedh@gmail.com>
Sun, 8 Feb 2009 17:01:28 +0000 (17:01 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sun, 8 Feb 2009 17:01:28 +0000 (17:01 +0000)
source/blender/bmesh/bmesh_operators.h
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_operators.c
source/blender/bmesh/operators/subdivideop.c
source/blender/bmesh/operators/triangulateop.c
source/blender/editors/mesh/editmesh_loop.c
source/blender/editors/mesh/mesh_ops.c

index 9f0d6cb1c8c1b5ef5b24d0ef529becae8376a09a..3debb0cbede29d78cc9a7c030e0c2961818a3fab 100644 (file)
@@ -62,6 +62,7 @@ void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op, int
 void BMO_Set_Float(struct BMOperator *op, int slotcode, float f);
 void BMO_Set_Int(struct BMOperator *op, int slotcode, int i);
 void BMO_Set_PntBuf(struct BMOperator *op, int slotcode, void *p, int len);
+void BMO_Set_FltBuf(BMOperator *op, int slotcode, float *p, int len);
 void BMO_Set_Pnt(struct BMOperator *op, int slotcode, void *p);
 void BMO_Set_Vec(struct BMOperator *op, int slotcode, float *vec);
 void BMO_SetFlag(struct BMesh *bm, void *element, int flag);
@@ -161,7 +162,7 @@ enum {
        BMOP_ESUBDIVIDE_CUSTOMFILL_FACES,
        BMOP_ESUBDIVIDE_CUSTOMFILL_PATTERNS,
 
-       BMOP_ESUBDIVIDE_PERCENT_VERTS,
+       BMOP_ESUBDIVIDE_PERCENT_EDGES,
        BMOP_ESUBDIVIDE_PERCENT_VALUES,
 
        BMOP_ESUBDIVIDE_TOTSLOT,
index ac13f8319a6453e7fcdc2614ae85949dad30061c..b26b594037586d174b4e10d3d95fda2aa31e7510 100644 (file)
@@ -42,7 +42,7 @@ BMOpDefine def_subdop = {
         BMOP_OPSLOT_PNT_BUF,
         BMOP_OPSLOT_PNT_BUF,
         BMOP_OPSLOT_PNT_BUF,
-        BMOP_OPSLOT_FLT},
+        BMOP_OPSLOT_FLT_BUF},
        esubdivide_exec,
        BMOP_ESUBDIVIDE_TOTSLOT,
        0
index 5be0ec881c0132a266f204b53bd8181720d76293..f58c2d6c0cbc05b56370d2b4d332e1c27da21fee 100644 (file)
@@ -212,6 +212,15 @@ void BMO_Set_PntBuf(BMOperator *op, int slotcode, void *p, int len)
        op->slots[slotcode].len = len;
 }
 
+void BMO_Set_FltBuf(BMOperator *op, int slotcode, float *p, int len)
+{
+       if( !(op->slots[slotcode].slottype == BMOP_OPSLOT_FLT_BUF) )
+               return;
+
+       op->slots[slotcode].data.p = p;
+       op->slots[slotcode].len = len;
+}
+
 void BMO_Set_Pnt(BMOperator *op, int slotcode, void *p)
 {
        if( !(op->slots[slotcode].slottype == BMOP_OPSLOT_PNT) )
index 076f47786ba6ae4c505de176351808cb04e42333..810ecd10319979f3efb1e5bf49b29e081ab23f2b 100644 (file)
@@ -21,6 +21,8 @@
 
 #define SUBD_SPLIT     1
 
+#define EDGE_PERCENT   2
+
 /*I don't think new faces are flagged, currently, but
   better safe than sorry.*/
 #define FACE_NEW       2
@@ -48,12 +50,12 @@ NOTE: beauty has been renamed to flag!
 */
 
 /* calculates offset for co, based on fractal, sphere or smooth settings  */
-static void alter_co(float *co, BMEdge *edge, float rad, int flag, float perc,
+static void alter_co(float *co, BMEdge *edge, subdparams *params, float perc,
                     BMVert *vsta, BMVert *vend)
 {
        float vec1[3], fac;
        
-       if(flag & B_SMOOTH) {
+       if(params->flag & B_SMOOTH) {
                /* we calculate an offset vector vec1[], to be added to *co */
                float len, fac, nor[3], nor1[3], nor2[3];
                
@@ -77,23 +79,23 @@ static void alter_co(float *co, BMEdge *edge, float rad, int flag, float perc,
                vec1[1]+= fac*nor2[1];
                vec1[2]+= fac*nor2[2];
                
-               vec1[0]*= rad*len;
-               vec1[1]*= rad*len;
-               vec1[2]*= rad*len;
+               vec1[0]*= params->rad*len;
+               vec1[1]*= params->rad*len;
+               vec1[2]*= params->rad*len;
                
                co[0] += vec1[0];
                co[1] += vec1[1];
                co[2] += vec1[2];
        }
        else {
-               if(rad > 0.0) {   /* subdivide sphere */
+               if(params->rad > 0.0) {   /* subdivide sphere */
                        Normalize(co);
-                       co[0]*= rad;
-                       co[1]*= rad;
-                       co[2]*= rad;
+                       co[0]*= params->rad;
+                       co[1]*= params->rad;
+                       co[2]*= params->rad;
                }
-               else if(rad< 0.0) {  /* fractal subdivide */
-                       fac= rad* VecLenf(vsta->co, vend->co);
+               else if(params->rad< 0.0) {  /* fractal subdivide */
+                       fac= params->rad* VecLenf(vsta->co, vend->co);
                        vec1[0]= fac*(float)(0.5-BLI_drand());
                        vec1[1]= fac*(float)(0.5-BLI_drand());
                        vec1[2]= fac*(float)(0.5-BLI_drand());
@@ -106,18 +108,18 @@ static void alter_co(float *co, BMEdge *edge, float rad, int flag, float perc,
 /* assumes in the edge is the correct interpolated vertices already */
 /* percent defines the interpolation, rad and flag are for special options */
 /* results in new vertex with correct coordinate, vertex normal and weight group info */
-static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge, float rad, 
-                                        int flag, float percent, BMEdge **out,
-                                        BMVert *vsta, BMVert *vend)
+static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge, 
+                                       subdparams *params, float percent, 
+                                       BMEdge **out,BMVert *vsta,BMVert *vend)
 {
        BMVert *ev;
 //     float co[3];
        
        ev = BM_Split_Edge(bm, edge->v1, edge, out, percent, 1);
-       if (flag & SELTYPE_INNER) BM_Select_Vert(bm, ev, 1);
+       if (params->flag & SELTYPE_INNER) BM_Select_Vert(bm, ev, 1);
 
        /* offset for smooth or sphere or fractal */
-       alter_co(ev->co, edge, rad, flag, percent, vsta, vend);
+       alter_co(ev->co, edge, params, percent, vsta, vend);
 
 #if 0 //TODO
        /* clip if needed by mirror modifier */
@@ -138,48 +140,33 @@ static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge, float rad,
 }
 
 static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, 
-                               int curpoint, int totpoint, float rad, 
-                               int flag, BMEdge **newe,
-                               BMVert *vsta, BMVert *vend)
+                               int curpoint, int totpoint, subdparams *params,
+                               BMEdge **newe, BMVert *vsta, BMVert *vend)
 {
        BMVert *ev;
        float percent;
         
-       if (flag & (B_PERCENTSUBD) && totpoint == 1)
-               /*I guess the idea is vertices store what
-                 percent to use?*/
-               //percent=(float)(edge->tmp.l)/32768.0f;
-               percent= 1.0; //edge->tmp.fp;
+       if (BMO_TestFlag(bm, edge, EDGE_PERCENT) && totpoint == 1)
+               percent= *((float*)BLI_ghash_lookup(params->percenthash,edge));
        else {
                percent= 1.0f/(float)(totpoint+1-curpoint);
 
        }
        
-       /*{
-               float co[3], co2[3];
-               VecSubf(co, edge->v2->co, edge->v1->co);
-               VecMulf(co, 1.0f/(float)(totpoint+1-curpoint));
-               VecAddf(co2, edge->v1->co, co);
-*/
-               ev= bm_subdivide_edge_addvert(bm, edge, rad, flag, percent, 
-                                      newe, vsta, vend);
-               
-/*             VECCOPY(ev->co, co2);
-       }
-*/     
+       ev= bm_subdivide_edge_addvert(bm, edge, params, percent, 
+                                     newe, vsta, vend);
        return ev;
 }
 
-static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, float rad,
-                                 int flag, int numcuts, 
+static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, subdparams *params, 
                                  BMVert *vsta, BMVert *vend) {
        BMEdge *eed = edge, *newe;
        BMVert *v;
-       int i;
+       int i, numcuts = params->numcuts;
 
        for(i=0;i<numcuts;i++) {
-               v = subdivideedgenum(bm, eed, i, numcuts, rad
-                       flag, &newe, vsta, vend);
+               v = subdivideedgenum(bm, eed, i, params->numcuts, params
+                                    &newe, vsta, vend);
                BMO_SetFlag(bm, v, SUBD_SPLIT);
                BMO_SetFlag(bm, eed, SUBD_SPLIT);
        }
@@ -199,28 +186,28 @@ v3---------v2
 v4---v0---v1
 
 */
-static void q_1edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
-                         int flag, float rad) {
+static void q_1edge_split(BMesh *bm, BMFace *face,
+                         BMVert **verts, subdparams *params) {
        BMFace *nf;
-       int i, add;
+       int i, add, numcuts = params->numcuts;
 
        /*if it's odd, the middle face is a quad, otherwise it's a triangle*/
        if (numcuts % 2==0) {
                add = 2;
                for (i=0; i<numcuts; i++) {
                        if (i == numcuts/2) add -= 1;
-                       BM_Connect_Verts(bm, vlist[i], vlist[numcuts+add], 
+                       BM_Connect_Verts(bm, verts[i], verts[numcuts+add], 
                                           &nf);
                }
        } else {
                add = 2;
                for (i=0; i<numcuts; i++) {
-                       BM_Connect_Verts(bm, vlist[i], vlist[numcuts+add], 
+                       BM_Connect_Verts(bm, verts[i], verts[numcuts+add], 
                                           &nf);
                        if (i == numcuts/2) {
                                add -= 1;
-                               BM_Connect_Verts(bm, vlist[i], 
-                                                  vlist[numcuts+add],
+                               BM_Connect_Verts(bm, verts[i], 
+                                                  verts[numcuts+add],
                                                   &nf);
                        }
                }
@@ -246,13 +233,14 @@ v5---v0---v1
 
 */
 
-static void q_2edge_op_split(BMesh *bm, BMFace *face, BMVert **vlist, 
-                            int numcuts, int flag, float rad) {
+static void q_2edge_op_split(BMesh *bm, BMFace *face, BMVert **verts, 
+                             subdparams *params)
+{
        BMFace *nf;
-       int i;
+       int i, numcuts = params->numcuts;
        
        for (i=0; i<numcuts; i++) {
-               BM_Connect_Verts(bm, vlist[i],vlist[(numcuts-i-1)+numcuts+2],
+               BM_Connect_Verts(bm, verts[i],verts[(numcuts-i-1)+numcuts+2],
                                   &nf);
        }
 }
@@ -272,16 +260,17 @@ v6--------v5
 v7-v0--v1-v2
 
 */
-static void q_2edge_split(BMesh *bm, BMFace *face, BMVert **vlist, 
-                            int numcuts, int flag, float rad) {
+static void q_2edge_split(BMesh *bm, BMFace *face, BMVert **verts, 
+                          subdparams *params)
+{
        BMFace *nf;
-       int i;
+       int i, numcuts = params->numcuts;
        
        for (i=0; i<numcuts; i++) {
-               BM_Connect_Verts(bm, vlist[i], vlist[numcuts+(numcuts-i)],
+               BM_Connect_Verts(bm, verts[i], verts[numcuts+(numcuts-i)],
                                   &nf);
        }
-       BM_Connect_Verts(bm, vlist[numcuts*2+3], vlist[numcuts*2+1], &nf);
+       BM_Connect_Verts(bm, verts[numcuts*2+3], verts[numcuts*2+1], &nf);
 }
 
 subdpattern q_2edge = {
@@ -300,25 +289,26 @@ v8--v7--v6-v5
 v9-v0--v1-v2
 
 */
-static void q_3edge_split(BMesh *bm, BMFace *face, BMVert **vlist, 
-                            int numcuts, int flag, float rad) {
+static void q_3edge_split(BMesh *bm, BMFace *face, BMVert **verts, 
+                          subdparams *params)
+{
        BMFace *nf;
-       int i, add=0;
+       int i, add=0, numcuts = params->numcuts;
        
        for (i=0; i<numcuts; i++) {
                if (i == numcuts/2) {
                        if (numcuts % 2 != 0) {
-                               BM_Connect_Verts(bm, vlist[numcuts-i-1+add], 
-                                                vlist[i+numcuts+1], &nf);
+                               BM_Connect_Verts(bm, verts[numcuts-i-1+add], 
+                                                verts[i+numcuts+1], &nf);
                        }
                        add = numcuts*2+2;
                }
-               BM_Connect_Verts(bm, vlist[numcuts-i-1+add], 
-                                    vlist[i+numcuts+1], &nf);
+               BM_Connect_Verts(bm, verts[numcuts-i-1+add], 
+                                    verts[i+numcuts+1], &nf);
        }
 
        for (i=0; i<numcuts/2+1; i++) {
-               BM_Connect_Verts(bm, vlist[i],vlist[(numcuts-i)+numcuts*2+1],
+               BM_Connect_Verts(bm, verts[i],verts[(numcuts-i)+numcuts*2+1],
                                   &nf);
        }
 }
@@ -340,27 +330,30 @@ first line |          |   last line
 
           it goes from bottom up
 */
-static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
-                         int flag, float rad) {
+static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **verts, 
+                          subdparams *params)
+{
        BMFace *nf;
        BMVert *v, *v1, *v2;
        BMEdge *e, *ne;
-       BMVert **lines = MEM_callocN(sizeof(BMVert*)*(numcuts+2)*(numcuts+2),
-                                    "q_4edge_split");
+       BMVert **lines;
+       int numcuts = params->numcuts;
        int i, j, a, b, s=numcuts+2, totv=numcuts*4+4;
 
+       lines = MEM_callocN(sizeof(BMVert*)*(numcuts+2)*(numcuts+2),
+                                    "q_4edge_split");
        /*build a 2-dimensional array of verts,
          containing every vert (and all new ones)
          in the face.*/
 
        /*first line*/
        for (i=0; i<numcuts+2; i++) {
-               lines[i] = vlist[numcuts*3+2+(numcuts-i+1)];
+               lines[i] = verts[numcuts*3+2+(numcuts-i+1)];
        }
 
        /*last line*/
        for (i=0; i<numcuts+2; i++) {
-               lines[(s-1)*s+i] = vlist[numcuts+i];
+               lines[(s-1)*s+i] = verts[numcuts+i];
        }
        
        /*first and last members of middle lines*/
@@ -368,19 +361,19 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
                a = i;
                b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1);
                
-               e = BM_Connect_Verts(bm, vlist[a], vlist[b], &nf);
-               if (flag & SELTYPE_INNER) {
+               e = BM_Connect_Verts(bm, verts[a], verts[b], &nf);
+               if (params->flag & SELTYPE_INNER) {
                        BM_Select_Edge(bm, e, 1);
                        BM_Select_Face(bm, nf, 1);
                }
                
-               v1 = lines[(i+1)*s] = vlist[a];
-               v2 = lines[(i+1)*s + s-1] = vlist[b];
+               v1 = lines[(i+1)*s] = verts[a];
+               v2 = lines[(i+1)*s + s-1] = verts[b];
 
                for (a=0; a<numcuts; a++) {
-                       v = subdivideedgenum(bm, e, a, numcuts, rad, flag, &ne,
+                       v = subdivideedgenum(bm, e, a, numcuts, params, &ne,
                                             v1, v2);
-                       if (flag & SELTYPE_INNER) {
+                       if (params->flag & SELTYPE_INNER) {
                                BM_Select_Edge(bm, ne, 1);
                        }
                        lines[(i+1)*s+a+1] = v;
@@ -392,7 +385,7 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
                        a = i*s + j;
                        b = (i-1)*s + j;
                        e = BM_Connect_Verts(bm, lines[a], lines[b], &nf);
-                       if (flag & SELTYPE_INNER) {
+                       if (params->flag & SELTYPE_INNER) {
                                BM_Select_Edge(bm, e, 1);
                                BM_Select_Face(bm, nf, 1);
                        }
@@ -411,13 +404,14 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
 v4--v0--v1--v2
     s    s
 */
-static void t_1edge_split(BMesh *bm, BMFace *face, BMVert **vlist, 
-                            int numcuts, int flag, float rad) {
+static void t_1edge_split(BMesh *bm, BMFace *face, BMVert **verts, 
+                          subdparams *params)
+{
        BMFace *nf;
-       int i;
+       int i, numcuts = params->numcuts;
        
        for (i=0; i<numcuts; i++) {
-               BM_Connect_Verts(bm, vlist[i], vlist[numcuts+1], &nf);
+               BM_Connect_Verts(bm, verts[i], verts[numcuts+1], &nf);
        }
 }
 
@@ -436,13 +430,14 @@ subdpattern t_1edge = {
 v6--v0--v1--v2
     s   s
 */
-static void t_2edge_split(BMesh *bm, BMFace *face, BMVert **vlist, 
-                            int numcuts, int flag, float rad) {
+static void t_2edge_split(BMesh *bm, BMFace *face, BMVert **verts, 
+                          subdparams *params)
+{
        BMFace *nf;
-       int i;
+       int i, numcuts = params->numcuts;
        
        for (i=0; i<numcuts; i++) {
-               BM_Connect_Verts(bm, vlist[i], vlist[numcuts+numcuts-i], &nf);
+               BM_Connect_Verts(bm, verts[i], verts[numcuts+numcuts-i], &nf);
        }
 }
 
@@ -462,49 +457,50 @@ sv7/---v---\ v3 s
  v8--v0--v1--v2
     s    s
 */
-static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **vlist, 
-                            int numcuts, int flag, float rad) {
+static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **verts, 
+                          subdparams *params)
+{
        BMFace *nf;
        BMEdge *e, *ne;
        BMVert ***lines, *v;
        void *stackarr[1];
-       int i, j, a, b;
+       int i, j, a, b, numcuts = params->numcuts;
        
        /*number of verts in each line*/
        lines = MEM_callocN(sizeof(void*)*(numcuts+2), "triangle vert table");
        
        lines[0] = (BMVert**) stackarr;
-       lines[0][0] = vlist[numcuts*2+1];
+       lines[0][0] = verts[numcuts*2+1];
        
        lines[1+numcuts] = MEM_callocN(sizeof(void*)*(numcuts+2), 
                                       "triangle vert table 2");
        for (i=0; i<numcuts; i++) {
-               lines[1+numcuts][1+i] = vlist[i];
+               lines[1+numcuts][1+i] = verts[i];
        }
-       lines[1+numcuts][0] = vlist[numcuts*3+2];
-       lines[1+numcuts][1+numcuts] = vlist[numcuts];
+       lines[1+numcuts][0] = verts[numcuts*3+2];
+       lines[1+numcuts][1+numcuts] = verts[numcuts];
 
        for (i=0; i<numcuts; i++) {
                lines[i+1] = MEM_callocN(sizeof(void*)*(2+i), 
                                       "triangle vert table row");
                a = numcuts*2 + 2 + i;
                b = numcuts + numcuts - i;
-               e = BM_Connect_Verts(bm, vlist[a], vlist[b], &nf);
+               e = BM_Connect_Verts(bm, verts[a], verts[b], &nf);
                
-               if (flag & SELTYPE_INNER) {
+               if (params->flag & SELTYPE_INNER) {
                        BM_Select_Edge(bm, e, 1);
                        BM_Select_Face(bm, nf, 1);
                }
 
-               lines[i+1][0] = vlist[a];
-               lines[i+1][1+i] = vlist[b];
+               lines[i+1][0] = verts[a];
+               lines[i+1][1+i] = verts[b];
 
                for (j=0; j<i; j++) {
-                       v = subdivideedgenum(bm, e, j, i, rad, flag, &ne,
-                                            vlist[a], vlist[b]);
+                       v = subdivideedgenum(bm, e, j, i, params, &ne,
+                                            verts[a], verts[b]);
                        lines[i+1][j+1] = v;
 
-                       if (flag & SELTYPE_INNER) {
+                       if (params->flag & SELTYPE_INNER) {
                                BM_Select_Edge(bm, ne, 1);
                        }
                }
@@ -524,14 +520,14 @@ sv7/---v---\ v3 s
                for (j=0; j<i; j++) {
                        e= BM_Connect_Verts(bm, lines[i][j], lines[i+1][j+1],
                                           &nf);
-                       if (flag & SELTYPE_INNER) {
+                       if (params->flag & SELTYPE_INNER) {
                                BM_Select_Edge(bm, e, 1);
                                BM_Select_Face(bm, nf, 1);
                        }
 
                        e= BM_Connect_Verts(bm,lines[i][j+1],lines[i+1][j+1],
                                           &nf);
-                       if (flag & SELTYPE_INNER) {
+                       if (params->flag & SELTYPE_INNER) {
                                BM_Select_Edge(bm, e, 1);
                                BM_Select_Face(bm, nf, 1);
                        }
@@ -577,20 +573,21 @@ typedef struct subd_facedata {
 
 void esubdivide_exec(BMesh *bmesh, BMOperator *op)
 {
-       V_DECLARE(facedata);
-       V_DECLARE(verts);
-       V_DECLARE(edges);
        BMOpSlot *einput, *finput, *pinput;
        BMEdge *edge, **edges = NULL;
+       V_DECLARE(edges);
        BMFace *face;
        BMLoop *nl;
        BMVert **verts = NULL;
+       V_DECLARE(verts);
        BMIter fiter, liter;
-       GHash *customfill_hash; 
+       GHash *customfill_hash, *percent_hash
        subdpattern *pat;
+       subdparams params;
        subd_facedata *facedata = NULL;
+       V_DECLARE(facedata);
        float rad;
-       int i, j, matched, a, b, numcuts, flag, selaction, fillindex;
+       int i, j, matched, a, b, numcuts, flag, selaction;
        
        BMO_Flag_Buffer(bmesh, op, BMOP_ESUBDIVIDE_EDGES, SUBD_SPLIT);
        
@@ -602,8 +599,7 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
        if (selaction == SUBDIV_SELECT_INNER) flag |= SELTYPE_INNER;
 
        einput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_EDGES);
-       
-       /*first go through and split edges*/
+       /*first go through and tag edges*/
        for (i=0; i<einput->len; i++) {
                edge = ((BMEdge**)einput->data.p)[i];
                BMO_SetFlag(bmesh, edge, SUBD_SPLIT);
@@ -611,7 +607,9 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
        
        customfill_hash = BLI_ghash_new(BLI_ghashutil_ptrhash,
                                        BLI_ghashutil_ptrcmp);
-       
+       percent_hash = BLI_ghash_new(BLI_ghashutil_ptrhash,
+                                       BLI_ghashutil_ptrcmp);
+
        /*process custom fill patterns*/
        finput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_CUSTOMFILL_FACES);
        pinput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_CUSTOMFILL_PATTERNS);
@@ -622,6 +620,20 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
                                ((void**)pinput->data.p)[i]);
        }
        
+       einput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_PERCENT_EDGES);
+       pinput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_PERCENT_VALUES);
+       
+       for (i=0; i<einput->len; i++) {
+               edge = ((BMEdge**)einput->data.p)[i];
+               BMO_SetFlag(bmesh, edge, EDGE_PERCENT);
+               BLI_ghash_insert(percent_hash, edge, ((float*)pinput->data.p)+i);
+       }
+       
+       params.flag = flag;
+       params.numcuts = numcuts;
+       params.percenthash = percent_hash;
+       params.rad = rad;
+
        for (face=BMIter_New(&fiter, bmesh, BM_FACES, NULL);
             face; face=BMIter_Step(&fiter)) {
                /*figure out which pattern to use*/
@@ -694,11 +706,12 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
                }
        }
 
+       einput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_EDGES);
+
        /*go through and split edges*/
        for (i=0; i<einput->len; i++) {
                edge = ((BMEdge**)einput->data.p)[i];
-               bm_subdivide_multicut(bmesh, edge, rad, flag, numcuts,
-                                     edge->v1, edge->v2);
+               bm_subdivide_multicut(bmesh, edge,&params, edge->v1, edge->v2);
                //BM_Split_Edge_Multi(bmesh, edge, numcuts);
        }
 
@@ -737,7 +750,7 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
                        j += 1;
                }
                
-               pat->connectexec(bmesh, face, verts, numcuts, flag, rad);
+               pat->connectexec(bmesh, face, verts, &params);
                i++;
        }
 
index b08c633661ddcb06ed2a9caec3293c89c148874f..f8ef5f2f64e41bc9e0db792283434f8592331a12 100644 (file)
@@ -7,9 +7,12 @@
 #include "BLI_arithb.h"
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #define EDGE_NEW       1
 #define FACE_NEW       1
+
 void triangulate_exec(BMesh *bmesh, BMOperator *op)
 {
        BMOpSlot *finput;
index d93ceaf07b873794953e646ab15047c6ffe3fc6f..e5682726844bef953ab1a8c5f4a03acf3c804638 100644 (file)
@@ -76,6 +76,7 @@ editmesh_loop: tools with own drawing subloops, select, knife, subdiv
 #include "ED_view3d.h"
 
 #include "mesh_intern.h"
+#include "bmesh.h"
 
 /* **** XXX ******** */
 static void BIF_undo_push() {}
@@ -204,8 +205,8 @@ void CutEdgeloop(Object *obedit, EditMesh *em, int numcuts)
        EditEdge *nearest=NULL, *eed;
        float fac;
        int keys = 0, holdnum=0, selectmode, dist;
-       short mvalo[2] = {0,0}, mval[2];
-       short event, val, choosing=1, cancel=0, cuthalf = 0, smooth=0;
+       short mvalo[2] = {0,0}, mval[2] = {0, 0};
+       short event=0, val, choosing=1, cancel=0, cuthalf = 0, smooth=0;
        short hasHidden = 0;
        char msg[128];
        
@@ -473,7 +474,7 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
        float  m1, b1, m2, b2, x21, x22, y21, y22, xi;
        float  yi, x1min, x1max, y1max, y1min, perc=0; 
        float  *scr;
-       float  threshold;
+       float  threshold = 0.0;
        int  i;
        
        //threshold = 0.000001; /*tolerance for vertex intersection*/
@@ -619,20 +620,181 @@ static float seg_intersect(EditEdge *e, CutCurve *c, int len, char mode, struct
 } 
 
 
+static float bm_seg_intersect(BMEdge *e, CutCurve *c, int len, char mode,
+                              struct GHash *gh, int *isected)
+{
+#define MAXSLOPE 100000
+       float  x11, y11, x12=0, y12=0, x2max, x2min, y2max;
+       float  y2min, dist, lastdist=0, xdiff2, xdiff1;
+       float  m1, b1, m2, b2, x21, x22, y21, y22, xi;
+       float  yi, x1min, x1max, y1max, y1min, perc=0; 
+       float  *scr;
+       float  threshold = 0.0;
+       int  i;
+       
+       //threshold = 0.000001; /*tolerance for vertex intersection*/
+       // XXX  threshold = scene->toolsettings->select_thresh / 100;
+       
+       /* Get screen coords of verts */
+       scr = BLI_ghash_lookup(gh, e->v1);
+       x21=scr[0];
+       y21=scr[1];
+       
+       scr = BLI_ghash_lookup(gh, e->v2);
+       x22=scr[0];
+       y22=scr[1];
+       
+       xdiff2=(x22-x21);  
+       if (xdiff2) {
+               m2=(y22-y21)/xdiff2;
+               b2= ((x22*y21)-(x21*y22))/xdiff2;
+       }
+       else {
+               m2=MAXSLOPE;  /* Verticle slope  */
+               b2=x22;      
+       }
+
+       *isected = 0;
+
+       /*check for *exact* vertex intersection first*/
+       if(mode!=KNIFE_MULTICUT){
+               for (i=0; i<len; i++){
+                       if (i>0){
+                               x11=x12;
+                               y11=y12;
+                       }
+                       else {
+                               x11=c[i].x;
+                               y11=c[i].y;
+                       }
+                       x12=c[i].x;
+                       y12=c[i].y;
+                       
+                       /*test e->v1*/
+                       if((x11 == x21 && y11 == y21) || (x12 == x21 && y12 == y21)){
+                               perc = 0;
+                               *isected = 1;
+                               return(perc);
+                       }
+                       /*test e->v2*/
+                       else if((x11 == x22 && y11 == y22) || (x12 == x22 && y12 == y22)){
+                               perc = 0;
+                               *isected = 2;
+                               return(perc);
+                       }
+               }
+       }
+       
+       /*now check for edge interesect (may produce vertex intersection as well)*/
+       for (i=0; i<len; i++){
+               if (i>0){
+                       x11=x12;
+                       y11=y12;
+               }
+               else {
+                       x11=c[i].x;
+                       y11=c[i].y;
+               }
+               x12=c[i].x;
+               y12=c[i].y;
+               
+               /* Perp. Distance from point to line */
+               if (m2!=MAXSLOPE) dist=(y12-m2*x12-b2);/* /sqrt(m2*m2+1); Only looking for */
+                       /* change in sign.  Skip extra math */  
+               else dist=x22-x12;      
+               
+               if (i==0) lastdist=dist;
+               
+               /* if dist changes sign, and intersect point in edge's Bound Box*/
+               if ((lastdist*dist)<=0){
+                       xdiff1=(x12-x11); /* Equation of line between last 2 points */
+                       if (xdiff1){
+                               m1=(y12-y11)/xdiff1;
+                               b1= ((x12*y11)-(x11*y12))/xdiff1;
+                       }
+                       else{
+                               m1=MAXSLOPE;
+                               b1=x12;
+                       }
+                       x2max=MAX2(x21,x22)+0.001; /* prevent missed edges   */
+                       x2min=MIN2(x21,x22)-0.001; /* due to round off error */
+                       y2max=MAX2(y21,y22)+0.001;
+                       y2min=MIN2(y21,y22)-0.001;
+                       
+                       /* Found an intersect,  calc intersect point */
+                       if (m1==m2){ /* co-incident lines */
+                               /* cut at 50% of overlap area*/
+                               x1max=MAX2(x11, x12);
+                               x1min=MIN2(x11, x12);
+                               xi= (MIN2(x2max,x1max)+MAX2(x2min,x1min))/2.0;  
+                               
+                               y1max=MAX2(y11, y12);
+                               y1min=MIN2(y11, y12);
+                               yi= (MIN2(y2max,y1max)+MAX2(y2min,y1min))/2.0;
+                       }                       
+                       else if (m2==MAXSLOPE){ 
+                               xi=x22;
+                               yi=m1*x22+b1;
+                       }
+                       else if (m1==MAXSLOPE){ 
+                               xi=x12;
+                               yi=m2*x12+b2;
+                       }
+                       else {
+                               xi=(b1-b2)/(m2-m1);
+                               yi=(b1*m2-m1*b2)/(m2-m1);
+                       }
+                       
+                       /* Intersect inside bounding box of edge?*/
+                       if ((xi>=x2min)&&(xi<=x2max)&&(yi<=y2max)&&(yi>=y2min)){
+                               /*test for vertex intersect that may be 'close enough'*/
+                               if(mode!=KNIFE_MULTICUT){
+                                       if(xi <= (x21 + threshold) && xi >= (x21 - threshold)){
+                                               if(yi <= (y21 + threshold) && yi >= (y21 - threshold)){
+                                                       *isected = 1;
+                                                       perc = 0;
+                                                       break;
+                                               }
+                                       }
+                                       if(xi <= (x22 + threshold) && xi >= (x22 - threshold)){
+                                               if(yi <= (y22 + threshold) && yi >= (y22 - threshold)){
+                                                       *isected = 2;
+                                                       perc = 0;
+                                                       break;
+                                               }
+                                       }
+                               }
+                               if ((m2<=1.0)&&(m2>=-1.0)) perc = (xi-x21)/(x22-x21);   
+                               else perc=(yi-y21)/(y22-y21); /*lower slope more accurate*/
+                               //isect=32768.0*(perc+0.0000153); /* Percentage in 1/32768ths */
+                               
+                               break;
+                       }
+               }       
+               lastdist=dist;
+       }
+       return(perc);
+} 
+
 #define MAX_CUTS 256
 
 static int knife_cut_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh, *em2;
+       BMesh *bm;
        ARegion *ar= CTX_wm_region(C);
-       EditEdge *eed;
-       EditVert *eve;
+       BMVert *bv;
+       BMIter iter;
+       BMEdge **edges = NULL, *be;
+       V_DECLARE(edges);
+       BMOperator bmop;
        CutCurve curve[MAX_CUTS];
        struct GHash *gh;
        float isect=0.0;
-       float  *scr, co[4];
-       int len=0;
+       float  *scr, co[4], *percents = NULL;
+       V_DECLARE(percents);
+       int len=0, isected, flag;
        short numcuts=1, mode= RNA_int_get(op->ptr, "type");
        
        if (EM_nvertices_selected(em) < 2) {
@@ -651,51 +813,67 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
        
        if(len<2) return OPERATOR_CANCELLED;
        
-       /*store percentage of edge cut for KNIFE_EXACT here.*/
-       for(eed=em->edges.first; eed; eed= eed->next) 
-               eed->tmp.fp = 0.0; 
-       
+       bm = editmesh_to_bmesh(em);
+
        /*the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer*/
        gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
-       for(eve=em->verts.first; eve; eve=eve->next){
+       for(bv=BMIter_New(&iter, bm, BM_VERTS, NULL);bv;bv=BMIter_Step(&iter)){
                scr = MEM_mallocN(sizeof(float)*2, "Vertex Screen Coordinates");
-               VECCOPY(co, eve->co);
+               VECCOPY(co, bv->co);
                co[3]= 1.0;
                Mat4MulVec4fl(obedit->obmat, co);
                project_float(ar, co, scr);
-               BLI_ghash_insert(gh, eve, scr);
-               eve->f1 = 0; /*store vertex intersection flag here*/
-       
+               BLI_ghash_insert(gh, bv, scr);
        }
        
-       eed= em->edges.first;           
-       while(eed) {    
-               if( eed->v1->f & eed->v2->f & SELECT ){         // NOTE: uses vertex select, subdiv doesnt do edges yet
-                       isect= seg_intersect(eed, curve, len, mode, gh);
-                       if (isect!=0.0f) eed->f2= 1;
-                       else eed->f2=0;
-                       eed->tmp.fp= isect;
-                       //printf("isect=%i\n", isect);
-               }
-               else {
-                       eed->f2=0;
-                       eed->f1=0;
+       /*store percentage of edge cut for KNIFE_EXACT here.*/
+       for (be=BMIter_New(&iter, bm, BM_EDGES, NULL); be; be=BMIter_Step(&iter)) {
+               if( BM_Is_Selected(bm, be) ) {
+                       isect= bm_seg_intersect(be, curve, len, mode, gh, &isected);
+                       
+                       if (isect != 0.0f) {
+                               V_GROW(edges);
+                               V_GROW(percents);
+                               edges[V_COUNT(edges)-1] = be;
+                               percents[V_COUNT(percents)-1] = isect;
+                       }
                }
-               eed= eed->next;
        }
+               
+       BMO_Init_Op(&bmop, BMOP_ESUBDIVIDE);
+       
+       BMO_Set_Int(&bmop, BMOP_ESUBDIVIDE_NUMCUTS, numcuts);
+       flag = B_KNIFE;
+       if (mode == KNIFE_MIDPOINT) numcuts = 1;
+       else if (mode != KNIFE_MULTICUT) {
+               BMO_Set_PntBuf(&bmop, BMOP_ESUBDIVIDE_PERCENT_EDGES, edges, V_COUNT(edges));
+               BMO_Set_FltBuf(&bmop, BMOP_ESUBDIVIDE_PERCENT_VALUES, percents, V_COUNT(percents));
+       }
+
+       BMO_Set_Int(&bmop, BMOP_ESUBDIVIDE_FLAG, flag);
+       BMO_Set_Float(&bmop, BMOP_ESUBDIVIDE_RADIUS, 0);
+       BMO_Set_Int(&bmop, BMOP_ESUBDIVIDE_SELACTION, SUBDIV_SELECT_ORIG);
+       BMO_Set_PntBuf(&bmop, BMOP_ESUBDIVIDE_EDGES, edges, V_COUNT(edges));
        
-       if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, 1, SUBDIV_SELECT_ORIG);
-       else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, numcuts, SUBDIV_SELECT_ORIG);
-       else esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD, 1, SUBDIV_SELECT_ORIG);
+       BMO_Exec_Op(bm, &bmop);
+       BMO_Finish_Op(bm, &bmop);
+       
+       V_FREE(edges);
+       V_FREE(percents);
 
-       eed=em->edges.first;
-       while(eed){
-               eed->f2=0;
-               eed->f1=0;
-               eed=eed->next;
-       }       
+       //if (mode==KNIFE_MIDPOINT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, 1, SUBDIV_SELECT_ORIG);
+       //else if (mode==KNIFE_MULTICUT) esubdivideflag(obedit, em, SELECT, 0, B_KNIFE, numcuts, SUBDIV_SELECT_ORIG);
+       //else esubdivideflag(obedit, em, SELECT, 0, B_KNIFE|B_PERCENTSUBD, 1, SUBDIV_SELECT_ORIG);
        
        BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
+
+       free_editMesh(em);
+
+       em2 = bmesh_to_editmesh(bm);
+       *em = *em2;
+       
+       MEM_freeN(em2);
+       BM_Free_Mesh(bm);
        
        return OPERATOR_FINISHED;
 }
index f119c347915fe6877e7392523ba4e4dd627e3f47..686d9ec1b11f7724547fd545eae91d12dddeb3bc 100644 (file)
@@ -176,6 +176,8 @@ void ED_operatortypes_mesh(void)
        WM_operatortype_append(MESH_OT_smooth_vertex);
        WM_operatortype_append(MESH_OT_flip_editnormals);
        WM_operatortype_append(MESH_OT_knife_cut);
+
+       WM_operatortype_append(MESH_OT_bmesh_test);
        
 }
 
@@ -285,7 +287,7 @@ void ED_keymap_mesh(wmWindowManager *wm)
        
        WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
        
-       
-       
+
+       WM_keymap_add_item(keymap, "MESH_OT_bmesh_test", JKEY, KM_PRESS, 0, 0);
 }