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).
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#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
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
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,
|
||||
|
||||
@@ -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 <string.h>
|
||||
|
||||
@@ -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; i<bmesh_total_ops; i++) {
|
||||
if (!strcmp(opname, opdefines[i]->name)) 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user