select more/less properly uses bmops now, and also made a little start on documenting the bmops.
This commit is contained in:
@@ -344,18 +344,15 @@ BMVert *BM_Split_Edge(BMesh *bm, BMVert *v, BMEdge *e, BMEdge **ne, float percen
|
||||
v2 = bmesh_edge_getothervert(e,v);
|
||||
nv = bmesh_semv(bm,v,e,ne);
|
||||
if (nv == NULL) return NULL;
|
||||
|
||||
VECSUB(nv->co,v2->co,v->co);
|
||||
VECADDFAC(nv->co,v->co,nv->co,percent);
|
||||
|
||||
if (ne) {
|
||||
if(bmesh_test_sysflag(&(e->head), BM_SELECT)) {
|
||||
bmesh_set_sysflag((BMHeader*)*ne, BM_SELECT);
|
||||
bmesh_set_sysflag((BMHeader*)nv, BM_SELECT);
|
||||
}
|
||||
if(bmesh_test_sysflag(&(e->head), BM_HIDDEN)) {
|
||||
bmesh_set_sysflag((BMHeader*)*ne, BM_HIDDEN);
|
||||
bmesh_set_sysflag((BMHeader*)nv, BM_HIDDEN);
|
||||
}
|
||||
(*ne)->head.flag = e->head.flag;
|
||||
BM_Copy_Attributes(bm, bm, e, *ne);
|
||||
}
|
||||
|
||||
/*v->nv->v2*/
|
||||
BM_Data_Facevert_Edgeinterp(bm,v2, v, nv, e, percent);
|
||||
BM_Data_Interp_From_Verts(bm, v2, v, nv, percent);
|
||||
|
||||
@@ -2,11 +2,99 @@
|
||||
#include "bmesh_private.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*do not rename any operator or slot names! otherwise you must go
|
||||
through the code and find all references to them!*/
|
||||
/*
|
||||
This file defines (and documents) all bmesh operators (bmops).
|
||||
|
||||
Do not rename any operator or slot names! otherwise you must go
|
||||
through the code and find all references to them!
|
||||
|
||||
A word on slot names:
|
||||
|
||||
For geometry input slots, the following are valid names:
|
||||
* verts
|
||||
* edges
|
||||
* faces
|
||||
* edgefacein
|
||||
* vertfacein
|
||||
* vertedgein
|
||||
* vertfacein
|
||||
* geom
|
||||
|
||||
The basic rules are, for single-type geometry slots, use the plural of the
|
||||
type name (e.g. edges). for double-type slots, use the two type names plus
|
||||
"in" (e.g. edgefacein). for three-type slots, use geom.
|
||||
|
||||
for output slots, for single-type geometry slots, use the type name plus "out",
|
||||
(e.g. vertout), for double-type slots, use the two type names plus "out",
|
||||
(e.g. vertfaceout), for three-type slots, use geom. note that you can also
|
||||
use more esohteric names (e.g. skirtout) do long as the comment next to the
|
||||
slot definition tells you what types of elements are in it.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
ok, I'm going to write a little docgen script. so all
|
||||
bmop comments must conform to the following template/rules:
|
||||
|
||||
template (py quotes used because nested comments don't work
|
||||
on all C compilers):
|
||||
|
||||
"""
|
||||
Region Extend.
|
||||
|
||||
paragraph1, Extends bleh bleh bleh.
|
||||
Bleh Bleh bleh.
|
||||
|
||||
Another paragraph.
|
||||
|
||||
Another paragraph.
|
||||
"""
|
||||
|
||||
so the first line is the "title" of the bmop.
|
||||
subsequent line blocks seperated by blank lines
|
||||
are paragraphs. individual descriptions of slots
|
||||
would be extracted from comments
|
||||
next to them, e.g.
|
||||
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output slot, boundary region
|
||||
|
||||
the doc generator would automatically detect the presence of "output slot"
|
||||
and flag the slot as an output. the same happens for "input slot". also
|
||||
note that "edges", "faces", "verts", "loops", and "geometry" are valid
|
||||
substitutions for "slot".
|
||||
*/
|
||||
|
||||
/*
|
||||
Region Extend
|
||||
|
||||
used to implement the select more/less tools.
|
||||
this puts some geometry surrounding regions of
|
||||
geometry in geom into geomout.
|
||||
|
||||
if usefaces is 0 then geomout spits out verts and edges,
|
||||
otherwise it spits out faces.
|
||||
*/
|
||||
BMOpDefine def_regionextend = {
|
||||
"regionextend",
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output slot, computed boundary geometry.
|
||||
{BMOP_OPSLOT_INT, "constrict"}, //find boundary inside the regions, not outside.
|
||||
{BMOP_OPSLOT_INT, "usefaces"}, //extend from faces instead of edges
|
||||
{0} /*null-terminating sentinel*/,
|
||||
},
|
||||
bmesh_regionextend_exec,
|
||||
0
|
||||
};
|
||||
|
||||
/*
|
||||
Edge Rotate
|
||||
|
||||
Rotates edges topologically. Also known as "spin edge" to some people.
|
||||
Simple example: [/] becomes [|] then [\].
|
||||
*/
|
||||
BMOpDefine def_edgerotate = {
|
||||
"edgerotate",
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //newly spun edges
|
||||
{BMOP_OPSLOT_INT, "ccw"}, //rotate edge counter-clockwise if true, othewise clockwise
|
||||
{0} /*null-terminating sentinel*/,
|
||||
@@ -15,38 +103,54 @@ BMOpDefine def_edgerotate = {
|
||||
0
|
||||
};
|
||||
|
||||
/*
|
||||
Reverse Faces
|
||||
|
||||
Reverses the winding (vertex order) of faces. This has the effect of
|
||||
flipping the normal.
|
||||
*/
|
||||
BMOpDefine def_reversefaces = {
|
||||
"reversefaces",
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, //input faces
|
||||
{0} /*null-terminating sentinel*/,
|
||||
},
|
||||
bmesh_reversefaces_exec,
|
||||
0
|
||||
};
|
||||
|
||||
/*
|
||||
Edge Split
|
||||
|
||||
Splits input edges (but doesn't do anything else).
|
||||
*/
|
||||
BMOpDefine def_edgesplit = {
|
||||
"edgesplit",
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
|
||||
{BMOP_OPSLOT_INT, "numcuts"},
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "outsplit"},
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
|
||||
{BMOP_OPSLOT_INT, "numcuts"}, //number of cuts
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "outsplit"}, //newly created vertices and edges
|
||||
{0} /*null-terminating sentinel*/,
|
||||
},
|
||||
esplit_exec,
|
||||
0
|
||||
};
|
||||
|
||||
/*
|
||||
Mirror
|
||||
|
||||
Mirrors geometry along an axis. The resulting geometry is welded on using
|
||||
mergedist. Pairs of original/mirrored vertices are welded using the mergedist
|
||||
parameter (which defines the minimum distance for welding to happen).
|
||||
*/
|
||||
|
||||
BMOpDefine def_mirror = {
|
||||
"mirror",
|
||||
/*maps welded vertices to verts they should weld to.*/
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
|
||||
//list of verts to keep
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry
|
||||
{BMOP_OPSLOT_MAT, "mat"}, //matrix defining the mirror transformation
|
||||
{BMOP_OPSLOT_FLT, "mergedist"}, //does no merging if mergedist is 0
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "newout"},
|
||||
{BMOP_OPSLOT_INT, "axis"},
|
||||
{BMOP_OPSLOT_INT, "mirror_u"},
|
||||
{BMOP_OPSLOT_INT, "mirror_v"},
|
||||
{BMOP_OPSLOT_FLT, "mergedist"}, //maximum distance for merging. does no merging if 0.
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "newout"}, //output geometry, mirrored
|
||||
{BMOP_OPSLOT_INT, "axis"}, //the axis to use, 0, 1, or 2 for x, y, z
|
||||
{BMOP_OPSLOT_INT, "mirror_u"}, //mirror UVs across the u axis
|
||||
{BMOP_OPSLOT_INT, "mirror_v"}, //mirror UVs across the v axis
|
||||
{0, /*null-terminating sentinel*/}},
|
||||
bmesh_mirror_exec,
|
||||
0,
|
||||
@@ -369,6 +473,7 @@ BMOpDefine *opdefines[] = {
|
||||
&def_edgesplit,
|
||||
&def_reversefaces,
|
||||
&def_edgerotate,
|
||||
&def_regionextend,
|
||||
};
|
||||
|
||||
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
|
||||
|
||||
@@ -38,5 +38,6 @@ void bmesh_mirror_exec(BMesh *bm, BMOperator *op);
|
||||
void esplit_exec(BMesh *bm, BMOperator *op);
|
||||
void bmesh_reversefaces_exec(BMesh *bm, BMOperator *op);
|
||||
void bmesh_edgerotate_exec(BMesh *bm, BMOperator *op);
|
||||
void bmesh_regionextend_exec(BMesh *bm, BMOperator *op);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
void bmesh_makevert_exec(BMesh *bm, BMOperator *op) {
|
||||
void bmesh_makevert_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
float vec[3];
|
||||
|
||||
BMO_Get_Vec(op, "co", vec);
|
||||
@@ -40,7 +41,8 @@ void bmesh_makevert_exec(BMesh *bm, BMOperator *op) {
|
||||
BMO_Flag_To_Slot(bm, op, "newvertout", 1, BM_VERT);
|
||||
}
|
||||
|
||||
void bmesh_transform_exec(BMesh *bm, BMOperator *op) {
|
||||
void bmesh_transform_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOIter iter;
|
||||
BMVert *v;
|
||||
float mat[4][4];
|
||||
@@ -56,7 +58,8 @@ void bmesh_transform_exec(BMesh *bm, BMOperator *op) {
|
||||
is a little complex, but makes it easier to make
|
||||
sure the transform op is working, since initially
|
||||
only this one will be used.*/
|
||||
void bmesh_translate_exec(BMesh *bm, BMOperator *op) {
|
||||
void bmesh_translate_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
float mat[4][4], vec[3];
|
||||
|
||||
BMO_Get_Vec(op, "vec", vec);
|
||||
@@ -67,7 +70,8 @@ void bmesh_translate_exec(BMesh *bm, BMOperator *op) {
|
||||
BMO_CallOpf(bm, "transform mat=%m4 verts=%s", mat, op, "verts");
|
||||
}
|
||||
|
||||
void bmesh_rotate_exec(BMesh *bm, BMOperator *op) {
|
||||
void bmesh_rotate_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
float vec[3];
|
||||
|
||||
BMO_Get_Vec(op, "cent", vec);
|
||||
@@ -84,7 +88,8 @@ void bmesh_rotate_exec(BMesh *bm, BMOperator *op) {
|
||||
BMO_CallOpf(bm, "translate verts=%s vec=%v", op, "verts", vec);
|
||||
}
|
||||
|
||||
void bmesh_reversefaces_exec(BMesh *bm, BMOperator *op) {
|
||||
void bmesh_reversefaces_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOIter siter;
|
||||
BMFace *f;
|
||||
|
||||
@@ -93,7 +98,8 @@ void bmesh_reversefaces_exec(BMesh *bm, BMOperator *op) {
|
||||
}
|
||||
}
|
||||
|
||||
void bmesh_edgerotate_exec(BMesh *bm, BMOperator *op) {
|
||||
void bmesh_edgerotate_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOIter siter;
|
||||
BMEdge *e, *e2;
|
||||
int ccw = BMO_Get_Int(op, "ccw");
|
||||
@@ -109,3 +115,98 @@ void bmesh_edgerotate_exec(BMesh *bm, BMOperator *op) {
|
||||
|
||||
BMO_Flag_To_Slot(bm, op, "edgeout", 1, BM_EDGE);
|
||||
}
|
||||
|
||||
#define SEL_FLAG 1
|
||||
#define SEL_ORIG 2
|
||||
|
||||
static void bmesh_regionextend_extend(BMesh *bm, BMOperator *op, int usefaces)
|
||||
{
|
||||
BMVert *v;
|
||||
BMEdge *e;
|
||||
BMIter eiter;
|
||||
BMOIter siter;
|
||||
|
||||
if (!usefaces) {
|
||||
BMO_ITER(v, &siter, bm, op, "geom", BM_VERT) {
|
||||
BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
|
||||
if (!BMO_TestFlag(bm, e, SEL_ORIG))
|
||||
break;
|
||||
}
|
||||
|
||||
if (e) {
|
||||
BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
|
||||
BMO_SetFlag(bm, e, SEL_FLAG);
|
||||
BMO_SetFlag(bm, BM_OtherEdgeVert(e, v), SEL_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BMIter liter, fiter;
|
||||
BMFace *f, *f2;
|
||||
BMLoop *l;
|
||||
|
||||
BMO_ITER(f, &siter, bm, op, "geom", BM_FACE) {
|
||||
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
|
||||
BM_ITER(f2, &fiter, bm, BM_FACES_OF_EDGE, l->e) {
|
||||
if (!BMO_TestFlag(bm, f2, SEL_ORIG))
|
||||
BMO_SetFlag(bm, f2, SEL_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bmesh_regionextend_constrict(BMesh *bm, BMOperator *op, int usefaces)
|
||||
{
|
||||
BMVert *v;
|
||||
BMEdge *e;
|
||||
BMIter eiter;
|
||||
BMOIter siter;
|
||||
|
||||
if (!usefaces) {
|
||||
BMO_ITER(v, &siter, bm, op, "geom", BM_VERT) {
|
||||
BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
|
||||
if (!BMO_TestFlag(bm, e, SEL_ORIG))
|
||||
break;
|
||||
}
|
||||
|
||||
if (e) {
|
||||
BMO_SetFlag(bm, v, SEL_FLAG);
|
||||
|
||||
BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
|
||||
BMO_SetFlag(bm, e, SEL_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BMIter liter, fiter;
|
||||
BMFace *f, *f2;
|
||||
BMLoop *l;
|
||||
|
||||
BMO_ITER(f, &siter, bm, op, "geom", BM_FACE) {
|
||||
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
|
||||
BM_ITER(f2, &fiter, bm, BM_FACES_OF_EDGE, l->e) {
|
||||
if (!BMO_TestFlag(bm, f2, SEL_ORIG)) {
|
||||
BMO_SetFlag(bm, f, SEL_FLAG);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (constrict)
|
||||
bmesh_regionextend_constrict(bm, op, usefaces);
|
||||
else
|
||||
bmesh_regionextend_extend(bm, op, usefaces);
|
||||
|
||||
BMO_Flag_To_Slot(bm, op, "geomout", SEL_FLAG, BM_ALL);
|
||||
}
|
||||
@@ -1622,84 +1622,25 @@ void MESH_OT_select_linked(wmOperatorType *ot)
|
||||
|
||||
/* ******************** **************** */
|
||||
|
||||
void EDBM_select_more(BMEditMesh *em)
|
||||
{
|
||||
BMIter iter;
|
||||
|
||||
/*for now, bmops aren't supposed to mess with header flags
|
||||
(might need to revisit that design decision later), so
|
||||
this function is slightly unconventional to avoid the use
|
||||
of the BMO_[Set/Clear]Flag functions. it accumulates lists
|
||||
of elements to make selection changes to in pointer arrays.*/
|
||||
|
||||
if (em->selectmode <= SCE_SELECT_EDGE) {
|
||||
BMVert *v;
|
||||
BMEdge *e;
|
||||
BMIter eiter;
|
||||
BMVert **verts = NULL;
|
||||
V_DECLARE(verts);
|
||||
V_DECLARE(edges);
|
||||
BMEdge **edges = NULL;
|
||||
int vtot=0, etot=0, i;
|
||||
|
||||
BM_ITER_NOTSELECT(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL)
|
||||
BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v) {
|
||||
if (BM_TestHFlag(BM_OtherEdgeVert(e, v), BM_SELECT))
|
||||
break;
|
||||
}
|
||||
|
||||
if (e) {
|
||||
V_GROW(verts);
|
||||
verts[vtot++] = v;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (i=0; i<vtot; i++) {
|
||||
BM_Select(em->bm, verts[i], 1);
|
||||
}
|
||||
|
||||
/*make sure we flush from vertices on up, not from edges*/
|
||||
EDBM_select_flush(em, SCE_SELECT_VERTEX);
|
||||
|
||||
V_FREE(verts);
|
||||
} else {
|
||||
BMIter liter, fiter;
|
||||
BMFace *f, *f2, **faces = NULL;
|
||||
V_DECLARE(faces);
|
||||
BMLoop *l;
|
||||
int i, tot=0;
|
||||
|
||||
BM_ITER_SELECT(f, &iter, em->bm, BM_FACES_OF_MESH, NULL)
|
||||
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
|
||||
BM_ITER(f2, &fiter, em->bm, BM_FACES_OF_EDGE, l->e) {
|
||||
if (!BM_TestHFlag(f2, BM_SELECT)) {
|
||||
V_GROW(faces);
|
||||
faces[tot++] = f2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<tot; i++) {
|
||||
BM_Select(em->bm, faces[i], 1);
|
||||
}
|
||||
|
||||
V_FREE(faces);
|
||||
}
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
}
|
||||
|
||||
static int select_more(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
|
||||
BMOperator bmop;
|
||||
int usefaces = em->selectmode > SCE_SELECT_EDGE;
|
||||
|
||||
EDBM_select_more(em);
|
||||
EDBM_InitOpf(em, &bmop, op, "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);
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
|
||||
if (!EDBM_FinishOp(em, &bmop, op, 1))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -1717,92 +1658,23 @@ void MESH_OT_select_more(wmOperatorType *ot)
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
void EDBM_select_less(BMEditMesh *em)
|
||||
{
|
||||
BMIter iter;
|
||||
|
||||
/*for now, bmops aren't supposed to mess with header flags
|
||||
(might need to revisit that design decision later), so
|
||||
this function is slightly unconventional to avoid the use
|
||||
of the BMO_[Set/Clear]Flag functions. it accumulates lists
|
||||
of elements to make selection changes to in pointer arrays.*/
|
||||
|
||||
if (em->selectmode <= SCE_SELECT_EDGE) {
|
||||
BMVert *v;
|
||||
BMEdge *e;
|
||||
BMIter eiter;
|
||||
BMVert **verts = NULL;
|
||||
V_DECLARE(verts);
|
||||
V_DECLARE(edges);
|
||||
BMEdge **edges = NULL;
|
||||
int vtot=0, etot=0, i;
|
||||
|
||||
BM_ITER_SELECT(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL)
|
||||
BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v) {
|
||||
if (!BM_TestHFlag(e, BM_SELECT))
|
||||
break;
|
||||
}
|
||||
|
||||
if (e) {
|
||||
V_GROW(verts);
|
||||
verts[vtot++] = v;
|
||||
|
||||
BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v) {
|
||||
V_GROW(edges);
|
||||
edges[etot++] = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<vtot; i++) {
|
||||
BM_Select(em->bm, verts[i], 0);
|
||||
}
|
||||
|
||||
for (i=0; i<etot; i++) {
|
||||
BM_Select(em->bm, edges[i], 0);
|
||||
}
|
||||
|
||||
V_FREE(verts);
|
||||
V_FREE(edges);
|
||||
} else {
|
||||
BMIter liter, fiter;
|
||||
BMFace *f, *f2, **faces = NULL;
|
||||
V_DECLARE(faces);
|
||||
BMLoop *l;
|
||||
int i, tot=0;
|
||||
|
||||
BM_ITER_SELECT(f, &iter, em->bm, BM_FACES_OF_MESH, NULL)
|
||||
BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
|
||||
BM_ITER(f2, &fiter, em->bm, BM_FACES_OF_EDGE, l->e) {
|
||||
if (!BM_TestHFlag(f2, BM_SELECT))
|
||||
break;
|
||||
}
|
||||
if (f2)
|
||||
break;
|
||||
}
|
||||
|
||||
if (l) {
|
||||
V_GROW(faces);
|
||||
faces[tot++] = f;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<tot; i++) {
|
||||
BM_Select(em->bm, faces[i], 0);
|
||||
}
|
||||
|
||||
V_FREE(faces);
|
||||
}
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
}
|
||||
|
||||
static int select_less(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
|
||||
BMOperator bmop;
|
||||
int usefaces = em->selectmode > SCE_SELECT_EDGE;
|
||||
|
||||
EDBM_select_less(em);
|
||||
EDBM_InitOpf(em, &bmop, op, "regionextend geom=%hvef constrict=%d usefaces=%d",
|
||||
BM_SELECT, 1, usefaces);
|
||||
|
||||
BMO_Exec_Op(em->bm, &bmop);
|
||||
BMO_UnHeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT);
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
|
||||
if (!EDBM_FinishOp(em, &bmop, op, 1))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
|
||||
return OPERATOR_FINISHED;
|
||||
|
||||
@@ -502,18 +502,11 @@ short EDBM_Extrude_verts_indiv(BMEditMesh *em, wmOperator *op, short flag, float
|
||||
EDBM_InitOpf(em, &bmop, op, "extrude_vert_indiv verts=%hv", flag);
|
||||
|
||||
/*deselect original verts*/
|
||||
v = BMO_IterNew(&siter, em->bm, &bmop, "verts", BM_VERT);
|
||||
for (; v; v=BMO_IterStep(&siter)) {
|
||||
BM_Select(em->bm, v, 0);
|
||||
}
|
||||
BMO_UnHeaderFlag_Buffer(em->bm, &bmop, "verts", BM_SELECT);
|
||||
|
||||
BMO_Exec_Op(em->bm, &bmop);
|
||||
|
||||
v = BMO_IterNew(&siter, em->bm, &bmop, "vertout", BM_VERT);
|
||||
for (; v; v=BMO_IterStep(&siter)) {
|
||||
BM_Select(em->bm, v, 1);
|
||||
}
|
||||
|
||||
BMO_HeaderFlag_Buffer(em->bm, &bmop, "vertout", BM_SELECT);
|
||||
if (!EDBM_FinishOp(em, &bmop, op, 1)) return 0;
|
||||
|
||||
return 'g'; // g is grab
|
||||
|
||||
@@ -399,6 +399,37 @@ void EDBM_selectmode_flush(BMEditMesh *em)
|
||||
BM_SelectMode_Flush(em->bm);
|
||||
}
|
||||
|
||||
/*EDBM_select_[more/less] are api functions, I think the uv editor
|
||||
uses them? though the select more/less ops themselves do not.*/
|
||||
void EDBM_select_more(BMEditMesh *em)
|
||||
{
|
||||
BMOperator bmop;
|
||||
int usefaces = em->selectmode > SCE_SELECT_EDGE;
|
||||
|
||||
BMO_InitOpf(em->bm, &bmop,
|
||||
"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_Finish_Op(em->bm, &bmop);
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
}
|
||||
|
||||
void EDBM_select_less(BMEditMesh *em)
|
||||
{
|
||||
BMOperator bmop;
|
||||
int usefaces = em->selectmode > SCE_SELECT_EDGE;
|
||||
|
||||
BMO_InitOpf(em->bm, &bmop,
|
||||
"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_Finish_Op(em->bm, &bmop);
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
}
|
||||
|
||||
int EDBM_get_actSelection(BMEditMesh *em, BMEditSelection *ese)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user