-> Bevel
authorGeoffrey Bantle <hairbat@yahoo.com>
Mon, 25 Feb 2008 04:53:37 +0000 (04:53 +0000)
committerGeoffrey Bantle <hairbat@yahoo.com>
Mon, 25 Feb 2008 04:53:37 +0000 (04:53 +0000)
Fixed the following problems with Bevel code

  -meshes with 2 edged faces left over at the end would cause buffer
   overrun whens converting from a Bmesh to a Derived Mesh. The
   conversion process now checks for both double edges and faces
   and removes them when present.

  -BME_reverse_loop euler had a bug that was causing the corruption of
   radial cycle. This would lead to the bevel tool hanging for a long time
   and possibly crashing.

  -Added optimization of BME_reverse loop so that it no longer does tiny
   allocations but instead uses an area of 'scratch' memory. The same thing
   will be done to the Make Face euler soon

  -Added proper call to selection flushing for editmode.

  -Some miscellaneous cleanups and removal of unneeded debug printfs.

source/blender/blenkernel/BKE_bmesh.h
source/blender/blenkernel/intern/BME_conversions.c
source/blender/blenkernel/intern/BME_eulers.c
source/blender/blenkernel/intern/BME_mesh.c
source/blender/blenkernel/intern/BME_tools.c
source/blender/src/editmesh_tools.c

index 6a2209618d58c7bce876836a22d062c5729b03ed..ba85833863e0f7100feee398b83a090c48c3354a 100644 (file)
@@ -67,20 +67,18 @@ typedef struct BME_Mesh
        struct CustomData vdata, edata, pdata, ldata;   /*Custom Data Layer information*/
        struct DerivedMesh *derivedFinal, *derivedCage;
        struct RetopoPaintData *retopo_paint_data; /*here for temporary code compatibility only*/
-       //BME_ElementList selection;
+       /*some temporary storage used by loop reverse and make face eulers*/
+       struct BME_Edge **edar;
+       int edarlen;
        int lastDataMask;
 } BME_Mesh;
 
-//60, 52, 52, 12 704
-//60, 52, 84 
-
-
 typedef struct BME_Vert
 {
        struct BME_Vert *next, *prev;
        int     EID;
-       float co[3];                                                                    /*vertex location. Actually pointer to custom data block*/
-       float no[3];                                                                    /*vertex normal. Actually pointer to custom data block*/
+       float co[3];                                                                    
+       float no[3];                                                                    
        struct BME_Edge *edge;                                                  /*first edge in the disk cycle for this vertex*/
        void *data;                                                                             /*custom vertex data*/
        int eflag1, eflag2;                                                             /*reserved for use by eulers*/
@@ -122,7 +120,6 @@ typedef struct BME_Poly
 {
        struct BME_Poly *next, *prev;
        int EID;
-       //~ float no[3];
        struct BME_Loop *loopbase;                                              /*First editloop around Polygon.*/
        struct ListBase holes;                                                  /*list of inner loops in the face*/
        unsigned int len;                                                               /*total length of the face. Eulers should preserve this data*/
@@ -156,7 +153,6 @@ struct BME_Loop *BME_loop_find_loop(struct BME_Poly *f, struct BME_Vert *v);
 /*MESH CREATION/DESTRUCTION*/
 struct BME_Mesh *BME_make_mesh(void);
 void BME_free_mesh(struct BME_Mesh *bm);
-struct BME_Mesh *BME_copy_mesh(struct BME_Mesh *bm);
 /*FULL MESH VALIDATION*/
 int BME_validate_mesh(struct BME_Mesh *bm, int halt);
 /*ENTER/EXIT MODELLING LOOP*/
@@ -181,10 +177,6 @@ struct BME_Poly *BME_JFKE(struct BME_Mesh *bm, struct BME_Poly *f1, struct BME_P
 /*NORMAL FLIP(Is its own inverse)*/
 int BME_loop_reverse(struct BME_Mesh *bm, struct BME_Poly *f);
 
-/*TOOLS CODE*/
-struct BME_Loop *BME_inset_edge(struct BME_Mesh *bm, struct BME_Loop *l, struct BME_Poly *f);
-struct BME_Poly *BME_inset_poly(struct BME_Mesh *bm, struct BME_Poly *f);
-
 /* bevel tool defines */
 /* element flags */
 #define BME_BEVEL_ORIG                 1
index f7a9cfcb15c360c58779dab5381f424977bdd711..db4e39794d64c90052633c3a4c566b7991a22e6b 100644 (file)
@@ -191,17 +191,19 @@ EditMesh *BME_bmesh_to_editmesh(BME_Mesh *bm, BME_TransData_Head *td) {
        /* make edges */
        CustomData_copy(&bm->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0);
        for (e=bm->edges.first;e;e=e->next) {
-               eed= addedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1], NULL);
-               eed->crease = e->crease;
-               eed->bweight = e->bweight;
-               if(e->flag & ME_SEAM) eed->seam = 1;
-               if(e->flag & ME_SHARP) eed->sharp = 1;
-               if(e->flag & SELECT) eed->f |= SELECT;
-               if(e->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
-               if(e->flag & ME_HIDE) eed->h |= 1;
-               if(G.scene->selectmode==SCE_SELECT_EDGE) 
-                       EM_select_edge(eed, eed->f & SELECT);
-               CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data);
+               if(!(findedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1]))){
+                       eed= addedgelist(evlist[e->v1->tflag1], evlist[e->v2->tflag1], NULL);
+                       eed->crease = e->crease;
+                       eed->bweight = e->bweight;
+                       if(e->flag & ME_SEAM) eed->seam = 1;
+                       if(e->flag & ME_SHARP) eed->sharp = 1;
+                       if(e->flag & SELECT) eed->f |= SELECT;
+                       if(e->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
+                       if(e->flag & ME_HIDE) eed->h |= 1;
+                       if(G.scene->selectmode==SCE_SELECT_EDGE) 
+                               EM_select_edge(eed, eed->f & SELECT);
+                       CustomData_em_copy_data(&bm->edata, &em->edata, e->data, &eed->data);
+               }
        }
 
        /* make faces */
@@ -417,10 +419,10 @@ DerivedMesh *BME_bmesh_to_derivedmesh(BME_Mesh *bm, DerivedMesh *dm)
                                        test_index_face(mf, NULL, i, len);
                                }
                                i++;
+                               mf->mat_nr = (unsigned char)f->mat_nr;
+                               mf->flag = (unsigned char)f->flag;
+                               CustomData_from_em_block(&bm->pdata, &result->faceData, f->data, i);
                        }
-                       mf->mat_nr = (unsigned char)f->mat_nr;
-                       mf->flag = (unsigned char)f->flag;
-                       CustomData_from_em_block(&bm->pdata, &result->faceData, f->data, i);
                }
        }
        BLI_edgehash_free(edge_hash, NULL);
index b83ca48db5f8bab644062e6838735260568fdc5c..8ef46be1072283f1d49eb98e2a1f18f03d341a38 100644 (file)
@@ -132,7 +132,7 @@ BME_Edge *BME_ME(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2){
        int valance1=0, valance2=0, edok;
        
        /*edge must be between two distinct vertices...*/
-       if(v1 == v2) return BME_exit("ME returned NULL");
+       if(v1 == v2) return NULL;
        
        #ifndef BME_FASTEULER
        /*count valance of v1*/
@@ -199,10 +199,10 @@ BME_Poly *BME_MF(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge **elist, int
        BME_Vert *curvert, *tv, **vlist;
        int i, j, done, cont, edok;
        
-       if(len < 2) return BME_exit("MF returned NULL");
+       if(len < 2) return NULL;
        
        /*make sure that v1 and v2 are in elist[0]*/
-       if(BME_verts_in_edge(v1,v2,elist[0]) == 0) return BME_exit("MF returned NULL");
+       if(BME_verts_in_edge(v1,v2,elist[0]) == 0) return NULL;
        
        /*clear euler flags*/
        for(i=0;i<len;i++) elist[i]->eflag1=elist[i]->eflag2 = 0;
@@ -220,9 +220,9 @@ BME_Poly *BME_MF(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Edge **elist, int
        */
        for(i=0; i<len; i++){
                edok = BME_disk_count_edgeflag(elist[i]->v1, MF_CANDIDATE, 0);
-               if(edok != 2) return BME_exit("MF returned NULL");
+               if(edok != 2) return NULL;
                edok = BME_disk_count_edgeflag(elist[i]->v2, MF_CANDIDATE, 0);
-               if(edok != 2) return BME_exit("MF returned NULL");
+               if(edok != 2) return NULL;
        }
        
        /*set start edge, start vert and target vert for our loop traversal*/
@@ -430,7 +430,7 @@ BME_Vert *BME_SEMV(BME_Mesh *bm, BME_Vert *tv, BME_Edge *e, BME_Edge **re){
        BME_Edge *ne;
        int i, edok, valance1=0, valance2=0;
        
-       if(BME_vert_in_edge(e,tv) == 0) return BME_exit("SEMV returned NULL");
+       if(BME_vert_in_edge(e,tv) == 0) return NULL;
        ov = BME_edge_getothervert(e,tv);
        //v2 = tv;
 
@@ -601,7 +601,6 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
        BME_Edge *e;
        int i, len, f1len, f2len;
        
-       if(f->holes.first) return BME_exit("SFME returned NULL"); //not good, fix me
        
        /*verify that v1 and v2 are in face.*/
        len = BME_cycle_length(f->loopbase);
@@ -610,7 +609,7 @@ BME_Poly *BME_SFME(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Lo
                else if(curloop->v == v2) v2loop = curloop;
        }
        
-       if(!v1loop || !v2loop) return BME_exit("SFME returned NULL");
+       if(!v1loop || !v2loop) return NULL;
        
        /*allocate new edge between v1 and v2*/
        e = BME_addedgelist(bm, v1, v2,NULL);
@@ -799,12 +798,19 @@ int BME_loop_reverse(BME_Mesh *bm, BME_Poly *f){
        int i, j, edok, len = 0;
 
        len = BME_cycle_length(l);
-       elist = MEM_callocN(sizeof(BME_Edge *)*len, "BME Loop Reverse edge array");
+       if(bm->edarlen < len){
+               MEM_freeN(bm->edar);
+               bm->edar = MEM_callocN(sizeof(BME_Edge *)* len, "BMesh Edge pointer array");
+               bm->edarlen = bm->edarlen * len;
+       }
        
        for(i=0, curloop = l; i< len; i++, curloop=curloop->next){
-               BME_radial_remove_loop(curloop, curloop->e);
                curloop->e->eflag1 = 0;
-               elist[i] = curloop->e;
+               curloop->e->eflag2 = BME_cycle_length(&curloop->radial);
+               BME_radial_remove_loop(curloop, curloop->e);
+               /*in case of border edges we HAVE to zero out curloop->radial Next/Prev*/
+               curloop->radial.next = curloop->radial.prev = NULL;
+               bm->edar[i] = curloop->e;
        }
        
        /*actually reverse the loop. This belongs in BME_cycle_reverse!*/
@@ -818,16 +824,16 @@ int BME_loop_reverse(BME_Mesh *bm, BME_Poly *f){
 
        if(len == 2){ //two edged face
                //do some verification here!
-               l->e = elist[1];
-               l->next->e = elist[0];
+               l->e = bm->edar[1];
+               l->next->e = bm->edar[0];
        }
        else{
                for(i=0, curloop = l; i < len; i++, curloop = curloop->next){
                        edok = 0;
                        for(j=0; j < len; j++){
-                               edok = BME_verts_in_edge(curloop->v, curloop->next->v, elist[j]);
+                               edok = BME_verts_in_edge(curloop->v, curloop->next->v, bm->edar[j]);
                                if(edok){
-                                       curloop->e = elist[j];
+                                       curloop->e = bm->edar[j];
                                        break;
                                }
                        }
@@ -839,7 +845,13 @@ int BME_loop_reverse(BME_Mesh *bm, BME_Poly *f){
                //radok = BME_cycle_validate(curloop->e->tmp.l, &(curloop->radial));
                //if(!radok || curloop->e->loop == NULL) BME_error();
        }
-       MEM_freeN(elist);
+       /*validate radial*/
+       for(i=0, curloop = l; i < len; i++, curloop = curloop->next){
+               edok = BME_cycle_validate(curloop->e->eflag2, &(curloop->radial));
+               if(!edok){
+                       BME_error();
+               }
+       }
        return 1;
 }
 
@@ -881,8 +893,8 @@ BME_Poly *BME_JFKE(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e)
        BME_Loop *curloop, *f1loop=NULL, *f2loop=NULL;
        int loopok = 0, newlen = 0,i, f1len=0, f2len=0, radlen=0, edok;
        
-       if(f1->holes.first || f2->holes.first) return BME_exit("JFKE returned NULL"); //dont operate on faces with holes. Not best solution but tolerable.
-       if(f1 == f2) return BME_exit("JFKE returned NULL"); //can't join a face to itself
+       if(f1->holes.first || f2->holes.first) return NULL; //dont operate on faces with holes. Not best solution but tolerable.
+       if(f1 == f2) return NULL; //can't join a face to itself
        /*verify that e is in both f1 and f2*/
        f1len = BME_cycle_length(f1->loopbase);
        f2len = BME_cycle_length(f2->loopbase);
@@ -898,23 +910,23 @@ BME_Poly *BME_JFKE(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e)
                        break;
                }
        }
-       if(!(f1loop && f2loop)) return BME_exit("JFKE returned NULL");
+       if(!(f1loop && f2loop)) return NULL;
        
        /*validate that edge is 2-manifold edge*/
        radlen = BME_cycle_length(&(f1loop->radial));
-       if(radlen != 2) return BME_exit("JFKE returned NULL");
+       if(radlen != 2) return NULL;
 
        /*validate direction of f2's loop cycle is compatible.*/
-       if(f1loop->v == f2loop->v) return BME_exit("JFKE returned NULL");
+       if(f1loop->v == f2loop->v) return NULL;
        
        /*
                Finally validate that for each face, each vertex has another edge in its disk cycle that is 
                not e, and not shared.
        */
-       if(BME_radial_find_face(f1loop->next->e,f2)) return BME_exit("JFKE returned NULL");
-       if(BME_radial_find_face(f1loop->prev->e,f2)) return BME_exit("JFKE returned NULL");
-       if(BME_radial_find_face(f2loop->next->e,f1)) return BME_exit("JFKE returned NULL");
-       if(BME_radial_find_face(f2loop->prev->e,f1)) return BME_exit("JFKE returned NULL");
+       if(BME_radial_find_face(f1loop->next->e,f2)) return NULL;
+       if(BME_radial_find_face(f1loop->prev->e,f2)) return NULL;
+       if(BME_radial_find_face(f2loop->next->e,f1)) return NULL;
+       if(BME_radial_find_face(f2loop->prev->e,f1)) return NULL;
        
        /*join the two loops*/
        f1loop->prev->next = f2loop->next;
@@ -951,57 +963,4 @@ BME_Poly *BME_JFKE(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e)
        BME_free_loop(bm, f2loop);
        BME_free_poly(bm, f2);  
        return f1;
-}
-
-/**
- *                     BME_MEKL
- *
- *     MAKE EDGE KILL LOOP:
- *     
- *     Bridges a perphiary loop of a face with an internal loop
- *
- *     Examples:
- *
- *     ----------------                ----------------
- *     |      f1      |                |      f1      |
- *     |     -----    |                |     -----    |
- *     |     |   |    |                |     |   |    |
- *     X     X   |    |        X-----X   |    |
- *     |     |   |    |                |     |   |    |
- *     |     -----    |                |     -----    |
- *     |                          |            |                          |
- *     ----------------                ----------------
- *
- *
- *  Returns -
- *     A BME_Poly pointer
- */
-
-/**
- *                     BME_KEML
- *
- *     KILL EDGE MAKE LOOP:
- *     
- *     Kills an edge and splits the loose loops off into an internal loop
- *
- *     Examples:
- *
- *     ----------------                ----------------
- *     |      f1      |                |      f1      |
- *     |     -----    |                |     -----    |
- *     |     |   |    |                |     |   |    |
- *     X ----X   |    |        X     X   |    |
- *     |     |   |    |                |     |   |    |
- *     |     -----    |                |     -----    |
- *     |                          |            |                          |
- *     ----------------                ----------------
- *
- *     The tool author should take care to realize that although a face may have 
- *     a hole in its topology, that hole may be filled with one or many other faces.
- *     Regardless, this does not imply a parent child relationship.
- *
- *
- *  Returns -
- *     A BME_Poly pointer
- */
-
+}
\ No newline at end of file
index b6f4bc0a1bc407dbef882e719c7689a99a9b32d0..064db8cf148cd15632f48dd08f2d6a24538fbd85 100644 (file)
@@ -133,24 +133,6 @@ void BME_free_mesh(BME_Mesh *bm)
        MEM_freeN(bm);  
 }
 
-/*     
- *     BME COPY MESH
- *
- *     Copies a BME_Mesh structure.
- *
- *  This is probably more low level than any mesh manipulation routine should be
- *  and somewhat violates the rule about modifying/creating mesh structures outside
- *  of the euler API. Regardless, its much more effecient than rebuilding the mesh
- *  from scratch. 
-*/
-
-BME_Mesh *BME_copy_mesh(BME_Mesh *bm)
-{
-       BME_Mesh *meshcopy;
-       meshcopy = BME_make_mesh();
-       return meshcopy;
-}
-
 /*     
  *     BME MODEL BEGIN AND END
  *
@@ -173,9 +155,9 @@ BME_Mesh *BME_copy_mesh(BME_Mesh *bm)
 */
 
 int BME_model_begin(BME_Mesh *bm){
-       if(bm->lock) return 0;
-       bm->lock = 1;
-       bm->backup = BME_copy_mesh(bm);
+       /*scratch edge pointer array*/
+       bm->edar = MEM_callocN(sizeof(BME_Edge *) * 1024, "BMesh scratch edge array");
+       bm->edarlen = 1024;
        return 1;
 }
 
@@ -188,23 +170,20 @@ void BME_model_end(BME_Mesh *bm){
        totpoly = BLI_countlist(&(bm->polys));
        totloop = BLI_countlist(&(bm->loops));
        
+       if(bm->edar){ 
+               MEM_freeN(bm->edar);
+               bm->edar = NULL;
+               bm->edarlen = 0;
+       }
        if(bm->totvert!=totvert || bm->totedge!=totedge || bm->totpoly!=totpoly || bm->totloop!=totloop)
                BME_error();
        
        meshok = BME_validate_mesh(bm, 1);
        if(!meshok){
-               printf("Warning, Mesh failed validation, restoring from backup");
-               badmesh = bm;
-               bm= badmesh->backup;
-               bm->backup = badmesh;
-               backupok = BME_validate_mesh(bm,1);
-               if(!backupok) printf("Backup corrupted too, Briggs did something stupid!");
+               BME_error();
        }
-       BME_free_mesh(bm->backup);
-       bm->lock = 0;
 }
 
-
 /*     
  *     BME VALIDATE MESH
  *
@@ -220,7 +199,6 @@ void BME_model_end(BME_Mesh *bm){
  *
  *     TODO 
  *     
- *     -Add validation for hole loops (which are experimental anyway)
  *     -Write a full mesh validation function for debugging purposes.
  */
 
index 5e1b93129a9e0656e24438a9d6bc60726db9664b..664d4033a4cc67263e40edce15f356adb179ad15 100644 (file)
 
 #include "blendef.h"
 
-/**
- *                     BME_dissolve_edge
- *
- *     Edge Dissolve Function:
- *
- *     Dissolves a 2-manifold edge by joining it's two faces. if
- *     they have opposite windings it first makes them consistent
- *     by calling BME_loop_reverse()
- *
- *     Returns -
-*/
-
-/**
- *                     BME_inset_edge
- *
- *     Edge Inset Function:
- *
- *     Splits a face in two along an edge and returns the next loop
- *
- *     Returns -
- *     A BME_Poly pointer.
- */
-
-BME_Loop *BME_inset_edge(BME_Mesh *bm, BME_Loop *l, BME_Poly *f){
-       BME_Loop *nloop;
-       BME_SFME(bm, f, l->v, l->next->v, &nloop);
-       return nloop->next;
-}
-
-/**
- *                     BME_inset_poly
- *
- *     Face Inset Tool:
- *
- *     Insets a single face and returns a pointer to the face at the
- *     center of the newly created region
- *
- *     Returns -
- *     A BME_Poly pointer.
- */
-
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
-BME_Poly *BME_inset_poly(BME_Mesh *bm,BME_Poly *f){
-
-       BME_Vert *v;
-       BME_Loop *l,*nextloop, *killoop, *sloop;
-
-       int len,i;
-       float max[3],min[3],cent[3]; //center of original face
-
-       /*get bounding box for face*/
-       VECCOPY(max,f->loopbase->v->co);
-       VECCOPY(min,f->loopbase->v->co);
-       len = f->len;
-       for(i=0,l=f->loopbase;i<len;i++,l=l->next){
-               max[0] = MAX(max[0],l->v->co[0]);
-               max[1] = MAX(max[1],l->v->co[1]);
-               max[2] = MAX(max[2],l->v->co[2]);
-
-               min[0] = MIN(min[0],l->v->co[0]);
-               min[1] = MIN(min[1],l->v->co[1]);
-               min[2] = MIN(min[2],l->v->co[2]);
-       }
-
-       cent[0] = (min[0] + max[0]) / 2.0f;
-       cent[1] = (min[1] + max[1]) / 2.0f;
-       cent[2] = (min[2] + max[2]) / 2.0f;
-
-       /*inset each edge in the polygon.*/
-       len = f->len;
-       for(i=0,l=f->loopbase; i < len; i++){
-               nextloop = l->next;
-               f = BME_SFME(bm,l->f,l->v,l->next->v,NULL);
-               l=nextloop;
-       }
-
-       /*for each new edge, call SEMV on it*/
-       for(i=0,l=f->loopbase; i < len; i++, l=l->next){
-               l->tflag1 = 1; //going to store info that this loops edge still needs split
-               f = BME_SFME(bm,l->f,l->v,l->next->v,NULL);
-               l->tflag2 = l->v->tflag1 = l->v->tflag2 = 0;
-       }
-
-       len = f->len;
-       for(i=0,l=f->loopbase; i < len; i++){
-               if(l->tflag1){
-                       l->tflag1 = 0;
-                       v= BME_SEMV(bm,l->next->v,l->e,NULL);
-                       VECCOPY(v->co,l->v->co);
-                       v->tflag1 = 1;
-                       l = l->next->next;
-               }
-       }
-
-       len = f->len;
-       sloop = NULL;
-       for(i=0,l=f->loopbase; i < len; i++,l=l->next){
-               if(l->v->tflag1 && l->next->next->v->tflag1){
-                       sloop = l;
-                       break;
-               }
-       }
-       if(sloop){
-               for(i=0,l=sloop; i < len; i++){
-                       nextloop = l->next->next;
-                       f = BME_SFME(bm,f,l->v,l->next->next->v,&killoop);
-                       i+=1; //i+=2;
-                       BME_JFKE(bm,l->f,((BME_Loop*)l->radial.next->data)->f,l->e);
-                       l=nextloop;
-               }
-       }
-
-       len = f->len;
-       for(i=0,l=f->loopbase; i < len; i++,l=l->next){
-               l->v->co[0] = (l->v->co[0] + cent[0]) / 2.0f;
-               l->v->co[1] = (l->v->co[1] + cent[1]) / 2.0f;
-               l->v->co[2] = (l->v->co[2] + cent[2]) / 2.0f;
-       }
-       return NULL;
-}
+/*split this all into a seperate bevel.c file in src*/
 
 /* ------- Bevel code starts here -------- */
 
@@ -236,7 +115,7 @@ float *BME_new_transdata_float(BME_TransData_Head *td) {
        return BLI_memarena_alloc(td->ma, sizeof(float));
 }
 
-int BME_is_nonmanifold_vert(BME_Mesh *bm, BME_Vert *v) {
+static int BME_is_nonmanifold_vert(BME_Mesh *bm, BME_Vert *v) {
        BME_Edge *e, *oe;
        BME_Loop *l;
        int len, count, flag;
@@ -298,7 +177,7 @@ int BME_is_nonmanifold_vert(BME_Mesh *bm, BME_Vert *v) {
 
 /* a wrapper for BME_JFKE that [for now just] checks to
  * make sure loop directions are compatible */
-BME_Poly *BME_JFKE_safe(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e) {
+static BME_Poly *BME_JFKE_safe(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e) {
        BME_Loop *l1, *l2;
 
        l1 = e->loop;
@@ -311,7 +190,7 @@ BME_Poly *BME_JFKE_safe(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e) {
 }
 
 /* a wrapper for BME_SFME that transfers element flags */
-BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Loop **nl, BME_Edge *example) {
+static BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Loop **nl, BME_Edge *example) {
        BME_Poly *nf;
        nf = BME_SFME(bm,f,v1,v2,nl);
        nf->flag = f->flag;
@@ -330,7 +209,7 @@ BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2,
 }
 
 /* a wrapper for BME_SEMV that transfers element flags */
-BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) {
+static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) {
        BME_Vert *nv, *v2;
        float len;
 
@@ -352,7 +231,7 @@ BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne,
        return nv;
 }
 
-int BME_bevel_is_split_vert(BME_Loop *l) {
+static int BME_bevel_is_split_vert(BME_Loop *l) {
        /* look for verts that have already been added to the edge when
         * beveling other polys; this can be determined by testing the
         * vert and the edges around it for originality
@@ -370,13 +249,13 @@ int BME_bevel_is_split_vert(BME_Loop *l) {
  * the bevel operation as a whole based on the relationship between v1 and v2
  * (won't necessarily be a vec from v1->co to v2->co, though it probably will be);
  * the return value is -1 for failure, 0 if we used vert co's, and 1 if we used transform origins */
-int BME_bevel_get_vec(float *vec, BME_Vert *v1, BME_Vert *v2, BME_TransData_Head *td) {
+static int BME_bevel_get_vec(float *vec, BME_Vert *v1, BME_Vert *v2, BME_TransData_Head *td) {
        BME_TransData *vtd1, *vtd2;
 
        vtd1 = BME_get_transdata(td,v1);
        vtd2 = BME_get_transdata(td,v2);
        if (!vtd1 || !vtd2) {
-               printf("BME_bevel_get_vec() got called without proper BME_TransData\n");
+               //printf("BME_bevel_get_vec() got called without proper BME_TransData\n");
                return -1;
        }
 
@@ -408,7 +287,7 @@ int BME_bevel_get_vec(float *vec, BME_Vert *v1, BME_Vert *v2, BME_TransData_Head
  * vec2 is the direction of projection (pointing away from vec1)
  * up_vec is used for orientation (expected to be normalized)
  * returns the length of the projected vector that lies along vec1 */
-float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int is_forward, BME_TransData_Head *td) {
+static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int is_forward, BME_TransData_Head *td) {
        float factor, vec3[3], tmp[3],c1,c2;
 
        Crossf(tmp,vec1,vec2);
@@ -437,7 +316,7 @@ float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int is_forw
  * using the vert and the loop passed, get or make the split vert, set its coordinates
  * and transform properties, and set the max limits.
  * Finally, return the split vert. */
-BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) {
+static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) {
        BME_TransData *vtd, *vtd1, *vtd2;
        BME_Vert *sv, *v2, *v3;
        BME_Loop *lv1, *lv2;
@@ -452,19 +331,19 @@ BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop
                forward = 1;
                is_split_vert = 0;
                if (v->edge == NULL) {
-                       printf("We can't split a loose vert's edge!\n");
+                       //printf("We can't split a loose vert's edge!\n");
                        return NULL;
                }
                e1 = v->edge; /* we just use the first two edges */
                e2 = BME_disk_nextedge(v->edge, v);
                if (e1 == e2) {
-                       printf("You need at least two edges to use BME_bevel_split_edge()\n");
+                       //printf("You need at least two edges to use BME_bevel_split_edge()\n");
                        return NULL;
                }
                v2 = BME_edge_getothervert(e1, v);
                v3 = BME_edge_getothervert(e2, v);
                if (v1 != v2 && v1 != v3) {
-                       printf("Error: more than 2 edges in v's disk cycle, or v1 does not share an edge with v\n");
+                       //printf("Error: more than 2 edges in v's disk cycle, or v1 does not share an edge with v\n");
                        return NULL;
                }
                if (v1 == v2) {
@@ -500,7 +379,7 @@ BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop
                        v2 = l->next->next->v;
                }
                else {
-                       printf("ERROR: BME_bevel_split_edge() - v must be adjacent to l\n");
+                       //printf("ERROR: BME_bevel_split_edge() - v must be adjacent to l\n");
                        return NULL;
                }
 
@@ -572,7 +451,7 @@ BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop
        return sv;
 }
 
-float BME_bevel_set_max(BME_Vert *v1, BME_Vert *v2, float value, BME_TransData_Head *td) {
+static float BME_bevel_set_max(BME_Vert *v1, BME_Vert *v2, float value, BME_TransData_Head *td) {
        BME_TransData *vtd1, *vtd2;
        float max, fac1, fac2, vec1[3], vec2[3], vec3[3];
 
@@ -626,7 +505,7 @@ float BME_bevel_set_max(BME_Vert *v1, BME_Vert *v2, float value, BME_TransData_H
        return max;
 }
 
-BME_Vert *BME_bevel_wire(BME_Mesh *bm, BME_Vert *v, float value, int res, int options, BME_TransData_Head *td) {
+static BME_Vert *BME_bevel_wire(BME_Mesh *bm, BME_Vert *v, float value, int res, int options, BME_TransData_Head *td) {
        BME_Vert *ov1, *ov2, *v1, *v2;
 
        ov1 = BME_edge_getothervert(v->edge, v);
@@ -651,7 +530,7 @@ BME_Vert *BME_bevel_wire(BME_Mesh *bm, BME_Vert *v, float value, int res, int op
        return v1;
 }
 
-BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
+static BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
        BME_Vert *v1, *v2, *kv;
        BME_Loop *kl=NULL, *nl;
        BME_Edge *e;
@@ -740,12 +619,12 @@ BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int options, fl
                l = l->radial.next->data;
        }
 
-       if (l->f != f) printf("Whoops! You got something out of order in BME_bevel_edge()!\n");
+       if (l->f != f); //printf("Whoops! You got something out of order in BME_bevel_edge()!\n");
 
        return l;
 }
 
-BME_Loop *BME_bevel_vert(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
+static BME_Loop *BME_bevel_vert(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
        BME_Vert *v1, *v2;
        BME_Poly *f;
 
@@ -778,7 +657,7 @@ BME_Loop *BME_bevel_vert(BME_Mesh *bm, BME_Loop *l, float value, int options, fl
  *     Returns -
  *  A BME_Poly pointer to the resulting inner face.
 */
-BME_Poly *BME_bevel_poly(BME_Mesh *bm, BME_Poly *f, float value, int options, BME_TransData_Head *td) {
+static BME_Poly *BME_bevel_poly(BME_Mesh *bm, BME_Poly *f, float value, int options, BME_TransData_Head *td) {
        BME_Loop *l, *ol;
        BME_TransData *vtd1, *vtd2;
        float up_vec[3], vec1[3], vec2[3], vec3[3], fac1, fac2, max = -1;
@@ -863,7 +742,7 @@ BME_Poly *BME_bevel_poly(BME_Mesh *bm, BME_Poly *f, float value, int options, BM
        return l->f;
 }
 
-void BME_bevel_add_vweight(BME_TransData_Head *td, BME_Mesh *bm, BME_Vert *v, float weight, float factor, int options) {
+static void BME_bevel_add_vweight(BME_TransData_Head *td, BME_Mesh *bm, BME_Vert *v, float weight, float factor, int options) {
        BME_TransData *vtd;
 
        if (v->tflag1 & BME_BEVEL_NONMAN) return;
@@ -896,7 +775,7 @@ void BME_bevel_add_vweight(BME_TransData_Head *td, BME_Mesh *bm, BME_Vert *v, fl
        }
 }
 
-float BME_bevel_get_angle(BME_Mesh *bm, BME_Edge *e, BME_Vert *v) {
+static float BME_bevel_get_angle(BME_Mesh *bm, BME_Edge *e, BME_Vert *v) {
        BME_Vert *v1, *v2;
        BME_Loop *l1, *l2;
        float vec1[3], vec2[3], vec3[3], vec4[3];
@@ -944,7 +823,7 @@ float BME_bevel_get_angle(BME_Mesh *bm, BME_Edge *e, BME_Vert *v) {
  *     Returns -
  *  A BME_Mesh pointer to the BMesh passed as a parameter.
 */
-BME_Mesh *BME_bevel_initialize(BME_Mesh *bm, int options, int defgrp_index, float angle, BME_TransData_Head *td) {
+static BME_Mesh *BME_bevel_initialize(BME_Mesh *bm, int options, int defgrp_index, float angle, BME_TransData_Head *td) {
        BME_Vert *v;
        BME_Edge *e;
        BME_Poly *f;
@@ -1116,7 +995,7 @@ BME_Mesh *BME_bevel_initialize(BME_Mesh *bm, int options, int defgrp_index, floa
 }
 
 /* tags all elements as originals */
-BME_Mesh *BME_bevel_reinitialize(BME_Mesh *bm) {
+static BME_Mesh *BME_bevel_reinitialize(BME_Mesh *bm) {
        BME_Vert *v;
        BME_Edge *e;
        BME_Poly *f;
@@ -1149,12 +1028,39 @@ BME_Mesh *BME_bevel_reinitialize(BME_Mesh *bm) {
  *     Returns -
  *  A BME_Mesh pointer to the BMesh passed as a parameter.
 */
-BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) {
+
+static void bmesh_dissolve_disk(BME_Mesh *bm, BME_Vert *v){
+       BME_Poly *f;
+       BME_Edge *e;
+       int done, len;
+       
+       if(v->edge){
+               done = 0;
+               while(!done){
+                       done = 1;
+                       e = v->edge; /*loop the edge looking for a edge to dissolve*/
+                       do{
+                               f = NULL;
+                               len = BME_cycle_length(&(e->loop->radial));
+                               if(len == 2){
+                                       f = BME_JFKE_safe(bm,e->loop->f, ((BME_Loop*)(e->loop->radial.next->data))->f, e);
+                               }
+                               if(f){ 
+                                       done = 0;
+                                       break;
+                               }
+                               e = BME_disk_nextedge(e,v);
+                       }while(e != v->edge);
+               }
+               BME_JEKV(bm,v->edge,v);
+       }
+}
+static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) {
        BME_Vert *v, *nv;
        BME_Edge *e, *oe;
        BME_Loop *l, *l2;
-       BME_Poly *f, *nf;
-       unsigned int i, len, done;
+       BME_Poly *f;
+       unsigned int i, len;
 
        for (f=bm->polys.first; f; f=f->next) {
                if(f->tflag1 & BME_BEVEL_ORIG) {
@@ -1170,22 +1076,23 @@ BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int de
                        v = BME_bevel_wire(bm, v, value, res, options, td);
                }
                else if (res && ((v->tflag1 & BME_BEVEL_BEVEL) && (v->tflag1 & BME_BEVEL_ORIG))) {
+                       
                        /* first, make sure we're not sitting on an edge to be removed */
                        oe = v->edge;
                        e = BME_disk_nextedge(oe,v);
                        while ((e->tflag1 & BME_BEVEL_BEVEL) && (e->tflag1 & BME_BEVEL_ORIG)) {
                                e = BME_disk_nextedge(e,v);
                                if (e == oe) {
-                                       printf("Something's wrong! We can't remove every edge here!\n");
+                                       //printf("Something's wrong! We can't remove every edge here!\n");
                                        break;
                                }
                        }
                        /* look for original edges, and remove them */
                        oe = e;
-                       while ( (e = BME_disk_next_edgeflag(oe, v, 0, BME_BEVEL_ORIG | BME_BEVEL_BEVEL)) ) {
+                       while (e = BME_disk_next_edgeflag(oe, v, 0, BME_BEVEL_ORIG | BME_BEVEL_BEVEL)) {
                                /* join the faces (we'll split them later) */
                                f = BME_JFKE_safe(bm,e->loop->f,((BME_Loop*)e->loop->radial.next->data)->f,e);
-                               if (!f) printf("Non-manifold geometry not getting tagged right?\n");
+                               if (!f); //printf("Non-manifold geometry not getting tagged right?\n");
                        }
 
                        /* all original edges marked to be beveled have been removed;
@@ -1210,56 +1117,15 @@ BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int de
                                        }
                                }
                        }
-
-                       done = 0;
-                       while(!done){
-                               done = 1;
-                               e = v->edge;
-                               do{
-                                       f = NULL;
-                                       len = BME_cycle_length(&(e->loop->radial));
-                                       if(len == 2){
-                                               f = BME_JFKE_safe(bm,e->loop->f, ((BME_Loop*)(e->loop->radial.next->data))->f, e);
-                                       }
-                                       if(f){ 
-                                               done = 0;
-                                               break;
-                                       }
-                                       e = BME_disk_nextedge(e,v);
-                               }while(e != v->edge);
-                       }
-                       BME_JEKV(bm,e,v);
+                       bmesh_dissolve_disk(bm, v);
                }
                v = nv;
        }
 
-       /*clean up two edged faces here*/
-               for(f=bm->polys.first; f;){
-                       nf = f->next;
-                       if(f->len == 2){
-                               e = NULL;
-                               l = f->loopbase;
-                               do{
-                                       if(BME_cycle_length(&l->radial) == 2){
-                                               e = l->e;
-                                               break;
-                                       }
-                                       l = l->next;
-                               }while(l!=f->loopbase);
-
-                               if(e) BME_JFKE_safe(bm,f, ((BME_Loop*)(e->loop->radial.next->data))->f, e);
-                               else{
-                                       /*We are still leaving a stray edge? This shouldnt even be possible!*/
-                                       BME_KF(bm, f);
-                               }
-                       }
-                       f = nf;
-               }
-
        return bm;
 }
 
-BME_Mesh *BME_tesselate(BME_Mesh *bm) {
+static BME_Mesh *BME_tesselate(BME_Mesh *bm) {
        BME_Loop *l, *nextloop;
        BME_Poly *f;
 
@@ -1275,6 +1141,12 @@ BME_Mesh *BME_tesselate(BME_Mesh *bm) {
        return bm;
 }
 
+
+/*Main bevel function:
+       Should be only one exported
+
+*/
+
 /* options that can be passed:
  * BME_BEVEL_VWEIGHT   <---- v, Look at vertex weights; use defgrp_index if option is present
  * BME_BEVEL_SELECT            <---- v,e, check selection for verts and edges
@@ -1304,7 +1176,9 @@ BME_Mesh *BME_bevel(BME_Mesh *bm, float value, int res, int options, int defgrp_
        /* crazy idea. if res == 0, don't remove original geometry */
        for (i=0; i<res || (res==0 && i==0); i++) {
                if (i != 0) BME_bevel_reinitialize(bm);
+               BME_model_begin(bm);
                BME_bevel_mesh(bm,d,res,options,defgrp_index,td);
+               BME_model_end(bm);
                if (i==0) d /= 3; else d /= 2;
        }
 
index a20327dcfac03221360e5adcae2efc37c551dd5b..19b6ed287f94dd33ac847e90424282eab6df5d5b 100644 (file)
@@ -4503,6 +4503,7 @@ void bevel_menu() {
                free_editMesh(G.editMesh);
                BME_bevel(bm,0.1f,res,options,0,0,&td);
                BME_bmesh_to_editmesh(bm, td);
+               EM_selectmode_flush();
                G.editBMesh->bm = bm;
                G.editBMesh->td = td;
                initTransform(TFM_BEVEL,CTX_BMESH);