- convert all DerivedMesh map functions to use index based

mapping (instead of Edit{Vert,Edge,Face} pointers)
 - dropped convertToDispListMeshMapped (whew, glad of it too)
 - added DerivedMesh drawMappedFaces function
 - dropped EM suffix for DerivedMesh functions, it was neither
   particularly correct nor descriptive
 - converted test_index_mface to test_index_face that also corrects
   MCol and TFace. Good thing we had three versions of this routine,
   you never know when one might burn down.
 - removed flipnorm_mesh, not used anymore (and was incorrect to
   boot)

 - Getting face select to work with modifiers turned out to be much
   more complicated than expected. Reworked mapping architecture for
   modifiers - basically elements in a DispListMesh are now required
   to be stored in an order that corresponds exactly to original
   ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
   that is set on each element that is set on the first derived element
   of each original element. I can't say the code to follow these
   requirements for subsurf is particularly transparent, but on the
   upside it is a reasonably consistent and simple system that is memory
   efficient and allows keeping the DispListMesh structure.

 - rewrote mirror modifier to be simpler/conform to new requirements
   for mapped DispListMesh structure. This also means that mirror interacts
   much better with incremental subsurf calculation (it used to recalc
   one entire side on any topology change, now it generally avoids that).

 - added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
   functions to handle mapping indices back into appropriate EditMesh
   structures.
 - bug fix, make edges didn't recalc object data
 - bug fix, initial image assignment to TFace's didn't recalc object data

 - new feature, added circle select support for FACESELECT
 - bug fix, creating new faces in editmode duplicated the TFACE active
   flag - but there should only be one active tface
 - bug fix, possible crash when deleting all faces in faceselect mode
   on mesh with tfaces...

Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
This commit is contained in:
Daniel Dunbar 2005-08-20 03:08:23 +00:00
parent d81a5abf32
commit a30740c196
25 changed files with 1159 additions and 1166 deletions

View File

@ -48,9 +48,6 @@
struct MVert;
struct Object;
struct EditMesh;
struct EditVert;
struct EditEdge;
struct EditFace;
struct DispListMesh;
struct ModifierData;
@ -68,19 +65,19 @@ struct DerivedMesh {
* coordinate and normal. For historical reasons the normal can be
* passed as a float or short array, only one should be non-NULL.
*/
void (*foreachMappedVertEM)(DerivedMesh *dm, void (*func)(void *userData, struct EditVert *vert, float *co, float *no_f, short *no_s), void *userData);
void (*foreachMappedVert)(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData);
/* Iterate over each mapped vertex in the derived mesh, calling the
* given function with the original vert and the mapped edge's new
* coordinates.
*/
void (*foreachMappedEdgeEM)(DerivedMesh *dm, void (*func)(void *userData, struct EditEdge *edge, float *v0co, float *v1co), void *userData);
void (*foreachMappedEdge)(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData);
/* Iterate over each mapped face in the derived mesh, calling the
* given function with the original face and the mapped face's (or
* faces') center and normal.
*/
void (*foreachMappedFaceCenterEM)(DerivedMesh *dm, void (*func)(void *userData, struct EditFace *face, float *cent, float *no), void *userData);
void (*foreachMappedFaceCenter)(DerivedMesh *dm, void (*func)(void *userData, int index, float *cent, float *no), void *userData);
/* Convert to new DispListMesh, should be free'd by caller.
*
@ -91,18 +88,6 @@ struct DerivedMesh {
*/
struct DispListMesh* (*convertToDispListMesh)(DerivedMesh *dm, int allowShared);
/* Convert to new DispListMesh, should be free'd by caller.
*
* Additionally, allocate and return map arrays. Each map array should be
* have a length corresponding to the returned DLMs totvert, totedge, and
* totface fields respectively.
*
* Each index in the array should give the EditMesh element from which the
* element at the same index in the DLMs vert, edge, or face array was
* derived (which may be null).
*/
struct DispListMesh* (*convertToDispListMeshMapped)(DerivedMesh *dm, int allowShared, struct EditVert ***vertMap_r, struct EditEdge ***edgeMap_r, struct EditFace ***faceMap_r);
/* Iterate over all vertex points, calling DO_MINMAX with given args.
*
* Also called in Editmode
@ -158,33 +143,40 @@ struct DerivedMesh {
/* Draw all faces uses TFace
* o Drawing options too complicated to enumerate, look at code.
*/
void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr));
void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(TFace *tf, int matnr));
/* Draw mapped faces (no color, or texture)
* o Only if !setDrawOptions or setDrawOptions(userData, mapped-face-index, drawSmooth_r) returns true
*
* If drawSmooth is set to true then vertex normals should be set and glShadeModel
* called with GL_SMOOTH. Otherwise the face normal should be set and glShadeModel
* called with GL_FLAT.
*
* The setDrawOptions is allowed to not set drawSmooth (for example, when lighting
* is disabled), in which case the implementation should draw as smooth shaded.
*/
void (*drawMappedFaces)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData);
/* Draw mapped edges as lines
* o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge) returns true
*/
void (*drawMappedEdgesEM)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditEdge *eed), void *userData);
void (*drawMappedEdges)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData);
/* Draw mapped edges as lines with interpolation values
* o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge, mapped-v0, mapped-v1, t) returns true
*
* NOTE: This routine is optional!
*/
void (*drawMappedEdgesInterpEM)(DerivedMesh *dm,
int (*setDrawOptions)(void *userData, struct EditEdge *eed),
void (*setDrawInterpOptions)(void *userData, struct EditEdge *eed, float t),
void (*drawMappedEdgesInterp)(DerivedMesh *dm,
int (*setDrawOptions)(void *userData, int index),
void (*setDrawInterpOptions)(void *userData, int index, float t),
void *userData);
/* Draw all faces
* o Only if !setDrawOptions or setDrawOptions(userData, mapped-face) returns true
*/
void (*drawMappedFacesEM)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData);
void (*release)(DerivedMesh *dm);
};
/* Internal function, just temporarily exposed */
DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm, float (*vertexCos)[3], struct EditVert **vertMap, struct EditEdge **edgeMap, struct EditFace **faceMap);
DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm, float (*vertexCos)[3]);
DerivedMesh *mesh_get_derived_final(struct Object *ob, int *needsFree_r);
DerivedMesh *mesh_get_derived_deform(struct Object *ob, int *needsFree_r);

View File

@ -43,6 +43,7 @@ struct MDeformVert;
struct Mesh;
struct MFace;
struct MVert;
struct MCol;
struct Object;
struct TFace;
struct VecNor;
@ -61,9 +62,7 @@ void boundbox_mesh(struct Mesh *me, float *loc, float *size);
void tex_space_mesh(struct Mesh *me);
float *mesh_create_orco_render(struct Object *ob);
float *mesh_create_orco(struct Object *ob);
void test_index_mface(struct MFace *mface, int nr);
void test_index_face(struct MFace *mface, struct TFace *tface, int nr);
void flipnorm_mesh(struct Mesh *me);
void test_index_face(struct MFace *mface, struct MCol *mc, struct TFace *tface, int nr);
struct Mesh *get_mesh(struct Object *ob);
void set_mesh(struct Object *ob, struct Mesh *me);
void mball_to_mesh(struct ListBase *lb, struct Mesh *me);

View File

@ -35,13 +35,10 @@ struct Mesh;
struct Object;
struct DerivedMesh;
struct EditMesh;
struct EditVert;
struct EditEdge;
struct EditFace;
struct SubsurfModifierData;
struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, struct SubsurfModifierData *smd, float (*vertexCos)[3]);
struct DerivedMesh *subsurf_make_derived_from_dlm_em(struct DispListMesh *dlm, struct SubsurfModifierData *smd, float (*vertCos)[3], struct EditVert **vertMap, struct EditEdge **edgeMap, struct EditFace **faceMap);
struct DerivedMesh *subsurf_make_derived_from_dlm_em(struct DispListMesh *dlm, struct SubsurfModifierData *smd, float (*vertCos)[3]);
struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, struct DispListMesh *dlm, struct SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc);
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]);

View File

@ -693,6 +693,10 @@ CCGError ccgSubSurf_setAllowEdgeCreation(CCGSubSurf *ss, int allowEdgeCreation,
return eCCGError_None;
}
void ccgSubSurf_getAllowEdgeCreation(CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r) {
if (allowEdgeCreation_r) *allowEdgeCreation_r = ss->allowEdgeCreation;
if (defaultCreaseValue_r) *defaultCreaseValue_r = ss->defaultCreaseValue;
}
CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels) {
if (subdivisionLevels<=0) {
@ -850,9 +854,9 @@ CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL) {
return eCCGError_None;
}
CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData) {
CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, CCGVert **v_r) {
void **prevp;
CCGVert *v;
CCGVert *v = NULL;
if (ss->syncState==eSyncState_Partial) {
v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp);
@ -902,12 +906,13 @@ CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData) {
}
}
if (v_r) *v_r = v;
return eCCGError_None;
}
CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease) {
CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r) {
void **prevp;
CCGEdge *e, *eNew;
CCGEdge *e = NULL, *eNew;
if (ss->syncState==eSyncState_Partial) {
e = _ehash_lookupWithPrev(ss->eMap, eHDL, &prevp);
@ -955,12 +960,13 @@ CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0
}
}
if (e_r) *e_r = e;
return eCCGError_None;
}
CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs) {
CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r) {
void **prevp;
CCGFace *f, *fNew;
CCGFace *f = NULL, *fNew;
int j, k, topologyChanged = 0;
if (numVerts>ss->lenTempArrays) {
@ -1065,6 +1071,7 @@ CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGV
}
}
if (f_r) *f_r = f;
return eCCGError_None;
}

View File

@ -5,6 +5,10 @@ typedef void* CCGVertHDL;
typedef void* CCGEdgeHDL;
typedef void* CCGFaceHDL;
typedef struct _CCGVert CCGVert;
typedef struct _CCGEdge CCGEdge;
typedef struct _CCGFace CCGFace;
typedef struct _CCGMeshIFC CCGMeshIFC;
struct _CCGMeshIFC {
int vertUserSize, edgeUserSize, faceUserSize;
@ -45,9 +49,9 @@ CCGError ccgSubSurf_sync (CCGSubSurf *ss);
CCGError ccgSubSurf_initFullSync (CCGSubSurf *ss);
CCGError ccgSubSurf_initPartialSync (CCGSubSurf *ss);
CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData);
CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease);
CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs);
CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, CCGVert **v_r);
CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r);
CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r);
CCGError ccgSubSurf_syncVertDel (CCGSubSurf *ss, CCGVertHDL vHDL);
CCGError ccgSubSurf_syncEdgeDel (CCGSubSurf *ss, CCGEdgeHDL eHDL);
@ -58,16 +62,15 @@ CCGError ccgSubSurf_processSync (CCGSubSurf *ss);
CCGError ccgSubSurf_setSubdivisionLevels (CCGSubSurf *ss, int subdivisionLevels);
CCGError ccgSubSurf_setAllowEdgeCreation (CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue);
void ccgSubSurf_getAllowEdgeCreation (CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r);
void ccgSubSurf_getUseAgeCounts (CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r);
CCGError ccgSubSurf_setUseAgeCounts (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset);
CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, int normalDataOffset);
/***/
typedef struct _CCGVert CCGVert;
typedef struct _CCGEdge CCGEdge;
typedef struct _CCGFace CCGFace;
int ccgSubSurf_getNumVerts (CCGSubSurf *ss);
int ccgSubSurf_getNumEdges (CCGSubSurf *ss);
int ccgSubSurf_getNumFaces (CCGSubSurf *ss);

View File

@ -466,7 +466,6 @@ static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned ch
glShadeModel(GL_FLAT);
glDisable(GL_CULL_FACE);
}
static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr))
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
@ -526,6 +525,54 @@ static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
glEnd();
}
}
static void meshDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
Mesh *me = mdm->me;
MVert *mvert= mdm->verts;
MFace *mface= me->mface;
float *nors= mdm->nors;
int a, glmode, shademodel;
glShadeModel(shademodel = GL_SMOOTH);
glBegin(glmode = GL_QUADS);
for (a=0; a<me->totface; a++) {
MFace *mf= &mface[a];
int drawSmooth = 1;
if (mf->v3 && setDrawOptions(userData, a, &drawSmooth)) {
int newmode = mf->v4?GL_QUADS:GL_TRIANGLES;
int newshademodel = drawSmooth?GL_SMOOTH:GL_FLAT;
if (newmode!=glmode || newshademodel!=shademodel) {
glEnd();
glShadeModel(shademodel = newshademodel);
glBegin(glmode = newmode);
}
if (shademodel==GL_FLAT) {
glNormal3fv(&nors[a*3]);
glVertex3fv(mvert[mf->v1].co);
glVertex3fv(mvert[mf->v2].co);
glVertex3fv(mvert[mf->v3].co);
if(mf->v4) glVertex3fv(mvert[mf->v4].co);
} else {
glNormal3sv(mvert[mf->v1].no);
glVertex3fv(mvert[mf->v1].co);
glNormal3sv(mvert[mf->v2].no);
glVertex3fv(mvert[mf->v2].co);
glNormal3sv(mvert[mf->v3].no);
glVertex3fv(mvert[mf->v3].co);
if(mf->v4) {
glNormal3sv(mvert[mf->v4].no);
glVertex3fv(mvert[mf->v4].co);
}
}
}
}
glEnd();
}
static int meshDM_getNumVerts(DerivedMesh *dm)
{
MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
@ -573,6 +620,7 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3]
mdm->dm.drawFacesSolid = meshDM_drawFacesSolid;
mdm->dm.drawFacesColored = meshDM_drawFacesColored;
mdm->dm.drawFacesTex = meshDM_drawFacesTex;
mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
mdm->dm.release = meshDM_release;
@ -616,58 +664,55 @@ typedef struct {
float (*faceNos)[3];
} EditMeshDerivedMesh;
static void emDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData)
static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditVert *eve;
int i;
if (emdm->vertexCos) {
int i;
for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
func(userData, eve, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
}
} else {
for (eve= emdm->em->verts.first; eve; eve=eve->next) {
func(userData, eve, eve->co, eve->no, NULL);
for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
if (emdm->vertexCos) {
func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
} else {
func(userData, i, eve->co, eve->no, NULL);
}
}
}
static void emDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData)
static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditEdge *eed;
int i;
if (emdm->vertexCos) {
EditVert *eve, *preveve;
int i;
for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
eve->prev = (EditVert*) i++;
for(eed= emdm->em->edges.first; eed; eed= eed->next)
func(userData, eed, emdm->vertexCos[(int) eed->v1->prev], emdm->vertexCos[(int) eed->v2->prev]);
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
func(userData, i, emdm->vertexCos[(int) eed->v1->prev], emdm->vertexCos[(int) eed->v2->prev]);
for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
eve->prev = preveve;
} else {
for(eed= emdm->em->edges.first; eed; eed= eed->next)
func(userData, eed, eed->v1->co, eed->v2->co);
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
func(userData, i, eed->v1->co, eed->v2->co);
}
}
static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData)
static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditEdge *eed;
int i;
if (emdm->vertexCos) {
EditVert *eve, *preveve;
int i;
for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
eve->prev = (EditVert*) i++;
glBegin(GL_LINES);
for(eed= emdm->em->edges.first; eed; eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, eed)) {
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]);
glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]);
}
@ -678,8 +723,8 @@ static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *
eve->prev = preveve;
} else {
glBegin(GL_LINES);
for(eed= emdm->em->edges.first; eed; eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, eed)) {
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
glVertex3fv(eed->v1->co);
glVertex3fv(eed->v2->co);
}
@ -689,26 +734,26 @@ static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *
}
static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
{
emDM_drawMappedEdgesEM(dm, NULL, NULL);
emDM_drawMappedEdges(dm, NULL, NULL);
}
static void emDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void (*setDrawInterpOptions)(void *userData, EditEdge *edge, float t), void *userData)
static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditEdge *eed;
int i;
if (emdm->vertexCos) {
EditVert *eve, *preveve;
int i;
for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
eve->prev = (EditVert*) i++;
glBegin(GL_LINES);
for(eed= emdm->em->edges.first; eed; eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, eed)) {
setDrawInterpOptions(userData, eed, 0.0);
for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
setDrawInterpOptions(userData, i, 0.0);
glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]);
setDrawInterpOptions(userData, eed, 1.0);
setDrawInterpOptions(userData, i, 1.0);
glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]);
}
}
@ -718,11 +763,11 @@ static void emDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)(
eve->prev = preveve;
} else {
glBegin(GL_LINES);
for(eed= emdm->em->edges.first; eed; eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, eed)) {
setDrawInterpOptions(userData, eed, 0.0);
for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
setDrawInterpOptions(userData, i, 0.0);
glVertex3fv(eed->v1->co);
setDrawInterpOptions(userData, eed, 1.0);
setDrawInterpOptions(userData, i, 1.0);
glVertex3fv(eed->v2->co);
}
}
@ -749,22 +794,22 @@ static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[
VecMulf(cent, 0.33333333333f);
}
}
static void emDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData)
static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditVert *eve, *preveve;
EditFace *efa;
float cent[3];
int i=0; // gcc!
int i;
if (emdm->vertexCos) {
for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
eve->prev = (EditVert*) i++;
}
for(efa= emdm->em->faces.first; efa; efa= efa->next) {
for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
emDM__calcFaceCent(efa, cent, emdm->vertexCos);
func(userData, efa, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
}
if (emdm->vertexCos) {
@ -772,85 +817,75 @@ static void emDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *u
eve->prev = preveve;
}
}
static void emDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData)
static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData)
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditFace *efa;
int i;
if (emdm->vertexCos) {
EditVert *eve, *preveve;
int i;
int drawSmooth = 1;
for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
eve->prev = (EditVert*) i++;
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
if(!setDrawOptions || setDrawOptions(userData, efa)) {
glNormal3fv(emdm->faceNos[i]);
if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]);
glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]);
glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]);
if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]);
glEnd();
}
}
for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
eve->prev = preveve;
} else {
for (efa= emdm->em->faces.first; efa; efa= efa->next) {
if(!setDrawOptions || setDrawOptions(userData, efa)) {
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
glVertex3fv(efa->v1->co);
glVertex3fv(efa->v2->co);
glVertex3fv(efa->v3->co);
if(efa->v4) glVertex3fv(efa->v4->co);
glEnd();
}
}
}
}
static void emDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditFace *efa;
if (emdm->vertexCos) {
EditVert *eve, *preveve;
int i;
for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
eve->prev = (EditVert*) i++;
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
if(efa->h==0) {
if (setMaterial(efa->mat_nr+1)) {
if (drawSmooth) {
glNormal3fv(emdm->faceNos[i]);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]);
glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]);
glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]);
if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]);
glEnd();
} else {
glNormal3fv(emdm->vertexNos[(int) efa->v1->prev]);
glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]);
glNormal3fv(emdm->vertexNos[(int) efa->v2->prev]);
glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]);
glNormal3fv(emdm->vertexNos[(int) efa->v3->prev]);
glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]);
if(efa->v4) {
glNormal3fv(emdm->vertexNos[(int) efa->v4->prev]);
glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]);
}
}
glEnd();
}
}
for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
eve->prev = preveve;
} else {
for (efa= emdm->em->faces.first; efa; efa= efa->next) {
if(efa->h==0) {
if (setMaterial(efa->mat_nr+1)) {
int drawSmooth = 1;
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
if (drawSmooth) {
glNormal3fv(efa->n);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
glVertex3fv(efa->v1->co);
glVertex3fv(efa->v2->co);
glVertex3fv(efa->v3->co);
if(efa->v4) glVertex3fv(efa->v4->co);
glEnd();
} else {
glNormal3fv(efa->v1->no);
glVertex3fv(efa->v1->co);
glNormal3fv(efa->v2->no);
glVertex3fv(efa->v2->co);
glNormal3fv(efa->v3->no);
glVertex3fv(efa->v3->co);
if(efa->v4) {
glNormal3fv(efa->v4->no);
glVertex3fv(efa->v4->co);
}
}
glEnd();
}
}
}
@ -908,16 +943,14 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, float (*vertexCos)[3])
emdm->dm.getNumVerts = emDM_getNumVerts;
emdm->dm.getNumFaces = emDM_getNumFaces;
emdm->dm.foreachMappedVertEM = emDM_foreachMappedVertEM;
emdm->dm.foreachMappedEdgeEM = emDM_foreachMappedEdgeEM;
emdm->dm.foreachMappedFaceCenterEM = emDM_foreachMappedFaceCenterEM;
emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
emdm->dm.drawEdges = emDM_drawEdges;
emdm->dm.drawMappedEdgesEM = emDM_drawMappedEdgesEM;
emdm->dm.drawMappedEdgesInterpEM = emDM_drawMappedEdgesInterpEM;
emdm->dm.drawFacesSolid = emDM_drawFacesSolid;
emdm->dm.drawMappedFacesEM = emDM_drawMappedFacesEM;
emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
emdm->dm.release = emDM_release;
@ -979,120 +1012,92 @@ typedef struct {
DerivedMesh dm;
DispListMesh *dlm;
EditVert **vertMap;
EditEdge **edgeMap;
EditFace **faceMap;
} SSDerivedMesh;
static void ssDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData)
static void ssDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
DispListMesh *dlm = ssdm->dlm;
int i;
int i, index=-1;
if (ssdm->vertMap) {
for (i=0; i<dlm->totvert; i++) {
if (ssdm->vertMap[i]) {
func(userData, ssdm->vertMap[i], dlm->mvert[i].co, NULL, dlm->mvert[i].no);
}
for (i=0; i<dlm->totvert; i++) {
MVert *mv = &dlm->mvert[i];
if (mv->flag&ME_VERT_STEPINDEX) index++;
if (index!=-1) {
func(userData, index, mv->co, NULL, mv->no);
}
}
}
static void ssDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData)
static void ssDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
DispListMesh *dlm = ssdm->dlm;
int i;
int i, index=-1;
if (ssdm->edgeMap) {
for (i=0; i<dlm->totedge; i++) {
if (ssdm->edgeMap[i]) {
MEdge *med = &dlm->medge[i];
for (i=0; i<dlm->totedge; i++) {
MEdge *med = &dlm->medge[i];
func(userData, ssdm->edgeMap[i], dlm->mvert[med->v1].co, dlm->mvert[med->v2].co);
}
if (med->flag&ME_EDGE_STEPINDEX) index++;
if (index!=-1) {
func(userData, index, dlm->mvert[med->v1].co, dlm->mvert[med->v2].co);
}
}
}
static void ssDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData)
static void ssDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
DispListMesh *dlm = ssdm->dlm;
int i;
int i, index=-1;
if (ssdm->edgeMap) {
glBegin(GL_LINES);
for(i=0; i<dlm->totedge; i++) {
if(ssdm->edgeMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->edgeMap[i]))) {
MEdge *med = &dlm->medge[i];
glBegin(GL_LINES);
for(i=0; i<dlm->totedge; i++) {
MEdge *med = &dlm->medge[i];
glVertex3fv(dlm->mvert[med->v1].co);
glVertex3fv(dlm->mvert[med->v2].co);
}
if (med->flag&ME_EDGE_STEPINDEX) index++;
if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
glVertex3fv(dlm->mvert[med->v1].co);
glVertex3fv(dlm->mvert[med->v2].co);
}
glEnd();
}
glEnd();
}
static void ssDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData)
static void ssDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
DispListMesh *dlm = ssdm->dlm;
int i;
int i, index=-1;
if (ssdm->faceMap) {
for (i=0; i<dlm->totface; i++) {
if(ssdm->faceMap[i]) {
MFace *mf = &dlm->mface[i];
for (i=0; i<dlm->totface; i++) {
MFace *mf = &dlm->mface[i];
if (mf->v3) {
float cent[3];
float no[3];
if (mf->flag&ME_FACE_STEPINDEX) index++;
VECCOPY(cent, dlm->mvert[mf->v1].co);
VecAddf(cent, cent, dlm->mvert[mf->v2].co);
VecAddf(cent, cent, dlm->mvert[mf->v3].co);
if(index!=-1 && mf->v3) {
float cent[3];
float no[3];
if (mf->v4) {
CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, no);
VecAddf(cent, cent, dlm->mvert[mf->v4].co);
VecMulf(cent, 0.25f);
} else {
CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, no);
VecMulf(cent, 0.33333333333f);
}
VECCOPY(cent, dlm->mvert[mf->v1].co);
VecAddf(cent, cent, dlm->mvert[mf->v2].co);
VecAddf(cent, cent, dlm->mvert[mf->v3].co);
func(userData, ssdm->faceMap[i], cent, no);
}
if (mf->v4) {
CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, no);
VecAddf(cent, cent, dlm->mvert[mf->v4].co);
VecMulf(cent, 0.25f);
} else {
CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, no);
VecMulf(cent, 0.33333333333f);
}
func(userData, index, cent, no);
}
}
}
static void ssDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
DispListMesh *dlm = ssdm->dlm;
int i;
if (ssdm->faceMap) {
for (i=0; i<dlm->totface; i++) {
if(ssdm->faceMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->faceMap[i]))) {
MFace *mf = &dlm->mface[i];
if (mf->v3) {
glBegin(mf->v3?GL_QUADS:GL_TRIANGLES);
glVertex3fv(dlm->mvert[mf->v1].co);
glVertex3fv(dlm->mvert[mf->v2].co);
glVertex3fv(dlm->mvert[mf->v3].co);
if(mf->v4) glVertex3fv(dlm->mvert[mf->v4].co);
glEnd();
}
}
}
}
}
static void ssDM_drawVerts(DerivedMesh *dm)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
@ -1146,6 +1151,7 @@ static void ssDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
DispListMesh *dlm = ssdm->dlm;
MVert *mvert = dlm->mvert;
int tfaceFlags = (ME_EDGE_TFSEL|ME_EDGE_TFACT|ME_EDGE_TFVISIBLE|ME_EDGE_TFACTFIRST|ME_EDGE_TFACTLAST);
int i;
if (dlm->medge) {
@ -1159,6 +1165,78 @@ static void ssDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int
}
}
glEnd();
} else if ((mask&tfaceFlags) && dlm->tface) {
MFace *mface = dlm->mface;
TFace *tface = dlm->tface;
glBegin(GL_LINES);
for(i=0; i<dlm->totface; i++, mface++, tface++) {
if (mface->v3) {
unsigned int flags = ME_EDGEDRAW|ME_EDGEMAPPED;
unsigned int flag0, flag1, flag2, flag3;
if (tface->flag&TF_SELECT) flags |= ME_EDGE_TFSEL;
if (!(tface->flag&TF_HIDE)) flags |= ME_EDGE_TFVISIBLE;
if (tface->flag&TF_ACTIVE) {
flags |= ME_EDGE_TFACT;
flag0 = flag1 = flag2 = flag3 = flags;
flag0 |= ME_EDGE_TFACTFIRST;
flag3 |= ME_EDGE_TFACTLAST;
} else {
flag0 = flag1 = flag2 = flag3 = flags;
}
if (mask&ME_SEAM) {
if (tface->unwrap&TF_SEAM1) flag0 |= ME_SEAM;
if (tface->unwrap&TF_SEAM2) flag1 |= ME_SEAM;
if (tface->unwrap&TF_SEAM3) flag2 |= ME_SEAM;
if (tface->unwrap&TF_SEAM4) flag3 |= ME_SEAM;
}
if ((flag0&mask)==value) {
glVertex3fv(mvert[mface->v1].co);
glVertex3fv(mvert[mface->v2].co);
}
if ((flag1&mask)==value) {
glVertex3fv(mvert[mface->v2].co);
glVertex3fv(mvert[mface->v3].co);
}
if (mface->v4) {
if ((flag2&mask)==value) {
glVertex3fv(mvert[mface->v3].co);
glVertex3fv(mvert[mface->v4].co);
}
if ((flag3&mask)==value) {
glVertex3fv(mvert[mface->v4].co);
glVertex3fv(mvert[mface->v1].co);
}
} else {
if ((flag3&mask)==value) {
glVertex3fv(mvert[mface->v3].co);
glVertex3fv(mvert[mface->v1].co);
}
}
}
}
glEnd();
} else {
MFace *mface = dlm->mface;
glBegin(GL_LINES);
for(i=0; i<dlm->totface; i++, mface++) {
if (!mface->v3) {
if (((ME_EDGEDRAW|ME_LOOSEEDGE|ME_EDGEMAPPED)&mask)==value) {
glVertex3fv(mvert[mface->v1].co);
glVertex3fv(mvert[mface->v2].co);
}
}
}
glEnd();
}
}
static void ssDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
@ -1366,7 +1444,56 @@ static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, i
glEnd();
}
}
static void ssDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
DispListMesh *dlm = ssdm->dlm;
MVert *mvert= dlm->mvert;
MFace *mface= dlm->mface;
float *nors = dlm->nors;
int i, glmode, shademodel, index=-1;
glShadeModel(shademodel = GL_SMOOTH);
glBegin(glmode=GL_QUADS);
for (i=0; i<dlm->totface; i++) {
MFace *mf = &mface[i];
int drawSmooth = 1;
if (mf->flag&ME_FACE_STEPINDEX) index++;
if (index!=-1 && mf->v3 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) {
int newmode = mf->v4?GL_QUADS:GL_TRIANGLES;
int newshademodel = drawSmooth?GL_SMOOTH:GL_FLAT;
if (newmode!=glmode || newshademodel!=shademodel) {
glEnd();
glShadeModel(shademodel = newshademodel);
glBegin(glmode = newmode);
}
if (shademodel==GL_FLAT) {
glNormal3fv(&nors[i*3]);
glVertex3fv(mvert[mf->v1].co);
glVertex3fv(mvert[mf->v2].co);
glVertex3fv(mvert[mf->v3].co);
if(mf->v4) glVertex3fv(mvert[mf->v4].co);
} else {
glNormal3sv(mvert[mf->v1].no);
glVertex3fv(mvert[mf->v1].co);
glNormal3sv(mvert[mf->v2].no);
glVertex3fv(mvert[mf->v2].co);
glNormal3sv(mvert[mf->v3].no);
glVertex3fv(mvert[mf->v3].co);
if(mf->v4) {
glNormal3sv(mvert[mf->v4].no);
glVertex3fv(mvert[mf->v4].co);
}
}
}
}
glEnd();
}
static void ssDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
@ -1417,38 +1544,16 @@ static DispListMesh *ssDM_convertToDispListMesh(DerivedMesh *dm, int allowShared
}
}
static DispListMesh *ssDM_convertToDispListMeshMapped(DerivedMesh *dm, int allowShared, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
// We should never get here if the appropriate ssdm fields weren't given.
*vertMap_r = MEM_dupallocN(ssdm->vertMap);
*edgeMap_r = MEM_dupallocN(ssdm->edgeMap);
*faceMap_r = MEM_dupallocN(ssdm->faceMap);
if (allowShared) {
return displistmesh_copyShared(ssdm->dlm);
} else {
return displistmesh_copy(ssdm->dlm);
}
}
static void ssDM_release(DerivedMesh *dm)
{
SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
displistmesh_free(ssdm->dlm);
if (ssdm->vertMap) {
MEM_freeN(ssdm->vertMap);
MEM_freeN(ssdm->edgeMap);
MEM_freeN(ssdm->faceMap);
}
MEM_freeN(dm);
}
DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap)
DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3])
{
SSDerivedMesh *ssdm = MEM_callocN(sizeof(*ssdm), "ssdm");
@ -1457,7 +1562,6 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)
ssdm->dm.getNumVerts = ssDM_getNumVerts;
ssdm->dm.getNumFaces = ssDM_getNumFaces;
ssdm->dm.convertToDispListMesh = ssDM_convertToDispListMesh;
ssdm->dm.convertToDispListMeshMapped = ssDM_convertToDispListMeshMapped;
ssdm->dm.getVertCos = ssDM_getVertCos;
@ -1470,24 +1574,20 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)
ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid;
ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
ssdm->dm.drawFacesTex = ssDM_drawFacesTex;
ssdm->dm.drawMappedFaces = ssDM_drawMappedFaces;
/* EM functions */
ssdm->dm.foreachMappedVertEM = ssDM_foreachMappedVertEM;
ssdm->dm.foreachMappedEdgeEM = ssDM_foreachMappedEdgeEM;
ssdm->dm.foreachMappedFaceCenterEM = ssDM_foreachMappedFaceCenterEM;
ssdm->dm.foreachMappedVert = ssDM_foreachMappedVert;
ssdm->dm.foreachMappedEdge = ssDM_foreachMappedEdge;
ssdm->dm.foreachMappedFaceCenter = ssDM_foreachMappedFaceCenter;
ssdm->dm.drawMappedEdgesEM = ssDM_drawMappedEdgesEM;
ssdm->dm.drawMappedEdgesInterpEM = NULL; // no way to implement this one
ssdm->dm.drawMappedEdges = ssDM_drawMappedEdges;
ssdm->dm.drawMappedEdgesInterp = NULL; // no way to implement this one
ssdm->dm.drawMappedFacesEM = ssDM_drawMappedFacesEM;
ssdm->dm.release = ssDM_release;
ssdm->dlm = dlm;
ssdm->vertMap = vertMap;
ssdm->edgeMap = edgeMap;
ssdm->faceMap = faceMap;
if (vertexCos) {
int i;
@ -1642,7 +1742,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
dm->release(dm);
*final_r = derivedmesh_from_displistmesh(dlm, deformedVerts, NULL, NULL, NULL);
*final_r = derivedmesh_from_displistmesh(dlm, deformedVerts);
} else if (dm) {
*final_r = dm;
} else {
@ -1739,13 +1839,10 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
if (cage_r && i==cageIndex) {
if (dm && deformedVerts) {
DispListMesh *dlm;
EditVert **vertMap;
EditEdge **edgeMap;
EditFace **faceMap;
dlm = dm->convertToDispListMeshMapped(dm, 0, &vertMap, &edgeMap, &faceMap);
dlm = dm->convertToDispListMesh(dm, 0);
*cage_r = derivedmesh_from_displistmesh(dlm, deformedVerts, vertMap, edgeMap, faceMap);
*cage_r = derivedmesh_from_displistmesh(dlm, deformedVerts);
} else if (dm) {
*cage_r = dm;
} else {
@ -1763,7 +1860,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
if (!cage_r || dm!=*cage_r) dm->release(dm);
*final_r = derivedmesh_from_displistmesh(dlm, deformedVerts, NULL, NULL, NULL);
*final_r = derivedmesh_from_displistmesh(dlm, deformedVerts);
MEM_freeN(deformedVerts);
} else if (dm) {
*final_r = dm;

View File

@ -137,7 +137,7 @@ DispListMesh *displistmesh_copy(DispListMesh *odlm)
if (odlm->nors) ndlm->nors = MEM_dupallocN(odlm->nors);
if (odlm->mcol) ndlm->mcol= MEM_dupallocN(odlm->mcol);
if (odlm->tface) ndlm->tface= MEM_dupallocN(odlm->tface);
return ndlm;
}

View File

@ -649,7 +649,7 @@ static void read_videoscape_mesh(char *str)
}
mface->edcode= 3;
test_index_mface(mface, poly);
test_index_face(mface, NULL, NULL, poly);
mface++;
}
@ -823,7 +823,7 @@ static void read_radiogour(char *str)
}
mface->edcode= 3;
test_index_mface(mface, poly);
test_index_face(mface, NULL, NULL, poly);
mface++;
}
@ -2128,7 +2128,7 @@ static void displist_to_mesh(DispList *dlfirst)
mface->v4= p3;
mface->mat_nr= colnr;
test_index_mface(mface, 4);
test_index_face(mface, NULL, NULL, 4);
mface++;
@ -2161,7 +2161,7 @@ static void displist_to_mesh(DispList *dlfirst)
mface->v2= startve+a*dl->nr+1;
mface->v3= startve+a*dl->nr+2;
mface->mat_nr= colnr;
test_index_mface(mface, 3);
test_index_face(mface, NULL, NULL, 3);
mface++;
}
else {
@ -2170,7 +2170,7 @@ static void displist_to_mesh(DispList *dlfirst)
mface->v3= startve+a*dl->nr+2;
mface->v4= startve+a*dl->nr+3;
mface->mat_nr= colnr;
test_index_mface(mface, 4);
test_index_face(mface, NULL, NULL, 4);
mface++;
}
}
@ -2196,7 +2196,7 @@ static void displist_to_mesh(DispList *dlfirst)
else mface->v2= startve+a+1;
mface->mat_nr= colnr;
test_index_mface(mface, 2);
test_index_face(mface, NULL, NULL, 2);
mface++;
}
@ -2226,7 +2226,7 @@ static void displist_to_mesh(DispList *dlfirst)
if (mface->v2>maxvertidx) mface->v2= maxvertidx;
if (mface->v3>maxvertidx) mface->v3= maxvertidx;
test_index_mface(mface, 3);
test_index_face(mface, NULL, NULL, 3);
mface++;
idata+= 3;
}
@ -2248,7 +2248,7 @@ static void displist_to_mesh(DispList *dlfirst)
mface->v1= startve+a;
mface->v2= startve+a+1;
mface->mat_nr= colnr;
test_index_mface(mface, 2);
test_index_face(mface, NULL, NULL, 2);
mface++;
}
startve += dl->nr;
@ -4328,7 +4328,7 @@ static void dxf_read_polyline(int noob) {
mface->edcode= 3;
mface->mat_nr= 0;
test_index_mface(mface, 2);
test_index_face(mface, NULL, NULL, 2);
}
}
@ -4445,9 +4445,9 @@ static void dxf_read_polyline(int noob) {
if(vids[3] && vids[3]!=vids[0]) {
mface->v4= vids[3]-1;
test_index_mface(mface, 4);
test_index_face(mface, NULL, NULL, 4);
}
else test_index_mface(mface, 3);
else test_index_face(mface, NULL, NULL, 3);
mface->edcode= 3;
mface->mat_nr= 0;
@ -4786,7 +4786,7 @@ static void dxf_read_3dface(int noob)
mface->edcode= 3;
mface->mat_nr= 0;
test_index_mface(mface, nverts);
test_index_face(mface, NULL, NULL, nverts);
hasbumped=1;
}

View File

@ -488,89 +488,12 @@ float *mesh_create_orco(Object *ob)
return make_orco_mesh_internal(ob, 0);
}
/** rotates the vertices of a face in case v[2] or v[3] (vertex index)
* is = 0.
* Helaas, the MFace structure has no pointer to its
* texture face, therefore, texture can not be fixed inside
* this function.
*
* see also blender/src/editmesh.c, fix_faceindices()
* THIS FUNCTION WILL BE DINOSOURCE. For the moment, another hack
is added to fix texture coordinates / vertex colors:
void test_index_face(MFace *mface, TFace *tface, int nr)
*/
void test_index_mface(MFace *mface, int nr)
/* rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0. */
#define UVSWAP(t, s) { SWAP(float, t[0], s[0]); SWAP(float, t[1], s[1]); }
void test_index_face(MFace *mface, MCol *mc, TFace *tface, int nr)
{
int a;
/* first test if the face is legal */
if(mface->v3 && mface->v3==mface->v4) {
mface->v4= 0;
nr--;
}
if(mface->v2 && mface->v2==mface->v3) {
mface->v3= mface->v4;
mface->v4= 0;
nr--;
}
if(mface->v1==mface->v2) {
mface->v2= mface->v3;
mface->v3= mface->v4;
mface->v4= 0;
nr--;
}
/* prevent a zero at wrong index location */
if(nr==2) {
if(mface->v2==0) SWAP(int, mface->v1, mface->v2);
}
else if(nr==3) {
if(mface->v3==0) {
SWAP(int, mface->v1, mface->v2);
SWAP(int, mface->v2, mface->v3);
a= mface->edcode;
mface->edcode= 0;
if(a & ME_V1V2) mface->edcode |= ME_V3V1;
if(a & ME_V2V3) mface->edcode |= ME_V1V2;
if(a & ME_V3V1) mface->edcode |= ME_V2V3;
}
}
else if(nr==4) {
if(mface->v3==0 || mface->v4==0) {
SWAP(int, mface->v1, mface->v3);
SWAP(int, mface->v2, mface->v4);
a= mface->edcode;
mface->edcode= 0;
if(a & ME_V1V2) mface->edcode |= ME_V3V4;
if(a & ME_V2V3) mface->edcode |= ME_V2V3;
if(a & ME_V3V4) mface->edcode |= ME_V1V2;
if(a & ME_V4V1) mface->edcode |= ME_V4V1;
}
}
}
/** This function should die as soon as there is another mesh
structure. Functionality is the same as
void test_index_mface()
but it fixes texture coordinates as well.
*/
#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
void test_index_face(MFace *mface, TFace *tface, int nr)
{
int a;
float tmpuv[2];
unsigned int tmpcol;
/* first test if the face is legal */
if(mface->v3 && mface->v3==mface->v4) {
@ -597,18 +520,19 @@ void test_index_face(MFace *mface, TFace *tface, int nr)
if(mface->v3==0) {
SWAP(int, mface->v1, mface->v2);
SWAP(int, mface->v2, mface->v3);
/* rotate face UV coordinates, too */
UVCOPY(tmpuv, tface->uv[0]);
UVCOPY(tface->uv[0], tface->uv[1]);
UVCOPY(tface->uv[1], tface->uv[2]);
UVCOPY(tface->uv[2], tmpuv);
/* same with vertex colours */
tmpcol = tface->col[0];
tface->col[0] = tface->col[1];
tface->col[1] = tface->col[2];
tface->col[2] = tmpcol;
if (tface) {
UVSWAP(tface->uv[0], tface->uv[1]);
UVSWAP(tface->uv[1], tface->uv[2]);
SWAP(unsigned int, tface->col[0], tface->col[1]);
SWAP(unsigned int, tface->col[1], tface->col[2]);
}
if (mc) {
SWAP(MCol, mc[0], mc[1]);
SWAP(MCol, mc[1], mc[2]);
}
a= mface->edcode;
mface->edcode= 0;
if(a & ME_V1V2) mface->edcode |= ME_V3V1;
@ -620,20 +544,19 @@ void test_index_face(MFace *mface, TFace *tface, int nr)
if(mface->v3==0 || mface->v4==0) {
SWAP(int, mface->v1, mface->v3);
SWAP(int, mface->v2, mface->v4);
/* swap UV coordinates */
UVCOPY(tmpuv, tface->uv[0]);
UVCOPY(tface->uv[0], tface->uv[2]);
UVCOPY(tface->uv[2], tmpuv);
UVCOPY(tmpuv, tface->uv[1]);
UVCOPY(tface->uv[1], tface->uv[3]);
UVCOPY(tface->uv[3], tmpuv);
/* swap vertex colours */
tmpcol = tface->col[0];
tface->col[0] = tface->col[2];
tface->col[2] = tmpcol;
tmpcol = tface->col[1];
tface->col[1] = tface->col[3];
tface->col[3] = tmpcol;
if (tface) {
UVSWAP(tface->uv[0], tface->uv[2]);
UVSWAP(tface->uv[1], tface->uv[3]);
SWAP(unsigned int, tface->col[0], tface->col[2]);
SWAP(unsigned int, tface->col[1], tface->col[3]);
}
if (mc) {
SWAP(MCol, mc[0], mc[2]);
SWAP(MCol, mc[1], mc[3]);
}
a= mface->edcode;
mface->edcode= 0;
@ -645,39 +568,6 @@ void test_index_face(MFace *mface, TFace *tface, int nr)
}
}
void flipnorm_mesh(Mesh *me)
{
MFace *mface;
MVert *mvert;
int a;
mvert= me->mvert;
a= me->totvert;
while(a--) {
mvert->no[0]= -mvert->no[0];
mvert->no[1]= -mvert->no[1];
mvert->no[2]= -mvert->no[2];
mvert++;
}
mface= me->mface;
a= me->totface;
while(a--) {
if(mface->v3) {
if(mface->v4) {
SWAP(int, mface->v4, mface->v1);
SWAP(int, mface->v3, mface->v2);
test_index_mface(mface, 4);
}
else {
SWAP(int, mface->v3, mface->v1);
test_index_mface(mface, 3);
}
}
mface++;
}
}
Mesh *get_mesh(Object *ob)
{
@ -942,7 +832,7 @@ void nurbs_to_mesh(Object *ob)
mface->v1= startvert+ofs+b-1;
mface->v2= startvert+ofs+b;
mface->edcode= ME_V1V2;
test_index_mface(mface, 2);
test_index_face(mface, NULL, NULL, 2);
mface++;
}
}
@ -968,7 +858,7 @@ void nurbs_to_mesh(Object *ob)
if(b==dl->nr-1) mface->v2= startvert+ofs;
else mface->v2= startvert+ofs+b+1;
mface->edcode= ME_V1V2;
test_index_mface(mface, 2);
test_index_face(mface, NULL, NULL, 2);
mface++;
}
}
@ -994,7 +884,7 @@ void nurbs_to_mesh(Object *ob)
mface->v4= 0;
mface->edcode= ME_V1V2+ME_V2V3;
test_index_mface(mface, 3);
test_index_face(mface, NULL, NULL, 3);
mface++;
index+= 3;
@ -1043,7 +933,7 @@ void nurbs_to_mesh(Object *ob)
mface->v4= p2;
mface->mat_nr= (unsigned char)dl->col;
mface->edcode= ME_V1V2+ME_V2V3;
test_index_mface(mface, 4);
test_index_face(mface, NULL, NULL, 4);
mface++;
p4= p3;

View File

@ -202,12 +202,9 @@ static void *subsurfModifier_applyModifierEM(ModifierData *md, Object *ob, void
SubsurfModifierData *smd = (SubsurfModifierData*) md;
if (dm) {
EditVert **vertMap;
EditEdge **edgeMap;
EditFace **faceMap;
DispListMesh *dlm = dm->convertToDispListMeshMapped(dm, 0, &vertMap, &edgeMap, &faceMap);
DispListMesh *dlm = dm->convertToDispListMesh(dm, 0);
dm = subsurf_make_derived_from_dlm_em(dlm, smd, vertexCos, vertMap, edgeMap, faceMap);
dm = subsurf_make_derived_from_dlm_em(dlm, smd, vertexCos);
return dm;
} else {
@ -452,7 +449,7 @@ static void *buildModifier_applyModifier(ModifierData *md, Object *ob, void *der
mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
return derivedmesh_from_displistmesh(ndlm, NULL);
}
/* Mirror */
@ -473,307 +470,257 @@ static void mirrorModifier_copyData(ModifierData *md, ModifierData *target)
tmmd->tolerance = mmd->tolerance;
}
static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm, float (*vertexCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r)
static DispListMesh *mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *inDLM, float (*vertexCos)[3], int initFlags)
{
int totvert=ndlm->totvert, totedge=ndlm->totedge, totface=ndlm->totface;
int i, axis = mmd->axis;
float tolerance = mmd->tolerance;
EditVert **vMapOut;
EditEdge **eMapOut;
EditFace **fMapOut;
DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "mirror_dlm");
int (*indexMap)[2];
if (vertMap) {
*vertMap_r = vMapOut = MEM_mallocN(sizeof(*vMapOut)*totvert*2, "vmap");
*edgeMap_r = eMapOut = MEM_mallocN(sizeof(*eMapOut)*totedge*2, "emap");
*faceMap_r = fMapOut = MEM_mallocN(sizeof(*fMapOut)*totface*2, "fmap");
} else {
*vertMap_r = vMapOut = NULL;
*edgeMap_r = eMapOut = NULL;
*faceMap_r = fMapOut = NULL;
}
dlm->totvert = dlm->totedge = dlm->totface = 0;
indexMap = MEM_mallocN(sizeof(*indexMap)*inDLM->totvert, "indexmap");
dlm->mvert = MEM_callocN(sizeof(*dlm->mvert)*inDLM->totvert*2, "dlm_mvert");
dlm->mface = MEM_callocN(sizeof(*dlm->mface)*inDLM->totface*2, "dlm_mface");
for (i=0; i<totvert; i++) {
MVert *mv = &ndlm->mvert[i];
int isShared = ABS(mv->co[axis])<=tolerance;
if (inDLM->medge) dlm->medge = MEM_callocN(sizeof(*dlm->medge)*inDLM->totedge*2, "dlm_medge");
if (inDLM->tface) dlm->tface = MEM_callocN(sizeof(*dlm->tface)*inDLM->totface*2, "dlm_tface");
if (inDLM->mcol) dlm->mcol = MEM_callocN(sizeof(*dlm->mcol)*inDLM->totface*4*2, "dlm_mcol");
/* Because the topology result (# of vertices) must stuff the same
for (i=0; i<inDLM->totvert; i++) {
MVert *inMV = &inDLM->mvert[i];
MVert *mv = &dlm->mvert[dlm->totvert++];
int isShared = ABS(inMV->co[axis])<=tolerance;
/* Because the topology result (# of vertices) must be the same
* if the mesh data is overridden by vertex cos, have to calc sharedness
* based on original coordinates. Only write new cos for non-shared
* vertices. This is why we test before copy.
* based on original coordinates. This is why we test before copy.
*/
*mv = *inMV;
if (vertexCos) {
VECCOPY(mv->co, vertexCos[i]);
}
if (initFlags) mv->flag |= ME_VERT_STEPINDEX;
if (vMapOut) vMapOut[i] = vertMap[i];
indexMap[i][0] = dlm->totvert-1;
indexMap[i][1] = !isShared;
if (isShared) {
mv->co[axis] = 0;
*((int*) mv->no) = i;
} else {
MVert *nmv = &ndlm->mvert[ndlm->totvert];
MVert *mv2 = &dlm->mvert[dlm->totvert++];
memcpy(nmv, mv, sizeof(*mv));
nmv ->co[axis] = -nmv ->co[axis];
if (vMapOut) vMapOut[ndlm->totvert] = vertMap[i];
*((int*) mv->no) = ndlm->totvert++;
*mv2 = *mv;
mv2->co[axis] = -mv2->co[axis];
mv2->flag &= ~ME_VERT_STEPINDEX;
}
}
if (ndlm->medge) {
for (i=0; i<totedge; i++) {
MEdge *med = &ndlm->medge[i];
MEdge *nmed = &ndlm->medge[ndlm->totedge];
for (i=0; i<inDLM->totedge; i++) {
MEdge *inMED = &inDLM->medge[i];
MEdge *med = &dlm->medge[dlm->totedge++];
memcpy(nmed, med, sizeof(*med));
*med = *inMED;
med->v1 = indexMap[inMED->v1][0];
med->v2 = indexMap[inMED->v2][0];
if (initFlags) med->flag |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED|ME_EDGE_STEPINDEX;
nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no);
nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no);
if (indexMap[inMED->v1][1] || indexMap[inMED->v2][2]) {
MEdge *med2 = &dlm->medge[dlm->totedge++];
if (eMapOut) eMapOut[i] = edgeMap[i];
if (nmed->v1!=med->v1 || nmed->v2!=med->v2) {
if (eMapOut) eMapOut[ndlm->totedge] = edgeMap[i];
ndlm->totedge++;
}
*med2 = *med;
med2->v1 = med->v1+indexMap[inMED->v1][1];
med2->v2 = med->v2+indexMap[inMED->v2][1];
med2->flag &= ~ME_EDGE_STEPINDEX;
}
}
for (i=0; i<totface; i++) {
MFace *mf = &ndlm->mface[i];
MFace *nmf = &ndlm->mface[ndlm->totface];
TFace *tf=NULL, *ntf=NULL; /* gcc's mother is uninitialized! */
MCol *mc=NULL, *nmc=NULL;
for (i=0; i<inDLM->totface; i++) {
MFace *inMF = &inDLM->mface[i];
MFace *mf = &dlm->mface[dlm->totface++];
*mf = *inMF;
mf->v1 = indexMap[inMF->v1][0];
mf->v2 = indexMap[inMF->v2][0];
mf->v3 = indexMap[inMF->v3][0];
mf->v4 = indexMap[inMF->v4][0];
if (initFlags) mf->flag |= ME_FACE_STEPINDEX;
if (inDLM->tface) {
TFace *inTF = &inDLM->tface[i];
TFace *tf = &dlm->tface[dlm->totface-1];
*tf = *inTF;
} else if (inDLM->mcol) {
MCol *inMC = &inDLM->mcol[i*4];
MCol *mc = &dlm->mcol[(dlm->totface-1)*4];
mc[0] = inMC[0];
mc[1] = inMC[1];
mc[2] = inMC[2];
mc[3] = inMC[3];
}
memcpy(nmf, mf, sizeof(*mf));
if (ndlm->tface) {
ntf = &ndlm->tface[ndlm->totface];
tf = &ndlm->tface[i];
memcpy(ntf, tf, sizeof(*ndlm->tface));
} else if (ndlm->mcol) {
nmc = &ndlm->mcol[ndlm->totface*4];
mc = &ndlm->mcol[i*4];
memcpy(nmc, mc, sizeof(*ndlm->mcol)*4);
}
if (indexMap[inMF->v1][1] || indexMap[inMF->v2][1] || (mf->v3 && indexMap[inMF->v3][1]) || (mf->v4 && indexMap[inMF->v4][1])) {
MFace *mf2 = &dlm->mface[dlm->totface++];
TFace *tf = NULL;
MCol *mc = NULL;
/* Map vertices to shared */
*mf2 = *mf;
mf2->v1 = indexMap[inMF->v1][0] + indexMap[inMF->v1][1];
mf2->v2 = indexMap[inMF->v2][0] + indexMap[inMF->v2][1];
mf2->v3 = indexMap[inMF->v3][0] + (inMF->v3?indexMap[inMF->v3][1]:0);
mf2->v4 = indexMap[inMF->v4][0] + (inMF->v4?indexMap[inMF->v4][1]:0);
mf2->flag &= ~ME_FACE_STEPINDEX;
nmf->v1 = *((int*) ndlm->mvert[nmf->v1].no);
nmf->v2 = *((int*) ndlm->mvert[nmf->v2].no);
if (nmf->v3) {
nmf->v3 = *((int*) ndlm->mvert[nmf->v3].no);
if (nmf->v4) nmf->v4 = *((int*) ndlm->mvert[nmf->v4].no);
}
if (inDLM->tface) {
TFace *inTF = &inDLM->tface[i];
tf = &dlm->tface[dlm->totface-1];
if (fMapOut) fMapOut[i] = faceMap[i];
*tf = *inTF;
} else if (inDLM->mcol) {
MCol *inMC = &inDLM->mcol[i*4];
mc = &dlm->mcol[(dlm->totface-1)*4];
/* If all vertices shared don't duplicate face */
if (nmf->v1==mf->v1 && nmf->v2==mf->v2 && nmf->v3==mf->v3 && nmf->v4==mf->v4)
continue;
mc[0] = inMC[0];
mc[1] = inMC[1];
mc[2] = inMC[2];
mc[3] = inMC[3];
}
if (fMapOut) fMapOut[ndlm->totface] = faceMap[i];
if (nmf->v3) {
/* Need to flip face normal, pick which verts to flip
* in order to prevent nmf->v3==0 or nmf->v4==0
*/
if (nmf->v1) {
SWAP(int, nmf->v1, nmf->v3);
if (ndlm->tface) {
SWAP(unsigned int, ntf->col[0], ntf->col[2]);
SWAP(float, ntf->uv[0][0], ntf->uv[2][0]);
SWAP(float, ntf->uv[0][1], ntf->uv[2][1]);
} else if (ndlm->mcol) {
SWAP(MCol, nmc[0], nmc[2]);
if (mf2->v3) {
/* Flip face normal */
SWAP(int, mf2->v1, mf2->v3);
if (tf) {
SWAP(unsigned int, tf->col[0], tf->col[2]);
SWAP(float, tf->uv[0][0], tf->uv[2][0]);
SWAP(float, tf->uv[0][1], tf->uv[2][1]);
} else if (mc) {
SWAP(MCol, mc[0], mc[2]);
}
} else {
if (nmf->v4) {
SWAP(int, nmf->v2, nmf->v4);
if (ndlm->tface) {
SWAP(unsigned int, ntf->col[1], ntf->col[3]);
SWAP(float, ntf->uv[1][0], ntf->uv[3][0]);
SWAP(float, ntf->uv[1][1], ntf->uv[3][1]);
} else if (ndlm->mcol) {
SWAP(MCol, nmc[1], nmc[3]);
}
} else {
SWAP(int, nmf->v2, nmf->v3);
if (ndlm->tface) {
SWAP(unsigned int, ntf->col[1], ntf->col[2]);
SWAP(float, ntf->uv[1][0], ntf->uv[2][0]);
SWAP(float, ntf->uv[1][1], ntf->uv[2][1]);
} else if (ndlm->mcol) {
SWAP(MCol, nmc[1], nmc[2]);
}
}
test_index_face(mf2, mc, tf, inMF->v4?4:3);
}
}
ndlm->totface++;
}
MEM_freeN(indexMap);
return dlm;
}
static void *mirrorModifier_applyModifier__internal(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc, int needsMaps)
static void *mirrorModifier_applyModifier__internal(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
{
DerivedMesh *dm = derivedData;
MirrorModifierData *mmd = (MirrorModifierData*) md;
DispListMesh *dlm=NULL, *ndlm = MEM_callocN(sizeof(*dlm), "mm_dlm");
MVert *mvert;
MEdge *medge;
MFace *mface;
TFace *tface;
MCol *mcol;
EditVert **vertMapOut, **vertMap = NULL;
EditEdge **edgeMapOut, **edgeMap = NULL;
EditFace **faceMapOut, **faceMap = NULL;
DispListMesh *outDLM, *inDLM;
if (dm) {
if (needsMaps) {
dlm = dm->convertToDispListMeshMapped(dm, 1, &vertMap, &edgeMap, &faceMap);
} else {
dlm = dm->convertToDispListMesh(dm, 1);
}
mvert = dlm->mvert;
medge = dlm->medge;
mface = dlm->mface;
tface = dlm->tface;
mcol = dlm->mcol;
ndlm->totvert = dlm->totvert;
ndlm->totedge = dlm->totedge;
ndlm->totface = dlm->totface;
inDLM = dm->convertToDispListMesh(dm, 1);
} else {
Mesh *me = ob->data;
mvert = me->mvert;
medge = me->medge;
mface = me->mface;
tface = me->tface;
mcol = me->mcol;
ndlm->totvert = me->totvert;
ndlm->totedge = me->totedge;
ndlm->totface = me->totface;
inDLM = MEM_callocN(sizeof(*inDLM), "inDLM");
inDLM->dontFreeVerts = inDLM->dontFreeOther = 1;
inDLM->mvert = me->mvert;
inDLM->medge = me->medge;
inDLM->mface = me->mface;
inDLM->tface = me->tface;
inDLM->mcol = me->mcol;
inDLM->totvert = me->totvert;
inDLM->totedge = me->totedge;
inDLM->totface = me->totface;
}
ndlm->mvert = MEM_mallocN(sizeof(*mvert)*ndlm->totvert*2, "mm_mv");
memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert);
outDLM = mirrorModifier__doMirror(mmd, inDLM, vertexCos, dm?0:1);
if (medge) {
ndlm->medge = MEM_mallocN(sizeof(*medge)*ndlm->totedge*2, "mm_med");
memcpy(ndlm->medge, medge, sizeof(*medge)*ndlm->totedge);
}
ndlm->mface = MEM_mallocN(sizeof(*mface)*ndlm->totface*2, "mm_mf");
memcpy(ndlm->mface, mface, sizeof(*mface)*ndlm->totface);
if (tface) {
ndlm->tface = MEM_mallocN(sizeof(*tface)*ndlm->totface*2, "mm_tf");
memcpy(ndlm->tface, tface, sizeof(*tface)*ndlm->totface);
} else if (mcol) {
ndlm->mcol = MEM_mallocN(sizeof(*mcol)*4*ndlm->totface*2, "mm_mcol");
memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*ndlm->totface);
}
mirrorModifier__doMirror(mmd, ndlm, vertexCos, vertMap, edgeMap, faceMap, &vertMapOut, &edgeMapOut, &faceMapOut);
if (dlm) {
displistmesh_free(dlm);
if (needsMaps) {
MEM_freeN(vertMap);
MEM_freeN(edgeMap);
MEM_freeN(faceMap);
}
}
mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
displistmesh_free(inDLM);
return derivedmesh_from_displistmesh(ndlm, NULL, vertMapOut, edgeMapOut, faceMapOut);
mesh_calc_normals(outDLM->mvert, outDLM->totvert, outDLM->mface, outDLM->totface, &outDLM->nors);
return derivedmesh_from_displistmesh(outDLM, NULL);
}
static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
{
return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1, 0);
return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1);
}
static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3])
{
if (derivedData) {
return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1, 1);
return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1);
} else {
MirrorModifierData *mmd = (MirrorModifierData*) md;
DispListMesh *ndlm = MEM_callocN(sizeof(*ndlm), "mm_dlm");
DispListMesh *outDLM, *inDLM = MEM_callocN(sizeof(*inDLM), "mm_dlm");
EditMesh *em = editData;
EditVert *eve, *preveve;
EditEdge *eed;
EditFace *efa;
EditVert **vertMapOut, **vertMap;
EditEdge **edgeMapOut, **edgeMap;
EditFace **faceMapOut, **faceMap;
int i;
for (i=0,eve=em->verts.first; eve; eve= eve->next)
eve->prev = (EditVert*) i++;
ndlm->totvert = BLI_countlist(&em->verts);
ndlm->totedge = BLI_countlist(&em->edges);
ndlm->totface = BLI_countlist(&em->faces);
inDLM->totvert = BLI_countlist(&em->verts);
inDLM->totedge = BLI_countlist(&em->edges);
inDLM->totface = BLI_countlist(&em->faces);
vertMap = MEM_mallocN(sizeof(*vertMap)*ndlm->totvert, "mm_vmap");
edgeMap = MEM_mallocN(sizeof(*edgeMap)*ndlm->totedge, "mm_emap");
faceMap = MEM_mallocN(sizeof(*faceMap)*ndlm->totface, "mm_fmap");
inDLM->mvert = MEM_mallocN(sizeof(*inDLM->mvert)*inDLM->totvert*2, "mm_mv");
inDLM->medge = MEM_mallocN(sizeof(*inDLM->medge)*inDLM->totedge*2, "mm_med");
inDLM->mface = MEM_mallocN(sizeof(*inDLM->mface)*inDLM->totface*2, "mm_mf");
ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert*2, "mm_mv");
ndlm->medge = MEM_mallocN(sizeof(*ndlm->medge)*ndlm->totedge*2, "mm_med");
ndlm->mface = MEM_mallocN(sizeof(*ndlm->mface)*ndlm->totface*2, "mm_mf");
/* Need to be able to mark loose edges */
for (eed=em->edges.first; eed; eed=eed->next) {
eed->f2 = 0;
}
for (efa=em->faces.first; efa; efa=efa->next) {
efa->e1->f2 = 1;
efa->e2->f2 = 1;
efa->e3->f2 = 1;
efa->e4->f2 = 1;
}
for (i=0,eve=em->verts.first; i<ndlm->totvert; i++,eve=eve->next) {
MVert *mv = &ndlm->mvert[i];
for (i=0,eve=em->verts.first; i<inDLM->totvert; i++,eve=eve->next) {
MVert *mv = &inDLM->mvert[i];
VECCOPY(mv->co, eve->co);
vertMap[i] = eve;
mv->mat_nr = 0;
mv->flag = ME_VERT_STEPINDEX;
}
for (i=0,eed=em->edges.first; i<ndlm->totedge; i++,eed=eed->next) {
MEdge *med = &ndlm->medge[i];
for (i=0,eed=em->edges.first; i<inDLM->totedge; i++,eed=eed->next) {
MEdge *med = &inDLM->medge[i];
med->v1 = (int) eed->v1->prev;
med->v2 = (int) eed->v2->prev;
med->crease = (unsigned char) (eed->crease*255.0f);
edgeMap[i] = eed;
med->flag = ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED|ME_EDGE_STEPINDEX;
if (eed->seam) med->flag |= ME_SEAM;
if (!eed->f2) med->flag |= ME_LOOSEEDGE;
}
for (i=0,efa=em->faces.first; i<ndlm->totface; i++,efa=efa->next) {
MFace *mf = &ndlm->mface[i];
for (i=0,efa=em->faces.first; i<inDLM->totface; i++,efa=efa->next) {
MFace *mf = &inDLM->mface[i];
mf->v1 = (int) efa->v1->prev;
mf->v2 = (int) efa->v2->prev;
mf->v3 = (int) efa->v3->prev;
mf->v4 = efa->v4?(int) efa->v4->prev:0;
mf->mat_nr = efa->mat_nr;
mf->flag = efa->flag;
mf->flag = efa->flag|ME_FACE_STEPINDEX;
mf->edcode = 0;
test_index_mface(mf, efa->v4?4:3);
faceMap[i] = efa;
test_index_face(mf, NULL, NULL, efa->v4?4:3);
}
mirrorModifier__doMirror(mmd, ndlm, vertexCos, vertMap, edgeMap, faceMap, &vertMapOut, &edgeMapOut, &faceMapOut);
outDLM = mirrorModifier__doMirror(mmd, inDLM, vertexCos, 0);
displistmesh_free(inDLM);
for (preveve=NULL, eve=em->verts.first; eve; preveve=eve, eve= eve->next)
eve->prev = preveve;
mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
MEM_freeN(faceMap);
MEM_freeN(edgeMap);
MEM_freeN(vertMap);
mesh_calc_normals(outDLM->mvert, outDLM->totvert, outDLM->mface, outDLM->totface, &outDLM->nors);
return derivedmesh_from_displistmesh(ndlm, NULL, vertMapOut, edgeMapOut, faceMapOut);
return derivedmesh_from_displistmesh(outDLM, NULL);
}
}
@ -895,7 +842,7 @@ static void *decimateModifier_applyModifier(ModifierData *md, Object *ob, void *
mf->v1 = tri[0];
mf->v2 = tri[1];
mf->v3 = tri[2];
test_index_mface(mf, 3);
test_index_face(mface, NULL, NULL, 3);
}
}
else {
@ -918,7 +865,7 @@ exit:
if (ndlm) {
mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
return derivedmesh_from_displistmesh(ndlm, NULL);
} else {
return NULL;
}

View File

@ -68,9 +68,9 @@ typedef struct _VertData {
typedef struct CCGDerivedMesh CCGDerivedMesh;
static EditVert *ccgDM_getVertHandle(CCGDerivedMesh *ccgdm, CCGVert *v);
static EditEdge *ccgDM_getEdgeHandle(CCGDerivedMesh *ccgdm, CCGEdge *e);
static EditFace *ccgDM_getFaceHandle(CCGDerivedMesh *ccgdm, CCGFace *f);
static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v);
static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e);
static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f);
///
@ -113,9 +113,9 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAgin
}
if (useAging) {
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
} else {
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 4;
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
}
ifc.vertDataSize = sizeof(VertData);
@ -134,7 +134,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAgin
}
if (useAging) {
ccgSubSurf_setUseAgeCounts(ccgSS, 1, 4, 4, 4);
ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
}
if (useEdgeCreation) {
ccgSubSurf_setAllowEdgeCreation(ccgSS, 1, useFlatSubdiv?subdivLevels:0.0f);
@ -197,9 +197,9 @@ static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edg
}
}
static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditmesh, MEdge *medge, TFace *tface)
static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, TFace *tface)
{
unsigned int flags = ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED;
unsigned int flags = 0;
int j, N = ccgSubSurf_getEdgeNumFaces(ss, e);
if (!N) flags |= ME_LOOSEEDGE;
@ -207,40 +207,53 @@ static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditme
if (ssFromEditmesh) {
EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e);
flags |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED;
if (eed->seam) {
flags |= ME_SEAM;
}
} else {
int edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e);
int makeFlags = 0, edgeIdx = (int) ccgSubSurf_getEdgeEdgeHandle(ss, e);
/* Edges created by lib have handle of -1 */
if (edgeIdx!=-1 && medge) {
if (edgeIdx==-1) {
if (!medge) {
makeFlags = 1;
}
} else {
MEdge *origMed = &medge[edgeIdx];
flags |= (origMed->flag&ME_SEAM);
if (dlm) {
flags |= origMed->flag&~ME_EDGE_STEPINDEX;
} else {
flags |= (origMed->flag&ME_SEAM);
makeFlags = 1;
}
}
if (makeFlags) {
flags |= ME_EDGEDRAW|ME_EDGERENDER|ME_EDGEMAPPED;
if (tface) {
for (j=0; j<N; j++) {
CCGFace *f = ccgSubSurf_getEdgeFace(ss, e, j);
int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
TFace *tf = &tface[origIdx];
if (tface) {
for (j=0; j<N; j++) {
CCGFace *f = ccgSubSurf_getEdgeFace(ss, e, j);
int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
TFace *tf = &tface[origIdx];
if (!(tf->flag&TF_HIDE)) flags |= ME_EDGE_TFVISIBLE;
if (tf->flag&TF_SELECT) flags |= ME_EDGE_TFSEL;
if (!(tf->flag&TF_HIDE)) flags |= ME_EDGE_TFVISIBLE;
if (tf->flag&TF_SELECT) flags |= ME_EDGE_TFSEL;
if (tf->flag&TF_ACTIVE) {
int fN = ccgSubSurf_getFaceNumVerts(ss, f);
int k = ccgSubSurf_getFaceEdgeIndex(ss, f, e);
if (tf->flag&TF_ACTIVE) {
int fN = ccgSubSurf_getFaceNumVerts(ss, f);
int k = ccgSubSurf_getFaceEdgeIndex(ss, f, e);
flags |= ME_EDGE_TFACT;
flags |= ME_EDGE_TFACT;
if (k==0) {
flags |= ME_EDGE_TFACTFIRST;
if (k==0) {
flags |= ME_EDGE_TFACTFIRST;
}
else if (k==fN-1) {
flags |= ME_EDGE_TFACTLAST;
}
}
else if (k==fN-1) {
flags |= ME_EDGE_TFACTLAST;
}
}
}
}
@ -249,12 +262,12 @@ static unsigned int ss_getEdgeFlags(CCGSubSurf *ss, CCGEdge *e, int ssFromEditme
return flags;
}
static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, int drawInteriorEdges, Mesh *inMe, DispListMesh *inDLM, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) {
static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, int drawInteriorEdges, Mesh *inMe, DispListMesh *inDLM) {
DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
int edgeSize = ccgSubSurf_getEdgeSize(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
int edgeIndexBase, edgeBase, faceBase;
int i, j, k, S, x, y;
int edgeBase, faceBase;
int i, j, k, S, x, y, index, lastIndex;
int vertBase = 0;
TFace *tface = NULL;
MEdge *medge = NULL;
@ -263,9 +276,55 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
CCGVertIterator *vi;
CCGEdgeIterator *ei;
CCGFaceIterator *fi;
EditVert **vertMap = NULL;
EditEdge **edgeMap = NULL;
EditFace **faceMap = NULL;
CCGFace **faceMap2;
CCGEdge **edgeMap2;
CCGVert **vertMap2;
int totvert, totedge, totface, useEdgeCreation;
ccgSubSurf_getAllowEdgeCreation(ss, &useEdgeCreation, NULL);
totvert = ccgSubSurf_getNumVerts(ss);
vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
vi = ccgSubSurf_getVertIterator(ss);
for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
if (ssFromEditmesh) {
vertMap2[ccgDM_getVertMapIndex(ccgdm,ss,v)] = v;
} else {
vertMap2[(int) ccgSubSurf_getVertVertHandle(ss, v)] = v;
}
}
ccgVertIterator_free(vi);
totedge = ccgSubSurf_getNumEdges(ss);
edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
ei = ccgSubSurf_getEdgeIterator(ss);
for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
if (useEdgeCreation) {
edgeMap2[i] = e;
} else if (ssFromEditmesh) {
edgeMap2[ccgDM_getEdgeMapIndex(ccgdm,ss,e)] = e;
} else {
edgeMap2[(int) ccgSubSurf_getEdgeEdgeHandle(ss, e)] = e;
}
}
totface = ccgSubSurf_getNumFaces(ss);
faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
fi = ccgSubSurf_getFaceIterator(ss);
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
if (ssFromEditmesh) {
faceMap2[ccgDM_getFaceMapIndex(ccgdm,ss,f)] = f;
} else {
faceMap2[(int) ccgSubSurf_getFaceFaceHandle(ss, f)] = f;
}
}
ccgFaceIterator_free(fi);
if (!ssFromEditmesh) {
if (inDLM) {
@ -285,12 +344,6 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
dlm->totedge = ccgSubSurf_getNumFinalEdges(ss);
dlm->totface = ccgSubSurf_getNumFinalFaces(ss);
if (vertMap_r) {
*vertMap_r = vertMap = MEM_callocN(dlm->totvert*sizeof(*vertMap), "vmap");
*edgeMap_r = edgeMap = MEM_callocN(dlm->totedge*sizeof(*edgeMap), "emap");
*faceMap_r = faceMap = MEM_callocN(dlm->totface*sizeof(*faceMap), "fmap");
}
dlm->mvert = MEM_callocN(dlm->totvert*sizeof(*dlm->mvert), "dlm->mvert");
dlm->medge = MEM_callocN(dlm->totedge*sizeof(*dlm->medge), "dlm->medge");
dlm->mface = MEM_callocN(dlm->totface*sizeof(*dlm->mface), "dlm->mface");
@ -305,39 +358,17 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
dlm->mcol = NULL;
}
// load vertices
/* Load vertices... we do in this funny order because
* all "added" vertices" are required to appear first
* in the displist (before STEPINDEX flags start). Also
* note that the vertex with index 0 is always a face
* center vert, this is relied upon to ensure we don't
* need to do silly test_index_face calls.
*/
vertBase = i = 0;
vi = ccgSubSurf_getVertIterator(ss);
for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
VecCopyf(dlm->mvert[i].co, ccgSubSurf_getVertData(ss, v));
if (vertMap) {
vertMap[i] = ccgDM_getVertHandle(ccgdm, v);
}
*((int*) ccgSubSurf_getVertUserData(ss, v)) = i++;
}
ccgVertIterator_free(vi);
edgeIndexBase = edgeBase = i;
ei = ccgSubSurf_getEdgeIterator(ss);
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
int x;
for (x=1; x<edgeSize-1; x++) {
VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
}
*((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
edgeBase += edgeSize-2;
}
ccgEdgeIterator_free(ei);
faceBase = i;
fi = ccgSubSurf_getFaceIterator(ss);
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
faceBase = i = 0;
for (index=0; index<totface; index++) {
CCGFace *f = faceMap2[index];
int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getFaceCenterData(ss, f));
@ -359,34 +390,37 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
*((int*) ccgSubSurf_getFaceUserData(ss, f)) = faceBase;
faceBase += 1 + numVerts*((gridSize-2) + (gridSize-2)*(gridSize-2));
}
ccgFaceIterator_free(fi);
edgeBase = i;
for (index=0; index<totedge; index++) {
CCGEdge *e= edgeMap2[index];
int x;
for (x=1; x<edgeSize-1; x++) {
VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
}
*((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
edgeBase += edgeSize-2;
}
vertBase = i;
lastIndex = -1;
for (index=0; index<totvert; index++) {
CCGVert *v = vertMap2[index];
int mapIndex = ccgDM_getVertMapIndex(ccgdm, ss, v);
VecCopyf(dlm->mvert[i].co, ccgSubSurf_getVertData(ss, v));
if (mapIndex!=lastIndex)
dlm->mvert[i].flag = ME_VERT_STEPINDEX;
*((int*) ccgSubSurf_getVertUserData(ss, v)) = i++;
lastIndex = mapIndex;
}
// load edges
i=0;
ei = ccgSubSurf_getEdgeIterator(ss);
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
unsigned int flags = ss_getEdgeFlags(ss, e, ssFromEditmesh, medge, tface);
for (x=0; x<edgeSize-1; x++) {
MEdge *med = &dlm->medge[i];
med->v1 = getEdgeIndex(ss, e, x, edgeSize);
med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
med->flag = flags;
if (edgeMap) {
edgeMap[i] = ccgDM_getEdgeHandle(ccgdm, e);
}
i++;
}
}
ccgEdgeIterator_free(ei);
fi = ccgSubSurf_getFaceIterator(ss);
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
i = 0;
for (index=0; index<totface; index++) {
CCGFace *f = faceMap2[index];
int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
for (k=0; k<numVerts; k++) {
@ -417,14 +451,35 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
}
}
}
ccgFaceIterator_free(fi);
lastIndex = -1;
for (index=0; index<totedge; index++) {
CCGEdge *e= edgeMap2[index];
unsigned int flags = ss_getEdgeFlags(ss, e, ssFromEditmesh, inDLM, medge, tface);
int edgeStart = i;
for (x=0; x<edgeSize-1; x++) {
MEdge *med = &dlm->medge[i];
med->v1 = getEdgeIndex(ss, e, x, edgeSize);
med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
med->flag = flags;
i++;
}
if (!useEdgeCreation) {
int mapIndex = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
if (mapIndex!=lastIndex)
dlm->medge[edgeStart].flag |= ME_EDGE_STEPINDEX;
lastIndex = mapIndex;
}
}
// load faces
i = 0;
fi = ccgSubSurf_getFaceIterator(ss);
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
i=0;
lastIndex = -1;
for (index=0; index<totface; index++) {
CCGFace *f = faceMap2[index];
int numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
float edge_data[4][6];
float corner_data[4][6];
@ -433,6 +488,7 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
TFace *origTFace = NULL;
int mat_nr;
int flag;
int mapIndex = ccgDM_getFaceMapIndex(ccgdm, ss, f);
if (!ssFromEditmesh) {
int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
@ -488,26 +544,28 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
for (y=0; y<gridSize-1; y++) {
for (x=0; x<gridSize-1; x++) {
MFace *mf = &dlm->mface[i];
mf->v1 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
mf->v2 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize);
mf->v3 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
mf->v4 = getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize);
mf->v1 = getFaceIndex(ss, f, S, x+0, y+0, edgeSize, gridSize);
mf->v2 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
mf->v3 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize);
mf->v4 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
mf->mat_nr = mat_nr;
mf->flag = flag;
mf->flag = flag&~ME_FACE_STEPINDEX;
mf->edcode = 0;
if (faceMap) {
faceMap[i] = ccgDM_getFaceHandle(ccgdm, f);
if (S==0 && x==0 && y==0) {
if (mapIndex!=lastIndex)
mf->flag |= ME_FACE_STEPINDEX;
lastIndex = mapIndex;
}
if (x+1==gridSize-1)
mf->edcode|= ME_V2V3;
mf->edcode|= ME_V3V4;
if (y+1==gridSize-1)
mf->edcode|= ME_V1V2;
mf->edcode|= ME_V2V3;
for (j=0; j<4; j++) {
int fx = x + (j==1||j==2);
int fy = y + (j==0||j==1);
int fx = x + (j==2||j==3);
int fy = y + (j==1||j==2);
float x_v = (float) fx/(gridSize-1);
float y_v = (float) fy/(gridSize-1);
float data[6];
@ -550,7 +608,10 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, i
}
}
}
ccgFaceIterator_free(fi);
MEM_freeN(faceMap2);
MEM_freeN(edgeMap2);
MEM_freeN(vertMap2);
mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
@ -566,47 +627,53 @@ static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float
int totvert = dlm?dlm->totvert:me->totvert;
int totedge = dlm?dlm->totedge:me->totedge;
int totface = dlm?dlm->totface:me->totface;
int i;
int i, index;
ccgSubSurf_initFullSync(ss);
if (vertexCos) {
for (i=0; i<totvert; i++) {
ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos[i]);
}
} else {
for (i=0; i<totvert; i++) {
ccgSubSurf_syncVert(ss, (CCGVertHDL) i, mvert[i].co);
}
for (i=0,index=-1; i<totvert; i++) {
CCGVert *v;
ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos?vertexCos[i]:mvert[i].co, &v);
if (!dlm || (mvert[i].flag&ME_VERT_STEPINDEX)) index++;
((int*) ccgSubSurf_getVertUserData(ss, v))[1] = index;
}
if (medge) {
for (i=0; i<totedge; i++) {
for (i=0, index=-1; i<totedge; i++) {
MEdge *med = &medge[i];
CCGEdge *e;
float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease);
ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease, &e);
if (!dlm || (med->flag&ME_EDGE_STEPINDEX)) index++;
((int*) ccgSubSurf_getEdgeUserData(ss, e))[1] = index;
}
} else {
for (i=0; i<totface; i++) {
MFace *mf = &((MFace*) mface)[i];
if (!mf->v3) {
ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0f);
ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0f, NULL);
}
}
}
for (i=0; i<totface; i++) {
for (i=0, index=-1; i<totface; i++) {
MFace *mf = &((MFace*) mface)[i];
if (!dlm || (mf->flag&ME_FACE_STEPINDEX)) index++;
if (mf->v3) {
CCGFace *f;
fVerts[0] = (CCGVertHDL) mf->v1;
fVerts[1] = (CCGVertHDL) mf->v2;
fVerts[2] = (CCGVertHDL) mf->v3;
fVerts[3] = (CCGVertHDL) mf->v4;
ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts);
ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts, &f);
((int*) ccgSubSurf_getFaceUserData(ss, f))[1] = index;
}
}
@ -619,32 +686,40 @@ void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], in
EditVert *ev, *fVerts[4];
EditEdge *ee;
EditFace *ef;
int i;
ccgSubSurf_initFullSync(ss);
if (vertCos) {
int i=0;
for (ev=em->verts.first; ev; ev=ev->next) {
ccgSubSurf_syncVert(ss, ev, vertCos[i++]);
for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) {
CCGVert *v;
ccgSubSurf_syncVert(ss, ev, vertCos[i], &v);
((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i;
}
} else {
for (ev=em->verts.first; ev; ev=ev->next) {
ccgSubSurf_syncVert(ss, ev, ev->co);
for (i=0,ev=em->verts.first; ev; i++,ev=ev->next) {
CCGVert *v;
ccgSubSurf_syncVert(ss, ev, ev->co, &v);
((int*) ccgSubSurf_getVertUserData(ss, v))[1] = i;
}
}
for (ee=em->edges.first; ee; ee=ee->next) {
ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor);
for (i=0,ee=em->edges.first; ee; i++,ee=ee->next) {
CCGEdge *e;
ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor, &e);
((int*) ccgSubSurf_getEdgeUserData(ss, e))[1] = i;
}
for (ef=em->faces.first; ef; ef=ef->next) {
for (i=0,ef=em->faces.first; ef; i++,ef=ef->next) {
CCGFace *f;
fVerts[0] = ef->v1;
fVerts[1] = ef->v2;
fVerts[2] = ef->v3;
fVerts[3] = ef->v4;
ccgSubSurf_syncFace(ss, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
ccgSubSurf_syncFace(ss, ef, ef->v4?4:3, (CCGVertHDL*) fVerts, &f);
((int*) ccgSubSurf_getFaceUserData(ss, f))[1] = i;
}
ccgSubSurf_processSync(ss);
@ -660,38 +735,18 @@ struct CCGDerivedMesh {
Mesh *me;
DispListMesh *dlm;
EditVert **vertMap;
EditEdge **edgeMap;
EditFace **faceMap;
};
static EditVert *ccgDM_getVertHandle(CCGDerivedMesh *ccgdm, CCGVert *v) {
if (ccgdm->vertMap) {
int index = (int) ccgSubSurf_getVertVertHandle(ccgdm->ss, v);
return ccgdm->vertMap[index];
} else {
return ccgSubSurf_getVertVertHandle(ccgdm->ss, v);
}
static int ccgDM_getVertMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGVert *v) {
return ((int*) ccgSubSurf_getVertUserData(ss, v))[1];
}
static EditEdge *ccgDM_getEdgeHandle(CCGDerivedMesh *ccgdm, CCGEdge *e) {
if (ccgdm->vertMap) {
int index = (int) ccgSubSurf_getEdgeEdgeHandle(ccgdm->ss, e);
return ccgdm->edgeMap[index];
} else {
return ccgSubSurf_getEdgeEdgeHandle(ccgdm->ss, e);
}
static int ccgDM_getEdgeMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGEdge *e) {
return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1];
}
static EditFace *ccgDM_getFaceHandle(CCGDerivedMesh *ccgdm, CCGFace *f) {
if (ccgdm->vertMap) {
int index = (int) ccgSubSurf_getFaceFaceHandle(ccgdm->ss, f);
return ccgdm->faceMap[index];
} else {
return ccgSubSurf_getFaceFaceHandle(ccgdm->ss, f);
}
static int ccgDM_getFaceMapIndex(CCGDerivedMesh *ccgdm, CCGSubSurf *ss, CCGFace *f) {
return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1];
}
static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
@ -792,20 +847,22 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
}
ccgFaceIterator_free(fi);
}
static void ccgDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData) {
static void ccgDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
CCGVert *v = ccgVertIterator_getCurrent(vi);
VertData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
int index = ccgDM_getVertMapIndex(ccgdm, ccgdm->ss, v);
func(userData, ccgDM_getVertHandle(ccgdm, v), vd->co, vd->no, NULL);
if (index!=-1)
func(userData, index, vd->co, vd->no, NULL);
}
ccgVertIterator_free(vi);
}
static void ccgDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData) {
static void ccgDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
@ -813,11 +870,13 @@ static void ccgDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userDa
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e);
VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
for (i=0; i<edgeSize-1; i++)
func(userData, edge, edgeData[i].co, edgeData[i+1].co);
if (index!=-1) {
for (i=0; i<edgeSize-1; i++)
func(userData, index, edgeData[i].co, edgeData[i+1].co);
}
}
ccgEdgeIterator_free(ei);
@ -825,12 +884,7 @@ static void ccgDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userDa
static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm, int allowShared) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm, NULL, NULL, NULL);
}
static DispListMesh *ccgDM_convertToDispListMeshMapped(DerivedMesh *dm, int allowShared, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm, vertMap_r, edgeMap_r, faceMap_r);
return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, ccgdm->drawInteriorEdges, ccgdm->me, ccgdm->dlm);
}
static void ccgDM_drawVerts(DerivedMesh *dm) {
@ -892,11 +946,6 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
if (ccgdm->fromEditmesh) {
EditEdge *eed = ccgDM_getEdgeHandle(ccgdm, e);
if (eed && eed->h!=0)
continue;
}
if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(ss, e))
continue;
@ -922,12 +971,6 @@ static void ccgDM_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
if (ccgdm->fromEditmesh) {
EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
if (efa && efa->h!=0)
continue;
}
for (S=0; S<numVerts; S++) {
VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
@ -970,7 +1013,7 @@ static void ccgDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
unsigned int flags = ss_getEdgeFlags(ss, e, ccgdm->fromEditmesh, medge, tface);
unsigned int flags = ss_getEdgeFlags(ss, e, ccgdm->fromEditmesh, ccgdm->dlm, medge, tface);
if ((flags&mask)==value) {
glBegin(GL_LINE_STRIP);
@ -984,39 +1027,29 @@ static void ccgDM_drawEdgesFlag(DerivedMesh *dm, unsigned int mask, unsigned int
ccgEdgeIterator_free(ei);
}
/* Only used by non-editmesh types */
static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
MFace *mface = ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface;
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
unsigned char flag,mat_nr;
if (ccgdm->fromEditmesh || ccgdm->vertMap) {
EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
if (efa && efa->h!=0)
continue;
flag = efa->flag;
mat_nr = efa->mat_nr;
} else {
int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
MFace *mf = (ccgdm->dlm?ccgdm->dlm->mface:ccgdm->me->mface) + index;
flag = mf->flag;
mat_nr = mf->mat_nr;
}
if (!setMaterial(mat_nr+1))
int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
MFace *mf = &mface[index];
if (!setMaterial(mf->mat_nr+1))
continue;
glShadeModel((flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT);
glShadeModel((mf->flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT);
for (S=0; S<numVerts; S++) {
VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
if (flag&ME_SMOOTH) {
if (mf->flag&ME_SMOOTH) {
for (y=0; y<gridSize-1; y++) {
glBegin(GL_QUAD_STRIP);
for (x=0; x<gridSize; x++) {
@ -1159,10 +1192,10 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
for (y=0; y<gridSize-1; y++) {
for (x=0; x<gridSize-1; x++) {
VertData *a = &faceGridData[(y+0)*gridSize + x];
VertData *a = &faceGridData[(y+0)*gridSize + x + 0];
VertData *b = &faceGridData[(y+0)*gridSize + x + 1];
VertData *c = &faceGridData[(y+1)*gridSize + x + 1];
VertData *d = &faceGridData[(y+1)*gridSize + x];
VertData *d = &faceGridData[(y+1)*gridSize + x + 0];
if (!(mf->flag&ME_SMOOTH)) {
float a_cX = c->co[0]-a->co[0], a_cY = c->co[1]-a->co[1], a_cZ = c->co[2]-a->co[2];
@ -1243,8 +1276,68 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
}
*/
}
static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int i, gridSize = ccgSubSurf_getGridSize(ss);
static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) {
for (i=0; !ccgFaceIterator_isStopped(fi); i++,ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
int drawSmooth = 1, index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index, &drawSmooth))) {
for (S=0; S<numVerts; S++) {
VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
if (drawSmooth) {
glShadeModel(GL_SMOOTH);
for (y=0; y<gridSize-1; y++) {
glBegin(GL_QUAD_STRIP);
for (x=0; x<gridSize; x++) {
VertData *a = &faceGridData[(y+0)*gridSize + x];
VertData *b = &faceGridData[(y+1)*gridSize + x];
glNormal3fv(a->no);
glVertex3fv(a->co);
glNormal3fv(b->no);
glVertex3fv(b->co);
}
glEnd();
}
} else {
glShadeModel(GL_FLAT);
glBegin(GL_QUADS);
for (y=0; y<gridSize-1; y++) {
for (x=0; x<gridSize-1; x++) {
float *a = faceGridData[(y+0)*gridSize + x].co;
float *b = faceGridData[(y+0)*gridSize + x + 1].co;
float *c = faceGridData[(y+1)*gridSize + x + 1].co;
float *d = faceGridData[(y+1)*gridSize + x].co;
float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
float no[3];
no[0] = b_dY*a_cZ - b_dZ*a_cY;
no[1] = b_dZ*a_cX - b_dX*a_cZ;
no[2] = b_dX*a_cY - b_dY*a_cX;
glNormal3fv(no);
glVertex3fv(d);
glVertex3fv(c);
glVertex3fv(b);
glVertex3fv(a);
}
}
glEnd();
}
}
}
}
ccgFaceIterator_free(fi);
}
static void ccgDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
@ -1254,11 +1347,11 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e);
VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
glBegin(GL_LINE_STRIP);
if (edge && (!setDrawOptions || setDrawOptions(userData, edge))) {
if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
if (useAging && !(G.f&G_BACKBUFSEL)) {
int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0);
@ -1274,7 +1367,7 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void
ccgEdgeIterator_free(ei);
}
static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void (*setDrawInterpOptions)(void *userData, EditEdge *edge, float t), void *userData) {
static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
@ -1284,13 +1377,13 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)
for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e);
VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
int index = ccgDM_getEdgeMapIndex(ccgdm, ss, e);
glBegin(GL_LINE_STRIP);
if (edge && (!setDrawOptions || setDrawOptions(userData, edge))) {
if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
for (i=0; i<edgeSize; i++) {
setDrawInterpOptions(userData, edge, (float) i/(edgeSize-1));
setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
if (useAging && !(G.f&G_BACKBUFSEL)) {
int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
@ -1302,50 +1395,23 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)
}
glEnd();
}
ccgEdgeIterator_free(ei);
}
static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
int gridSize = ccgSubSurf_getGridSize(ss);
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
if (efa && (!setDrawOptions || setDrawOptions(userData, efa))) {
int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
for (S=0; S<numVerts; S++) {
VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
for (y=0; y<gridSize-1; y++) {
glBegin(GL_QUAD_STRIP);
for (x=0; x<gridSize; x++) {
glVertex3fv(faceGridData[(y+0)*gridSize + x].co);
glVertex3fv(faceGridData[(y+1)*gridSize + x].co);
}
glEnd();
}
}
}
}
ccgFaceIterator_free(fi);
}
static void ccgDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData) {
static void ccgDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
CCGFace *f = ccgFaceIterator_getCurrent(fi);
EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
int index = ccgDM_getFaceMapIndex(ccgdm, ss, f);
if (efa) {
if (index!=-1) {
/* Face center data normal isn't updated atm. */
VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
func(userData, efa, vd->co, vd->no);
func(userData, index, vd->co, vd->no);
}
}
@ -1356,39 +1422,33 @@ static void ccgDM_release(DerivedMesh *dm) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
if (ccgdm->dlm) displistmesh_free(ccgdm->dlm);
if (ccgdm->vertMap) {
MEM_freeN(ccgdm->vertMap);
MEM_freeN(ccgdm->edgeMap);
MEM_freeN(ccgdm->faceMap);
}
MEM_freeN(ccgdm);
}
static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int drawInteriorEdges, Mesh *me, DispListMesh *dlm, EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) {
static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int drawInteriorEdges, Mesh *me, DispListMesh *dlm) {
CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
ccgdm->dm.getMinMax = ccgDM_getMinMax;
ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
ccgdm->dm.getVertCos = ccgdm_getVertCos;
ccgdm->dm.foreachMappedVertEM = ccgDM_foreachMappedVertEM;
ccgdm->dm.foreachMappedEdgeEM = ccgDM_foreachMappedEdgeEM;
ccgdm->dm.foreachMappedFaceCenterEM = ccgDM_foreachMappedFaceCenterEM;
ccgdm->dm.foreachMappedVert = ccgDM_foreachMappedVert;
ccgdm->dm.foreachMappedEdge = ccgDM_foreachMappedEdge;
ccgdm->dm.foreachMappedFaceCenter = ccgDM_foreachMappedFaceCenter;
ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh;
ccgdm->dm.convertToDispListMeshMapped = ccgDM_convertToDispListMeshMapped;
ccgdm->dm.drawVerts = ccgDM_drawVerts;
ccgdm->dm.drawEdges = ccgDM_drawEdges;
ccgdm->dm.drawEdgesFlag = ccgDM_drawEdgesFlag;
ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
ccgdm->dm.drawMappedEdgesInterpEM = ccgDM_drawMappedEdgesInterpEM;
ccgdm->dm.drawMappedEdgesEM = ccgDM_drawMappedEdgesEM;
ccgdm->dm.drawMappedFacesEM = ccgDM_drawMappedFacesEM;
ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
ccgdm->dm.release = ccgDM_release;
ccgdm->ss = ss;
@ -1396,9 +1456,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int d
ccgdm->drawInteriorEdges = drawInteriorEdges;
ccgdm->me = me;
ccgdm->dlm = dlm;
ccgdm->vertMap = vertMap;
ccgdm->edgeMap = edgeMap;
ccgdm->faceMap = faceMap;
return ccgdm;
}
@ -1413,10 +1470,10 @@ DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierDat
smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, 0, useSimple);
ss_sync_from_editmesh(smd->emCache, em, vertCos, useSimple);
return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, drawInteriorEdges, NULL, NULL, NULL, NULL, NULL);
return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, drawInteriorEdges, NULL, NULL);
}
DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) {
DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3]) {
int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
int drawInteriorEdges = !(smd->flags&eSubsurfModifierFlag_ControlEdges);
@ -1425,7 +1482,7 @@ DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifier
ss_sync_from_mesh(smd->emCache, NULL, dlm, vertCos, useSimple);
return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, drawInteriorEdges, NULL, dlm, vertMap, edgeMap, faceMap);
return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, drawInteriorEdges, NULL, dlm);
}
DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) {
@ -1439,12 +1496,12 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf
ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm, NULL, NULL, NULL);
ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm);
if (dlm) displistmesh_free(dlm);
ccgSubSurf_free(ss);
return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
return derivedmesh_from_displistmesh(ndlm, NULL);
} else {
int useEdgeCreation = !(dlm?dlm->medge:me->medge);
int useIncremental = (smd->flags&eSubsurfModifierFlag_Incremental) && !useEdgeCreation;
@ -1469,7 +1526,7 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf
ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
return (DerivedMesh*) getCCGDerivedMesh(ss, 0, drawInteriorEdges, me, dlm, NULL, NULL, NULL);
return (DerivedMesh*) getCCGDerivedMesh(ss, 0, drawInteriorEdges, me, dlm);
} else {
if (smd->mCache && isFinalCalc) {
ccgSubSurf_free(smd->mCache);
@ -1479,12 +1536,12 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf
ss = _getSubSurf(NULL, smd->levels, 0, 1, useEdgeCreation, useSimple);
ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm, NULL, NULL, NULL);
ndlm = ss_to_displistmesh(ss, NULL, 0, drawInteriorEdges, me, dlm);
if (dlm) displistmesh_free(dlm);
ccgSubSurf_free(ss);
return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
return derivedmesh_from_displistmesh(ndlm, NULL);
}
}
}

View File

@ -91,6 +91,13 @@ extern void flip_editnormals(void);
/* ******************* editmesh_mods.c */
extern void EM_init_index_arrays(int forVert, int forEdge, int forFace);
extern void EM_free_index_arrays(void);
extern struct EditVert *EM_get_vert_for_index(int index);
extern struct EditEdge *EM_get_edge_for_index(int index);
extern struct EditFace *EM_get_face_for_index(int index);
extern void EM_select_face_fgon(struct EditFace *efa, int sel);
extern int EM_init_backbuf_border(short xmin, short ymin, short xmax, short ymax);

View File

@ -75,6 +75,7 @@ typedef struct MSticky {
#define ME_SPHERETEST 2
#define ME_SPHERETEMP 4
#define ME_HIDE 16
#define ME_VERT_STEPINDEX (1<<7)
/* medge->flag (1=SELECT)*/
#define ME_EDGEDRAW (1<<1)
@ -89,6 +90,7 @@ typedef struct MSticky {
#define ME_EDGE_TFVISIBLE (1<<10)
#define ME_EDGE_TFACTFIRST (1<<11)
#define ME_EDGE_TFACTLAST (1<<12)
#define ME_EDGE_STEPINDEX (1<<15)
/* puno = vertexnormal (mface) */
#define ME_FLIPV1 1
@ -107,9 +109,9 @@ typedef struct MSticky {
#define ME_V4V1 8
/* flag (mface) */
#define ME_SMOOTH 1
#define ME_FACE_SEL 2
/* flag ME_HIDE is used here too */
#define ME_SMOOTH 1
#define ME_FACE_SEL 2
/* flag ME_HIDE==16 is used here too */
#define ME_FACE_STEPINDEX (1<<7)
#endif

View File

@ -2612,9 +2612,9 @@ static void mface_from_data( MFace * mf, TFace * tf, MCol * col,
return;
}
test_index_face( mf, tf, i );
test_index_face(mf, NULL, tf, i );
} else {
test_index_mface( mf, i );
test_index_face(mf, NULL, NULL, i );
}
mf->mat_nr = from->mat_nr;

View File

@ -981,7 +981,7 @@ void rad_addmesh(void)
if(face->v4) mface->v4= *((unsigned int *)face->v4+3);
mface->edcode= 3;
test_index_mface(mface, face->v4 ? 4 : 3);
test_index_face(mface, NULL, NULL, face->v4 ? 4 : 3);
mface->mat_nr= face->matindex;
if (face->tface) {

View File

@ -772,9 +772,9 @@ ConvertCSGDescriptorsToMeshObject(
((((unsigned int)floor(color[3] + 0.5f)) & 0xff) << 0);
}
test_index_face(mface, tface, 3);
test_index_face(mface, NULL, tface, 3);
} else {
test_index_mface(mface, 3);
test_index_face(mface, NULL, NULL, 3);
}
fi_insert_pos++;

View File

@ -2434,6 +2434,7 @@ void do_meshbuts(unsigned short event)
me->totedge= 1;
}
else make_edges(me);
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWBUTSEDIT, 0);
break;
case B_DELEDGES:
@ -2475,11 +2476,6 @@ void do_meshbuts(unsigned short event)
if(G.obedit) {
flip_editnormals();
}
else {
flipnorm_mesh( get_mesh(ob) );
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
allqueue(REDRAWVIEW3D, 0);
break;

View File

@ -185,7 +185,7 @@ void image_changed(SpaceImage *sima, int dotile)
if(sima->mode==SI_TEXTURE) {
if(G.f & G_FACESELECT) {
me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0);
me= get_mesh(OBACT);
if(me && me->tface) {
tface= me->tface;
a= me->totface;
@ -211,7 +211,8 @@ void image_changed(SpaceImage *sima, int dotile)
}
tface++;
}
allqueue(REDRAWVIEW3D, 0);
object_uvs_changed(OBACT);
allqueue(REDRAWBUTSEDIT, 0);
}
}

View File

@ -896,9 +896,10 @@ static void drawlattice(Object *ob)
/* ***************** ******************** */
static void mesh_foreachScreenVert__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s)
static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float mat[4][4]; } *data = userData;
EditVert *eve = EM_get_vert_for_index(index);
short s[2];
if (eve->h==0) {
@ -908,7 +909,7 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, EditVert *eve, float
view3d_project_short_noclip(curarea, co, s, data->mat);
}
data->func(data->userData, eve, s[0], s[1], (int) eve->prev);
data->func(data->userData, eve, s[0], s[1], index);
}
}
void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
@ -916,8 +917,6 @@ void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, i
struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; float mat[4][4]; } data;
int dmNeedsFree;
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
EditVert *eve, *preveve;
int index;
data.func = func;
data.userData = userData;
@ -925,22 +924,19 @@ void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, i
view3d_get_object_project_mat(curarea, G.obedit, data.mat);
for (index=0,eve=G.editMesh->verts.first; eve; index++,eve= eve->next)
eve->prev = (EditVert*) index;
dm->foreachMappedVertEM(dm, mesh_foreachScreenVert__mapFunc, &data);
for (preveve=NULL, eve=G.editMesh->verts.first; eve; preveve=eve, eve= eve->next)
eve->prev = preveve;
EM_init_index_arrays(1, 0, 0);
dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);
EM_free_index_arrays();
if (dmNeedsFree) {
dm->release(dm);
}
}
static void mesh_foreachScreenEdge__mapFunc(void *userData, EditEdge *eed, float *v0co, float *v1co)
static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co)
{
struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float mat[4][4]; } *data = userData;
EditEdge *eed = EM_get_edge_for_index(index);
short s[2][2];
if (eed->h==0) {
@ -958,7 +954,7 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, EditEdge *eed, float
}
}
data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], (int) eed->prev);
data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], index);
}
}
void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
@ -966,8 +962,6 @@ void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0,
struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; float mat[4][4]; } data;
int dmNeedsFree;
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
EditEdge *eed, *preveed;
int index;
data.func = func;
data.userData = userData;
@ -975,28 +969,25 @@ void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0,
view3d_get_object_project_mat(curarea, G.obedit, data.mat);
for (index=0,eed=G.editMesh->edges.first; eed; index++,eed= eed->next)
eed->prev = (EditEdge*) index;
dm->foreachMappedEdgeEM(dm, mesh_foreachScreenEdge__mapFunc, &data);
for (preveed=NULL, eed=G.editMesh->edges.first; eed; preveed=eed, eed= eed->next)
eed->prev = preveed;
EM_init_index_arrays(0, 1, 0);
dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);
EM_free_index_arrays();
if (dmNeedsFree) {
dm->release(dm);
}
}
static void mesh_foreachScreenFace__mapFunc(void *userData, EditFace *efa, float *cent, float *no)
static void mesh_foreachScreenFace__mapFunc(void *userData, int index, float *cent, float *no)
{
struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float mat[4][4]; } *data = userData;
EditFace *efa = EM_get_face_for_index(index);
short s[2];
if (efa && efa->fgonf!=EM_FGON) {
if (efa && efa->h==0 && efa->fgonf!=EM_FGON) {
view3d_project_short(curarea, cent, s, data->mat);
data->func(data->userData, efa, s[0], s[1], (int) efa->prev);
data->func(data->userData, efa, s[0], s[1], index);
}
}
void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData)
@ -1004,21 +995,15 @@ void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, i
struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; float mat[4][4]; } data;
int dmNeedsFree;
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
EditFace *efa, *prevefa;
int index = 0;
data.func = func;
data.userData = userData;
view3d_get_object_project_mat(curarea, G.obedit, data.mat);
for (index=0,efa=G.editMesh->faces.first; efa; index++,efa= efa->next)
efa->prev = (EditFace*) index;
dm->foreachMappedFaceCenterEM(dm, mesh_foreachScreenFace__mapFunc, &data);
for (prevefa=NULL, efa=G.editMesh->faces.first; efa; prevefa=efa, efa= efa->next)
efa->prev = prevefa;
EM_init_index_arrays(0, 0, 1);
dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);
EM_free_index_arrays();
if (dmNeedsFree) {
dm->release(dm);
@ -1118,8 +1103,10 @@ static unsigned char *calc_weightpaint_colors(Object *ob)
* logic!!!
*/
static void draw_dm_face_normals__mapFunc(void *userData, EditFace *efa, float *cent, float *no)
static void draw_dm_face_normals__mapFunc(void *userData, int index, float *cent, float *no)
{
EditFace *efa = EM_get_face_for_index(index);
if (efa->h==0 && efa->fgonf!=EM_FGON) {
glVertex3fv(cent);
glVertex3f( cent[0] + no[0]*G.scene->editbutsize,
@ -1129,12 +1116,13 @@ static void draw_dm_face_normals__mapFunc(void *userData, EditFace *efa, float *
}
static void draw_dm_face_normals(DerivedMesh *dm) {
glBegin(GL_LINES);
dm->foreachMappedFaceCenterEM(dm, draw_dm_face_normals__mapFunc, 0);
dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, 0);
glEnd();
}
static void draw_dm_face_centers__mapFunc(void *userData, EditFace *efa, float *cent, float *no)
static void draw_dm_face_centers__mapFunc(void *userData, int index, float *cent, float *no)
{
EditFace *efa = EM_get_face_for_index(index);
int sel = *((int*) userData);
if (efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel) {
@ -1144,12 +1132,14 @@ static void draw_dm_face_centers__mapFunc(void *userData, EditFace *efa, float *
static void draw_dm_face_centers(DerivedMesh *dm, int sel)
{
bglBegin(GL_POINTS);
dm->foreachMappedFaceCenterEM(dm, draw_dm_face_centers__mapFunc, &sel);
dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, &sel);
bglEnd();
}
static void draw_dm_vert_normals__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s)
static void draw_dm_vert_normals__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
EditVert *eve = EM_get_vert_for_index(index);
if (eve->h==0) {
glVertex3fv(co);
@ -1166,13 +1156,14 @@ static void draw_dm_vert_normals__mapFunc(void *userData, EditVert *eve, float *
}
static void draw_dm_vert_normals(DerivedMesh *dm) {
glBegin(GL_LINES);
dm->foreachMappedVertEM(dm, draw_dm_vert_normals__mapFunc, NULL);
dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, NULL);
glEnd();
}
/* Draw verts with color set based on selection */
static void draw_dm_verts__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s)
static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
EditVert *eve = EM_get_vert_for_index(index);
int sel = *((int*) userData);
if (eve->h==0 && (eve->f&SELECT)==sel) {
@ -1182,13 +1173,14 @@ static void draw_dm_verts__mapFunc(void *userData, EditVert *eve, float *co, flo
static void draw_dm_verts(DerivedMesh *dm, int sel)
{
bglBegin(GL_POINTS);
dm->foreachMappedVertEM(dm, draw_dm_verts__mapFunc, &sel);
dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &sel);
bglEnd();
}
/* Draw edges with color set based on selection */
static int draw_dm_edges_sel__setDrawOptions(void *userData, EditEdge *eed)
static int draw_dm_edges_sel__setDrawOptions(void *userData, int index)
{
EditEdge *eed = EM_get_edge_for_index(index);
unsigned char **cols = userData;
if (eed->h==0) {
@ -1203,26 +1195,27 @@ static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned
unsigned char *cols[2];
cols[0] = baseCol;
cols[1] = selCol;
dm->drawMappedEdgesEM(dm, draw_dm_edges_sel__setDrawOptions, cols);
dm->drawMappedEdges(dm, draw_dm_edges_sel__setDrawOptions, cols);
}
/* Draw edges */
static int draw_dm_edges__setDrawOptions(void *userData, EditEdge *eed)
static int draw_dm_edges__setDrawOptions(void *userData, int index)
{
return eed->h==0;
return EM_get_edge_for_index(index)->h==0;
}
static void draw_dm_edges(DerivedMesh *dm)
{
dm->drawMappedEdgesEM(dm, draw_dm_edges__setDrawOptions, NULL);
dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, NULL);
}
/* Draw edges with color interpolated based on selection */
static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, EditEdge *eed)
static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, int index)
{
return (eed->h==0);
return EM_get_edge_for_index(index)->h==0;
}
static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, EditEdge *eed, float t)
static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int index, float t)
{
EditEdge *eed = EM_get_edge_for_index(index);
unsigned char **cols = userData;
unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0];
unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0];
@ -1237,26 +1230,30 @@ static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, un
unsigned char *cols[2];
cols[0] = baseCol;
cols[1] = selCol;
dm->drawMappedEdgesInterpEM(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
}
/* Draw only seam edges */
static int draw_dm_edges_seams__setDrawOptions(void *userData, EditEdge *eed)
static int draw_dm_edges_seams__setDrawOptions(void *userData, int index)
{
EditEdge *eed = EM_get_edge_for_index(index);
return (eed->h==0 && eed->seam);
}
static void draw_dm_edges_seams(DerivedMesh *dm)
{
dm->drawMappedEdgesEM(dm, draw_dm_edges_seams__setDrawOptions, NULL);
dm->drawMappedEdges(dm, draw_dm_edges_seams__setDrawOptions, NULL);
}
/* Draw faces with color set based on selection */
static int draw_dm_faces_sel__setDrawOptions(void *userData, EditFace *efa)
static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *drawSmooth_r)
{
EditFace *efa = EM_get_face_for_index(index);
unsigned char **cols = userData;
if (efa->h==0) {
glColor4ubv(cols[(efa->f&SELECT)?1:0]);
*drawSmooth_r = (efa->flag&ME_SMOOTH);
return 1;
} else {
return 0;
@ -1267,11 +1264,13 @@ static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned
unsigned char *cols[2];
cols[0] = baseCol;
cols[1] = selCol;
dm->drawMappedFacesEM(dm, draw_dm_faces_sel__setDrawOptions, cols);
dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, cols);
}
static int draw_dm_creases__setDrawOptions(void *userData, EditEdge *eed)
static int draw_dm_creases__setDrawOptions(void *userData, int index)
{
EditEdge *eed = EM_get_edge_for_index(index);
if (eed->h==0 && eed->crease!=0.0) {
BIF_ThemeColorShade((eed->f&SELECT)?TH_EDGE_SELECT:TH_WIRE, 120*eed->crease);
return 1;
@ -1279,11 +1278,10 @@ static int draw_dm_creases__setDrawOptions(void *userData, EditEdge *eed)
return 0;
}
}
static void draw_dm_creases(DerivedMesh *dm)
{
glLineWidth(3.0);
dm->drawMappedEdgesEM(dm, draw_dm_creases__setDrawOptions, NULL);
dm->drawMappedEdges(dm, draw_dm_creases__setDrawOptions, NULL);
glLineWidth(1.0);
}
@ -1382,7 +1380,7 @@ static void draw_em_fancy_edges(DerivedMesh *cageDM)
draw_dm_edges_sel(cageDM, wire, sel);
}
else if( (G.f & G_DRAWEDGES) || (G.scene->selectmode & SCE_SELECT_EDGE) ) {
if(cageDM->drawMappedEdgesInterpEM && (G.scene->selectmode & SCE_SELECT_VERTEX)) {
if(cageDM->drawMappedEdgesInterp && (G.scene->selectmode & SCE_SELECT_VERTEX)) {
glShadeModel(GL_SMOOTH);
draw_dm_edges_sel_interp(cageDM, wire, sel);
glShadeModel(GL_FLAT);
@ -1552,17 +1550,31 @@ static void draw_em_measure_stats(Object *ob, EditMesh *em)
}
}
static int draw_em_fancy__setFaceOpts(void *userData, int index, int *drawSmooth_r)
{
EditFace *efa = EM_get_face_for_index(index);
if (efa->h==0) {
set_gl_material(efa->mat_nr);
*drawSmooth_r = efa->flag&ME_SMOOTH;
return 1;
} else {
return 0;
}
}
static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
{
Mesh *me = ob->data;
EM_init_index_arrays(1, 1, 1);
if(dt>OB_WIRE) {
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
glEnable(GL_LIGHTING);
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
finalDM->drawFacesSolid(finalDM, set_gl_material);
finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, NULL);
glFrontFace(GL_CCW);
glDisable(GL_LIGHTING);
@ -1635,6 +1647,8 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived
glDepthMask(1);
bglPolygonOffset(0.0);
}
EM_free_index_arrays();
}
/* Mesh drawing routines */
@ -1729,7 +1743,7 @@ static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, in
else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->tface) {
tface_to_mcol(me);
baseDM->drawFacesColored(baseDM, me->flag&ME_TWOSIDED, (unsigned char*) me->mcol, 0);
MEM_freeN(me->mcol);
MEM_freeN(me->mcol);
me->mcol= 0;
}
else {
@ -3756,36 +3770,34 @@ void draw_object_ext(Base *base)
/* ***************** BACKBUF SEL (BBS) ********* */
static void bbs_mesh_verts__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s)
static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
{
int offset = (int) userData;
EditVert *eve = EM_get_vert_for_index(index);
if (eve->h==0) {
set_framebuffer_index_color((int) eve->prev);
set_framebuffer_index_color(offset+index);
bglVertex3fv(co);
}
}
static int bbs_mesh_verts(DerivedMesh *dm, int offset)
{
EditVert *eve, *preveve;
for (eve=G.editMesh->verts.first; eve; eve= eve->next)
eve->prev = (EditVert*) offset++;
glPointSize( BIF_GetThemeValuef(TH_VERTEX_SIZE) );
bglBegin(GL_POINTS);
dm->foreachMappedVertEM(dm, bbs_mesh_verts__mapFunc, NULL);
dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, (void*) offset);
bglEnd();
glPointSize(1.0);
for (preveve=NULL, eve=G.editMesh->verts.first; eve; preveve=eve, eve= eve->next)
eve->prev = preveve;
return offset;
return offset + G.totvert; // XXX is G variable reliable?
}
static int bbs_mesh_wire__setDrawOptions(void *userData, EditEdge *eed)
static int bbs_mesh_wire__setDrawOptions(void *userData, int index)
{
int offset = (int) userData;
EditEdge *eed = EM_get_edge_for_index(index);
if (eed->h==0) {
set_framebuffer_index_color((int) eed->vn);
set_framebuffer_index_color(offset+index);
return 1;
} else {
return 0;
@ -3793,21 +3805,16 @@ static int bbs_mesh_wire__setDrawOptions(void *userData, EditEdge *eed)
}
static int bbs_mesh_wire(DerivedMesh *dm, int offset)
{
EditEdge *eed;
dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, (void*) offset);
for(eed= G.editMesh->edges.first; eed; eed= eed->next)
eed->vn= (EditVert*) offset++;
dm->drawMappedEdgesEM(dm, bbs_mesh_wire__setDrawOptions, NULL);
return offset;
return offset + G.totedge; // XXX is G variable reliable?
}
static int bbs_mesh_solid__setSolidDrawOptions(void *userData, EditFace *efa)
static int bbs_mesh_solid__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
{
if (efa->h==0) {
if (EM_get_face_for_index(index)->h==0) {
if (userData) {
set_framebuffer_index_color((int) efa->prev);
set_framebuffer_index_color(index+1);
}
return 1;
} else {
@ -3815,10 +3822,12 @@ static int bbs_mesh_solid__setSolidDrawOptions(void *userData, EditFace *efa)
}
}
static void bbs_mesh_solid__drawCenter(void *userData, EditFace *efa, float *cent, float *no)
static void bbs_mesh_solid__drawCenter(void *userData, int index, float *cent, float *no)
{
EditFace *efa = EM_get_face_for_index(index);
if (efa->h==0 && efa->fgonf!=EM_FGON) {
set_framebuffer_index_color((int) efa->prev);
set_framebuffer_index_color(index+1);
bglVertex3fv(cent);
}
@ -3830,64 +3839,43 @@ static int bbs_mesh_solid_EM(DerivedMesh *dm, int facecol)
cpack(0);
if (facecol) {
EditFace *efa, *prevefa;
int a, b;
// tuck original indices in efa->prev
for(b=1, efa= G.editMesh->faces.first; efa; efa= efa->next, b++)
efa->prev= (EditFace *)(b);
a = b;
dm->drawMappedFacesEM(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 1);
dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 1);
if(G.scene->selectmode & SCE_SELECT_FACE) {
glPointSize(BIF_GetThemeValuef(TH_FACEDOT_SIZE));
bglBegin(GL_POINTS);
dm->foreachMappedFaceCenterEM(dm, bbs_mesh_solid__drawCenter, NULL);
dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, NULL);
bglEnd();
}
for (prevefa= NULL, efa= G.editMesh->faces.first; efa; prevefa= efa, efa= efa->next)
efa->prev= prevefa;
return a;
return 1+G.totface;
} else {
dm->drawMappedFacesEM(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 0);
dm->drawMappedFaces(dm, bbs_mesh_solid__setSolidDrawOptions, (void*) 0);
return 1;
}
}
static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmooth_r)
{
Mesh *me = userData;
MFace *mf = &me->mface[index];
if (!me->tface || !(me->tface[index].flag&TF_HIDE)) {
set_framebuffer_index_color(index+1);
return 1;
} else {
return 0;
}
}
static void bbs_mesh_solid(Object *ob)
{
Mesh *me= ob->data;
MFace *mface= me->mface;
TFace *tface= me->tface;
float co[3];
int a, glmode, dmNeedsFree;
DerivedMesh *dm = mesh_get_derived_deform(ob, &dmNeedsFree);
int dmNeedsFree;
DerivedMesh *dm = mesh_get_derived_final(ob, &dmNeedsFree);
glColor3ub(0, 0, 0);
glBegin(glmode=GL_QUADS);
for(a=0; a<me->totface; a++, mface++, tface++) {
if(mface->v3 && (!me->tface || !(tface->flag&TF_HIDE))) {
int newmode = mface->v4?GL_QUADS:GL_TRIANGLES;
set_framebuffer_index_color(a+1);
if (newmode!=glmode) {
glEnd();
glBegin(glmode=newmode);
}
glVertex3fv( (dm->getVertCo(dm, mface->v1, co),co) );
glVertex3fv( (dm->getVertCo(dm, mface->v2, co),co) );
glVertex3fv( (dm->getVertCo(dm, mface->v3, co),co) );
if(mface->v4) glVertex3fv( (dm->getVertCo(dm, mface->v4, co),co) );
}
}
glEnd();
dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, ob->data);
if (dmNeedsFree) {
dm->release(dm);
}
@ -3907,6 +3895,8 @@ void draw_object_backbufsel(Object *ob)
int dmNeedsFree;
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
EM_init_index_arrays(1, 1, 1);
em_solidoffs= bbs_mesh_solid_EM(dm, G.scene->selectmode & SCE_SELECT_FACE);
bglPolygonOffset(1.0);
@ -3923,6 +3913,8 @@ void draw_object_backbufsel(Object *ob)
if (dmNeedsFree) {
dm->release(dm);
}
EM_free_index_arrays();
}
else bbs_mesh_solid(ob);

View File

@ -344,9 +344,11 @@ int get_border(rcti *rect, short col)
if (G.obedit) {
if ELEM4(G.obedit->type, OB_MESH, OB_CURVE, OB_SURF, OB_LATTICE) {
circle_selectCB(&obedit_selectionCB);
return 0;
}
}
else if (G.f&G_FACESELECT) {
circle_selectCB(&obedit_selectionCB);
}
return 0;
case SPACE_IMAGE: // brush select in UV editor

View File

@ -363,6 +363,7 @@ EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, Ed
if(example) {
efa->mat_nr= example->mat_nr;
efa->tf= example->tf;
efa->tf.flag &= ~TF_ACTIVE;
efa->flag= example->flag;
}
else {
@ -803,7 +804,7 @@ void make_editMesh()
}
if(mface->flag & ME_HIDE) efa->h= 1;
}
else {
else if (tface) {
if( tface->flag & TF_HIDE)
efa->h= 1;
else if( tface->flag & TF_SELECT) {
@ -841,96 +842,6 @@ void make_editMesh()
waitcursor(0);
}
/** Rotates MFace and UVFace vertices in case the last
* vertex index is = 0.
* This function is a hack and may only be called in the
* conversion from EditMesh to Mesh data.
* This function is similar to test_index_mface in
* blenkernel/intern/mesh.c.
* To not clutter the blenkernel code with more bad level
* calls/structures, this function resides here.
*/
static void fix_faceindices(MFace *mface, EditFace *efa, int nr)
{
int a;
float tmpuv[2];
unsigned int tmpcol;
/* first test if the face is legal */
if(mface->v3 && mface->v3==mface->v4) {
mface->v4= 0;
nr--;
}
if(mface->v2 && mface->v2==mface->v3) {
mface->v3= mface->v4;
mface->v4= 0;
nr--;
}
if(mface->v1==mface->v2) {
mface->v2= mface->v3;
mface->v3= mface->v4;
mface->v4= 0;
nr--;
}
/* prevent a zero index value at the wrong location */
if(nr==2) {
if(mface->v2==0) SWAP(int, mface->v1, mface->v2);
}
else if(nr==3) {
if(mface->v3==0) {
SWAP(int, mface->v1, mface->v2);
SWAP(int, mface->v2, mface->v3);
/* rotate face UV coordinates, too */
UVCOPY(tmpuv, efa->tf.uv[0]);
UVCOPY(efa->tf.uv[0], efa->tf.uv[1]);
UVCOPY(efa->tf.uv[1], efa->tf.uv[2]);
UVCOPY(efa->tf.uv[2], tmpuv);
/* same with vertex colours */
tmpcol = efa->tf.col[0];
efa->tf.col[0] = efa->tf.col[1];
efa->tf.col[1] = efa->tf.col[2];
efa->tf.col[2] = tmpcol;
a= mface->edcode;
mface->edcode= 0;
if(a & ME_V1V2) mface->edcode |= ME_V3V1;
if(a & ME_V2V3) mface->edcode |= ME_V1V2;
if(a & ME_V3V1) mface->edcode |= ME_V2V3;
}
}
else if(nr==4) {
if(mface->v3==0 || mface->v4==0) {
SWAP(int, mface->v1, mface->v3);
SWAP(int, mface->v2, mface->v4);
/* swap UV coordinates */
UVCOPY(tmpuv, efa->tf.uv[0]);
UVCOPY(efa->tf.uv[0], efa->tf.uv[2]);
UVCOPY(efa->tf.uv[2], tmpuv);
UVCOPY(tmpuv, efa->tf.uv[1]);
UVCOPY(efa->tf.uv[1], efa->tf.uv[3]);
UVCOPY(efa->tf.uv[3], tmpuv);
/* swap vertex colours */
tmpcol = efa->tf.col[0];
efa->tf.col[0] = efa->tf.col[2];
efa->tf.col[2] = tmpcol;
tmpcol = efa->tf.col[1];
efa->tf.col[1] = efa->tf.col[3];
efa->tf.col[3] = tmpcol;
a= mface->edcode;
mface->edcode= 0;
if(a & ME_V1V2) mface->edcode |= ME_V3V4;
if(a & ME_V2V3) mface->edcode |= ME_V2V3;
if(a & ME_V3V4) mface->edcode |= ME_V1V2;
if(a & ME_V4V1) mface->edcode |= ME_V4V1;
}
}
}
/* makes Mesh out of editmesh */
void load_editMesh(void)
{
@ -1117,8 +1028,7 @@ void load_editMesh(void)
/* no index '0' at location 3 or 4 */
if(efa->v4) fix_faceindices(mface, efa, 4);
else fix_faceindices(mface, efa, 3);
test_index_face(mface, NULL, &efa->tf, efa->v4?4:3);
i++;
efa= efa->next;
@ -1132,7 +1042,7 @@ void load_editMesh(void)
mface= &((MFace *) me->mface)[i];
mface->v1= (unsigned int) eed->v1->vn;
mface->v2= (unsigned int) eed->v2->vn;
test_index_mface(mface, 2);
test_index_face(mface, NULL, NULL, 2);
mface->edcode= ME_V1V2;
i++;
}
@ -1865,4 +1775,60 @@ void undo_push_mesh(char *name)
/* *************** END UNDO *************/
static EditVert **g_em_vert_array = NULL;
static EditEdge **g_em_edge_array = NULL;
static EditFace **g_em_face_array = NULL;
void EM_init_index_arrays(int forVert, int forEdge, int forFace)
{
EditVert *eve;
EditEdge *eed;
EditFace *efa;
int i;
if (forVert) {
g_em_vert_array = MEM_mallocN(sizeof(*g_em_vert_array)*G.totvert, "em_v_arr");
for (i=0,eve=G.editMesh->verts.first; eve; i++,eve=eve->next)
g_em_vert_array[i] = eve;
}
if (forEdge) {
g_em_edge_array = MEM_mallocN(sizeof(*g_em_edge_array)*G.totedge, "em_e_arr");
for (i=0,eed=G.editMesh->edges.first; eed; i++,eed=eed->next)
g_em_edge_array[i] = eed;
}
if (forFace) {
g_em_face_array = MEM_mallocN(sizeof(*g_em_face_array)*G.totface, "em_f_arr");
for (i=0,efa=G.editMesh->faces.first; efa; i++,efa=efa->next)
g_em_face_array[i] = efa;
}
}
void EM_free_index_arrays(void)
{
if (g_em_vert_array) MEM_freeN(g_em_vert_array);
if (g_em_edge_array) MEM_freeN(g_em_edge_array);
if (g_em_face_array) MEM_freeN(g_em_face_array);
g_em_vert_array = NULL;
g_em_edge_array = NULL;
g_em_face_array = NULL;
}
EditVert *EM_get_vert_for_index(int index)
{
return g_em_vert_array?g_em_vert_array[index]:NULL;
}
EditEdge *EM_get_edge_for_index(int index)
{
return g_em_edge_array?g_em_edge_array[index]:NULL;
}
EditFace *EM_get_face_for_index(int index)
{
return g_em_face_array?g_em_face_array[index]:NULL;
}

View File

@ -405,7 +405,12 @@ int EM_init_backbuf_circle(short xs, short ys, short rads)
short xmin, ymin, xmax, ymax, xc, yc;
int radsq;
if(G.obedit==NULL || G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0;
/* method in use for face selecting too */
if(G.obedit==NULL) {
if(G.f & G_FACESELECT);
else return 0;
}
else if(G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0;
if(em_vertoffs==0) return 0;
xmin= xs-rads; xmax= xs+rads;
@ -651,39 +656,45 @@ static EditFace *findnearestface(short *dist)
}
/* for interactivity, frontbuffer draw in current window */
static void draw_dm_mapped_vert__mapFunc(void *theVert, EditVert *eve, float *co, float *no_f, short *no_s)
static void draw_dm_mapped_vert__mapFunc(void *theVert, int index, float *co, float *no_f, short *no_s)
{
if (eve==theVert) {
if (EM_get_vert_for_index(index)==theVert) {
bglVertex3fv(co);
}
}
static void draw_dm_mapped_vert(DerivedMesh *dm, EditVert *eve)
{
EM_init_index_arrays(1, 0, 0);
bglBegin(GL_POINTS);
dm->foreachMappedVertEM(dm, draw_dm_mapped_vert__mapFunc, eve);
dm->foreachMappedVert(dm, draw_dm_mapped_vert__mapFunc, eve);
bglEnd();
EM_free_index_arrays();
}
static int draw_dm_mapped_edge__setDrawOptions(void *theEdge, EditEdge *eed)
static int draw_dm_mapped_edge__setDrawOptions(void *theEdge, int index)
{
return theEdge==eed;
return EM_get_edge_for_index(index)==theEdge;
}
static void draw_dm_mapped_edge(DerivedMesh *dm, EditEdge *eed)
{
dm->drawMappedEdgesEM(dm, draw_dm_mapped_edge__setDrawOptions, eed);
EM_init_index_arrays(0, 1, 0);
dm->drawMappedEdges(dm, draw_dm_mapped_edge__setDrawOptions, eed);
EM_free_index_arrays();
}
static void draw_dm_mapped_face_center__mapFunc(void *theFace, EditFace *efa, float *cent, float *no)
static void draw_dm_mapped_face_center__mapFunc(void *theFace, int index, float *cent, float *no)
{
if (efa==theFace) {
if (EM_get_face_for_index(index)==theFace) {
bglVertex3fv(cent);
}
}
static void draw_dm_mapped_face_center(DerivedMesh *dm, EditFace *efa)
{
EM_init_index_arrays(0, 0, 1);
bglBegin(GL_POINTS);
dm->foreachMappedFaceCenterEM(dm, draw_dm_mapped_face_center__mapFunc, efa);
dm->foreachMappedFaceCenter(dm, draw_dm_mapped_face_center__mapFunc, efa);
bglEnd();
EM_free_index_arrays();
}
static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)

View File

@ -1348,7 +1348,7 @@ static void facecopy(EditFace *source,EditFace *target)
}
target->mat_nr = source->mat_nr;
target->tf.flag = source->tf.flag;
target->tf.flag = source->tf.flag&~TF_ACTIVE;
target->tf.transp = source->tf.transp;
target->tf.mode = source->tf.mode;
target->tf.tile = source->tf.tile;

View File

@ -147,6 +147,20 @@ void EM_backbuf_checkAndSelectFaces(EditMesh *em, int select)
}
}
void EM_backbuf_checkAndSelectTFaces(Mesh *me, int select)
{
TFace *tface = me->tface;
int a;
if (tface) {
for(a=1; a<=me->totface; a++, tface++) {
if(EM_check_backbuf(a)) {
tface->flag = select?(tface->flag|TF_SELECT):(tface->flag&~TF_SELECT);
}
}
}
}
void arrows_move_cursor(unsigned short event)
{
short mval[2];
@ -502,30 +516,22 @@ static void do_lasso_select_armature(short mcords[][2], short moves, short selec
static void do_lasso_select_facemode(short mcords[][2], short moves, short select)
{
Mesh *me;
TFace *tface;
rcti rect;
int a;
me= get_mesh(OBACT);
if(me==NULL || me->tface==NULL) return;
if(me->totface==0) return;
tface= me->tface;
em_vertoffs= me->totface+1; // max index array
lasso_select_boundbox(&rect, mcords, moves);
EM_mask_init_backbuf_border(mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
for(a=1; a<=me->totface; a++, tface++) {
if(EM_check_backbuf(a)) {
tface->flag = select?(tface->flag|TF_SELECT):(tface->flag&~TF_SELECT);
}
}
EM_backbuf_checkAndSelectTFaces(me, select);
EM_free_backbuf();
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWIMAGE, 0);
object_tface_flags_changed(OBACT, 0);
}
static void do_lasso_select(short mcords[][2], short moves, short select)
@ -1728,7 +1734,23 @@ static void mesh_selectionCB(int selecting, Object *editobj, short *mval, float
struct { short select, mval[2]; float radius; } data;
EditMesh *em = G.editMesh;
int bbsel;
if(!G.obedit && (G.f&G_FACESELECT)) {
Mesh *me = get_mesh(OBACT);
if (me) {
em_vertoffs= me->totface+1; // max index array
bbsel= EM_init_backbuf_circle(mval[0], mval[1], (short)(rad+1.0));
EM_backbuf_checkAndSelectTFaces(me, selecting==LEFTMOUSE);
EM_free_backbuf();
object_tface_flags_changed(OBACT, 0);
}
return;
}
bbsel= EM_init_backbuf_circle(mval[0], mval[1], (short)(rad+1.0));
data.select = (selecting==LEFTMOUSE);

View File

@ -293,6 +293,8 @@ void vpaint_undo()
*from= temp;
to++; from++;
}
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
if(me->tface) mcol_to_tface(me, 1);
}
@ -325,6 +327,8 @@ void clear_vpaint()
to++;
}
BIF_undo_push("Clear vertex colors");
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
if(me->tface) mcol_to_tface(me, 1);
}
@ -1282,6 +1286,7 @@ void vertex_paint()
mcol_to_tface(me, 0);
}
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
scrarea_do_windraw(curarea);
if(Gvp.flag & (VP_AREA|VP_SOFT)) {