diff --git a/source/blender/bmesh/bmesh_operator_api.h b/source/blender/bmesh/bmesh_operator_api.h index 6717c23ffe2..cbfd07d8923 100644 --- a/source/blender/bmesh/bmesh_operator_api.h +++ b/source/blender/bmesh/bmesh_operator_api.h @@ -259,6 +259,12 @@ void *BMO_Get_MapPointer(BMesh *bm, BMOperator *op, int slotcode, for (; key; key=BMO_IterStep(&oiter)) { val = BMO_IterMapVal(&oiter); //do something with the key/val pair + //note that val is a pointer to the val data, + //whether it's a float, pointer, whatever. + // + // so to get a pointer, for example, use: + // *((void**)BMO_IterMapVal(&oiter)); + //or something like that. } */ diff --git a/source/blender/bmesh/bmesh_operators.h b/source/blender/bmesh/bmesh_operators.h index 75aa09518e1..74c0bdcc869 100644 --- a/source/blender/bmesh/bmesh_operators.h +++ b/source/blender/bmesh/bmesh_operators.h @@ -16,6 +16,7 @@ enum { //bounding edges of split faces BMOP_SPLIT_BOUNDS_EDGEMAP, /*boundarymap*/ + BMOP_SPLIT_ISOLATED_VERTS_MAP, /*isovertmap*/ BMOP_SPLIT_TOTSLOT, }; @@ -31,6 +32,7 @@ enum { /*we need a map for verts duplicated not connected to any faces, too.*/ BMOP_DUPE_BOUNDS_EDGEMAP, /*boundarymap*/ + BMOP_DUPE_ISOLATED_VERTS_MAP, /*isovertmap*/ BMOP_DUPE_TOTSLOT }; diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index b84937dc2fa..cbeceae384b 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -103,7 +103,8 @@ BMOpDefine def_dupeop = { {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, {BMOP_OPSLOT_ELEMENT_BUF, "origout"}, {BMOP_OPSLOT_ELEMENT_BUF, "newout"}, - {BMOP_OPSLOT_MAPPING, "boundarymap"}}, + {BMOP_OPSLOT_MAPPING, "boundarymap"}, + {BMOP_OPSLOT_MAPPING, "isovertmap"}}, dupeop_exec, BMOP_DUPE_TOTSLOT, 0 @@ -113,7 +114,8 @@ BMOpDefine def_splitop = { "split", {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, - {BMOP_OPSLOT_MAPPING, "boundarymap"}}, + {BMOP_OPSLOT_MAPPING, "boundarymap"}, + {BMOP_OPSLOT_MAPPING, "isovertmap"}}, splitop_exec, BMOP_SPLIT_TOTSLOT, 0 diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index f0010b52fbb..1f065353c85 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -637,7 +637,6 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3], } } -#if 1 /*each pair of loops defines a new edge, a split. this function goes through and sets pairs that are geometrically invalid to null. a split is invalid, if it forms a concave angle or it intersects other @@ -718,9 +717,6 @@ void BM_LegalSplits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) shrink_edgef(v1, v2, 1.00001f); if (linecrossesf(p1, p2, mid, out)) clen++; - //else if (linecrossesf(p2, p1, out, mid)) clen++; - //else if (linecrossesf(p1, p2, out, mid)) clen++; - } if (clen%2 == 0) { @@ -764,4 +760,3 @@ void BM_LegalSplits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) if (projverts != projectverts) MEM_freeN(projverts); if (edgeverts != edgevertsstack) MEM_freeN(edgeverts); } -#endif diff --git a/source/blender/bmesh/operators/bmesh_dupeops.c b/source/blender/bmesh/operators/bmesh_dupeops.c index 8c92e3b81ce..c27b7dc8b3b 100644 --- a/source/blender/bmesh/operators/bmesh_dupeops.c +++ b/source/blender/bmesh/operators/bmesh_dupeops.c @@ -147,7 +147,7 @@ static BMFace *copy_face(BMesh *source_mesh, BMFace *source_face, BMesh *target_ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target) { - BMVert *v = NULL; + BMVert *v = NULL, *v2; BMEdge *e = NULL, **edar = NULL; BMLoop *l = NULL; BMFace *f = NULL; @@ -215,7 +215,9 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target) /*finally dupe all loose vertices*/ for(v = BMIter_New(&verts, source, BM_VERTS, source); v; v = BMIter_Step(&verts)){ if(BMO_TestFlag(source, (BMHeader*)v, DUPE_INPUT) && (!BMO_TestFlag(source, (BMHeader*)v, DUPE_DONE))){ - copy_vertex(source, v, target, vhash); + v2 = copy_vertex(source, v, target, vhash); + BMO_Insert_MapPointer(source, op, + BMOP_DUPE_ISOLATED_VERTS_MAP, v, v2); BMO_SetFlag(source, (BMHeader*)v, DUPE_DONE); } } @@ -390,7 +392,9 @@ void splitop_exec(BMesh *bm, BMOperator *op) BMO_CopySlot(&dupeop, splitop, BMOP_DUPE_NEW, BMOP_SPLIT_MULTOUT); BMO_CopySlot(&dupeop, splitop, BMOP_DUPE_BOUNDS_EDGEMAP, BMOP_SPLIT_BOUNDS_EDGEMAP); - + BMO_CopySlot(&dupeop, splitop, BMOP_DUPE_ISOLATED_VERTS_MAP, + BMOP_SPLIT_ISOLATED_VERTS_MAP); + /*cleanup*/ BMO_Finish_Op(bm, &delop); BMO_Finish_Op(bm, &dupeop); diff --git a/source/blender/bmesh/operators/extrudeops.c b/source/blender/bmesh/operators/extrudeops.c index 1d2135aadbd..3fa3161328c 100644 --- a/source/blender/bmesh/operators/extrudeops.c +++ b/source/blender/bmesh/operators/extrudeops.c @@ -19,9 +19,9 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op) BMOperator dupeop, delop; BMOIter siter; BMIter iter, fiter, viter; - BMEdge *e, *newedge, *e2; + BMEdge *e, *newedge, *e2, *ce; BMLoop *l, *l2; - BMVert *verts[4], *v; + BMVert *verts[4], *v, *v2; BMFace *f; int rlen, found, delorig=0, i, reverse; @@ -100,8 +100,10 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op) newedge = BMO_IterMapVal(&siter); newedge = *(BMEdge**)newedge; if (!newedge) continue; + if (!newedge->loop) ce = e; + else ce = newedge; - if (newedge->loop->v == newedge->v1) { + if (ce->loop && (ce->loop->v == ce->v1)) { verts[0] = e->v1; verts[1] = e->v2; verts[2] = newedge->v2; @@ -150,7 +152,13 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op) } } - + /*link isolated verts*/ + v = BMO_IterNew(&siter, bm, &dupeop, BMOP_DUPE_ISOLATED_VERTS_MAP); + for (; v; v=BMO_IterStep(&siter)) { + v2 = *((void**)BMO_IterMapVal(&siter)); + BM_Make_Edge(bm, v, v2, v->edge, 1); + } + /*cleanup*/ if (delorig) BMO_Finish_Op(bm, &delop); BMO_Finish_Op(bm, &dupeop); diff --git a/source/blender/editors/mesh/editmesh_lib.c b/source/blender/editors/mesh/editmesh_lib.c index 6e745744c18..ca495893d92 100644 --- a/source/blender/editors/mesh/editmesh_lib.c +++ b/source/blender/editors/mesh/editmesh_lib.c @@ -1165,7 +1165,7 @@ short BM_extrude_edgeflag(Object *obedit, BMesh *bm, int eflag, float *nor) BMO_Init_Op(&extop, BMOP_EXTRUDE_EDGECONTEXT); BMO_HeaderFlag_To_Slot(bm, &extop, BMOP_EXFACE_EDGEFACEIN, - flag, BM_EDGE|BM_FACE); + flag, BM_VERT|BM_EDGE|BM_FACE); for (edge=BMIter_New(&iter, bm, BM_EDGES, NULL); edge; edge=BMIter_Step(&iter)) { BM_Select_Edge(bm, edge, 0); @@ -1802,9 +1802,22 @@ short extrudeflag_vert(Object *obedit, EditMesh *em, short flag, float *nor) /* generic extrude */ short extrudeflag(Object *obedit, EditMesh *em, short flag, float *nor) { - if(em->selectmode & SCE_SELECT_VERTEX) - return extrudeflag_vert(obedit, em, flag, nor); - else + if(em->selectmode & SCE_SELECT_VERTEX) { + EditEdge *eed; + + /*ensure vert flags are consistent for edge selections*/ + for (eed=em->edges.first; eed; eed=eed->next) { + if (eed->f & flag) { + eed->v1->f |= flag; + eed->v2->f |= flag; + } else { + if ((eed->v1->f & flag) && (eed->v2->f & flag)) + eed->f |= flag; + } + } + + return extrudeflag_edge(obedit, em, flag, nor); + } else return extrudeflag_edge(obedit, em, flag, nor); }