- added DirectMesh.getVert{Co,No} functions

- added mesh_get_derived_deform function (always returns a DerivedMesh
   corresponding to deformed (but not subdivided) mesh). used in places
   where original mesh is to be displayed but with deformed coordinates
   (vpaint for example).
 - added DirectMesh.getVert{Co,No} implementations for MeshDerivedMesh
 - updated vpaint to use mesh_get_derived_deform
This commit is contained in:
Daniel Dunbar 2005-07-17 01:18:59 +00:00
parent 7c9422111b
commit 67d58c0f45
4 changed files with 122 additions and 115 deletions

View File

@ -64,6 +64,17 @@ struct DerivedMesh {
/* Convert to new DispListMesh, should be free'd by caller */
struct DispListMesh* (*convertToDispListMesh)(DerivedMesh *dm);
/* Direct Access Operations */
/* o Can be undefined */
/* o Must be defined for modifiers that only deform however */
/* Get vertex location, undefined if index is not valid */
void (*getVertCo)(DerivedMesh *dm, int index, float co_r[3]);
/* Get vertex normal, undefined if index is not valid */
void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
/* Drawing Operations */
/* Draw all vertices as bgl points (no options) */
@ -135,6 +146,7 @@ DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm);
DerivedMesh *mesh_get_derived(struct Object *ob);
DerivedMesh *mesh_get_derived_final(struct Object *ob, int *needsFree_r);
DerivedMesh *mesh_get_derived_render(struct Object *ob, int *needsFree_r);
DerivedMesh *mesh_get_derived_deform(struct Object *ob, int *needsFree_r);
/* IMPORTANT: The functions below do not return "true" DerivedMesh
* objects, rather they are just proxies for the mesh or editmesh

View File

@ -103,7 +103,7 @@ static DispListMesh *meshDM_convertToDispListMesh(DerivedMesh *dm)
return dlm;
}
static float *meshDM__getVertCo(MeshDerivedMesh *mdm, int index)
static float *meshDM__getVertCoP(MeshDerivedMesh *mdm, int index)
{
if (mdm->extverts) {
return mdm->extverts+3*index;
@ -112,6 +112,25 @@ static float *meshDM__getVertCo(MeshDerivedMesh *mdm, int index)
}
}
static void meshDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
{
float *co = meshDM__getVertCoP((MeshDerivedMesh*) dm, index);
co_r[0] = co[0];
co_r[1] = co[1];
co_r[2] = co[2];
}
static void meshDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
short *no = ((Mesh*) mdm->ob->data)->mvert[index].no;
no_r[0] = no[0]/32767.f;
no_r[1] = no[1]/32767.f;
no_r[2] = no[2]/32767.f;
}
static void meshDM_drawVerts(DerivedMesh *dm)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
@ -122,7 +141,7 @@ static void meshDM_drawVerts(DerivedMesh *dm)
glBegin(GL_POINTS);
for(a= start; a<end; a++) {
glVertex3fv(meshDM__getVertCo(mdm, a));
glVertex3fv(meshDM__getVertCoP(mdm, a));
}
glEnd();
}
@ -144,8 +163,8 @@ static void meshDM_drawEdges(DerivedMesh *dm)
glBegin(GL_LINES);
for(a=me->totedge; a>0; a--, medge++) {
if(medge->flag & ME_EDGEDRAW) {
glVertex3fv(meshDM__getVertCo(mdm, medge->v1));
glVertex3fv(meshDM__getVertCo(mdm, medge->v2));
glVertex3fv(meshDM__getVertCoP(mdm, medge->v1));
glVertex3fv(meshDM__getVertCoP(mdm, medge->v2));
}
}
glEnd();
@ -157,29 +176,29 @@ static void meshDM_drawEdges(DerivedMesh *dm)
if(test) {
if(test&ME_V1V2){
glVertex3fv(meshDM__getVertCo(mdm, mface->v1));
glVertex3fv(meshDM__getVertCo(mdm, mface->v2));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v1));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v2));
}
if(mface->v3) {
if(test&ME_V2V3){
glVertex3fv(meshDM__getVertCo(mdm, mface->v2));
glVertex3fv(meshDM__getVertCo(mdm, mface->v3));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v2));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v3));
}
if (mface->v4) {
if(test&ME_V3V4){
glVertex3fv(meshDM__getVertCo(mdm, mface->v3));
glVertex3fv(meshDM__getVertCo(mdm, mface->v4));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v3));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v4));
}
if(test&ME_V4V1){
glVertex3fv(meshDM__getVertCo(mdm, mface->v4));
glVertex3fv(meshDM__getVertCo(mdm, mface->v1));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v4));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v1));
}
} else {
if(test&ME_V3V1){
glVertex3fv(meshDM__getVertCo(mdm, mface->v3));
glVertex3fv(meshDM__getVertCo(mdm, mface->v1));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v3));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v1));
}
}
}
@ -201,8 +220,8 @@ static void meshDM_drawLooseEdges(DerivedMesh *dm)
glBegin(GL_LINES);
for(a=start; a<end; a++, mface++) {
if(!mface->v3) {
glVertex3fv(meshDM__getVertCo(mdm, mface->v3));
glVertex3fv(meshDM__getVertCo(mdm, mface->v4));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v3));
glVertex3fv(meshDM__getVertCoP(mdm, mface->v4));
}
}
glEnd();
@ -229,7 +248,7 @@ static void meshDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
glNormal3sv(no); \
} \
} \
glVertex3fv(meshDM__getVertCo(mdm,index)); \
glVertex3fv(meshDM__getVertCoP(mdm,index)); \
}
glBegin(glmode=GL_QUADS);
@ -309,26 +328,26 @@ static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned ch
}
glColor3ub(cp1[3], cp1[2], cp1[1]);
glVertex3fv( meshDM__getVertCo(mdm,mface->v1) );
glVertex3fv( meshDM__getVertCoP(mdm,mface->v1) );
glColor3ub(cp1[7], cp1[6], cp1[5]);
glVertex3fv( meshDM__getVertCo(mdm,mface->v2) );
glVertex3fv( meshDM__getVertCoP(mdm,mface->v2) );
glColor3ub(cp1[11], cp1[10], cp1[9]);
glVertex3fv( meshDM__getVertCo(mdm,mface->v3) );
glVertex3fv( meshDM__getVertCoP(mdm,mface->v3) );
if(mface->v4) {
glColor3ub(cp1[15], cp1[14], cp1[13]);
glVertex3fv( meshDM__getVertCo(mdm,mface->v4) );
glVertex3fv( meshDM__getVertCoP(mdm,mface->v4) );
}
if(useTwoSide) {
glColor3ub(cp2[11], cp2[10], cp2[9]);
glVertex3fv( meshDM__getVertCo(mdm,mface->v3) );
glVertex3fv( meshDM__getVertCoP(mdm,mface->v3) );
glColor3ub(cp2[7], cp2[6], cp2[5]);
glVertex3fv( meshDM__getVertCo(mdm,mface->v2) );
glVertex3fv( meshDM__getVertCoP(mdm,mface->v2) );
glColor3ub(cp2[3], cp2[2], cp2[1]);
glVertex3fv( meshDM__getVertCo(mdm,mface->v1) );
glVertex3fv( meshDM__getVertCoP(mdm,mface->v1) );
if(mface->v4) {
glColor3ub(cp2[15], cp2[14], cp2[13]);
glVertex3fv( meshDM__getVertCo(mdm,mface->v4) );
glVertex3fv( meshDM__getVertCoP(mdm,mface->v4) );
}
}
}
@ -376,23 +395,23 @@ static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
if (tf) glTexCoord2fv(tf->uv[0]);
if (cp) glColor3ub(cp[3], cp[2], cp[1]);
if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
glVertex3fv(meshDM__getVertCo(mdm, mf->v1));
glVertex3fv(meshDM__getVertCoP(mdm, mf->v1));
if (tf) glTexCoord2fv(tf->uv[1]);
if (cp) glColor3ub(cp[7], cp[6], cp[5]);
if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
glVertex3fv(meshDM__getVertCo(mdm, mf->v2));
glVertex3fv(meshDM__getVertCoP(mdm, mf->v2));
if (tf) glTexCoord2fv(tf->uv[2]);
if (cp) glColor3ub(cp[11], cp[10], cp[9]);
if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
glVertex3fv(meshDM__getVertCo(mdm, mf->v3));
glVertex3fv(meshDM__getVertCoP(mdm, mf->v3));
if(mf->v4) {
if (tf) glTexCoord2fv(tf->uv[3]);
if (cp) glColor3ub(cp[15], cp[14], cp[13]);
if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
glVertex3fv(meshDM__getVertCo(mdm, mf->v4));
glVertex3fv(meshDM__getVertCoP(mdm, mf->v4));
}
glEnd();
}
@ -420,6 +439,9 @@ static DerivedMesh *getMeshDerivedMesh(Object *ob, float *extverts, float *nors)
mdm->dm.getNumVerts = meshDM_getNumVerts;
mdm->dm.getNumFaces = meshDM_getNumFaces;
mdm->dm.getVertCo = meshDM_getVertCo;
mdm->dm.getVertNo = meshDM_getVertNo;
mdm->dm.drawVerts = meshDM_drawVerts;
mdm->dm.drawEdges = meshDM_drawEdges;
@ -940,13 +962,28 @@ DerivedMesh *mesh_get_derived_final(Object *ob, int *needsFree_r)
return NULL;
}
DerivedMesh *mesh_get_derived_render(Object *ob, int *needsFree)
DerivedMesh *mesh_get_derived_deform(Object *ob, int *needsFree_r)
{
Mesh *me = ob->data;
DispList *dl;
DispList *meDL;
build_mesh_data(ob, G.obedit && me==G.obedit->data);
*needsFree_r = 1;
dl = find_displist(&ob->disp, DL_VERTS);
meDL = me->disp.first;
return getMeshDerivedMesh(ob, dl?dl->verts:NULL, meDL?meDL->nors:NULL);
}
DerivedMesh *mesh_get_derived_render(Object *ob, int *needsFree_r)
{
Mesh *me= ob->data;
if ((me->flag&ME_SUBSURF) && me->subdivr) {
if (me->subdiv==me->subdivr) {
*needsFree = 0;
*needsFree_r = 0;
// Don't reuse cache in editmode, we need to guarantee
// index order of result and the incremental syncing messes
@ -956,7 +993,7 @@ DerivedMesh *mesh_get_derived_render(Object *ob, int *needsFree)
}
}
*needsFree = 1;
*needsFree_r = 1;
if(G.obedit && me==G.obedit->data) {
return subsurf_make_derived_from_editmesh(G.editMesh, me->subdivr, me->subsurftype, NULL);
} else {
@ -966,7 +1003,7 @@ DerivedMesh *mesh_get_derived_render(Object *ob, int *needsFree)
DispList *dl;
DispList *meDL;
*needsFree = 1;
*needsFree_r = 1;
dl = find_displist(&ob->disp, DL_VERTS);
meDL = me->disp.first;
return getMeshDerivedMesh(ob, dl?dl->verts:NULL, meDL?meDL->nors:NULL);
@ -990,18 +1027,18 @@ DerivedMesh *mesh_get_base_derived(Object *ob)
}
}
DerivedMesh *mesh_get_cage_derived(struct Object *ob, int *needsFree)
DerivedMesh *mesh_get_cage_derived(struct Object *ob, int *needsFree_r)
{
Mesh *me= ob->data;
DerivedMesh *dm = NULL;
*needsFree = 0;
*needsFree_r = 0;
if (me->flag&ME_OPT_EDGES) {
dm = mesh_get_derived(ob);
}
if (!dm) {
*needsFree = 1;
*needsFree_r = 1;
dm = mesh_get_base_derived(ob);
}

View File

@ -1783,14 +1783,10 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *realDM
int hasHaloMat = (ma && (ma->mode&MA_HALO));
int draw_wire = ob->dtx&OB_DRAWWIRE;
DispList *dl;
float *obExtVerts;
DerivedMesh *dm = realDM?realDM:baseDM;
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
dl = find_displist(&ob->disp, DL_VERTS);
obExtVerts = dl?dl->verts:NULL;
// Unwanted combination.
if (G.f&G_FACESELECT) draw_wire = 0;

View File

@ -60,6 +60,7 @@
#include "DNA_view3d_types.h"
#include "DNA_userdef_types.h"
#include "BKE_DerivedMesh.h"
#include "BKE_depsgraph.h"
#include "BKE_displist.h"
#include "BKE_global.h"
@ -273,7 +274,7 @@ void make_vertexcol() /* single ob */
if(me->tface) mcol_to_tface(me, 1);
}
freedisplist(&(ob->disp));
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWVIEW3D, 0);
@ -662,14 +663,17 @@ static unsigned int sample_backbuf(int x, int y)
return framebuffer_to_index(col);
}
static int calc_vp_alpha(MVert *mvert, short *mval)
static int calc_vp_alpha_dl(DerivedMesh *dm, int vert, short *mval)
{
float fac, dx, dy, nor[3];
float co[3], no[3];
float fac, dx, dy;
int alpha;
short vertco[2];
if(Gvp.flag & VP_SOFT) {
project_short_noclip(mvert->co , vertco);
dm->getVertCo(dm, vert, co);
project_short_noclip(co, vertco);
dx= mval[0]-vertco[0];
dy= mval[1]-vertco[1];
@ -681,14 +685,15 @@ static int calc_vp_alpha(MVert *mvert, short *mval)
else {
alpha= 255.0*Gvp.a;
}
if(Gvp.flag & VP_NORMALS) {
VECCOPY(nor, mvert->no);
/* transpose ! */
fac= vpimat[2][0]*nor[0]+vpimat[2][1]*nor[1]+vpimat[2][2]*nor[2];
dm->getVertNo(dm, vert, no);
/* transpose ! */
fac= vpimat[2][0]*no[0]+vpimat[2][1]*no[1]+vpimat[2][2]*no[2];
if(fac>0.0) {
dx= vpimat[0][0]*nor[0]+vpimat[0][1]*nor[1]+vpimat[0][2]*nor[2];
dy= vpimat[1][0]*nor[0]+vpimat[1][1]*nor[1]+vpimat[1][2]*nor[2];
dx= vpimat[0][0]*no[0]+vpimat[0][1]*no[1]+vpimat[0][2]*no[2];
dy= vpimat[1][0]*no[0]+vpimat[1][1]*no[1]+vpimat[1][2]*no[2];
alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac);
}
@ -696,53 +701,6 @@ static int calc_vp_alpha(MVert *mvert, short *mval)
}
return alpha;
}
static int calc_vp_alpha_dl(DispList *disp, MVert *mvert, int vert, short *mval)
/* Lets us do soft vertex painting onto a deformed mesh */
{
float fac, dx, dy, nor[3];
int alpha;
short vertco[2];
/* For safety's sake !*/
if (!disp || !disp->verts)
return calc_vp_alpha (mvert+vert, mval);
// use display list
if(Gvp.flag & VP_SOFT) {
project_short_noclip(disp->verts+(vert*3), vertco);
dx= mval[0]-vertco[0];
dy= mval[1]-vertco[1];
fac= sqrt(dx*dx + dy*dy);
if(fac > Gvp.size) return 0;
alpha= 255.0*Gvp.a*(1.0-fac/Gvp.size);
}
else {
alpha= 255.0*Gvp.a;
}
if(Gvp.flag & VP_NORMALS) {
if(disp->nors) {
VECCOPY(nor, disp->nors+(vert*3));
// transpose !
fac= vpimat[2][0]*nor[0]+vpimat[2][1]*nor[1]+vpimat[2][2]*nor[2];
if(fac>0.0) {
dx= vpimat[0][0]*nor[0]+vpimat[0][1]*nor[1]+vpimat[0][2]*nor[2];
dy= vpimat[1][0]*nor[0]+vpimat[1][1]*nor[1]+vpimat[1][2]*nor[2];
alpha*= fac/sqrt(dx*dx + dy*dy + fac*fac);
}
else return 0;
}
}
return alpha;
}
@ -792,7 +750,6 @@ void weight_paint(void)
short mval[2], mvalo[2], firsttime=1, mousebut;
MDeformWeight *dw, *uw;
extern float editbutvweight;
DispList *dl;
if((G.f & G_WEIGHTPAINT)==0) return;
if(G.obedit) return;
@ -838,7 +795,9 @@ void weight_paint(void)
getmouseco_areawin(mval);
if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
DerivedMesh *dm;
int needsFree;
firsttime= 0;
/* which faces are involved */
@ -879,33 +838,32 @@ void weight_paint(void)
}
}
dl= find_displist(&ob->disp, DL_VERTS);
dm = mesh_get_derived_deform(ob, &needsFree);
for(index=0; index<totindex; index++) {
if(indexar[index] && indexar[index]<=me->totface) {
mface= ((MFace *)me->mface) + (indexar[index]-1);
mface= me->mface + (indexar[index]-1);
if (calc_vp_alpha_dl(dl, me->mvert, mface->v1, mval)){
if (calc_vp_alpha_dl(dm, mface->v1, mval)){
dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1);
uw= verify_defweight(wpaintundobuf+mface->v1, ob->actdef-1);
if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a));
}
if (calc_vp_alpha_dl(dl, me->mvert, mface->v2, mval)){
if (calc_vp_alpha_dl(dm, mface->v2, mval)){
dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1);
uw= verify_defweight(wpaintundobuf+mface->v2, ob->actdef-1);
if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a));
}
if (calc_vp_alpha_dl(dl, me->mvert, mface->v3, mval)){
if (calc_vp_alpha_dl(dm, mface->v3, mval)){
dw= verify_defweight(me->dvert+mface->v3, ob->actdef-1);
uw= verify_defweight(wpaintundobuf+mface->v3, ob->actdef-1);
if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a));
}
if(mface->v4) {
if (calc_vp_alpha_dl(dl, me->mvert, mface->v4, mval)){
if (calc_vp_alpha_dl(dm, mface->v4, mval)){
dw= verify_defweight(me->dvert+mface->v4, ob->actdef-1);
uw= verify_defweight(wpaintundobuf+mface->v4, ob->actdef-1);
if (dw) dw->weight = editbutvweight*Gvp.a + (uw->weight*(1.0-Gvp.a));
@ -913,6 +871,8 @@ void weight_paint(void)
}
}
}
if (needsFree)
dm->release(dm);
MTC_Mat4SwapMat4(G.vd->persmat, mat);
@ -955,7 +915,6 @@ void vertex_paint()
Mesh *me;
MFace *mface;
TFace *tface;
DispList *dl;
float mat[4][4], imat[4][4];
unsigned int paintcol=0, *mcol, fcol1, fcol2;
int index, alpha, totindex, total;
@ -1006,7 +965,9 @@ void vertex_paint()
getmouseco_areawin(mval);
if(firsttime || mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
DerivedMesh *dm;
int needsFree;
firsttime= 0;
/* which faces are involved */
@ -1046,8 +1007,7 @@ void vertex_paint()
}
}
dl= find_displist(&ob->disp, DL_VERTS);
dm= mesh_get_derived_deform(ob, &needsFree);
for(index=0; index<totindex; index++) {
if(indexar[index] && indexar[index]<=me->totface) {
@ -1069,17 +1029,17 @@ void vertex_paint()
total= 0;
total+= alpha= calc_vp_alpha_dl(dl, me->mvert, mface->v1, mval);
total+= alpha= calc_vp_alpha_dl(dm, mface->v1, mval);
if(alpha) vpaint_blend( mcol, paintcol, alpha);
total+= alpha= calc_vp_alpha_dl(dl, me->mvert, mface->v2, mval);
total+= alpha= calc_vp_alpha_dl(dm, mface->v2, mval);
if(alpha) vpaint_blend( mcol+1, paintcol, alpha);
total+= alpha= calc_vp_alpha_dl(dl, me->mvert, mface->v3, mval);
total+= alpha= calc_vp_alpha_dl(dm, mface->v3, mval);
if(alpha) vpaint_blend( mcol+2, paintcol, alpha);
if(mface->v4) {
total+= alpha= calc_vp_alpha_dl(dl, me->mvert, mface->v4, mval);
total+= alpha= calc_vp_alpha_dl(dm, mface->v4, mval);
if(alpha) vpaint_blend( mcol+3, paintcol, alpha);
}
@ -1092,7 +1052,9 @@ void vertex_paint()
/* } */
}
}
if (needsFree)
dm->release(dm);
MTC_Mat4SwapMat4(G.vd->persmat, mat);
do_shared_vertexcol(me);