Do a better job of propagating face data in multires, including flags and materials

This commit is contained in:
Nicholas Bishop
2006-12-11 01:54:34 +00:00
parent 3d2dfe8631
commit c0823d1de6
2 changed files with 80 additions and 20 deletions

View File

@@ -94,7 +94,7 @@ typedef struct MultiresFace {
unsigned int v[4];
unsigned int mid;
unsigned int childrenstart;
char flag, pad[3];
char flag, mat_nr, pad[2];
} MultiresFace;
typedef struct MultiresEdge {
unsigned int v[2];

View File

@@ -535,12 +535,14 @@ void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m)
test_index_face(&tmp, NULL, 0, efa->v4?4:3);
for(j=0; j<4; ++j) f->v[j]= (&tmp.v1)[j];
f->flag= tmp.flag;
f->mat_nr= efa->mat_nr;
} 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;
f->mat_nr= m->mat_nr;
}
}
@@ -879,6 +881,7 @@ void multires_add_level(void *ob, void *me_v)
lvl->prev->faces[i].v[j==max?0:j+1]);
lvl->faces[curf].v[3]= lvl->prev->totvert + lvl->prev->totedge + i;
lvl->faces[curf].flag= lvl->prev->faces[i].flag;
lvl->faces[curf].mat_nr= lvl->prev->faces[i].mat_nr;
++curf;
}
@@ -1078,8 +1081,10 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
for(i=0; i<lvl->totface; ++i) {
if(em) {
EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL;
addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]],
eves[lvl->faces[i].v[2]], eve4, NULL, NULL); /* TODO */
EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]],
eves[lvl->faces[i].v[2]], eve4, NULL, NULL); /* TODO */
efa->flag= lvl->faces[i].flag;
efa->mat_nr= lvl->faces[i].mat_nr;
}
else {
me->mface[i].v1= lvl->faces[i].v[0];
@@ -1088,6 +1093,7 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
me->mface[i].v4= lvl->faces[i].v[3];
me->mface[i].flag= lvl->faces[i].flag;
me->mface[i].flag &= ~ME_HIDE;
me->mface[i].mat_nr= lvl->faces[i].mat_nr;
}
}
for(i=0; i<lvl->totedge; ++i) {
@@ -1328,6 +1334,8 @@ 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;
char *pr_flag_damaged= NULL, *cr_flag_damaged= NULL, *pr_mat_damaged= NULL, *cr_mat_damaged= NULL;
char *or_flag_damaged= NULL, *or_mat_damaged= NULL;
EditMesh *em= G.obedit ? G.editMesh : NULL;
EditVert *eve= NULL;
EditFace *efa= NULL;
@@ -1350,13 +1358,35 @@ void multires_update_levels(Mesh *me)
} else
VecSubf(&cr_deltas[i].x, me->mvert[i].co, cr_lvl->verts[i].co);
}
/* Faces -- find whether flag/mat has changed */
cr_flag_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface, "flag_damaged 1");
cr_mat_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface, "mat_damaged 1");
if(em) efa= em->faces.first;
for(i=0; i<cr_lvl->totface; ++i) {
if(cr_lvl->faces[i].flag != (em ? efa->flag : me->mface[i].flag))
cr_flag_damaged[i]= 1;
if(cr_lvl->faces[i].mat_nr != (em ? efa->mat_nr : me->mface[i].mat_nr))
cr_mat_damaged[i]= 1;
if(em) efa= efa->next;
}
or_flag_damaged= MEM_dupallocN(cr_flag_damaged);
or_mat_damaged= MEM_dupallocN(cr_mat_damaged);
/* Update current level -- copy current mesh into current level */
if(em) eve= em->verts.first;
if(em) {
eve= em->verts.first;
efa= em->faces.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;
}
for(i=0; i<cr_lvl->totface; ++i) {
cr_lvl->faces[i].flag= em ? efa->flag : me->mface[i].flag;
cr_lvl->faces[i].mat_nr= em ? efa->mat_nr : me->mface[i].mat_nr;
if(em) efa= efa->next;
}
/* Update higher levels */
pr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
@@ -1366,10 +1396,15 @@ void multires_update_levels(Mesh *me)
if(pr_deltas) MEM_freeN(pr_deltas);
pr_deltas= cr_deltas;
cr_deltas= MEM_callocN(sizeof(vec3f)*cr_lvl->totvert,"deltas");
if(pr_flag_damaged) MEM_freeN(pr_flag_damaged);
pr_flag_damaged= cr_flag_damaged;
cr_flag_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface,"flag_damaged 2");
if(pr_mat_damaged) MEM_freeN(pr_mat_damaged);
pr_mat_damaged= cr_mat_damaged;
cr_mat_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface,"mat_damaged 2");
/* Calculate and add new deltas
============================*/
for(i=0; i<pr_lvl->totface; ++i) {
const MultiresFace *f= &pr_lvl->faces[i];
data.corner1= &pr_deltas[f->v[0]].x;
@@ -1445,13 +1480,17 @@ void multires_update_levels(Mesh *me)
/* Update faces */
curf= 0;
for(i=0; i<cr_lvl->prev->totface; ++i) {
for(i=0; i<pr_lvl->totface; ++i) {
const int sides= cr_lvl->prev->faces[i].v[3] ? 4 : 3;
for(j=0; j<sides; ++j) {
if(pr_lvl->faces[i].flag & ME_SMOOTH)
cr_lvl->faces[curf].flag |= ME_SMOOTH;
else
cr_lvl->faces[curf].flag &= ~ME_SMOOTH;
if(pr_flag_damaged[i]) {
cr_lvl->faces[curf].flag= pr_lvl->faces[i].flag;
cr_flag_damaged[curf]= 1;
}
if(pr_mat_damaged[i]) {
cr_lvl->faces[curf].mat_nr= pr_lvl->faces[i].mat_nr;
cr_mat_damaged[curf]= 1;
}
++curf;
}
}
@@ -1465,7 +1504,24 @@ void multires_update_levels(Mesh *me)
/* Update lower levels */
cr_lvl= me->mr->levels.last;
cr_lvl= cr_lvl->prev;
/* Clear to original damages */
if(pr_flag_damaged) MEM_freeN(pr_flag_damaged);
if(cr_flag_damaged) MEM_freeN(cr_flag_damaged);
if(pr_mat_damaged) MEM_freeN(pr_mat_damaged);
if(cr_mat_damaged) MEM_freeN(cr_mat_damaged);
pr_flag_damaged= pr_mat_damaged= NULL;
cr_flag_damaged= or_flag_damaged;
cr_mat_damaged= or_mat_damaged;
while(cr_lvl) {
if(pr_flag_damaged) MEM_freeN(pr_flag_damaged);
pr_flag_damaged= cr_flag_damaged;
cr_flag_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface,"flag_damaged 3");
if(pr_mat_damaged) MEM_freeN(pr_mat_damaged);
pr_mat_damaged= cr_mat_damaged;
cr_mat_damaged= MEM_callocN(sizeof(char)*cr_lvl->totface,"mat_damaged 3");
for(i=0; i<cr_lvl->totvert; ++i)
cr_lvl->verts[i]= cr_lvl->next->verts[i];
@@ -1473,24 +1529,28 @@ void multires_update_levels(Mesh *me)
curf= 0;
for(i=0; i<cr_lvl->totface; ++i) {
const int sides= cr_lvl->faces[i].v[3] ? 4 : 3;
char smooth= 1;
for(j=0; j<sides; ++j) {
if(!(cr_lvl->next->faces[curf].flag & ME_SMOOTH)) {
smooth= 0;
break;
/* Check damages */
for(j=0; j<sides; ++j, ++curf) {
if(pr_flag_damaged[curf]) {
cr_lvl->faces[i].flag= cr_lvl->next->faces[curf].flag;
cr_flag_damaged[i]= 1;
}
if(pr_mat_damaged[curf]) {
cr_lvl->faces[i].mat_nr= cr_lvl->next->faces[curf].mat_nr;
cr_mat_damaged[i]= 1;
}
++curf;
}
if(smooth)
cr_lvl->faces[i].flag |= ME_SMOOTH;
else
cr_lvl->faces[i].flag &= ~ME_SMOOTH;
}
cr_lvl= cr_lvl->prev;
}
if(pr_flag_damaged) MEM_freeN(pr_flag_damaged);
if(cr_flag_damaged) MEM_freeN(cr_flag_damaged);
if(pr_mat_damaged) MEM_freeN(pr_mat_damaged);
if(cr_mat_damaged) MEM_freeN(cr_mat_damaged);
multires_update_colors(me);
}