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); void post_server_add(void);
/* multires.c */ /* multires.c */
struct Multires;
struct MultiresLevel; 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_set_level(void *ob, void *me_v);
void multires_calc_level_maps(struct MultiresLevel *lvl); void multires_calc_level_maps(struct MultiresLevel *lvl);
struct Multires *multires_copy(struct Multires *orig); 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_layer_destroy(struct VLayer *vlayer) {}
void post_server_add(void) {} void post_server_add(void) {}
/* Multires/sculpt stubs */ /* 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_set_level(void *ob, void *me_v) {}
void multires_calc_level_maps(struct MultiresLevel *lvl) {} 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_init(struct Scene *sce) {}
void sculptmode_free_all(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->bb) MEM_freeN(me->bb);
if(me->mselect) MEM_freeN(me->mselect); 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) 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_make(void *ob, void *me);
void multires_delete(void *ob, void *me); void multires_delete(void *ob, void *me);
struct Multires *multires_copy(struct Multires *orig); 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_free_level(MultiresLevel *lvl);
void multires_del_lower(void *ob, void *me); void multires_del_lower(void *ob, void *me);
void multires_del_higher(void *ob, void *me); void multires_del_higher(void *ob, void *me);

@ -104,6 +104,7 @@
#include "BDR_editface.h" #include "BDR_editface.h"
#include "BDR_vpaint.h" #include "BDR_vpaint.h"
#include "multires.h"
#include "mydevice.h" #include "mydevice.h"
#include "blendef.h" #include "blendef.h"
@ -1815,6 +1816,7 @@ typedef struct UndoMesh {
RetopoPaintData *retopo_paint_data; RetopoPaintData *retopo_paint_data;
char retopo_mode; char retopo_mode;
CustomData vdata, fdata; CustomData vdata, fdata;
Multires *mr;
} UndoMesh; } UndoMesh;
/* for callbacks */ /* 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); if(um->retopo_paint_data) retopo_free_paint_data(um->retopo_paint_data);
CustomData_free(&um->vdata, um->totvert); CustomData_free(&um->vdata, um->totvert);
CustomData_free(&um->fdata, um->totface); CustomData_free(&um->fdata, um->totface);
if(um->mr) multires_free(um->mr);
MEM_freeN(um); 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_paint_data= retopo_paint_data_copy(em->retopo_paint_data);
um->retopo_mode= em->retopo_mode; um->retopo_mode= em->retopo_mode;
um->mr = get_mesh(G.obedit)->mr ? multires_copy(get_mesh(G.obedit)->mr) : NULL;
return um; return um;
} }
@ -2034,6 +2039,13 @@ static void undoMesh_to_editMesh(void *umv)
retopo_free_paint(); retopo_free_paint();
em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data); em->retopo_paint_data= retopo_paint_data_copy(um->retopo_paint_data);
em->retopo_mode= um->retopo_mode; 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) void multires_make(void *ob, void *me_v)
{ {
Mesh *me= 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"); lvl->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts");
if(em) eve= em->verts.first; if(em) eve= em->verts.first;
for(i=0; i<lvl->totvert; ++i) { for(i=0; i<lvl->totvert; ++i) {
if(em) { multires_get_vert(&lvl->verts[i], eve, &me->mvert[i], i);
VecCopyf(lvl->verts[i].co, eve->co); if(em) eve= eve->next;
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];
} }
/* Load faces */ /* Load faces */
@ -546,26 +582,8 @@ void multires_make(void *ob, void *me_v)
lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces"); lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces");
if(em) efa= em->faces.first; if(em) efa= em->faces.first;
for(i=0; i<lvl->totface; ++i) { for(i=0; i<lvl->totface; ++i) {
MultiresFace* f= &lvl->faces[i]; multires_get_face(&lvl->faces[i], efa, &me->mface[i]);
if(em) { if(em) efa= efa->next;
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;
} }
/* Load edges */ /* Load edges */
@ -573,15 +591,8 @@ void multires_make(void *ob, void *me_v)
lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges"); lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges");
if(em) eed= em->edges.first; if(em) eed= em->edges.first;
for(i=0; i<lvl->totedge; ++i) { for(i=0; i<lvl->totedge; ++i) {
if(em) { multires_get_edge(&lvl->edges[i], eed, &me->medge[i]);
lvl->edges[i].v[0]= eed->v1->tmp.l; if(em) eed= eed->next;
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;
} }
/* Load dverts */ /* Load dverts */
@ -603,7 +614,9 @@ void multires_make(void *ob, void *me_v)
void multires_delete(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); allqueue(REDRAWBUTSEDIT, 0);
@ -652,24 +665,23 @@ Multires *multires_copy(Multires *orig)
return NULL; return NULL;
} }
void multires_free(Mesh *me) void multires_free(Multires *mr)
{ {
if(me->mr) { if(mr) {
MultiresLevel* lvl= me->mr->levels.first; MultiresLevel* lvl= mr->levels.first;
/* Free the first-level data */ /* Free the first-level data */
if(lvl) if(lvl)
free_dverts(me->mr->dverts, lvl->totvert); free_dverts(mr->dverts, lvl->totvert);
while(lvl) { while(lvl) {
multires_free_level(lvl); multires_free_level(lvl);
lvl= lvl->next; lvl= lvl->next;
} }
BLI_freelistN(&me->mr->levels); BLI_freelistN(&mr->levels);
MEM_freeN(me->mr); MEM_freeN(mr);
me->mr= NULL;
} }
} }
@ -782,15 +794,12 @@ void multires_add_level(void *ob, void *me_v)
int i,j, curf, cure; int i,j, curf, cure;
Mesh *me= me_v; Mesh *me= me_v;
MultiresLevel *lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel"); MultiresLevel *lvl= MEM_callocN(sizeof(MultiresLevel), "multireslevel");
int em= G.obedit!=NULL;
MultiApplyData data; MultiApplyData data;
waitcursor(1); waitcursor(1);
if(me->pv) sculptmode_pmv_off(me); if(me->pv) sculptmode_pmv_off(me);
if(em) exit_editmode(2);
check_colors(me); check_colors(me);
++me->mr->level_count; ++me->mr->level_count;
@ -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; if(me->mr->renderlvl == me->mr->level_count - 1) me->mr->renderlvl= me->mr->level_count;
multires_level_to_mesh(ob,me); multires_level_to_mesh(ob,me);
if(em) enter_editmode(0);
allqueue(REDRAWBUTSEDIT, 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) void multires_set_level(void *ob, void *me_v)
{ {
Mesh *me= me_v; Mesh *me= me_v;
int em= G.obedit!=NULL;
waitcursor(1); waitcursor(1);
if(me->pv) sculptmode_pmv_off(me); if(me->pv) sculptmode_pmv_off(me);
if(em) exit_editmode(2);
check_colors(me); check_colors(me);
multires_update_levels(me); multires_update_levels(me);
@ -986,7 +991,8 @@ void multires_set_level(void *ob, void *me_v)
multires_level_to_mesh(ob,me); multires_level_to_mesh(ob,me);
if(em) enter_editmode(0); if(G.obedit)
BIF_undo_push("Multires set level");
allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSEDIT, 0);
@ -997,6 +1003,17 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
{ {
MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
int i,sm= G.f & G_SCULPTMODE; int i,sm= G.f & G_SCULPTMODE;
EditMesh *em= G.obedit ? G.editMesh : NULL;
EditVert **eves= NULL;
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(); if(sm) set_sculptmode();
CustomData_free_layer(&me->vdata, CD_MVERT, me->totvert); CustomData_free_layer(&me->vdata, CD_MVERT, me->totvert);
@ -1014,11 +1031,22 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, 0, NULL, me->totvert); 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->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->mface= CustomData_add_layer(&me->fdata, CD_MFACE, 0, NULL, me->totface);
}
/* Vertices/Edges/Faces */ /* Vertices/Edges/Faces */
for(i=0; i<lvl->totvert; ++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]; me->mvert[i]= lvl->verts[i];
}
for(i=0; i<lvl->totface; ++i) { for(i=0; i<lvl->totface; ++i) {
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].v1= lvl->faces[i].v[0];
me->mface[i].v2= lvl->faces[i].v[1]; me->mface[i].v2= lvl->faces[i].v[1];
me->mface[i].v3= lvl->faces[i].v[2]; me->mface[i].v3= lvl->faces[i].v[2];
@ -1026,11 +1054,15 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
me->mface[i].flag= lvl->faces[i].flag; me->mface[i].flag= lvl->faces[i].flag;
me->mface[i].flag &= ~ME_HIDE; me->mface[i].flag &= ~ME_HIDE;
} }
}
for(i=0; i<lvl->totedge; ++i) { for(i=0; i<lvl->totedge; ++i) {
if(em) {
} else {
me->medge[i].v1= lvl->edges[i].v[0]; me->medge[i].v1= lvl->edges[i].v[0];
me->medge[i].v2= lvl->edges[i].v[1]; me->medge[i].v2= lvl->edges[i].v[1];
me->medge[i].flag &= ~ME_HIDE; me->medge[i].flag &= ~ME_HIDE;
} }
}
/* Vertex groups */ /* Vertex groups */
if(me->mr->dverts && lvl==me->mr->levels.first) { if(me->mr->dverts && lvl==me->mr->levels.first) {
@ -1098,12 +1130,15 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
for(i=0; i<lvl->totface; ++i) for(i=0; i<lvl->totface; ++i)
multirestexcol_to_mcol(&lvl->texcolfaces[i], &me->mcol[i*4]); multirestexcol_to_mcol(&lvl->texcolfaces[i], &me->mcol[i*4]);
} }
multires_edge_level_update(ob,me);
if(em)
MEM_freeN(eves);
else {
multires_edge_level_update(ob,me);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
if(sm) set_sculptmode(); if(sm) set_sculptmode();
}
countall(); 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; MultiresLevel *cr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1), *pr_lvl;
vec3f *pr_deltas= NULL, *cr_deltas= NULL; vec3f *pr_deltas= NULL, *cr_deltas= NULL;
EditMesh *em= G.obedit ? G.editMesh : NULL;
EditVert *eve= NULL;
EditFace *efa= NULL;
MultiApplyData data; MultiApplyData data;
unsigned i,j,curf; 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"); cr_deltas= MEM_callocN(sizeof(vec3f)*cr_lvl->totvert,"initial deltas");
/* Calculate initial deltas -- current mesh subtracted from current level*/ /* Calculate initial deltas -- current mesh subtracted from current level*/
for(i=0; i<cr_lvl->totvert; ++i) if(em) eve= em->verts.first;
VecSubf(&cr_deltas[i].x,me->mvert[i].co,cr_lvl->verts[i].co); 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 */ /* Update current level -- copy current mesh into current level */
for(i=0; i<cr_lvl->totvert; ++i) if(em) eve= em->verts.first;
cr_lvl->verts[i]= me->mvert[i]; for(i=0; i<cr_lvl->totvert; ++i) {
for(i=0; i<cr_lvl->totface; ++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; cr_lvl->faces[i].flag= me->mface[i].flag;
}
/* Update higher levels */ /* Update higher levels */
pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);