extrude handles active face, and operators now properly restore unmodified mesh on failure
This commit is contained in:
@@ -28,6 +28,9 @@ typedef struct BMEditSelection
|
||||
and not BMesh. Mesh->editbmesh will store a pointer to this structure.*/
|
||||
typedef struct BMEditMesh {
|
||||
struct BMesh *bm;
|
||||
|
||||
/*this is for undoing failed operations*/
|
||||
struct BMEditMesh *emcopy;
|
||||
|
||||
/*we store tesselations as triplets of three loops,
|
||||
which each define a triangle.*/
|
||||
|
||||
@@ -127,7 +127,7 @@ void BMEdit_RecalcTesselation(BMEditMesh *tm)
|
||||
BMIter iter, liter;
|
||||
BMFace *f;
|
||||
BMLoop *l;
|
||||
int i = 0;
|
||||
int i = 0, j;
|
||||
|
||||
if (tm->looptris) MEM_freeN(tm->looptris);
|
||||
|
||||
@@ -152,6 +152,7 @@ void BMEdit_RecalcTesselation(BMEditMesh *tm)
|
||||
looptris[i*3] = l;
|
||||
looptris[i*3+1] = (BMLoop*)l->head.next;
|
||||
looptris[i*3+2] = f->loopbase;
|
||||
|
||||
i += 1;
|
||||
}
|
||||
} else {
|
||||
@@ -161,7 +162,10 @@ void BMEdit_RecalcTesselation(BMEditMesh *tm)
|
||||
EditFace *efa;
|
||||
|
||||
l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
|
||||
for (; l; l=BMIter_Step(&liter)) {
|
||||
for (j=0; l; l=BMIter_Step(&liter), j++) {
|
||||
/*mark order*/
|
||||
l->head.eflag2 = j;
|
||||
|
||||
v = BLI_addfillvert(l->v->co);
|
||||
v->tmp.p = l;
|
||||
|
||||
@@ -182,10 +186,18 @@ void BMEdit_RecalcTesselation(BMEditMesh *tm)
|
||||
V_GROW(looptris);
|
||||
V_GROW(looptris);
|
||||
V_GROW(looptris);
|
||||
|
||||
|
||||
looptris[i*3] = efa->v1->tmp.p;
|
||||
looptris[i*3+1] = efa->v2->tmp.p;
|
||||
looptris[i*3+2] = efa->v3->tmp.p;
|
||||
|
||||
if (looptris[i*3]->head.eflag2 > looptris[i*3+1]->head.eflag2);
|
||||
SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]);
|
||||
if (looptris[i*3+1]->head.eflag2 > looptris[i*3+2]->head.eflag2);
|
||||
SWAP(BMLoop*, looptris[i*3+1], looptris[i*3+2]);
|
||||
if (looptris[i*3]->head.eflag2 > looptris[i*3+1]->head.eflag2);
|
||||
SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]);
|
||||
|
||||
i += 1;
|
||||
}
|
||||
BLI_end_edgefill();
|
||||
|
||||
@@ -225,6 +225,9 @@ BMOpDefine def_dupeop = {
|
||||
{{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "origout"},
|
||||
{BMOP_OPSLOT_ELEMENT_BUF, "newout"},
|
||||
/*facemap maps from source faces to dupe
|
||||
faces, and from dupe faces to source faces.*/
|
||||
{BMOP_OPSLOT_MAPPING, "facemap"},
|
||||
{BMOP_OPSLOT_MAPPING, "boundarymap"},
|
||||
{BMOP_OPSLOT_MAPPING, "isovertmap"},
|
||||
{0} /*null-terminating sentinel*/},
|
||||
|
||||
@@ -206,6 +206,9 @@ void bmesh_free_edge(BMesh *bm, BMEdge *e){
|
||||
BLI_mempool_free(bm->epool, e);
|
||||
}
|
||||
void bmesh_free_poly(BMesh *bm, BMFace *f){
|
||||
if (f == bm->act_face)
|
||||
bm->act_face = NULL;
|
||||
|
||||
bm->totface--;
|
||||
CustomData_bmesh_free_block(&bm->pdata, &f->data);
|
||||
BLI_mempool_free(bm->flagpool, f->head.flags);
|
||||
|
||||
@@ -101,7 +101,9 @@ static BMEdge *copy_edge(BMOperator *op, BMesh *source_mesh,
|
||||
* Copy an existing face from one bmesh to another.
|
||||
*
|
||||
*/
|
||||
static BMFace *copy_face(BMesh *source_mesh, BMFace *source_face, BMesh *target_mesh, BMEdge **edar, GHash *vhash, GHash *ehash)
|
||||
static BMFace *copy_face(BMOperator *op, BMesh *source_mesh,
|
||||
BMFace *source_face, BMesh *target_mesh,
|
||||
BMEdge **edar, GHash *vhash, GHash *ehash)
|
||||
{
|
||||
BMVert *target_vert1, *target_vert2;
|
||||
BMLoop *source_loop, *target_loop;
|
||||
@@ -121,7 +123,11 @@ static BMFace *copy_face(BMesh *source_mesh, BMFace *source_face, BMesh *target_
|
||||
|
||||
/*create new face*/
|
||||
target_face = BM_Make_Ngon(target_mesh, target_vert1, target_vert2, edar, source_face->len, 0);
|
||||
|
||||
BMO_Insert_MapPointer(source_mesh, op,
|
||||
"facemap", source_face, target_face);
|
||||
BMO_Insert_MapPointer(source_mesh, op,
|
||||
"facemap", target_face, source_face);
|
||||
|
||||
BM_Copy_Attributes(source_mesh, target_mesh, source_face, target_face);
|
||||
|
||||
/*mark the face for output*/
|
||||
@@ -189,7 +195,7 @@ static void copy_mesh(BMOperator *op, BMesh *source, BMesh *target)
|
||||
BMO_SetFlag(source, (BMHeader*)e, DUPE_DONE);
|
||||
}
|
||||
}
|
||||
copy_face(source, f, target, edar, vhash, ehash);
|
||||
copy_face(op, source, f, target, edar, vhash, ehash);
|
||||
BMO_SetFlag(source, (BMHeader*)f, DUPE_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,8 +101,11 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
|
||||
EXT_DEL, DEL_ONLYTAGGED);
|
||||
|
||||
BMO_CopySlot(op, &dupeop, "edgefacein", "geom");
|
||||
|
||||
BMO_Exec_Op(bm, &dupeop);
|
||||
|
||||
if (bm->act_face && BMO_TestFlag(bm, bm->act_face, EXT_INPUT))
|
||||
bm->act_face = BMO_Get_MapPointer(bm, &dupeop, "facemap", bm->act_face);
|
||||
|
||||
if (delorig) BMO_Exec_Op(bm, &delop);
|
||||
|
||||
/*if not delorig, reverse loops of original faces*/
|
||||
@@ -113,7 +116,7 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BMO_CopySlot(&dupeop, op, "newout", "geomout");
|
||||
e = BMO_IterNew(&siter, bm, &dupeop, "boundarymap");
|
||||
for (; e; e=BMO_IterStep(&siter)) {
|
||||
|
||||
@@ -158,6 +158,8 @@ int EDBM_InitOpf(BMEditMesh *em, BMOperator *bmop, wmOperator *op, char *fmt, ..
|
||||
return 0;
|
||||
}
|
||||
|
||||
em->emcopy = BMEdit_Copy(em);
|
||||
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
@@ -169,24 +171,17 @@ int EDBM_FinishOp(BMEditMesh *em, BMOperator *bmop, wmOperator *op, int report)
|
||||
BMO_Finish_Op(em->bm, bmop);
|
||||
|
||||
if (BMO_GetError(em->bm, &errmsg, NULL)) {
|
||||
BMEditMesh *emcopy = em->emcopy;
|
||||
|
||||
if (report) BKE_report(op->reports, RPT_ERROR, errmsg);
|
||||
/*BMESH_TODOwe should really undo here or something, back
|
||||
out of the failed op :/*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*returns 0 on error, 1 on success*/
|
||||
static int finalize_bmop(BMesh *bm, BMEditMesh *em, wmOperator *op, int report) {
|
||||
char *errmsg;
|
||||
|
||||
if (BMO_GetError(bm, &errmsg, NULL)) {
|
||||
if (report) BKE_report(op->reports, RPT_ERROR, errmsg);
|
||||
/*BMESH_TODOwe should really undo here or something, back
|
||||
out of the failed op :/*/
|
||||
|
||||
BMEdit_Free(em);
|
||||
*em = *emcopy;
|
||||
return 0;
|
||||
} else {
|
||||
BMEdit_Free(em->emcopy);
|
||||
MEM_freeN(em->emcopy);
|
||||
em->emcopy = NULL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -207,12 +202,12 @@ int EDBM_CallOpf(BMEditMesh *em, wmOperator *op, char *fmt, ...)
|
||||
return 0;
|
||||
}
|
||||
|
||||
em->emcopy = BMEdit_Copy(em);
|
||||
|
||||
BMO_Exec_Op(bm, &bmop);
|
||||
BMO_Finish_Op(bm, &bmop);
|
||||
|
||||
va_end(list);
|
||||
|
||||
return finalize_bmop(bm, em, op, 1);
|
||||
return EDBM_FinishOp(em, &bmop, op, 1);
|
||||
}
|
||||
|
||||
int EDBM_CallOpfSilent(BMEditMesh *em, char *fmt, ...)
|
||||
@@ -228,12 +223,12 @@ int EDBM_CallOpfSilent(BMEditMesh *em, char *fmt, ...)
|
||||
return 0;
|
||||
}
|
||||
|
||||
em->emcopy = BMEdit_Copy(em);
|
||||
|
||||
BMO_Exec_Op(bm, &bmop);
|
||||
BMO_Finish_Op(bm, &bmop);
|
||||
|
||||
va_end(list);
|
||||
|
||||
return finalize_bmop(bm, em, NULL, 0);
|
||||
return EDBM_FinishOp(em, &bmop, NULL, 0);
|
||||
}
|
||||
|
||||
void EDBM_MakeEditBMesh(Scene *scene, Object *ob)
|
||||
|
||||
Reference in New Issue
Block a user