the make ngon function's overlap test needed some work, the API function
authorJoseph Eagar <joeedh@gmail.com>
Thu, 12 Mar 2009 03:55:53 +0000 (03:55 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Thu, 12 Mar 2009 03:55:53 +0000 (03:55 +0000)
that does that needed to be split in two. this made dissolve faces sometimes
not work.

also added some api functions to recalculate normals for verts, edges and
faces.  and added a new flag, BM_NONORMCALC, to prevent this from happening
on individual fgon faces after they are tesselated.  and made dissolve faces
happen on fkey in all the selection modes, not just face select.

12 files changed:
source/blender/blenkernel/intern/customdata.c
source/blender/bmesh/bmesh.h
source/blender/bmesh/bmesh_queries.h
source/blender/bmesh/intern/bmesh_construct.c
source/blender/bmesh/intern/bmesh_mesh.c
source/blender/bmesh/intern/bmesh_mods.c
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/intern/bmesh_queries.c
source/blender/bmesh/intern/bmesh_to_editmesh.c
source/blender/bmesh/intern/editmesh_to_bmesh.c
source/blender/editors/mesh/editmesh_add.c
source/blender/editors/mesh/editmesh_lib.c

index d9f7625652990df141e28dea2a647210384806ac..4e626bb867fbecc74734f4773c0a0756a099540a 100644 (file)
@@ -257,6 +257,7 @@ static void layerInterp_tface(void **sources, float *weights,
        }
 
        *tf = *(MTFace *)sources[0];
        }
 
        *tf = *(MTFace *)sources[0];
+
        for(j = 0; j < 4; ++j) {
                tf->uv[j][0] = uv[j][0];
                tf->uv[j][1] = uv[j][1];
        for(j = 0; j < 4; ++j) {
                tf->uv[j][0] = uv[j][0];
                tf->uv[j][1] = uv[j][1];
index 0416ca8efdfc5a95af945115d574c37d9cf411eb..2403163fc70e64a099f2958d0aa122e5867ef0b6 100644 (file)
@@ -77,6 +77,7 @@ struct BMLoop;
 #define BM_SHARP       (1<<4)
 #define BM_SMOOTH      (1<<5)
 #define BM_ACTIVE      (1<<6)
 #define BM_SHARP       (1<<4)
 #define BM_SMOOTH      (1<<5)
 #define BM_ACTIVE      (1<<6)
+#define BM_NONORMCALC  (1<<7)
 
 typedef struct BMHeader {
        struct BMHeader *next, *prev;
 
 typedef struct BMHeader {
        struct BMHeader *next, *prev;
@@ -196,6 +197,9 @@ void BM_Collapse_Vert(struct BMesh *bm, struct BMEdge *ke, struct BMVert *kv, fl
 struct BMVert *BM_Split_Edge(struct BMesh *bm, struct BMVert *v, struct BMEdge *e, struct BMEdge **ne, float percent, int calcnorm);
 struct BMVert  *BM_Split_Edge_Multi(struct BMesh *bm, struct BMEdge *e, int numcuts);
 BMEdge *BM_Connect_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf);
 struct BMVert *BM_Split_Edge(struct BMesh *bm, struct BMVert *v, struct BMEdge *e, struct BMEdge **ne, float percent, int calcnorm);
 struct BMVert  *BM_Split_Edge_Multi(struct BMesh *bm, struct BMEdge *e, int numcuts);
 BMEdge *BM_Connect_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf);
+void BM_Face_UpdateNormal(BMesh *bm, BMFace *f);
+void BM_Edge_UpdateNormals(BMesh *bm, BMEdge *e);
+void BM_Vert_UpdateNormal(BMesh *bm, BMVert *v);
 
 /*dissolves vert surrounded by faces*/
 int BM_Dissolve_Disk(BMesh *bm, BMVert *v);
 
 /*dissolves vert surrounded by faces*/
 int BM_Dissolve_Disk(BMesh *bm, BMVert *v);
index 204f3fb3305929d9436220dde0d32d492ae95ddf..301580fc2d300493cd3f998e6e0943c6ae063f2d 100644 (file)
@@ -30,6 +30,7 @@ int BM_Boundary_Edge(struct BMEdge *e);
 int BM_Face_Sharededges(struct BMFace *f1, struct BMFace *f2);
 float BM_Face_Angle(struct BMesh *bm, struct BMEdge *e);
 int BM_Exist_Face_Overlaps(struct BMesh *bm, struct BMVert **varr, int len, struct BMFace **existface);
 int BM_Face_Sharededges(struct BMFace *f1, struct BMFace *f2);
 float BM_Face_Angle(struct BMesh *bm, struct BMEdge *e);
 int BM_Exist_Face_Overlaps(struct BMesh *bm, struct BMVert **varr, int len, struct BMFace **existface);
+int BM_Face_Exists(BMesh *bm, BMVert **varr, int len, BMFace **existface);
 int BM_Edge_Share_Faces(struct BMEdge *e1, struct BMEdge *e2);
 int BM_Validate_Face(BMesh *bm, BMFace *face, FILE *err);
 int BM_FacesAroundEdge(BMEdge *e);
 int BM_Edge_Share_Faces(struct BMEdge *e1, struct BMEdge *e2);
 int BM_Validate_Face(BMesh *bm, BMFace *face, FILE *err);
 int BM_FacesAroundEdge(BMEdge *e);
index c517e802602c09d5eee87a0fbf8e410fe82c297c..ad6381c20e973434b1c3271464c9d634367c7a85 100644 (file)
@@ -245,7 +245,7 @@ BMFace *BM_Make_Ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len,
                        return NULL;
                }
 
                        return NULL;
                }
 
-               overlap = BM_Exist_Face_Overlaps(bm, verts, len, &f);
+               overlap = BM_Face_Exists(bm, verts, len, &f);
                
                /*clear flags*/
                for(i = 0; i < len; i++){
                
                /*clear flags*/
                for(i = 0; i < len; i++){
index b79a8a5f4ab0909d41dcafbe76c810a0c94f0264..95de605f7acb7c6fe6fa7cf60a2008167f6c528f 100644 (file)
@@ -197,6 +197,7 @@ void BM_Compute_Normals(BMesh *bm)
        
        /*calculate all face normals*/
        for(f = BMIter_New(&faces, bm, BM_FACES, bm ); f; f = BMIter_Step(&faces)){
        
        /*calculate all face normals*/
        for(f = BMIter_New(&faces, bm, BM_FACES, bm ); f; f = BMIter_Step(&faces)){
+               if (f->head.flag & BM_NONORMCALC) continue;
                bmesh_update_face_normal(bm, f, projectverts);          
        }
        
                bmesh_update_face_normal(bm, f, projectverts);          
        }
        
index 378c29e3f9ad7828cfb2060386f47bc8d8f25f2a..27b9add3b631be4982b3d00d7beb3621be975632 100644 (file)
@@ -227,7 +227,11 @@ BMFace *BM_Join_Faces(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, int calcnorm
                bmesh_loop_reverse(bm, f2);
        }
 
                bmesh_loop_reverse(bm, f2);
        }
 
-       return bmesh_jfke(bm, f1, f2, jed);
+       f1 = bmesh_jfke(bm, f1, f2, jed);
+       
+       if (calcnorm && f1) BM_Face_UpdateNormal(bm, f1);
+       
+       return f1;
 }
 
 /*connects two verts together, automatically (if very naively) finding the
 }
 
 /*connects two verts together, automatically (if very naively) finding the
@@ -278,18 +282,11 @@ BMFace *BM_Split_Face(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **nl,
        
        BM_Copy_Attributes(bm, bm, f, nf);
 
        
        BM_Copy_Attributes(bm, bm, f, nf);
 
-       /*
-       nf->flag = f->flag;
-       if (example->flag & SELECT) f->flag |= BM_SELECT;
-       nf->h = f->h;
-       nf->mat_nr = f->mat_nr;
-       if (nl && example) {
-               (*nl)->e->flag = example->flag;
-               (*nl)->e->h = example->h;
-               (*nl)->e->crease = example->crease;
-               (*nl)->e->bweight = example->bweight;
+       if (calcnorm && nf) {
+               BM_Face_UpdateNormal(bm, nf);
+               BM_Face_UpdateNormal(bm, f);
        }
        }
-       */
+
        return nf;
 }
 
        return nf;
 }
 
index 5f35f6da9a09a1c1094b3cbf733529c68a04abfe..3c4b738a84082cd33ee6bb5d0cb5239ee672e3d1 100644 (file)
@@ -287,6 +287,56 @@ void poly_rotate_plane(float normal[3], float (*verts)[3], int nverts)
  *
 */
 
  *
 */
 
+void BM_Face_UpdateNormal(BMesh *bm, BMFace *f)
+{
+       float projverts[12][3];
+       float (*proj)[3] = f->len < 12 ? projverts : MEM_mallocN(sizeof(float)*f->len*3, "projvertsn");
+       BMLoop *l = f->loopbase;
+       int i=0;
+
+       if (f->len < 3) return;
+       
+       do {
+               VECCOPY(proj[i], l->v->co);
+               i += 1;
+       } while (l != f->loopbase);
+
+       bmesh_update_face_normal(bm, f, proj);
+
+       if (projverts != proj) MEM_freeN(proj);
+}
+
+void BM_Edge_UpdateNormals(BMesh *bm, BMEdge *e)
+{
+       BMIter *iter;
+       BMFace *f;
+       
+       f = BMIter_New(&iter, bm, BM_FACES_OF_EDGE, e);
+       for (; f; f=BMIter_Step(&iter)) {
+               BM_Face_UpdateNormal(bm, f);
+       }
+
+       BM_Vert_UpdateNormal(bm, e->v1);
+       BM_Vert_UpdateNormal(bm, e->v2);
+}
+
+void BM_Vert_UpdateNormal(BMesh *bm, BMVert *v)
+{
+       BMIter iter;
+       BMFace *f;
+       float norm[3] = {0.0f, 0.0f, 0.0f};
+       int len=0;
+
+       f = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v);
+       for (; f; f=BMIter_Step(&iter), len++) {
+               VecAddf(norm, f->no, norm);
+       }
+
+       if (!len) return;
+
+       VecMulf(norm, 1.0f/(int)len);
+}
+
 void bmesh_update_face_normal(BMesh *bm, BMFace *f, float (*projectverts)[3])
 {
        BMLoop *l;
 void bmesh_update_face_normal(BMesh *bm, BMFace *f, float (*projectverts)[3])
 {
        BMLoop *l;
@@ -529,6 +579,8 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3],
                        f = BM_Split_Face(bm, l->f, ((BMLoop*)(l->head.prev))->v, 
                                          ((BMLoop*)(l->head.next))->v, 
                                          &newl, NULL, 0);
                        f = BM_Split_Face(bm, l->f, ((BMLoop*)(l->head.prev))->v, 
                                          ((BMLoop*)(l->head.next))->v, 
                                          &newl, NULL, 0);
+                       VECCOPY(f->no, l->f->no);
+
                        if (!f) {
                                printf("yeek! triangulator failed to split face!\n");
                                break;
                        if (!f) {
                                printf("yeek! triangulator failed to split face!\n");
                                break;
index dcad4023d8aac4be3b5eeb46e45c9c930ad2f3a5..de17f0aebda8b765ed19ed8c16badd8cd4185aa7 100644 (file)
@@ -501,8 +501,7 @@ float BM_Face_Angle(BMesh *bm, BMEdge *e)
  * BMESH EXIST FACE OVERLAPS
  *
  * Given a set of vertices (varr), find out if
  * BMESH EXIST FACE OVERLAPS
  *
  * Given a set of vertices (varr), find out if
- * a face exists with those vertices already, or
- * if those vertices overlap an existing face.
+ * all those vertices overlap an existing face.
  *
  * Returns:
  * 0 for no overlap
  *
  * Returns:
  * 0 for no overlap
@@ -511,21 +510,56 @@ float BM_Face_Angle(BMesh *bm, BMEdge *e)
  *
 */
 
  *
 */
 
-int BM_Exist_Face_Overlaps(BMesh *bm, BMVert **varr, int len, BMFace **existface)
+int BM_Exist_Face_Overlaps(BMesh *bm, BMVert **varr, int len, BMFace **overlapface)
 {
        BMIter vertfaces;
        BMFace *f;
        int i, amount;
 
 {
        BMIter vertfaces;
        BMFace *f;
        int i, amount;
 
-       *existface = NULL;
+       if (overlapface) *overlapface = NULL;
 
        for(i=0; i < len; i++){
                f = BMIter_New(&vertfaces, bm, BM_FACES_OF_VERT, varr[i] );
                while(f){
                        amount = BM_Verts_In_Face(bm, f, varr, len);
                        if(amount >= len){
 
        for(i=0; i < len; i++){
                f = BMIter_New(&vertfaces, bm, BM_FACES_OF_VERT, varr[i] );
                while(f){
                        amount = BM_Verts_In_Face(bm, f, varr, len);
                        if(amount >= len){
-                               if((len == f->len) && existface)
-                                       *existface = f;
+                               if (overlapface) *overlapface = f;
+                               return 1;                               
+                       }
+                       f = BMIter_Step(&vertfaces);
+               }
+       }
+       return 0;
+}
+
+/*
+ * BMESH FACE EXISTS
+ *
+ * Given a set of vertices (varr), find out if
+ * there is a face with exactly those vertices
+ * (and only those vertices).
+ *
+ * Returns:
+ * 0 for no face found
+ * 1 for face found
+ * 
+ *
+*/
+
+int BM_Face_Exists(BMesh *bm, BMVert **varr, int len, BMFace **existface)
+{
+       BMIter vertfaces;
+       BMFace *f;
+       int i, amount;
+
+       if (existface) *existface = NULL;
+
+       for(i=0; i < len; i++){
+               f = BMIter_New(&vertfaces, bm, BM_FACES_OF_VERT, varr[i] );
+               while(f){
+                       amount = BM_Verts_In_Face(bm, f, varr, len);
+                       if(amount == len && amount == f->len){
+                               if (existface) *existface = f;
                                return 1;                               
                        }
                        f = BMIter_Step(&vertfaces);
                                return 1;                               
                        }
                        f = BMIter_Step(&vertfaces);
index 12bf0bf5e86908e6858b3e8c22efed7a8147f034..b2dc694b898da8178de8a0983abdbd01b038e111 100644 (file)
@@ -256,7 +256,6 @@ void bmesh_make_fgons_exec(BMesh *bmesh, BMOperator *op)
 
        BMO_Init_Op(&triop, BMOP_TRIANGULATE);
        
 
        BMO_Init_Op(&triop, BMOP_TRIANGULATE);
        
-       /*HACK: I don't know if this'll conflict with other flags at all!*/
        for (face = BMIter_New(&iter, bmesh, BM_FACES, NULL); face; face=BMIter_Step(&iter)) {
                if (face->len > 4) {
                        BMO_SetFlag(bmesh, face, FACE_NGON);
        for (face = BMIter_New(&iter, bmesh, BM_FACES, NULL); face; face=BMIter_Step(&iter)) {
                if (face->len > 4) {
                        BMO_SetFlag(bmesh, face, FACE_NGON);
@@ -270,6 +269,11 @@ void bmesh_make_fgons_exec(BMesh *bmesh, BMOperator *op)
        for (i=0; i<eout->len; i++) {
                edge = ((BMEdge**)eout->data.buf)[i];
                edge->head.flag |= BM_FGON;
        for (i=0; i<eout->len; i++) {
                edge = ((BMEdge**)eout->data.buf)[i];
                edge->head.flag |= BM_FGON;
+               face = BMIter_New(&iter, bmesh, BM_FACES_OF_EDGE, edge);
+               
+               for (; face; face=BMIter_Step(&iter)) {
+                       face->head.flag |= BM_NONORMCALC;
+               }
        }
 
        BMO_Finish_Op(bmesh, &triop);
        }
 
        BMO_Finish_Op(bmesh, &triop);
index 656e9804aaf40d7aea1c7306db09c8d7fd18c13d..57cea7e52b48017c651df331db76ac7ac56d7afa 100644 (file)
@@ -195,6 +195,7 @@ static BMFace *editface_to_BMFace(BMesh *bm, BMOperator *op, EditMesh *em, EditF
                f->head.flag = 0;
                f->mat_nr = efa->mat_nr;
                if(efa->f & SELECT) BM_Select_Face(bm, f, 1);
                f->head.flag = 0;
                f->mat_nr = efa->mat_nr;
                if(efa->f & SELECT) BM_Select_Face(bm, f, 1);
+               if (efa->flag & ME_SMOOTH) f->head.flag |= BM_SMOOTH;
                if(efa->h) f->head.flag |= BM_HIDDEN;
 
                if (efa == em->act_face) f->head.flag |= BM_ACTIVE;
                if(efa->h) f->head.flag |= BM_HIDDEN;
 
                if (efa == em->act_face) f->head.flag |= BM_ACTIVE;
index b32c733ad8c9ce63b761babcf48bd0d702b16c4a..8f7214d08a3ad01a5465c739f312dc6351d1d763 100644 (file)
@@ -691,7 +691,7 @@ static void addedgeface_mesh(EditMesh *em, wmOperator *op)
          bmeshafied eventually, but until then
          hacks like this to integrate with it
          are necassary.*/
          bmeshafied eventually, but until then
          hacks like this to integrate with it
          are necassary.*/
-       if (em->selectmode & SCE_SELECT_FACE) {
+       {
                BMesh *bm = editmesh_to_bmesh(em);
                BMOperator bmop;
                int len, ok;
                BMesh *bm = editmesh_to_bmesh(em);
                BMOperator bmop;
                int len, ok;
index 3f01363553c80e6a33bdc9729ec8597ee634fc7b..6e745744c185d4701e5b6d4a04d7b41de807e7e9 100644 (file)
@@ -2028,6 +2028,9 @@ void recalc_editnormals(EditMesh *em)
        }
 
        for(efa= em->faces.first; efa; efa=efa->next) {
        }
 
        for(efa= em->faces.first; efa; efa=efa->next) {
+               if (efa->e1->fgoni||efa->e2->fgoni||efa->e3->fgoni) continue;
+               if (efa->e4 && efa->e4->fgoni) continue;
+
                if(efa->v4) {
                        CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
                        CalcCent4f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
                if(efa->v4) {
                        CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
                        CalcCent4f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);