Brought Extrude all the way back. The contextual menu works,

as does only edges and individual faces extrude (individual vert 
extrude already did).

Note that I need to port this, after we all figure out how to handle
operators with variable transform follow-ons.

I also implemented the merge->collapse function, which is currently
accessable under ctrl->v, Bmesh Test Operator.  I still need to
implement the other merge modes, and properly hook everything into
the merge menu tool, which I plan on doing soon (tomorrow hopefully).

The cool thing about the collapse tool, is not only does it handle (all)
UV layers, it handles vcols as well.  To do this, I had to add a few math
functions to the customdata API, which seem to be working well.
This commit is contained in:
Joseph Eagar
2009-08-11 07:49:35 +00:00
parent 31421e0796
commit eb34e3ad7c
27 changed files with 1325 additions and 147 deletions

View File

@@ -37,6 +37,9 @@ struct CustomData;
struct CustomDataLayer;
typedef unsigned int CustomDataMask;
/*a data type large enough to hold 1 element from any customdata layer type*/
typedef struct {unsigned char data[64];} CDBlockBytes;
extern const CustomDataMask CD_MASK_BAREMESH;
extern const CustomDataMask CD_MASK_MESH;
extern const CustomDataMask CD_MASK_EDITMESH;
@@ -59,6 +62,20 @@ extern const CustomDataMask CD_MASK_FACECORNERS;
#define CD_DUPLICATE 4 /* do a full copy of all layers, only allowed if source
has same number of elements */
/* Checks if the layer at physical offset layern (in data->layers) support math
* the below operations.
*/
int CustomData_layer_has_math(struct CustomData *data, int layern);
/* compares if data1 is equal to data2. type is a valid CustomData type
* enum (e.g. CD_MLOOPUV). the layer type's equal function is used to compare
* the data, if it exists, otherwise memcmp is used.*/
int CustomData_data_equals(int type, void *data1, void *data2);
void CustomData_data_initminmax(int type, void *min, void *max);
void CustomData_data_dominmax(int type, void *data, void *min, void *max);
void CustomData_data_multiply(int type, void *data, float fac);
void CustomData_data_add(int type, void *data1, void *data2);
/* initialises a CustomData object with the same layer setup as source.
* mask is a bitfield where (mask & (1 << (layer type))) indicates
* if a layer should be copied or not. alloctype must be one of the above. */
@@ -192,6 +209,10 @@ void *CustomData_em_get_n(const struct CustomData *data, void *block, int type,
void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type);
void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n);
/* gets the layer at physical index n, with no type checking.
*/
void *CustomData_bmesh_get_layer_n(const struct CustomData *data, void *block, int n);
/* gets a pointer to the active or first layer of type
* returns NULL if there is no layer of type
*/
@@ -227,6 +248,11 @@ void CustomData_bmesh_set(const struct CustomData *data, void *block, int type,
void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n,
void *source);
/*sets the data of the block at physical layer n. no real type checking
*is performed.
*/
void CustomData_bmesh_set_layer_n(struct CustomData *data, void *block, int n,
void *source);
/* set the pointer of to the first layer of type. the old data is not freed.
* returns the value of ptr if the layer is found, NULL otherwise

View File

@@ -91,6 +91,13 @@ typedef struct LayerTypeInfo {
/* a function to set a layer's data to default values. if NULL, the
default is assumed to be all zeros */
void (*set_default)(void *data, int count);
/* functions necassary for geometry collapse*/
int (*equal)(void *data1, void *data2);
void (*multiply)(void *data, float fac);
void (*initminmax)(void *min, void *max);
void (*add)(void *data1, void *data2);
void (*dominmax)(void *data1, void *min, void *max);
} LayerTypeInfo;
static void layerCopy_mdeformvert(const void *source, void *dest,
@@ -535,11 +542,76 @@ static void layerFree_mdisps(void *data, int count, int size)
/* --------- */
static int layerEqual_mloopcol(void *data1, void *data2)
{
MLoopCol *m1 = data1, *m2 = data2;
float r, g, b, a;
r = m1->r - m2->r;
g = m1->g - m2->g;
b = m1->b - m2->b;
a = m1->a - m2->a;
return r*r + g*g + b*b + a*a < 0.001;
}
static void layerMultiply_mloopcol(void *data, float fac)
{
MLoopCol *m = data;
m->r = (float)m->r * fac;
m->g = (float)m->g * fac;
m->b = (float)m->b * fac;
m->a = (float)m->a * fac;
}
static void layerAdd_mloopcol(void *data1, void *data2)
{
MLoopCol *m = data1, *m2 = data2;
m->r += m2->r;
m->g += m2->g;
m->b += m2->b;
m->a += m2->a;
}
static void layerDoMinMax_mloopcol(void *data, void *vmin, void *vmax)
{
MLoopCol *m = data;
MLoopCol *min = vmin, *max = vmax;
if (m->r < min->r) min->r = m->r;
if (m->g < min->g) min->g = m->g;
if (m->b < min->b) min->b = m->b;
if (m->a < min->a) min->a = m->a;
if (m->r > max->r) max->r = m->r;
if (m->g > max->g) max->g = m->g;
if (m->b > max->b) max->b = m->b;
if (m->a > max->a) max->a = m->a;
}
static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
{
MLoopCol *min = vmin, *max = vmax;
min->r = 255;
min->g = 255;
min->b = 255;
min->a = 255;
max->r = 0;
max->g = 0;
max->b = 0;
max->a = 0;
}
static void layerDefault_mloopcol(void *data, int count)
{
static MLoopCol default_mloopcol = {255,255,255,255};
MLoopCol default_mloopcol = {255,255,255,255};
MLoopCol *mlcol = (MLoopCol*)data;
int i;
for(i = 0; i < count; i++)
mlcol[i] = default_mloopcol;
@@ -589,6 +661,48 @@ static void layerInterp_mloopcol(void **sources, float *weights,
mc->g = (int)col.g;
mc->b = (int)col.b;
}
static int layerEqual_mloopuv(void *data1, void *data2)
{
MLoopUV *luv1 = data1, *luv2 = data2;
float u, v;
u = luv1->uv[0] - luv2->uv[0];
v = luv1->uv[1] - luv2->uv[1];
return u*u + v*v < 0.00001;
}
static void layerMultiply_mloopuv(void *data, float fac)
{
MLoopUV *luv = data;
luv->uv[0] *= fac;
luv->uv[1] *= fac;
}
static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
{
MLoopUV *min = vmin, *max = vmax;
INIT_MINMAX2(min->uv, max->uv);
}
static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax)
{
MLoopUV *min = vmin, *max = vmax, *luv = data;
DO_MINMAX2(luv->uv, min->uv, max->uv);
}
static void layerAdd_mloopuv(void *data1, void *data2)
{
MLoopUV *l1 = data1, *l2 = data2;
l1->uv[0] += l2->uv[0];
l1->uv[1] += l2->uv[1];
}
static void layerInterp_mloopuv(void **sources, float *weights,
float *sub_weights, int count, void *dest)
{
@@ -722,8 +836,12 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
{sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
{sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL,
layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv,
layerAdd_mloopuv, layerDoMinMax_mloopuv},
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL,
layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
layerAdd_mloopcol, layerDoMinMax_mloopcol},
{sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
{sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL},
@@ -1872,7 +1990,7 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest,
BMIter iter;
CustomData destold = *dest;
void *tmp;
int i, t;
int t;
CustomData_merge(source, dest, mask, alloctype, 0);
CustomData_bmesh_init_pool(dest, 512);
@@ -2014,6 +2132,68 @@ void *CustomData_bmesh_get_n(const CustomData *data, void *block, int type, int
return (char *)block + data->layers[layer_index+n].offset;
}
/*gets from the layer at physical index n, note: doesn't check type.*/
void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
{
if(n < 0 || n >= data->totlayer) return NULL;
return (char *)block + data->layers[n].offset;
}
int CustomData_layer_has_math(struct CustomData *data, int layern)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layern].type);
if (typeInfo->equal && typeInfo->add && typeInfo->multiply &&
typeInfo->initminmax && typeInfo->dominmax) return 1;
return 0;
}
int CustomData_data_equals(int type, void *data1, void *data2)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if (typeInfo->equal)
return typeInfo->equal(data1, data2);
else return !memcmp(data1, data2, typeInfo->size);
}
void CustomData_data_initminmax(int type, void *min, void *max)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if (typeInfo->equal)
typeInfo->initminmax(min, max);
}
void CustomData_data_dominmax(int type, void *data, void *min, void *max)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if (typeInfo->equal)
typeInfo->dominmax(data, min, max);
}
void CustomData_data_multiply(int type, void *data, float fac)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if (typeInfo->equal)
typeInfo->multiply(data, fac);
}
void CustomData_data_add(int type, void *data1, void *data2)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if (typeInfo->equal)
typeInfo->add(data1, data2);
}
void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
{
void *dest = CustomData_bmesh_get(data, block, type);
@@ -2040,6 +2220,19 @@ void CustomData_bmesh_set_n(CustomData *data, void *block, int type, int n, void
memcpy(dest, source, typeInfo->size);
}
void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source)
{
void *dest = CustomData_bmesh_get_layer_n(data, block, n);
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
if(!dest) return;
if(typeInfo->copy)
typeInfo->copy(source, dest, 1);
else
memcpy(dest, source, typeInfo->size);
}
void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
float *sub_weights, int count, void *dest_block)
{

View File

@@ -26,6 +26,21 @@
#define BM_EDGES_OF_MESH 2
#define BM_FACES_OF_MESH 3
/*these are topological iterators.*/
#define BM_EDGES_OF_VERT 4
#define BM_FACES_OF_VERT 5
#define BM_LOOPS_OF_VERT 6
#define BM_FACES_OF_EDGE 7
#define BM_VERTS_OF_FACE 8
#define BM_FACEVERTS_OF_FACE 9
#define BM_EDGES_OF_FACE 10
#define BM_LOOPS_OF_FACE 11
/*iterate through loops around this loop, which are fetched
from the other faces in the radial cycle surrounding the
input loop's edge.*/
#define BM_LOOPS_OF_LOOP 12
#define BM_ITER(ele, iter, bm, type, data) \
ele = BMIter_New(iter, bm, type, data); \
for ( ; ele; ele=BMIter_Step(iter))
@@ -38,20 +53,6 @@ for (ele = BMIter_New(iter, bm, type, data); ele; ele=BMIter_Step(iter)) {\
for (ele = BMIter_New(iter, bm, type, data); ele; ele=BMIter_Step(iter)) {\
if (BM_TestHFlag(ele, BM_HIDDEN) || BM_TestHFlag(ele, BM_SELECT)) continue;
/*these are topological iterators.*/
#define BM_EDGES_OF_VERT 4
#define BM_FACES_OF_VERT 5
#define BM_FACES_OF_EDGE 6
#define BM_VERTS_OF_FACE 7
#define BM_FACEVERTS_OF_FACE 8
#define BM_EDGES_OF_FACE 9
#define BM_LOOPS_OF_FACE 10
/*iterate through loops around this loop, which are fetched
from the other faces in the radial cycle surrounding the
input loop's edge.*/
#define BM_LOOPS_OF_LOOP 11
/*Iterator Structure*/
typedef struct BMIter{

View File

@@ -224,14 +224,14 @@ void BMO_Get_Mat3(struct BMOperator *op, char *slotname, float mat[3][3]);
void BMO_Flag_To_Slot(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag, int type);
/*tool-flags all elements inside an element slot array with flag flag.*/
void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag);
void BMO_Flag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag, int type);
/*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);
void BMO_Unflag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag, int type);
/*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);
void BMO_HeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag, int type);
/*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);
void BMO_UnHeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag, int type);
/*puts every element of type type (which is a bitmask) with header flag
flag, into a slot. note: ignores hidden elements (e.g. elements with

View File

@@ -17,11 +17,12 @@ typedef struct BMWalker {
void *(*step) (struct BMWalker *walker);
int restrictflag;
GHash *visithash;
int flag;
} BMWalker;
/*initialize a walker. searchmask restricts some (not all) walkers to
elements with a specific tool flag set.*/
void BMW_Init(struct BMWalker *walker, BMesh *bm, int type, int searchmask);
elements with a specific tool flag set. flags is specific to each walker.*/
void BMW_Init(struct BMWalker *walker, BMesh *bm, int type, int searchmask, int flags);
void *BMW_Begin(BMWalker *walker, void *start);
void *BMW_Step(struct BMWalker *walker);
void BMW_End(struct BMWalker *walker);
@@ -42,14 +43,22 @@ BMW_End(&walker);
enum {
/*walk over connected geometry. can restrict to a search flag,
or not, it's optional.*/
or not, it's optional.
takes a vert as an arugment, and spits out edges, restrict flag acts
on the edges as well.*/
BMW_SHELL,
/*walk over an edge loop. search flag doesn't do anything.*/
BMW_LOOP,
BMW_FACELOOP,
BMW_EDGERING,
/*#define BMW_RING 2
#define BMW_UVISLANDS 3*/
/*#define BMW_RING 2*/
//walk over uv islands; takes a loop as input. restrict flag
//restricts the walking to loops whose vert has restrict flag set as a
//tool flag.
//
//the flag parameter to BMW_Init maps to a loop customdata layer index.
BMW_UVISLAND,
/*walk over an island of flagged faces. note, that this doesn't work on
non-manifold geometry. it might be better to rewrite this to extract
boundary info from the island walker, rather then directly walking

View File

@@ -69,6 +69,22 @@ void BM_Data_Interp_From_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, flo
}
}
/*
BM Data Vert Average
Sets all the customdata (e.g. vert, loop) associated with a vert
to the average of the face regions surrounding it.
*/
//CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->head.data);
void BM_Data_Vert_Average(BMesh *bm, BMFace *f)
{
BMIter iter;
}
/**
* bmesh_data_facevert_edgeinterp
*

View File

@@ -203,6 +203,46 @@ static void *face_of_vert_step(BMIter *iter)
return NULL;
}
/*
* LOOP OF VERT CALLBACKS
*
*/
static void loop_of_vert_begin(BMIter *iter)
{
init_iterator(iter);
iter->count = 0;
if(iter->vdata->edge)
iter->count = bmesh_disk_count_facevert(iter->vdata);
if(iter->count){
iter->firstedge = bmesh_disk_find_first_faceedge(iter->vdata->edge, iter->vdata);
iter->nextedge = iter->firstedge;
iter->firstloop = bmesh_radial_find_first_facevert(iter->firstedge->loop, iter->vdata);
iter->nextloop = iter->firstloop;
}
}
static void *loop_of_vert_step(BMIter *iter)
{
BMLoop *current = iter->nextloop;
if(iter->count){
iter->count--;
iter->nextloop = bmesh_radial_find_next_facevert(iter->nextloop, iter->vdata);
if(iter->nextloop == iter->firstloop){
iter->nextedge = bmesh_disk_find_next_faceedge(iter->nextedge, iter->vdata);
iter->firstloop = bmesh_radial_find_first_facevert(iter->nextedge->loop, iter->vdata);
iter->nextloop = iter->firstloop;
}
}
if(!iter->count) iter->nextloop = NULL;
if(current) return current;
return NULL;
}
static void loops_of_loop_begin(BMIter *iter)
{
BMLoop *l;
@@ -359,6 +399,11 @@ void *BMIter_New(BMIter *iter, BMesh *bm, int type, void *data)
iter->step = face_of_vert_step;
iter->vdata = data;
break;
case BM_LOOPS_OF_VERT:
iter->begin = loop_of_vert_begin;
iter->step = loop_of_vert_step;
iter->vdata = data;
break;
case BM_FACES_OF_EDGE:
iter->begin = face_of_edge_begin;
iter->step = face_of_edge_step;

View File

@@ -223,6 +223,47 @@ BMOpDefine def_removedoubles = {
0,
};
/*
Collapse Connected
Collapses connected vertices
*/
BMOpDefine def_collapse = {
"collapse",
{{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /*input edges*/
{0, /*null-terminating sentinel*/}},
bmesh_collapse_exec,
0,
};
/*
Point Merge
Merge verts together at a point.
*/
BMOpDefine def_pointmerge = {
"pointmerge",
{{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, /*input vertices*/
{BMOP_OPSLOT_VEC, "mergeco"},
{0, /*null-terminating sentinel*/}},
bmesh_pointmerge_exec,
0,
};
/*
Collapse Connected UVs
Collapses connected UV vertices.
*/
BMOpDefine def_collapse_uvs = {
"collapse_uvs",
{{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, /*input edges*/
{0, /*null-terminating sentinel*/}},
bmesh_collapsecon_exec,
0,
};
/*
Weld Verts
@@ -359,6 +400,36 @@ BMOpDefine def_mesh_to_bmesh = {
0
};
/*
Individual Face Extrude
Extrudes faces individually.
*/
BMOpDefine def_extrude_indivface = {
"extrude_face_indiv",
{{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, //input faces
{BMOP_OPSLOT_ELEMENT_BUF, "faceout"}, //output faces
{BMOP_OPSLOT_ELEMENT_BUF, "skirtout"}, //output skirt geometry, faces and edges
{0} /*null-terminating sentinel*/},
bmesh_extrude_face_indiv_exec,
0
};
/*
Extrude Only Edges
Extrudes Edges into faces, note that this is very simple, there's no fancy
winged extrusion.
*/
BMOpDefine def_extrude_onlyedge = {
"extrude_edge_only",
{{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input vertices
{BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output geometry
{0} /*null-terminating sentinel*/},
bmesh_extrude_onlyedge_exec,
0
};
/*
Individual Vertex Extrude
@@ -572,6 +643,11 @@ BMOpDefine *opdefines[] = {
&def_regionextend,
&def_righthandfaces,
&def_vertexsmooth,
&def_extrude_onlyedge,
&def_extrude_indivface,
&def_collapse_uvs,
&def_pointmerge,
&def_collapse,
};
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));

View File

@@ -739,16 +739,19 @@ void BMO_Flag_To_Slot(BMesh *bm, BMOperator *op, char *slotname, int flag, int t
*
*/
void BMO_HeaderFlag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag)
void BMO_HeaderFlag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag, int type)
{
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 (!(type & data[i]->type))
continue;
if (flag & BM_SELECT)
BM_Select(bm, data[i], 1);
BM_SetHFlag(data[i], flag);
}
}
@@ -761,16 +764,19 @@ void BMO_HeaderFlag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag)
*
*/
void BMO_UnHeaderFlag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag)
void BMO_UnHeaderFlag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag, int type)
{
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 (!(type & data[i]->type))
continue;
if (flag & BM_SELECT)
BM_Select(bm, data[i], 0);
BM_ClearHFlag(data[i], flag);
}
}
@@ -783,14 +789,18 @@ void BMO_UnHeaderFlag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag
*
*/
void BMO_Flag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag)
void BMO_Flag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag, int type)
{
BMOpSlot *slot = BMO_GetSlot(op, slotname);
BMHeader **data = slot->data.p;
int i;
for(i = 0; i < slot->len; i++)
for(i = 0; i < slot->len; i++) {
if (!(type & data[i]->type))
continue;
BMO_SetFlag(bm, data[i], flag);
}
}
/*
@@ -801,14 +811,18 @@ void BMO_Flag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag)
*
*/
void BMO_Unflag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag)
void BMO_Unflag_Buffer(BMesh *bm, BMOperator *op, char *slotname, int flag, int type)
{
BMOpSlot *slot = BMO_GetSlot(op, slotname);
BMHeader **data = slot->data.p;
int i;
for(i = 0; i < slot->len; i++)
for(i = 0; i < slot->len; i++) {
if (!(type & data[i]->type))
continue;
BMO_ClearFlag(bm, data[i], flag);
}
}

View File

@@ -41,5 +41,10 @@ void bmesh_edgerotate_exec(BMesh *bm, BMOperator *op);
void bmesh_regionextend_exec(BMesh *bm, BMOperator *op);
void bmesh_righthandfaces_exec(BMesh *bm, BMOperator *op);
void bmesh_vertexsmooth_exec(BMesh *bm, BMOperator *op);
void bmesh_extrude_onlyedge_exec(BMesh *bm, BMOperator *op);
void bmesh_extrude_face_indiv_exec(BMesh *bm, BMOperator *op);
void bmesh_collapsecon_exec(BMesh *bm, BMOperator *op);
void bmesh_pointmerge_exec(BMesh *bm, BMOperator *op);
void bmesh_collapse_exec(BMesh *bm, BMOperator *op);
#endif

View File

@@ -1,5 +1,12 @@
#include <stdio.h>
#include <string.h>
#include "BKE_utildefines.h"
#include "BKE_customdata.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
#include "BLI_mempool.h"
#include "bmesh_private.h"
@@ -65,6 +72,11 @@ typedef struct edgeringWalker {
BMLoop *l;
} edgeringWalker;
typedef struct uvedgeWalker {
struct uvedgeWalker *prev;
BMLoop *l;
} uvedgeWalker;
/* NOTE: this comment is out of date, update it - joeedh
* BMWalker - change this to use the filters functions.
*
@@ -117,6 +129,10 @@ static void edgeringWalker_begin(BMWalker *walker, void *data);
static void *edgeringWalker_yield(BMWalker *walker);
static void *edgeringWalker_step(BMWalker *walker);
static void uvedgeWalker_begin(BMWalker *walker, void *data);
static void *uvedgeWalker_yield(BMWalker *walker);
static void *uvedgeWalker_step(BMWalker *walker);
/* Pointer hiding*/
typedef struct bmesh_walkerGeneric{
struct bmesh_walkerGeneric *prev;
@@ -126,7 +142,7 @@ typedef struct bmesh_walkerGeneric{
void *BMW_Begin(BMWalker *walker, void *start) {
walker->begin(walker, start);
return walker->step(walker);
return walker->currentstate ? walker->step(walker) : NULL;
}
/*
@@ -138,11 +154,13 @@ void *BMW_Begin(BMWalker *walker, void *start) {
*
*/
void BMW_Init(BMWalker *walker, BMesh *bm, int type, int searchmask)
void BMW_Init(BMWalker *walker, BMesh *bm, int type, int searchmask, int flag)
{
int size = 0;
memset(walker, 0, sizeof(BMWalker));
walker->flag = flag;
walker->bm = bm;
walker->restrictflag = searchmask;
walker->visithash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
@@ -184,6 +202,12 @@ void BMW_Init(BMWalker *walker, BMesh *bm, int type, int searchmask)
walker->yield = edgeringWalker_yield;
size = sizeof(edgeringWalker);
break;
case BMW_UVISLAND:
walker->begin = uvedgeWalker_begin;
walker->step = uvedgeWalker_step;
walker->yield = uvedgeWalker_yield;
size = sizeof(uvedgeWalker);
break;
default:
break;
}
@@ -291,27 +315,71 @@ void BMW_reset(BMWalker *walker) {
*/
static void shellWalker_begin(BMWalker *walker, void *data){
BMIter eiter;
BMEdge *e;
BMVert *v = data;
shellWalker *shellWalk = NULL;
if (!v->edge)
return;
if (walker->restrictflag) {
BM_ITER(e, &eiter, walker->bm, BM_EDGES_OF_VERT, v) {
if (BMO_TestFlag(walker->bm, e, walker->restrictflag))
break;
}
} else {
e = v->edge;
}
if (!e)
return;
BMW_pushstate(walker);
shellWalk = walker->currentstate;
shellWalk->base = NULL;
shellWalk->curedge = NULL;
if(v->edge){
shellWalk->base = v;
shellWalk->curedge = v->edge;
BLI_ghash_insert(walker->visithash, v->edge, NULL);
}
shellWalk->base = v;
shellWalk->curedge = e;
BLI_ghash_insert(walker->visithash, e, NULL);
}
static void *shellWalker_yield(BMWalker *walker)
{
shellWalker *shellWalk = walker->currentstate;
return shellWalk->curedge;
}
static void *shellWalker_step(BMWalker *walker)
{
shellWalker *swalk = walker->currentstate;
BMEdge *e, *e2;
BMVert *v;
BMIter iter;
int i;
BMW_popstate(walker);
e = swalk->curedge;
for (i=0; i<2; i++) {
v = i ? e->v2 : e->v1;
BM_ITER(e2, &iter, walker->bm, BM_EDGES_OF_VERT, v) {
if (walker->restrictflag && !BMO_TestFlag(walker->bm, e2, walker->restrictflag))
continue;
if (BLI_ghash_haskey(walker->visithash, e2))
continue;
BMW_pushstate(walker);
BLI_ghash_insert(walker->visithash, e2, NULL);
swalk = walker->currentstate;
swalk->curedge = e2;
}
}
return e;
}
#if 0
static void *shellWalker_step(BMWalker *walker)
{
BMEdge *curedge, *next = NULL;
@@ -324,19 +392,19 @@ static void *shellWalker_step(BMWalker *walker)
BMW_popstate(walker);
/*find the next edge whose other vertex has not been visited*/
curedge = shellWalk.curedge;
do{
if (!BLI_ghash_haskey(walker->visithash, curedge)) {
BLI_ghash_insert(walker->visithash, curedge, NULL);
if(!(walker->restrictflag &&
!BMO_TestFlag(walker->bm, curedge, walker->restrictflag)))
if(!walker->restrictflag || (walker->restrictflag &&
BMO_TestFlag(walker->bm, curedge, walker->restrictflag)))
{
ov = BM_OtherEdgeVert(curedge, shellWalk.base);
/*push a new state onto the stack*/
BMW_pushstate(walker);
BLI_ghash_insert(walker->visithash, curedge, NULL);
/*populate the new state*/
@@ -349,6 +417,7 @@ static void *shellWalker_step(BMWalker *walker)
return shellWalk.curedge;
}
#endif
/* Island Boundary Walker:
*
@@ -757,3 +826,90 @@ static void *edgeringWalker_step(BMWalker *walker)
return e;
}
static void uvedgeWalker_begin(BMWalker *walker, void *data)
{
uvedgeWalker *lwalk;
BMLoop *l = data;
if (BLI_ghash_haskey(walker->visithash, l))
return;
BMW_pushstate(walker);
lwalk = walker->currentstate;
lwalk->l = l;
BLI_ghash_insert(walker->visithash, l, NULL);
}
static void *uvedgeWalker_yield(BMWalker *walker)
{
uvedgeWalker *lwalk = walker->currentstate;
if (!lwalk) return NULL;
}
static int walker_compare_uv(MLoopUV *luv1, MLoopUV *luv2)
{
float udelta = luv1->uv[0] - luv2->uv[0];
float vdelta = luv1->uv[1] - luv2->uv[1];
/*BMESH_TODO: look up proper threshold value*/
return udelta*udelta + vdelta*vdelta < 0.0001f;
}
static void *uvedgeWalker_step(BMWalker *walker)
{
uvedgeWalker *lwalk = walker->currentstate;
BMLoop *l, *l2, *l3, *nl, *cl;
BMIter liter;
void *d1, *d2;
int i, j, rlen, type;
l = lwalk->l;
nl = l->head.next;
type = walker->bm->ldata.layers[walker->flag].type;
BMW_popstate(walker);
if (walker->restrictflag && !BMO_TestFlag(walker->bm, l->e, walker->restrictflag))
return l;
/*go over loops around l->v and nl->v and see which ones share l and nl's
mloopuv's coordinates. in addition, push on l->head.next if necassary.*/
for (i=0; i<2; i++) {
BM_ITER(l2, &liter, walker->bm, BM_LOOPS_OF_VERT, i?nl->v:l->v) {
cl = i ? nl : l;
d1 = CustomData_bmesh_get_layer_n(&walker->bm->ldata,
cl->head.data, walker->flag);
rlen = BM_Edge_FaceCount(l2->e);
for (j=0; j<rlen; j++) {
if (BLI_ghash_haskey(walker->visithash, l2))
continue;
if (walker->restrictflag && !(BMO_TestFlag(walker->bm, l2->e, walker->restrictflag)))
{
if (l2->v != l->v)
continue;
}
l3 = l2->v != cl->v ? (BMLoop*)l2->head.next : l2;
d2 = CustomData_bmesh_get_layer_n(&walker->bm->ldata,
l3->head.data, walker->flag);
if (!CustomData_data_equals(type, d1, d2))
continue;
BMW_pushstate(walker);
BLI_ghash_insert(walker->visithash, l2, NULL);
lwalk = walker->currentstate;
lwalk->l = l2;
l2 = l2->radial.next->data;
}
}
}
return l;
}

View File

@@ -315,7 +315,8 @@ void dupeop_exec(BMesh *bm, BMOperator *op)
BMOperator *dupeop = op;
/*flag input*/
BMO_Flag_Buffer(bm, dupeop, "geom", DUPE_INPUT);
BMO_Flag_Buffer(bm, dupeop, "geom", DUPE_INPUT, BM_ALL);
/*use the internal copy function*/
copy_mesh(dupeop, bm, bm);
@@ -380,7 +381,7 @@ void splitop_exec(BMesh *bm, BMOperator *op)
BMO_CopySlot(splitop, &dupeop, "geom", "geom");
BMO_Exec_Op(bm, &dupeop);
BMO_Flag_Buffer(bm, splitop, "geom", SPLIT_INPUT);
BMO_Flag_Buffer(bm, splitop, "geom", SPLIT_INPUT, BM_ALL);
/*make sure to remove edges and verts we don't need.*/
for (e= BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);e;e=BMIter_Step(&iter)) {
@@ -437,7 +438,7 @@ void delop_exec(BMesh *bm, BMOperator *op)
BMOperator *delop = op;
/*Mark Buffers*/
BMO_Flag_Buffer(bm, delop, "geom", DEL_INPUT);
BMO_Flag_Buffer(bm, delop, "geom", DEL_INPUT, BM_ALL);
delete_context(bm, BMO_Get_Int(op, "context"));
}

View File

@@ -25,7 +25,7 @@ void connectverts_exec(BMesh *bm, BMOperator *op)
V_DECLARE(verts);
int i;
BMO_Flag_Buffer(bm, op, "verts", VERT_INPUT);
BMO_Flag_Buffer(bm, op, "verts", VERT_INPUT, BM_VERT);
for (f=BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL); f; f=BMIter_Step(&iter)){
V_RESET(loops);

View File

@@ -26,7 +26,7 @@ static int check_hole_in_region(BMesh *bm, BMFace *f) {
/*checks if there are any unmarked boundary edges in the face region*/
BMW_Init(&regwalker, bm, BMW_ISLAND, FACE_MARK);
BMW_Init(&regwalker, bm, BMW_ISLAND, FACE_MARK, 0);
f2 = BMW_Begin(&regwalker, f);
for (; f2; f2=BMW_Step(&regwalker)) {
l2 = BMIter_New(&liter2, bm, BM_LOOPS_OF_FACE, f2);
@@ -59,7 +59,7 @@ void dissolvefaces_exec(BMesh *bm, BMOperator *op)
BMWalker regwalker;
int i, j, fcopied;
BMO_Flag_Buffer(bm, op, "faces", FACE_MARK);
BMO_Flag_Buffer(bm, op, "faces", FACE_MARK, BM_FACE);
/*collect regions*/
f = BMO_IterNew(&oiter, bm, op, "faces", BM_FACE);
@@ -70,7 +70,7 @@ void dissolvefaces_exec(BMesh *bm, BMOperator *op)
region = NULL; /*forces different allocation*/
/*yay, walk!*/
BMW_Init(&regwalker, bm, BMW_ISLAND, FACE_MARK);
BMW_Init(&regwalker, bm, BMW_ISLAND, FACE_MARK, 0);
f2 = BMW_Begin(&regwalker, f);
for (; f2; f2=BMW_Step(&regwalker)) {
l2 = BMIter_New(&liter2, bm, BM_LOOPS_OF_FACE, f2);
@@ -91,7 +91,7 @@ void dissolvefaces_exec(BMesh *bm, BMOperator *op)
}
BMW_End(&regwalker);
BMW_Init(&regwalker, bm, BMW_ISLAND, FACE_MARK);
BMW_Init(&regwalker, bm, BMW_ISLAND, FACE_MARK, 0);
f2 = BMW_Begin(&regwalker, f);
for (; f2; f2=BMW_Step(&regwalker)) {
BMO_ClearFlag(bm, f2, FACE_MARK);
@@ -313,7 +313,7 @@ void dissolveverts_exec(BMesh *bm, BMOperator *op)
int i;
vinput = BMO_GetSlot(op, "verts");
BMO_Flag_Buffer(bm, op, "verts", VERT_MARK);
BMO_Flag_Buffer(bm, op, "verts", VERT_MARK, BM_VERT);
for (v=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); v; v=BMIter_Step(&iter)) {
if (BMO_TestFlag(bm, v, VERT_MARK)) {

View File

@@ -10,10 +10,129 @@
#include "bmesh.h"
#include "bmesh_operators_private.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EXT_INPUT 1
#define EXT_KEEP 2
#define EXT_DEL 4
void bmesh_extrude_face_indiv_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMIter liter, liter2;
BMFace *f, *f2, *f3;
BMLoop *l, *l2, *l3, *l4;
BMEdge **edges = NULL, *e, *laste;
BMVert *v, *lastv, *firstv;
V_DECLARE(edges);
int i;
BMO_ITER(f, &siter, bm, op, "faces", BM_FACE) {
V_RESET(edges);
i = 0;
firstv = lastv = NULL;
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
V_GROW(edges);
v = BM_Make_Vert(bm, l->v->co, NULL);
BM_Copy_Attributes(bm, bm, l->v, v);
if (lastv) {
e = BM_Make_Edge(bm, lastv, v, l->e, 0);
edges[i++] = e;
}
lastv = v;
laste = l->e;
if (!firstv) firstv = v;
}
V_GROW(edges);
e = BM_Make_Edge(bm, v, firstv, laste, 0);
edges[i++] = e;
BMO_SetFlag(bm, f, EXT_DEL);
f2 = BM_Make_Ngon(bm, edges[0]->v1, edges[0]->v2, edges, f->len, 0);
BMO_SetFlag(bm, f2, EXT_KEEP);
BM_Copy_Attributes(bm, bm, f, f2);
l2 = BMIter_New(&liter2, bm, BM_LOOPS_OF_FACE, f2);
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
BM_Copy_Attributes(bm, bm, l, l2);
l3 = l->head.next;
l4 = l2->head.next;
f3 = BM_Make_QuadTri(bm, l3->v, l4->v, l2->v, l->v, f, 0);
BM_Copy_Attributes(bm, bm, l->head.next, f3->loopbase);
BM_Copy_Attributes(bm, bm, l->head.next, f3->loopbase->head.next);
BM_Copy_Attributes(bm, bm, l, f3->loopbase->head.next->next);
BM_Copy_Attributes(bm, bm, l, f3->loopbase->head.next->next->next);
l2 = BMIter_Step(&liter2);
}
}
BMO_CallOpf(bm, "del geom=%ff context=%d", EXT_DEL, DEL_ONLYFACES);
BMO_Flag_To_Slot(bm, op, "faceout", EXT_KEEP, BM_FACE);
}
void bmesh_extrude_onlyedge_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMOperator dupeop;
BMVert *v1, *v2, *v3, *v4;
BMEdge *e, *e2;
BMFace *f;
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
BMO_SetFlag(bm, e, EXT_INPUT);
BMO_SetFlag(bm, e->v1, EXT_INPUT);
BMO_SetFlag(bm, e->v2, EXT_INPUT);
}
BMO_InitOpf(bm, &dupeop, "dupe geom=%fve", EXT_INPUT);
BMO_Exec_Op(bm, &dupeop);
e = BMO_IterNew(&siter, bm, &dupeop, "boundarymap", 0);
for (; e; e=BMO_IterStep(&siter)) {
e2 = BMO_IterMapVal(&siter);
e2 = *(BMEdge**)e2;
if (e->loop && e->v1 != e->loop->v) {
v1 = e->v1;
v2 = e->v2;
v3 = e2->v2;
v4 = e2->v1;
} else {
v1 = e2->v1;
v2 = e2->v2;
v3 = e->v2;
v4 = e->v1;
}
/*not sure what to do about example face, pass NULL for now.*/
f = BM_Make_QuadTri(bm, v1, v2, v3, v4, NULL, 0);
if (BMO_TestFlag(bm, e, EXT_INPUT))
e = e2;
BMO_SetFlag(bm, f, EXT_KEEP);
BMO_SetFlag(bm, e, EXT_KEEP);
BMO_SetFlag(bm, e->v1, EXT_KEEP);
BMO_SetFlag(bm, e->v2, EXT_KEEP);
}
BMO_Finish_Op(bm, &dupeop);
BMO_Flag_To_Slot(bm, op, "geomout", EXT_KEEP, BM_ALL);
}
void extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
@@ -45,12 +164,12 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
BMLoop *l, *l2;
BMVert *verts[4], *v, *v2;
BMFace *f;
int rlen, found, delorig=0, i, reverse;
int rlen, found, delorig=0, i;
/*initialize our sub-operators*/
BMO_Init_Op(&dupeop, "dupe");
BMO_Flag_Buffer(bm, op, "edgefacein", EXT_INPUT);
BMO_Flag_Buffer(bm, op, "edgefacein", EXT_INPUT, BM_EDGE|BM_FACE);
/*if one flagged face is bordered by an unflagged face, then we delete
original geometry.*/

View File

@@ -56,7 +56,7 @@ void bmesh_mirror_exec(BMesh *bm, BMOperator *op) {
BMO_InitOpf(bm, &dupeop, "dupe geom=%s", op, "geom");
BMO_Exec_Op(bm, &dupeop);
BMO_Flag_Buffer(bm, &dupeop, "newout", ELE_NEW);
BMO_Flag_Buffer(bm, &dupeop, "newout", ELE_NEW, BM_ALL);
/*create old -> new mapping*/
i = 0;

View File

@@ -1,12 +1,19 @@
#include "MEM_guardedalloc.h"
#include "DNA_meshdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_utildefines.h"
#include "BLI_arithb.h"
#include "BLI_ghash.h"
#include "BLI_blenlib.h"
#include "bmesh.h"
#include "mesh_intern.h"
#include "bmesh_private.h"
#include "BLI_arithb.h"
#include "BLI_ghash.h"
#include <stdio.h>
#include <stdlib.h>
@@ -157,7 +164,7 @@ void bmesh_weldverts_exec(BMesh *bm, BMOperator *op)
v2 = BMO_Get_MapPointer(bm, op, "targetmap", v2);
f2 = BM_Make_Ngon(bm, v2, v, edges, a, 0);
f2 = BM_Make_Ngon(bm, v, v2, edges, a, 0);
if (f2) {
BM_Copy_Attributes(bm, bm, f, f2);
BMO_SetFlag(bm, f, ELE_DEL);
@@ -195,6 +202,128 @@ static int vergaverco(const void *e1, const void *e2)
#define VERT_DOUBLE 2
#define VERT_TARGET 4
#define VERT_KEEP 8
#define VERT_MARK 16
#define EDGE_MARK 1
void bmesh_pointmerge_exec(BMesh *bm, BMOperator *op)
{
}
void bmesh_collapse_exec(BMesh *bm, BMOperator *op)
{
BMOperator weldop;
BMWalker walker;
BMOIter siter;
BMIter iter, liter, liter2;
BMVert *v;
BMEdge *e, **edges = NULL;
V_DECLARE(edges);
float min[3], max[3];
int i, tot;
BMO_CallOpf(bm, "collapse_uvs edges=%s", op, "edges");
BMO_Init_Op(&weldop, "weldverts");
BMO_Flag_Buffer(bm, op, "edges", EDGE_MARK, BM_EDGE);
BMW_Init(&walker, bm, BMW_SHELL, EDGE_MARK, 0);
BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
if (!BMO_TestFlag(bm, e, EDGE_MARK))
continue;
e = BMW_Begin(&walker, e->v1);
V_RESET(edges);
INIT_MINMAX(min, max);
for (tot=0; e; tot++, e=BMW_Step(&walker)) {
V_GROW(edges);
edges[tot] = e;
DO_MINMAX(e->v1->co, min, max);
DO_MINMAX(e->v2->co, min, max);
}
VECADD(min, min, max);
VECMUL(min, 0.5f);
/*snap edges to a point. for initial testing purposes anyway.*/
for (i=0; i<tot; i++) {
VECCOPY(edges[i]->v1->co, min);
VECCOPY(edges[i]->v2->co, min);
if (edges[i]->v1 != edges[0]->v1)
BMO_Insert_MapPointer(bm, &weldop, "targetmap", edges[i]->v1, edges[0]->v1);
if (edges[i]->v2 != edges[0]->v1)
BMO_Insert_MapPointer(bm, &weldop, "targetmap", edges[i]->v2, edges[0]->v1);
}
}
BMO_Exec_Op(bm, &weldop);
BMO_Finish_Op(bm, &weldop);
BMW_End(&walker);
V_FREE(edges);
}
/*uv collapse function*/
void bmesh_collapsecon_do_layer(BMesh *bm, BMOperator *op, int layer)
{
BMIter iter, liter, liter2;
BMFace *f;
BMLoop *l, *l2;
BMEdge *e;
BMVert *v;
BMWalker walker;
void **blocks = NULL;
V_DECLARE(blocks);
CDBlockBytes min, max;
int i, tot, type = bm->ldata.layers[layer].type;
BMO_Flag_Buffer(bm, op, "edges", EDGE_MARK, BM_EDGE);
BMW_Init(&walker, bm, BMW_UVISLAND, EDGE_MARK, layer);
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
if (BMO_TestFlag(bm, l->e, EDGE_MARK)) {
/*walk*/
V_RESET(blocks);
tot = 0;
l2 = BMW_Begin(&walker, l);
CustomData_data_initminmax(type, &min, &max);
for (tot=0; l2; tot++, l2=BMW_Step(&walker)) {
V_GROW(blocks);
blocks[tot] = CustomData_bmesh_get_layer_n(&bm->ldata, l2->head.data, layer);
CustomData_data_dominmax(type, blocks[tot], &min, &max);
}
CustomData_data_multiply(type, &min, 0.5f);
CustomData_data_multiply(type, &max, 0.5f);
CustomData_data_add(type, &min, &max);
/*snap CD (uv, vcol) points to their centroid*/
for (i=0; i<tot; i++) {
CustomData_bmesh_set_layer_n(&bm->ldata, blocks[i], layer, &min);
}
}
}
}
BMW_End(&walker);
V_FREE(blocks);
}
void bmesh_collapsecon_exec(BMesh *bm, BMOperator *op)
{
int i;
for (i=0; i<bm->ldata.totlayer; i++) {
if (CustomData_layer_has_math(&bm->ldata, i))
bmesh_collapsecon_do_layer(bm, op, i);
}
}
void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op)
{
@@ -275,7 +404,7 @@ void bmesh_finddoubles_exec(BMesh *bm, BMOperator *op)
/*sort by vertex coordinates added together*/
//qsort(verts, V_COUNT(verts), sizeof(void*), vergaverco);
BMO_Flag_Buffer(bm, op, "keepverts", VERT_KEEP);
BMO_Flag_Buffer(bm, op, "keepverts", VERT_KEEP, BM_VERT);
len = V_COUNT(verts);
for (i=0; i<len; i++) {

View File

@@ -631,7 +631,7 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
int beauty;
int i, j, matched, a, b, numcuts, totesel;
BMO_Flag_Buffer(bmesh, op, "edges", SUBD_SPLIT);
BMO_Flag_Buffer(bmesh, op, "edges", SUBD_SPLIT, BM_EDGE);
numcuts = BMO_GetSlot(op, "numcuts")->data.i;
smooth = BMO_GetSlot(op, "smooth")->data.f;

View File

@@ -201,7 +201,7 @@ void bmesh_regionextend_exec(BMesh *bm, BMOperator *op)
int usefaces = BMO_Get_Int(op, "usefaces");
int constrict = BMO_Get_Int(op, "constrict");
BMO_Flag_Buffer(bm, op, "geom", SEL_ORIG);
BMO_Flag_Buffer(bm, op, "geom", SEL_ORIG, BM_ALL);
if (constrict)
bmesh_regionextend_constrict(bm, op, usefaces);
@@ -249,7 +249,7 @@ void bmesh_righthandfaces_exec(BMesh *bm, BMOperator *op)
startf= NULL;
maxx= -1.0e10;
BMO_Flag_Buffer(bm, op, "faces", FACE_FLAG);
BMO_Flag_Buffer(bm, op, "faces", FACE_FLAG, BM_FACE);
/*find a starting face*/
BMO_ITER(f, &siter, bm, op, "faces", BM_FACE) {

View File

@@ -815,7 +815,7 @@ static void walker_select(BMEditMesh *em, int walkercode, void *start, int selec
BMHeader *h;
BMWalker walker;
BMW_Init(&walker, bm, walkercode, 0);
BMW_Init(&walker, bm, walkercode, 0, 0);
h = BMW_Begin(&walker, start);
for (; h; h=BMW_Step(&walker)) {
BM_Select(bm, h, select);
@@ -1536,7 +1536,7 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event
eed = eve->edge;
}
BMW_Init(&walker, em->bm, BMW_SHELL, 0);
BMW_Init(&walker, em->bm, BMW_SHELL, 0, 0);
e = BMW_Begin(&walker, eed->v1);
for (; e; e=BMW_Step(&walker)) {
BM_Select(em->bm, e->v1, sel);
@@ -1587,7 +1587,7 @@ static int select_linked_exec(bContext *C, wmOperator *op)
}
}
BMW_Init(&walker, em->bm, BMW_SHELL, 0);
BMW_Init(&walker, em->bm, BMW_SHELL, 0, 0);
for (i=0; i<tot; i++) {
e = BMW_Begin(&walker, verts[i]);
for (; e; e=BMW_Step(&walker)) {
@@ -1633,7 +1633,7 @@ static int select_more(bContext *C, wmOperator *op)
BM_SELECT, 0, usefaces);
BMO_Exec_Op(em->bm, &bmop);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT, BM_ALL);
EDBM_selectmode_flush(em);
@@ -1669,7 +1669,7 @@ static int select_less(bContext *C, wmOperator *op)
BM_SELECT, 1, usefaces);
BMO_Exec_Op(em->bm, &bmop);
BMO_UnHeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT);
BMO_UnHeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT, BM_ALL);
EDBM_selectmode_flush(em);

View File

@@ -334,10 +334,37 @@ void MESH_OT_subdivs(wmOperatorType *ot)
/* individual face extrude */
/* will use vertex normals for extrusion directions, so *nor is unaffected */
short EDBM_Extrude_face_indiv(BMEditMesh *em, short flag, float *nor)
short EDBM_Extrude_face_indiv(BMEditMesh *em, wmOperator *op, short flag, float *nor)
{
return 'g';
BMOIter siter;
BMIter liter;
BMFace *f;
BMLoop *l;
BMOperator bmop;
EDBM_InitOpf(em, &bmop, op, "extrude_face_indiv faces=%hf", flag);
/*deselect original verts*/
EDBM_clear_flag_all(em, BM_SELECT);
BMO_Exec_Op(em->bm, &bmop);
BMO_ITER(f, &siter, em->bm, &bmop, "faceout", BM_FACE) {
BM_Select(em->bm, f, 1);
/*set face vertex normals to face normal*/
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
VECCOPY(l->v->no, f->no);
}
}
if (!EDBM_FinishOp(em, &bmop, op, 1)) return 0;
return 's'; // s is shrink/fatten
}
#if 0
short EDBM_Extrude_face_indiv(BMEditMesh *em, wmOperator *op, short flag, float *nor)
EditVert *eve, *v1, *v2, *v3, *v4;
EditEdge *eed;
EditFace *efa, *nextfa;
@@ -421,15 +448,31 @@ short EDBM_Extrude_face_indiv(BMEditMesh *em, short flag, float *nor)
EM_select_flush(em);
return 'n';
#endif
}
#endif
/* extrudes individual edges */
short EDBM_Extrude_edges_indiv(BMEditMesh *em, wmOperator *op, short flag, float *nor)
{
BMOperator bmop;
EDBM_InitOpf(em, &bmop, op, "extrude_edge_only edges=%he", flag);
/*deselect original verts*/
EDBM_clear_flag_all(em, BM_SELECT);
BMO_Exec_Op(em->bm, &bmop);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT, BM_VERT|BM_EDGE);
if (!EDBM_FinishOp(em, &bmop, op, 1)) return 0;
return 'n'; // n is normal grab
}
#if 0
/* nor is filled with constraint vector */
short EDBM_Extrude_edges_indiv(BMEditMesh *em, short flag, float *nor)
{
#if 0
EditVert *eve;
EditEdge *eed;
EditFace *efa;
@@ -488,25 +531,23 @@ short EDBM_Extrude_edges_indiv(BMEditMesh *em, short flag, float *nor)
}
if(nor[0]==0.0 && nor[1]==0.0 && nor[2]==0.0) return 'g'; // g is grab
#endif
return 'n'; // n is for normal constraint
}
#endif
/* extrudes individual vertices */
short EDBM_Extrude_verts_indiv(BMEditMesh *em, wmOperator *op, short flag, float *nor)
{
BMOperator bmop;
BMOIter siter;
BMVert *v;
EDBM_InitOpf(em, &bmop, op, "extrude_vert_indiv verts=%hv", flag);
/*deselect original verts*/
BMO_UnHeaderFlag_Buffer(em->bm, &bmop, "verts", BM_SELECT);
BMO_UnHeaderFlag_Buffer(em->bm, &bmop, "verts", BM_SELECT, BM_VERT);
BMO_Exec_Op(em->bm, &bmop);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "vertout", BM_SELECT, BM_VERT);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "vertout", BM_SELECT);
if (!EDBM_FinishOp(em, &bmop, op, 1)) return 0;
return 'g'; // g is grab
@@ -650,7 +691,6 @@ static int extrude_repeat_mesh(bContext *C, wmOperator *op)
int steps = RNA_int_get(op->ptr,"steps");
float offs = RNA_float_get(op->ptr,"offset");
float dvec[3], tmat[3][3], bmat[3][3], nor[3]= {0.0, 0.0, 0.0};
short a;
@@ -711,6 +751,7 @@ int EDBM_Extrude_Mesh(Object *obedit, BMEditMesh *em, wmOperator *op, float *nor
float *nor = norin ? norin : stacknor;
nor[0] = nor[1] = nor[2] = 0.0f;
if(em->selectmode & SCE_SELECT_VERTEX) {
if(em->bm->totvertsel==0) nr= 0;
else if(em->bm->totvertsel==1) nr= 4;
@@ -740,15 +781,15 @@ int EDBM_Extrude_Mesh(Object *obedit, BMEditMesh *em, wmOperator *op, float *nor
else
nr= 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2");
}
if(nr<1) return 'g';
if(nr==1 && em->selectmode & SCE_SELECT_VERTEX)
transmode= EDBM_Extrude_vert(obedit, em, SELECT, nor);
else if (nr == 1) transmode= EDBM_Extrude_edge(obedit, em, SELECT, nor);
else if(nr==4) transmode= EDBM_Extrude_verts_indiv(em, op, SELECT, nor);
else if(nr==3) transmode= EDBM_Extrude_edges_indiv(em, SELECT, nor);
else transmode= EDBM_Extrude_face_indiv(em, SELECT, nor);
else if(nr==3) transmode= EDBM_Extrude_edges_indiv(em, op, SELECT, nor);
else transmode= EDBM_Extrude_face_indiv(em, op, SELECT, nor);
if(transmode==0) {
BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude");
@@ -784,15 +825,29 @@ int EDBM_Extrude_Mesh(Object *obedit, BMEditMesh *em, wmOperator *op, float *nor
return transmode;
}
static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
/* extrude without transform */
static int mesh_extrude_region_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
EDBM_Extrude_Mesh(obedit, em, op, NULL);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
return OPERATOR_FINISHED;
}
static int mesh_extrude_region_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
float nor[3];
int constraint_axis[3] = {0, 0, 1};
int tmode;
tmode = EDBM_Extrude_Mesh(obedit, em, op, NULL);
tmode = EDBM_Extrude_edge(obedit, em, BM_SELECT, nor);
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
@@ -809,29 +864,15 @@ static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
}
/* extrude without transform */
static int mesh_extrude_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
EDBM_Extrude_Mesh(obedit, em, op, NULL);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
return OPERATOR_FINISHED;
}
void MESH_OT_extrude(wmOperatorType *ot)
void MESH_OT_extrude_region(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Extrude";
ot->idname= "MESH_OT_extrude";
ot->name= "Extrude Region";
ot->idname= "MESH_OT_extrude_region";
/* api callbacks */
ot->invoke= mesh_extrude_invoke;
ot->exec= mesh_extrude_exec;
ot->invoke= mesh_extrude_region_invoke;
ot->exec= mesh_extrude_region_exec;
ot->poll= ED_operator_editmesh;
/* flags */
@@ -843,6 +884,296 @@ void MESH_OT_extrude(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
}
static int mesh_extrude_verts_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
float nor[3];
EDBM_Extrude_verts_indiv(em, op, BM_SELECT, nor);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
return OPERATOR_FINISHED;
}
static int mesh_extrude_verts_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
float nor[3];
int constraint_axis[3] = {0, 0, 1};
int tmode;
tmode = EDBM_Extrude_verts_indiv(em, op, BM_SELECT, nor);
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
RNA_enum_set(op->ptr, "proportional", 0);
RNA_boolean_set(op->ptr, "mirror", 0);
if (tmode == 'n') {
RNA_enum_set(op->ptr, "constraint_orientation", V3D_MANIP_NORMAL);
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
}
WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
return OPERATOR_FINISHED;
}
void MESH_OT_extrude_verts_indiv(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Extrude Only Vertices";
ot->idname= "MESH_OT_extrude_verts_indiv";
/* api callbacks */
ot->invoke= mesh_extrude_verts_invoke;
ot->exec= mesh_extrude_verts_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* to give to transform */
Properties_Proportional(ot);
Properties_Constraints(ot);
RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
}
static int mesh_extrude_edges_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
float nor[3];
EDBM_Extrude_edges_indiv(em, op, BM_SELECT, nor);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
return OPERATOR_FINISHED;
}
static int mesh_extrude_edges_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
float nor[3];
int constraint_axis[3] = {0, 0, 1};
int tmode;
tmode = EDBM_Extrude_edges_indiv(em, op, BM_SELECT, nor);
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
RNA_enum_set(op->ptr, "proportional", 0);
RNA_boolean_set(op->ptr, "mirror", 0);
/*if (tmode == 'n') {
RNA_enum_set(op->ptr, "constraint_orientation", V3D_MANIP_NORMAL);
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
}*/
WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
return OPERATOR_FINISHED;
}
void MESH_OT_extrude_edges_indiv(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Extrude Only Edges";
ot->idname= "MESH_OT_extrude_edges_indiv";
/* api callbacks */
ot->invoke= mesh_extrude_edges_invoke;
ot->exec= mesh_extrude_edges_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* to give to transform */
Properties_Proportional(ot);
Properties_Constraints(ot);
RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
}
static int mesh_extrude_faces_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
float nor[3];
EDBM_Extrude_face_indiv(em, op, BM_SELECT, nor);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
return OPERATOR_FINISHED;
}
static int mesh_extrude_faces_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
float nor[3];
int constraint_axis[3] = {0, 0, 1};
int tmode;
tmode = EDBM_Extrude_face_indiv(em, op, BM_SELECT, nor);
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
RNA_enum_set(op->ptr, "proportional", 0);
RNA_boolean_set(op->ptr, "mirror", 0);
if (tmode == 's') {
WM_operator_name_call(C, "TFM_OT_shrink_fatten", WM_OP_INVOKE_REGION_WIN, op->ptr);
} else {
if (tmode == 'n') {
RNA_enum_set(op->ptr, "constraint_orientation", V3D_MANIP_NORMAL);
RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
}
WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
}
return OPERATOR_FINISHED;
}
void MESH_OT_extrude_faces_indiv(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Extrude Individual Faces";
ot->idname= "MESH_OT_extrude_faces_indiv";
/* api callbacks */
ot->invoke= mesh_extrude_faces_invoke;
ot->exec= mesh_extrude_faces_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* to give to transform */
Properties_Proportional(ot);
Properties_Constraints(ot);
RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
}
int extrude_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
uiPopupMenu *pup;
uiLayout *layout;
if(em->selectmode & SCE_SELECT_VERTEX) {
if(em->bm->totvertsel==0) {
return OPERATOR_CANCELLED;
} else if(em->bm->totvertsel==1) {
WM_operator_name_call(C, "MESH_OT_extrude_verts_indiv", WM_OP_INVOKE_REGION_WIN, op->ptr);
} else if(em->bm->totedgesel==0) {
WM_operator_name_call(C, "MESH_OT_extrude_verts_indiv", WM_OP_INVOKE_REGION_WIN, op->ptr);
} else if(em->bm->totfacesel==0) {
// pupmenu("Extrude %t|Only Edges%x3|Only Vertices%x4");
pup= uiPupMenuBegin(C, "Extrude", 0);
layout= uiPupMenuLayout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
uiItemO(layout, "Only Edges", 0, "MESH_OT_extrude_edges_indiv");
uiItemO(layout, "Only Verts", 0, "MESH_OT_extrude_verts_indiv");
uiPupMenuEnd(C, pup);
} else if(em->bm->totfacesel==1) {
// pupmenu("Extrude %t|Region %x1|Only Edges%x3|Only Vertices%x4");
pup= uiPupMenuBegin(C, "Extrude", 0);
layout= uiPupMenuLayout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
uiItemO(layout, "Region", 0, "MESH_OT_extrude_region");
uiItemO(layout, "Only Edges", 0, "MESH_OT_extrude_edges_indiv");
uiItemO(layout, "Only Verts", 0, "MESH_OT_extrude_verts_indiv");
uiPupMenuEnd(C, pup);
} else {
// pupmenu("Extrude %t|Region %x1||Individual Faces %x2|Only Edges%x3|Only Vertices%x4");
pup= uiPupMenuBegin(C, "Extrude", 0);
layout= uiPupMenuLayout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
uiItemO(layout, "Region", 0, "MESH_OT_extrude_region");
uiItemO(layout, "Individual Faces", 0, "MESH_OT_extrude_faces_indiv");
uiItemO(layout, "Only Edges", 0, "MESH_OT_extrude_edges_indiv");
uiItemO(layout, "Only Verts", 0, "MESH_OT_extrude_verts_indiv");
uiPupMenuEnd(C, pup);
}
} else if (em->selectmode & SCE_SELECT_EDGE) {
if (em->bm->totedge==0)
return OPERATOR_CANCELLED;
else if (em->bm->totedgesel==1)
WM_operator_name_call(C, "MESH_OT_extrude_edges_indiv", WM_OP_INVOKE_REGION_WIN, op->ptr);
else if (em->bm->totfacesel==0) {
WM_operator_name_call(C, "MESH_OT_extrude_edges_indiv", WM_OP_INVOKE_REGION_WIN, op->ptr);
} else if (em->bm->totfacesel==1) {
// pupmenu("Extrude %t|Region %x1|Only Edges%x3");
pup= uiPupMenuBegin(C, "Extrude", 0);
layout= uiPupMenuLayout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
uiItemO(layout, "Region", 0, "MESH_OT_extrude_region");
uiItemO(layout, "Only Edges", 0, "MESH_OT_extrude_edges_indiv");
uiPupMenuEnd(C, pup);
} else {
// pupmenu("Extrude %t|Region %x1||Individual Faces %x2|Only Edges%x3");
pup= uiPupMenuBegin(C, "Extrude", 0);
layout= uiPupMenuLayout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
uiItemO(layout, "Region", 0, "MESH_OT_extrude_region");
uiItemO(layout, "Individual Faces", 0, "MESH_OT_extrude_faces_indiv");
uiItemO(layout, "Only Edges", 0, "MESH_OT_extrude_edges_indiv");
uiPupMenuEnd(C, pup);
}
} else if (em->selectmode & SCE_SELECT_FACE) {
if (em->bm->totfacesel==0)
return OPERATOR_CANCELLED;
else if (em->bm->totfacesel==1)
WM_operator_name_call(C, "MESH_OT_extrude_region", WM_OP_INVOKE_REGION_WIN, op->ptr);
else {
// pupmenu("Extrude %t|Region %x1||Individual Faces %x2");
pup= uiPupMenuBegin(C, "Extrude", 0);
layout= uiPupMenuLayout(pup);
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
uiItemO(layout, "Region", 0, "MESH_OT_extrude_region");
uiItemO(layout, "Individual Faces", 0, "MESH_OT_extrude_faces_indiv");
uiPupMenuEnd(C, pup);
}
}
return OPERATOR_CANCELLED;
}
void MESH_OT_extrude(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Extrude";
ot->idname= "MESH_OT_extrude";
/* api callbacks */
ot->invoke= extrude_menu_invoke;
ot->poll= ED_operator_editmesh;
}
/* ******************** (de)select all operator **************** */
void EDBM_toggle_select_all(BMEditMesh *em) /* exported for UV */
@@ -1116,7 +1447,7 @@ static int addedgeface_mesh_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
BMO_Exec_Op(em->bm, &bmop);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "faceout", BM_SELECT);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "faceout", BM_SELECT, BM_FACE);
if (!EDBM_FinishOp(em, &bmop, op, 1))
return OPERATOR_CANCELLED;
@@ -1383,7 +1714,7 @@ static int mesh_duplicate_exec(bContext *C, wmOperator *op)
BMO_Exec_Op(em->bm, &bmop);
EDBM_clear_flag_all(em, BM_SELECT);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "newout", BM_SELECT);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "newout", BM_SELECT, BM_ALL);
if (!EDBM_FinishOp(em, &bmop, op, 1))
return OPERATOR_CANCELLED;
@@ -1506,7 +1837,7 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
EDBM_InitOpf(em, &bmop, op, "edgerotate edges=%e ccw=%d", eed, ccw);
BMO_Exec_Op(em->bm, &bmop);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "edgeout", BM_SELECT);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "edgeout", BM_SELECT, BM_EDGE);
if (!EDBM_FinishOp(em, &bmop, op, 1))
return OPERATOR_CANCELLED;
@@ -1745,3 +2076,66 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot)
RNA_def_int(ot->srna, "repeat", 1, 1, 100, "Number of times to smooth the mesh", "", 1, INT_MAX);
}
static int bm_test_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
#if 1
if (!EDBM_CallOpf(em, op, "collapse edges=%he", BM_SELECT))
return OPERATOR_CANCELLED;
#else //uv island walker test
BMIter iter, liter;
BMFace *f;
BMLoop *l, *l2;
MLoopUV *luv;
BMWalker walker;
int i=0;
BM_ITER(f, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
}
}
BMW_Init(&walker, em->bm, BMW_UVISLAND, 0);
BM_ITER(f, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
if (luv->flag & MLOOPUV_VERTSEL) {
l2 = BMW_Begin(&walker, l);
for (; l2; l2=BMW_Step(&walker)) {
luv = CustomData_bmesh_get(&em->bm->ldata, l2->head.data, CD_MLOOPUV);
luv->flag |= MLOOPUV_VERTSEL;
}
}
}
}
BMW_End(&walker);
#endif
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); //TODO is this needed ?
return OPERATOR_FINISHED;
}
void MESH_OT_bm_test(wmOperatorType *ot)
{
/* identifiers */
ot->name= "BMesh Test Operator";
ot->idname= "MESH_OT_bm_test";
/* api callbacks */
ot->exec= bm_test_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
//RNA_def_int(ot->srna, "repeat", 1, 1, 100, "Number of times to smooth the mesh", "", 1, INT_MAX);
}

View File

@@ -410,7 +410,7 @@ void EDBM_select_more(BMEditMesh *em)
"regionextend geom=%hvef constrict=%d usefaces=%d",
BM_SELECT, 0, usefaces);
BMO_Exec_Op(em->bm, &bmop);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT, BM_ALL);
BMO_Finish_Op(em->bm, &bmop);
EDBM_selectmode_flush(em);
@@ -425,7 +425,7 @@ void EDBM_select_less(BMEditMesh *em)
"regionextend geom=%hvef constrict=%d usefaces=%d",
BM_SELECT, 0, usefaces);
BMO_Exec_Op(em->bm, &bmop);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT);
BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT, BM_ALL);
BMO_Finish_Op(em->bm, &bmop);
EDBM_selectmode_flush(em);

View File

@@ -1508,34 +1508,6 @@ static int edge_not_in_tagged_face(EditMesh *em, EditEdge *eed)
- has vertices with valence 2
*/
static void edgeloop_select(EditMesh *em, EditEdge *starteed, int select)
{
BMesh *bm;
BMEdge *e;
EditMesh *em2;
BMOperator op;
BMWalker walker;
bm = init_editmesh_to_bmesh(em, &op);
BMO_Exec_Op(bm, &op);
e = BMO_Get_MapPointer(bm, &op, "map", starteed);
BMW_Init(&walker, bm, BMW_LOOP, 0);
e = BMW_Begin(&walker, e);
for (; e; e=BMW_Step(&walker)) {
BM_Select(bm, e, 1);
}
BMW_End(&walker);
BMO_Finish_Op(bm, &op);
em2 = bmesh_to_editmesh(bm);
BM_Free_Mesh(bm);
set_editMesh(em, em2);
MEM_freeN(em2);
}
static void edgeloop_select_old(EditMesh *em, EditEdge *starteed, int select)
{
EditVert *eve;
EditEdge *eed;

View File

@@ -5499,8 +5499,6 @@ static int merge_exec(bContext *C, wmOperator *op)
if(!count)
return OPERATOR_CANCELLED;
BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices.", count);
BKE_mesh_end_editmesh(obedit->data, em);
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);

View File

@@ -295,6 +295,11 @@ void MESH_OT_sticky_remove(struct wmOperatorType *ot);
/* ************* bmesh_tools.c ***********/
void MESH_OT_vert_connect(struct wmOperatorType *ot);
void MESH_OT_edge_split(struct wmOperatorType *ot);
void MESH_OT_extrude_region(struct wmOperatorType *ot);
void MESH_OT_extrude_verts_indiv(struct wmOperatorType *ot);
void MESH_OT_extrude_edges_indiv(struct wmOperatorType *ot);
void MESH_OT_extrude_faces_indiv(struct wmOperatorType *ot);
void MESH_OT_bm_test(struct wmOperatorType *ot);
#endif // MESH_INTERN_H

View File

@@ -78,6 +78,7 @@ static int vertex_specials_invoke(bContext *C, wmOperator *op, wmEvent *event)
uiItemO(layout, "Merge...", 0, "MESH_OT_merge");
uiItemO(layout, "Smooth", 0, "MESH_OT_vertices_smooth");
uiItemO(layout, "Select Vertex Path", 0, "MESH_OT_select_vertex_path");
uiItemO(layout, "BMesh Test Operator", 0, "MESH_OT_bm_test");
//uiItemO(layout, "Blend From Shape", 0, "MESH_OT_blend_from_shape");
//uiItemO(layout, "Propagate to All Shapes", 0, "MESH_OT_shape_propagate_to_all");
@@ -231,7 +232,9 @@ static void MESH_OT_specials(wmOperatorType *ot)
void ED_operatortypes_mesh(void)
{
wmOperatorType *ot;
wmOperatorTypeMacro *otm;
static int constraint_axis[3] = {0, 0, 1};
WM_operatortype_append(MESH_OT_select_all_toggle);
WM_operatortype_append(MESH_OT_select_more);
WM_operatortype_append(MESH_OT_select_less);
@@ -317,7 +320,14 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_specials);
WM_operatortype_append(MESH_OT_vert_connect);
WM_operatortype_append(MESH_OT_edge_split);
WM_operatortype_append(MESH_OT_extrude_region);
WM_operatortype_append(MESH_OT_extrude_verts_indiv);
WM_operatortype_append(MESH_OT_extrude_edges_indiv);
WM_operatortype_append(MESH_OT_extrude_faces_indiv);
WM_operatortype_append(MESH_OT_bm_test);
/* macros */
ot= WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MESH_OT_duplicate");
@@ -329,7 +339,14 @@ void ED_operatortypes_mesh(void)
/*ot= WM_operatortype_append_macro("MESH_OT_extrude_move", "Extrude", OPTYPE_UNDO|OPTYPE_REGISTER);
WM_operatortype_macro_define(ot, "MESH_OT_extrude");
WM_operatortype_macro_define(ot, "TFM_OT_translate");*/
otm = WM_operatortype_macro_define(ot, "TFM_OT_translate");
RNA_enum_set(otm->ptr, "proportional", 0);
RNA_boolean_set(otm->ptr, "mirror", 0);
RNA_enum_set(otm->ptr, "constraint_orientation", V3D_MANIP_NORMAL);
RNA_boolean_set_array(otm->ptr, "constraint_axis", constraint_axis);*/
}
/* note mesh keymap also for other space? */

View File

@@ -75,9 +75,11 @@ void WM_operator_free(wmOperator *op)
}
if(op->macro.first) {
wmOperator *opm;
for(opm= op->macro.first; opm; opm= opm->next)
wmOperator *opm, *onext;
for(opm= op->macro.first; opm; opm= onext) {
onext = opm->next;
WM_operator_free(opm);
}
}
MEM_freeN(op);