diff options
author | Geoffrey Bantle <hairbat@yahoo.com> | 2008-02-25 07:53:37 +0300 |
---|---|---|
committer | Geoffrey Bantle <hairbat@yahoo.com> | 2008-02-25 07:53:37 +0300 |
commit | d566fe665ad1c9f5a1078fba76f230fdd8675452 (patch) | |
tree | d07bbfbe316bf789438236934697d61595150d22 | |
parent | 3023458aa7319a100cfb248a3ace72de5f854670 (diff) |
-> Bevel
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.
-rw-r--r-- | source/blender/blenkernel/BKE_bmesh.h | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/BME_conversions.c | 30 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/BME_eulers.c | 117 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/BME_mesh.c | 40 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/BME_tools.c | 262 | ||||
-rw-r--r-- | source/blender/src/editmesh_tools.c | 1 |
6 files changed, 137 insertions, 331 deletions
diff --git a/source/blender/blenkernel/BKE_bmesh.h b/source/blender/blenkernel/BKE_bmesh.h index 6a2209618d5..ba85833863e 100644 --- a/source/blender/blenkernel/BKE_bmesh.h +++ b/source/blender/blenkernel/BKE_bmesh.h @@ -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 diff --git a/source/blender/blenkernel/intern/BME_conversions.c b/source/blender/blenkernel/intern/BME_conversions.c index f7a9cfcb15c..db4e39794d6 100644 --- a/source/blender/blenkernel/intern/BME_conversions.c +++ b/source/blender/blenkernel/intern/BME_conversions.c @@ -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); diff --git a/source/blender/blenkernel/intern/BME_eulers.c b/source/blender/blenkernel/intern/BME_eulers.c index b83ca48db5f..8ef46be1072 100644 --- a/source/blender/blenkernel/intern/BME_eulers.c +++ b/source/blender/blenkernel/intern/BME_eulers.c @@ -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 diff --git a/source/blender/blenkernel/intern/BME_mesh.c b/source/blender/blenkernel/intern/BME_mesh.c index b6f4bc0a1bc..064db8cf148 100644 --- a/source/blender/blenkernel/intern/BME_mesh.c +++ b/source/blender/blenkernel/intern/BME_mesh.c @@ -134,24 +134,6 @@ void BME_free_mesh(BME_Mesh *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 * * These two functions represent the 'point of entry' for tools. Every BMesh tool @@ -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. */ diff --git a/source/blender/blenkernel/intern/BME_tools.c b/source/blender/blenkernel/intern/BME_tools.c index 5e1b93129a9..664d4033a4c 100644 --- a/source/blender/blenkernel/intern/BME_tools.c +++ b/source/blender/blenkernel/intern/BME_tools.c @@ -49,128 +49,7 @@ #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; } diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c index a20327dcfac..19b6ed287f9 100644 --- a/source/blender/src/editmesh_tools.c +++ b/source/blender/src/editmesh_tools.c @@ -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); |