diff --git a/source/blender/bmesh/bmesh_operators.h b/source/blender/bmesh/bmesh_operators.h index aaa6e29d79e..0c11b3c09e3 100644 --- a/source/blender/bmesh/bmesh_operators.h +++ b/source/blender/bmesh/bmesh_operators.h @@ -4,6 +4,8 @@ #include "BLI_memarena.h" #include "BLI_ghash.h" +#include + #define BMOP_OPSLOT_INT 0 #define BMOP_OPSLOT_FLT 1 #define BMOP_OPSLOT_PNT 2 @@ -51,6 +53,7 @@ typedef struct BMOperator{ /*need to refactor code to use this*/ typedef struct BMOpDefine { + char *name; int slottypes[BMOP_MAX_SLOTS]; void (*exec)(BMesh *bm, BMOperator *op); int totslot; @@ -122,6 +125,11 @@ void *BMO_IterStep(BMOIter *iter); remember for pointer maps this will be a pointer to a pointer.*/ void *BMO_IterMapVal(BMOIter *iter); +/*formatted operator initialization/execution*/ +int BMO_CallOpf(BMesh *bm, char *fmt, ...); +int BMO_InitOpf(BMesh *bm, BMOperator *op, char *fmt, ...); +int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist); + /*----------- bmop error system ----------*/ /*pushes an error onto the bmesh error stack. @@ -274,8 +282,10 @@ enum { /*dissolve verts*/ #define BMOP_DISSOLVE_VERTS 8 -#define BMOP_DISVERTS_VERTIN 0 -#define BMOP_DISVERTS_TOTSLOT 1 +enum { + BMOP_DISVERTS_VERTIN, + BMOP_DISVERTS_TOTSLOT, +}; #define BMOP_MAKE_FGONS 9 #define BMOP_MAKE_FGONS_TOTSLOT 0 diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 082de58d953..3c7504c869e 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -4,6 +4,7 @@ #include BMOpDefine def_connectverts = { + "connectvert", {BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_PNT_BUF}, connectverts_exec, @@ -12,6 +13,7 @@ BMOpDefine def_connectverts = { }; BMOpDefine def_extrudefaceregion = { + "extrudefaceregion", {BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_MAPPING, BMOP_OPSLOT_PNT_BUF}, @@ -21,6 +23,7 @@ BMOpDefine def_extrudefaceregion = { }; BMOpDefine def_makefgonsop = { + "makefgon", {0}, bmesh_make_fgons_exec, BMOP_MAKE_FGONS_TOTSLOT, @@ -28,6 +31,7 @@ BMOpDefine def_makefgonsop = { }; BMOpDefine def_dissolvevertsop = { + "dissolveverts", {BMOP_OPSLOT_PNT_BUF}, dissolveverts_exec, BMOP_DISVERTS_TOTSLOT, @@ -35,6 +39,7 @@ BMOpDefine def_dissolvevertsop = { }; BMOpDefine def_dissolvefacesop = { + "dissolvefaces", {BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_PNT_BUF}, dissolvefaces_exec, @@ -44,6 +49,7 @@ BMOpDefine def_dissolvefacesop = { BMOpDefine def_triangop = { + "triangulate", {BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_PNT_BUF}, @@ -53,6 +59,7 @@ BMOpDefine def_triangop = { }; BMOpDefine def_subdop = { + "esubd", {BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_INT, BMOP_OPSLOT_INT, @@ -68,6 +75,7 @@ BMOpDefine def_subdop = { }; BMOpDefine def_edit2bmesh = { + "editmesh_to_bmesh", {BMOP_OPSLOT_PNT}, edit2bmesh_exec, BMOP_TO_EDITMESH_TOTSLOT, @@ -75,6 +83,7 @@ BMOpDefine def_edit2bmesh = { }; BMOpDefine def_bmesh2edit = { + "bmesh_to_editmesh", {BMOP_OPSLOT_PNT}, bmesh2edit_exec, BMOP_FROM_EDITMESH_TOTSLOT, @@ -82,6 +91,7 @@ BMOpDefine def_bmesh2edit = { }; BMOpDefine def_delop = { + "del", {BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_INT}, delop_exec, BMOP_DEL_TOTSLOT, @@ -89,6 +99,7 @@ BMOpDefine def_delop = { }; BMOpDefine def_dupeop = { + "dupe", {BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_MAPPING}, dupeop_exec, @@ -97,6 +108,7 @@ BMOpDefine def_dupeop = { }; BMOpDefine def_splitop = { + "split", {BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_MAPPING}, splitop_exec, diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 3e2c3d9c4aa..2ece55c7e91 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -2,11 +2,13 @@ #include "BLI_memarena.h" #include "BLI_mempool.h" +#include "BLI_blenlib.h" #include "BKE_utildefines.h" #include "bmesh.h" #include "bmesh_private.h" +#include "stdarg.h" #include @@ -832,3 +834,150 @@ int BMO_PopError(BMesh *bm, char **msg, BMOperator **op) return errorcode; } + +/* +typedef struct bflag { + char *str; + int flag; +} bflag; + +#define b(f) {#f, f}, +static char *bmesh_flags = { + b(BM_SELECT); + b(BM_SEAM); + b(BM_FGON); + b(BM_HIDDEN); + b(BM_SHARP); + b(BM_SMOOTH); + {NULL, 0}; +}; + +int bmesh_str_to_flag(char *str) +{ + int i; + + while (bmesh_flags[i]->name) { + if (!strcmp(bmesh_flags[i]->name, str)) + return bmesh_flags[i]->flag; + } + + return -1; +} +*/ + +//example: +//BMO_CallOp(bm, "del %d %hv", DEL_ONLYFACES, BM_SELECT); +/* + d - int + i - int + f - float + hv - header flagged verts + he - header flagged edges + hf - header flagged faces + fv - flagged verts + fe - flagged edges + ff - flagged faces + +*/ + +#define nextc(fmt) ((fmt)[0] != 0 ? (fmt)[1] : 0) + +int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist) +{ + int i, n=strlen(fmt), slotcode = -1, ret, type; + char *opname; + + i = strcspn(fmt, " \t"); + + opname = fmt; + opname[i] = 0; + + fmt += i + 1; + + for (i=0; iname)) break; + } + + if (i == bmesh_total_ops) return 0; + BMO_Init_Op(op, i); + + i = 0; + while (*fmt) { + switch (*fmt) { + case ' ': + case '\t': + break; + case '%': + slotcode += 1; + break; + case 'i': + case 'd': + BMO_Set_Int(op, slotcode, va_arg(vlist, int)); + break; + case 'f': + case 'h': + type = *fmt; + + if (nextc(fmt) == ' ' || nextc(fmt) == '\t') { + BMO_Set_Float(op,slotcode,va_arg(vlist,float)); + } else { + switch (nextc(fmt)) { + case 'f': ret = BM_FACE; break; + case 'e': ret = BM_EDGE; break; + case 'v': ret = BM_VERT; break; + default: goto error; + } + + if (type == 'h') + BMO_HeaderFlag_To_Slot(bm, op, + slotcode, va_arg(vlist, int), ret); + else + BMO_Flag_To_Slot(bm, op, slotcode, + va_arg(vlist, int), ret); + fmt++; + } + break; + } + fmt++; + } + + + return 1; +error: + BMO_Finish_Op(bm, op); + return 0; +} + + +int BMO_InitOpf(BMesh *bm, BMOperator *op, char *fmt, ...) { + va_list list; + + va_start(list, fmt); + if (!BMO_VInitOpf(bm, op, fmt, list)) { + printf("BMO_InitOpf failed\n"); + va_end(list); + return 0; + } + va_end(list); + + return 1; +} + +int BMO_CallOpf(BMesh *bm, char *fmt, ...) { + va_list list; + BMOperator op; + + va_start(list, fmt); + if (!BMO_VInitOpf(bm, &op, fmt, list)) { + printf("BMO_CallOpf failed\n"); + va_end(list); + return 0; + } + + BMO_Exec_Op(bm, &op); + BMO_Finish_Op(bm, &op); + + va_end(list); + return 1; +} + diff --git a/source/blender/editors/mesh/bmeshutils.c b/source/blender/editors/mesh/bmeshutils.c index 76c10b75db5..2d3a3c9b193 100644 --- a/source/blender/editors/mesh/bmeshutils.c +++ b/source/blender/editors/mesh/bmeshutils.c @@ -26,6 +26,7 @@ * ***** END GPL LICENSE BLOCK ***** */ #include +#include #include #include #include @@ -88,14 +89,38 @@ #include "mesh_intern.h" #include "bmesh.h" +int EDBM_CallOpf(EditMesh *em, wmOperator *op, char *fmt, ...) +{ + BMesh *bm = editmesh_to_bmesh(em); + BMOperator bmop; + va_list list; + + va_start(list, fmt); + + if (!BMO_VInitOpf(bm, &bmop, fmt, list)) { + BKE_report(op->reports, RPT_ERROR, + "Parse error in EDBM_CallOpf"); + va_end(list); + return 0; + } + + BMO_Exec_Op(bm, &bmop); + BMO_Finish_Op(bm, &bmop); + + va_end(list); + + return EDBM_Finish(bm, em, op); + return 1; +} + /*returns 0 on error, 1 on success*/ -int EDBM_Finish(BMesh *bm, EditMesh *em, wmOperator *op, bContext *c) { +int EDBM_Finish(BMesh *bm, EditMesh *em, wmOperator *op) { EditMesh *em2; char *errmsg; if (BMO_GetError(bm, &errmsg, NULL)) { BKE_report(op->reports, RPT_ERROR, errmsg); - BMO_ClearStack(bm); + BM_Free_Mesh(bm); return 0; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index c339c0b72a4..cd6f208f6f0 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1135,19 +1135,8 @@ static int delete_mesh_exec(bContext *C, wmOperator *op) erase_vertices(em, &em->verts); } else if(event==7) { - BMesh *bm = editmesh_to_bmesh(em); - BMOperator bmop; - EditMesh *em2; - char *errmsg; - - BMO_Init_Op(&bmop, BMOP_DISSOLVE_VERTS); - BMO_HeaderFlag_To_Slot(bm, &bmop, BMOP_DISVERTS_VERTIN, - BM_SELECT, BM_VERT); - BMO_Exec_Op(bm, &bmop); - - BMO_Finish_Op(bm, &bmop); - - if (!EDBM_Finish(bm, em, op, C)) return OPERATOR_CANCELLED; + if (!EDBM_CallOpf(em, op, "dissolveverts %hv", BM_SELECT)) + return OPERATOR_CANCELLED; } else if(event==6) { if(!EdgeLoopDelete(em, op)) @@ -1254,24 +1243,9 @@ static int delete_mesh_exec(bContext *C, wmOperator *op) if(em->selected.first) BLI_freelistN(&(em->selected)); } else if(event==5) { - BMesh *bm = editmesh_to_bmesh(em); - BMOperator bmop; - EditMesh *em2; - char *errmsg; - + if (!EDBM_CallOpf(em, op, "del %hf %d", BM_SELECT, DEL_ONLYFACES)) + return OPERATOR_CANCELLED; str= "Erase Only Faces"; - - BMO_Init_Op(&bmop, BMOP_DEL); - BMO_HeaderFlag_To_Slot(bm, &bmop, BMOP_DEL_MULTIN, - BM_SELECT, BM_FACE); - BMO_Set_Int(&bmop, BMOP_DEL_CONTEXT, DEL_ONLYFACES); - - BMO_Exec_Op(bm, &bmop); - - BMO_Finish_Op(bm, &bmop); - - if (!EDBM_Finish(bm, em, op, C)) return OPERATOR_CANCELLED; - } EM_fgon_flags(em); // redo flags and indices for fgons diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 344ea75691b..3d6a249ddc3 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -45,11 +45,15 @@ struct BMesh; #define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float)); /* ******************** bmeshutils.c */ +/*calls EDBM_Finish*/ +int EDBM_CallOpf(EditMesh *em, struct wmOperator *op, char *fmt, ...); + /*called after bmesh tool exec. checks for errors and does conversions. if any errors are raised by bmesh, it displays the error to the user and returns 0 (and does not convert). otherwise, it converts the bmesh back into the editmesh, and returns 1.*/ -int EDBM_Finish(struct BMesh *bm, EditMesh *em, struct wmOperator *op, struct bContext *c); +int EDBM_Finish(struct BMesh *bm, EditMesh *em, struct wmOperator *op); + /* ******************** editface.c */