Do a better job of propagating face data in multires, including flags and materials
This commit is contained in:
@@ -94,7 +94,7 @@ typedef struct MultiresFace {
|
|||||||
unsigned int v[4];
|
unsigned int v[4];
|
||||||
unsigned int mid;
|
unsigned int mid;
|
||||||
unsigned int childrenstart;
|
unsigned int childrenstart;
|
||||||
char flag, pad[3];
|
char flag, mat_nr, pad[2];
|
||||||
} MultiresFace;
|
} MultiresFace;
|
||||||
typedef struct MultiresEdge {
|
typedef struct MultiresEdge {
|
||||||
unsigned int v[2];
|
unsigned int v[2];
|
||||||
|
@@ -535,12 +535,14 @@ void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m)
|
|||||||
test_index_face(&tmp, NULL, 0, efa->v4?4:3);
|
test_index_face(&tmp, NULL, 0, efa->v4?4:3);
|
||||||
for(j=0; j<4; ++j) f->v[j]= (&tmp.v1)[j];
|
for(j=0; j<4; ++j) f->v[j]= (&tmp.v1)[j];
|
||||||
f->flag= tmp.flag;
|
f->flag= tmp.flag;
|
||||||
|
f->mat_nr= efa->mat_nr;
|
||||||
} else {
|
} else {
|
||||||
f->v[0]= m->v1;
|
f->v[0]= m->v1;
|
||||||
f->v[1]= m->v2;
|
f->v[1]= m->v2;
|
||||||
f->v[2]= m->v3;
|
f->v[2]= m->v3;
|
||||||
f->v[3]= m->v4;
|
f->v[3]= m->v4;
|
||||||
f->flag= m->flag;
|
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->prev->faces[i].v[j==max?0:j+1]);
|
||||||
lvl->faces[curf].v[3]= lvl->prev->totvert + lvl->prev->totedge + i;
|
lvl->faces[curf].v[3]= lvl->prev->totvert + lvl->prev->totedge + i;
|
||||||
lvl->faces[curf].flag= lvl->prev->faces[i].flag;
|
lvl->faces[curf].flag= lvl->prev->faces[i].flag;
|
||||||
|
lvl->faces[curf].mat_nr= lvl->prev->faces[i].mat_nr;
|
||||||
|
|
||||||
++curf;
|
++curf;
|
||||||
}
|
}
|
||||||
@@ -1078,8 +1081,10 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
|
|||||||
for(i=0; i<lvl->totface; ++i) {
|
for(i=0; i<lvl->totface; ++i) {
|
||||||
if(em) {
|
if(em) {
|
||||||
EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL;
|
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]],
|
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 */
|
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 {
|
else {
|
||||||
me->mface[i].v1= lvl->faces[i].v[0];
|
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].v4= lvl->faces[i].v[3];
|
||||||
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;
|
||||||
|
me->mface[i].mat_nr= lvl->faces[i].mat_nr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i=0; i<lvl->totedge; ++i) {
|
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;
|
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;
|
||||||
|
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;
|
EditMesh *em= G.obedit ? G.editMesh : NULL;
|
||||||
EditVert *eve= NULL;
|
EditVert *eve= NULL;
|
||||||
EditFace *efa= NULL;
|
EditFace *efa= NULL;
|
||||||
@@ -1350,13 +1358,35 @@ void multires_update_levels(Mesh *me)
|
|||||||
} else
|
} else
|
||||||
VecSubf(&cr_deltas[i].x, me->mvert[i].co, cr_lvl->verts[i].co);
|
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 */
|
/* 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) {
|
for(i=0; i<cr_lvl->totvert; ++i) {
|
||||||
multires_get_vert(&cr_lvl->verts[i], eve, &me->mvert[i], i);
|
multires_get_vert(&cr_lvl->verts[i], eve, &me->mvert[i], i);
|
||||||
if(em) eve= eve->next;
|
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 */
|
/* 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);
|
||||||
@@ -1366,10 +1396,15 @@ void multires_update_levels(Mesh *me)
|
|||||||
if(pr_deltas) MEM_freeN(pr_deltas);
|
if(pr_deltas) MEM_freeN(pr_deltas);
|
||||||
pr_deltas= cr_deltas;
|
pr_deltas= cr_deltas;
|
||||||
cr_deltas= MEM_callocN(sizeof(vec3f)*cr_lvl->totvert,"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
|
/* Calculate and add new deltas
|
||||||
============================*/
|
============================*/
|
||||||
|
|
||||||
for(i=0; i<pr_lvl->totface; ++i) {
|
for(i=0; i<pr_lvl->totface; ++i) {
|
||||||
const MultiresFace *f= &pr_lvl->faces[i];
|
const MultiresFace *f= &pr_lvl->faces[i];
|
||||||
data.corner1= &pr_deltas[f->v[0]].x;
|
data.corner1= &pr_deltas[f->v[0]].x;
|
||||||
@@ -1445,13 +1480,17 @@ void multires_update_levels(Mesh *me)
|
|||||||
|
|
||||||
/* Update faces */
|
/* Update faces */
|
||||||
curf= 0;
|
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;
|
const int sides= cr_lvl->prev->faces[i].v[3] ? 4 : 3;
|
||||||
for(j=0; j<sides; ++j) {
|
for(j=0; j<sides; ++j) {
|
||||||
if(pr_lvl->faces[i].flag & ME_SMOOTH)
|
if(pr_flag_damaged[i]) {
|
||||||
cr_lvl->faces[curf].flag |= ME_SMOOTH;
|
cr_lvl->faces[curf].flag= pr_lvl->faces[i].flag;
|
||||||
else
|
cr_flag_damaged[curf]= 1;
|
||||||
cr_lvl->faces[curf].flag &= ~ME_SMOOTH;
|
}
|
||||||
|
if(pr_mat_damaged[i]) {
|
||||||
|
cr_lvl->faces[curf].mat_nr= pr_lvl->faces[i].mat_nr;
|
||||||
|
cr_mat_damaged[curf]= 1;
|
||||||
|
}
|
||||||
++curf;
|
++curf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1465,7 +1504,24 @@ void multires_update_levels(Mesh *me)
|
|||||||
/* Update lower levels */
|
/* Update lower levels */
|
||||||
cr_lvl= me->mr->levels.last;
|
cr_lvl= me->mr->levels.last;
|
||||||
cr_lvl= cr_lvl->prev;
|
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) {
|
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)
|
for(i=0; i<cr_lvl->totvert; ++i)
|
||||||
cr_lvl->verts[i]= cr_lvl->next->verts[i];
|
cr_lvl->verts[i]= cr_lvl->next->verts[i];
|
||||||
|
|
||||||
@@ -1473,24 +1529,28 @@ void multires_update_levels(Mesh *me)
|
|||||||
curf= 0;
|
curf= 0;
|
||||||
for(i=0; i<cr_lvl->totface; ++i) {
|
for(i=0; i<cr_lvl->totface; ++i) {
|
||||||
const int sides= cr_lvl->faces[i].v[3] ? 4 : 3;
|
const int sides= cr_lvl->faces[i].v[3] ? 4 : 3;
|
||||||
char smooth= 1;
|
|
||||||
|
|
||||||
for(j=0; j<sides; ++j) {
|
/* Check damages */
|
||||||
if(!(cr_lvl->next->faces[curf].flag & ME_SMOOTH)) {
|
for(j=0; j<sides; ++j, ++curf) {
|
||||||
smooth= 0;
|
if(pr_flag_damaged[curf]) {
|
||||||
break;
|
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;
|
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);
|
multires_update_colors(me);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user