edge subdivide ops now use bmesh code, rather then just the test bmesh op. also...
authorJoseph Eagar <joeedh@gmail.com>
Mon, 16 Mar 2009 14:15:18 +0000 (14:15 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Mon, 16 Mar 2009 14:15:18 +0000 (14:15 +0000)
source/blender/bmesh/bmesh_operators.h
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/intern/bmesh_private.h
source/blender/bmesh/operators/subdivideop.c
source/blender/bmesh/operators/triangulateop.c
source/blender/editors/mesh/editmesh.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/space_view3d/drawobject.c
source/blender/makesdna/DNA_meshdata_types.h

index 74c0bdcc869c6a499017086d452b59c03fc22294..6c43ff5c8e48b12542cd134c54ed2c1343ba96a8 100644 (file)
@@ -119,6 +119,11 @@ enum {
        BMOP_TRIANG_FACEIN, /*faces*/
        BMOP_TRIANG_NEW_EDGES, /*edgeout*/
        BMOP_TRIANG_NEW_FACES, /*faceout*/
+       
+       /*facemap, maps new faces to old one.  since triangulator
+         uses only split face, the original ngon face is still there,
+         though it's just another triangle now.*/
+       BMOP_TRIANG_FACEMAP,
        BMOP_TRIANG_TOTSLOT,
 };
 
@@ -187,6 +192,9 @@ struct EditMesh;
 void BMOP_DupeFromFlag(struct BMesh *bm, int etypeflag, int flag);
 void BM_esubdivideflag(struct Object *obedit, struct BMesh *bm, int selflag, float rad, 
               int flag, int numcuts, int seltype);
+void BM_esubdivideflag_conv(struct Object *obedit, struct EditMesh *em, 
+                            int selflag, float rad, int flag, int numcuts, 
+                            int seltype);
 void BM_extrudefaceflag(BMesh *bm, int flag);
 
 /*this next one return 1 if they did anything, or zero otherwise.
index cbeceae384bc1869cdaa8e41820e9257fac31e20..cdd229b2ca01d17cda165fbd4501482b6737b6f0 100644 (file)
@@ -52,7 +52,8 @@ BMOpDefine def_triangop = {
        "triangulate",
        {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
        {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"},
-       {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}},
+       {BMOP_OPSLOT_ELEMENT_BUF, "faceout"},
+       {BMOP_OPSLOT_MAPPING, "facemap"}},
        triangulate_exec,
        BMOP_TRIANG_TOTSLOT,
        0
index 1f065353c858c82c2711826b7fa11e35b652a685..7a5e664dda4eb292a97bf8a9683fc659d902b699 100644 (file)
@@ -351,17 +351,18 @@ void BM_Vert_UpdateNormal(BMesh *bm, BMVert *v)
 {
        BMIter iter;
        BMFace *f;
-       float norm[3] = {0.0f, 0.0f, 0.0f};
        int len=0;
 
+       v->no[0] = v->no[1] = v->no[2] = 0.0f;
+
        f = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v);
        for (; f; f=BMIter_Step(&iter), len++) {
-               VecAddf(norm, f->no, norm);
+               VecAddf(v->no, f->no, v->no);
        }
 
        if (!len) return;
 
-       VecMulf(norm, 1.0f/(int)len);
+       VecMulf(v->no, 1.0f/(int)len);
 }
 
 void bmesh_update_face_normal(BMesh *bm, BMFace *f, float (*projectverts)[3])
@@ -429,11 +430,11 @@ int linecrosses(double *v1, double *v2, double *v3, double *v4)
        
        return (w1 == w2) && (w3 == w4);*/
 
-       w1 = testedgesidef(v1, v3, v2);
-       w2 = testedgesidef(v2, v4, v1);
-       w3 = !testedgesidef(v1, v2, v3);
-       w4 = testedgesidef(v3, v2, v4);
-       w5 = !testedgesidef(v3, v1, v4);
+       w1 = testedgeside(v1, v3, v2);
+       w2 = testedgeside(v2, v4, v1);
+       w3 = !testedgeside(v1, v2, v3);
+       w4 = testedgeside(v3, v2, v4);
+       w5 = !testedgeside(v3, v1, v4);
        return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5;
 }
 
@@ -552,17 +553,17 @@ static BMLoop *find_ear(BMesh *bm, BMFace *f, float (*verts)[3],
  * triangles (angles less than 
  * 90 degrees). If the triangulator
  * has bits left over (or cannot
- * triangulate at all) it uses an 
- * arbitrary triangulation.
- *
- * TODO:
- * -Modify this to try and find ears that will not create a non-manifold face after conversion back to editmesh
+ * triangulate at all) it uses a
+ * simple fan triangulation
  *
+ * newfaces, if non-null, must be an array of BMFace pointers,
+ * with a length equal to f->len.  it will be filled with the new
+ * triangles, and will be NULL-terminated.
 */
 void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3], 
-                        int newedgeflag, int newfaceflag)
+                         int newedgeflag, int newfaceflag, BMFace **newfaces)
 {
-       int i, done, nvert;
+       int i, done, nvert, nf_i = 0;
        BMLoop *l, *newl, *nextloop;
        BMVert *v;
 
@@ -607,6 +608,8 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3],
 
                        BMO_SetFlag(bm, newl->e, newedgeflag);
                        BMO_SetFlag(bm, f, newfaceflag);
+                       
+                       if (newfaces) newfaces[nf_i++] = f;
 
                        /*l = f->loopbase;
                        do {
@@ -627,14 +630,22 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3],
                                          &newl, NULL);
                        if (!f) {
                                printf("triangle fan step of triangulator failed.\n");
+
+                               /*NULL-terminate*/
+                               if (newfaces) newfaces[nf_i] = NULL;
                                return;
                        }
 
+                       if (newfaces) newfaces[nf_i++] = f;
+                       
                        BMO_SetFlag(bm, newl->e, newedgeflag);
                        BMO_SetFlag(bm, f, newfaceflag);
                        l = nextloop;
                }
        }
+       
+       /*NULL-terminate*/
+       if (newfaces) newfaces[nf_i] = NULL;
 }
 
 /*each pair of loops defines a new edge, a split.  this function goes
index 1e5a4958e7966b174f9b24cb3fe9b7de896c1c87..999285a6d1200e7d2cf3d1321a142a3676284f28 100644 (file)
@@ -66,8 +66,10 @@ int bmesh_test_sysflag(struct BMHeader *element, int flag);
 
 /*Polygon Utilities ? FIXME... where do these each go?*/
 /*newedgeflag sets a flag layer flag, obviously not the header flag.*/
-void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3], int newedgeflag, int newfaceflag);
-void bmesh_update_face_normal(struct BMesh *bm, struct BMFace *f, float (*projectverts)[3]);
+void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3], 
+                         int newedgeflag, int newfaceflag, BMFace **newfaces);
+void bmesh_update_face_normal(struct BMesh *bm, struct BMFace *f, 
+                              float (*projectverts)[3]);
 void compute_poly_plane(float (*verts)[3], int nverts);
 void poly_rotate_plane(float normal[3], float (*verts)[3], int nverts);
 void bmesh_flip_normal(struct BMesh *bm, struct BMFace *f);
index 0b2aba376dbe29c478259e6de5e9f55806c956e8..b7f12344e2f9d358da395c067449c24722d04b80 100644 (file)
@@ -140,18 +140,21 @@ static void alter_co(float *co, BMEdge *edge, subdparams *params, 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, 
-                                       subdparams *params, float percent, 
+static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge,BMEdge *oedge,
+                                       subdparams *params, float percent,
+                                       float percent2,
                                        BMEdge **out,BMVert *vsta,BMVert *vend)
 {
        BMVert *ev;
 //     float co[3];
        
        ev = BM_Split_Edge(bm, edge->v1, edge, out, percent);
+       BM_Vert_UpdateNormal(bm, ev);
+
        BMO_SetFlag(bm, ev, ELE_INNER);
 
        /* offset for smooth or sphere or fractal */
-       alter_co(ev->co, edge, params, percent, vsta, vend);
+       alter_co(ev->co, oedge, params, percent2, vsta, vend);
 
 #if 0 //TODO
        /* clip if needed by mirror modifier */
@@ -171,34 +174,35 @@ static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge,
        return ev;
 }
 
-static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, 
+static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
                                int curpoint, int totpoint, subdparams *params,
                                BMEdge **newe, BMVert *vsta, BMVert *vend)
 {
        BMVert *ev;
-       float percent;
+       float percent, percent2 = 0.0f;
         
        if (BMO_TestFlag(bm, edge, EDGE_PERCENT) && totpoint == 1)
                percent = BMO_Get_MapFloat(bm, params->op, 
                                        BMOP_ESUBDIVIDE_PERCENT_EDGEMAP, edge);
        else {
                percent= 1.0f/(float)(totpoint+1-curpoint);
+               percent2 = (float)curpoint / (float)(totpoint + 1);
 
        }
        
-       ev= bm_subdivide_edge_addvert(bm, edge, params, percent, 
-                                     newe, vsta, vend);
+       ev= bm_subdivide_edge_addvert(bm, edge, oedge, params, percent,
+                                     percent2, newe, vsta, vend);
        return ev;
 }
 
 static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, subdparams *params, 
                                  BMVert *vsta, BMVert *vend) {
-       BMEdge *eed = edge, *newe;
+       BMEdge *eed = edge, *newe, temp = *edge;
        BMVert *v;
        int i, numcuts = params->numcuts;
 
        for(i=0;i<numcuts;i++) {
-               v = subdivideedgenum(bm, eed, i, params->numcuts, params, 
+               v = subdivideedgenum(bm, eed, &temp, i, params->numcuts, params, 
                                     &newe, vsta, vend);
                BMO_SetFlag(bm, v, SUBD_SPLIT);
                BMO_SetFlag(bm, eed, SUBD_SPLIT);
@@ -371,7 +375,7 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **verts,
 {
        BMFace *nf;
        BMVert *v, *v1, *v2;
-       BMEdge *e, *ne;
+       BMEdge *e, *ne, temp;
        BMVert **lines;
        int numcuts = params->numcuts;
        int i, j, a, b, s=numcuts+2, totv=numcuts*4+4;
@@ -406,9 +410,10 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **verts,
                
                v1 = lines[(i+1)*s] = verts[a];
                v2 = lines[(i+1)*s + s-1] = verts[b];
-
+               
+               temp = *e;
                for (a=0; a<numcuts; a++) {
-                       v = subdivideedgenum(bm, e, a, numcuts, params, &ne,
+                       v = subdivideedgenum(bm, e, &temp, a, numcuts, params, &ne,
                                             v1, v2);
                        BMO_SetFlag(bm, ne, ELE_INNER);
                        lines[(i+1)*s+a+1] = v;
@@ -496,7 +501,7 @@ static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **verts,
                           subdparams *params)
 {
        BMFace *nf;
-       BMEdge *e, *ne;
+       BMEdge *e, *ne, temp;
        BMVert ***lines, *v;
        void *stackarr[1];
        int i, j, a, b, numcuts = params->numcuts;
@@ -528,9 +533,10 @@ static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **verts,
 
                lines[i+1][0] = verts[a];
                lines[i+1][1+i] = verts[b];
-
+               
+               temp = *e;
                for (j=0; j<i; j++) {
-                       v = subdivideedgenum(bm, e, j, i, params, &ne,
+                       v = subdivideedgenum(bm, e, &temp, j, i, params, &ne,
                                             verts[a], verts[b]);
                        lines[i+1][j+1] = v;
 
index e84efe5f2b6f23d47ff25f7e176476f3fb76ceab..5f46577945c472ddbb12c041c93ee67bf7d26cd4 100644 (file)
 #define EDGE_NEW       1
 #define FACE_NEW       1
 
-void triangulate_exec(BMesh *bmesh, BMOperator *op)
+void triangulate_exec(BMesh *bm, BMOperator *op)
 {
-       BMOpSlot *finput;
-       BMFace *face;
+       BMOIter siter;
+       BMFace *face, **newfaces = NULL;
+       V_DECLARE(newfaces);
        float (*projectverts)[3] = NULL;
        V_DECLARE(projectverts);
        int i, lastlen=0, count = 0;
        
-       finput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_EDGES);
-
-       for (i=0; i<finput->len; i++) {
-               face = ((BMFace**)finput->data.p)[i];
-
+       face = BMO_IterNew(&siter, bm, op, BMOP_TRIANG_FACEIN);
+       for (; face; face=BMO_IterStep(&siter)) {
                if (lastlen < face->len) {
                        V_RESET(projectverts);
+                       V_RESET(newfaces);
                        for (lastlen=0; lastlen<face->len; lastlen++) {
                                V_GROW(projectverts);
                                V_GROW(projectverts);
                                V_GROW(projectverts);
+                               V_GROW(newfaces);
                        }
                }
                
-               BM_Triangulate_Face(bmesh, face, projectverts, EDGE_NEW, FACE_NEW);
+               BM_Triangulate_Face(bm, face, projectverts, EDGE_NEW, 
+                                   FACE_NEW, newfaces);
+
+               BMO_Insert_MapPointer(bm, op, BMOP_TRIANG_FACEMAP, 
+                                     face, face);
+               for (i=0; newfaces[i]; i++) {
+                       BMO_Insert_MapPointer(bm, op, BMOP_TRIANG_FACEMAP, 
+                                             newfaces[i], face);
+
+               }
        }
        
-       BMO_Flag_To_Slot(bmesh, op, BMOP_TRIANG_NEW_EDGES, EDGE_NEW, BM_EDGE);
-       BMO_Flag_To_Slot(bmesh, op, BMOP_TRIANG_NEW_FACES, FACE_NEW, BM_FACE);
+       BMO_Flag_To_Slot(bm, op, BMOP_TRIANG_NEW_EDGES, EDGE_NEW, BM_EDGE);
+       BMO_Flag_To_Slot(bm, op, BMOP_TRIANG_NEW_FACES, FACE_NEW, BM_FACE);
        
        V_FREE(projectverts);
 }
\ No newline at end of file
index 0535f87ab88ead8fe4d80d2702fef212953270bf..1a37b4837107d67c62eddb373d3fbba678811040 100644 (file)
@@ -1675,6 +1675,7 @@ typedef struct UndoMesh {
        EditVertC *verts;
        EditEdgeC *edges;
        EditFaceC *faces;
+       EditFaceC *act_face;
        EditSelectionC *selected;
        int totvert, totedge, totface, totsel;
        short selectmode;
@@ -1785,6 +1786,8 @@ static void *editMesh_to_undoMesh(void *emv)
                CustomData_from_em_block(&em->fdata, &um->fdata, efa->data, a);
        }
        
+       if (em->act_face) um->act_face = um->faces + em->act_face->tmp.l;
+
        a = 0;
        for(ese=em->selected.first; ese; ese=ese->next, esec++){
                esec->type = ese->type;
@@ -1872,7 +1875,9 @@ static void undoMesh_to_editMesh(void *umv, void *emv)
                efa->f= efac->f;
                efa->h= efac->h;
                efa->fgonf= efac->fgonf;
-               
+
+               if (efac == um->act_face) em->act_face = efa;
+
                CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data);
        }
        
@@ -1896,6 +1901,10 @@ static void undoMesh_to_editMesh(void *umv, void *emv)
                EM_free_index_arrays();
        }
 
+       EM_nvertices_selected(em);
+       EM_nedges_selected(em);
+       EM_nfaces_selected(em);
+
 // XXX retopo_free_paint();
 //     em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
 //     scene->toolsettings->retopo_mode= um->retopo_mode;
index 0e0694fa168ca50d1ccd44927e326ea489ba8683..7ec0fceaf2c12886d31095068126f74594a7fb95 100644 (file)
@@ -3257,8 +3257,10 @@ static int bmesh_test_exec(bContext *C, wmOperator *op)
        bm = editmesh_to_bmesh(em);
 
 #if 1 /*edge subdivide test*/
-       //BM_esubdivideflag(obedit, bm, SELECT, 0.292f*5.0, B_SMOOTH, G.rt==0?1:G.rt, 0);
-       BM_esubdivideflag(obedit, bm, SELECT, 0, 0, G.rt==0?1:G.rt, SUBDIV_SELECT_INNER);
+       //esubdivideflag(obedit, em, 1, -(RNA_float_get(op->ptr, "random_factor")/100), scene->toolsettings->editbutflag, RNA_int_get(op->ptr, "number_cuts"), 0);
+
+       BM_esubdivideflag(obedit, bm, SELECT, -0.05f, 0, G.rt==0?1:G.rt, 0);
+       //BM_esubdivideflag(obedit, bm, SELECT, 0, 0, G.rt==0?1:G.rt, SUBDIV_SELECT_INNER);
 
 #endif
 
index 5e759f912c6b7869f9415f1a5efff9f8a0ef2cb8..68a6a48a0980936a852bcae967c58bf9c89c58d0 100644 (file)
@@ -2188,7 +2188,7 @@ static void fill_quad_quadruple(EditMesh *em, EditFace *efa, struct GHash *gh, i
        
        for(i=1;i<=numcuts;i++) {
                /* we create a fake edge for the next loop */
-               temp.v2 = innerverts[i][0]                      = verts[1][i];
+               temp.v2 = innerverts[i][0] = verts[1][i];
                temp.v1 = innerverts[i][numcuts+1]  = verts[3][i];
                
                for(j=1;j<=numcuts;j++) { 
@@ -6439,7 +6439,7 @@ static int subdivide_exec(bContext *C, wmOperator *op)
        Scene *scene = CTX_data_scene(C);
        EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
        
-       esubdivideflag(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, 1, 0);
+       BM_esubdivideflag_conv(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, 1, 0);
                
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        
@@ -6466,7 +6466,7 @@ static int subdivide_multi_exec(bContext *C, wmOperator *op)
        Scene *scene = CTX_data_scene(C);
        EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
        
-       esubdivideflag(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, RNA_int_get(op->ptr,"number_cuts"), 0);
+       BM_esubdivideflag_conv(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, RNA_int_get(op->ptr,"number_cuts"), 0);
                
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        
@@ -6496,7 +6496,7 @@ static int subdivide_multi_fractal_exec(bContext *C, wmOperator *op)
        Scene *scene = CTX_data_scene(C);
        EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
 
-       esubdivideflag(obedit, em, 1, -(RNA_float_get(op->ptr, "random_factor")/100), scene->toolsettings->editbutflag, RNA_int_get(op->ptr, "number_cuts"), 0);
+       BM_esubdivideflag_conv(obedit, em, 1, -(RNA_float_get(op->ptr, "random_factor")/100), scene->toolsettings->editbutflag, RNA_int_get(op->ptr, "number_cuts"), 0);
                
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        
@@ -6527,7 +6527,7 @@ static int subdivide_smooth_exec(bContext *C, wmOperator *op)
        Scene *scene = CTX_data_scene(C);
        EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
 
-       esubdivideflag(obedit, em, 1, 0.292f*RNA_float_get(op->ptr, "smoothness"), scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
+       BM_esubdivideflag_conv(obedit, em, 1, 0.292f*RNA_float_get(op->ptr, "smoothness"), scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
                
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        
index f9a5195860dfa3f68bccf0db747135ad8a6e247c..ab4781a25a817d1838608919515b727bfdad5845 100644 (file)
@@ -1569,7 +1569,7 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *dra
        unsigned char *col;
        
        if (efa->h==0) {
-               if (efa == data->efa_act) {
+               if (efa == data->efa_act || efa->flag & ME_DRAW_ACT) {
                        glColor4ubv(data->cols[2]);
                        return 2; /* stipple */
                } else {
index c07989b2ce69b5d79b75af5256b0a8e7de0eecf9..fce1c8b00e371eed9b5d9bf3176afdeeaadebd6e 100644 (file)
@@ -216,7 +216,9 @@ typedef struct PartialVisibility {
 /* flag (mface) */
 #define ME_SMOOTH                      1
 #define ME_FACE_SEL                    2
-                                               /* flag ME_HIDE==16 is used here too */ 
+/* flag ME_HIDE==16 is used here too */ 
+#define ME_DRAW_ACT                    4
+
 /* mselect->type */
 #define ME_VSEl        0
 #define ME_ESEl 1