- added DerivedMesh.getVertCos function and implementations

- added mesh_create_derived_no_deform[_render]
 - mesh_create_orco now always goes through a DerivedMesh, some
   redundant copying atm but can be fixed (and orco generation is
   not a big bottleneck)

New feature: TexMesh (texcomesh) works with subsurf now (are
you listening rob?)
This commit is contained in:
2005-07-18 19:58:23 +00:00
parent 291af7418e
commit 1e3bd6d45e
7 changed files with 149 additions and 120 deletions

View File

@@ -75,6 +75,9 @@ struct DerivedMesh {
/* Get vertex location, undefined if index is not valid */
void (*getVertCo)(DerivedMesh *dm, int index, float co_r[3]);
/* Fill the array (of length .getNumVerts()) with all vertex locations */
void (*getVertCos)(DerivedMesh *dm, float (*cos_r)[3]);
/* Get vertex normal, undefined if index is not valid */
void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]);
@@ -152,6 +155,9 @@ 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);
DerivedMesh *mesh_create_derived_no_deform(struct Mesh *me, float (*vertCos)[3]);
DerivedMesh *mesh_create_derived_no_deform_render(struct Mesh *me, float (*vertCos)[3]);
/* IMPORTANT: The functions below do not return "true" DerivedMesh
* objects, rather they are just proxies for the mesh or editmesh
* objects and are used to keep the drawing code consistent. They

View File

@@ -37,7 +37,7 @@ struct DerivedMesh;
struct EditMesh;
struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, int subdivLevels, short type, struct DerivedMesh *oldDerived);
struct DerivedMesh *subsurf_make_derived_from_mesh(struct Object *ob, int subdivLevels, int useDeformVerts);
struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, int subdivLevels, struct Object *deformedVertsOb, float (*vertCos)[3]);
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]);

View File

@@ -65,6 +65,7 @@ typedef struct {
DerivedMesh dm;
Object *ob;
Mesh *me;
MVert *verts;
float *nors;
@@ -74,7 +75,7 @@ typedef struct {
static DispListMesh *meshDM_convertToDispListMesh(DerivedMesh *dm)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->ob->data;
Mesh *me = mdm->me;
DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
dlm->totvert = me->totvert;
@@ -94,7 +95,7 @@ static DispListMesh *meshDM_convertToDispListMesh(DerivedMesh *dm)
static void meshDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->ob->data;
Mesh *me = mdm->me;
int i;
if (me->totvert) {
@@ -106,6 +107,19 @@ static void meshDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
}
}
static void meshDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->me;
int i;
for (i=0; i<me->totvert; i++) {
cos_r[i][0] = mdm->verts[i].co[0];
cos_r[i][1] = mdm->verts[i].co[1];
cos_r[i][2] = mdm->verts[i].co[2];
}
}
static void meshDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
@@ -129,10 +143,10 @@ static void meshDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
static void meshDM_drawVerts(DerivedMesh *dm)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->ob->data;
Mesh *me = mdm->me;
int a, start=0, end=me->totvert;
set_buildvars(mdm->ob, &start, &end);
if (mdm->ob) set_buildvars(mdm->ob, &start, &end);
glBegin(GL_POINTS);
for(a= start; a<end; a++) {
@@ -143,11 +157,11 @@ static void meshDM_drawVerts(DerivedMesh *dm)
static void meshDM_drawEdges(DerivedMesh *dm)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me= mdm->ob->data;
Mesh *me= mdm->me;
int a, start= 0, end= me->totface;
MFace *mface = me->mface;
set_buildvars(mdm->ob, &start, &end);
if (mdm->ob) set_buildvars(mdm->ob, &start, &end);
mface+= start;
// edges can't cope with buildvars, draw with
@@ -205,11 +219,11 @@ static void meshDM_drawEdges(DerivedMesh *dm)
static void meshDM_drawLooseEdges(DerivedMesh *dm)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->ob->data;
Mesh *me = mdm->me;
MFace *mface= me->mface;
int a, start=0, end=me->totface;
set_buildvars(mdm->ob, &start, &end);
if (mdm->ob) set_buildvars(mdm->ob, &start, &end);
mface+= start;
glBegin(GL_LINES);
@@ -224,14 +238,14 @@ static void meshDM_drawLooseEdges(DerivedMesh *dm)
static void meshDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->ob->data;
Mesh *me = mdm->me;
MVert *mvert= mdm->verts;
MFace *mface= me->mface;
float *nors = mdm->nors;
int a, start=0, end=me->totface;
int glmode=-1, shademodel=-1, matnr=-1, drawCurrentMat=1;
set_buildvars(mdm->ob, &start, &end);
if (mdm->ob) set_buildvars(mdm->ob, &start, &end);
mface+= start;
#define PASSVERT(index, punoBit) { \
@@ -286,13 +300,12 @@ static void meshDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned char *col1, unsigned char *col2)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Object *ob= mdm->ob;
Mesh *me= ob->data;
Mesh *me= mdm->me;
MFace *mface= me->mface;
int a, glmode, start=0, end=me->totface;
unsigned char *cp1, *cp2;
set_buildvars(ob, &start, &end);
if (mdm->ob) set_buildvars(mdm->ob, &start, &end);
mface+= start;
col1+= 4*start;
if(col2) col2+= 4*start;
@@ -357,14 +370,14 @@ static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned ch
static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr))
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->ob->data;
Mesh *me = mdm->me;
MVert *mvert= mdm->verts;
MFace *mface= me->mface;
TFace *tface = me->tface;
float *nors = mdm->nors;
int a, start=0, end=me->totface;
set_buildvars(mdm->ob, &start, &end);
if (mdm->ob) set_buildvars(mdm->ob, &start, &end);
for (a=start; a<end; a++) {
MFace *mf= &mface[a];
@@ -414,14 +427,14 @@ static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
static int meshDM_getNumVerts(DerivedMesh *dm)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->ob->data;
Mesh *me = mdm->me;
return me->totvert;
}
static int meshDM_getNumFaces(DerivedMesh *dm)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->ob->data;
Mesh *me = mdm->me;
return me->totface;
}
@@ -431,14 +444,13 @@ static void meshDM_release(DerivedMesh *dm)
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
if (mdm->freeNors) MEM_freeN(mdm->nors);
if (mdm->verts!=((Mesh*) mdm->ob->data)->mvert) MEM_freeN(mdm->verts);
if (mdm->verts!=((Mesh*) mdm->me)->mvert) MEM_freeN(mdm->verts);
MEM_freeN(mdm);
}
static DerivedMesh *getMeshDerivedMesh(Object *ob, MVert *deformedVerts, float *nors)
static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, MVert *deformedVerts, float *nors, float (*vertCos)[3])
{
MeshDerivedMesh *mdm = MEM_callocN(sizeof(*mdm), "mdm");
Mesh *me = ob->data;
mdm->dm.getMinMax = meshDM_getMinMax;
@@ -446,6 +458,7 @@ static DerivedMesh *getMeshDerivedMesh(Object *ob, MVert *deformedVerts, float *
mdm->dm.getNumVerts = meshDM_getNumVerts;
mdm->dm.getNumFaces = meshDM_getNumFaces;
mdm->dm.getVertCos = meshDM_getVertCos;
mdm->dm.getVertCo = meshDM_getVertCo;
mdm->dm.getVertNo = meshDM_getVertNo;
@@ -462,9 +475,21 @@ static DerivedMesh *getMeshDerivedMesh(Object *ob, MVert *deformedVerts, float *
mdm->dm.release = meshDM_release;
mdm->ob = ob;
mdm->me = me;
mdm->nors = nors;
mdm->freeNors = 0;
if (vertCos) {
int i;
deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*me->totvert, "deformedVerts");
for (i=0; i<me->totvert; i++) {
deformedVerts[i].co[0] = vertCos[i][0];
deformedVerts[i].co[1] = vertCos[i][1];
deformedVerts[i].co[2] = vertCos[i][2];
}
}
if (deformedVerts) {
mdm->verts = deformedVerts;
mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
@@ -889,6 +914,18 @@ static void ssDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
}
}
static void ssDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
int i;
for (i=0; i<ssdm->dlm->totvert; i++) {
cos_r[i][0] = ssdm->dlm->mvert[i].co[0];
cos_r[i][1] = ssdm->dlm->mvert[i].co[1];
cos_r[i][2] = ssdm->dlm->mvert[i].co[2];
}
}
static int ssDM_getNumVerts(DerivedMesh *dm)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
@@ -928,6 +965,8 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm)
ssdm->dm.getNumFaces = ssDM_getNumFaces;
ssdm->dm.convertToDispListMesh = ssDM_convertToDispListMesh;
ssdm->dm.getVertCos = ssDM_getVertCos;
ssdm->dm.drawVerts = ssDM_drawVerts;
ssdm->dm.drawEdges = ssDM_drawEdges;
@@ -1014,7 +1053,7 @@ DerivedMesh *mesh_get_derived_deform(Object *ob, int *needsFree_r)
*needsFree_r = 1;
meDL = me->disp.first;
return getMeshDerivedMesh(ob, NULL, meDL?meDL->nors:NULL);
return getMeshDerivedMesh(ob->data, ob, NULL, meDL?meDL->nors:NULL, NULL);
}
}
@@ -1038,7 +1077,7 @@ DerivedMesh *mesh_get_derived_render(Object *ob, int *needsFree_r)
if(G.obedit && me==G.obedit->data) {
return subsurf_make_derived_from_editmesh(G.editMesh, me->subdivr, me->subsurftype, NULL);
} else {
return subsurf_make_derived_from_mesh(ob, me->subdivr, 1);
return subsurf_make_derived_from_mesh(ob->data, me->subdivr, ob, NULL);
}
} else {
return mesh_get_derived_deform(ob, needsFree_r);
@@ -1056,7 +1095,7 @@ DerivedMesh *mesh_get_base_derived(Object *ob)
} else {
DispList *meDL = me->disp.first;
return getMeshDerivedMesh(ob, NULL, meDL?meDL->nors:NULL);
return getMeshDerivedMesh(ob->data, ob, NULL, meDL?meDL->nors:NULL, NULL);
}
}
@@ -1082,5 +1121,23 @@ DerivedMesh *derivedmesh_from_mesh(Object *ob, MVert *deformedVerts)
{
Mesh *me = ob->data;
return getMeshDerivedMesh(ob, deformedVerts, NULL);
return getMeshDerivedMesh(ob->data, ob, deformedVerts, NULL, NULL);
}
DerivedMesh *mesh_create_derived_no_deform(Mesh *me, float (*vertCos)[3])
{
if ((me->flag&ME_SUBSURF) && me->subdiv) {
return subsurf_make_derived_from_mesh(me, me->subdiv, NULL, vertCos);
} else {
return getMeshDerivedMesh(me, NULL, NULL, NULL, vertCos);
}
}
DerivedMesh *mesh_create_derived_no_deform_render(Mesh *me, float (*vertCos)[3])
{
if ((me->flag&ME_SUBSURF) && me->subdivr) {
return subsurf_make_derived_from_mesh(me, me->subdivr, NULL, vertCos);
} else {
return getMeshDerivedMesh(me, NULL, NULL, NULL, vertCos);
}
}

View File

@@ -1447,7 +1447,7 @@ void makeDispListMesh(Object *ob)
if (ob==G.obedit) {
G.editMesh->derived= subsurf_make_derived_from_editmesh(G.editMesh, me->subdiv, me->subsurftype, G.editMesh->derived);
} else {
me->derived= subsurf_make_derived_from_mesh(ob, me->subdiv, 1);
me->derived= subsurf_make_derived_from_mesh(ob->data, me->subdiv, ob, NULL);
}
}

View File

@@ -428,112 +428,73 @@ void mesh_get_texspace(Mesh *me, float *loc_r, float *rot_r, float *size_r)
if (size_r) VECCOPY(size_r, me->size);
}
static float *make_orco_displist_mesh(Object *ob, int subdivlvl)
static float *make_orco_mesh_internal(Mesh *me, int render)
{
Mesh *me= ob->data;
DerivedMesh *dm;
DispListMesh *dlm;
float *orco, *fp, loc[3], size[3];
int i;
if (G.obedit && G.obedit->data==me) {
dm= subsurf_make_derived_from_editmesh(G.editMesh, subdivlvl, me->subsurftype, NULL);
dlm= dm->convertToDispListMesh(dm);
dm->release(dm);
} else {
/* if there's a key, set the first one */
if(me->key && me->texcomesh==0) {
cp_key(0, me->totvert, me->totvert, (char*) me->mvert->co, me->key, me->key->refkey, 0);
}
dm= subsurf_make_derived_from_mesh(ob, subdivlvl, 0);
dlm= dm->convertToDispListMesh(dm);
dm->release(dm);
/* Restore correct key */
do_ob_key(ob);
}
fp= orco= MEM_mallocN(dlm->totvert*3*sizeof(float), "mesh displist orco");
mesh_get_texspace(me, loc, NULL, size);
for(i=0; i<dlm->totvert; i++,fp+=3) {
fp[0]= (dlm->mvert[i].co[0] - loc[0])/size[0];
fp[1]= (dlm->mvert[i].co[1] - loc[1])/size[1];
fp[2]= (dlm->mvert[i].co[2] - loc[2])/size[2];
}
displistmesh_free(dlm);
return orco;
}
static float *make_orco_mesh(Mesh *me)
{
MVert *mvert;
KeyBlock *kb;
float *orcoData, *orco, *fp;
float (*orcoData)[3];
int a, totvert;
float loc[3], size[3];
DerivedMesh *dm;
float (*vcos)[3] = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
totvert= me->totvert;
orco= orcoData= MEM_mallocN(sizeof(float)*3*totvert, "orco mesh");
/* Get appropriate vertex coordinates */
mesh_get_texspace(me, loc, NULL, size);
if(me->key && me->texcomesh==0) {
kb= me->key->refkey;
if (kb) { /***** BUG *****/
fp= kb->data;
if(me->key && me->texcomesh==0 && me->key->refkey) {
KeyBlock *kb= me->key->refkey;
float *fp= kb->data;
totvert= MIN2(kb->totelem, me->totvert);
for(a=0; a<totvert; a++, orco+=3) {
orco[0]= (fp[0]-loc[0])/size[0];
orco[1]= (fp[1]-loc[1])/size[1];
orco[2]= (fp[2]-loc[2])/size[2];
/* only increase mvert when totvert <= kb->totelem */
if(a<kb->totelem) fp+=3;
}
for(a=0; a<totvert; a++, fp+=3) {
vcos[a][0]= fp[0];
vcos[a][1]= fp[1];
vcos[a][2]= fp[2];
}
}
else {
if(me->texcomesh) {
me= me->texcomesh;
}
Mesh *tme = me->texcomesh?me->texcomesh:me;
MVert *mvert = tme->mvert;
totvert = MIN2(tme->totvert, me->totvert);
mvert= me->mvert;
for(a=0; a<totvert; a++, orco+=3) {
orco[0]= (mvert->co[0]-loc[0])/size[0];
orco[1]= (mvert->co[1]-loc[1])/size[1];
orco[2]= (mvert->co[2]-loc[2])/size[2];
/* only increase mvert when totvert <= me->totvert */
if(a<me->totvert) mvert++;
for(a=0; a<totvert; a++, mvert++) {
vcos[a][0]= mvert->co[0];
vcos[a][1]= mvert->co[1];
vcos[a][2]= mvert->co[2];
}
}
return orcoData;
/* Apply orco-changing modifiers */
if (render) {
dm = mesh_create_derived_no_deform_render(me, vcos);
} else {
dm = mesh_create_derived_no_deform(me, vcos);
}
totvert = dm->getNumVerts(dm);
orcoData = MEM_mallocN(sizeof(*orcoData)*totvert, "orcoData");
dm->getVertCos(dm, orcoData);
dm->release(dm);
MEM_freeN(vcos);
mesh_get_texspace(me, loc, NULL, size);
for(a=0; a<totvert; a++) {
float *co = orcoData[a];
co[0] = (co[0]-loc[0])/size[0];
co[1] = (co[1]-loc[1])/size[1];
co[2] = (co[2]-loc[2])/size[2];
}
return (float*) orcoData;
}
float *mesh_create_orco_render(Object *ob)
{
Mesh *me = ob->data;
if ((me->flag&ME_SUBSURF) && me->subdivr) {
return make_orco_displist_mesh(ob, me->subdivr);
} else {
return make_orco_mesh(me);
}
return make_orco_mesh_internal(ob->data, 1);
}
float *mesh_create_orco(Object *ob)
{
Mesh *me = ob->data;
if ((me->flag&ME_SUBSURF) && me->subdiv) {
return make_orco_displist_mesh(ob, me->subdiv);
} else {
return make_orco_mesh(me);
}
return make_orco_mesh_internal(ob->data, 0);
}
/** rotates the vertices of a face in case v[2] or v[3] (vertex index)

View File

@@ -73,6 +73,7 @@ typedef struct _SubSurf {
Mesh *me;
Object *deformOb;
float (*vertCos)[3];
} SubSurf;
typedef struct _VertData {
@@ -144,7 +145,7 @@ static SubSurf *subSurf_fromEditmesh(EditMesh *em, int subdivLevels, int useAgin
return ss;
}
static SubSurf *subSurf_fromMesh(Mesh *me, int useFlatSubdiv, int subdivLevels, Object *deformOb) {
static SubSurf *subSurf_fromMesh(Mesh *me, int useFlatSubdiv, int subdivLevels, Object *deformOb, float (*vertCos)[3]) {
SubSurf *ss = MEM_mallocN(sizeof(*ss), "ss_m");
ss->controlType = SUBSURF_CONTROLTYPE_MESH;
@@ -152,6 +153,7 @@ static SubSurf *subSurf_fromMesh(Mesh *me, int useFlatSubdiv, int subdivLevels,
ss->subSurf = _getSubSurf(ss, subdivLevels, 1);
ss->me = me;
ss->deformOb = deformOb;
ss->vertCos = vertCos;
ccgSubSurf_setAllowEdgeCreation(ss->subSurf, 1, useFlatSubdiv?subdivLevels:0.0f);
@@ -515,6 +517,10 @@ static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) {
}
displistmesh_free(dlm);
} else if (ss->vertCos) {
for (i=0; i<ss->me->totvert; i++) {
ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, ss->vertCos[i]);
}
} else {
for (i=0; i<ss->me->totvert; i++) {
ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, ss->me->mvert[i].co);
@@ -1017,10 +1023,9 @@ DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, int subdivLevels,
return (DerivedMesh*) ccgdm;
}
DerivedMesh *subsurf_make_derived_from_mesh(Object *ob, int subdivLevels, int useDeformVerts) {
Mesh *me = ob->data;
DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, int subdivLevels, Object *deformedVertsOb, float (*vertCos)[3]) {
int useFlatSubdiv = me->subsurftype==ME_SIMPLE_SUBSURF;
SubSurf *ss = subSurf_fromMesh(me, useFlatSubdiv, subdivLevels, useDeformVerts?ob:NULL);
SubSurf *ss = subSurf_fromMesh(me, useFlatSubdiv, subdivLevels, deformedVertsOb, vertCos);
DispListMesh *dlm;
subSurf_sync(ss, useFlatSubdiv);
@@ -1039,7 +1044,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
* calculated vert positions is incorrect for the verts
* on the boundary of the mesh.
*/
SubSurf *ss = subSurf_fromMesh(me, 0, 1, NULL);
SubSurf *ss = subSurf_fromMesh(me, 0, 1, NULL, NULL);
float edge_sum[3], face_sum[3];
CCGVertIterator *vi;

View File

@@ -2211,7 +2211,7 @@ void convertmenu(void)
for(a=0; a<ob1->totcol; a++) id_us_plus((ID *)me->mat[a]);
}
dm= subsurf_make_derived_from_mesh(ob, oldme->subdiv, 0);
dm= subsurf_make_derived_from_mesh(ob->data, oldme->subdiv, NULL, NULL);
dlm= dm->convertToDispListMesh(dm);
dm->release(dm);