== Multires ==

Fixed bad level calls within multires usage.
This commit is contained in:
Nicholas Bishop 2007-12-26 10:43:51 +00:00
parent 88e71a5b79
commit 9807586192
7 changed files with 150 additions and 137 deletions

@ -53,6 +53,7 @@ void multires_create(struct Mesh *me);
void multires_delete_layer(struct Mesh *me, struct CustomData *cd, const int type, int n);
void multires_add_layer(struct Mesh *me, struct CustomData *cd, const int type, const int n);
void multires_del_lower_customdata(struct Multires *mr, struct MultiresLevel *cr_lvl);
void multires_to_mcol(struct MultiresColFace *f, MCol mcol[4]);
/* After adding or removing vcolor layers, run this */
void multires_load_cols(struct Mesh *me);

@ -994,19 +994,6 @@ static unsigned int find_mid_edge(ListBase *vert_edge_map,
return -1;
}
static void medge_flag_to_eed(const short flag, const char crease, EditEdge *eed)
{
if(!eed) return;
if(flag & ME_SEAM) eed->seam= 1;
if(flag & ME_SHARP) eed->sharp = 1;
if(flag & SELECT) eed->f |= SELECT;
if(flag & ME_FGON) eed->h= EM_FGON;
if(flag & ME_HIDE) eed->h |= 1;
eed->crease= ((float)crease)/255.0;
}
static float clamp_component(const float c)
{
if(c<0) return 0;
@ -1014,7 +1001,7 @@ static float clamp_component(const float c)
else return c;
}
static void multires_to_mcol(MultiresColFace *f, MCol mcol[4])
void multires_to_mcol(MultiresColFace *f, MCol mcol[4])
{
unsigned char j;
for(j=0; j<4; ++j) {
@ -1031,88 +1018,51 @@ void multires_level_to_mesh(Object *ob, Mesh *me, const int render)
MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
int i;
EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
EditVert **eves= NULL;
EditEdge *eed= NULL;
if(em) {
/* Remove editmesh elements */
free_editMesh(em);
eves= MEM_callocN(sizeof(EditVert*)*lvl->totvert, "editvert pointers");
} else {
CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface);
CustomData_free_layers(&me->fdata, CD_MCOL, me->totface);
me->totvert= lvl->totvert;
me->totface= lvl->totface;
me->totedge= lvl->totedge;
if(em)
return;
CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
mesh_update_customdata_pointers(me);
}
CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert);
CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge);
CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface);
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface);
CustomData_free_layers(&me->fdata, CD_MCOL, me->totface);
me->totvert= lvl->totvert;
me->totface= lvl->totface;
me->totedge= lvl->totedge;
CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge);
CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
mesh_update_customdata_pointers(me);
/* Vertices/Edges/Faces */
for(i=0; i<lvl->totvert; ++i) {
if(em) {
eves[i]= addvertlist(me->mr->verts[i].co, NULL);
if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT;
if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1;
eves[i]->data= NULL;
}
else
me->mvert[i]= me->mr->verts[i];
me->mvert[i]= me->mr->verts[i];
}
for(i=0; i<lvl->totedge; ++i) {
if(em) {
addedgelist(eves[lvl->edges[i].v[0]], eves[lvl->edges[i].v[1]], NULL);
} 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;
}
me->medge[i].v1= lvl->edges[i].v[0];
me->medge[i].v2= lvl->edges[i].v[1];
me->medge[i].flag &= ~ME_HIDE;
}
for(i=0; i<lvl->totface; ++i) {
if(em) {
EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL;
EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]],
eves[lvl->faces[i].v[2]], eve4, NULL, NULL);
efa->flag= lvl->faces[i].flag & ~ME_HIDE;
efa->mat_nr= lvl->faces[i].mat_nr;
if(lvl->faces[i].flag & ME_FACE_SEL)
efa->f |= SELECT;
if(lvl->faces[i].flag & ME_HIDE) efa->h= 1;
efa->data= NULL;
}
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;
me->mface[i].mat_nr= lvl->faces[i].mat_nr;
}
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;
me->mface[i].mat_nr= lvl->faces[i].mat_nr;
}
/* Edge flags */
if(em) eed= em->edges.first;
if(lvl==me->mr->levels.first) {
for(i=0; i<lvl->totedge; ++i) {
if(em) {
medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed);
eed= eed->next;
}
else {
me->medge[i].flag= me->mr->edge_flags[i];
me->medge[i].crease= me->mr->edge_creases[i];
}
me->medge[i].flag= me->mr->edge_flags[i];
me->medge[i].crease= me->mr->edge_creases[i];
}
} else {
MultiresLevel *lvl1= me->mr->levels.first;
@ -1120,67 +1070,32 @@ void multires_level_to_mesh(Object *ob, Mesh *me, const int render)
for(i=0; i<last; ++i) {
const int ndx= i / pow(2, me->mr->current-1);
if(em) {
medge_flag_to_eed(me->mr->edge_flags[ndx], me->mr->edge_creases[ndx], eed);
eed= eed->next;
}
else {
me->medge[i].flag= me->mr->edge_flags[ndx];
me->medge[i].crease= me->mr->edge_creases[ndx];
}
me->medge[i].flag= me->mr->edge_flags[ndx];
me->medge[i].crease= me->mr->edge_creases[ndx];
}
}
if(em) {
eed= em->edges.first;
for(i=0, eed= em->edges.first; i<lvl->totedge; ++i, eed= eed->next) {
eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE ||
me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE;
}
}
EM_select_flush();
multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT);
multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE);
/* Colors */
if(me->mr->use_col) {
MCol c[4];
EditFace *efa= NULL;
CustomData *src= em ? &em->fdata : &me->fdata;
if(em) {
if(me->mr->use_col) EM_add_data_layer(src, CD_MCOL);
efa= em->faces.first;
}
else {
if(me->mr->use_col) me->mcol= CustomData_add_layer(src, CD_MCOL, CD_CALLOC, NULL, me->totface);
}
CustomData *src= &me->fdata;
if(me->mr->use_col) me->mcol= CustomData_add_layer(src, CD_MCOL, CD_CALLOC, NULL, me->totface);
for(i=0; i<lvl->totface; ++i) {
if(em) {
if(me->mr->use_col) {
multires_to_mcol(&lvl->colfaces[i], c);
CustomData_em_set(src, efa->data, CD_MCOL, c);
}
efa= efa->next;
}
else if(me->mr->use_col) multires_to_mcol(&lvl->colfaces[i], &me->mcol[i*4]);
if(me->mr->use_col)
multires_to_mcol(&lvl->colfaces[i], &me->mcol[i*4]);
}
}
mesh_update_customdata_pointers(me);
if(em) {
MEM_freeN(eves);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
recalc_editnormals();
} 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);
}
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);
}
void multires_add_level(Object *ob, Mesh *me, const char subdiv_type)

@ -47,6 +47,7 @@ void multires_draw_interface(struct uiBlock *block, unsigned short cx, unsigned
void multires_make(void *ob, void *me);
void multires_delete(void *ob, void *me);
void multires_level_to_editmesh(struct Object *ob, struct Mesh *me, const int render);
void multires_subdivide(void *ob, void *me);
void multires_del_lower(void *ob, void *me);
void multires_del_higher(void *ob, void *me);

@ -7161,7 +7161,7 @@ static int Mesh_setMultires( BPy_Mesh * self, PyObject *value, void *type )
switch ((int)type) {
case MESH_MULTIRES_LEVEL:
self->mesh->mr->newlvl = i;
multires_set_level(self->object, self->mesh, 0);
multires_set_level_cb(self->object, self->mesh);
break;
case MESH_MULTIRES_EDGE:
self->mesh->mr->edgelvl = i;

@ -737,6 +737,7 @@ static void delete_customdata_layer(void *data1, void *data2)
from the data stored in multires */
if(me && me->mr) {
multires_delete_layer(me, &me->mr->fdata, type, layer - &data->layers[index]);
multires_level_to_editmesh(OBACT, me, 0);
}
else if(G.obedit) {
EM_free_data_layer(data, type);
@ -4468,6 +4469,7 @@ void do_meshbuts(unsigned short event)
if(me && me->mr) {
multires_add_layer(me, &me->mr->fdata, CD_MTFACE, layernum);
multires_level_to_editmesh(ob, me, 0);
}
else if(G.obedit) {
EM_add_data_layer(&em->fdata, CD_MTFACE);

@ -108,17 +108,109 @@ void multires_check_state()
sculptmode_correct_state();
}
void Vec3fAvg3(float *out, float *v1, float *v2, float *v3)
static void medge_flag_to_eed(const short flag, const char crease, EditEdge *eed)
{
out[0]= (v1[0]+v2[0]+v3[0])/3;
out[1]= (v1[1]+v2[1]+v3[1])/3;
out[2]= (v1[2]+v2[2]+v3[2])/3;
if(!eed) return;
if(flag & ME_SEAM) eed->seam= 1;
if(flag & ME_SHARP) eed->sharp = 1;
if(flag & SELECT) eed->f |= SELECT;
if(flag & ME_FGON) eed->h= EM_FGON;
if(flag & ME_HIDE) eed->h |= 1;
eed->crease= ((float)crease)/255.0;
}
void Vec3fAvg4(float *out, float *v1, float *v2, float *v3, float *v4)
void multires_level_to_editmesh(Object *ob, Mesh *me, const int render)
{
out[0]= (v1[0]+v2[0]+v3[0]+v4[0])/4;
out[1]= (v1[1]+v2[1]+v3[1]+v4[1])/4;
out[2]= (v1[2]+v2[2]+v3[2]+v4[2])/4;
MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
int i;
EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
EditVert **eves= NULL;
EditEdge *eed= NULL;
if(em) {
/* Remove editmesh elements */
free_editMesh(em);
eves= MEM_callocN(sizeof(EditVert*)*lvl->totvert, "editvert pointers");
/* Vertices/Edges/Faces */
for(i=0; i<lvl->totvert; ++i) {
eves[i]= addvertlist(me->mr->verts[i].co, NULL);
if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT;
if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1;
eves[i]->data= NULL;
}
for(i=0; i<lvl->totedge; ++i) {
addedgelist(eves[lvl->edges[i].v[0]], eves[lvl->edges[i].v[1]], NULL);
}
for(i=0; i<lvl->totface; ++i) {
EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL;
EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]],
eves[lvl->faces[i].v[2]], eve4, NULL, NULL);
efa->flag= lvl->faces[i].flag & ~ME_HIDE;
efa->mat_nr= lvl->faces[i].mat_nr;
if(lvl->faces[i].flag & ME_FACE_SEL)
efa->f |= SELECT;
if(lvl->faces[i].flag & ME_HIDE) efa->h= 1;
efa->data= NULL;
}
/* Edge flags */
eed= em->edges.first;
if(lvl==me->mr->levels.first) {
for(i=0; i<lvl->totedge; ++i) {
medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed);
eed= eed->next;
}
} else {
MultiresLevel *lvl1= me->mr->levels.first;
const int last= lvl1->totedge * pow(2, me->mr->current-1);
for(i=0; i<last; ++i) {
const int ndx= i / pow(2, me->mr->current-1);
medge_flag_to_eed(me->mr->edge_flags[ndx], me->mr->edge_creases[ndx], eed);
eed= eed->next;
}
}
eed= em->edges.first;
for(i=0, eed= em->edges.first; i<lvl->totedge; ++i, eed= eed->next) {
eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE ||
me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE;
}
EM_select_flush();
multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT);
multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE);
/* Colors */
if(me->mr->use_col) {
MCol c[4];
EditFace *efa= NULL;
CustomData *src= &em->fdata;
if(me->mr->use_col) EM_add_data_layer(src, CD_MCOL);
efa= em->faces.first;
for(i=0; i<lvl->totface; ++i) {
if(me->mr->use_col) {
multires_to_mcol(&lvl->colfaces[i], c);
CustomData_em_set(src, efa->data, CD_MCOL, c);
}
efa= efa->next;
}
}
mesh_update_customdata_pointers(me);
MEM_freeN(eves);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
recalc_editnormals();
}
}
void multires_make(void *ob, void *me_v)
@ -284,6 +376,7 @@ void multires_subdivide(void *ob_v, void *me_v)
waitcursor(1);
multires_add_level(ob_v, me, G.scene->toolsettings->multires_subdiv_type);
multires_level_to_editmesh(ob_v, me, 0);
multires_finish_mesh_update(ob_v);
allqueue(REDRAWBUTSEDIT, 0);
@ -298,6 +391,7 @@ void multires_set_level_cb(void *ob, void *me)
multires_check_state();
multires_set_level(ob, me, 0);
multires_level_to_editmesh(ob, me, 0);
multires_finish_mesh_update(ob);
if(G.obedit || G.f & G_SCULPTMODE)

@ -1495,13 +1495,13 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case PAGEUPKEY:
if(me && me->mr) {
me->mr->newlvl= ((Mesh*)ob->data)->mr->current+1;
multires_set_level(ob, ob->data, 0);
multires_set_level_cb(ob, ob->data);
}
break;
case PAGEDOWNKEY:
if(me && me->mr) {
me->mr->newlvl= ((Mesh*)ob->data)->mr->current-1;
multires_set_level(ob, ob->data, 0);
multires_set_level_cb(ob, ob->data);
}
break;
/* Partial Visibility */