Better integration of multires with editmode. Setting/adding levels no longer exits editmode, and undo should now work as expected. Still to come is loading customdata from the editmesh.

This commit is contained in:
Nicholas Bishop 2006-12-02 23:37:52 +00:00
parent 76616f2a3b
commit 472c3677fb
6 changed files with 162 additions and 97 deletions

@ -197,8 +197,9 @@ void post_layer_destroy(struct VLayer *vlayer);
void post_server_add(void);
/* multires.c */
struct Multires;
struct MultiresLevel;
void multires_free(struct Mesh *me);
void multires_free(struct Multires *mr);
void multires_set_level(void *ob, void *me_v);
void multires_calc_level_maps(struct MultiresLevel *lvl);
struct Multires *multires_copy(struct Multires *orig);

@ -284,9 +284,9 @@ void post_layer_create(struct VLayer *vlayer) {}
void post_layer_destroy(struct VLayer *vlayer) {}
void post_server_add(void) {}
/* Multires/sculpt stubs */
void multires_free(struct Mesh *me) {}
void multires_free(struct Multires *mr) {}
void multires_set_level(void *ob, void *me_v) {}
void multires_calc_level_maps(struct MultiresLevel *lvl) {}
struct Multires *multires_copy(struct Multires *orig) {}
struct Multires *multires_copy(struct Multires *orig) {return NULL;}
void sculptmode_init(struct Scene *sce) {}
void sculptmode_free_all(struct Scene *sce) {}

@ -186,7 +186,7 @@ void free_mesh(Mesh *me)
if(me->bb) MEM_freeN(me->bb);
if(me->mselect) MEM_freeN(me->mselect);
if(me->mr) multires_free(me);
if(me->mr) multires_free(me->mr);
}
void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)

@ -42,7 +42,7 @@ void multires_disp_map(void *, void*);
void multires_make(void *ob, void *me);
void multires_delete(void *ob, void *me);
struct Multires *multires_copy(struct Multires *orig);
void multires_free(Mesh *me);
void multires_free(Multires *mr);
void multires_free_level(MultiresLevel *lvl);
void multires_del_lower(void *ob, void *me);
void multires_del_higher(void *ob, void *me);

@ -104,6 +104,7 @@
#include "BDR_editface.h"
#include "BDR_vpaint.h"
#include "multires.h"
#include "mydevice.h"
#include "blendef.h"
@ -1815,6 +1816,7 @@ typedef struct UndoMesh {
RetopoPaintData *retopo_paint_data;
char retopo_mode;
CustomData vdata, fdata;
Multires *mr;
} UndoMesh;
/* for callbacks */
@ -1830,6 +1832,7 @@ static void free_undoMesh(void *umv)
if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
CustomData_free(&um->vdata, um->totvert);
CustomData_free(&um->fdata, um->totface);
if(um->mr) multires_free(um->mr);
MEM_freeN(um);
}
@ -1924,6 +1927,8 @@ static void *editMesh_to_undoMesh(void)
um->retopo_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
um->retopo_mode= em->retopo_mode;
um->mr = get_mesh(G.obedit)->mr ? multires_copy(get_mesh(G.obedit)->mr) : NULL;
return um;
}
@ -2034,6 +2039,13 @@ static void undoMesh_to_editMesh(void *umv)
retopo_free_paint();
em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
em->retopo_mode= um->retopo_mode;
{
Mesh *me= get_mesh(G.obedit);
multires_free(me->mr);
me->mr= NULL;
if(um->mr) me->mr= multires_copy(um->mr);
}
}

@ -500,6 +500,49 @@ void multires_load_cols(Mesh *me)
}
}
void multires_get_vert(MVert *v, EditVert *eve, MVert *m, int i)
{
if(eve) {
VecCopyf(v->co, eve->co);
if(eve->f & SELECT) v->flag |= 1;
if(eve->h) v->flag |= ME_HIDE;
eve->tmp.l= i;
}
else
v= m;
}
void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m)
{
if(efa) {
f->v[0]= efa->v1->tmp.l;
f->v[1]= efa->v2->tmp.l;
f->v[2]= efa->v3->tmp.l;
if(efa->v4) f->v[3]= efa->v4->tmp.l;
f->flag= efa->flag;
if(efa->f & 1) f->flag |= ME_FACE_SEL;
else f->flag &= ~ME_FACE_SEL;
if(efa->h) f->flag |= ME_HIDE;
} else {
f->v[0]= m->v1;
f->v[1]= m->v2;
f->v[2]= m->v3;
f->v[3]= m->v4;
f->flag= m->flag;
}
}
void multires_get_edge(MultiresEdge *e, EditEdge *eed, MEdge *m)
{
if(eed) {
e->v[0]= eed->v1->tmp.l;
e->v[1]= eed->v2->tmp.l;
} else {
e->v[0]= m->v1;
e->v[1]= m->v2;
}
}
void multires_make(void *ob, void *me_v)
{
Mesh *me= me_v;
@ -530,15 +573,8 @@ void multires_make(void *ob, void *me_v)
lvl->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts");
if(em) eve= em->verts.first;
for(i=0; i<lvl->totvert; ++i) {
if(em) {
VecCopyf(lvl->verts[i].co, eve->co);
if(eve->f & SELECT) lvl->verts[i].flag |= 1;
if(eve->h) lvl->verts[i].flag |= ME_HIDE;
eve->tmp.l= i;
eve= eve->next;
}
else
lvl->verts[i]= me->mvert[i];
multires_get_vert(&lvl->verts[i], eve, &me->mvert[i], i);
if(em) eve= eve->next;
}
/* Load faces */
@ -546,26 +582,8 @@ void multires_make(void *ob, void *me_v)
lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces");
if(em) efa= em->faces.first;
for(i=0; i<lvl->totface; ++i) {
MultiresFace* f= &lvl->faces[i];
if(em) {
f->v[0]= efa->v1->tmp.l;
f->v[1]= efa->v2->tmp.l;
f->v[2]= efa->v3->tmp.l;
if(efa->v4) f->v[3]= efa->v4->tmp.l;
f->flag= efa->flag;
if(efa->f & 1) f->flag |= ME_FACE_SEL;
else f->flag &= ~ME_FACE_SEL;
if(efa->h) f->flag |= ME_HIDE;
efa= efa->next;
} else {
f->v[0]= me->mface[i].v1;
f->v[1]= me->mface[i].v2;
f->v[2]= me->mface[i].v3;
f->v[3]= me->mface[i].v4;
f->flag= me->mface[i].flag;
}
f->mid= 0;
f->childrenstart= 0;
multires_get_face(&lvl->faces[i], efa, &me->mface[i]);
if(em) efa= efa->next;
}
/* Load edges */
@ -573,15 +591,8 @@ void multires_make(void *ob, void *me_v)
lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges");
if(em) eed= em->edges.first;
for(i=0; i<lvl->totedge; ++i) {
if(em) {
lvl->edges[i].v[0]= eed->v1->tmp.l;
lvl->edges[i].v[1]= eed->v2->tmp.l;
eed= eed->next;
} else {
lvl->edges[i].v[0]= me->medge[i].v1;
lvl->edges[i].v[1]= me->medge[i].v2;
}
lvl->edges[i].mid= 0;
multires_get_edge(&lvl->edges[i], eed, &me->medge[i]);
if(em) eed= eed->next;
}
/* Load dverts */
@ -603,7 +614,9 @@ void multires_make(void *ob, void *me_v)
void multires_delete(void *ob, void *me_v)
{
multires_free(me_v);
Mesh *me= me_v;
multires_free(me->mr);
me->mr= NULL;
allqueue(REDRAWBUTSEDIT, 0);
@ -652,24 +665,23 @@ Multires *multires_copy(Multires *orig)
return NULL;
}
void multires_free(Mesh *me)
void multires_free(Multires *mr)
{
if(me->mr) {
MultiresLevel* lvl= me->mr->levels.first;
if(mr) {
MultiresLevel* lvl= mr->levels.first;
/* Free the first-level data */
if(lvl)
free_dverts(me->mr->dverts, lvl->totvert);
free_dverts(mr->dverts, lvl->totvert);
while(lvl) {
multires_free_level(lvl);
lvl= lvl->next;
}
BLI_freelistN(&me->mr->levels);
BLI_freelistN(&mr->levels);
MEM_freeN(me->mr);
me->mr= NULL;
MEM_freeN(mr);
}
}
@ -782,14 +794,11 @@ void multires_add_level(void *ob, void *me_v)
int i,j, curf, cure;
Mesh *me= me_v;
MultiresLevel *lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel");
int em= G.obedit!=NULL;
MultiApplyData data;
waitcursor(1);
if(me->pv) sculptmode_pmv_off(me);
if(em) exit_editmode(2);
check_colors(me);
@ -957,7 +966,6 @@ void multires_add_level(void *ob, void *me_v)
if(me->mr->renderlvl == me->mr->level_count - 1) me->mr->renderlvl= me->mr->level_count;
multires_level_to_mesh(ob,me);
if(em) enter_editmode(0);
allqueue(REDRAWBUTSEDIT, 0);
@ -969,14 +977,11 @@ void multires_add_level(void *ob, void *me_v)
void multires_set_level(void *ob, void *me_v)
{
Mesh *me= me_v;
int em= G.obedit!=NULL;
waitcursor(1);
if(me->pv) sculptmode_pmv_off(me);
if(em) exit_editmode(2);
check_colors(me);
multires_update_levels(me);
@ -985,8 +990,9 @@ void multires_set_level(void *ob, void *me_v)
else if(me->mr->current>me->mr->level_count) me->mr->current= me->mr->level_count;
multires_level_to_mesh(ob,me);
if(em) enter_editmode(0);
if(G.obedit)
BIF_undo_push("Multires set level");
allqueue(REDRAWBUTSEDIT, 0);
@ -997,39 +1003,65 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
{
MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
int i,sm= G.f & G_SCULPTMODE;
if(sm) set_sculptmode();
CustomData_free_layer(&me->vdata, CD_MVERT, me->totvert);
CustomData_free_layer(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer(&me->fdata, CD_MFACE, me->totface);
CustomData_free_layer(&me->vdata, CD_MDEFORMVERT, me->totvert);
CustomData_free_layer(&me->fdata, CD_MTFACE, me->totface);
CustomData_free_layer(&me->fdata, CD_MCOL, me->totface);
mesh_update_customdata_pointers(me);
EditMesh *em= G.obedit ? G.editMesh : NULL;
EditVert **eves= NULL;
me->totvert= lvl->totvert;
me->totface= lvl->totface;
me->totedge= lvl->totedge;
if(em) {
/* Remove editmesh elements */
free_vertlist(&em->verts);
free_edgelist(&em->edges);
free_facelist(&em->faces);
eves= MEM_callocN(sizeof(EditVert)*lvl->totvert, "editvert pointers");
} else {
if(sm) set_sculptmode();
CustomData_free_layer(&me->vdata, CD_MVERT, me->totvert);
CustomData_free_layer(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer(&me->fdata, CD_MFACE, me->totface);
CustomData_free_layer(&me->vdata, CD_MDEFORMVERT, me->totvert);
CustomData_free_layer(&me->fdata, CD_MTFACE, me->totface);
CustomData_free_layer(&me->fdata, CD_MCOL, me->totface);
mesh_update_customdata_pointers(me);
me->totvert= lvl->totvert;
me->totface= lvl->totface;
me->totedge= lvl->totedge;
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, NULL, me->totvert);
me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, 0, NULL, me->totedge);
me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0, NULL, me->totface);
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, NULL, me->totvert);
me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, 0, NULL, me->totedge);
me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0, NULL, me->totface);
}
/* Vertices/Edges/Faces */
for(i=0; i<lvl->totvert; ++i)
me->mvert[i]= lvl->verts[i];
for(i=0; i<lvl->totvert; ++i) {
if(em)
eves[i]= addvertlist(lvl->verts[i].co, NULL); /* TODO */
else
me->mvert[i]= lvl->verts[i];
}
for(i=0; i<lvl->totface; ++i) {
me->mface[i].v1= lvl->faces[i].v[0];
me->mface[i].v2= lvl->faces[i].v[1];
me->mface[i].v3= lvl->faces[i].v[2];
me->mface[i].v4= lvl->faces[i].v[3];
me->mface[i].flag= lvl->faces[i].flag;
me->mface[i].flag &= ~ME_HIDE;
if(em) {
addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]],
eves[lvl->faces[i].v[2]], eves[lvl->faces[i].v[3]], NULL, NULL); /* TODO */
}
else {
me->mface[i].v1= lvl->faces[i].v[0];
me->mface[i].v2= lvl->faces[i].v[1];
me->mface[i].v3= lvl->faces[i].v[2];
me->mface[i].v4= lvl->faces[i].v[3];
me->mface[i].flag= lvl->faces[i].flag;
me->mface[i].flag &= ~ME_HIDE;
}
}
for(i=0; i<lvl->totedge; ++i) {
me->medge[i].v1= lvl->edges[i].v[0];
me->medge[i].v2= lvl->edges[i].v[1];
me->medge[i].flag &= ~ME_HIDE;
if(em) {
} else {
me->medge[i].v1= lvl->edges[i].v[0];
me->medge[i].v2= lvl->edges[i].v[1];
me->medge[i].flag &= ~ME_HIDE;
}
}
/* Vertex groups */
@ -1098,12 +1130,15 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
for(i=0; i<lvl->totface; ++i)
multirestexcol_to_mcol(&lvl->texcolfaces[i], &me->mcol[i*4]);
}
multires_edge_level_update(ob,me);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
if(sm) set_sculptmode();
if(em)
MEM_freeN(eves);
else {
multires_edge_level_update(ob,me);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
if(sm) set_sculptmode();
}
countall();
@ -1211,6 +1246,9 @@ void multires_update_levels(Mesh *me)
{
MultiresLevel *cr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1), *pr_lvl;
vec3f *pr_deltas= NULL, *cr_deltas= NULL;
EditMesh *em= G.obedit ? G.editMesh : NULL;
EditVert *eve= NULL;
EditFace *efa= NULL;
MultiApplyData data;
unsigned i,j,curf;
@ -1228,14 +1266,28 @@ void multires_update_levels(Mesh *me)
cr_deltas= MEM_callocN(sizeof(vec3f)*cr_lvl->totvert,"initial deltas");
/* Calculate initial deltas -- current mesh subtracted from current level*/
for(i=0; i<cr_lvl->totvert; ++i)
VecSubf(&cr_deltas[i].x,me->mvert[i].co,cr_lvl->verts[i].co);
if(em) eve= em->verts.first;
for(i=0; i<cr_lvl->totvert; ++i) {
if(em) {
VecSubf(&cr_deltas[i].x, eve->co, cr_lvl->verts[i].co);
eve= eve->next;
} else
VecSubf(&cr_deltas[i].x, me->mvert[i].co, cr_lvl->verts[i].co);
}
/* Update current level -- copy current mesh into current level */
for(i=0; i<cr_lvl->totvert; ++i)
cr_lvl->verts[i]= me->mvert[i];
for(i=0; i<cr_lvl->totface; ++i)
cr_lvl->faces[i].flag= me->mface[i].flag;
if(em) eve= em->verts.first;
for(i=0; i<cr_lvl->totvert; ++i) {
multires_get_vert(&cr_lvl->verts[i], eve, &me->mvert[i], i);
if(em) eve= eve->next;
}
if(em) efa= em->faces.first;
for(i=0; i<cr_lvl->totface; ++i) {
if(em) {
efa= efa->next;
} else
cr_lvl->faces[i].flag= me->mface[i].flag;
}
/* Update higher levels */
pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);