fix [#30257] bmesh: Rip "V" don't work on end vertex
added option to edgesplit bmesh operator to take tagged vertices as well so an edge at a boundary can split without splitting off the boundary vertex. the behavior/speed of the edge split modifier and tool remainss the same, this is only used for rip.
This commit is contained in:
@@ -893,6 +893,9 @@ static BMOpDefine bmo_edgesplit_def = {
|
|||||||
"edgesplit",
|
"edgesplit",
|
||||||
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
|
{{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
|
||||||
{BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* old output disconnected edges */
|
{BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* old output disconnected edges */
|
||||||
|
/* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
|
||||||
|
{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* optional tag verts, use to have greater control of splits */
|
||||||
|
{BMO_OP_SLOT_BOOL, "use_verts"}, /* use 'verts' for splitting, else just find verts to split from edges */
|
||||||
{0} /* null-terminating sentine */},
|
{0} /* null-terminating sentine */},
|
||||||
bmo_edgesplit_exec,
|
bmo_edgesplit_exec,
|
||||||
BMO_OP_FLAG_UNTAN_MULTIRES
|
BMO_OP_FLAG_UNTAN_MULTIRES
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ enum {
|
|||||||
EDGE_SEAM = 1
|
EDGE_SEAM = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
VERT_SEAM = 2
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the EDGE_SEAM flag for edges we cant split
|
* Remove the EDGE_SEAM flag for edges we cant split
|
||||||
*
|
*
|
||||||
@@ -88,13 +92,35 @@ static void bm_edgesplit_validate_seams(BMesh *bm, BMOperator *op)
|
|||||||
MEM_freeN(vtouch);
|
MEM_freeN(vtouch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* keep this operator fast, its used in a modifier */
|
||||||
void bmo_edgesplit_exec(BMesh *bm, BMOperator *op)
|
void bmo_edgesplit_exec(BMesh *bm, BMOperator *op)
|
||||||
{
|
{
|
||||||
BMOIter siter;
|
BMOIter siter;
|
||||||
BMEdge *e;
|
BMEdge *e;
|
||||||
|
const int use_verts = BMO_slot_bool_get(op, "use_verts");
|
||||||
|
|
||||||
BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, EDGE_SEAM);
|
BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, EDGE_SEAM);
|
||||||
|
|
||||||
|
if (use_verts) {
|
||||||
|
/* this slows down the operation but its ok because the modifier doesn't use */
|
||||||
|
BMO_slot_buffer_flag_enable(bm, op, "verts", BM_VERT, VERT_SEAM);
|
||||||
|
|
||||||
|
/* prevent one edge having both verts unflagged
|
||||||
|
* we could alternately disable these edges, either way its a corner case.
|
||||||
|
*
|
||||||
|
* This is needed so we don't split off the edge but then none of its verts which
|
||||||
|
* would leave a duplicate edge.
|
||||||
|
*/
|
||||||
|
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
|
||||||
|
if (UNLIKELY((BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE &&
|
||||||
|
(BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE))))
|
||||||
|
{
|
||||||
|
BMO_elem_flag_enable(bm, e->v1, VERT_SEAM);
|
||||||
|
BMO_elem_flag_enable(bm, e->v2, VERT_SEAM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bm_edgesplit_validate_seams(bm, op);
|
bm_edgesplit_validate_seams(bm, op);
|
||||||
|
|
||||||
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
|
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
|
||||||
@@ -108,6 +134,17 @@ void bmo_edgesplit_exec(BMesh *bm, BMOperator *op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_verts) {
|
||||||
|
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
|
||||||
|
if (BMO_elem_flag_test(bm, e->v1, VERT_SEAM) == FALSE) {
|
||||||
|
BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
|
||||||
|
}
|
||||||
|
if (BMO_elem_flag_test(bm, e->v2, VERT_SEAM) == FALSE) {
|
||||||
|
BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
|
BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
|
||||||
if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) {
|
if (BMO_elem_flag_test(bm, e, EDGE_SEAM)) {
|
||||||
if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
|
if (BM_elem_flag_test(e->v1, BM_ELEM_TAG)) {
|
||||||
|
|||||||
@@ -1227,9 +1227,7 @@ static int edbm_edge_split_exec(bContext *C, wmOperator *op)
|
|||||||
BMOperator bmop;
|
BMOperator bmop;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
if (!EDBM_InitOpf(em, &bmop, op, "edgesplit edges=%he",
|
if (!EDBM_InitOpf(em, &bmop, op, "edgesplit edges=%he", BM_ELEM_SELECT)) {
|
||||||
BM_ELEM_SELECT))
|
|
||||||
{
|
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
BMO_op_exec(bm, &bmop);
|
BMO_op_exec(bm, &bmop);
|
||||||
@@ -2305,7 +2303,8 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EDBM_InitOpf(em, &bmop, op, "edgesplit edges=%he", BM_ELEM_TAG)) {
|
if (!EDBM_InitOpf(em, &bmop, op, "edgesplit edges=%he verts=%hv use_verts=%b",
|
||||||
|
BM_ELEM_TAG, BM_ELEM_SELECT, TRUE)) {
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user