diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index e7e8c1e1b0d..65c1ef27214 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -223,8 +223,11 @@ void BM_Compute_Normals(struct BMesh *bm); struct BMVert *BM_Make_Vert(struct BMesh *bm, float co[3], struct BMVert *example); struct BMEdge *BM_Make_Edge(struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMEdge *example, int nodouble); struct BMFace *BM_Make_Quadtriangle(struct BMesh *bm, struct BMVert **verts, BMEdge **edges, int len, struct BMFace *example, int nodouble); -/*more easier to use version of BM_Make_Quadtriangle*/ -BMFace *BM_Make_QuadTri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4, BMFace *example); + +/*more easier to use version of BM_Make_Quadtriangle. + creates edges if necassary.*/ +BMFace *BM_Make_QuadTri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, + BMVert *v4, BMFace *example, int nodouble); /*makes an ngon from an unordered list of edges. v1 and v2 must be the verts defining edges[0], and define the winding of the new face.*/ diff --git a/source/blender/bmesh/bmesh_operator_api.h b/source/blender/bmesh/bmesh_operator_api.h index 2aee9b4813a..4990a296db1 100644 --- a/source/blender/bmesh/bmesh_operator_api.h +++ b/source/blender/bmesh/bmesh_operator_api.h @@ -221,6 +221,11 @@ void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, in /*clears tool-flag flag from all elements inside a slot array.*/ void BMO_Unflag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag); +/*tool-flags all elements inside an element slot array with flag flag.*/ +void BMO_HeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag); +/*clears tool-flag flag from all elements inside a slot array.*/ +void BMO_UnHeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag); + /*puts every element of type type (which is a bitmask) with header flag flag, into a slot.*/ void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag, int type); diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index a00560fa3d5..ea97bfa8886 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -127,23 +127,29 @@ BMEdge *BM_Make_Edge(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge *example, int nod * */ -BMFace *BM_Make_QuadTri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4, BMFace *example) +BMFace *BM_Make_QuadTri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, + BMVert *v4, BMFace *example, int nodouble) { BMEdge *edar[4]; BMVert *vtar[4]; - edar[0] = v1->edge; - edar[1] = v1->edge; - edar[2] = v1->edge; - if (v4) edar[3] = v1->edge; + edar[0] = bmesh_disk_existedge(v1, v2); + edar[1] = bmesh_disk_existedge(v2, v3); + edar[2] = bmesh_disk_existedge(v3, v4? v4 : v1); + if (v4) edar[3] = bmesh_disk_existedge(v4, v1); else edar[3] = NULL; + if (!edar[0]) edar[0] = BM_Make_Edge(bm, v1, v2, NULL, 0); + if (!edar[1]) edar[1] = BM_Make_Edge(bm, v2, v3, NULL, 0); + if (!edar[2]) edar[2] = BM_Make_Edge(bm, v3, v4?v4:v1, NULL, 0); + if (!edar[0] && v4) edar[0] = BM_Make_Edge(bm, v4, v1, NULL, 0); + vtar[0] = v1; vtar[1] = v2; vtar[2] = v3; vtar[3] = v4; - return BM_Make_Quadtriangle(bm, vtar, edar, v4?4:3, example, 0); + return BM_Make_Quadtriangle(bm, vtar, edar, v4?4:3, example, nodouble); } /*remove the edge array bits from this. Its not really needed?*/ diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 06da42e8d6e..31398b80ce6 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -5,6 +5,28 @@ /*applies a transform to vertices*/ +/*contextual_create is fkey, it creates + new faces, makes stuff from edge nets, + makes wire edges, etc. it also dissolves + faces.*/ +BMOpDefine def_contextual_create= { + "contextual_create", + {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, + {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, + {0, /*null-terminating sentinel*/}}, + bmesh_contextual_create_exec, + 0, +}; + +BMOpDefine def_edgenet_fill= { + "edgenet_fill", + {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, + {BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, + {0, /*null-terminating sentinel*/}}, + bmesh_edgenet_fill_exec, + 0, +}; + BMOpDefine def_translate= { "translate", {{BMOP_OPSLOT_VEC, "vec"}, @@ -213,6 +235,8 @@ BMOpDefine *opdefines[] = { &def_object_load_bmesh, &def_transform, &def_translate, + &def_edgenet_fill, + &def_contextual_create, }; int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*)); diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 812cd5cd9d9..d57bc826fdb 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -265,7 +265,7 @@ void BMO_Set_Mat(struct BMOperator *op, char *slotname, float *mat, int size) { BMOpSlot *slot = BMO_GetSlot(op, slotname); if( !(slot->slottype == BMOP_OPSLOT_MAT) ) - return 0; + return; slot->len = 4; slot->data.p = BLI_memarena_alloc(op->arena, sizeof(float)*4*4); @@ -684,6 +684,51 @@ void BMO_Flag_To_Slot(BMesh *bm, BMOperator *op, char *slotname, int flag, int t } } +/* + * + * BMO_FLAG_BUFFER + * + * Header Flags elements in a slots buffer, automatically + * using the selection API where appropriate. + * +*/ + +void BMO_HeaderFlag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag) +{ + BMOpSlot *slot = BMO_GetSlot(op, slotname); + BMHeader **data = slot->data.p; + int i; + + for(i = 0; i < slot->len; i++) { + BM_SetHFlag(data[i], flag); + if (flag & BM_SELECT) + BM_Select(bm, data[i], 1); + } +} + +/* + * + * BMO_FLAG_BUFFER + * + * Removes flags from elements in a slots buffer, automatically + * using the selection API where appropriate. + * +*/ + +void BMO_UnHeaderFlag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag) +{ + BMOpSlot *slot = BMO_GetSlot(op, slotname); + BMHeader **data = slot->data.p; + int i; + + for(i = 0; i < slot->len; i++) { + BM_ClearHFlag(data[i], flag); + if (flag & BM_SELECT) + BM_Select(bm, data[i], 0); + } +} + + /* * * BMO_FLAG_BUFFER diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index a3cbb67b660..fdd1bbea9c2 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -25,5 +25,7 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op); void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op); void bmesh_translate_exec(BMesh *bm, BMOperator *op); void bmesh_transform_exec(BMesh *bm, BMOperator *op); +void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op); +void bmesh_edgenet_fill_exec(BMesh *bm, BMOperator *op); #endif diff --git a/source/blender/bmesh/operators/createops.c b/source/blender/bmesh/operators/createops.c new file mode 100644 index 00000000000..ef4d3ff661c --- /dev/null +++ b/source/blender/bmesh/operators/createops.c @@ -0,0 +1,156 @@ +#include "MEM_guardedalloc.h" + +#include "BKE_utildefines.h" + +#include "BLI_ghash.h" +#include "BLI_memarena.h" +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "bmesh.h" +#include "bmesh_operators_private.h" + +#define ELE_NEW 1 +#define ELE_OUT 2 + +void bmesh_edgenet_fill_exec(BMesh *bm, BMOperator *op) +{ + /*unimplemented, need to think on how to do this. probably are graph + theory stuff that could help with this problem.*/ +} + +/* evaluate if entire quad is a proper convex quad */ +static int convex(float *v1, float *v2, float *v3, float *v4) +{ + float nor[3], nor1[3], nor2[3], vec[4][2]; + + /* define projection, do both trias apart, quad is undefined! */ + CalcNormFloat(v1, v2, v3, nor1); + CalcNormFloat(v1, v3, v4, nor2); + nor[0]= ABS(nor1[0]) + ABS(nor2[0]); + nor[1]= ABS(nor1[1]) + ABS(nor2[1]); + nor[2]= ABS(nor1[2]) + ABS(nor2[2]); + + if(nor[2] >= nor[0] && nor[2] >= nor[1]) { + vec[0][0]= v1[0]; vec[0][1]= v1[1]; + vec[1][0]= v2[0]; vec[1][1]= v2[1]; + vec[2][0]= v3[0]; vec[2][1]= v3[1]; + vec[3][0]= v4[0]; vec[3][1]= v4[1]; + } + else if(nor[1] >= nor[0] && nor[1]>= nor[2]) { + vec[0][0]= v1[0]; vec[0][1]= v1[2]; + vec[1][0]= v2[0]; vec[1][1]= v2[2]; + vec[2][0]= v3[0]; vec[2][1]= v3[2]; + vec[3][0]= v4[0]; vec[3][1]= v4[2]; + } + else { + vec[0][0]= v1[1]; vec[0][1]= v1[2]; + vec[1][0]= v2[1]; vec[1][1]= v2[2]; + vec[2][0]= v3[1]; vec[2][1]= v3[2]; + vec[3][0]= v4[1]; vec[3][1]= v4[2]; + } + + /* linetests, the 2 diagonals have to instersect to be convex */ + if( IsectLL2Df(vec[0], vec[2], vec[1], vec[3]) > 0 ) return 1; + return 0; +} + +/*this is essentially new fkey*/ +void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op) +{ + BMOperator op2; + BMOIter oiter; + BMIter iter, liter; + BMHeader *h; + BMVert *v, *verts[4]; + BMEdge *e; + BMLoop *l; + BMFace *f; + int totv=0, tote=0, totf=0, amount; + + /*count number of each element type we were passed*/ + BMO_ITER(h, &oiter, bm, op, "geom") { + switch (h->type) { + case BM_VERT: totv++; break; + case BM_EDGE: tote++; break; + case BM_FACE: totf++; break; + } + + BMO_SetFlag(bm, h, ELE_NEW); + } + + /*first call dissolve faces*/ + BMO_InitOpf(bm, &op2, "dissolvefaces faces=%ff", ELE_NEW); + BMO_Exec_Op(bm, &op2); + BMO_ITER(f, &oiter, bm, &op2, "regionout") { + BMO_SetFlag(bm, f, ELE_OUT); + + /*unflag verts associated with dissolved faces*/ + BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) { + BMO_ClearFlag(bm, l->v, ELE_NEW); + } + } + BMO_Finish_Op(bm, &op2); + + /*then call edgenet create, which may still be unimplemented, heh*/ + BMO_InitOpf(bm, &op2, "edgenet_fill edges=%fe", ELE_NEW); + BMO_Exec_Op(bm, &op2); + BMO_ITER(f, &oiter, bm, &op2, "faceout") { + BMO_SetFlag(bm, f, ELE_OUT); + + /*unflag verts associated with the output faces*/ + BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) { + BMO_ClearFlag(bm, l->v, ELE_NEW); + } + } + BMO_Finish_Op(bm, &op2); + + /*now, count how many verts we have*/ + amount = 0; + BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) { + if (BMO_TestFlag(bm, v, ELE_NEW)) { + verts[amount] = v; + amount++; + + if (amount > 4) break; + } + } + + if (amount == 2) { + /*create edge*/ + e = BM_Make_Edge(bm, verts[0], verts[1], NULL, 1); + BMO_SetFlag(bm, e, ELE_OUT); + } else if (amount == 3) { + /*create triangle*/ + BM_Make_QuadTri(bm, verts[0], verts[1], verts[2], NULL, NULL, 1); + } else if (amount == 4) { + f = NULL; + + /* the order of vertices can be anything, 6 cases to check */ + if( convex(verts[0]->co, verts[1]->co, verts[2]->co, verts[3]->co) ) { + f= BM_Make_QuadTri(bm, verts[0], verts[1], verts[2], verts[3], NULL, 1); + } + else if( convex(verts[0]->co, verts[2]->co, verts[3]->co, verts[1]->co) ) { + f= BM_Make_QuadTri(bm, verts[0], verts[2], verts[3], verts[1], NULL, 1); + } + else if( convex(verts[0]->co, verts[2]->co, verts[1]->co, verts[3]->co) ) { + f= BM_Make_QuadTri(bm, verts[0], verts[2], verts[1], verts[3], NULL, 1); + } + else if( convex(verts[0]->co, verts[1]->co, verts[3]->co, verts[2]->co) ) { + f= BM_Make_QuadTri(bm, verts[0], verts[1], verts[3], verts[2], NULL, 1); + } + else if( convex(verts[0]->co, verts[3]->co, verts[2]->co, verts[1]->co) ) { + f= BM_Make_QuadTri(bm, verts[0], verts[3], verts[2], verts[1], NULL, 1); + } + else if( convex(verts[0]->co, verts[3]->co, verts[1]->co, verts[2]->co) ) { + f= BM_Make_QuadTri(bm, verts[0], verts[3], verts[1], verts[2], NULL, 1); + } + else { + printf("cannot find nice quad from concave set of vertices\n"); + } + + if (f) BMO_SetFlag(bm, f, ELE_OUT); + } + + BMO_Flag_To_Slot(bm, op, "faceout", ELE_OUT, BM_FACE); +} diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index d8a9c3e994f..f779a77335d 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -949,3 +949,129 @@ void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } + +static int delete_mesh(Object *obedit, wmOperator *op, int event, Scene *scene) +{ + BMEditMesh *bem = ((Mesh*)obedit->data)->edit_btmesh; + + if(event<1) return OPERATOR_CANCELLED; + + if(event==10 ) { + //"Erase Vertices"; + + if (!EDBM_CallOpf(bem, op, "del geom=%hv context=%i", BM_SELECT, DEL_VERTS)) + return OPERATOR_CANCELLED; + } + else if(event==7) { + //"Dissolve Verts" + if (!EDBM_CallOpf(bem, op, "dissolveverts verts=%hv",BM_SELECT)) + return OPERATOR_CANCELLED; + } + else if(event==6) { + //"Erase Edge Loop"; + } + else if(event==4) { + if (!EDBM_CallOpf(bem, op, "del geom=%hef context=%i", BM_SELECT, DEL_EDGESFACES)) + return OPERATOR_CANCELLED; + } + else if(event==1) { + //"Erase Edges" + if (!EDBM_CallOpf(bem, op, "del geom=%he context=%i", BM_SELECT, DEL_EDGES)) + return OPERATOR_CANCELLED; + } + else if(event==2) { + //"Erase Faces"; + if (!EDBM_CallOpf(bem, op, "del geom=%hf context=%i", BM_SELECT, DEL_FACES)) + return OPERATOR_CANCELLED; + } + else if(event==5) { + //"Erase Only Faces"; + if (!EDBM_CallOpf(bem, op, "del geom=%hf context=%d", + BM_SELECT, DEL_ONLYFACES)) + return OPERATOR_CANCELLED; + } + + DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + + return OPERATOR_FINISHED; +} + +/* Note, these values must match delete_mesh() event values */ +static EnumPropertyItem prop_mesh_delete_types[] = { + {7, "DISSOLVE", "Dissolve Verts", ""}, + {10,"VERT", "Vertices", ""}, + {1, "EDGE", "Edges", ""}, + {2, "FACE", "Faces", ""}, + {4, "EDGE_FACE","Edges & Faces", ""}, + {5, "ONLY_FACE","Only Faces", ""}, + {6, "EDGE_LOOP","Edge Loop", ""}, + {0, NULL, NULL, NULL} +}; + +static int delete_mesh_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + Scene *scene = CTX_data_scene(C); + + delete_mesh(obedit, op, RNA_enum_get(op->ptr, "type"), scene); + + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA|ND_GEOM_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void MESH_OT_delete(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete"; + ot->idname= "MESH_OT_delete"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= delete_mesh_exec; + + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /*props */ + RNA_def_enum(ot->srna, "type", prop_mesh_delete_types, 10, "Type", "Method used for deleting mesh data"); +} + + +static int addedgeface_mesh_exec(bContext *C, wmOperator *op) +{ + BMOperator bmop; + Object *obedit= CTX_data_edit_object(C); + BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh; + + if (!EDBM_InitOpf(em, &bmop, op, "contextual_create geom=%hfev", BM_SELECT)) + return OPERATOR_CANCELLED; + + BMO_Exec_Op(em->bm, &bmop); + BMO_HeaderFlag_Buffer(em->bm, &bmop, "faceout", BM_SELECT); + + if (!EDBM_FinishOp(em, &bmop, op, 1)) + return OPERATOR_CANCELLED; + + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); + + return OPERATOR_FINISHED; +} + +void MESH_OT_edge_face_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Make Edge/Face"; + ot->idname= "MESH_OT_edge_face_add"; + + /* api callbacks */ + ot->exec= addedgeface_mesh_exec; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + +} diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 318a217bcd3..405d2a19d41 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -711,37 +711,6 @@ static void addedgeface_mesh(Mesh *me, BMEditMesh *bem, wmOperator *op) BKE_mesh_end_editmesh(me, em); } -static int addedgeface_mesh_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh; - - addedgeface_mesh((Mesh *)obedit->data, em, op); - - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - - DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA); - - return OPERATOR_FINISHED; -} - -void MESH_OT_edge_face_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Make Edge/Face"; - ot->idname= "MESH_OT_edge_face_add"; - - /* api callbacks */ - ot->exec= addedgeface_mesh_exec; - ot->poll= ED_operator_editmesh; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - -} - - - /* ************************ primitives ******************* */ // HACK: these can also be found in cmoview.tga.c, but are here so that they can be found by linker diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index faf82f106da..8b817b4b333 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1146,210 +1146,6 @@ static void erase_vertices(EditMesh *em, ListBase *l) } } -static int delete_mesh(Object *obedit, wmOperator *op, int event, Scene *scene) -{ - BMEditMesh *bem = ((Mesh*)obedit->data)->edit_btmesh; - EditMesh *em = NULL; - EditFace *efa, *nextvl; - EditVert *eve,*nextve; - EditEdge *eed,*nexted; - int count; - - if(event<1) return OPERATOR_CANCELLED; - - if (event != 7 && event != 5) - em= BKE_mesh_get_editmesh((Mesh *)obedit->data); - - if(event==10 ) { - //"Erase Vertices"; - erase_edges(em, &em->edges); - erase_faces(em, &em->faces); - erase_vertices(em, &em->verts); - - EM_fgon_flags(em); // redo flags and indices for fgons - BKE_mesh_end_editmesh(obedit->data, em); - } - else if(event==7) { - //"Dissolve Verts" - if (!EDBM_CallOpf(bem, op, "dissolveverts verts=%hv",BM_SELECT)) - return OPERATOR_CANCELLED; - } - else if(event==6) { - //"Erase Edge Loop"; - if(!EdgeLoopDelete(em, op)) { - BKE_mesh_end_editmesh(obedit->data, em); - return OPERATOR_CANCELLED; - } - - EM_fgon_flags(em); // redo flags and indices for fgons - BKE_mesh_end_editmesh(obedit->data, em); - } - else if(event==4) { - //"Erase Edges & Faces"; - efa= em->faces.first; - while(efa) { - nextvl= efa->next; - /* delete only faces with 1 or more edges selected */ - count= 0; - if(efa->e1->f & SELECT) count++; - if(efa->e2->f & SELECT) count++; - if(efa->e3->f & SELECT) count++; - if(efa->e4 && (efa->e4->f & SELECT)) count++; - if(count) { - BLI_remlink(&em->faces, efa); - free_editface(em, efa); - } - efa= nextvl; - } - eed= em->edges.first; - while(eed) { - nexted= eed->next; - if(eed->f & SELECT) { - remedge(em, eed); - free_editedge(em, eed); - } - eed= nexted; - } - efa= em->faces.first; - while(efa) { - nextvl= efa->next; - event=0; - if( efa->v1->f & SELECT) event++; - if( efa->v2->f & SELECT) event++; - if( efa->v3->f & SELECT) event++; - if(efa->v4 && (efa->v4->f & SELECT)) event++; - - if(event>1) { - BLI_remlink(&em->faces, efa); - free_editface(em, efa); - } - efa= nextvl; - - } - EM_fgon_flags(em); // redo flags and indices for fgons - BKE_mesh_end_editmesh(obedit->data, em); - } - else if(event==1) { - //"Erase Edges"; - // faces first - efa= em->faces.first; - while(efa) { - nextvl= efa->next; - event=0; - if( efa->e1->f & SELECT) event++; - if( efa->e2->f & SELECT) event++; - if( efa->e3->f & SELECT) event++; - if(efa->e4 && (efa->e4->f & SELECT)) event++; - - if(event) { - BLI_remlink(&em->faces, efa); - free_editface(em, efa); - } - efa= nextvl; - } - eed= em->edges.first; - while(eed) { - nexted= eed->next; - if(eed->f & SELECT) { - remedge(em, eed); - free_editedge(em, eed); - } - eed= nexted; - } - /* to remove loose vertices: */ - eed= em->edges.first; - while(eed) { - if( eed->v1->f & SELECT) eed->v1->f-=SELECT; - if( eed->v2->f & SELECT) eed->v2->f-=SELECT; - eed= eed->next; - } - eve= em->verts.first; - while(eve) { - nextve= eve->next; - if(eve->f & SELECT) { - BLI_remlink(&em->verts,eve); - free_editvert(em, eve); - } - eve= nextve; - } - - EM_fgon_flags(em); // redo flags and indices for fgons - BKE_mesh_end_editmesh(obedit->data, em); - } - else if(event==2) { - //"Erase Faces"; - delfaceflag(em, SELECT); - - EM_fgon_flags(em); // redo flags and indices for fgons - BKE_mesh_end_editmesh(obedit->data, em); - } - else if(event==3) { - //"Erase All"; - if(em->verts.first) free_vertlist(em, &em->verts); - if(em->edges.first) free_edgelist(em, &em->edges); - if(em->faces.first) free_facelist(em, &em->faces); - if(em->selected.first) BLI_freelistN(&(em->selected)); - - EM_fgon_flags(em); // redo flags and indices for fgons - BKE_mesh_end_editmesh(obedit->data, em); - } - else if(event==5) { - //"Erase Only Faces"; - if (!EDBM_CallOpf(bem, op, "del geom=%hf context=%d", - BM_SELECT, DEL_ONLYFACES)) - return OPERATOR_CANCELLED; - } - - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - - return OPERATOR_FINISHED; -} - -/* Note, these values must match delete_mesh() event values */ -static EnumPropertyItem prop_mesh_delete_types[] = { - {7, "DISSOLVE", "Dissolve Verts", ""}, - {10,"VERT", "Vertices", ""}, - {1, "EDGE", "Edges", ""}, - {2, "FACE", "Faces", ""}, - {3, "ALL", "All", ""}, - {4, "EDGE_FACE","Edges & Faces", ""}, - {5, "ONLY_FACE","Only Faces", ""}, - {6, "EDGE_LOOP","Edge Loop", ""}, - {0, NULL, NULL, NULL} -}; - -static int delete_mesh_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - Scene *scene = CTX_data_scene(C); - - delete_mesh(obedit, op, RNA_enum_get(op->ptr, "type"), scene); - - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA|ND_GEOM_SELECT, obedit); - - return OPERATOR_FINISHED; -} - -void MESH_OT_delete(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Delete"; - ot->idname= "MESH_OT_delete"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= delete_mesh_exec; - - ot->poll= ED_operator_editmesh; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /*props */ - RNA_def_enum(ot->srna, "type", prop_mesh_delete_types, 10, "Type", "Method used for deleting mesh data"); -} - - /*GB*/ /*-------------------------------------------------------------------------------*/ /*--------------------------- Edge Based Subdivide ------------------------------*/