- added data arguments to deformer modifiers, in case someone wants
authorDaniel Dunbar <daniel@zuster.org>
Fri, 22 Jul 2005 07:37:15 +0000 (07:37 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Fri, 22 Jul 2005 07:37:15 +0000 (07:37 +0000)
   to write one that is based on geometry (and not just vertex position)
 - added editmode versions of modifier deform/apply calls and flag
   to tag modifiers that support editmode
 - added isFinalCalc param to applyModifier, basically a switch to let
   subsurf know if it is calc'ng orco or not (so it can deal with cache
   appropriately). This is kinda hacky and perhaps I can come up with
   a better solution (its also a waste to do a complete subdivide just
   to get vertex locations).
 - changed ccgsubsurf to not preallocate hash's to be approximately correct
   size... this was probably not a big performance savings but means that
   the order of faces returned by the iterator can vary after the first
   call, this messes up orco calculation so dropped for time being.
 - minor bug fix, meshes with only key didn't get vertex normals correctly
   calc'd
 - updated editmesh derivedmesh to support auxiliary locations
 - changed mesh_calc_modifiers to alloc deformVerts on demand
 - added editmesh_calc_modifiers for calculating editmesh cage and final
   derivedmesh's
 - bug fix, update shadedisplist to always calc colors (even if totvert==0)
 - changed load_editMesh and make_edge to build me->medge even if totedge==0
   (incremental subsurf checks this)

todo: add drawFacesTex for ccgderivedmesh

So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.

Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).

source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/BKE_subsurf.h
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/python/api2_2x/Lattice.c
source/blender/src/editmesh.c

index 2fd1eed2a3ea2d4c802b07d0d4d0d7f67fbeea25..080c21c5d5e81dd7af5588324d26bfb063eccff0 100644 (file)
@@ -91,7 +91,10 @@ struct DerivedMesh {
                        /* Draw all vertices as bgl points (no options) */
        void (*drawVerts)(DerivedMesh *dm);
 
-                       /* Draw all edges as lines (no options) */
+                       /* Draw all edges as lines (no options) 
+                        *
+                        * Also called for *final* editmode DerivedMeshes
+                        */
        void (*drawEdges)(DerivedMesh *dm);
 
                        /* Draw mapped edges as lines (no options) */
@@ -106,7 +109,7 @@ struct DerivedMesh {
                         *  o Use inherited face material index to call setMaterial
                         *  o Only if setMaterial returns true
                         *
-                        * Also called in Editmode
+                        * Also called for *final* editmode DerivedMeshes
                         */
        void (*drawFacesSolid)(DerivedMesh *dm, int (*setMaterial)(int));
 
index a09ee20b385b8c6ddd8575c04fc57c6f8a98bf5a..e079b2f2e3096b3552d606bbb782f3dd41ab7232 100644 (file)
@@ -58,6 +58,7 @@ typedef enum {
        eModifierTypeFlag_AcceptsMesh = (1<<0),
        eModifierTypeFlag_AcceptsCVs = (1<<1),
        eModifierTypeFlag_SupportsMapping = (1<<2),
+       eModifierTypeFlag_SupportsEditmode = (1<<3),
 } ModifierTypeFlag;
 
 typedef struct ModifierTypeInfo {
@@ -112,9 +113,14 @@ typedef struct ModifierTypeInfo {
        int (*dependsOnTime)(struct ModifierData *md);
 
                /* Only for deform types, should apply the deformation
-                * to the given vertex array. 
+                * to the given vertex array. If the deformer requires information from
+                * the object it can obtain it from the _derivedData_ argument if non-NULL,
+                * and otherwise the _ob_ argument.
                 */
-       void (*deformVerts)(struct ModifierData *md, struct Object *ob, float (*vertexCos)[3], int numVerts);
+       void (*deformVerts)(struct ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts);
+
+               /* Like deformVerts but called during editmode (for supporting modifiers) */
+       void (*deformVertsEM)(struct ModifierData *md, struct Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts);
 
                /* For non-deform types: apply the modifier and return a new derived
                 * data object (type is dependent on object type). If the _derivedData_
@@ -130,10 +136,23 @@ typedef struct ModifierTypeInfo {
                 * The _useRenderParams_ indicates if the modifier is being applied in
                 * the service of the renderer which may alter quality settings.
                 *
+                * The _isFinalCalc_ parameter indicates if the modifier is being calculated
+                * for a final result or for something temporary (like orcos). This is a hack
+                * at the moment, it is meant so subsurf can know if it is safe to reuse its
+                * internal cache.
+                *
                 * The modifier is expected to release (or reuse) the _derivedData_ argument
                 * if non-NULL. The modifier *MAY NOT* share the _vertexCos_ argument.
                 */
-       void *(*applyModifier)(struct ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams);
+       void *(*applyModifier)(struct ModifierData *md, struct Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc);
+
+               /* Like applyModifier but called during editmode (for supporting modifiers).
+                * 
+                * The derived object that is returned must support the operations that are expected
+                * from editmode objects. The same qualifications regarding _derivedData_ and _vertexCos_
+                * apply as for applyModifier.
+                */
+       void *(*applyModifierEM)(struct ModifierData *md, struct Object *ob, void *editData, void *derivedData, float (*vertexCos)[3]);
 } ModifierTypeInfo;
 
 ModifierTypeInfo *modifierType_get_info(ModifierType type);
index a52002761593e8e76e25d7aa00b0b194e0f412da..925ef15288fb12a0062e2734aa04d6eb64a524a9 100644 (file)
@@ -37,8 +37,8 @@ struct DerivedMesh;
 struct EditMesh;
 struct SubsurfModifierData;
 
-struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, struct SubsurfModifierData *smd);
-struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, struct DispListMesh *dlm, struct SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3]);
+struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, struct SubsurfModifierData *smd, float (*vertexCos)[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 6bfc431a2099fb44b92d39c46c21b4981af86ab4..ccc214284ac2561eeacf32ff27eecd3bd126fa6e 100644 (file)
@@ -766,9 +766,9 @@ CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss) {
        ss->oldEMap = ss->eMap; 
        ss->oldFMap = ss->fMap;
 
-       ss->vMap = _ehash_new(ss->oldVMap->numEntries, &ss->allocatorIFC, ss->allocator);
-       ss->eMap = _ehash_new(ss->oldFMap->numEntries, &ss->allocatorIFC, ss->allocator);
-       ss->fMap = _ehash_new(ss->oldEMap->numEntries, &ss->allocatorIFC, ss->allocator);
+       ss->vMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
+       ss->eMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
+       ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
 
        ss->numGrids = 0;
 
index a7678ce8056c16b9b69b4c922debb23046aeb686..f0807857248686625dfc041ddd51b82bba88bdbb 100644 (file)
@@ -502,7 +502,11 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3]
                mdm->freeNors = 1;
                mdm->freeVerts = 1;
        } else {
-               mdm->nors = mesh_build_faceNormals(ob);
+                       // XXX this is kinda hacky because we shouldn't really be editing
+                       // the mesh here, however, we can't just call mesh_build_faceNormals(ob)
+                       // because in the case when a key is applied to a mesh the vertex normals
+                       // would never be correctly computed (and renderer makes this assumption.
+               mesh_calc_normals(mdm->verts, me->totvert, me->mface, me->totface, &mdm->nors);
                mdm->freeNors = 1;
        }
 
@@ -515,6 +519,7 @@ typedef struct {
        DerivedMesh dm;
 
        EditMesh *em;
+       float (*vertexCos)[3];
 } EditMeshDerivedMesh;
 
 static void emDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
@@ -530,12 +535,23 @@ static void emDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
        EditVert *eve;
 
-       bglBegin(GL_POINTS);
-       for(eve= emdm->em->verts.first; eve; eve= eve->next) {
-               if(!setDrawOptions || setDrawOptions(userData, eve))
-                       bglVertex3fv(eve->co);
+       if (emdm->vertexCos) {
+               int i;
+
+               bglBegin(GL_POINTS);
+               for(i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
+                       if(!setDrawOptions || setDrawOptions(userData, eve))
+                               bglVertex3fv(emdm->vertexCos[i]);
+               }
+               bglEnd();               
+       } else {
+               bglBegin(GL_POINTS);
+               for(eve= emdm->em->verts.first; eve; eve= eve->next) {
+                       if(!setDrawOptions || setDrawOptions(userData, eve))
+                               bglVertex3fv(eve->co);
+               }
+               bglEnd();               
        }
-       bglEnd();               
 }
 static void emDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge)
 {
@@ -551,56 +567,106 @@ static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
        EditEdge *eed;
 
-       glBegin(GL_LINES);
-       for(eed= emdm->em->edges.first; eed; eed= eed->next) {
-               if(!setDrawOptions || setDrawOptions(userData, eed)) {
-                       glVertex3fv(eed->v1->co);
-                       glVertex3fv(eed->v2->co);
+       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)) {
+                               glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]);
+                               glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]);
+                       }
                }
+               glEnd();
+
+               for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
+                       eve->prev = preveve;
+       } else {
+               glBegin(GL_LINES);
+               for(eed= emdm->em->edges.first; eed; eed= eed->next) {
+                       if(!setDrawOptions || setDrawOptions(userData, eed)) {
+                               glVertex3fv(eed->v1->co);
+                               glVertex3fv(eed->v2->co);
+                       }
+               }
+               glEnd();
        }
-       glEnd();
+}
+static void emDM_drawEdges(DerivedMesh *dm)
+{
+       emDM_drawMappedEdgesEM(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) 
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
        EditEdge *eed;
 
-       glBegin(GL_LINES);
-       for(eed= emdm->em->edges.first; eed; eed= eed->next) {
-               if(!setDrawOptions || setDrawOptions(userData, eed)) {
-                       setDrawInterpOptions(userData, eed, 0.0);
-                       glVertex3fv(eed->v1->co);
-                       setDrawInterpOptions(userData, eed, 1.0);
-                       glVertex3fv(eed->v2->co);
+       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);
+                               glVertex3fv(emdm->vertexCos[(int) eed->v1->prev]);
+                               setDrawInterpOptions(userData, eed, 1.0);
+                               glVertex3fv(emdm->vertexCos[(int) eed->v2->prev]);
+                       }
                }
-       }
-       glEnd();
-}
-static void emDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditFace *efa;
+               glEnd();
 
-       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();
+               for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
+                       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);
+                               glVertex3fv(eed->v1->co);
+                               setDrawInterpOptions(userData, eed, 1.0);
+                               glVertex3fv(eed->v2->co);
+                       }
                }
+               glEnd();
        }
 }
-static void emDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
+static void emDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData)
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
        EditFace *efa;
 
-       for (efa= emdm->em->faces.first; efa; efa= efa->next) {
-               if(efa->h==0) {
-                       if (setMaterial(efa->mat_nr+1)) {
+       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 (efa= emdm->em->faces.first; efa; efa= efa->next) {
+                       if(!setDrawOptions || setDrawOptions(userData, efa)) {
                                glNormal3fv(efa->n);
+                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+                               glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]);
+                               glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]);
+                               glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]);
+                               if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]);
+                               glEnd();
+                       }
+               }
+
+               for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
+                       eve->prev = preveve;
+       } else {
+               for (efa= emdm->em->faces.first; efa; efa= efa->next) {
+                       if(!setDrawOptions || setDrawOptions(userData, efa)) {
                                glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
                                glVertex3fv(efa->v1->co);
                                glVertex3fv(efa->v2->co);
@@ -611,15 +677,64 @@ static void emDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
                }
        }
 }
+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 (efa= emdm->em->faces.first; efa; efa= efa->next) {
+                       if(efa->h==0) {
+                               if (setMaterial(efa->mat_nr+1)) {
+                                       glNormal3fv(efa->n);
+                                       glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
+                                       glVertex3fv(emdm->vertexCos[(int) efa->v1->prev]);
+                                       glVertex3fv(emdm->vertexCos[(int) efa->v2->prev]);
+                                       glVertex3fv(emdm->vertexCos[(int) efa->v3->prev]);
+                                       if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->prev]);
+                                       glEnd();
+                               }
+                       }
+               }
+
+               for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
+                       eve->prev = preveve;
+       } else {
+               for (efa= emdm->em->faces.first; efa; efa= efa->next) {
+                       if(efa->h==0) {
+                               if (setMaterial(efa->mat_nr+1)) {
+                                       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();
+                               }
+                       }
+               }
+       }
+}
 
 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
        EditVert *eve;
+       int i;
 
        if (emdm->em->verts.first) {
-               for (eve= emdm->em->verts.first; eve; eve= eve->next) {
-                       DO_MINMAX(eve->co, min_r, max_r);
+               for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
+                       if (emdm->vertexCos) {
+                               DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
+                       } else {
+                               DO_MINMAX(eve->co, min_r, max_r);
+                       }
                }
        } else {
                min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
@@ -638,7 +753,17 @@ static int emDM_getNumFaces(DerivedMesh *dm)
        return BLI_countlist(&emdm->em->faces);
 }
 
-static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em)
+static void emDM_release(DerivedMesh *dm)
+{
+       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
+
+       if (emdm->vertexCos)
+               MEM_freeN(emdm->vertexCos);
+
+       MEM_freeN(emdm);
+}
+
+static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, float (*vertexCos)[3])
 {
        EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
 
@@ -650,6 +775,7 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em)
 
        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;
@@ -657,9 +783,10 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em)
        emdm->dm.drawFacesSolid = emDM_drawFacesSolid;
        emdm->dm.drawMappedFacesEM = emDM_drawMappedFacesEM;
 
-       emdm->dm.release = (void(*)(DerivedMesh*)) MEM_freeN;
+       emdm->dm.release = emDM_release;
        
        emdm->em = em;
+       emdm->vertexCos = vertexCos;
 
        return (DerivedMesh*) emdm;
 }
@@ -994,13 +1121,27 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm)
 
 /***/
 
+typedef float vec3f[3];
+
+static vec3f *mesh_getVertexCos(Mesh *me, int *numVerts_r)
+{
+       int i, numVerts = *numVerts_r = me->totvert;
+       float (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos1");
+
+       for (i=0; i<numVerts; i++) {
+               VECCOPY(cos[i], me->mvert[i].co);
+       }
+
+       return cos;
+}
+
 static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform)
 {
        Mesh *me = ob->data;
        ModifierData *md= ob->modifiers.first;
        float (*deformedVerts)[3];
        DerivedMesh *dm;
-       int a, numVerts = me->totvert;
+       int numVerts = me->totvert;
 
        if (deform_r) *deform_r = NULL;
        *final_r = NULL;
@@ -1008,14 +1149,6 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
        if (useDeform) {
                mesh_modifier(ob, &deformedVerts);
 
-                       // XXX this copy should be done on demand
-               if (!deformedVerts) {
-                       deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "vertexcos1");
-                       for (a=0; a<numVerts; a++) {
-                               VECCOPY(deformedVerts[a], me->mvert[a].co);
-                       }
-               }
-
                        /* Apply all leading deforming modifiers */
                for (; md; md=md->next) {
                        ModifierTypeInfo *mti = modifierType_get_info(md->type);
@@ -1024,7 +1157,8 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
                        if (mti->isDisabled && mti->isDisabled(md)) continue;
 
                        if (mti->type==eModifierTypeType_OnlyDeform) {
-                               mti->deformVerts(md, ob, deformedVerts, numVerts);
+                               if (!deformedVerts) deformedVerts = mesh_getVertexCos(me, &numVerts);
+                               mti->deformVerts(md, ob, NULL, deformedVerts, numVerts);
                        } else {
                                break;
                        }
@@ -1066,27 +1200,23 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
                                        deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "dfmv");
                                        dm->getVertCos(dm, deformedVerts);
                                } else {
-                                       numVerts = me->totvert;
-                                       deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "vertexcos2");
-                                       for (a=0; a<numVerts; a++) {
-                                               VECCOPY(deformedVerts[a], me->mvert[a].co);
-                                       }
+                                       deformedVerts = mesh_getVertexCos(me, &numVerts);
                                }
                        }
 
-                       mti->deformVerts(md, ob, deformedVerts, numVerts);
+                       mti->deformVerts(md, ob, dm, deformedVerts, numVerts);
                } else {
                                /* There are 4 cases here (have deform? have dm?) but they all are handled
                                 * by the modifier apply function, which will also free the DerivedMesh if
                                 * it exists.
                                 */
-                       dm = mti->applyModifier(md, ob, dm, deformedVerts, useRenderParams);
+                       dm = mti->applyModifier(md, ob, dm, deformedVerts, useRenderParams, !inputVertexCos);
 
                        if (deformedVerts) {
                                if (deformedVerts!=inputVertexCos) {
                                        MEM_freeN(deformedVerts);
                                }
-                               deformedVerts = 0;
+                               deformedVerts = NULL;
                        }
                }
        }
@@ -1126,6 +1256,111 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
        }
 }
 
+static vec3f *editmesh_getVertexCos(EditMesh *em, int *numVerts_r)
+{
+       int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
+       float (*cos)[3];
+       EditVert *eve;
+
+       cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
+       for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
+               VECCOPY(cos[i], eve->co);
+       }
+
+       return cos;
+}
+
+static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
+{
+       Object *ob = G.obedit;
+       EditMesh *em = G.editMesh;
+       ModifierData *md= ob->modifiers.first;
+       float (*deformedVerts)[3] = NULL;
+       DerivedMesh *dm;
+       int numVerts;
+
+       if (cage_r) *cage_r = NULL;
+       *final_r = NULL;
+
+       *cage_r = getEditMeshDerivedMesh(em, NULL);
+
+//     mesh_modifier(ob, &deformedVerts);
+
+       dm = NULL;
+       for (; md; md=md->next) {
+               ModifierTypeInfo *mti = modifierType_get_info(md->type);
+
+               if (!(md->mode&1)) continue;
+               if (mti->isDisabled && mti->isDisabled(md)) continue;
+               if (!(mti->flags&eModifierTypeFlag_SupportsEditmode)) continue;
+
+                       /* How to apply modifier depends on (a) what we already have as
+                        * a result of previous modifiers (could be a DerivedMesh or just
+                        * deformed vertices) and (b) what type the modifier is.
+                        */
+
+               if (mti->type==eModifierTypeType_OnlyDeform) {
+                               /* No existing verts to deform, need to build them. */
+                       if (!deformedVerts) {
+                               if (dm) {
+                                               /* Deforming a derived mesh, read the vertex locations out of the mesh and
+                                                * deform them. Once done with this run of deformers verts will be written back.
+                                                */
+                                       numVerts = dm->getNumVerts(dm);
+                                       deformedVerts = MEM_mallocN(sizeof(*deformedVerts)*numVerts, "dfmv");
+                                       dm->getVertCos(dm, deformedVerts);
+                               } else {
+                                       deformedVerts = editmesh_getVertexCos(em, &numVerts);
+                               }
+                       }
+
+                       mti->deformVertsEM(md, ob, em, dm, deformedVerts, numVerts);
+               } else {
+                               /* There are 4 cases here (have deform? have dm?) but they all are handled
+                                * by the modifier apply function, which will also free the DerivedMesh if
+                                * it exists.
+                                */
+                       dm = mti->applyModifierEM(md, ob, em, dm, deformedVerts);
+
+                       if (deformedVerts) {
+                               MEM_freeN(deformedVerts);
+                               deformedVerts = NULL;
+                       }
+               }
+       }
+
+               /* Yay, we are done. If we have a DerivedMesh and deformed vertices need to apply
+                * these back onto the DerivedMesh. If we have no DerivedMesh then we need to build
+                * one.
+                */
+       if (dm && deformedVerts) {
+               DispListMesh *dlm = dm->convertToDispListMesh(dm); // XXX what if verts or nors were shared
+               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);
+               MEM_freeN(deformedVerts);
+       } else if (dm) {
+               *final_r = dm;
+       } else {
+               *final_r = getEditMeshDerivedMesh(em, deformedVerts);
+       }
+}
+
 /***/
 
 static void clear_mesh_caches(Object *ob)
@@ -1171,6 +1406,8 @@ static void mesh_build_data(Object *ob)
 
 static void editmesh_build_data(void)
 {
+       float min[3], max[3];
+
        EditMesh *em = G.editMesh;
 
        clear_mesh_caches(G.obedit);
@@ -1186,21 +1423,11 @@ static void editmesh_build_data(void)
                em->derivedCage = NULL;
        }
 
-/*
-       if ((me->flag&ME_SUBSURF) && me->subdiv) {
-               em->derivedFinal = subsurf_make_derived_from_editmesh(em, me->subdiv, me->subsurftype, NULL);
+       editmesh_calc_modifiers(&em->derivedCage, &em->derivedFinal);
 
-               if (me->flag&ME_OPT_EDGES) {
-                       em->derivedCage = em->derivedFinal;
-               } else {
-                       em->derivedCage = getEditMeshDerivedMesh(em);
-               }
-       } else {
-*/
-       em->derivedFinal = em->derivedCage = getEditMeshDerivedMesh(em);
-/*
-       }
-*/
+       em->derivedFinal->getMinMax(em->derivedFinal, min, max);
+
+       boundbox_set_from_min_max(mesh_get_bb(G.obedit->data), min, max);
 }
 
 void makeDispListMesh(Object *ob)
index 8fbb10d46b95e33f5480c67c15f799829e3c3ead..ada30151d1e71dcf9735f73e7f1ee275aea17f73 100644 (file)
@@ -717,101 +717,98 @@ void shadeDispList(Object *ob)
                DerivedMesh *dm= mesh_get_derived_final(ob, &dmNeedsFree);
                DispListMesh *dlm;
                MVert *mvert;
-
+               float *vnors, *vn;
+               int i;
+                       
                if (need_orco) {
                        orco = mesh_create_orco(ob);
                }
 
                dlm= dm->convertToDispListMesh(dm);
 
-               if (dlm && dlm->totvert) {
-                       float *vnors, *vn;
-                       int i;
-                       
-                       dlob= MEM_callocN(sizeof(DispList), "displistshade");
-                       BLI_addtail(&ob->disp, dlob);
-                       dlob->type= DL_VERTCOL;
+               dlob= MEM_callocN(sizeof(DispList), "displistshade");
+               BLI_addtail(&ob->disp, dlob);
+               dlob->type= DL_VERTCOL;
+       
+               dlob->col1= MEM_mallocN(sizeof(*dlob->col1)*dlm->totface*4, "col1");
+               if (me->flag & ME_TWOSIDED)
+                       dlob->col2= MEM_mallocN(sizeof(*dlob->col2)*dlm->totface*4, "col1");
                
-                       dlob->col1= MEM_mallocN(sizeof(*dlob->col1)*dlm->totface*4, "col1");
-                       if (me->flag & ME_TWOSIDED)
-                               dlob->col2= MEM_mallocN(sizeof(*dlob->col2)*dlm->totface*4, "col1");
+               /* vertexnormals */
+               vn=vnors= MEM_mallocN(dlm->totvert*3*sizeof(float), "vnors disp");
+               mvert= dlm->mvert;
+               a= dlm->totvert;
+               while(a--) {
                        
-                       /* vertexnormals */
-                       vn=vnors= MEM_mallocN(dlm->totvert*3*sizeof(float), "vnors disp");
-                       mvert= dlm->mvert;
-                       a= dlm->totvert;
-                       while(a--) {
-                               
-                               xn= mvert->no[0]; 
-                               yn= mvert->no[1]; 
-                               zn= mvert->no[2];
+                       xn= mvert->no[0]; 
+                       yn= mvert->no[1]; 
+                       zn= mvert->no[2];
+                       
+                       /* transpose ! */
+                       vn[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
+                       vn[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
+                       vn[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
+                       Normalise(vn);
+                       
+                       mvert++; vn+=3;
+               }               
+
+               for (i=0; i<dlm->totface; i++) {
+                       MFace *mf= &dlm->mface[i];
+
+                       if (mf->v3) {
+                               int j, vidx[4], nverts= mf->v4?4:3;
+                               unsigned char *col1base= (unsigned char*) &dlob->col1[i*4];
+                               unsigned char *col2base= (unsigned char*) (dlob->col2?&dlob->col2[i*4]:NULL);
+                               unsigned char *mcolbase;
+                               float nor[3];
                                
-                               /* transpose ! */
-                               vn[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
-                               vn[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
-                               vn[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
-                               Normalise(vn);
+                               if (dlm->tface) {
+                                       mcolbase = (unsigned char*) dlm->tface[i].col;
+                               } else if (dlm->mcol) {
+                                       mcolbase = (unsigned char*) &dlm->mcol[i*4];
+                               } else {
+                                       mcolbase = NULL;
+                               }
+
+                               ma= give_current_material(ob, mf->mat_nr+1);
+                               if(ma==0) ma= &defmaterial;
                                
-                               mvert++; vn+=3;
-                       }               
-       
-                       for (i=0; i<dlm->totface; i++) {
-                               MFace *mf= &dlm->mface[i];
-
-                               if (mf->v3) {
-                                       int j, vidx[4], nverts= mf->v4?4:3;
-                                       unsigned char *col1base= (unsigned char*) &dlob->col1[i*4];
-                                       unsigned char *col2base= (unsigned char*) (dlob->col2?&dlob->col2[i*4]:NULL);
-                                       unsigned char *mcolbase;
-                                       float nor[3];
-                                       
-                                       if (dlm->tface) {
-                                               mcolbase = (unsigned char*) dlm->tface[i].col;
-                                       } else if (dlm->mcol) {
-                                               mcolbase = (unsigned char*) &dlm->mcol[i*4];
-                                       } else {
-                                               mcolbase = NULL;
-                                       }
+                               vidx[0]= mf->v1;
+                               vidx[1]= mf->v2;
+                               vidx[2]= mf->v3;
+                               vidx[3]= mf->v4;
+
+                                       // XXX, should all DLM's have normals?
+                               if (dlm->nors) {
+                                       VECCOPY(nor, &dlm->nors[i*3]);
+                               } else {
+                                       if (mf->v4)
+                                               CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, nor);
+                                       else
+                                               CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, nor);
+                               }
 
-                                       ma= give_current_material(ob, mf->mat_nr+1);
-                                       if(ma==0) ma= &defmaterial;
+                               n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
+                               n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
+                               n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
+                               Normalise(n1);
+
+                               vn = n1;
+                               for (j=0; j<nverts; j++) {
+                                       MVert *mv= &dlm->mvert[vidx[j]];
+                                       unsigned char *col1= &col1base[j*4];
+                                       unsigned char *col2= col2base?&col2base[j*4]:NULL;
+                                       unsigned char *mcol= mcolbase?&mcolbase[j*4]:NULL;
                                        
-                                       vidx[0]= mf->v1;
-                                       vidx[1]= mf->v2;
-                                       vidx[2]= mf->v3;
-                                       vidx[3]= mf->v4;
-
-                                               // XXX, should all DLM's have normals?
-                                       if (dlm->nors) {
-                                               VECCOPY(nor, &dlm->nors[i*3]);
-                                       } else {
-                                               if (mf->v4)
-                                                       CalcNormFloat4(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, dlm->mvert[mf->v4].co, nor);
-                                               else
-                                                       CalcNormFloat(dlm->mvert[mf->v1].co, dlm->mvert[mf->v2].co, dlm->mvert[mf->v3].co, nor);
-                                       }
-
-                                       n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2];
-                                       n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2];
-                                       n1[2]= imat[2][0]*nor[0]+imat[2][1]*nor[1]+imat[2][2]*nor[2];
-                                       Normalise(n1);
-
-                                       vn = n1;
-                                       for (j=0; j<nverts; j++) {
-                                               MVert *mv= &dlm->mvert[vidx[j]];
-                                               unsigned char *col1= &col1base[j*4];
-                                               unsigned char *col2= col2base?&col2base[j*4]:NULL;
-                                               unsigned char *mcol= mcolbase?&mcolbase[j*4]:NULL;
-                                               
-                                               VECCOPY(vec, mv->co);
-                                               Mat4MulVecfl(mat, vec);
-                                               if(mf->flag & ME_SMOOTH) vn= vnors+3*vidx[j];
-                                               fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2, mcol);
-                                       }
+                                       VECCOPY(vec, mv->co);
+                                       Mat4MulVecfl(mat, vec);
+                                       if(mf->flag & ME_SMOOTH) vn= vnors+3*vidx[j];
+                                       fastshade(vec, vn, orco?&orco[vidx[j]*3]:mv->co, ma, col1, col2, mcol);
                                }
                        }
-                       MEM_freeN(vnors);
                }
+               MEM_freeN(vnors);
                displistmesh_free(dlm);
 
                if (orco) {
index 4713f13c9b9940379d8589992630ea5158ee5ab3..8c2ee1334872f35fc6923dd1cc49ef1fe886836e 100644 (file)
@@ -790,7 +790,12 @@ void make_edges(Mesh *me)
                else totedge+=1;
        }
        
-       if(totedge==0) return;
+       if(totedge==0) {
+                       /* flag that mesh has edges */
+               me->medge = MEM_callocN(0, "make mesh edges");
+               me->totedge = 0;
+               return;
+       }
        
        ed= edsort= MEM_mallocN(totedge*sizeof(struct edgesort), "edgesort");
        
index ad52d58a35f43fd7b601d51599cac5cfca8c71b3..d9bcbc29e9b80d74bf00589a3247badafbdf8cd0 100644 (file)
@@ -1,5 +1,6 @@
 #include "string.h"
 
+#include "BLI_blenlib.h"
 #include "BLI_rand.h"
 
 #include "MEM_guardedalloc.h"
@@ -9,6 +10,7 @@
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "BLI_editVert.h"
 
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
@@ -50,7 +52,14 @@ static void curveModifier_updateDepgraph(ModifierData *md, DagForest *forest, Ob
        }
 }
 
-static void curveModifier_deformVerts(ModifierData *md, Object *ob, float (*vertexCos)[3], int numVerts)
+static void curveModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts)
+{
+       CurveModifierData *cmd = (CurveModifierData*) md;
+
+       curve_deform_verts(cmd->object, ob, vertexCos, numVerts);
+}
+
+static void curveModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts)
 {
        CurveModifierData *cmd = (CurveModifierData*) md;
 
@@ -77,7 +86,14 @@ static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest,
        }
 }
 
-static void latticeModifier_deformVerts(ModifierData *md, Object *ob, float (*vertexCos)[3], int numVerts)
+static void latticeModifier_deformVerts(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int numVerts)
+{
+       LatticeModifierData *lmd = (LatticeModifierData*) md;
+
+       lattice_deform_verts(lmd->object, ob, vertexCos, numVerts);
+}
+
+static void latticeModifier_deformVertsEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3], int numVerts)
 {
        LatticeModifierData *lmd = (LatticeModifierData*) md;
 
@@ -101,9 +117,12 @@ static void subsurfModifier_freeData(ModifierData *md)
        if (smd->mCache) {
                ccgSubSurf_free(smd->mCache);
        }
+       if (smd->emCache) {
+               ccgSubSurf_free(smd->emCache);
+       }
 }      
 
-static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams)
+static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm = derivedData;
        SubsurfModifierData *smd = (SubsurfModifierData*) md;
@@ -122,12 +141,39 @@ static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, void *d
                }
                dm->release(dm);
 
-               dm = subsurf_make_derived_from_mesh(me, dlm, smd, useRenderParams, NULL);
-               displistmesh_free(dlm);
+               dm = subsurf_make_derived_from_mesh(me, dlm, smd, useRenderParams, NULL, isFinalCalc);
+
+               return dm;
+       } else {
+               return subsurf_make_derived_from_mesh(me, NULL, smd, useRenderParams, vertexCos, isFinalCalc);
+       }
+}
+
+static void *subsurfModifier_applyModifierEM(ModifierData *md, Object *ob, void *editData, void *derivedData, float (*vertexCos)[3])
+{
+       EditMesh *em = editData;
+       DerivedMesh *dm = derivedData;
+       SubsurfModifierData *smd = (SubsurfModifierData*) md;
+
+       if (dm) {
+               DispListMesh *dlm = dm->convertToDispListMesh(dm); // XXX what if verts were shared
+               int i;
+
+               if (vertexCos) {
+                       int numVerts = dm->getNumVerts(dm);
+
+                       for (i=0; i<numVerts; i++) {
+                               VECCOPY(dlm->mvert[i].co, vertexCos[i]);
+                       }
+               }
+               dm->release(dm);
+
+                       // XXX, should I worry about reuse of mCache in editmode?
+               dm = subsurf_make_derived_from_mesh(NULL, dlm, smd, 0, NULL, 1);
 
                return dm;
        } else {
-               return subsurf_make_derived_from_mesh(me, NULL, smd, useRenderParams, vertexCos);
+               return subsurf_make_derived_from_editmesh(em, smd, vertexCos);
        }
 }
 
@@ -146,7 +192,7 @@ static int buildModifier_dependsOnTime(ModifierData *md)
        return 1;
 }
 
-static void *buildModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams)
+static void *buildModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm = derivedData;
        BuildModifierData *bmd = (BuildModifierData*) md;
@@ -370,56 +416,20 @@ static void mirrorModifier_initData(ModifierData *md)
        mmd->tolerance = 0.001;
 }
 
-static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *derivedData, float (*vertexCos)[3], int useRenderParams)
+static void mirrorModifier__doMirror(MirrorModifierData *mmd, DispListMesh *ndlm, float (*vertexCos)[3])
 {
-       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;
-       int i, j, totvert, totedge, totface;
-       int axis = mmd->axis;
+       int totvert=ndlm->totvert, totedge=ndlm->totedge, totface=ndlm->totface;
+       int i, axis = mmd->axis;
        float tolerance = mmd->tolerance;
 
-       if (dm) {
-               dlm = dm->convertToDispListMesh(dm);
-
-               mvert = dlm->mvert;
-               medge = dlm->medge;
-               mface = dlm->mface;
-               tface = dlm->tface;
-               mcol = dlm->mcol;
-               totvert = dlm->totvert;
-               totedge = dlm->totedge;
-               totface = dlm->totface;
-       } else {
-               Mesh *me = ob->data;
-
-               mvert = me->mvert;
-               medge = me->medge;
-               mface = me->mface;
-               tface = me->tface;
-               mcol = me->mcol;
-               totvert = me->totvert;
-               totedge = me->totedge;
-               totface = me->totface;
-       }
-
-       ndlm->mvert = MEM_mallocN(sizeof(*mvert)*totvert*2, "mm_mv");
-       for (i=0,j=totvert; i<totvert; i++) {
-               MVert *mv = &mvert[i];
-               MVert *nmv = &ndlm->mvert[i];
-
-               memcpy(nmv, mv, sizeof(*mv));
+       for (i=0; i<totvert; i++) {
+               MVert *mv = &ndlm->mvert[i];
 
-               if (ABS(nmv->co[axis])<=tolerance) {
-                       nmv->co[axis] = 0;
-                       *((int*) nmv->no) = i;
+               if (ABS(mv->co[axis])<=tolerance) {
+                       mv->co[axis] = 0;
+                       *((int*) mv->no) = i;
                } else {
-                       MVert *nmvMirror = &ndlm->mvert[j];
+                       MVert *nmv = &ndlm->mvert[ndlm->totvert];
 
                                /* Because the topology result (# of vertices) must stuff the same
                                 * if the mesh data is overridden by vertex cos, have to calc sharedness
@@ -427,22 +437,17 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de
                                 * vertices.
                                 */
                        if (vertexCos) {
-                               VECCOPY(nmv->co, vertexCos[i]);
+                               VECCOPY(mv->co, vertexCos[i]);
                        }
 
-                       memcpy(nmvMirror, nmv, sizeof(*mv));
-                       nmvMirror->co[axis] = -nmvMirror->co[axis];
+                       memcpy(nmvmv, sizeof(*mv));
+                       nmv ->co[axis] = -nmv ->co[axis];
 
-                       *((int*) nmv->no) = j++;
+                       *((int*) mv->no) = ndlm->totvert++;
                }
        }
-       ndlm->totvert = j;
-
-       if (medge) {
-               ndlm->medge = MEM_mallocN(sizeof(*medge)*totedge*2, "mm_med");
-               memcpy(ndlm->medge, medge, sizeof(*medge)*totedge);
-               ndlm->totedge = totedge;
 
+       if (ndlm->medge) {
                for (i=0; i<totedge; i++) {
                        MEdge *med = &ndlm->medge[i];
                        MEdge *nmed = &ndlm->medge[ndlm->totedge];
@@ -458,18 +463,6 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de
                }
        }
 
-       ndlm->mface = MEM_mallocN(sizeof(*mface)*totface*2, "mm_mf");
-       memcpy(ndlm->mface, mface, sizeof(*mface)*totface);
-
-       if (tface) {
-               ndlm->tface = MEM_mallocN(sizeof(*tface)*totface*2, "mm_tf");
-               memcpy(ndlm->tface, tface, sizeof(*tface)*totface);
-       } else if (mcol) {
-               ndlm->mcol = MEM_mallocN(sizeof(*mcol)*4*totface*2, "mm_mcol");
-               memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*totface);
-       }
-
-       ndlm->totface = totface;
        for (i=0; i<totface; i++) {
                MFace *mf = &ndlm->mface[i];
                MFace *nmf = &ndlm->mface[ndlm->totface];
@@ -477,14 +470,14 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de
                MCol *mc=NULL, *nmc=NULL; /* gcc's mother is uninitialized! */
 
                memcpy(nmf, mf, sizeof(*mf));
-               if (tface) {
+               if (ndlm->tface) {
                        ntf = &ndlm->tface[ndlm->totface];
                        tf = &ndlm->tface[i];
-                       memcpy(ntf, tf, sizeof(*tface));
-               } else if (mcol) {
+                       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(*mcol)*4);
+                       memcpy(nmc, mc, sizeof(*ndlm->mcol)*4);
                }
 
                        /* Map vertices to shared */
@@ -529,11 +522,11 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de
                                if (copyIdx!=-1) {
                                        int fromIdx = (copyIdx+2)%4;
 
-                                       if (tface) {
+                                       if (ndlm->tface) {
                                                tf->col[copyIdx] = ntf->col[fromIdx];
                                                tf->uv[copyIdx][0] = ntf->uv[fromIdx][0];
                                                tf->uv[copyIdx][1] = ntf->uv[fromIdx][1];
-                                       } else if (mcol) {
+                                       } else if (ndlm->mcol) {
                                                mc[copyIdx] = nmc[fromIdx];
                                        }
 
@@ -547,21 +540,21 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de
                        if (nmf->v1) {
                                SWAP(int, nmf->v1, nmf->v3);
 
-                               if (tface) {
+                               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 (mcol) {
+                               } else if (ndlm->mcol) {
                                        SWAP(MCol, nmc[0], nmc[2]);
                                }
                        } else {
                                SWAP(int, nmf->v2, nmf->v4);
 
-                               if (tface) {
+                               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 (mcol) {
+                               } else if (ndlm->mcol) {
                                        SWAP(MCol, nmc[1], nmc[3]);
                                }
                        }
@@ -569,6 +562,63 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de
 
                ndlm->totface++;
        }
+}
+
+static void *mirrorModifier_applyModifier(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;
+
+       if (dm) {
+               dlm = dm->convertToDispListMesh(dm);
+
+               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;
+       } 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);
+       }
+
+       ndlm->mface = MEM_mallocN(sizeof(*mface)*ndlm->totface*2, "mm_mf");
+       memcpy(ndlm->mface, mface, sizeof(*mface)*ndlm->totface);
+
+       if (tface) {
+               ndlm->tface = MEM_mallocN(sizeof(*tface)*ndlm->totface*2, "mm_tf");
+               memcpy(ndlm->tface, tface, sizeof(*tface)*ndlm->totface);
+       } else if (mcol) {
+               ndlm->mcol = MEM_mallocN(sizeof(*mcol)*4*ndlm->totface*2, "mm_mcol");
+               memcpy(ndlm->mcol, mcol, sizeof(*mcol)*4*ndlm->totface);
+       }
+
+       mirrorModifier__doMirror(mmd, ndlm, vertexCos);
 
        if (dlm) displistmesh_free(dlm);
        if (dm) dm->release(dm);
@@ -578,6 +628,64 @@ static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, void *de
        return derivedmesh_from_displistmesh(ndlm);
 }
 
+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);
+       } else {
+               MirrorModifierData *mmd = (MirrorModifierData*) md;
+               DispListMesh *ndlm = MEM_callocN(sizeof(*ndlm), "mm_dlm");
+               int i, axis = mmd->axis;
+               float tolerance = mmd->tolerance;
+               EditMesh *em = editData;
+               EditVert *eve, *preveve;
+               EditEdge *eed;
+               EditFace *efa;
+
+               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);
+
+               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");
+
+               for (i=0,eve=em->verts.first; i<ndlm->totvert; i++,eve=eve->next) {
+                       MVert *mv = &ndlm->mvert[i];
+
+                       VECCOPY(mv->co, eve->co);
+               }
+               for (i=0,eed=em->edges.first; i<ndlm->totedge; i++,eed=eed->next) {
+                       MEdge *med = &ndlm->medge[i];
+
+                       med->v1 = (int) eed->v1->prev;
+                       med->v2 = (int) eed->v2->prev;
+                       med->crease = eed->crease;
+               }
+               for (i=0,efa=em->faces.first; i<ndlm->totface; i++,efa=efa->next) {
+                       MFace *mf = &ndlm->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;
+               }
+
+               mirrorModifier__doMirror(mmd, ndlm, vertexCos);
+
+               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);
+       }
+}
+
 /***/
 
 static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
@@ -611,24 +719,27 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type)
 
                mti = INIT_TYPE(Curve);
                mti->type = eModifierTypeType_OnlyDeform;
-               mti->flags = eModifierTypeFlag_AcceptsCVs;
+               mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode;
                mti->isDisabled = curveModifier_isDisabled;
                mti->updateDepgraph = curveModifier_updateDepgraph;
                mti->deformVerts = curveModifier_deformVerts;
+               mti->deformVertsEM = curveModifier_deformVertsEM;
 
                mti = INIT_TYPE(Lattice);
                mti->type = eModifierTypeType_OnlyDeform;
-               mti->flags = eModifierTypeFlag_AcceptsCVs;
+               mti->flags = eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode;
                mti->isDisabled = latticeModifier_isDisabled;
                mti->updateDepgraph = latticeModifier_updateDepgraph;
                mti->deformVerts = latticeModifier_deformVerts;
+               mti->deformVertsEM = latticeModifier_deformVertsEM;
 
                mti = INIT_TYPE(Subsurf);
                mti->type = eModifierTypeType_Constructive;
-               mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping;
+               mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode;
                mti->initData = subsurfModifier_initData;
                mti->freeData = subsurfModifier_freeData;
                mti->applyModifier = subsurfModifier_applyModifier;
+               mti->applyModifierEM = subsurfModifier_applyModifierEM;
 
                mti = INIT_TYPE(Build);
                mti->type = eModifierTypeType_Nonconstructive;
@@ -639,9 +750,10 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type)
 
                mti = INIT_TYPE(Mirror);
                mti->type = eModifierTypeType_Constructive;
-               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode;
                mti->initData = mirrorModifier_initData;
                mti->applyModifier = mirrorModifier_applyModifier;
+               mti->applyModifierEM = mirrorModifier_applyModifierEM;
 
                typeArrInit = 0;
 #undef INIT_TYPE
index 7c5022e3fde2788a8ef819b33af2e5e4a780b5a9..db874df01cdbc47008b454314bdb067cf27b0f77 100644 (file)
@@ -517,7 +517,7 @@ static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float
                        MFace *mf = &((MFace*) mface)[i];
 
                        if (!mf->v3) {
-                               ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0);
+                               ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0f);
                        }
                }
        }
@@ -538,7 +538,7 @@ static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float
        ccgSubSurf_processSync(ss);
 }
 
-void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, int useFlatSubdiv)
+void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, float (*vertCos)[3], int useFlatSubdiv)
 {
        float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
        EditVert *ev, *fVerts[4];
@@ -547,8 +547,16 @@ void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, int useFlatSubdiv)
 
        ccgSubSurf_initFullSync(ss);
 
-       for (ev=em->verts.first; ev; ev=ev->next) {
-               ccgSubSurf_syncVert(ss, ev, ev->co);
+       if (vertCos) {
+               int i=0;
+
+               for (ev=em->verts.first; ev; ev=ev->next) {
+                       ccgSubSurf_syncVert(ss, ev, vertCos[i++]);
+               }
+       } else {
+               for (ev=em->verts.first; ev; ev=ev->next) {
+                       ccgSubSurf_syncVert(ss, ev, ev->co);
+               }
        }
 
        for (ee=em->edges.first; ee; ee=ee->next) {
@@ -574,6 +582,9 @@ typedef struct {
 
        CCGSubSurf *ss;
        int fromEditmesh;
+
+       Mesh *me;
+       DispListMesh *dlm;
 } CCGDerivedMesh;
 
 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
@@ -599,7 +610,7 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
                VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
 
-               for (i=1; i<edgeSize-1; i++)
+               for (i=0; i<edgeSize; i++)
                        DO_MINMAX(edgeData[i].co, min_r, max_r);
        }
 
@@ -610,8 +621,6 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
                for (S=0; S<numVerts; S++) {
                        VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
 
-                       for (x=0; x<gridSize; x++)
-                               DO_MINMAX(faceGridData[x].co, min_r, max_r);
                        for (y=0; y<gridSize; y++)
                                for (x=0; x<gridSize; x++)
                                        DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
@@ -632,6 +641,50 @@ static int ccgDM_getNumFaces(DerivedMesh *dm) {
 
        return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
 }
+static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
+       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = ccgdm->ss;
+       int edgeSize = ccgSubSurf_getEdgeSize(ss);
+       int gridSize = ccgSubSurf_getGridSize(ss);
+       int i;
+       CCGVertIterator *vi;
+       CCGEdgeIterator *ei;
+       CCGFaceIterator *fi;
+
+       i = 0;
+       vi = ccgSubSurf_getVertIterator(ss);
+       for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
+               CCGVert *v = ccgVertIterator_getCurrent(vi);
+               VecCopyf(cos[i++], ccgSubSurf_getVertData(ss, v));
+       }
+       ccgVertIterator_free(vi);
+
+       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(cos[i++], ccgSubSurf_getEdgeData(ss, e, x));
+       }
+       ccgEdgeIterator_free(ei);
+
+       fi = ccgSubSurf_getFaceIterator(ss);
+       for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
+               CCGFace *f = ccgFaceIterator_getCurrent(fi);
+               int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
+
+               VecCopyf(cos[i++], ccgSubSurf_getFaceCenterData(ss, f));
+               for (S=0; S<numVerts; S++)
+                       for (x=1; x<gridSize-1; x++)
+                               VecCopyf(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
+               for (S=0; S<numVerts; S++)
+                       for (y=1; y<gridSize-1; y++)
+                               for (x=1; x<gridSize-1; x++)
+                                       VecCopyf(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y));
+       }
+       ccgFaceIterator_free(fi);
+}
 static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
        CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert);
@@ -644,11 +697,52 @@ static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
 static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 
-       return ss_to_displistmesh(ccgdm->ss, 1, NULL, NULL);
+       return ss_to_displistmesh(ccgdm->ss, ccgdm->fromEditmesh, ccgdm->me, ccgdm->dlm);
 }
 
 static void ccgDM_drawVerts(DerivedMesh *dm) {
-//     CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = ccgdm->ss;
+       int edgeSize = ccgSubSurf_getEdgeSize(ss);
+       int gridSize = ccgSubSurf_getGridSize(ss);
+       CCGVertIterator *vi;
+       CCGEdgeIterator *ei;
+       CCGFaceIterator *fi;
+
+       glBegin(GL_POINTS);
+       vi = ccgSubSurf_getVertIterator(ss);
+       for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
+               CCGVert *v = ccgVertIterator_getCurrent(vi);
+               glVertex3fv(ccgSubSurf_getVertData(ss, v));
+       }
+       ccgVertIterator_free(vi);
+
+       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++)
+                       glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x));
+       }
+       ccgEdgeIterator_free(ei);
+
+       fi = ccgSubSurf_getFaceIterator(ss);
+       for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
+               CCGFace *f = ccgFaceIterator_getCurrent(fi);
+               int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
+
+               glVertex3fv(ccgSubSurf_getFaceCenterData(ss, f));
+               for (S=0; S<numVerts; S++)
+                       for (x=1; x<gridSize-1; x++)
+                               glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x));
+               for (S=0; S<numVerts; S++)
+                       for (y=1; y<gridSize-1; y++)
+                               for (x=1; x<gridSize-1; x++)
+                                       glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y));
+       }
+       ccgFaceIterator_free(fi);
+       glEnd();
 }
 static void ccgDM_drawEdges(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
@@ -776,29 +870,30 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
                int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
-               int isSmooth;
+               unsigned char flag,mat_nr;
 
                if (ccgdm->fromEditmesh) {
                        EditFace *efa = ccgSubSurf_getFaceFaceHandle(ss, f);
-                       isSmooth = efa->flag&ME_SMOOTH;
                        if (efa->h!=0)
                                continue;
-                       if (!setMaterial(efa->mat_nr+1))
-                               continue;
+
+                       flag = efa->flag;
+                       mat_nr = efa->mat_nr;
                } else {
-                               // XXX, can't do these correctly, handle info could have been
-                               // free'd if came from a dlm
-                       isSmooth = 0;
-//                     if (!setMaterial(efa->mat_nr+1))
-//                             continue;
+                       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))
+                       continue;
 
-               glShadeModel(isSmooth?GL_SMOOTH:GL_FLAT);
+               glShadeModel((flag&ME_SMOOTH)?GL_SMOOTH:GL_FLAT);
                for (S=0; S<numVerts; S++) {
                        VertData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S);
 
-                       if (isSmooth) {
+                       if (flag&ME_SMOOTH) {
                                for (y=0; y<gridSize-1; y++) {
                                        glBegin(GL_QUAD_STRIP);
                                        for (x=0; x<gridSize; x++) {
@@ -843,10 +938,186 @@ static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
        ccgFaceIterator_free(fi);
 }
 static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
-//     CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = ccgdm->ss;
+       CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
+       int gridSize = ccgSubSurf_getGridSize(ss);
+       unsigned char *cp1, *cp2;
+       int useTwoSide=1;
+
+       cp1= col1;
+       if(col2) {
+               cp2= col2;
+       } else {
+               cp2= NULL;
+               useTwoSide= 0;
+       }
+
+       glShadeModel(GL_SMOOTH);
+       if(col1 && col2)
+               glEnable(GL_CULL_FACE);
+
+       glBegin(GL_QUADS);
+       for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
+               CCGFace *f = ccgFaceIterator_getCurrent(fi);
+               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++) {
+                               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;
+
+                                       glColor3ub(cp1[3], cp1[2], cp1[1]);
+                                       glVertex3fv(d);
+                                       glColor3ub(cp1[7], cp1[6], cp1[5]);
+                                       glVertex3fv(c);
+                                       glColor3ub(cp1[11], cp1[10], cp1[9]);
+                                       glVertex3fv(b);
+                                       glColor3ub(cp1[15], cp1[14], cp1[13]);
+                                       glVertex3fv(a);
+
+                                       if (useTwoSide) {
+                                               glColor3ub(cp2[15], cp2[14], cp2[13]);
+                                               glVertex3fv(a);
+                                               glColor3ub(cp2[11], cp2[10], cp2[9]);
+                                               glVertex3fv(b);
+                                               glColor3ub(cp2[7], cp2[6], cp2[5]);
+                                               glVertex3fv(c);
+                                               glColor3ub(cp2[3], cp2[2], cp2[1]);
+                                               glVertex3fv(d);
+                                       }
+
+                                       if (cp2) cp2+=16;
+                                       cp1+=16;
+                               }
+                       }
+               }
+       }
+       glEnd();
+
+       ccgFaceIterator_free(fi);
 }
 static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) {
-//     CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+       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;
+       TFace *tface = ccgdm->dlm?ccgdm->dlm->tface:ccgdm->me->tface;
+       MCol *mcol = ccgdm->dlm?ccgdm->dlm->mcol:ccgdm->me->mcol;
+//     float uv[4][2];
+//     float col[4][3];
+
+       glBegin(GL_QUADS);
+       for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
+               CCGFace *f = ccgFaceIterator_getCurrent(fi);
+               int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(ss, f);
+               int index = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
+               MFace *mf = &mface[index];
+               TFace *tf = tface?&tface[index]:NULL;
+               unsigned char *cp= NULL;
+               
+               if(tf && ((tf->flag&TF_HIDE) || (tf->mode&TF_INVISIBLE))) continue;
+
+               if (setDrawParams(tf, mf->mat_nr)) {
+                       if (tf) {
+                               cp= (unsigned char *) tf->col;
+                       } else if (mcol) {
+                               cp= (unsigned char *) &mcol[index*4];
+                       }
+               }
+
+               for (S=0; S<numVerts; S++) {
+                       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 *b = &faceGridData[(y+0)*gridSize + x + 1];
+                                       VertData *c = &faceGridData[(y+1)*gridSize + x + 1];
+                                       VertData *d = &faceGridData[(y+1)*gridSize + x];
+
+                                       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];
+                                               float b_dX = d->co[0]-b->co[0], b_dY = d->co[1]-b->co[1], b_dZ = d->co[2]-b->co[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);
+                                       }
+
+//                                     if (tf) glTexCoord2fv(tf->uv[0]);
+//                                     if (cp) glColor3ub(cp[3], cp[2], cp[1]);
+//                                     if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v1].no);
+//                                     glVertex3fv(mvert[mf->v1].co);
+
+/*
+                                       {
+                                               float x_v = (float) fx/(gridSize-1);
+                                               float y_v = (float) fy/(gridSize-1);
+                                               float data[6];
+
+                                               for (k=0; k<numDataComponents; k++) {
+                                                       data[k] = (center_data[k]*(1.0f-x_v) + edge_data[S][k]*x_v)*(1.0f-y_v) + 
+                                                                       (edge_data[prevS][k]*(1.0f-x_v) + corner_data[S][k]*x_v)*y_v;
+                                       }
+*/
+
+//                                     if (cp) glColor3ub(cp[3], cp[2], cp[1]);
+                                       if (mf->flag&ME_SMOOTH) glNormal3fv(d->no);
+                                       glVertex3fv(d->co);
+//                                     if (cp) glColor3ub(cp[7], cp[6], cp[5]);
+                                       if (mf->flag&ME_SMOOTH) glNormal3fv(c->no);
+                                       glVertex3fv(c->co);
+//                                     if (cp) glColor3ub(cp[11], cp[10], cp[9]);
+                                       if (mf->flag&ME_SMOOTH) glNormal3fv(b->no);
+                                       glVertex3fv(b->co);
+//                                     if (cp) glColor3ub(cp[15], cp[14], cp[13]);
+                                       if (mf->flag&ME_SMOOTH) glNormal3fv(a->no);
+                                       glVertex3fv(a->co);
+                               }
+                       }
+               }
+       }
+       glEnd();
+
+       ccgFaceIterator_free(fi);
+/*
+       MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
+       Mesh *me = mdm->me;
+       MVert *mvert= mdm->verts;
+       MFace *mface= me->mface;
+       TFace *tface = me->tface;
+       float *nors = mdm->nors;
+       int a;
+
+       for (a=0; a<me->totface; a++) {
+               MFace *mf= &mface[a];
+               if (tf) glTexCoord2fv(tf->uv[1]);
+               if (cp) glColor3ub(cp[7], cp[6], cp[5]);
+               if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v2].no);
+               glVertex3fv(mvert[mf->v2].co);
+
+               if (tf) glTexCoord2fv(tf->uv[2]);
+               if (cp) glColor3ub(cp[11], cp[10], cp[9]);
+               if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v3].no);
+               glVertex3fv(mvert[mf->v3].co);
+
+               if(mf->v4) {
+                       if (tf) glTexCoord2fv(tf->uv[3]);
+                       if (cp) glColor3ub(cp[15], cp[14], cp[13]);
+                       if (mf->flag&ME_SMOOTH) glNormal3sv(mvert[mf->v4].no);
+                       glVertex3fv(mvert[mf->v4].co);
+               }
+               glEnd();
+       }
+*/
 }
 
 static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData) {
@@ -974,22 +1245,21 @@ static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void
 static void ccgDM_release(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 
-       ccgSubSurf_free(ccgdm->ss);
+       if (ccgdm->dlm) displistmesh_free(ccgdm->dlm);
 
        MEM_freeN(ccgdm);
 }
 
-static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh) {
-       CCGDerivedMesh *ccgdm = MEM_mallocN(sizeof(*ccgdm), "ccgdm");
+static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, 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.getMappedVertCoEM = ccgDM_getMappedVertCoEM;
        ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh;
 
-       //ccgdm->dm.getVertCos = ccgdm_getVertCos; // XXX fixme
-
        ccgdm->dm.drawVerts = ccgDM_drawVerts;
        ccgdm->dm.drawEdges = ccgDM_drawEdges;
        ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
@@ -1008,23 +1278,26 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh) {
        
        ccgdm->ss = ss;
        ccgdm->fromEditmesh = fromEditmesh;
+       ccgdm->me = me;
+       ccgdm->dlm = dlm;
 
        return ccgdm;
 }
 
 /***/
 
-DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd) {
+DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd, float (*vertCos)[3]) {
        int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
-       CCGSubSurf *ss = _getSubSurf(NULL, smd->levels, G.rt==52, 0, 0, useSimple);
-
-       ss_sync_from_editmesh(ss, em, useSimple);
+       
+       smd->emCache = _getSubSurf(smd->emCache, smd->levels, G.rt==52, 0, 0, useSimple);
+       ss_sync_from_editmesh(smd->emCache, em, vertCos, useSimple);
 
-       return (DerivedMesh*) getCCGDerivedMesh(ss, 1);
+       return (DerivedMesh*) getCCGDerivedMesh(smd->emCache, 1, NULL, NULL);
 }
 
-DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3]) {
+DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3], int isFinalCalc) {
        int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
+       DispListMesh *ndlm;
 
                /* Do not use cache in render mode. */
        if (useRenderParams) {
@@ -1032,34 +1305,51 @@ DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, Subsurf
 
                ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
 
-               dlm = ss_to_displistmesh(ss, 0, me, dlm);
+               ndlm = ss_to_displistmesh(ss, 0, me, dlm);
+               if (dlm) displistmesh_free(dlm);
 
                ccgSubSurf_free(ss);
                
-               return derivedmesh_from_displistmesh(dlm);
+               return derivedmesh_from_displistmesh(ndlm);
        } else {
                int useEdgeCreation = !(dlm?dlm->medge:me->medge);
-               int useIncremental = useEdgeCreation?0:smd->useIncrementalMesh;
+               int useIncremental = smd->useIncrementalMesh && !useEdgeCreation;
                CCGSubSurf *ss;
                
-               if (!useIncremental && smd->mCache) {
-                       ccgSubSurf_free(smd->mCache);
-                       smd->mCache = NULL;
+                       /* It is quite possible there is a much better place to do this. It
+                        * depends a bit on how rigourously we expect this function to never
+                        * be called in editmode. In semi-theory we could share a single
+                        * cache, but the handles used inside and outside editmode are not
+                        * the same so we would need some way of converting them. Its probably
+                        * not worth the effort. But then why am I even writing this long
+                        * comment that no one will read? Hmmm. - zr
+                        */
+               if (smd->emCache) {
+                       ccgSubSurf_free(smd->emCache);
+                       smd->emCache = NULL;
                }
 
-               ss = _getSubSurf(smd->mCache, smd->levels, 0, 1, useEdgeCreation, useSimple);
+               if (useIncremental && isFinalCalc) {
+                       smd->mCache = ss = _getSubSurf(smd->mCache, smd->levels, G.rt==52, 0, 0, useSimple);
 
-               ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
+                       ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
 
-               dlm = ss_to_displistmesh(ss, 0, me, dlm);
-
-               if (useIncremental) {
-                       smd->mCache = ss;
+                       return (DerivedMesh*) getCCGDerivedMesh(ss, 0, me, dlm);
                } else {
+                       if (smd->mCache && isFinalCalc) {
+                               ccgSubSurf_free(smd->mCache);
+                               smd->mCache = NULL;
+                       }
+
+                       ss = _getSubSurf(NULL, smd->levels, G.rt==52, 1, useEdgeCreation, useSimple);
+                       ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
+                       ndlm = ss_to_displistmesh(ss, 0, me, dlm);
+
+                       if (dlm) displistmesh_free(dlm);
                        ccgSubSurf_free(ss);
-               }
 
-               return derivedmesh_from_displistmesh(dlm);
+                       return derivedmesh_from_displistmesh(ndlm);
+               }
        }
 }
 
index 6fa7423f54f4f5cc053eed8bce903a19131771e7..87e0c3ae1686d77d9e11a4d97015b20b25aadcb4 100644 (file)
@@ -45,6 +45,7 @@
 #include "DNA_curve_types.h"
 #include "DNA_scene_types.h"
 #include "BIF_editkey.h"
+#include "BIF_editdeform.h"
 #include "blendef.h"
 #include "gen_utils.h"
 
index 2e3ca06a9bbbb6f8d18458f37c2fb45801e364f9..bcfc70c4e62aa211891d4a48817944578db2157e 100644 (file)
@@ -945,10 +945,8 @@ void load_editMesh(void)
        else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh vert");
 
        /* new Edge block */
-       if(totedge) {
-               if(me->medge==NULL) totedge= 0; // if edges get added is defined by orig mesh
-               else medge= MEM_callocN(totedge*sizeof(MEdge), "loadeditMesh edge");
-       }
+       if(me->medge==NULL) totedge= 0; // if edges get added is defined by orig mesh
+       else medge= MEM_callocN(totedge*sizeof(MEdge), "loadeditMesh edge");
        
        /* new Face block */
        if(G.totface==0) mface= NULL;