- got rid of DerivedMesh.drawMappedEdgeEM function, can be implemented with
authorDaniel Dunbar <daniel@zuster.org>
Sun, 7 Aug 2005 05:42:03 +0000 (05:42 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sun, 7 Aug 2005 05:42:03 +0000 (05:42 +0000)
   drawMappedEdges
 - added DerivedMesh.convertToDispListMeshMapped function which converts and
   also returns mapping information for use in editmode
 - updated DispListMesh derivedmesh to be able to function in editmode
 - update mirror modifier to support use as a cage
 - update mirror & subsurf modifiers to properly pass mapping information down
   modifier stack

It is now possible to have a mesh with mirror/subsurf modifiers where you
can edit with both as cage. Selecting the mirror'd part works, but of course
transform is flipped so it is a bit weird. Not the cleanest code in the
world and I can't say I am really happy with the architecture but it works for
now and supports the existing feature set.

source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_subsurf.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/src/editmesh_mods.c

index 6350332fd66eaa9adc04497facc4757e9f66992d..1158f89dde09eb95fff6da7a9fd8a1d303d1911f 100644 (file)
@@ -74,6 +74,18 @@ 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
@@ -137,9 +149,6 @@ struct DerivedMesh {
                         */
        void (*drawMappedVertsEM)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditVert *eve), void *userData);
 
-                       /* Draw single mapped edge as lines (no options) */
-       void (*drawMappedEdgeEM)(DerivedMesh *dm, void *edge);
-
                        /* Draw mapped edges as lines
                         *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge) returns true
                         */
@@ -179,7 +188,7 @@ struct DerivedMesh {
 };
 
        /* Internal function, just temporarily exposed */
-DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm);
+DerivedMesh *derivedmesh_from_displistmesh(struct DispListMesh *dlm, float (*vertexCos)[3], struct EditVert **vertMap, struct EditEdge **edgeMap, struct EditFace **faceMap);
 
 DerivedMesh *mesh_get_derived_final(struct Object *ob, int *needsFree_r);
 DerivedMesh *mesh_get_derived_deform(struct Object *ob, int *needsFree_r);
index 925ef15288fb12a0062e2734aa04d6eb64a524a9..dbcc2dd3e17015100bb5abaf6ac14e567b18a7a3 100644 (file)
@@ -35,9 +35,13 @@ 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_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 b26d40f60fe2b6efb667ce20fbd33626e09e1800..25ec8d6e3a49385077755d2c413f0559d229d299 100644 (file)
@@ -140,11 +140,8 @@ static void meshDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
 static void meshDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
 {
        MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
-       float *co = mdm->verts[index].co;
 
-       co_r[0] = co[0];
-       co_r[1] = co[1];
-       co_r[2] = co[2];
+       VECCOPY(co_r, mdm->verts[index].co);
 }
 
 static void meshDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
@@ -479,9 +476,7 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3]
 
                mdm->verts = MEM_mallocN(sizeof(*mdm->verts)*me->totvert, "deformedVerts");
                for (i=0; i<me->totvert; i++) {
-                       mdm->verts[i].co[0] = vertCos[i][0];
-                       mdm->verts[i].co[1] = vertCos[i][1];
-                       mdm->verts[i].co[2] = vertCos[i][2];
+                       VECCOPY(mdm->verts[i].co, vertCos[i]);
                }
                mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
                mdm->freeNors = 1;
@@ -519,18 +514,14 @@ static void emDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
 
                for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
                        if (eve==vert) {
-                               co_r[0] = emdm->vertexCos[i][0];
-                               co_r[1] = emdm->vertexCos[i][1];
-                               co_r[2] = emdm->vertexCos[i][2];
+                               VECCOPY(co_r, emdm->vertexCos[i]);
                                break;
                        }
                }
        } else {
                EditVert *eve = vert;
 
-               co_r[0] = eve->co[0];
-               co_r[1] = eve->co[1];
-               co_r[2] = eve->co[2];
+               VECCOPY(co_r, eve->co);
        }
 }
 static void emDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData)
@@ -556,15 +547,6 @@ static void emDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *
                bglEnd();               
        }
 }
-static void emDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge)
-{
-       EditEdge *eed = edge;
-
-       glBegin(GL_LINES);
-       glVertex3fv(eed->v1->co);
-       glVertex3fv(eed->v2->co);
-       glEnd();
-}
 static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) 
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
@@ -656,13 +638,9 @@ static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[
        }
 
        if (efa->v4) {
-               cent[0] *= 0.25f;
-               cent[1] *= 0.25f;
-               cent[2] *= 0.25f;
+               VecMulf(cent, 0.25f);
        } else {
-               cent[0] *= 0.33333333333f;
-               cent[1] *= 0.33333333333f;
-               cent[2] *= 0.33333333333f;
+               VecMulf(cent, 0.33333333333f);
        }
 }
 static void emDM_drawMappedFaceCentersEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData)
@@ -892,7 +870,6 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, float (*vertexCos)[3])
        emdm->dm.drawMappedVertsEM = emDM_drawMappedVertsEM;
 
        emdm->dm.drawEdges = emDM_drawEdges;
-       emdm->dm.drawMappedEdgeEM = emDM_drawMappedEdgeEM;
        emdm->dm.drawMappedEdgesEM = emDM_drawMappedEdgesEM;
        emdm->dm.drawMappedEdgesInterpEM = emDM_drawMappedEdgesInterpEM;
        
@@ -963,8 +940,183 @@ typedef struct {
        DerivedMesh dm;
 
        DispListMesh *dlm;
+
+       EditVert **vertMap;
+       EditEdge **edgeMap;
+       EditFace **faceMap;
 } SSDerivedMesh;
 
+static void ssDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
+{
+       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       DispListMesh *dlm = ssdm->dlm;
+
+       if (ssdm->vertMap) {
+               int i;
+
+               for (i=0; i<dlm->totvert; i++) {
+                       if (ssdm->vertMap[i]==vert) {
+                               VECCOPY(co_r, dlm->mvert[i].co);
+                               break;
+                       }
+               }
+       }
+}
+static void ssDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData)
+{
+       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       DispListMesh *dlm = ssdm->dlm;
+
+       if (ssdm->vertMap) {
+               int i;
+
+               bglBegin(GL_POINTS);
+               for (i=0; i<dlm->totvert; i++) {
+                       if(ssdm->vertMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->vertMap[i]))) {
+                               bglVertex3fv(dlm->mvert[i].co);
+                       }
+               }
+               bglEnd();
+       }
+}
+static void ssDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) 
+{
+       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       DispListMesh *dlm = ssdm->dlm;
+       int i;
+
+       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];
+
+                               glVertex3fv(dlm->mvert[med->v1].co);
+                               glVertex3fv(dlm->mvert[med->v2].co);
+                       }
+               }
+               glEnd();
+       }
+}
+
+static void ssDM_drawMappedFaceCentersEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData)
+{
+       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       DispListMesh *dlm = ssdm->dlm;
+       int i;
+
+       if (ssdm->faceMap) {
+               bglBegin(GL_POINTS);
+               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) {
+                                       float cent[3];
+
+                                       VECCOPY(cent, dlm->mvert[mf->v1].co);
+                                       VecAddf(cent, cent, dlm->mvert[mf->v2].co);
+                                       VecAddf(cent, cent, dlm->mvert[mf->v3].co);
+
+                                       if (mf->v4) {
+                                               VecAddf(cent, cent, dlm->mvert[mf->v4].co);
+                                               VecMulf(cent, 0.25f);
+                                       } else {
+                                               VecMulf(cent, 0.33333333333f);
+                                       }
+
+                                       bglVertex3fv(cent);
+                               }
+                       }
+               }
+               bglEnd();
+       }
+}
+static void ssDM_drawMappedFaceNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData)
+{
+       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       DispListMesh *dlm = ssdm->dlm;
+       int i;
+
+       if (ssdm->faceMap) {
+               glBegin(GL_LINES);
+               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) {
+                                       float cent[3];
+                                       float no[3];
+
+                                       VECCOPY(cent, dlm->mvert[mf->v1].co);
+                                       VecAddf(cent, cent, dlm->mvert[mf->v2].co);
+                                       VecAddf(cent, cent, dlm->mvert[mf->v3].co);
+
+                                       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);
+                                       }
+
+                                       glVertex3fv(cent);
+                                       glVertex3f(     cent[0] + length*no[0],
+                                                               cent[1] + length*no[1],
+                                                               cent[2] + length*no[2]);
+                               }
+                       }
+               }
+               glEnd();
+       }
+}
+static void ssDM_drawMappedVertNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditVert *eve), void *userData)
+{
+       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       DispListMesh *dlm = ssdm->dlm;
+       int i;
+
+       if (ssdm->vertMap) {
+               glBegin(GL_LINES);
+               for (i=0; i<dlm->totvert; i++) {
+                       if(ssdm->vertMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->vertMap[i]))) {
+                               float *co = dlm->mvert[i].co;
+                               short *no = dlm->mvert[i].no;
+
+                               glVertex3fv(co);
+                               glVertex3f(     co[0] + length*no[0]/32767.0,
+                                                       co[1] + length*no[1]/32767.0,
+                                                       co[2] + length*no[2]/32767.0);
+                       }
+               }
+               glEnd();
+       }
+}
+static void ssDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData)
+{
+       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
+       DispListMesh *dlm = ssdm->dlm;
+       int i;
+
+       if (ssdm->faceMap) {            
+               for (i=0; i<dlm->totface; i++) {
+                       if(ssdm->faceMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->faceMap[i]))) {
+                               MFace *mf = &dlm->mface[i];
+
+                               if (mf->v3) {
+                                       glBegin(mf->v3?GL_QUADS:GL_TRIANGLES);
+                                       glVertex3fv(dlm->mvert[mf->v1].co);
+                                       glVertex3fv(dlm->mvert[mf->v2].co);
+                                       glVertex3fv(dlm->mvert[mf->v3].co);
+                                       if(mf->v4) glVertex3fv(dlm->mvert[mf->v4].co);
+                                       glEnd();
+                               }
+                       }
+               }
+       }
+}
+
 static void ssDM_drawMappedEdges(DerivedMesh *dm)
 {
        SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
@@ -1251,16 +1403,38 @@ 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)
+DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap)
 {
        SSDerivedMesh *ssdm = MEM_callocN(sizeof(*ssdm), "ssdm");
 
@@ -1269,6 +1443,7 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm)
        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;
 
@@ -1282,9 +1457,41 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm)
        ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
        ssdm->dm.drawFacesTex = ssDM_drawFacesTex;
 
+               /* EM functions */
+       
+       ssdm->dm.getMappedVertCoEM = ssDM_getMappedVertCoEM;
+       ssdm->dm.drawMappedVertsEM = ssDM_drawMappedVertsEM;
+
+       ssdm->dm.drawMappedEdgesEM = ssDM_drawMappedEdgesEM;
+       ssdm->dm.drawMappedEdgesInterpEM = NULL; // no way to implement this one
+       
+       ssdm->dm.drawMappedVertNormalsEM = ssDM_drawMappedVertNormalsEM;
+       ssdm->dm.drawMappedFaceNormalsEM = ssDM_drawMappedFaceNormalsEM;
+       ssdm->dm.drawMappedFaceCentersEM = ssDM_drawMappedFaceCentersEM;
+
+       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;
+
+               for (i=0; i<dlm->totvert; i++) {
+                       VECCOPY(dlm->mvert[i].co, vertexCos[i]);
+               }
+
+               if (dlm->nors && !dlm->dontFreeNors) {
+                       MEM_freeN(dlm->nors);
+                       dlm->nors = 0;
+               }
+
+               mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
+       }
 
        return (DerivedMesh*) ssdm;
 }
@@ -1417,24 +1624,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
                 */
        if (dm && deformedVerts) {
                DispListMesh *dlm = dm->convertToDispListMesh(dm, 0);
-               int i;
-
-                       /* XXX, would like to avoid the conversion to a DLM here if possible.
-                        * Requires adding a DerivedMesh.updateVertCos method.
-                        */
-               for (i=0; i<numVerts; i++) {
-                       VECCOPY(dlm->mvert[i].co, deformedVerts[i]);
-               }
 
                dm->release(dm);
 
-               if (dlm->nors && !dlm->dontFreeNors) {
-                       MEM_freeN(dlm->nors);
-                       dlm->nors = 0;
-               }
-
-               mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
-               *final_r = derivedmesh_from_displistmesh(dlm);
+               *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts, NULL, NULL, NULL);
        } else if (dm) {
                *final_r = dm;
        } else {
@@ -1526,8 +1719,14 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
 
                if (cage_r && i==cageIndex) {
                        if (dm && deformedVerts) {
-                                       // XXX  this is not right, need to convert the dm
-                               *cage_r = dm;
+                               DispListMesh *dlm;
+                               EditVert **vertMap;
+                               EditEdge **edgeMap;
+                               EditFace **faceMap;
+
+                               dlm = dm->convertToDispListMeshMapped(dm, 0, &vertMap, &edgeMap, &faceMap);
+
+                               *cage_r = derivedmesh_from_displistmesh(dlm, deformedVerts, vertMap, edgeMap, faceMap);
                        } else if (dm) {
                                *cage_r = dm;
                        } else {
@@ -1542,24 +1741,10 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
                 */
        if (dm && deformedVerts) {
                DispListMesh *dlm = dm->convertToDispListMesh(dm, 0);
-               int i;
-
-                       /* XXX, would like to avoid the conversion to a DLM here if possible.
-                        * Requires adding a DerivedMesh.updateVertCos method.
-                        */
-               for (i=0; i<numVerts; i++) {
-                       VECCOPY(dlm->mvert[i].co, deformedVerts[i]);
-               }
 
                if (!cage_r || dm!=*cage_r) dm->release(dm);
 
-               if (dlm->nors && !dlm->dontFreeNors) {
-                       MEM_freeN(dlm->nors);
-                       dlm->nors = 0;
-               }
-
-               mesh_calc_normals(dlm->mvert, dlm->totvert, dlm->mface, dlm->totface, &dlm->nors);
-               *final_r = derivedmesh_from_displistmesh(dlm);
+               *final_r = derivedmesh_from_displistmesh(dlm, deformedVerts, NULL, NULL, NULL);
                MEM_freeN(deformedVerts);
        } else if (dm) {
                *final_r = dm;
index a1786ed8898c119b7cf52c14e4c54c48f0d6c3e1..6f9e2f861b2599bb501533c260067950b0f67cd4 100644 (file)
@@ -189,7 +189,14 @@ static void *subsurfModifier_applyModifierEM(ModifierData *md, Object *ob, void
        SubsurfModifierData *smd = (SubsurfModifierData*) md;
 
        if (dm) {
-               return subsurfModifier_applyModifier(md, ob, dm, vertexCos, 0, 1);
+               EditVert **vertMap;
+               EditEdge **edgeMap;
+               EditFace **faceMap;
+               DispListMesh *dlm = dm->convertToDispListMeshMapped(dm, 0, &vertMap, &edgeMap, &faceMap);
+
+               dm = subsurf_make_derived_from_dlm_em(dlm, smd, vertexCos, vertMap, edgeMap, faceMap);
+
+               return dm;
        } else {
                return subsurf_make_derived_from_editmesh(em, smd, vertexCos);
        }
@@ -432,7 +439,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);
+       return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
 }
 
 /* Mirror */
@@ -453,25 +460,40 @@ static void mirrorModifier_copyData(ModifierData *md, ModifierData *target)
        tmmd->tolerance = mmd->tolerance;
 }
 
-static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm, float (*vertexCos)[3])
+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)
 {
        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;
+       }
 
        for (i=0; i<totvert; i++) {
                MVert *mv = &ndlm->mvert[i];
                int isShared = ABS(mv->co[axis])<=tolerance;
 
-                       /* Because the topology result (# of vertices) must stuff 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.
-                               */
+                               /* Because the topology result (# of vertices) must stuff 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.
+                                */
                if (vertexCos) {
                        VECCOPY(mv->co, vertexCos[i]);
                }
 
+               if (vMapOut) vMapOut[i] = vertMap[i];
+
                if (isShared) {
                        mv->co[axis] = 0;
                        *((int*) mv->no) = i;
@@ -481,6 +503,8 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm
                        memcpy(nmv, mv, sizeof(*mv));
                        nmv ->co[axis] = -nmv ->co[axis];
 
+                       if (vMapOut) vMapOut[ndlm->totvert] = vertMap[i];
+
                        *((int*) mv->no) = ndlm->totvert++;
                }
        }
@@ -495,7 +519,11 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm
                        nmed->v1 = *((int*) ndlm->mvert[nmed->v1].no);
                        nmed->v2 = *((int*) ndlm->mvert[nmed->v2].no);
 
+                       if (eMapOut) eMapOut[i] = edgeMap[i];
+
                        if (nmed->v1!=med->v1 || nmed->v2!=med->v2) {
+                               if (eMapOut) eMapOut[ndlm->totedge] = edgeMap[i];
+
                                ndlm->totedge++;
                        }
                }
@@ -505,7 +533,7 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm
                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; /* gcc's mother is uninitialized! */
+               MCol *mc=NULL, *nmc=NULL;
                
                memcpy(nmf, mf, sizeof(*mf));
                if (ndlm->tface) {
@@ -527,10 +555,14 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm
                        if (nmf->v4) nmf->v4 = *((int*) ndlm->mvert[nmf->v4].no);
                }
 
+               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
@@ -574,7 +606,7 @@ static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm
        }
 }
 
-static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
+static void *mirrorModifier_applyModifier__internal(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc, int needsMaps)
 {
        DerivedMesh *dm = derivedData;
        MirrorModifierData *mmd = (MirrorModifierData*) md;
@@ -584,9 +616,16 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de
        MFace *mface;
        TFace *tface;
        MCol *mcol;
+       EditVert **vertMapOut, **vertMap = NULL;
+       EditEdge **edgeMapOut, **edgeMap = NULL;
+       EditFace **faceMapOut, **faceMap = NULL;
 
        if (dm) {
-               dlm = dm->convertToDispListMesh(dm, 1);
+               if (needsMaps) {
+                       dlm = dm->convertToDispListMeshMapped(dm, 1, &vertMap, &edgeMap, &faceMap);
+               } else {
+                       dlm = dm->convertToDispListMesh(dm, 1);
+               }
 
                mvert = dlm->mvert;
                medge = dlm->medge;
@@ -628,19 +667,31 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de
                memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*ndlm->totface);
        }
 
-       mirrorModifier__doMirror(mmd, ndlm, vertexCos);
+       mirrorModifier__doMirror(mmd, ndlm, vertexCos, vertMap, edgeMap, faceMap, &vertMapOut, &edgeMapOut, &faceMapOut);
 
-       if (dlm) displistmesh_free(dlm);
+       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);
        
-       return derivedmesh_from_displistmesh(ndlm);
+       return derivedmesh_from_displistmesh(ndlm, NULL, vertMapOut, edgeMapOut, faceMapOut);
+}
+
+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);
 }
 
 static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3])
 {
        if (derivedData) {
-               return mirrorModifier_applyModifier(md, ob, derivedData, vertexCos, 0, 1);
+               return mirrorModifier_applyModifier__internal(md, ob, derivedData, vertexCos, 0, 1, 1);
        } else {
                MirrorModifierData *mmd = (MirrorModifierData*) md;
                DispListMesh *ndlm = MEM_callocN(sizeof(*ndlm), "mm_dlm");
@@ -648,6 +699,9 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *
                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)
@@ -657,6 +711,10 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *
                ndlm->totedge = BLI_countlist(&em->edges);
                ndlm->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");
+
                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");
@@ -665,6 +723,8 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *
                        MVert *mv = &ndlm->mvert[i];
 
                        VECCOPY(mv->co, eve->co);
+
+                       vertMap[i] = eve;
                }
                for (i=0,eed=em->edges.first; i<ndlm->totedge; i++,eed=eed->next) {
                        MEdge *med = &ndlm->medge[i];
@@ -672,6 +732,8 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *
                        med->v1 = (int) eed->v1->prev;
                        med->v2 = (int) eed->v2->prev;
                        med->crease = (unsigned char) (eed->crease*255.0f);
+
+                       edgeMap[i] = eed;
                }
                for (i=0,efa=em->faces.first; i<ndlm->totface; i++,efa=efa->next) {
                        MFace *mf = &ndlm->mface[i];
@@ -683,16 +745,22 @@ static void *mirrorModifier_applyModifierEM(ModifierData *md, Object *ob, void *
                        mf->flag = efa->flag;
 
                        test_index_mface(mf, efa->v4?4:3);
+
+                       faceMap[i] = efa;
                }
 
-               mirrorModifier__doMirror(mmd, ndlm, vertexCos);
+               mirrorModifier__doMirror(mmd, ndlm, vertexCos, vertMap, edgeMap, faceMap, &vertMapOut, &edgeMapOut, &faceMapOut);
 
                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);
                
-               return derivedmesh_from_displistmesh(ndlm);
+               MEM_freeN(faceMap);
+               MEM_freeN(edgeMap);
+               MEM_freeN(vertMap);
+
+               return derivedmesh_from_displistmesh(ndlm, NULL, vertMapOut, edgeMapOut, faceMapOut);
        }
 }
 
@@ -837,7 +905,7 @@ exit:
        if (ndlm) {
                mesh_calc_normals(ndlm->mvert, ndlm->totvert, ndlm->mface, ndlm->totface, &ndlm->nors);
 
-               return derivedmesh_from_displistmesh(ndlm);
+               return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
        } else {
                return NULL;
        }
@@ -1008,7 +1076,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
 
                mti = INIT_TYPE(Mirror);
                mti->type = eModifierTypeType_Constructive;
-               mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode;
+               mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode;
                mti->initData = mirrorModifier_initData;
                mti->copyData = mirrorModifier_copyData;
                mti->applyModifier = mirrorModifier_applyModifier;
index 316b7425988ab33e400313322e7ed88740439309..c28c0b20b7307d9a82a74221b28fa5a6b66ac1c5 100644 (file)
@@ -66,6 +66,12 @@ typedef struct _VertData {
        float no[3];
 } 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 void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
@@ -190,7 +196,7 @@ static int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edg
                return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
        }
 }
-static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh *inMe, DispListMesh *inDLM) {
+static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, CCGDerivedMesh *ccgdm, int ssFromEditmesh, Mesh *inMe, DispListMesh *inDLM, EditVert ***vertMap_r, EditEdge ***edgeMap_r, EditFace ***faceMap_r) {
        DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
@@ -204,7 +210,10 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh
        CCGVertIterator *vi;
        CCGEdgeIterator *ei;
        CCGFaceIterator *fi;
-       
+       EditVert **vertMap = NULL;
+       EditEdge **edgeMap = NULL;
+       EditFace **faceMap = NULL;
+
        if (!ssFromEditmesh) {
                if (inDLM) {
                        tface = inDLM->tface;
@@ -223,6 +232,12 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh
        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");
@@ -244,6 +259,9 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh
        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);
@@ -303,9 +321,9 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh
                        med->flag = ME_EDGEDRAW;
 
                        if (ssFromEditmesh) {
-                               EditEdge *ee = ccgSubSurf_getEdgeEdgeHandle(ss, e);
+                               EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e);
 
-                               if (ee->seam) {
+                               if (eed->seam) {
                                        med->flag|= ME_SEAM;
                                }
                        } else {
@@ -319,6 +337,10 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh
                                }
                        }
 
+                       if (edgeMap) {
+                               edgeMap[i] = ccgDM_getEdgeHandle(ccgdm, e);
+                       }
+
                        i++;
                }
        }
@@ -434,6 +456,10 @@ static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh
                                        mf->flag = flag;
                                        mf->edcode = 0;
 
+                                       if (faceMap) {
+                                               faceMap[i] = ccgDM_getFaceHandle(ccgdm, f);
+                                       }
+
                                        if (x+1==gridSize-1)
                                                mf->edcode|= ME_V2V3;
                                        if (y+1==gridSize-1)
@@ -585,7 +611,7 @@ void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], in
 
 /***/
 
-typedef struct {
+struct CCGDerivedMesh {
        DerivedMesh dm;
 
        CCGSubSurf *ss;
@@ -593,7 +619,39 @@ typedef struct {
 
        Mesh *me;
        DispListMesh *dlm;
-} CCGDerivedMesh;
+
+       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 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 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 void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
@@ -695,17 +753,47 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
 }
 static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert);
-       float *co = ccgSubSurf_getVertData(ccgdm->ss, v);
 
-       co_r[0] = co[0];
-       co_r[1] = co[1];
-       co_r[2] = co[2];
+               /* The vert handle is an index into the vmap in this case, have
+                * to search for it.
+                */
+       if (ccgdm->vertMap) {
+               CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
+
+               for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
+                       CCGVert *v = ccgVertIterator_getCurrent(vi);
+                       int index = (int) ccgSubSurf_getVertVertHandle(ccgdm->ss, v);
+
+                       if (ccgdm->vertMap[index]==vert) {
+                               float *co = ccgSubSurf_getVertData(ccgdm->ss, v);
+
+                               co_r[0] = co[0];
+                               co_r[1] = co[1];
+                               co_r[2] = co[2];
+
+                               break;
+                       }
+               }
+
+               ccgVertIterator_free(vi);
+       } else {
+               CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert);
+               float *co = ccgSubSurf_getVertData(ccgdm->ss, v);
+
+               co_r[0] = co[0];
+               co_r[1] = co[1];
+               co_r[2] = co[2];
+       }
 }
 static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm, int allowShared) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 
-       return ss_to_displistmesh(ccgdm->ss, ccgdm->fromEditmesh, ccgdm->me, ccgdm->dlm);
+       return ss_to_displistmesh(ccgdm->ss, ccgdm, ccgdm->fromEditmesh, 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->me, ccgdm->dlm, vertMap_r, edgeMap_r, faceMap_r);
 }
 
 static void ccgDM_drawVerts(DerivedMesh *dm) {
@@ -768,7 +856,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
                VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
 
                if (ccgdm->fromEditmesh) {
-                       EditEdge *eed = ccgSubSurf_getEdgeEdgeHandle(ss, e);
+                       EditEdge *eed = ccgDM_getEdgeHandle(ccgdm, e);
                        if (eed->h!=0)
                                continue;
                }
@@ -795,7 +883,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
                int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
 
                if (ccgdm->fromEditmesh) {
-                       EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f);
+                       EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
                        if (efa->h!=0)
                                continue;
                }
@@ -880,8 +968,8 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
                int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
                unsigned char flag,mat_nr;
 
-               if (ccgdm->fromEditmesh) {
-                       EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f);
+               if (ccgdm->fromEditmesh || ccgdm->vertMap) {
+                       EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
                        if (efa->h!=0)
                                continue;
 
@@ -1136,7 +1224,7 @@ static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void
        bglBegin(GL_POINTS);
        for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
-               EditVert *vert = ccgSubSurf_getVertVertHandle(ss,v);
+               EditVert *vert = ccgDM_getVertHandle(ccgdm, v);
 
                if (!setDrawOptions || setDrawOptions(userData, vert)) {
                        bglVertex3fv(ccgSubSurf_getVertData(ss, v));
@@ -1154,7 +1242,7 @@ static void ccgDM_drawMappedVertNormalsEM(DerivedMesh *dm, float length, int (*s
        glBegin(GL_LINES);
        for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
-               EditVert *vert = ccgSubSurf_getVertVertHandle(ss,v);
+               EditVert *vert = ccgDM_getVertHandle(ccgdm, v);
 
                if (!setDrawOptions || setDrawOptions(userData, vert)) {
                        VertData *vd = ccgSubSurf_getVertData(ss, v);
@@ -1169,21 +1257,6 @@ static void ccgDM_drawMappedVertNormalsEM(DerivedMesh *dm, float length, int (*s
 
        ccgVertIterator_free(vi);
 }
-static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
-       CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
-       CCGEdge *e = ccgSubSurf_getEdge(ss, edge);
-       VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
-       int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
-
-       glBegin(GL_LINE_STRIP);
-       for (i=0; i<edgeSize; i++)
-               glVertex3fv(edgeData[i].co);
-       glEnd();
-
-       ccgEdgeIterator_free(ei);
-}
 static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
        CCGSubSurf *ss = ccgdm->ss;
@@ -1194,7 +1267,7 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void
 
        for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
-               EditEdge *edge = ccgSubSurf_getEdgeEdgeHandle(ss, e);
+               EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e);
                VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
 
                glBegin(GL_LINE_STRIP);
@@ -1224,7 +1297,7 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)
 
        for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
-               EditEdge *edge = ccgSubSurf_getEdgeEdgeHandle(ss, e);
+               EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e);
                VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
 
                glBegin(GL_LINE_STRIP);
@@ -1251,7 +1324,7 @@ static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void
 
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
-               EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f);
+               EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
                if (!setDrawOptions || setDrawOptions(userData, efa)) {
                        int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
 
@@ -1281,7 +1354,7 @@ static void ccgDM_drawMappedFaceNormalsEM(DerivedMesh *dm, float length, int (*s
        glBegin(GL_LINES);
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
-               EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f);
+               EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
                if (!setDrawOptions || setDrawOptions(userData, efa)) {
                                /* Face center data normal isn't updated atm. */
                        VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
@@ -1301,11 +1374,16 @@ 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, Mesh *me, DispListMesh *dlm) {
+static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh *me, DispListMesh *dlm, EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) {
        CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm");
 
        ccgdm->dm.getMinMax = ccgDM_getMinMax;
@@ -1314,6 +1392,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh
        ccgdm->dm.getVertCos = ccgdm_getVertCos;
        ccgdm->dm.getMappedVertCoEM = ccgDM_getMappedVertCoEM;
        ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh;
+       ccgdm->dm.convertToDispListMeshMapped = ccgDM_convertToDispListMeshMapped;
 
        ccgdm->dm.drawVerts = ccgDM_drawVerts;
        ccgdm->dm.drawEdges = ccgDM_drawEdges;
@@ -1325,7 +1404,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh
 
        ccgdm->dm.drawMappedVertsEM = ccgDM_drawMappedVertsEM;
        ccgdm->dm.drawMappedVertNormalsEM = ccgDM_drawMappedVertNormalsEM;
-       ccgdm->dm.drawMappedEdgeEM = ccgDM_drawMappedEdgeEM;
        ccgdm->dm.drawMappedEdgesInterpEM = ccgDM_drawMappedEdgesInterpEM;
        ccgdm->dm.drawMappedEdgesEM = ccgDM_drawMappedEdgesEM;
        ccgdm->dm.drawMappedFacesEM = ccgDM_drawMappedFacesEM;
@@ -1337,6 +1415,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh
        ccgdm->fromEditmesh = fromEditmesh;
        ccgdm->me = me;
        ccgdm->dlm = dlm;
+       ccgdm->vertMap = vertMap;
+       ccgdm->edgeMap = edgeMap;
+       ccgdm->faceMap = faceMap;
 
        return ccgdm;
 }
@@ -1350,7 +1431,18 @@ 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, NULL, NULL);
+       return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, NULL, NULL, NULL, NULL, NULL);
+}
+
+DerivedMesh *subsurf_make_derived_from_dlm_em(DispListMesh *dlm, SubsurfModifierData *smd, float (*vertCos)[3], EditVert **vertMap, EditEdge **edgeMap, EditFace **faceMap) {
+       int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
+       int useAging = smd->flags&eSubsurfModifierFlag_DebugIncr;
+               
+       smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, 0, useSimple);
+
+       ss_sync_from_mesh(smd->emCache, NULL, dlm, vertCos, useSimple);
+
+       return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 0, NULL, dlm, vertMap, edgeMap, faceMap);
 }
 
 DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) {
@@ -1363,12 +1455,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, 0, me, dlm);
+               ndlm = ss_to_displistmesh(ss, NULL, 0, me, dlm, NULL, NULL, NULL);
                if (dlm) displistmesh_free(dlm);
 
                ccgSubSurf_free(ss);
                
-               return derivedmesh_from_displistmesh(ndlm);
+               return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
        } else {
                int useEdgeCreation = !(dlm?dlm->medge:me->medge);
                int useIncremental = (smd->flags&eSubsurfModifierFlag_Incremental) && !useEdgeCreation;
@@ -1393,7 +1485,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, me, dlm);
+                       return (DerivedMesh*) getCCGDerivedMesh(ss, 0, me, dlm, NULL, NULL, NULL);
                } else {
                        if (smd->mCache && isFinalCalc) {
                                ccgSubSurf_free(smd->mCache);
@@ -1402,12 +1494,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, 0, me, dlm);
+                       ndlm = ss_to_displistmesh(ss, NULL, 0, me, dlm, NULL, NULL, NULL);
 
                        if (dlm) displistmesh_free(dlm);
                        ccgSubSurf_free(ss);
 
-                       return derivedmesh_from_displistmesh(ndlm);
+                       return derivedmesh_from_displistmesh(ndlm, NULL, NULL, NULL, NULL);
                }
        }
 }
index 4623d171f55a5ae7f0c3da8cc53349313851dfa5..dcc43167369b0a1dd8d8ca08fbcc3804823c6a64 100644 (file)
@@ -675,6 +675,15 @@ static EditFace *findnearestface(short *dist)
 }
 
 /* for interactivity, frontbuffer draw in current window */
+static int draw_dm_mapped_edge__setDrawOptions(void *theEdge, EditEdge *eed)
+{
+       return theEdge==eed;
+}
+static void draw_dm_mapped_edge(DerivedMesh *dm, EditEdge *eed)
+{
+       dm->drawMappedEdgesEM(dm, draw_dm_mapped_edge__setDrawOptions, eed);
+}
+
 static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
 {
        int dmNeedsFree;
@@ -706,11 +715,11 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
                        if(efa->fgonf==0) {
                                BIF_ThemeColor((efa->f & SELECT)?TH_EDGE_SELECT:TH_WIRE);
        
-                               dm->drawMappedEdgeEM(dm, efa->e1);
-                               dm->drawMappedEdgeEM(dm, efa->e2);
-                               dm->drawMappedEdgeEM(dm, efa->e3);
+                               draw_dm_mapped_edge(dm, efa->e1);
+                               draw_dm_mapped_edge(dm, efa->e2);
+                               draw_dm_mapped_edge(dm, efa->e3);
                                if (efa->e4) {
-                                       dm->drawMappedEdgeEM(dm, efa->e4);
+                                       draw_dm_mapped_edge(dm, efa->e4);
                                }
                        }
                }
@@ -731,7 +740,7 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
                if(G.scene->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_FACE)) {
                        BIF_ThemeColor((eed->f & SELECT)?TH_EDGE_SELECT:TH_WIRE);
 
-                       dm->drawMappedEdgeEM(dm, eed);
+                       draw_dm_mapped_edge(dm, eed);
                }
                if(G.scene->selectmode & SCE_SELECT_VERTEX) {
                        float co[3];