diff options
-rw-r--r-- | source/blender/blenkernel/BKE_tessmesh.h | 12 | ||||
-rw-r--r-- | source/blender/bmesh/bmesh.h | 3 | ||||
-rw-r--r-- | source/blender/bmesh/bmesh_marking.h | 15 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_construct.c | 43 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_marking.c | 189 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 52 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_structure.c | 5 | ||||
-rw-r--r-- | source/blender/bmesh/operators/mesh_conv.c | 1 | ||||
-rw-r--r-- | source/blender/bmesh/operators/subdivideop.c | 113 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_select.c | 16 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_selecthistory.c | 160 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmeshutils.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 4 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 4 |
14 files changed, 415 insertions, 206 deletions
diff --git a/source/blender/blenkernel/BKE_tessmesh.h b/source/blender/blenkernel/BKE_tessmesh.h index c3ccf4b1e6a..e448f904841 100644 --- a/source/blender/blenkernel/BKE_tessmesh.h +++ b/source/blender/blenkernel/BKE_tessmesh.h @@ -11,13 +11,6 @@ ok: the EDBM module is for editmode bmesh stuff. in contrast, the the BMEditMesh structure. */ -typedef struct BMEditSelection -{ - struct BMEditSelection *next, *prev; - short type; - void *data; -} BMEditSelection; - /*this structure replaces EditMesh. through this, you get access to both the edit bmesh, @@ -25,7 +18,7 @@ typedef struct BMEditSelection struct itself. the entire derivedmesh and modifier system works with this structure, - and not BMesh. Mesh->editbmesh will store a pointer to this structure.*/ + and not BMesh. Mesh->edit_bmesh stores a pointer to this structure.*/ typedef struct BMEditMesh { struct BMesh *bm; @@ -50,9 +43,6 @@ typedef struct BMEditMesh { struct BMVert **vert_index; struct BMEdge **edge_index; struct BMFace **face_index; - - /*selection order list*/ - ListBase selected; /*selection mode*/ int selectmode; diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index ba5b26444c0..3c8194ee205 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -170,6 +170,9 @@ typedef struct BMesh { int totflags, walkers; /*total number of tool flag layers*/ ListBase errorstack; + /*selection order list*/ + ListBase selected; + /*active face pointer*/ struct BMFace *act_face; } BMesh; diff --git a/source/blender/bmesh/bmesh_marking.h b/source/blender/bmesh/bmesh_marking.h index 1074b057eba..dbe6a867385 100644 --- a/source/blender/bmesh/bmesh_marking.h +++ b/source/blender/bmesh/bmesh_marking.h @@ -1,6 +1,13 @@ #ifndef BM_MARKING_H #define BM_MARKING_H +typedef struct BMEditSelection +{ + struct BMEditSelection *next, *prev; + short type; + void *data; +} BMEditSelection; + /*Selection code*/ void BM_Select_Vert(struct BMesh *bm, struct BMVert *v, int select); void BM_Select_Edge(struct BMesh *bm, struct BMEdge *e, int select); @@ -13,4 +20,12 @@ int BM_CountFlag(struct BMesh *bm, int type, int flag); void BM_Select(struct BMesh *bm, void *element, int select); int BM_Is_Selected(BMesh *bm, void *element); +/*edit selection stuff*/ +void BM_editselection_center(BMesh *bm, float *center, BMEditSelection *ese); +void BM_editselection_normal(float *normal, BMEditSelection *ese); +void BM_editselection_plane(BMesh *bm, float *plane, BMEditSelection *ese); +void BM_remove_selection(BMesh *bm, void *data); +void BM_store_selection(BMesh *bm, void *data); +void BM_validate_selections(BMesh *bm); + #endif diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 58025fd33cc..06b7116de59 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -418,11 +418,12 @@ BMesh *BM_Copy_Mesh(BMesh *bmold) V_DECLARE(etable); BMLoop *l, *l2, **loops = NULL; V_DECLARE(loops); - BMFace *f, *f2; - + BMFace *f, *f2, **ftable = NULL; + V_DECLARE(ftable); + BMEditSelection *ese; BMIter iter, liter; int allocsize[4] = {512,512,2048,512}, numTex, numCol; - int i; + int i, j; /*allocate a bmesh*/ bm = BM_Make_Mesh(allocsize); @@ -468,15 +469,15 @@ BMesh *BM_Copy_Mesh(BMesh *bmold) } f = BMIter_New(&iter, bmold, BM_FACES_OF_MESH, NULL); - for (; f; f=BMIter_Step(&iter)) { + for (i=0; f; f=BMIter_Step(&iter), i++) { V_RESET(loops); V_RESET(edges); l = BMIter_New(&liter, bmold, BM_LOOPS_OF_FACE, f); - for (i=0; i<f->len; i++, l = BMIter_Step(&liter)) { + for (j=0; j<f->len; j++, l = BMIter_Step(&liter)) { V_GROW(loops); V_GROW(edges); - loops[i] = l; - edges[i] = etable[BMINDEX_GET(l->e)]; + loops[j] = l; + edges[j] = etable[BMINDEX_GET(l->e)]; } v = vtable[BMINDEX_GET(loops[0]->v)]; @@ -488,19 +489,41 @@ BMesh *BM_Copy_Mesh(BMesh *bmold) } f2 = BM_Make_Ngon(bm, v, v2, edges, f->len, 0); + + BMINDEX_SET(f, i); + V_GROW(ftable); + ftable[i] = f2; + BM_Copy_Attributes(bmold, bm, f, f2); VECCOPY(f2->no, f->no); l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f2); - for (i=0; i<f->len; i++, l = BMIter_Step(&liter)) { - BM_Copy_Attributes(bmold, bm, loops[i], l); + for (j=0; j<f->len; j++, l = BMIter_Step(&liter)) { + BM_Copy_Attributes(bmold, bm, loops[j], l); } if (f == bmold->act_face) bm->act_face = f2; } - + + /*copy over edit selection history*/ + for (ese=bmold->selected.first; ese; ese=ese->next) { + void *ele; + + if (ese->type == BM_VERT) + ele = vtable[BMINDEX_GET(ese->data)]; + else if (ese->type == BM_EDGE) + ele = etable[BMINDEX_GET(ese->data)]; + else if (ese->type == BM_FACE) { + ele = ftable[BMINDEX_GET(ese->data)]; + } + + BM_store_selection(bm, ele); + } + V_FREE(etable); V_FREE(vtable); + V_FREE(ftable); + V_FREE(loops); V_FREE(edges); diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 5923add3025..578e7646b2d 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -1,7 +1,14 @@ -#include <string.h> +#include "MEM_guardedalloc.h" + +#include "BKE_utildefines.h" + +#include "BLI_arithb.h" +#include "BLI_blenlib.h" + #include "bmesh.h" #include "bmesh_private.h" +#include <string.h> /* * BM_MARK.C @@ -304,4 +311,182 @@ int BM_Is_Selected(BMesh *bm, void *element) { BMHeader *head = element; return BM_TestHFlag(head, BM_SELECT); -}
\ No newline at end of file +} + + +/* generic way to get data from an EditSelection type +These functions were written to be used by the Modifier widget when in Rotate about active mode, +but can be used anywhere. +EM_editselection_center +EM_editselection_normal +EM_editselection_plane +*/ +void BM_editselection_center(BMesh *em, float *center, BMEditSelection *ese) +{ + if (ese->type==BM_VERT) { + BMVert *eve= ese->data; + VecCopyf(center, eve->co); + } else if (ese->type==BM_EDGE) { + BMEdge *eed= ese->data; + VecAddf(center, eed->v1->co, eed->v2->co); + VecMulf(center, 0.5); + } else if (ese->type==BM_FACE) { + BMFace *efa= ese->data; + BM_Compute_Face_Center(em, efa, center); + } +} + +void BM_editselection_normal(float *normal, BMEditSelection *ese) +{ + if (ese->type==BM_VERT) { + BMVert *eve= ese->data; + VecCopyf(normal, eve->no); + } else if (ese->type==BM_EDGE) { + BMEdge *eed= ese->data; + float plane[3]; /* need a plane to correct the normal */ + float vec[3]; /* temp vec storage */ + + VecAddf(normal, eed->v1->no, eed->v2->no); + VecSubf(plane, eed->v2->co, eed->v1->co); + + /* the 2 vertex normals will be close but not at rightangles to the edge + for rotate about edge we want them to be at right angles, so we need to + do some extra colculation to correct the vert normals, + we need the plane for this */ + Crossf(vec, normal, plane); + Crossf(normal, plane, vec); + Normalize(normal); + + } else if (ese->type==BM_FACE) { + BMFace *efa= ese->data; + VecCopyf(normal, efa->no); + } +} + +/* Calculate a plane that is rightangles to the edge/vert/faces normal +also make the plane run allong an axis that is related to the geometry, +because this is used for the manipulators Y axis.*/ +void BM_editselection_plane(BMesh *em, float *plane, BMEditSelection *ese) +{ + if (ese->type==BM_VERT) { + BMVert *eve= ese->data; + float vec[3]={0,0,0}; + + if (ese->prev) { /*use previously selected data to make a usefull vertex plane */ + BM_editselection_center(em, vec, ese->prev); + VecSubf(plane, vec, eve->co); + } else { + /* make a fake plane thats at rightangles to the normal + we cant make a crossvec from a vec thats the same as the vec + unlikely but possible, so make sure if the normal is (0,0,1) + that vec isnt the same or in the same direction even.*/ + if (eve->no[0]<0.5) vec[0]=1; + else if (eve->no[1]<0.5) vec[1]=1; + else vec[2]=1; + Crossf(plane, eve->no, vec); + } + } else if (ese->type==BM_EDGE) { + BMEdge *eed= ese->data; + + /*the plane is simple, it runs allong the edge + however selecting different edges can swap the direction of the y axis. + this makes it less likely for the y axis of the manipulator + (running along the edge).. to flip less often. + at least its more pradictable */ + if (eed->v2->co[1] > eed->v1->co[1]) /*check which to do first */ + VecSubf(plane, eed->v2->co, eed->v1->co); + else + VecSubf(plane, eed->v1->co, eed->v2->co); + + } else if (ese->type==BM_FACE) { + BMFace *efa= ese->data; + float vec[3] = {0.0f, 0.0f, 0.0f}; + + /*for now, use face normal*/ + + /* make a fake plane thats at rightangles to the normal + we cant make a crossvec from a vec thats the same as the vec + unlikely but possible, so make sure if the normal is (0,0,1) + that vec isnt the same or in the same direction even.*/ + if (efa->no[0]<0.5) vec[0]=1.0f; + else if (efa->no[1]<0.5) vec[1]=1.0f; + else vec[2]=1.0f; + Crossf(plane, efa->no, vec); +#if 0 + + if (efa->v4) { /*if its a quad- set the plane along the 2 longest edges.*/ + float vecA[3], vecB[3]; + VecSubf(vecA, efa->v4->co, efa->v3->co); + VecSubf(vecB, efa->v1->co, efa->v2->co); + VecAddf(plane, vecA, vecB); + + VecSubf(vecA, efa->v1->co, efa->v4->co); + VecSubf(vecB, efa->v2->co, efa->v3->co); + VecAddf(vec, vecA, vecB); + /*use the biggest edge length*/ + if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]) + VecCopyf(plane, vec); + } else { + /*start with v1-2 */ + VecSubf(plane, efa->v1->co, efa->v2->co); + + /*test the edge between v2-3, use if longer */ + VecSubf(vec, efa->v2->co, efa->v3->co); + if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]) + VecCopyf(plane, vec); + + /*test the edge between v1-3, use if longer */ + VecSubf(vec, efa->v3->co, efa->v1->co); + if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]) + VecCopyf(plane, vec); + } +#endif + } + Normalize(plane); +} + +static int BM_check_selection(BMesh *em, void *data) +{ + BMEditSelection *ese; + + for(ese = em->selected.first; ese; ese = ese->next){ + if(ese->data == data) return 1; + } + + return 0; +} + +void BM_remove_selection(BMesh *em, void *data) +{ + BMEditSelection *ese; + for(ese=em->selected.first; ese; ese = ese->next){ + if(ese->data == data){ + BLI_freelinkN(&(em->selected),ese); + break; + } + } +} + +void BM_store_selection(BMesh *em, void *data) +{ + BMEditSelection *ese; + if(!BM_check_selection(em, data)){ + ese = (BMEditSelection*) MEM_callocN( sizeof(BMEditSelection), "BMEdit Selection"); + ese->type = ((BMHeader*)data)->type; + ese->data = data; + BLI_addtail(&(em->selected),ese); + } +} + +void BM_validate_selections(BMesh *em) +{ + BMEditSelection *ese, *nextese; + + ese = em->selected.first; + + while(ese){ + nextese = ese->next; + if (!BM_TestHFlag(ese->data, BM_SELECT)) BLI_freelinkN(&(em->selected), ese); + ese = nextese; + } +} diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index c013952a622..9df2bb8c202 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -83,12 +83,14 @@ static int point_in_triangle(double *v1, double *v2, double *v3, double *pt) * computing newell normal. * */ +#define FEQ(f1, f2) (ABS((double)(f1)-(double)(f2)) < 0.1) + static void compute_poly_normal(float normal[3], float (*verts)[3], int nverts) { - float *u, *v;/*, *w, v1[3], v2[3];*/ - double n[3] = {0.0, 0.0, 0.0}, l; - int i; + double u[3], v[3], w[3];/*, *w, v1[3], v2[3];*/ + double n[3] = {0.0, 0.0, 0.0}, l, v1[3], v2[3]; + int i, s=0; /*this fixes some weird numerical error*/ verts[0][0] += 0.0001f; @@ -96,9 +98,19 @@ static void compute_poly_normal(float normal[3], float (*verts)[3], int nverts) verts[0][2] += 0.0001f; for(i = 0; i < nverts; i++){ - u = verts[i]; - v = verts[(i+1) % nverts]; + VECCOPY(u, verts[i]); + VECCOPY(v, verts[(i+1) % nverts]); + VECCOPY(w, verts[(i+2) % nverts]); + VECSUB(v1, w, v); + VECSUB(v2, v, u); + Normalize_d(v1); + Normalize_d(v2); + + l = INPR(v1, v2); + if (l < 0.01 && l > -0.01) + continue; + /* newell's method so thats?: @@ -472,7 +484,7 @@ int linecrosses(double *v1, double *v2, double *v3, double *v4) note, there could be more winding cases then there needs to be. */ int linecrossesf(float *v1, float *v2, float *v3, float *v4) { - int w1, w2, w3, w4, w5; + int w1, w2, w3, w4, w5, ret; /* int test1_a, test1_a, test2_a, test2_a; @@ -504,12 +516,38 @@ int linecrossesf(float *v1, float *v2, float *v3, float *v4) return (w1 == w2) && (w2 == w3) && (w3 == w4);*/ + /*do an interval test on the x and y axes*/ + /*first do x axis*/ + #define T 0.01 + if (ABS(v1[1]-v2[1]) < T && ABS(v3[1]-v4[1]) < T && + ABS(v1[1]-v3[1]) < T) { + if (v3[0] >= v1[0] && v3[0] <= v2[0]) + return 1; + if (v4[0] >= v1[0] && v4[0] <= v2[0]) + return 1; + if (v3[0] <= v1[0] && v4[0] >= v2[0]) + return 1; + } + + /*now do y axis*/ + if (ABS(v1[0]-v2[0]) < T && ABS(v3[0]-v4[0]) < T && + ABS(v1[0]-v3[0]) < T) { + if (v3[1] >= v1[1] && v3[1] <= v2[1]) + return 1; + if (v4[1] >= v1[1] && v4[1] <= v2[1]) + return 1; + if (v3[1] <= v1[1] && v4[1] >= v2[1]) + return 1; + } + + /*now test winding*/ w1 = testedgesidef(v1, v3, v2); w2 = testedgesidef(v2, v4, v1); w3 = !testedgesidef(v1, v2, v3); w4 = testedgesidef(v3, v2, v4); w5 = !testedgesidef(v3, v1, v4); - return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5; + + return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5; } int goodline(float (*projectverts)[3], BMFace *f, int v1i, diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index a14f1d662ae..664e07f805b 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -195,12 +195,16 @@ BMFace *bmesh_addpolylist(BMesh *bm, BMFace *example){ */ void bmesh_free_vert(BMesh *bm, BMVert *v){ bm->totvert--; + BM_remove_selection(bm, v); + CustomData_bmesh_free_block(&bm->vdata, &v->head.data); BLI_mempool_free(bm->flagpool, v->head.flags); BLI_mempool_free(bm->vpool, v); } void bmesh_free_edge(BMesh *bm, BMEdge *e){ bm->totedge--; + BM_remove_selection(bm, e); + CustomData_bmesh_free_block(&bm->edata, &e->head.data); BLI_mempool_free(bm->flagpool, e->head.flags); BLI_mempool_free(bm->epool, e); @@ -208,6 +212,7 @@ void bmesh_free_edge(BMesh *bm, BMEdge *e){ void bmesh_free_poly(BMesh *bm, BMFace *f){ if (f == bm->act_face) bm->act_face = NULL; + BM_remove_selection(bm, f); bm->totface--; CustomData_bmesh_free_block(&bm->pdata, &f->head.data); diff --git a/source/blender/bmesh/operators/mesh_conv.c b/source/blender/bmesh/operators/mesh_conv.c index 26dd9026320..9944c9b8d23 100644 --- a/source/blender/bmesh/operators/mesh_conv.c +++ b/source/blender/bmesh/operators/mesh_conv.c @@ -131,6 +131,7 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) { f = BM_Make_Ngon(bm, v1, v2, fedges, mpoly->totloop, 0); f->head.flag = MEFlags_To_BMFlags(mpoly->flag, BM_FACE); + f->mat_nr = mpoly->mat_nr; if (i == me->act_face) bm->act_face = f; /*Copy over loop customdata*/ diff --git a/source/blender/bmesh/operators/subdivideop.c b/source/blender/bmesh/operators/subdivideop.c index 21da2775070..7164ed9f121 100644 --- a/source/blender/bmesh/operators/subdivideop.c +++ b/source/blender/bmesh/operators/subdivideop.c @@ -607,6 +607,7 @@ subdpattern *patterns[] = { typedef struct subd_facedata { BMVert *start; subdpattern *pat; + int totedgesel; //only used if pat was NULL, e.g. no pattern was found } subd_facedata; void esubdivide_exec(BMesh *bmesh, BMOperator *op) @@ -623,9 +624,12 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op) subdparams params; subd_facedata *facedata = NULL; V_DECLARE(facedata); + BMLoop *l, **splits = NULL, **loops = NULL; + V_DECLARE(splits); + V_DECLARE(loops); float smooth, fractal; int beauty; - int i, j, matched, a, b, numcuts; + int i, j, matched, a, b, numcuts, totesel; BMO_Flag_Buffer(bmesh, op, "edges", SUBD_SPLIT); @@ -658,13 +662,20 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op) V_RESET(edges); V_RESET(verts); + matched = 0; + i = 0; + totesel = 0; for (nl=BMIter_New(&liter, bmesh, BM_LOOPS_OF_FACE, face); nl; nl=BMIter_Step(&liter)) { V_GROW(edges); V_GROW(verts); edges[i] = nl->e; verts[i] = nl->v; + + if (BMO_TestFlag(bmesh, edges[i], SUBD_SPLIT)) + totesel++; + i++; } @@ -703,26 +714,37 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op) pat = patterns[i]; if (pat->len == face->len) { for (a=0; a<pat->len; a++) { - matched = 1; - for (b=0; b<pat->len; b++) { - j = (b + a) % pat->len; - if ((!!BMO_TestFlag(bmesh, edges[j], SUBD_SPLIT)) - != (!!pat->seledges[b])) { - matched = 0; - break; + matched = 1; + for (b=0; b<pat->len; b++) { + j = (b + a) % pat->len; + if ((!!BMO_TestFlag(bmesh, edges[j], SUBD_SPLIT)) + != (!!pat->seledges[b])) { + matched = 0; + break; + } } - } - if (matched) break; + if (matched) break; } if (matched) { V_GROW(facedata); - BMO_SetFlag(bmesh, face, SUBD_SPLIT); j = V_COUNT(facedata) - 1; + + BMO_SetFlag(bmesh, face, SUBD_SPLIT); + facedata[j].pat = pat; facedata[j].start = verts[a]; break; } } + + } + + if (!matched && totesel) { + V_GROW(facedata); + j = V_COUNT(facedata) - 1; + + BMO_SetFlag(bmesh, face, SUBD_SPLIT); + facedata[j].totedgesel = totesel; } } @@ -743,10 +765,73 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op) face; face=BMIter_Step(&fiter)) { /*figure out which pattern to use*/ V_RESET(verts); - if (BMO_TestFlag(bmesh, face, SUBD_SPLIT) == 0) continue; + if (BMO_TestFlag(bmesh, face, SUBD_SPLIT) == 0) + continue; pat = facedata[i].pat; - if (!pat) continue; + if (!pat && facedata[i].totedgesel == 2) { /*ok, no pattern. we still may be able to do something.*/ + BMFace *nf; + int vlen; + + V_RESET(loops); + V_RESET(splits); + + /*for case of two edges, connecting them shouldn't be too hard*/ + BM_ITER(l, &liter, bmesh, BM_LOOPS_OF_FACE, face) { + V_GROW(loops); + loops[V_COUNT(loops)-1] = l; + } + + vlen = V_COUNT(loops); + + /*find the boundary of one of the split edges*/ + for (a=1; a<vlen; a++) { + if (!BMO_TestFlag(bmesh, loops[a-1]->v, ELE_INNER) + && BMO_TestFlag(bmesh, loops[a]->v, ELE_INNER)) + break; + } + + if (BMO_TestFlag(bmesh, loops[(a+numcuts+1)%vlen]->v, ELE_INNER)) { + b = (a+numcuts+1)%vlen; + } else { + /*find the boundary of the other edge.*/ + for (j=0; j<vlen; j++) { + b = (j + a + numcuts + 1) % vlen; + if (!BMO_TestFlag(bmesh, loops[b==0 ? vlen-1 : b-1]->v, ELE_INNER) + && BMO_TestFlag(bmesh, loops[b]->v, ELE_INNER)) + break; + } + } + + b += numcuts - 1; + + for (j=0; j<numcuts; j++) { + V_GROW(splits); + splits[V_COUNT(splits)-1] = loops[a]; + + V_GROW(splits); + splits[V_COUNT(splits)-1] = loops[b]; + + b = (b-1) % vlen; + a = (a+1) % vlen; + } + + BM_LegalSplits(bmesh, face, splits, V_COUNT(splits)/2); + + for (j=0; j<V_COUNT(splits)/2; j++) { + if (splits[j*2]) { + BMFace *nf; + + nf = BM_Split_Face(bmesh, face, splits[j*a]->v, splits[j*2+1]->v, &nl, NULL); + } + } + + i++; + continue; + } else if (!pat) { + i++; + continue; + } j = a = 0; for (nl=BMIter_New(&liter, bmesh, BM_LOOPS_OF_FACE, face); @@ -777,6 +862,8 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op) if (facedata) V_FREE(facedata); if (edges) V_FREE(edges); if (verts) V_FREE(verts); + V_FREE(splits); + V_FREE(loops); BMO_Flag_To_Slot(bmesh, op, "outinner", ELE_INNER, BM_ALL); diff --git a/source/blender/editors/mesh/bmesh_select.c b/source/blender/editors/mesh/bmesh_select.c index c4f2a294d0b..760bb5b65e0 100644 --- a/source/blender/editors/mesh/bmesh_select.c +++ b/source/blender/editors/mesh/bmesh_select.c @@ -1140,8 +1140,8 @@ static void mouse_mesh_shortest_path(bContext *C, short mval[2]) Mesh *me= vc.obedit->data; int path = 0; - if (em->selected.last) { - EditSelection *ese = em->selected.last; + if (em->bm->selected.last) { + EditSelection *ese = em->bm->selected.last; if(ese && ese->type == BMEdge) { BMEdge *eed_act; @@ -1292,26 +1292,26 @@ static void EDBM_strip_selections(BMEditMesh *em) BMEditSelection *ese, *nextese; if(!(em->selectmode & SCE_SELECT_VERTEX)){ - ese = em->selected.first; + ese = em->bm->selected.first; while(ese){ nextese = ese->next; - if(ese->type == BM_VERT) BLI_freelinkN(&(em->selected),ese); + if(ese->type == BM_VERT) BLI_freelinkN(&(em->bm->selected),ese); ese = nextese; } } if(!(em->selectmode & SCE_SELECT_EDGE)){ - ese=em->selected.first; + ese=em->bm->selected.first; while(ese){ nextese = ese->next; - if(ese->type == BM_EDGE) BLI_freelinkN(&(em->selected), ese); + if(ese->type == BM_EDGE) BLI_freelinkN(&(em->bm->selected), ese); ese = nextese; } } if(!(em->selectmode & SCE_SELECT_FACE)){ - ese=em->selected.first; + ese=em->bm->selected.first; while(ese){ nextese = ese->next; - if(ese->type == BM_FACE) BLI_freelinkN(&(em->selected), ese); + if(ese->type == BM_FACE) BLI_freelinkN(&(em->bm->selected), ese); ese = nextese; } } diff --git a/source/blender/editors/mesh/bmesh_selecthistory.c b/source/blender/editors/mesh/bmesh_selecthistory.c index 9421a98a11c..5fb19dc1648 100644 --- a/source/blender/editors/mesh/bmesh_selecthistory.c +++ b/source/blender/editors/mesh/bmesh_selecthistory.c @@ -88,57 +88,19 @@ #include "BLO_sys_types.h" // for intptr_t support -/* XXX */ -static void waitcursor() {} -static int pupmenu() {return 0;} +/*these wrap equivilent bmesh functions. I'm in two minds of it we should + just use the bm functions directly; on the one hand, there's no real + need (at the moment) to wrap them, but on the other hand having these + wrapped avoids a confusing mess of mixing BM_ and EDBM_ namespaces.*/ -/* generic way to get data from an EditSelection type -These functions were written to be used by the Modifier widget when in Rotate about active mode, -but can be used anywhere. -EM_editselection_center -EM_editselection_normal -EM_editselection_plane -*/ void EDBM_editselection_center(BMEditMesh *em, float *center, BMEditSelection *ese) { - if (ese->type==BM_VERT) { - BMVert *eve= ese->data; - VecCopyf(center, eve->co); - } else if (ese->type==BM_EDGE) { - BMEdge *eed= ese->data; - VecAddf(center, eed->v1->co, eed->v2->co); - VecMulf(center, 0.5); - } else if (ese->type==BM_FACE) { - BMFace *efa= ese->data; - BM_Compute_Face_Center(em->bm, efa, center); - } + BM_editselection_center(em->bm, center, ese); } void EDBM_editselection_normal(float *normal, BMEditSelection *ese) { - if (ese->type==BM_VERT) { - BMVert *eve= ese->data; - VecCopyf(normal, eve->no); - } else if (ese->type==BM_EDGE) { - BMEdge *eed= ese->data; - float plane[3]; /* need a plane to correct the normal */ - float vec[3]; /* temp vec storage */ - - VecAddf(normal, eed->v1->no, eed->v2->no); - VecSubf(plane, eed->v2->co, eed->v1->co); - - /* the 2 vertex normals will be close but not at rightangles to the edge - for rotate about edge we want them to be at right angles, so we need to - do some extra colculation to correct the vert normals, - we need the plane for this */ - Crossf(vec, normal, plane); - Crossf(normal, plane, vec); - Normalize(normal); - - } else if (ese->type==BM_FACE) { - BMFace *efa= ese->data; - VecCopyf(normal, efa->no); - } + BM_editselection_normal(normal, ese); } /* Calculate a plane that is rightangles to the edge/vert/faces normal @@ -146,125 +108,25 @@ also make the plane run allong an axis that is related to the geometry, because this is used for the manipulators Y axis.*/ void EDBM_editselection_plane(BMEditMesh *em, float *plane, BMEditSelection *ese) { - if (ese->type==BM_VERT) { - BMVert *eve= ese->data; - float vec[3]={0,0,0}; - - if (ese->prev) { /*use previously selected data to make a usefull vertex plane */ - EDBM_editselection_center(em, vec, ese->prev); - VecSubf(plane, vec, eve->co); - } else { - /* make a fake plane thats at rightangles to the normal - we cant make a crossvec from a vec thats the same as the vec - unlikely but possible, so make sure if the normal is (0,0,1) - that vec isnt the same or in the same direction even.*/ - if (eve->no[0]<0.5) vec[0]=1; - else if (eve->no[1]<0.5) vec[1]=1; - else vec[2]=1; - Crossf(plane, eve->no, vec); - } - } else if (ese->type==BM_EDGE) { - BMEdge *eed= ese->data; - - /*the plane is simple, it runs allong the edge - however selecting different edges can swap the direction of the y axis. - this makes it less likely for the y axis of the manipulator - (running along the edge).. to flip less often. - at least its more pradictable */ - if (eed->v2->co[1] > eed->v1->co[1]) /*check which to do first */ - VecSubf(plane, eed->v2->co, eed->v1->co); - else - VecSubf(plane, eed->v1->co, eed->v2->co); - - } else if (ese->type==BM_FACE) { - BMFace *efa= ese->data; - float vec[3] = {0.0f, 0.0f, 0.0f}; - - /*for now, use face normal*/ - - /* make a fake plane thats at rightangles to the normal - we cant make a crossvec from a vec thats the same as the vec - unlikely but possible, so make sure if the normal is (0,0,1) - that vec isnt the same or in the same direction even.*/ - if (efa->no[0]<0.5) vec[0]=1.0f; - else if (efa->no[1]<0.5) vec[1]=1.0f; - else vec[2]=1.0f; - Crossf(plane, efa->no, vec); -#if 0 - - if (efa->v4) { /*if its a quad- set the plane along the 2 longest edges.*/ - float vecA[3], vecB[3]; - VecSubf(vecA, efa->v4->co, efa->v3->co); - VecSubf(vecB, efa->v1->co, efa->v2->co); - VecAddf(plane, vecA, vecB); - - VecSubf(vecA, efa->v1->co, efa->v4->co); - VecSubf(vecB, efa->v2->co, efa->v3->co); - VecAddf(vec, vecA, vecB); - /*use the biggest edge length*/ - if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]) - VecCopyf(plane, vec); - } else { - /*start with v1-2 */ - VecSubf(plane, efa->v1->co, efa->v2->co); - - /*test the edge between v2-3, use if longer */ - VecSubf(vec, efa->v2->co, efa->v3->co); - if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]) - VecCopyf(plane, vec); - - /*test the edge between v1-3, use if longer */ - VecSubf(vec, efa->v3->co, efa->v1->co); - if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]) - VecCopyf(plane, vec); - } -#endif - } - Normalize(plane); + BM_editselection_plane(em->bm, plane, ese); } static int EDBM_check_selection(BMEditMesh *em, void *data) { - BMEditSelection *ese; - - for(ese = em->selected.first; ese; ese = ese->next){ - if(ese->data == data) return 1; - } - - return 0; + BM_check_selection(em, data); } void EDBM_remove_selection(BMEditMesh *em, void *data) { - BMEditSelection *ese; - for(ese=em->selected.first; ese; ese = ese->next){ - if(ese->data == data){ - BLI_freelinkN(&(em->selected),ese); - break; - } - } + BM_remove_selection(em->bm, data); } void EDBM_store_selection(BMEditMesh *em, void *data) { - BMEditSelection *ese; - if(!EDBM_check_selection(em, data)){ - ese = (BMEditSelection*) MEM_callocN( sizeof(BMEditSelection), "BMEdit Selection"); - ese->type = ((BMHeader*)data)->type; - ese->data = data; - BLI_addtail(&(em->selected),ese); - } + BM_store_selection(em->bm, data); } void EDBM_validate_selections(BMEditMesh *em) { - BMEditSelection *ese, *nextese; - - ese = em->selected.first; - - while(ese){ - nextese = ese->next; - if (!BM_TestHFlag(ese->data, BM_SELECT)) BLI_freelinkN(&(em->selected), ese); - ese = nextese; - } + BM_validate_selections(em->bm); } diff --git a/source/blender/editors/mesh/bmeshutils.c b/source/blender/editors/mesh/bmeshutils.c index e3ec1c16ce3..5e8c295d7b8 100644 --- a/source/blender/editors/mesh/bmeshutils.c +++ b/source/blender/editors/mesh/bmeshutils.c @@ -363,7 +363,7 @@ BMFace *EDBM_get_actFace(BMEditMesh *em, int sloppy) BMFace *efa= NULL; BMEditSelection *ese; - ese = em->selected.last; + ese = em->bm->selected.last; for (; ese; ese=ese->prev){ if(ese->type == BM_FACE) { efa = (BMFace *)ese->data; @@ -395,7 +395,7 @@ void EDBM_selectmode_flush(BMEditMesh *em) int EDBM_get_actSelection(BMEditMesh *em, BMEditSelection *ese) { - BMEditSelection *ese_last = em->selected.last; + BMEditSelection *ese_last = em->bm->selected.last; BMFace *efa = EDBM_get_actFace(em, 0); ese->next = ese->prev = NULL; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 0c521512c12..99e68f3cf6b 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2074,8 +2074,8 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object BMEdge *eed_act = NULL; BMVert *eve_act = NULL; - if (em->selected.last) { - BMEditSelection *ese = em->selected.last; + if (em->bm->selected.last) { + BMEditSelection *ese = em->bm->selected.last; /* face is handeled above */ /*if (ese->type == EDITFACE ) { efa_act = (EditFace *)ese->data; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index aeccaee070e..f8b66dbca21 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2182,8 +2182,8 @@ static void createTransEditVerts(bContext *C, TransInfo *t) if (countsel==0) return; /* check active */ - if (em->selected.last) { - BMEditSelection *ese = em->selected.last; + if (em->bm->selected.last) { + BMEditSelection *ese = em->bm->selected.last; if ( ese->type == EDITVERT ) { eve_act = (BMVert *)ese->data; } |