== Multires ==

Partial fix for bug #5771, Multires tool deletes crease flags on edges

* Modified the edge flags code to support all of the edge flags (not just seams.)
* Added a new array to the Multires struct to store creases.
* For Mark Sharp, Clear Sharp, and Crease, displays an error if applied to a multires mesh not on level 1.
This commit is contained in:
2007-01-22 08:34:53 +00:00
parent cbbd736a9d
commit d58cc7b9e6
7 changed files with 75 additions and 21 deletions

View File

@@ -2543,9 +2543,13 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
if(mesh->mr->edge_flags)
mesh->mr->edge_flags= newdataadr(fd, mesh->mr->edge_flags);
if(mesh->mr->edge_creases)
mesh->mr->edge_creases= newdataadr(fd, mesh->mr->edge_creases);
if(!mesh->mr->edge_flags)
mesh->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "Multires Edge Flags");
if(!mesh->mr->edge_creases)
mesh->mr->edge_creases= MEM_callocN(sizeof(char)*lvl->totedge, "Multires Edge Creases");
for(; lvl; lvl= lvl->next) {
lvl->verts= newdataadr(fd, lvl->verts);

View File

@@ -1178,6 +1178,7 @@ static void write_meshs(WriteData *wd, ListBase *idbase)
write_customdata(wd, lvl->totvert, &mesh->mr->vdata);
write_customdata(wd, lvl->totface, &mesh->mr->fdata);
writedata(wd, DATA, sizeof(short)*lvl->totedge, mesh->mr->edge_flags);
writedata(wd, DATA, sizeof(char)*lvl->totedge, mesh->mr->edge_creases);
}
for(; lvl; lvl= lvl->next) {
writestruct(wd, DATA, "MultiresLevel", 1, lvl);

View File

@@ -129,6 +129,7 @@ typedef struct Multires {
CustomData vdata;
CustomData fdata;
short *edge_flags;
char *edge_creases;
} Multires;
typedef struct PartialVisibility {

View File

@@ -2635,6 +2635,8 @@ void editmesh_mark_sharp(int set)
}
#endif
if(multires_level1_test()) return;
if(set) {
eed= em->edges.first;
while(eed) {

View File

@@ -124,6 +124,7 @@
#include "BPY_menus.h"
#include "blendef.h"
#include "multires.h"
#include "mydevice.h"
#include "butspace.h"
@@ -2545,8 +2546,10 @@ void do_view3d_edit_mesh_edgesmenu(void *arg, int event)
editmesh_mark_seam(1);
break;
case 9: /* Cease SubSurf */
initTransform(TFM_CREASE, CTX_EDGE);
Transform();
if(!multires_level1_test()) {
initTransform(TFM_CREASE, CTX_EDGE);
Transform();
}
break;
case 10: /* Rotate Edge */
edge_rotate_selected(2);

View File

@@ -509,18 +509,33 @@ void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m)
}
}
void multires_get_edge(MultiresEdge *e, EditEdge *eed, MEdge *m, short *flag)
void eed_to_medge_flag(EditEdge *eed, short *flag, char *crease)
{
if(!eed || !flag) return;
/* Would be nice if EditMesh edge flags could be unified with Mesh flags! */
*flag= (eed->f & SELECT) | ME_EDGERENDER;
if(eed->f2<2) *flag |= ME_EDGEDRAW;
if(eed->f2==0) *flag |= ME_LOOSEEDGE;
if(eed->sharp) *flag |= ME_SHARP;
if(eed->seam) *flag |= ME_SEAM;
if(eed->h & EM_FGON) *flag |= ME_FGON;
if(eed->h & 1) *flag |= ME_HIDE;
*crease= (char)(255.0*eed->crease);
}
void multires_get_edge(MultiresEdge *e, EditEdge *eed, MEdge *m, short *flag, char *crease)
{
if(eed) {
e->v[0]= eed->v1->tmp.l;
e->v[1]= eed->v2->tmp.l;
*flag= 0;
if(eed->seam)
*flag |= ME_SEAM;
eed_to_medge_flag(eed, flag, crease);
} else {
e->v[0]= m->v1;
e->v[1]= m->v2;
*flag= m->flag;
*crease= m->crease;
}
}
@@ -591,9 +606,10 @@ void multires_make(void *ob, void *me_v)
lvl->totedge= em ? BLI_countlist(&em->edges) : me->totedge;
lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges");
me->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge flags");
me->mr->edge_creases= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge creases");
if(em) eed= em->edges.first;
for(i=0; i<lvl->totedge; ++i) {
multires_get_edge(&lvl->edges[i], eed, &me->medge[i], &me->mr->edge_flags[i]);
multires_get_edge(&lvl->edges[i], eed, &me->medge[i], &me->mr->edge_flags[i], &me->mr->edge_creases[i]);
if(em) eed= eed->next;
}
@@ -655,6 +671,7 @@ Multires *multires_copy(Multires *orig)
CustomData_copy(&orig->vdata, &mr->vdata, vdata_mask, CD_DUPLICATE, lvl->totvert);
CustomData_copy(&orig->fdata, &mr->fdata, CD_MASK_MTFACE, CD_DUPLICATE, lvl->totface);
mr->edge_flags= MEM_dupallocN(orig->edge_flags);
mr->edge_creases= MEM_dupallocN(orig->edge_creases);
}
return mr;
@@ -672,6 +689,7 @@ void multires_free(Multires *mr)
CustomData_free(&mr->vdata, lvl->totvert);
CustomData_free(&mr->fdata, lvl->totface);
MEM_freeN(mr->edge_flags);
MEM_freeN(mr->edge_creases);
}
while(lvl) {
@@ -727,6 +745,7 @@ void multires_del_lower(void *ob, void *me)
MultiresLevel *lvl1= mr->levels.first, *cr_lvl= current_level(mr);
MultiresLevel *lvl= NULL, *lvlprev= NULL;
short *edgeflags= NULL;
char *edgecreases= NULL;
int i, last;
if(cr_lvl == lvl1) return;
@@ -735,11 +754,16 @@ void multires_del_lower(void *ob, void *me)
/* Subdivide the edge flags to the current level */
edgeflags= MEM_callocN(sizeof(short)*current_level(mr)->totedge, "Multires Edge Flags");
edgecreases= MEM_callocN(sizeof(char)*current_level(mr)->totedge, "Multires Edge Creases");
last= lvl1->totedge * pow(2, mr->current-1);
for(i=0; i<last; ++i)
for(i=0; i<last; ++i) {
edgeflags[i] = mr->edge_flags[(int)(i / pow(2, mr->current-1))];
edgecreases[i] = mr->edge_creases[(int)(i / pow(2, mr->current-1))];
}
MEM_freeN(mr->edge_flags);
MEM_freeN(mr->edge_creases);
mr->edge_flags= edgeflags;
mr->edge_creases= edgecreases;
multires_del_lower_customdata(mr, cr_lvl);
@@ -1022,6 +1046,20 @@ void multires_set_level(void *ob, void *me_v)
waitcursor(0);
}
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;
}
/* note, function is called in background render too, without UI */
void multires_level_to_mesh(Object *ob, Mesh *me)
{
@@ -1105,25 +1143,28 @@ void multires_level_to_mesh(Object *ob, Mesh *me)
if(lvl==me->mr->levels.first) {
for(i=0; i<lvl->totedge; ++i) {
if(em) {
if(me->mr->edge_flags[i] & ME_SEAM)
eed->seam= 1;
medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed);
eed= eed->next;
}
else
else {
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;
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);
if(me->mr->edge_flags[ndx] & ME_SEAM) {
if(em)
eed->seam= 1;
else
me->medge[i].flag |= ME_SEAM;
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];
}
if(em) eed= eed->next;
}
}
@@ -1285,12 +1326,13 @@ void multires_update_edge_flags(Multires *mr, Mesh *me, EditMesh *em)
for(i=0; i<lvl->totedge; ++i) {
if(em) {
mr->edge_flags[i]= 0;
if(eed->seam)
mr->edge_flags[i] |= ME_SEAM;
eed_to_medge_flag(eed, &mr->edge_flags[i], &mr->edge_creases[i]);
eed= eed->next;
}
else
else {
mr->edge_flags[i]= me->medge[i].flag;
mr->edge_creases[i]= me->medge[i].crease;
}
}
}

View File

@@ -1658,7 +1658,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
seam_mark_clear_tface(0);
}
else if (G.qual==LR_SHIFTKEY) {
if (G.obedit && G.obedit->type==OB_MESH) {
if (G.obedit && G.obedit->type==OB_MESH &&
!multires_level1_test()) {
initTransform(TFM_CREASE, CTX_EDGE);
Transform();
}