ringsel works right again. improved shift-vkey rip tool.

This commit is contained in:
Joseph Eagar
2009-11-04 09:37:08 +00:00
parent 3e6b33b112
commit 48b35b4ef8
2 changed files with 104 additions and 19 deletions

View File

@@ -399,18 +399,6 @@ short EDBM_Extrude_edge(Object *obedit, BMEditMesh *em, int flag, float *nor)
BMO_HeaderFlag_To_Slot(bm, &extop, "edgefacein",
flag, BM_VERT|BM_EDGE|BM_FACE);
BM_ITER(vert, &iter, bm, BM_VERTS_OF_MESH, NULL) {
BM_Select(bm, vert, 0);
}
BM_ITER(edge, &iter, bm, BM_EDGES_OF_MESH, NULL) {
BM_Select(bm, edge, 0);
}
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
BM_Select(bm, f, 0);
}
/* If a mirror modifier with clipping is on, we need to adjust some
* of the cases above to handle edges on the line of symmetry.
*/
@@ -461,6 +449,18 @@ short EDBM_Extrude_edge(Object *obedit, BMEditMesh *em, int flag, float *nor)
}
}
BM_ITER(vert, &iter, bm, BM_VERTS_OF_MESH, NULL) {
BM_Select(bm, vert, 0);
}
BM_ITER(edge, &iter, bm, BM_EDGES_OF_MESH, NULL) {
BM_Select(bm, edge, 0);
}
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
BM_Select(bm, f, 0);
}
BMO_Exec_Op(bm, &extop);
nor[0] = nor[1] = nor[2] = 0.0f;
@@ -2973,7 +2973,7 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
BMLoop *l;
BMEdge *e, *e2, *closest = NULL;
BMVert *v;
int side = 0, i;
int side = 0, i, singlesel = 0;
float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1], 0.0f};
float dist = FLT_MAX, d;
@@ -2989,6 +2989,8 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
the closest edge around that vert to the mouse cursor,
then rip the two adjacent edges in the vert fan.*/
if (em->bm->totvertsel == 1 && em->bm->totedgesel == 0 && em->bm->totfacesel == 0) {
singlesel = 1;
/*find selected vert*/
BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
if (BM_TestHFlag(v, BM_SELECT))
@@ -3015,21 +3017,23 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
/*rip two adjacent edges*/
if (BM_Edge_FaceCount(e2) == 1) {
l = e2->loop;
e = BM_OtherFaceLoop(e2, l->f, v);
e = BM_OtherFaceLoop(e2, l->f, v)->e;
BMINDEX_SET(e, 1);
BM_SetHFlag(e, BM_SELECT);
} else if (BM_Edge_FaceCount(e2) == 2) {
l = e2->loop;
e = BM_OtherFaceLoop(e2, l->f, v);
e = BM_OtherFaceLoop(e2, l->f, v)->e;
BMINDEX_SET(e, 1);
BM_SetHFlag(e, BM_SELECT);
l = e2->loop->radial.next->data;
e = BM_OtherFaceLoop(e2, l->f, v);
e = BM_OtherFaceLoop(e2, l->f, v)->e;
BMINDEX_SET(e, 1);
BM_SetHFlag(e, BM_SELECT);
}
dist = FLT_MAX;
} else {
/*expand edge selection*/
BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
@@ -3121,8 +3125,12 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
if (i == 1)
BM_Select(em->bm, e2, 0);
if (i == 1) {
if (singlesel)
BM_Select(em->bm, v, 0);
else
BM_Select(em->bm, e2, 0);
}
}
EDBM_selectmode_flush(em);

View File

@@ -383,6 +383,79 @@ static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event)
view3d_operator_needs_opengl(C);
switch (event->type) {
case LEFTMOUSE: /* abort */ // XXX hardcoded
ED_region_tag_redraw(lcd->ar);
ringsel_exit(C, op);
return OPERATOR_FINISHED;
case RIGHTMOUSE: /* confirm */ // XXX hardcoded
if (event->val == KM_RELEASE) {
/* finish */
ED_region_tag_redraw(lcd->ar);
ringsel_finish(C, op);
ringsel_exit(C, op);
return OPERATOR_FINISHED;
}
ED_region_tag_redraw(lcd->ar);
break;
case ESCKEY:
if (event->val == KM_RELEASE) {
/* cancel */
ED_region_tag_redraw(lcd->ar);
return ringsel_cancel(C, op);
}
ED_region_tag_redraw(lcd->ar);
break;
case WHEELUPMOUSE: /* change number of cuts */
cuts++;
RNA_int_set(op->ptr,"number_cuts",cuts);
ringsel_find_edge(lcd, C, lcd->ar, cuts);
ED_region_tag_redraw(lcd->ar);
break;
case WHEELDOWNMOUSE: /* change number of cuts */
cuts=MAX2(cuts-1,1);
RNA_int_set(op->ptr,"number_cuts",cuts);
ringsel_find_edge(lcd, C, lcd->ar,cuts);
ED_region_tag_redraw(lcd->ar);
break;
case MOUSEMOVE: { /* mouse moved somewhere to select another loop */
int dist = 75;
BMEdge *edge;
lcd->vc.mval[0] = event->mval[0];
lcd->vc.mval[1] = event->mval[1];
edge = EDBM_findnearestedge(&lcd->vc, &dist);
if (edge != lcd->eed) {
lcd->eed = edge;
ringsel_find_edge(lcd, C, lcd->ar, cuts);
}
ED_region_tag_redraw(lcd->ar);
break;
}
}
/* keep going until the user confirms */
return OPERATOR_RUNNING_MODAL;
}
static int loopcut_modal (bContext *C, wmOperator *op, wmEvent *event)
{
int cuts= RNA_int_get(op->ptr,"number_cuts");
tringselOpData *lcd= op->customdata;
view3d_operator_needs_opengl(C);
switch (event->type) {
case LEFTMOUSE: /* confirm */ // XXX hardcoded
if (event->val == KM_RELEASE) {
@@ -398,6 +471,10 @@ static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event)
ED_region_tag_redraw(lcd->ar);
break;
case RIGHTMOUSE: /* abort */ // XXX hardcoded
ED_region_tag_redraw(lcd->ar);
ringsel_exit(C, op);
return OPERATOR_FINISHED;
case ESCKEY:
if (event->val == KM_RELEASE) {
/* cancel */
@@ -472,7 +549,7 @@ void MESH_OT_loopcut (wmOperatorType *ot)
/* callbacks */
ot->invoke= ringcut_invoke;
ot->modal= ringsel_modal;
ot->modal= loopcut_modal;
ot->cancel= ringsel_cancel;
ot->poll= ED_operator_editmesh;