- convert all DerivedMesh map functions to use index based
authorDaniel Dunbar <daniel@zuster.org>
Sat, 20 Aug 2005 03:08:23 +0000 (03:08 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sat, 20 Aug 2005 03:08:23 +0000 (03:08 +0000)
   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).

25 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/BKE_subsurf.h
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/CCGSubSurf.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/exotic.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/include/BIF_editmesh.h
source/blender/makesdna/DNA_meshdata_types.h
source/blender/python/api2_2x/NMesh.c
source/blender/radiosity/intern/source/radpostprocess.c
source/blender/src/booleanops.c
source/blender/src/buttons_editing.c
source/blender/src/drawimage.c
source/blender/src/drawobject.c
source/blender/src/edit.c
source/blender/src/editmesh.c
source/blender/src/editmesh_mods.c
source/blender/src/editmesh_tools.c
source/blender/src/editview.c
source/blender/src/vpaint.c

index 99d438743fa5df7445ad52791a34f14bde4c5e02..9c0d87b02548d731b4ebe5b69f7616008a24d515 100644 (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);
index 7c28297194e77165a2efa1a3e95699e591ff15fe..f3d878d5341649a419cf9ee9544201d6896f6400 100644 (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);
index dbcc2dd3e17015100bb5abaf6ac14e567b18a7a3..2289fb027eb241547eec2d97aff7220dace35d98 100644 (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]);
index 2ed7d60e57e370962d0decfb4c86f8c2b9c400d0..75099157fd712752a557e257d906b0a6fbc0e950 100644 (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;
 }
 
index 547580bca6e33715c9a9a78770a6005e623a13a6..f6469866d32512d17f2d0218d5ec5fadc0a22208 100644 (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);
index eda5e3ff485b19f5f64732105ce403b9a7d01a58..d2d17c322de461bbc6cec9f863a8f73ed5c0b0b8 100644 (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]);
-                               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();
-                       }
-               }
+                       if(!setDrawOptions || setDrawOptions(userData, i, &drawSmooth)) {
+                               glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
 
-               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);
                        }
-               }
-       }
-}
-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();
-                               }
-                       }
+                       func(userData, index, cent, no);
                }
        }
 }
-
 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;
index 4ee8fc2640fa038d4c733a08456acffa61ffd87b..c2aa614dc714d369c75e44160443fcef21de67db 100644 (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;
 }
 
index 5ecbafa9e8029833558218293912c6e0e14886af..85b3b3a7954487f17061d89cba8137592669e7e2 100644 (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;
 }
index 2dea698db800099b652d18e5c97502252c1de226..e1c1f337bb6cad93f452b41189779ac6f8adb360 100644 (file)
@@ -488,25 +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) {
@@ -533,82 +520,19 @@ void test_index_mface(MFace *mface, int nr)
                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) {
-               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--;
-       }
+                       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]);
+                       }
 
-       /* 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);
-                       /* 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 (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; 
index 04e8b16c6bcb15f888f783a37b5d59ac4c15d5fd..a7b3f2b9bb6f083a59229418f44a1189285ace74 100644 (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;
-
-       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;
-       }
+       DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "mirror_dlm");
+       int (*indexMap)[2];
+
+       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");
+
+       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");
 
-       for (i=0; i<totvert; i++) {
-               MVert *mv = &ndlm->mvert[i];
-               int isShared = ABS(mv->co[axis])<=tolerance;
+       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 stuff the same
+                               /* 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];
-
-                       memcpy(nmed, med, sizeof(*med));
+       for (i=0; i<inDLM->totedge; i++) {
+               MEdge *inMED = &inDLM->medge[i];
+               MEdge *med = &dlm->medge[dlm->totedge++];
 
-                       nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no);
-                       nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no);
+               *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;
 
-                       if (eMapOut) eMapOut[i] = edgeMap[i];
+               if (indexMap[inMED->v1][1] || indexMap[inMED->v2][2]) {
+                       MEdge *med2 = &dlm->medge[dlm->totedge++];
 
-                       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;
-               
-               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);
-               }
-
-                       /* Map vertices to shared */
-
-               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);
+       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];
                }
+               
+               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;
+
+                       *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;
+
+                       if (inDLM->tface) {
+                               TFace *inTF = &inDLM->tface[i];
+                               tf = &dlm->tface[dlm->totface-1];
+
+                               *tf = *inTF;
+                       } else if (inDLM->mcol) {
+                               MCol *inMC = &inDLM->mcol[i*4];
+                               mc = &dlm->mcol[(dlm->totface-1)*4];
+
+                               mc[0] = inMC[0];
+                               mc[1] = inMC[1];
+                               mc[2] = inMC[2];
+                               mc[3] = inMC[3];
+                       }
 
-               if (fMapOut) fMapOut[i] = faceMap[i];
-
-                       /* 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;
-
-               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]);
-                               }
-                       } 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]);
-                                       }
+                       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]);
                                }
+
+                               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;
-       }
-
-       ndlm->mvert = MEM_mallocN(sizeof(*mvert)*ndlm->totvert*2, "mm_mv");
-       memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert);
-
-       if (medge) {
-               ndlm->medge = MEM_mallocN(sizeof(*medge)*ndlm->totedge*2, "mm_med");
-               memcpy(ndlm->medge, medge, sizeof(*medge)*ndlm->totedge);
+               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->mface = MEM_mallocN(sizeof(*mface)*ndlm->totface*2, "mm_mf");
-       memcpy(ndlm->mface, mface, sizeof(*mface)*ndlm->totface);
+       outDLM = mirrorModifier__doMirror(mmd, inDLM, vertexCos, dm?0:1);
 
-       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);
+       
+       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);
 }
 
 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;
        }
index e16ade4b7cc2c93649bc18bc80f91068a24a1ea7..f324a046c5fc157649c2e6ca1a1ceba8aed2ca9f 100644 (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
-
-       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);
+               /* 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.
+                */
 
-       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);
-
-               // 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);
+       edgeBase = i;
+       for (index=0; index<totedge; index++) {
+               CCGEdge *e= edgeMap2[index];
+               int x;
 
-               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;
+               for (x=1; x<edgeSize-1; x++) {
+                       VecCopyf(dlm->mvert[i++].co, ccgSubSurf_getEdgeData(ss, e, x));
+               }
 
-                       if (edgeMap) {
-                               edgeMap[i] = ccgDM_getEdgeHandle(ccgdm, e);
-                       }
+               *((int*) ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase;
+               edgeBase += edgeSize-2;
+       }
 
-                       i++;
-               }
+       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;
        }
-       ccgEdgeIterator_free(ei);
 
-       fi = ccgSubSurf_getFaceIterator(ss);
-       for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
-               CCGFace *f = ccgFaceIterator_getCurrent(fi);
+               // load edges
+
+       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);
+
+       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);
 
-static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) {
+               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();
        }
-}
-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);
+       ccgEdgeIterator_free(ei);
 }
-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);
                }
        }
 }
index 21fc7f738865dd239c74e14b60706526de755420..44b1cc53669675cc7c8e035b5c06ecd83a04d58a 100644 (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);
index 76dc57cd70d0e0f0c37f67d2b18512889399e7f3..decb52ec1fc7f8489fb358693ac23a62ae03353d 100644 (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
index fc2961364f05c1b72a4227b78118538828be374c..6e11883b16cef9033d4734381fde020c8eedb62f 100644 (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;
index 12a7408a3999131b9f97dea6d30767ac05d23469..a722d88120045892031f69f8fd60a6d690ec56ad 100644 (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) {
index 2578c1b1216390167cf7ef1ad3777d43bd63d423..4097c76dd11f6b4f94dfbbe921bd4401b1b1d57f 100644 (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++;
index 3ad4742730cfda6eed87eabc35a581aee051e43a..ef35971cfa129f1bace15749bab06aa4e9d07e77 100644 (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;
 
index 8193809ca1860147553f11f311041eaa75f3ee51..11081fc43b8f7d31656604ab084d8a51355e62d3 100644 (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);
                        }
                }
index 2f0547b137e6e829502b7e6581e704eb41f70e5d..8acaf622988dc6c66272b9b2b660f063cd0c4794 100644 (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;
-
-       for(eed= G.editMesh->edges.first; eed; eed= eed->next)
-               eed->vn= (EditVert*) offset++;
+       dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, (void*) 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);
 
index 015dac2c9b73c46bf543a8abf44d159d8ceb6b4b..ca6be579bb1bd0f30a0fe2701fdcb8e7f327790e 100644 (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
index aef790fa4395d7f9d6d6fb3351e4ebb6b5327d2a..4d850a6e14d558b6d8ccc8ccf21dbd6621e76fdb 100644 (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;
+}
index 650271ac73ca2c8d1412e1d627314276a34405d8..11aabb263cdb464526973a361b63d74052eac789 100644 (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)
index c35803103eee8c84c49230bf40edce0d8feaf775..f0c62fac81788a6d11d14fa7ac1161620c794e0e 100644 (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;
index ce9ffad1bf0812a2d82ce4c97909e45e2c13ebc8..c9e2a09c957b44688257e06a25c8cb081817921b 100644 (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);
index 65a2387fd8330a8766b61dfa2cfba61cb8dfd6cf..044373d10f78e6257215472bd2e71bad7f4f9afc 100644 (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)) {