extrude handles active face, and operators now properly restore unmodified mesh on failure

This commit is contained in:
Joseph Eagar
2009-06-18 07:11:55 +00:00
parent 9dfb7c4cf0
commit 5abbb20c89
7 changed files with 55 additions and 30 deletions

View File

@@ -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.*/

View File

@@ -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();

View File

@@ -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*/},

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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)) {

View File

@@ -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)