Fix for bug #3802: Display problems with modifiers and uv face select

The bug reported here was already fixed some weeks ago, but there were
more issues. Modifier display in face select and paint modes was never
properly finished.

This fixes some small drawing update glitches, and only allows modifiers
that preserve a mapping to the original mesh to be applied. Otherwise
selection and painting isn't even possible.
This commit is contained in:
Brecht Van Lommel 2006-03-11 16:13:10 +00:00
parent 5f550b4ceb
commit 7d5be54fec
8 changed files with 136 additions and 46 deletions

View File

@ -46,6 +46,7 @@
*/
struct MVert;
struct TFace;
struct Object;
struct EditMesh;
struct DispListMesh;
@ -140,10 +141,10 @@ struct DerivedMesh {
*/
void (*drawFacesColored)(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2);
/* Draw all faces uses TFace
/* Draw all faces using TFace
* o Drawing options too complicated to enumerate, look at code.
*/
void (*drawMappedFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int matnr), void *userData);
void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(struct TFace *tface, int matnr));
/* Draw mapped faces (no color, or texture)
* o Only if !setDrawOptions or setDrawOptions(userData, mapped-face-index, drawSmooth_r) returns true
@ -157,6 +158,11 @@ struct DerivedMesh {
*/
void (*drawMappedFaces)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors);
/* Draw mapped faces using TFace
* o Drawing options too complicated to enumerate, look at code.
*/
void (*drawMappedFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData);
/* Draw mapped edges as lines
* o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge) returns true
*/

View File

@ -366,7 +366,8 @@ static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned ch
glShadeModel(GL_FLAT);
glDisable(GL_CULL_FACE);
}
static void meshDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData)
static void meshDM_drawFacesTex_common(DerivedMesh *dm, int (*drawParams)(TFace *tface, int matnr), int (*drawParamsMapped)(void *userData, int index), void *userData)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->me;
@ -382,7 +383,10 @@ static void meshDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void
int flag;
unsigned char *cp= NULL;
flag = setDrawParams(userData, i, mf->mat_nr);
if (drawParams)
flag = drawParams(tf, mf->mat_nr);
else
flag = drawParamsMapped(userData, i);
if (flag==0) {
continue;
@ -425,6 +429,15 @@ static void meshDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void
glEnd();
}
}
static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tface, int matnr))
{
meshDM_drawFacesTex_common(dm, setDrawParams, NULL, NULL);
}
static void meshDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData)
{
meshDM_drawFacesTex_common(dm, NULL, setDrawParams, userData);
}
static void meshDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
@ -535,8 +548,9 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3]
mdm->dm.drawFacesSolid = meshDM_drawFacesSolid;
mdm->dm.drawFacesColored = meshDM_drawFacesColored;
mdm->dm.drawMappedFacesTex = meshDM_drawMappedFacesTex;
mdm->dm.drawFacesTex = meshDM_drawFacesTex;
mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
mdm->dm.drawMappedFacesTex = meshDM_drawMappedFacesTex;
mdm->dm.drawMappedEdges = meshDM_drawMappedEdges;
mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
@ -1223,7 +1237,7 @@ static void ssDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
#undef PASSVERT
}
static void ssDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData)
static void ssDM_drawFacesTex_common(DerivedMesh *dm, int (*drawParams)(TFace *tface, int matnr), int (*drawParamsMapped)(void *userData, int index), void *userData)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
DispListMesh *dlm = ssdm->dlm;
@ -1239,9 +1253,13 @@ static void ssDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *
int flag;
unsigned char *cp= NULL;
if (mf->flag&ME_FACE_STEPINDEX) index++;
flag = setDrawParams(userData, index, mf->mat_nr);
if (drawParams) {
flag = drawParams(tf, mf->mat_nr);
}
else {
if (mf->flag&ME_FACE_STEPINDEX) index++;
flag = drawParamsMapped(userData, index);
}
if (flag==0) {
continue;
@ -1282,6 +1300,15 @@ static void ssDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *
glEnd();
}
}
static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tface, int matnr))
{
ssDM_drawFacesTex_common(dm, setDrawParams, NULL, NULL);
}
static void ssDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData)
{
ssDM_drawFacesTex_common(dm, NULL, setDrawParams, userData);
}
static void ssDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
@ -1424,8 +1451,9 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)
ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid;
ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
ssdm->dm.drawMappedFacesTex = ssDM_drawMappedFacesTex;
ssdm->dm.drawFacesTex = ssDM_drawFacesTex;
ssdm->dm.drawMappedFaces = ssDM_drawMappedFaces;
ssdm->dm.drawMappedFacesTex = ssDM_drawMappedFacesTex;
/* EM functions */
@ -1484,7 +1512,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md)
return dm;
}
static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform)
static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform, int needMapping)
{
Mesh *me = ob->data;
ModifierData *md= modifiers_getVirtualModifierList(ob);
@ -1559,6 +1587,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
continue;
}
if (mti->isDisabled && mti->isDisabled(md)) continue;
if (needMapping && !modifier_supportsMapping(md)) continue;
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a DerivedMesh or just
@ -1849,20 +1878,26 @@ static void mesh_build_data(Object *ob)
clear_mesh_caches(ob);
if(ob!=G.obedit) {
if( (G.f & G_WEIGHTPAINT) && ob==(G.scene->basact?G.scene->basact->object:NULL)) {
Object *obact = G.scene->basact?G.scene->basact->object:NULL;
int editing = (G.f & (G_FACESELECT|G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT));
int needMapping = editing && (ob==obact);
if( (G.f & G_WEIGHTPAINT) && ob==obact ) {
MCol *mcol = me->mcol;
TFace *tface = me->tface;
me->tface = NULL;
me->mcol = (MCol*) calc_weightpaint_colors(ob);
mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1);
mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1,
needMapping);
MEM_freeN(me->mcol);
me->mcol = mcol;
me->tface = tface;
} else {
mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1);
mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1,
needMapping);
}
INIT_MINMAX(min, max);
@ -1938,7 +1973,7 @@ DerivedMesh *mesh_create_derived_render(Object *ob)
{
DerivedMesh *final;
mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1);
mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0);
return final;
}
@ -1947,7 +1982,7 @@ DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3])
{
DerivedMesh *final;
mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0);
mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0, 0);
return final;
}
@ -1956,7 +1991,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, float (*vertCos)[3
{
DerivedMesh *final;
mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0);
mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0);
return final;
}

View File

@ -1376,7 +1376,15 @@ static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned ch
ccgFaceIterator_free(fi);
}
static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData) {
static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tface, int matnr))
{
/* unimplemented, no textures in editmode anyway */
}
static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index), void *userData)
{
/* unfinished code, no textures in editmode anyway */
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
@ -1396,7 +1404,7 @@ static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void
TFace *tf = tface?&tface[index]:NULL;
unsigned char *cp= NULL;
int findex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
int flag = (findex == -1)? 0: setDrawParams(userData, findex, mf->mat_nr);
int flag = (findex == -1)? 0: setDrawParams(userData, findex);
if (flag==0) {
continue;
@ -1663,8 +1671,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int d
ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;

View File

@ -53,6 +53,7 @@ void face_select(void);
void face_borderselect(void);
void uv_autocalc_tface(void);
void set_faceselect(void);
void set_texturepaint(void);
void face_draw(void);
void get_same_uv(void);
void seam_mark_clear_tface(short mode);

View File

@ -619,7 +619,7 @@ static int draw_tfaces3D__setActiveOpts(void *userData, int index)
return 0;
}
}
static int draw_tfaces3D__drawFaceOpts(void *userData, int index, int matnr)
static int draw_tfaces3D__drawFaceOpts(void *userData, int index)
{
Mesh *me = (Mesh*)userData;
@ -844,11 +844,8 @@ static Object *g_draw_tface_mesh_ob = NULL;
static int g_draw_tface_mesh_islight = 0;
static int g_draw_tface_mesh_istex = 0;
static unsigned char g_draw_tface_mesh_obcol[4];
static int draw_tface_mesh__set_draw(void *userData, int index, int matnr)
static int draw_tface__set_draw(TFace *tface, int matnr)
{
Mesh *me = (Mesh*)userData;
TFace *tface = (me->tface)? &me->tface[index]: NULL;
if (tface && ((tface->flag&TF_HIDE) || (tface->mode&TF_INVISIBLE))) return 0;
if (set_draw_settings_cached(0, g_draw_tface_mesh_istex, tface, g_draw_tface_mesh_islight, g_draw_tface_mesh_ob, matnr, TF_TWOSIDE)) {
@ -866,6 +863,15 @@ static int draw_tface_mesh__set_draw(void *userData, int index, int matnr)
return 1; /* Set color from tface */
}
}
static int draw_tface_mapped__set_draw(void *userData, int index)
{
Mesh *me = (Mesh*)userData;
TFace *tface = (me->tface)? &me->tface[index]: NULL;
int matnr = me->mface[index].mat_nr;
draw_tface__set_draw(tface, matnr);
}
void draw_tface_mesh(Object *ob, Mesh *me, int dt)
/* maximum dt (drawtype): exactly according values that have been set */
{
@ -910,7 +916,10 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt)
int editing= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
int start, totface;
dm->drawMappedFacesTex(dm, draw_tface_mesh__set_draw, (void*)me);
if(ob==OBACT && (G.f & G_FACESELECT) && me && me->tface)
dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, (void*)me);
else
dm->drawFacesTex(dm, draw_tface__set_draw);
start = 0;
totface = me->totface;

View File

@ -1435,14 +1435,15 @@ void set_faceselect() /* toggle */
return;
}
if(me) /* make sure modifiers are updated for mapping requirements */
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
if(G.f & G_FACESELECT) {
G.f &= ~G_FACESELECT;
if((G.f & (G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT))==0) {
if(me) {
if(me)
reveal_tface();
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
setcursor_space(SPACE_VIEW3D, CURSOR_STD);
BIF_undo_push("End UV Faceselect");
}
@ -1463,6 +1464,34 @@ void set_faceselect() /* toggle */
allqueue(REDRAWIMAGE, 0);
}
void set_texturepaint() /* toggle */
{
Object *ob = OBACT;
Mesh *me = 0;
scrarea_queue_headredraw(curarea);
if(ob==NULL) return;
if(ob->id.lib) {
error("Can't edit library data");
return;
}
me= get_mesh(ob);
if(me && me->id.lib) {
error("Can't edit library data");
return;
}
if(me)
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
if(G.f & G_TEXTUREPAINT)
G.f &= ~G_TEXTUREPAINT;
else if (me)
G.f |= G_TEXTUREPAINT;
allqueue(REDRAWVIEW3D, 0);
}
/**
* Get the view ray through the screen point.

View File

@ -4016,18 +4016,18 @@ void do_view3d_buttons(short event)
if (G.vd->modeselect == V3D_OBJECTMODE_SEL) {
G.vd->flag &= ~V3D_MODE;
G.f &= ~G_VERTEXPAINT; /* Switch off vertex paint */
G.f &= ~G_TEXTUREPAINT; /* Switch off texture paint */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
G.f &= ~G_FACESELECT; /* Switch off face select */
if(G.f & G_FACESELECT) set_faceselect(); /* Switch off face select */
if(ob) exit_posemode(); /* exit posemode for active object */
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
}
else if (G.vd->modeselect == V3D_EDITMODE_SEL) {
if(!G.obedit) {
G.vd->flag &= ~V3D_MODE;
G.f &= ~G_VERTEXPAINT; /* Switch off vertex paint */
G.f &= ~G_TEXTUREPAINT; /* Switch off texture paint */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
enter_editmode();
@ -4038,13 +4038,13 @@ void do_view3d_buttons(short event)
if ((G.obedit) && (G.f & G_FACESELECT)) {
exit_editmode(2); /* exit editmode and undo */
} else if ((G.f & G_FACESELECT) && (G.f & G_VERTEXPAINT)) {
G.f &= ~G_VERTEXPAINT;
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
} else if ((G.f & G_FACESELECT) && (G.f & G_TEXTUREPAINT)) {
G.f &= ~G_TEXTUREPAINT;
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
} else {
G.vd->flag &= ~V3D_MODE;
G.f &= ~G_VERTEXPAINT; /* Switch off vertex paint */
G.f &= ~G_TEXTUREPAINT; /* Switch off texture paint */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
if (G.obedit) exit_editmode(2); /* exit editmode and undo */
@ -4054,7 +4054,7 @@ void do_view3d_buttons(short event)
else if (G.vd->modeselect == V3D_VERTEXPAINTMODE_SEL) {
if (!(G.f & G_VERTEXPAINT)) {
G.vd->flag &= ~V3D_MODE;
G.f &= ~G_TEXTUREPAINT; /* Switch off texture paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
@ -4064,18 +4064,18 @@ void do_view3d_buttons(short event)
else if (G.vd->modeselect == V3D_TEXTUREPAINTMODE_SEL) {
if (!(G.f & G_TEXTUREPAINT)) {
G.vd->flag &= ~V3D_MODE;
G.f &= ~G_VERTEXPAINT; /* Switch off vertex paint */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_WEIGHTPAINT) set_wpaint(); /* Switch off weight paint */
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
G.f |= G_TEXTUREPAINT; /* Switch on texture paint flag */
set_texturepaint();
}
}
else if (G.vd->modeselect == V3D_WEIGHTPAINTMODE_SEL) {
if (!(G.f & G_WEIGHTPAINT) && (ob && ob->type == OB_MESH) ) {
G.vd->flag &= ~V3D_MODE;
G.f &= ~G_VERTEXPAINT; /* Switch off vertex paint */
G.f &= ~G_TEXTUREPAINT; /* Switch off texture paint */
if(G.f & G_VERTEXPAINT) set_vpaint(); /* Switch off vertex paint */
if(G.f & G_TEXTUREPAINT) set_texturepaint(); /* Switch off tex paint */
if(G.obedit) exit_editmode(2); /* exit editmode and undo */
set_wpaint();

View File

@ -1669,14 +1669,15 @@ void set_vpaint(void) /* toggle */
allqueue(REDRAWVIEW3D, 1); /* including header */
allqueue(REDRAWBUTSEDIT, 0);
if (me)
/* update modifier stack for mapping requirements */
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
if(G.f & G_VERTEXPAINT) {
setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT);
}
else {
freefastshade(); /* to be sure */
if (me) {
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
if((G.f & G_FACESELECT)==0) setcursor_space(SPACE_VIEW3D, CURSOR_STD);
}
}