editmode undo stores data as mesh dna now, instead of bmesh copies. also fixed a bug related to vpaint and hide flags.

This commit is contained in:
Joseph Eagar 2009-09-10 06:08:52 +00:00
parent 4c072f85d9
commit 4652d66c0a
10 changed files with 165 additions and 116 deletions

@ -66,7 +66,7 @@ int mesh_recalcTesselation(struct CustomData *fdata, struct CustomData *ldata,
int totloop, int totpoly); int totloop, int totpoly);
void unlink_mesh(struct Mesh *me); void unlink_mesh(struct Mesh *me);
void free_mesh(struct Mesh *me); void free_mesh(struct Mesh *me, int unlink);
struct Mesh *add_mesh(char *name); struct Mesh *add_mesh(char *name);
struct Mesh *copy_mesh(struct Mesh *me); struct Mesh *copy_mesh(struct Mesh *me);
void mesh_update_customdata_pointers(struct Mesh *me); void mesh_update_customdata_pointers(struct Mesh *me);

@ -516,7 +516,7 @@ void free_libblock(ListBase *lb, void *idv)
free_object((Object *)id); free_object((Object *)id);
break; break;
case ID_ME: case ID_ME:
free_mesh((Mesh *)id); free_mesh((Mesh *)id, 1);
break; break;
case ID_CU: case ID_CU:
free_curve((Curve *)id); free_curve((Curve *)id);

@ -206,9 +206,10 @@ void unlink_mesh(Mesh *me)
/* do not free mesh itself */ /* do not free mesh itself */
void free_mesh(Mesh *me) void free_mesh(Mesh *me, int unlink)
{ {
unlink_mesh(me); if (unlink)
unlink_mesh(me);
if(me->pv) { if(me->pv) {
if(me->pv->vert_map) MEM_freeN(me->pv->vert_map); if(me->pv->vert_map) MEM_freeN(me->pv->vert_map);

@ -195,7 +195,7 @@ void BM_Compute_Normals(BMesh *bm)
float (*projectverts)[3]; float (*projectverts)[3];
/*first, find out the largest face in mesh*/ /*first, find out the largest face in mesh*/
for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm ); f; f = BMIter_Step(&faces)){ BM_ITER(f, &faces, bm, BM_FACES_OF_MESH, NULL) {
if (BM_TestHFlag(f, BM_HIDDEN)) if (BM_TestHFlag(f, BM_HIDDEN))
continue; continue;
@ -209,7 +209,7 @@ void BM_Compute_Normals(BMesh *bm)
projectverts = MEM_callocN(sizeof(float) * maxlength * 3, "BM normal computation array"); projectverts = MEM_callocN(sizeof(float) * maxlength * 3, "BM normal computation array");
/*calculate all face normals*/ /*calculate all face normals*/
for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm ); f; f = BMIter_Step(&faces)){ BM_ITER(f, &faces, bm, BM_FACES_OF_MESH, NULL) {
if (BM_TestHFlag(f, BM_HIDDEN)) if (BM_TestHFlag(f, BM_HIDDEN))
continue; continue;
if (f->head.flag & BM_NONORMCALC) if (f->head.flag & BM_NONORMCALC)
@ -219,7 +219,7 @@ void BM_Compute_Normals(BMesh *bm)
} }
/*Zero out vertex normals*/ /*Zero out vertex normals*/
for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm ); v; v = BMIter_Step(&verts)) { BM_ITER(v, &verts, bm, BM_VERTS_OF_MESH, NULL) {
if (BM_TestHFlag(v, BM_HIDDEN)) if (BM_TestHFlag(v, BM_HIDDEN))
continue; continue;
@ -227,7 +227,7 @@ void BM_Compute_Normals(BMesh *bm)
} }
/*add face normals to vertices*/ /*add face normals to vertices*/
for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm ); f; f = BMIter_Step(&faces)){ BM_ITER(f, &faces, bm, BM_FACES_OF_MESH, NULL) {
if (BM_TestHFlag(f, BM_HIDDEN)) if (BM_TestHFlag(f, BM_HIDDEN))
continue; continue;
@ -236,7 +236,7 @@ void BM_Compute_Normals(BMesh *bm)
} }
/*average the vertex normals*/ /*average the vertex normals*/
for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm ); v; v= BMIter_Step(&verts)){ BM_ITER(v, &verts, bm, BM_VERTS_OF_MESH, NULL) {
if (BM_TestHFlag(v, BM_HIDDEN)) if (BM_TestHFlag(v, BM_HIDDEN))
continue; continue;

@ -411,11 +411,25 @@ BMOpDefine def_object_load_bmesh = {
{{BMOP_OPSLOT_PNT, "scene"}, {{BMOP_OPSLOT_PNT, "scene"},
{BMOP_OPSLOT_PNT, "object"}, {BMOP_OPSLOT_PNT, "object"},
{0, /*null-terminating sentinel*/}}, {0, /*null-terminating sentinel*/}},
bmesh_to_mesh_exec, object_load_bmesh_exec,
0, 0,
}; };
/*
BMesh to Mesh
Converts a bmesh to a Mesh
*/
BMOpDefine def_bmesh_to_mesh = {
"bmesh_to_mesh",
{{BMOP_OPSLOT_PNT, "meshptr"}, //pointer to a mesh structure to fill in
{BMOP_OPSLOT_INT, "notesselation"}, //don't calculate mfaces
{0, /*null-terminating sentinel*/}},
bmesh_to_mesh_exec,
0,
};
/* /*
Mesh to BMesh Mesh to BMesh
@ -749,6 +763,7 @@ BMOpDefine *opdefines[] = {
&def_pointmerge_facedata, &def_pointmerge_facedata,
&def_vert_average_facedata, &def_vert_average_facedata,
&def_meshrotateuvs, &def_meshrotateuvs,
&def_bmesh_to_mesh,
}; };
int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*)); int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));

@ -1215,7 +1215,7 @@ int BMO_CallOpf(BMesh *bm, char *fmt, ...) {
va_start(list, fmt); va_start(list, fmt);
if (!BMO_VInitOpf(bm, &op, fmt, list)) { if (!BMO_VInitOpf(bm, &op, fmt, list)) {
printf("BMO_CallOpf failed\n"); printf("BMO_CallOpf failed, format is:\n \"%s\"\n", fmt);
va_end(list); va_end(list);
return 0; return 0;
} }

@ -52,5 +52,6 @@ void bmesh_similarverts_exec(BMesh *bm, BMOperator *op);
void bmesh_pointmerge_facedata_exec(BMesh *bm, BMOperator *op); void bmesh_pointmerge_facedata_exec(BMesh *bm, BMOperator *op);
void bmesh_vert_average_facedata_exec(BMesh *bm, BMOperator *op); void bmesh_vert_average_facedata_exec(BMesh *bm, BMOperator *op);
void bmesh_rotateuvs_exec(BMesh *bm, BMOperator *op); void bmesh_rotateuvs_exec(BMesh *bm, BMOperator *op);
void object_load_bmesh_exec(BMesh *bm, BMOperator *op);
#endif #endif

@ -31,10 +31,7 @@
* *
* This file contains functions * This file contains functions
* for converting a Mesh * for converting a Mesh
* into a Bmesh. will not support non-ngon * into a Bmesh, and back again.
* meshes at first, use the editmesh functions
* until it's implemented, and remove this
* comment if it already is. -joeedh
* *
*/ */
@ -214,10 +211,18 @@ static void loops_to_corners(BMesh *bm, Mesh *me, int findex,
} }
} }
void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) { void object_load_bmesh_exec(BMesh *bm, BMOperator *op) {
Object *ob = BMO_Get_Pnt(op, "object"); Object *ob = BMO_Get_Pnt(op, "object");
Scene *scene = BMO_Get_Pnt(op, "scene"); Scene *scene = BMO_Get_Pnt(op, "scene");
Mesh *me = ob->data; Mesh *me = ob->data;
BMO_CallOpf(bm, "bmesh_to_mesh meshptr=%p", me);
/*BMESH_TODO eventually we'll have to handle shapekeys here*/
}
void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
Mesh *me = BMO_Get_Pnt(op, "meshptr");
MLoop *mloop; MLoop *mloop;
MPoly *mpoly; MPoly *mpoly;
MVert *mvert, *oldverts; MVert *mvert, *oldverts;
@ -229,6 +234,7 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
BMFace *f; BMFace *f;
BMIter iter, liter; BMIter iter, liter;
int i, j, ototvert, totloop, totface, numTex, numCol; int i, j, ototvert, totloop, totface, numTex, numCol;
int dotess = !BMO_Get_Int(op, "notesselation");
numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY); numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL); numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
@ -321,103 +327,103 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
} }
/*new scanfill tesselation code*/ /*new scanfill tesselation code*/
if (dotess) {
/*first counter number of faces we'll need*/
totface = 0;
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
EditVert *eve, *lasteve = NULL, *firsteve = NULL;
EditFace *efa;
/*first counter number of faces we'll need*/ i = 0;
totface = 0; BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) { eve = BLI_addfillvert(l->v->co);
EditVert *eve, *lasteve = NULL, *firsteve = NULL; eve->tmp.p = l;
EditFace *efa;
BMINDEX_SET(l, i);
if (lasteve) {
BLI_addfilledge(lasteve, eve);
}
lasteve = eve;
if (!firsteve) firsteve = eve;
i++;
}
BLI_addfilledge(lasteve, firsteve);
BLI_edgefill(0, 0);
for (efa=fillfacebase.first; efa; efa=efa->next)
totface++;
BLI_end_edgefill();
}
me->totface = totface;
/* new tess face block */
if(totface==0) mface= NULL;
else mface= MEM_callocN(totface*sizeof(MFace), "loadeditbMesh face");
CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
CustomData_from_bmeshpoly(&me->fdata, &bm->pdata, &bm->ldata, totface);
mesh_update_customdata_pointers(me);
i = 0; i = 0;
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) { BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
eve = BLI_addfillvert(l->v->co); EditVert *eve, *lasteve = NULL, *firsteve = NULL;
eve->tmp.p = l; EditFace *efa;
BMLoop *ls[3];
BMINDEX_SET(l, i); BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
eve = BLI_addfillvert(l->v->co);
eve->tmp.p = l;
if (lasteve) { if (lasteve) {
BLI_addfilledge(lasteve, eve); BLI_addfilledge(lasteve, eve);
}
lasteve = eve;
if (!firsteve) firsteve = eve;
} }
lasteve = eve; BLI_addfilledge(lasteve, firsteve);
if (!firsteve) firsteve = eve; BLI_edgefill(0, 0);
i++; for (efa=fillfacebase.first; efa; efa=efa->next) {
ls[0] = efa->v1->tmp.p;
ls[1] = efa->v2->tmp.p;
ls[2] = efa->v3->tmp.p;
/*ensure correct winding. I believe this is
analogous to bubble sort on three elements.*/
if (BMINDEX_GET(ls[0]) > BMINDEX_GET(ls[1])) {
SWAP(BMLoop*, ls[0], ls[1]);
}
if (BMINDEX_GET(ls[1]) > BMINDEX_GET(ls[2])) {
SWAP(BMLoop*, ls[1], ls[2]);
}
if (BMINDEX_GET(ls[0]) > BMINDEX_GET(ls[1])) {
SWAP(BMLoop*, ls[0], ls[1]);
}
mface->mat_nr = f->mat_nr;
mface->flag = BMFlags_To_MEFlags(f);
mface->v1 = BMINDEX_GET(ls[0]->v);
mface->v2 = BMINDEX_GET(ls[1]->v);
mface->v3 = BMINDEX_GET(ls[2]->v);
test_index_face(mface, &me->fdata, i, 1);
loops_to_corners(bm, me, i, f, ls, numTex, numCol);
mface++;
i++;
}
BLI_end_edgefill();
} }
BLI_addfilledge(lasteve, firsteve);
BLI_edgefill(0, 0);
for (efa=fillfacebase.first; efa; efa=efa->next)
totface++;
BLI_end_edgefill();
}
me->totface = totface;
/* new tess face block */
if(totface==0) mface= NULL;
else mface= MEM_callocN(totface*sizeof(MFace), "loadeditbMesh face");
CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, mface, me->totface);
CustomData_from_bmeshpoly(&me->fdata, &bm->pdata, &bm->ldata, totface);
mesh_update_customdata_pointers(me);
i = 0;
BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
EditVert *eve, *lasteve = NULL, *firsteve = NULL;
EditFace *efa;
BMLoop *ls[3];
BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
eve = BLI_addfillvert(l->v->co);
eve->tmp.p = l;
if (lasteve) {
BLI_addfilledge(lasteve, eve);
}
lasteve = eve;
if (!firsteve) firsteve = eve;
}
BLI_addfilledge(lasteve, firsteve);
BLI_edgefill(0, 0);
for (efa=fillfacebase.first; efa; efa=efa->next) {
ls[0] = efa->v1->tmp.p;
ls[1] = efa->v2->tmp.p;
ls[2] = efa->v3->tmp.p;
/*ensure correct winding. I believe this is
analogous to bubble sort on three elements.*/
if (BMINDEX_GET(ls[0]) > BMINDEX_GET(ls[1])) {
SWAP(BMLoop*, ls[0], ls[1]);
}
if (BMINDEX_GET(ls[1]) > BMINDEX_GET(ls[2])) {
SWAP(BMLoop*, ls[1], ls[2]);
}
if (BMINDEX_GET(ls[0]) > BMINDEX_GET(ls[1])) {
SWAP(BMLoop*, ls[0], ls[1]);
}
mface->mat_nr = f->mat_nr;
mface->flag = BMFlags_To_MEFlags(f);
mface->v1 = BMINDEX_GET(ls[0]->v);
mface->v2 = BMINDEX_GET(ls[1]->v);
mface->v3 = BMINDEX_GET(ls[2]->v);
test_index_face(mface, &me->fdata, i, 1);
loops_to_corners(bm, me, i, f, ls, numTex, numCol);
mface++;
i++;
}
BLI_end_edgefill();
} }
i = 0; i = 0;
@ -445,4 +451,6 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
i++; i++;
mpoly++; mpoly++;
} }
mesh_update_customdata_pointers(me);
} }

@ -539,32 +539,52 @@ static void *getEditMesh(bContext *C)
return NULL; return NULL;
} }
typedef struct undomesh {
Mesh me;
int selectmode;
} undomesh;
/*undo simply makes copies of a bmesh*/ /*undo simply makes copies of a bmesh*/
static void *editbtMesh_to_undoMesh(void *emv) static void *editbtMesh_to_undoMesh(void *emv)
{ {
BMEditMesh *em = emv;
undomesh *me = MEM_callocN(sizeof(undomesh), "undo Mesh");
/*we recalc the tesselation here, to avoid seeding calls to /*we recalc the tesselation here, to avoid seeding calls to
BMEdit_RecalcTesselation throughout the code.*/ BMEdit_RecalcTesselation throughout the code.*/
BMEdit_RecalcTesselation(emv); BMEdit_RecalcTesselation(em);
return BMEdit_Copy(emv); BMO_CallOpf(em->bm, "bmesh_to_mesh meshptr=%p notesselation=%i", me, 1);
me->selectmode = em->selectmode;
return me;
} }
static void undoMesh_to_editbtMesh(void *umv, void *emv) static void undoMesh_to_editbtMesh(void *umv, void *emv)
{ {
BMEditMesh *em1 = umv, *em2 = emv; BMEditMesh *em = emv, *em2;
undomesh *me = umv;
BMesh *bm;
int allocsize[4] = {512, 512, 2048, 512};
BMEdit_Free(em2); BMEdit_Free(em);
*em2 = *BMEdit_Copy(em1); bm = BM_Make_Mesh(allocsize);
BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p", me);
em2 = BMEdit_Create(bm);
*em = *em2;
em->selectmode = me->selectmode;
MEM_freeN(em2);
} }
static void free_undo(void *umv) static void free_undo(void *umv)
{ {
BMEditMesh *em = umv; free_mesh(umv, 0);
MEM_freeN(umv);
BMEdit_Free(em);
MEM_freeN(em);
} }
/* and this is all the undo system needs to know */ /* and this is all the undo system needs to know */

@ -5750,7 +5750,11 @@ static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmoot
{ {
Mesh *me = userData; Mesh *me = userData;
if (!(me->mface[index].flag&ME_HIDE)) { /*sanity check*/
if (index >= me->totpoly)
return 0;
if (!(me->mpoly[index].flag&ME_HIDE)) {
WM_set_framebuffer_index_color(index+1); WM_set_framebuffer_index_color(index+1);
return 1; return 1;
} else { } else {