From 1bc67f36d682bb4e5786dee7adfacdc844f1a539 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 2 Mar 2009 04:08:24 +0000 Subject: [PATCH] Created a printf-style method of calling operators. I did this to cut down on duplicated code, and also because calling operators was such a pain. The basic form of the format is "opname %[code]", where each % matches to an argument. The codes are fairly simple: d - int i - int f - float h[v/e/f] - all verts/edges/faces with a certain header flag. f[v/e/f] - all verts/edges/faces with a certain flag. For example: EDBM_CallOpf(em, op, "dissolveverts %hv", BM_SELECT) will call the dissolve verts operator. The relevent functions are: //calls a bmesh operator, doing necassary conversions and error reporting. int EDBM_CallOpf(EditMesh *em, struct wmOperator *op, char *fmt, ...); //execute an operator int BMO_CallOpf(BMesh *bm, char *fmt, ...); //initializes but doesn't execute an op. int BMO_InitOpf(BMesh *bm, BMOperator *op, char *fmt, ...); //vlist version of above. int BMO_VInitOpf(BMesh *bm, BMOperator *op, char *fmt, va_list vlist); Note this system is dependant on getting the slot codes from the argument order. I'd like to make it better, possibly pass in slot names, but that'd mean actually giving the slots names (which I can do, but wanted to discuss with Briggs and others what I have now first). --- source/blender/bmesh/bmesh_operators.h | 14 +- source/blender/bmesh/intern/bmesh_opdefines.c | 12 ++ source/blender/bmesh/intern/bmesh_operators.c | 149 ++++++++++++++++++ source/blender/editors/mesh/bmeshutils.c | 29 +++- source/blender/editors/mesh/editmesh_tools.c | 34 +--- source/blender/editors/mesh/mesh_intern.h | 6 +- 6 files changed, 209 insertions(+), 35 deletions(-) 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 */