New: Fake Polygons, or Face-polygons, or FGons nicked for now.
authorTon Roosendaal <ton@blender.org>
Fri, 24 Sep 2004 16:06:20 +0000 (16:06 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 24 Sep 2004 16:06:20 +0000 (16:06 +0000)
Just select a bunch of faces (selection should be valid flat poly) and
press FKEY. Works in fact as selection-group optimizing. Nice in solid
drawmode!

Further some small additional fixes in the whole debugging process.
Found old error in loopselect for triangles, subdivision code, and
selection still.

NOTE: subdivide still works on vertex level only.

source/blender/blenlib/BLI_editVert.h
source/blender/include/editmesh.h
source/blender/src/editmesh.c
source/blender/src/editmesh_add.c
source/blender/src/editmesh_lib.c
source/blender/src/editmesh_loop.c
source/blender/src/editmesh_mods.c
source/blender/src/editmesh_tools.c

index e47d82043b7687f80a0cdf8217274120942da195..30be5cd7b30d5ce423efe6662d2052f5f6b25b22 100644 (file)
@@ -38,6 +38,7 @@
 #ifndef BLI_EDITVERT_H
 #define BLI_EDITVERT_H
 
+/* note; changing this also might affect the undo copy in editmesh.c */
 typedef struct EditVert
 {
        struct EditVert *next, *prev, *vn;
@@ -59,6 +60,7 @@ typedef struct HashEdge {
        struct HashEdge *next;
 } HashEdge;
 
+/* note; changing this also might affect the undo copy in editmesh.c */
 typedef struct EditEdge
 {
        struct EditEdge *next, *prev;
@@ -71,6 +73,7 @@ typedef struct EditEdge
        HashEdge hash;
 } EditEdge;
 
+/* note; changing this also might affect the undo copy in editmesh.c */
 typedef struct EditFace
 {
        struct EditFace *next, *prev;
index 927c8d401568406885416f5ede5e2c302412a14d..7ba5da6e7d65834efb4dd73c92ed363db74489a5 100644 (file)
@@ -62,6 +62,7 @@ extern struct EditEdge *findedgelist(struct EditVert *v1, struct EditVert *v2);
 
 
 /* ******************* editmesh_lib.c */
+extern void EM_fgon_flags(void);
 
 extern int faceselectedOR(EditFace *efa, int flag);
 extern int faceselectedAND(EditFace *efa, int flag);
@@ -83,7 +84,6 @@ extern float convex(float *v1, float *v2, float *v3, float *v4);
 
 /* ******************* editmesh_mods.c */
 extern EditEdge *findnearestedge(short *dist);
-extern void make_fgon(void);
 
 /* ******************* editmesh_tools.c */
 
index cc1f675a4bdd25d61833dbd5987a938c13e6d3d3..a6d75cf21be1dbc2c99ab499f3abd96f2a00f748 100644 (file)
@@ -781,7 +781,8 @@ void make_editMesh()
 
        /* this creates coherent selections. also needed for older files */
        EM_selectmode_set();
-
+       
+       EM_fgon_flags();
        countall();
        
        waitcursor(0);
@@ -1632,13 +1633,13 @@ typedef struct EditEdgeC
 {
        int v1, v2;
        unsigned char f, h, seam, pad;
-       float crease;
+       short crease, fgoni;
 } EditEdgeC;
 
 typedef struct EditFaceC
 {
        int v1, v2, v3, v4;
-       unsigned char mat_nr, flag, f, h, puno, pad;
+       unsigned char mat_nr, flag, f, h, puno, fgonf;
        short pad1;
 } EditFaceC;
 
@@ -1722,7 +1723,8 @@ static void *editMesh_to_undoMesh(void)
                eedc->f= eed->f;
                eedc->h= eed->h;
                eedc->seam= eed->seam;
-               eedc->crease= eed->crease;
+               eedc->crease= (short)(eed->crease*255.0);
+               eedc->fgoni= eed->fgoni;
        }
        
        /* copy faces */
@@ -1738,6 +1740,7 @@ static void *editMesh_to_undoMesh(void)
                efac->f= efa->f;
                efac->h= efa->h;
                efac->puno= efa->puno;
+               efac->fgonf= efa->fgonf;
                
                if(tface) {
                        *tface= efa->tf;
@@ -1789,7 +1792,8 @@ static void undoMesh_to_editMesh(void *umv)
                eed->f= eedc->f;
                eed->h= eedc->h;
                eed->seam= eedc->seam;
-               eed->crease= eedc->crease;
+               eed->fgoni= eedc->fgoni;
+               eed->crease= ((float)eedc->crease)/255.0;
        }
        
        /* copy faces */
@@ -1805,6 +1809,7 @@ static void undoMesh_to_editMesh(void *umv)
                efa->f= efac->f;
                efa->h= efac->h;
                efa->puno= efac->puno;
+               efa->fgonf= efac->fgonf;
                
                if(tface) {
                        efa->tf= *tface;
index 8421228fb2a0d6e523eabcb72cf5dcd4c336a8a0..fdcd09c96d3dd0671892ac28726f1a891ea6f7a3 100644 (file)
@@ -65,6 +65,7 @@
 
 #include "BIF_editmesh.h"
 #include "BIF_graphics.h"
+#include "BIF_interface.h"
 #include "BIF_mywindow.h"
 #include "BIF_screen.h"
 #include "BIF_space.h"
@@ -164,6 +165,128 @@ void addvert_mesh(void)
 
 }
 
+/* selected faces get hidden edges */
+static void make_fgon(void)
+{
+       EditMesh *em = G.editMesh;
+       EditFace *efa;
+       EditEdge *eed;
+       EditVert *eve;
+       float *nor=NULL, dot;   // reference
+       int done=0, ret;
+       
+       ret= pupmenu("FGon %t|Make|Clear");
+       if(ret<1) return;
+       
+       if(ret==2) {
+               for(efa= em->faces.first; efa; efa= efa->next) {
+                       if(efa->f & SELECT) {
+                               efa->fgonf= 0;
+                               efa->e1->h &= ~EM_FGON;
+                               efa->e2->h &= ~EM_FGON;
+                               efa->e3->h &= ~EM_FGON;
+                               if(efa->e4) efa->e4->h &= ~EM_FGON;
+                       }
+               }
+               allqueue(REDRAWVIEW3D, 0);
+               makeDispList(G.obedit);
+               BIF_undo_push("Clear FGon");
+               return;
+       }
+
+       /* tagging edges. rule is:
+          - edge used by exactly 2 selected faces
+          - no vertices allowed with only tagged edges (return)
+          - face normals should not differ too much 
+        
+       */
+       for(eed= em->edges.first; eed; eed= eed->next) {
+               eed->f1= 0;     // amount of selected
+               eed->f2= 0; // amount of unselected
+       }
+       
+       for(efa= em->faces.first; efa; efa= efa->next) {
+               if(efa->f & SELECT) {
+                       if(nor==NULL) nor= efa->n;
+                       if(efa->e1->f1 < 3) efa->e1->f1++;
+                       if(efa->e2->f1 < 3) efa->e2->f1++;
+                       if(efa->e3->f1 < 3) efa->e3->f1++;
+                       if(efa->e4 && efa->e4->f1 < 3) efa->e4->f1++;
+               }
+               else {
+                       if(efa->e1->f2 < 3) efa->e1->f2++;
+                       if(efa->e2->f2 < 3) efa->e2->f2++;
+                       if(efa->e3->f2 < 3) efa->e3->f2++;
+                       if(efa->e4 && efa->e4->f2 < 3) efa->e4->f2++;
+               }
+       }
+       // now eed->f1 becomes tagged edge
+       for(eed= em->edges.first; eed; eed= eed->next) {
+               if(eed->f1==2 && eed->f2==0) eed->f1= 1;
+               else eed->f1= 0;
+       }
+       
+       // no vertices allowed with only tagged edges
+       for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
+       for(eed= em->edges.first; eed; eed= eed->next) {
+               if(eed->f1) {
+                       eed->v1->f1 |= 1;
+                       eed->v2->f1 |= 1;
+               }
+               else {
+                       eed->v1->f1 |= 2;
+                       eed->v2->f1 |= 2;
+               }
+       }
+       for(eve= em->verts.first; eve; eve= eve->next) {
+               if(eve->f1==1) break;
+       }
+       if(eve) {
+               error("Cannot make polygon with interior vertices");
+               return;
+       }
+       
+       // check co-planar
+       if(nor==NULL) {
+               error("No faces selected to make FGon");
+               return;
+       }
+       for(efa= em->faces.first; efa; efa= efa->next) {
+               if(efa->f & SELECT) {
+                       dot= nor[0]*efa->n[0]+nor[1]*efa->n[1]+nor[2]*efa->n[2];
+                       if(dot<0.9 && dot > -0.9) break;
+               }
+       }
+       if(efa) {
+               error("Not a set of co-planar faces to make FGon");
+               return;
+       }
+       
+       // and there we go
+       for(eed= em->edges.first; eed; eed= eed->next) {
+               if(eed->f1) {
+                       eed->h |= EM_FGON;
+                       done= 1;
+               }
+       }
+       
+       if(done==0) {
+               error("Didn't find FGon to create");
+       }
+       else {
+               Mesh *me= G.obedit->data;
+               // signal to save edges with ngon flags
+               if(!me->medge)
+                       me->medge= MEM_callocN(sizeof(MEdge), "fake mesh edge");
+               
+               EM_fgon_flags();        // redo flags and indices for fgons
+
+               allqueue(REDRAWVIEW3D, 0);
+               makeDispList(G.obedit);
+               BIF_undo_push("Make FGon");
+       }
+}
+
 void addedgeface_mesh(void)
 {
        EditMesh *em = G.editMesh;
@@ -191,7 +314,7 @@ void addedgeface_mesh(void)
                return;
        }
        else if(amount > 4) {
-               //make_fgon();
+               make_fgon();
                return;
        }
        else if(amount<2) {
index 3ea520cf57103609f29cba81ec24d4a2986f16bd..1ec61a3b23058f86db2f55405dfd697caab5b85e 100644 (file)
@@ -820,6 +820,8 @@ void adduplicateflag(int flag)
                        efa->f |= 128;
                }
        }
+
+       EM_fgon_flags();        // redo flags and indices for fgons
 }
 
 void delfaceflag(int flag)
@@ -1183,3 +1185,102 @@ float convex(float *v1, float *v2, float *v3, float *v4)
 }
 
 
+/* ********************* Fake Polgon support (FGon) ***************** */
+
+
+/* results in:
+   - faces having ->fgonf flag set (also for draw)
+   - edges having ->fgoni index set (for select)
+*/
+
+static float editface_area(EditFace *efa)
+{
+       if(efa->v4) return AreaQ3Dfl(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
+       else return AreaT3Dfl(efa->v1->co, efa->v2->co, efa->v3->co);
+}
+
+void EM_fgon_flags(void)
+{
+       EditMesh *em = G.editMesh;
+       EditFace *efa, *efan, *efamax;
+       EditEdge *eed;
+       ListBase listb={NULL, NULL};
+       float size, maxsize;
+       short done, curindex= 1;
+       
+       // for each face with fgon edge AND not fgon flag set
+       for(eed= em->edges.first; eed; eed= eed->next) eed->fgoni= 0;  // index
+       for(efa= em->faces.first; efa; efa= efa->next) efa->fgonf= 0;  // flag
+       
+       // for speed & simplicity, put fgon face candidates in new listbase
+       efa= em->faces.first;
+       while(efa) {
+               efan= efa->next;
+               if( (efa->e1->h & EM_FGON) || (efa->e2->h & EM_FGON) || 
+                       (efa->e3->h & EM_FGON) || (efa->e4 && (efa->e4->h & EM_FGON)) ) {
+                       BLI_remlink(&em->faces, efa);
+                       BLI_addtail(&listb, efa);
+               }
+               efa= efan;
+       }
+       
+       // find an undone face with fgon edge
+       for(efa= listb.first; efa; efa= efa->next) {
+               if(efa->fgonf==0) {
+                       
+                       // init this face
+                       efa->fgonf= EM_FGON;
+                       if(efa->e1->h & EM_FGON) efa->e1->fgoni= curindex;
+                       if(efa->e2->h & EM_FGON) efa->e2->fgoni= curindex;
+                       if(efa->e3->h & EM_FGON) efa->e3->fgoni= curindex;
+                       if(efa->e4 && (efa->e4->h & EM_FGON)) efa->e4->fgoni= curindex;
+                       
+                       // we search for largest face, to give facedot drawing rights
+                       maxsize= editface_area(efa);
+                       efamax= efa;
+                       
+                       // now flush curendex over edges and set faceflags
+                       done= 1;
+                       while(done==1) {
+                               done= 0;
+                               
+                               for(efan= listb.first; efan; efan= efan->next) {
+                                       if(efan->fgonf==0) {
+                                               // if one if its edges has index set, do other too
+                                               if( (efan->e1->fgoni==curindex) || (efan->e2->fgoni==curindex) ||
+                                                       (efan->e3->fgoni==curindex) || (efan->e4 && (efan->e4->fgoni==curindex)) ) {
+                                                       
+                                                       efan->fgonf= EM_FGON;
+                                                       if(efan->e1->h & EM_FGON) efan->e1->fgoni= curindex;
+                                                       if(efan->e2->h & EM_FGON) efan->e2->fgoni= curindex;
+                                                       if(efan->e3->h & EM_FGON) efan->e3->fgoni= curindex;
+                                                       if(efan->e4 && (efan->e4->h & EM_FGON)) efan->e4->fgoni= curindex;
+                                                       
+                                                       size= editface_area(efan);
+                                                       if(size>maxsize) {
+                                                               efamax= efan;
+                                                               maxsize= size;
+                                                       }
+                                                       done= 1;
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       efamax->fgonf |= EM_FGON_DRAW;
+                       curindex++;
+
+               }
+       }
+
+       // put fgon face candidates back in listbase
+       efa= listb.first;
+       while(efa) {
+               efan= efa->next;
+               BLI_remlink(&listb, efa);
+               BLI_addtail(&em->faces, efa);
+               efa= efan;
+       }
+}
+
+
index e7350f8384fd0a5c6058bf620e42a4809896bd82..5c0a2345b106b2bb169972b1fbeae665c5a3fbc4 100644 (file)
@@ -826,25 +826,25 @@ void loopoperations(char mode)
                        while(efa){
                                if(efa->e1->f & 16){
                                        /* since this edge is on the face, check if the face has any hidden verts */
-                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4 && !efa->v4->h)  ){
+                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4==NULL || !efa->v4->h)  ){
                                                noface=0;
                                                efa->e1->f &= ~16;
                                        }
                                }
                                else if(efa->e2->f & 16){                                       
-                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4 && !efa->v4->h)  ){
+                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4==NULL || !efa->v4->h)  ){
                                                noface=0;
                                                efa->e2->f &= ~16;
                                        }
                                }
                                else if(efa->e3->f & 16){                                       
-                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4 && !efa->v4->h)  ){
+                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4==NULL || !efa->v4->h)  ){
                                                noface=0;
                                                efa->e3->f &= ~16;
                                        }
                                }
                                else if(efa->e4 && (efa->e4->f & 16)){                                  
-                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4 && !efa->v4->h)  ){
+                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4==NULL || !efa->v4->h)  ){
                                                noface=0;
                                                efa->e4->f &= ~16;
                                        }
index 7cd35e1421d54f5a82efccc56e3028cdf0310646..5cea6971aa5ac1a556c787e8911721cf7f9b4106 100644 (file)
@@ -238,7 +238,7 @@ static EditFace *findnearestface(short *dist)
        getmouseco_areawin(mval);
        efa= acto->next;
        while(efa) {
-               if(efa->h==0) {
+               if(efa->h==0 && efa->fgonf!=EM_FGON) {
                        temp= abs(mval[0]- efa->xs)+ abs(mval[1]- efa->ys);
                        if(temp< *dist) {
                                act= efa;
@@ -251,7 +251,7 @@ static EditFace *findnearestface(short *dist)
        if(*dist>3) {
                efa= em->faces.first;
                while(efa) {
-                       if(efa->h==0) {
+                       if(efa->h==0 && efa->fgonf!=EM_FGON) {
                                temp= abs(mval[0]- efa->xs)+ abs(mval[1]- efa->ys);
                                if(temp< *dist) {
                                        act= efa;
@@ -294,15 +294,17 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
                }
 
                if(G.scene->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) {
-                       if(efa->f & SELECT) BIF_ThemeColor(TH_EDGE_SELECT);
-                       else BIF_ThemeColor(TH_WIRE);
-                       
-                       glBegin(GL_LINE_LOOP);
-                       glVertex3fv(efa->v1->co);
-                       glVertex3fv(efa->v2->co);
-                       glVertex3fv(efa->v3->co);
-                       if(efa->v4) glVertex3fv(efa->v4->co);
-                       glEnd();
+                       if(efa->fgonf==0) {
+                               if(efa->f & SELECT) BIF_ThemeColor(TH_EDGE_SELECT);
+                               else BIF_ThemeColor(TH_WIRE);
+                               
+                               glBegin(GL_LINE_LOOP);
+                               glVertex3fv(efa->v1->co);
+                               glVertex3fv(efa->v2->co);
+                               glVertex3fv(efa->v3->co);
+                               if(efa->v4) glVertex3fv(efa->v4->co);
+                               glEnd();
+                       }
                }
                
                if(G.scene->selectmode & SCE_SELECT_FACE) {
@@ -581,7 +583,7 @@ void selectconnected_mesh(int qual)
                        EM_select_edge(eed, sel);
        }
        for(efa= em->faces.first; efa; efa= efa->next) {
-               if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4 && efa->v4->f1)) 
+               if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4==NULL || efa->v4->f1)) 
                        EM_select_face(efa, sel);
        }
        /* no flush needed, connected geometry is done */
@@ -593,206 +595,6 @@ void selectconnected_mesh(int qual)
        
 }
 
-/* results in:
-   - faces having ->fgonf flag set (also for draw)
-   - edges having ->fgoni index set (for select)
-*/
-
-static float editface_area(EditFace *efa)
-{
-       if(efa->v4) return AreaQ3Dfl(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
-       else return AreaT3Dfl(efa->v1->co, efa->v2->co, efa->v3->co);
-}
-
-void fgon_flags()
-{
-       EditMesh *em = G.editMesh;
-       EditFace *efa, *efan, *efamax;
-       EditEdge *eed;
-       ListBase listb={NULL, NULL};
-       float size, maxsize;
-       short done, curindex= 1;
-       
-       // for each face with fgon edge AND not fgon flag set
-       for(eed= em->edges.first; eed; eed= eed->next) eed->fgoni= 0;  // index
-       for(efa= em->faces.first; efa; efa= efa->next) efa->fgonf= 0;  // flag
-       
-       // for speed & simplicity, put fgon face candidates in new listbase
-       efa= em->faces.first;
-       while(efa) {
-               efan= efa->next;
-               if( (efa->e1->h & EM_FGON) || (efa->e2->h & EM_FGON) || 
-                       (efa->e3->h & EM_FGON) || (efa->e4 && (efa->e4->h & EM_FGON)) ) {
-                       BLI_remlink(&em->faces, efa);
-                       BLI_addtail(&listb, efa);
-               }
-               efa= efan;
-       }
-       
-       // find an undone face with fgon edge
-       for(efa= listb.first; efa; efa= efa->next) {
-               if(efa->fgonf==0) {
-                       
-                       // init this face
-                       efa->fgonf= EM_FGON;
-                       if(efa->e1->h & EM_FGON) efa->e1->fgoni= curindex;
-                       if(efa->e2->h & EM_FGON) efa->e2->fgoni= curindex;
-                       if(efa->e3->h & EM_FGON) efa->e3->fgoni= curindex;
-                       if(efa->e4 && (efa->e4->h & EM_FGON)) efa->e4->fgoni= curindex;
-                       
-                       // we search for largest face, to give facedot drawing rights
-                       maxsize= editface_area(efa);
-                       efamax= efa;
-                       
-                       // now flush curendex over edges and set faceflags
-                       done= 1;
-                       while(done==1) {
-                               done= 0;
-                               
-                               for(efan= listb.first; efan; efan= efan->next) {
-                                       if(efan->fgonf==0) {
-                                               // if one if its edges has index set, do other too
-                                               if( (efan->e1->fgoni==curindex) || (efan->e2->fgoni==curindex) ||
-                                                       (efan->e3->fgoni==curindex) || (efan->e4 && (efan->e4->fgoni==curindex)) ) {
-                                                       
-                                                       efan->fgonf= EM_FGON;
-                                                       if(efan->e1->h & EM_FGON) efan->e1->fgoni= curindex;
-                                                       if(efan->e2->h & EM_FGON) efan->e2->fgoni= curindex;
-                                                       if(efan->e3->h & EM_FGON) efan->e3->fgoni= curindex;
-                                                       if(efan->e4 && (efan->e4->h & EM_FGON)) efan->e4->fgoni= curindex;
-                                                       
-                                                       size= editface_area(efan);
-                                                       if(size>maxsize) {
-                                                               efamax= efan;
-                                                               maxsize= size;
-                                                       }
-                                                       done= 1;
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       efamax->fgonf |= EM_FGON_DRAW;
-                       curindex++;
-
-               }
-       }
-
-       // put fgon face candidates back in listbase
-       efa= listb.first;
-       while(efa) {
-               efan= efa->next;
-               BLI_remlink(&listb, efa);
-               BLI_addtail(&em->faces, efa);
-               efa= efan;
-       }
-}
-
-
-/* selected faces get hidden edges */
-void make_fgon(void)
-{
-       EditMesh *em = G.editMesh;
-       EditFace *efa;
-       EditEdge *eed;
-       EditVert *eve;
-       float *nor=NULL, dot;   // reference
-       int done=0;
-       
-       /* tagging edges. rule is:
-          - edge used by exactly 2 selected faces
-          - no vertices allowed with only tagged edges (return)
-          - face normals should not differ too much 
-        
-       */
-       for(eed= em->edges.first; eed; eed= eed->next) {
-               eed->f1= 0;     // amount of selected
-               eed->f2= 0; // amount of unselected
-       }
-       
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               if(efa->f & SELECT) {
-                       if(nor==NULL) nor= efa->n;
-                       if(efa->e1->f1 < 3) efa->e1->f1++;
-                       if(efa->e2->f1 < 3) efa->e2->f1++;
-                       if(efa->e3->f1 < 3) efa->e3->f1++;
-                       if(efa->e4 && efa->e4->f1 < 3) efa->e4->f1++;
-               }
-               else {
-                       if(efa->e1->f2 < 3) efa->e1->f2++;
-                       if(efa->e2->f2 < 3) efa->e2->f2++;
-                       if(efa->e3->f2 < 3) efa->e3->f2++;
-                       if(efa->e4 && efa->e4->f2 < 3) efa->e4->f2++;
-               }
-       }
-       // now eed->f1 becomes tagged edge
-       for(eed= em->edges.first; eed; eed= eed->next) {
-               if(eed->f1==2 && eed->f2==0) eed->f1= 1;
-               else eed->f1= 0;
-       }
-       
-       // no vertices allowed with only tagged edges
-       for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
-       for(eed= em->edges.first; eed; eed= eed->next) {
-               if(eed->f1) {
-                       eed->v1->f1 |= 1;
-                       eed->v2->f1 |= 1;
-               }
-               else {
-                       eed->v1->f1 |= 2;
-                       eed->v2->f1 |= 2;
-               }
-       }
-       for(eve= em->verts.first; eve; eve= eve->next) {
-               if(eve->f1==1) break;
-       }
-       if(eve) {
-               error("Cannot make polygon with interior vertices");
-               return;
-       }
-       
-       // check co-planar
-       if(nor==NULL) {
-               error("No faces selected to make FGon");
-               return;
-       }
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               if(efa->f & SELECT) {
-                       dot= nor[0]*efa->n[0]+nor[1]*efa->n[1]+nor[2]*efa->n[2];
-                       if(dot<0.9 && dot > -0.9) break;
-               }
-       }
-       if(efa) {
-               error("Not a set of co-planar faces to make FGon");
-               return;
-       }
-       
-       // and there we go
-       for(eed= em->edges.first; eed; eed= eed->next) {
-               if(eed->f1) {
-                       eed->h |= EM_FGON;
-                       done= 1;
-               }
-       }
-       
-       if(done==0) {
-               error("Didn't find FGon to create");
-       }
-       else {
-               Mesh *me= G.obedit->data;
-               // signal to save edges with ngon flags
-               if(!me->medge)
-                       me->medge= MEM_callocN(sizeof(MEdge), "fake mesh edge");
-               
-               fgon_flags();   // redo flags and indices for fgons
-
-               allqueue(REDRAWVIEW3D, 0);
-               makeDispList(G.obedit);
-               BIF_undo_push("Make FGon");
-       }
-}
-
-
 /* swap is 0 or 1, if 1 it hides not selected */
 void hide_mesh(int swap)
 {
@@ -1059,7 +861,7 @@ void select_more(void)
        /* new selected faces */
        for(efa= em->faces.first; efa; efa= efa->next) {
                if(efa->h==0) {
-                       if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4 && efa->v4->f1)) 
+                       if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4==NULL || efa->v4->f1)) 
                                EM_select_face(efa, 1);
                }
        }
@@ -1142,7 +944,7 @@ void select_less(void)
        }
        for(efa= em->faces.first; efa; efa= efa->next) {
                if(efa->h==0) {
-                       if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4 && efa->v4->f1)) 
+                       if(efa->v1->f1 && efa->v2->f1 && efa->v3->f1 && (efa->v4==NULL || efa->v4->f1)) 
                                EM_select_face(efa, 0);
                }
        }
index d1f1be2c26c66b9ae1b5e86a8fcbe7568bfc7706..3cbf29599b3edf54ac3a64463df0a221d7904060 100644 (file)
@@ -159,6 +159,7 @@ void convert_to_triface(int all)
                efa= next;
        }
        
+       EM_fgon_flags();        // redo flags and indices for fgons
        BIF_undo_push("Convert Quads to Triangles");
        
 }
@@ -414,6 +415,7 @@ short removedoublesflag(short flag, float limit)            /* return amount */
                }
                eve= nextve;
        }
+
        return a;       /* amount */
 }
 
@@ -540,6 +542,7 @@ void extrude_mesh(void)
                error("No valid selection");
        }
        else {
+               EM_fgon_flags();
                countall();  /* for G.totvert in calc_meshverts() */
                calc_meshverts();
                transform('n');
@@ -593,14 +596,15 @@ void extrude_repeat_mesh(int steps, float offs)
        Mat3MulVecfl(tmat, dvec);
 
        for(a=0;a<steps;a++) {
-               ok= extrudeflag_vert(SELECT);
+               ok= extrudeflag(SELECT);
                if(ok==0) {
                        error("No valid vertices are selected");
                        break;
                }
                translateflag(SELECT, dvec);
        }
-
+       
+       EM_fgon_flags();
        countall();
        allqueue(REDRAWVIEW3D, 0);
        makeDispList(G.obedit);
@@ -662,7 +666,7 @@ void spin_mesh(int steps,int degr,float *dvec, int mode)
        ok= 1;
 
        for(a=0;a<steps;a++) {
-               if(mode==0) ok= extrudeflag_vert(SELECT);
+               if(mode==0) ok= extrudeflag(SELECT);
                else adduplicateflag(SELECT);
                if(ok==0) {
                        error("No valid vertices are selected");
@@ -688,11 +692,14 @@ void spin_mesh(int steps,int degr,float *dvec, int mode)
                        eve= nextve;
                }
        }
+       
+       EM_fgon_flags();
        countall();
        recalc_editnormals();
        allqueue(REDRAWVIEW3D, 0);
        makeDispList(G.obedit);
-       BIF_undo_push("Spin");
+       
+       if(dvec==NULL) BIF_undo_push("Spin");
 }
 
 void screw_mesh(int steps,int turns)
@@ -941,6 +948,8 @@ void delete_mesh(void)
                }
        }
 
+       EM_fgon_flags();        // redo flags and indices for fgons
+
        countall();
        allqueue(REDRAWVIEW3D, 0);
        makeDispList(G.obedit);
@@ -1402,6 +1411,9 @@ void subdivideflag(int flag, float rad, int beauty)
        eed= em->edges.first;
        while(eed) {
                if(eed->f2 & flag) {
+                       /* for now */
+                       eed->h &= ~EM_FGON;
+               
                        /* Subdivide percentage is stored in 1/32768ths in eed->f1 */
                        if (beauty & B_PERCENTSUBD) percent=(float)(eed->f1)/32768.0;
                        else percent=0.5;
@@ -1448,6 +1460,9 @@ void subdivideflag(int flag, float rad, int beauty)
                efapin= *efa; /* make a copy of efa to recover uv pinning later */
 
                if( faceselectedOR(efa, flag) ) {
+                       /* for now */
+                       efa->fgonf= 0;
+                       
                        e1= efa->e1;
                        e2= efa->e2;
                        e3= efa->e3;