- shuffled editmesh derived function name/function
authorDaniel Dunbar <daniel@zuster.org>
Thu, 21 Jul 2005 20:30:33 +0000 (20:30 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 21 Jul 2005 20:30:33 +0000 (20:30 +0000)
 - added ModifierTypeInfo.freeData function
 - added modifier_{new,free] utility function
 - added ccgSubSurf_getUseAgeCounts to query info
 - removed subsurf modifier faking (ME_SUBSURF flag is no
   longer valid). subsurf modifier gets converted on file load
   although there is obscure linked mesh situation where this
   can go wrong, will fix shortly. this also means that some
   places in the code that test/copy subsurf settings are broken
   for the time being.
 - shuffled modifier calculation to be simpler. note that
   all modifiers are currently disabled in editmode (including
   subsurf). don't worry, will return shortly.
 - bug fix, build modifier didn't randomize meshes with only verts
 - cleaned up subsurf_ccg and adapted for future editmode modifier
   work
 - added editmesh.derived{Cage,Final}, not used yet
 - added SubsurfModifierData.{mCache,emCache}, will be used to cache
   subsurf instead of caching in derivedmesh itself
 - removed old subsurf buttons
 - added do_modifiers_buttons to handle modifier events
 - removed count_object counting of modifier (subsurfed) objects...
   this would be nice to add back at some point but requires care.
   probably requires rewrite of counting system.

New feature: Incremental Subsurf in Object Mode

The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.

However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.

I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).

19 files changed:
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/CCGSubSurf.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenlib/BLI_editVert.h
source/blender/blenloader/intern/readfile.c
source/blender/include/butspace.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/src/butspace.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/drawobject.c
source/blender/src/edit.c
source/blender/src/editmesh.c

index 406060dfb535189e4aec04bd20910cccf2f1573c..da7c053bb9cb32b10b861f8b4644ae50293898d4 100644 (file)
@@ -156,9 +156,8 @@ DerivedMesh *mesh_create_derived_render(struct Object *ob);
 DerivedMesh *mesh_create_derived_no_deform(struct Object *ob, float (*vertCos)[3]);
 DerivedMesh *mesh_create_derived_no_deform_render(struct Object *ob, float (*vertCos)[3]);
 
-DerivedMesh *editmesh_get_derived(void);
-DerivedMesh *editmesh_get_derived_proxy(void);
 DerivedMesh *editmesh_get_derived_cage(int *needsFree_r);
+DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, int *cageNeedsFree_r, int *finalNeedsFree_r);
 
 #endif
 
index b0736a1ab72c3f82daf44fe68322acf25a3214fe..a09ee20b385b8c6ddd8575c04fc57c6f8a98bf5a 100644 (file)
@@ -61,15 +61,33 @@ typedef enum {
 } ModifierTypeFlag;
 
 typedef struct ModifierTypeInfo {
-       char name[32], structName[32];
+               /* The user visible name for this modifier */
+       char name[32];
+
+               /* The DNA struct name for the modifier data type, used to
+                * write the DNA data out.
+                */
+       char structName[32];
+
+               /* The size of the modifier data type, used by allocation. */
+       int structSize;
+
        ModifierTypeType type;
        ModifierTypeFlag flags;
 
-               /* Create new instance data for this modifier type.
+               /* Initialize new instance data for this modifier type, this function
+                * should set modifier variables to their default values.
                 * 
-                * This function must be present.
+                * This function is optional.
                 */
-       struct ModifierData *(*allocData)(void);
+       void (*initData)(struct ModifierData *md);
+
+               /* Free internal modifier data variables, this function should
+                * not free the _md_ variable itself.
+                *
+                * This function is optional.
+                */
+       void (*freeData)(struct ModifierData *md);
 
                /* Return a boolean value indicating if this modifier is able to be calculated
                 * based on the modifier data. This is *not* regarding the md->flag, that is
@@ -120,7 +138,13 @@ typedef struct ModifierTypeInfo {
 
 ModifierTypeInfo *modifierType_get_info(ModifierType type);
 
-int modifier_dependsOnTime(struct ModifierData *md);
+       /* Modifier utility calls, do call through type pointer and return
+        * default values if pointer is optional.
+        */
+struct ModifierData*   modifier_new                    (int type);
+void                                   modifier_free                   (struct ModifierData *md);
+
+int                                            modifier_dependsOnTime  (struct ModifierData *md);
 
 #endif
 
index 5443ab727600bc9f765a4bcf8059e7c823f43f36..a52002761593e8e76e25d7aa00b0b194e0f412da 100644 (file)
@@ -35,10 +35,10 @@ struct Mesh;
 struct Object;
 struct DerivedMesh;
 struct EditMesh;
+struct SubsurfModifierData;
 
-struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, int subdivLevels, short type, struct DerivedMesh *oldDerived);
-struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, int subdivType, int subdivLevels, float (*vertCos)[3]);
-struct DerivedMesh *subsurf_make_derived_from_dlm(struct DispListMesh *dlm, int subdivType, int subdivLevels);
+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]);
 
 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]);
 
index bd935505ea90efab8fd6385d836be3a33833abc8..6bfc431a2099fb44b92d39c46c21b4981af86ab4 100644 (file)
@@ -289,8 +289,7 @@ struct _CCGSubSurf {
        EHash *fMap;    /* map of CCGFaceHDL -> Face */
 
        CCGMeshIFC meshIFC;
-       void *meshData;
-
+       
        CCGAllocatorIFC allocatorIFC;
        CCGAllocatorHDL allocator;
 
@@ -611,7 +610,7 @@ static void _face_unlinkMarkAndFree(CCGFace *f, CCGSubSurf *ss) {
 
 /***/
 
-CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, CCGMeshHDL meshData, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) {
+CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) {
        if (!allocatorIFC) {
                allocatorIFC = _getStandardAllocatorIFC();
                allocator = NULL;
@@ -630,8 +629,7 @@ CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, CCGMeshHDL meshData, int subdivLevel
                ss->fMap = _ehash_new(0, &ss->allocatorIFC, ss->allocator);
 
                ss->meshIFC = *ifc;
-               ss->meshData = meshData;
-
+               
                ss->subdivLevels = subdivLevels;
                ss->numGrids = 0;
                ss->allowEdgeCreation = 0;
@@ -710,6 +708,15 @@ CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels)
        return eCCGError_None;
 }
 
+void ccgSubSurf_getUseAgeCounts(CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r)
+{
+       *useAgeCounts_r = ss->useAgeCounts;
+
+       if (vertUserOffset_r) *vertUserOffset_r = ss->vertUserAgeOffset;
+       if (edgeUserOffset_r) *edgeUserOffset_r = ss->edgeUserAgeOffset;
+       if (faceUserOffset_r) *faceUserOffset_r = ss->faceUserAgeOffset;
+}
+
 CCGError ccgSubSurf_setUseAgeCounts(CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset) {
        if (useAgeCounts) {
                if (    (vertUserOffset+4>ss->meshIFC.vertUserSize) ||
index 4f0594a28ebefdce590ed7c0f3701866de3f8a94..4c522b1a8276abd041f2afd66a174e788ebce636 100644 (file)
@@ -37,7 +37,7 @@ typedef enum {
 
 typedef struct _CCGSubSurf CCGSubSurf;
 
-CCGSubSurf*    ccgSubSurf_new  (CCGMeshIFC *ifc, CCGMeshHDL meshData, int subdivisionLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator);
+CCGSubSurf*    ccgSubSurf_new  (CCGMeshIFC *ifc, int subdivisionLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator);
 void           ccgSubSurf_free (CCGSubSurf *ss);
 
 CCGError       ccgSubSurf_sync (CCGSubSurf *ss);
@@ -56,7 +56,9 @@ CCGError      ccgSubSurf_syncFaceDel  (CCGSubSurf *ss, CCGFaceHDL fHDL);
 CCGError       ccgSubSurf_processSync  (CCGSubSurf *ss);
 
 CCGError       ccgSubSurf_setSubdivisionLevels         (CCGSubSurf *ss, int subdivisionLevels);
+
 CCGError       ccgSubSurf_setAllowEdgeCreation         (CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue);
+void           ccgSubSurf_getUseAgeCounts                      (CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r);
 CCGError       ccgSubSurf_setUseAgeCounts                      (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset);
 CCGError       ccgSubSurf_setCalcVertexNormals         (CCGSubSurf *ss, int useVertNormals, int normalDataOffset);
 
index f54b152578a231ac0b62da07ed5bbcfe48b830e6..399f2afb6d42bd0359e1ab56d17bfabc188c5854 100644 (file)
@@ -1005,11 +1005,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
        if (deform_r) *deform_r = NULL;
        *final_r = NULL;
 
-               /* Note: useDeform==1 implies ob must be non-NULL */
-
        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++) {
@@ -1092,29 +1091,6 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
                }
        }
 
-               /* Fake the subsurf modifier */
-       {
-               int level = useRenderParams?me->subdivr:me->subdiv;
-
-               if ((me->flag&ME_SUBSURF) && level) {
-                       ModifierTypeInfo *mti = modifierType_get_info(eModifierType_Subsurf);
-                       SubsurfModifierData smd;
-
-                       smd.levels = me->subdiv;
-                       smd.renderLevels = me->subdivr;
-                       smd.subdivType = me->subsurftype;
-
-                       dm = mti->applyModifier(&smd.modifier, ob, dm, deformedVerts, useRenderParams);
-
-                       if (deformedVerts) {
-                               if (deformedVerts!=inputVertexCos) {
-                                       MEM_freeN(deformedVerts);
-                               }
-                               deformedVerts = 0;
-                       }
-               }
-       }
-
                /* 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.
@@ -1152,13 +1128,10 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3], DerivedM
 
 /***/
 
-static void clear_and_build_mesh_data(Object *ob, int mustBuildForMesh)
+static void clear_mesh_caches(Object *ob)
 {
-       float min[3], max[3];
        Mesh *me= ob->data;
 
-       if(ob->flag&OB_FROMDUPLI) return;
-
                /* also serves as signal to remake texspace */
        if (me->bb) {
                MEM_freeN(me->bb);
@@ -1175,27 +1148,70 @@ static void clear_and_build_mesh_data(Object *ob, int mustBuildForMesh)
                ob->derivedDeform->release(ob->derivedDeform);
                ob->derivedDeform= NULL;
        }
+}
 
-       if (ob==G.obedit) {
-               G.editMesh->derived= subsurf_make_derived_from_editmesh(G.editMesh, me->subdiv, me->subsurftype, G.editMesh->derived);
-       } 
-       
-       if (ob!=G.obedit || mustBuildForMesh) {
-               mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1);
+static void mesh_build_data(Object *ob)
+{
+       float min[3], max[3];
+       Mesh *me= ob->data;
+
+       if(ob->flag&OB_FROMDUPLI) return;
+
+       clear_mesh_caches(ob);
+
+       mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1);
        
-               INIT_MINMAX(min, max);
+       INIT_MINMAX(min, max);
 
-               ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
+       ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
 
-               boundbox_set_from_min_max(mesh_get_bb(ob->data), min, max);
+       boundbox_set_from_min_max(mesh_get_bb(ob->data), min, max);
 
-               build_particle_system(ob);
+       build_particle_system(ob);
+}
+
+static void editmesh_build_data(void)
+{
+       Mesh *me = G.obedit->data;
+       EditMesh *em = G.editMesh;
+
+       clear_mesh_caches(G.obedit);
+
+       if (em->derivedFinal) {
+               if (em->derivedFinal!=em->derivedCage) {
+                       em->derivedFinal->release(em->derivedFinal);
+               }
+               em->derivedFinal = NULL;
+       }
+       if (em->derivedCage) {
+               em->derivedCage->release(em->derivedCage);
+               em->derivedCage = NULL;
+       }
+
+/*
+       if ((me->flag&ME_SUBSURF) && me->subdiv) {
+               em->derivedFinal = subsurf_make_derived_from_editmesh(em, me->subdiv, me->subsurftype, NULL);
+
+               if (me->flag&ME_OPT_EDGES) {
+                       em->derivedCage = em->derivedFinal;
+               } else {
+                       em->derivedCage = getEditMeshDerivedMesh(em);
+               }
+       } else {
+*/
+       em->derivedFinal = em->derivedCage = getEditMeshDerivedMesh(em);
+/*
        }
+*/
 }
 
 void makeDispListMesh(Object *ob)
 {
-       clear_and_build_mesh_data(ob, 0);
+       if (ob==G.obedit) {
+               editmesh_build_data();
+       } else {
+               mesh_build_data(ob);
+       }
 }
 
 /***/
@@ -1205,7 +1221,7 @@ DerivedMesh *mesh_get_derived_final(Object *ob, int *needsFree_r)
        Mesh *me = ob->data;
 
        if (!ob->derivedFinal) {
-               clear_and_build_mesh_data(ob, 1);
+               mesh_build_data(ob);
        }
 
        *needsFree_r = 0;
@@ -1215,7 +1231,7 @@ DerivedMesh *mesh_get_derived_final(Object *ob, int *needsFree_r)
 DerivedMesh *mesh_get_derived_deform(Object *ob, int *needsFree_r)
 {
        if (!ob->derivedDeform) {
-               clear_and_build_mesh_data(ob, 1);
+               mesh_build_data(ob);
        } 
 
        *needsFree_r = 0;
@@ -1251,40 +1267,23 @@ DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, float (*vertCos)[3
 
 /***/
 
-DerivedMesh *editmesh_get_derived_proxy(void)
+DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r, int *cageNeedsFree_r, int *finalNeedsFree_r)
 {
-       return getEditMeshDerivedMesh(G.editMesh);
-}
+       *cageNeedsFree_r = *finalNeedsFree_r = 0;
 
-DerivedMesh *editmesh_get_derived(void)
-{
-       Mesh *me= G.obedit->data;
+       if (!G.editMesh->derivedCage)
+               editmesh_build_data();
 
-       if ((me->flag&ME_SUBSURF) && me->subdiv) {
-               if (!G.editMesh->derived) {
-                       makeDispListMesh(G.obedit);
-               }
-
-               return G.editMesh->derived;
-       } 
-
-       return NULL;
+       *final_r = G.editMesh->derivedFinal;
+       return G.editMesh->derivedCage;
 }
 
 DerivedMesh *editmesh_get_derived_cage(int *needsFree_r)
 {
-       Mesh *me= G.obedit->data;
-       DerivedMesh *dm = NULL;
-
        *needsFree_r = 0;
 
-       if (me->flag&ME_OPT_EDGES) {
-               dm = editmesh_get_derived();
-       }
-       if (!dm) {
-               *needsFree_r = 1;
-               dm = editmesh_get_derived_proxy();
-       }
+       if (!G.editMesh->derivedCage)
+               editmesh_build_data();
 
-       return dm;
+       return G.editMesh->derivedCage;
 }
index 709d6f0cd405a30465a12e4bffdd79f8169929ab..044c79711f816fffc7e75d1ac6ad6bb9bb19cb5e 100644 (file)
 #include "BKE_mesh.h"
 #include "depsgraph_private.h"
 
-/***/
+#include "CCGSubSurf.h"
 
-static void *allocModifierData(int type, int size)
-{
-       ModifierData *md = MEM_callocN(size, "md");
-       md->type = type;
-       md->mode = eModifierMode_RealtimeAndRender;
-
-       return md;
-}
-
-static ModifierData *noneModifier_allocData(void)
-{
-       return allocModifierData(eModifierType_None, sizeof(ModifierData));
-}
+/***/
 
 static int noneModifier_isDisabled(ModifierData *md)
 {
@@ -44,11 +32,6 @@ static int noneModifier_isDisabled(ModifierData *md)
 
 /* Curve */
 
-static ModifierData *curveModifier_allocData(void)
-{
-       return allocModifierData(eModifierType_Curve, sizeof(CurveModifierData));
-}
-
 static int curveModifier_isDisabled(ModifierData *md)
 {
        CurveModifierData *cmd = (CurveModifierData*) md;
@@ -76,11 +59,6 @@ static void curveModifier_deformVerts(ModifierData *md, Object *ob, float (*vert
 
 /* Lattice */
 
-static ModifierData *latticeModifier_allocData(void)
-{
-       return allocModifierData(eModifierType_Lattice, sizeof(LatticeModifierData));
-}
-
 static int latticeModifier_isDisabled(ModifierData *md)
 {
        LatticeModifierData *lmd = (LatticeModifierData*) md;
@@ -108,20 +86,26 @@ static void latticeModifier_deformVerts(ModifierData *md, Object *ob, float (*ve
 
 /* Subsurf */
 
-static ModifierData *subsurfModifier_allocData(void)
+static void subsurfModifier_initData(ModifierData *md)
 {
-       SubsurfModifierData *smd = allocModifierData(eModifierType_Subsurf, sizeof(SubsurfModifierData));
-
+       SubsurfModifierData *smd = (SubsurfModifierData*) md;
+       
        smd->levels = 1;
        smd->renderLevels = 2;
-
-       return (ModifierData*) smd;
 }
 
+static void subsurfModifier_freeData(ModifierData *md)
+{
+       SubsurfModifierData *smd = (SubsurfModifierData*) md;
+
+       if (smd->mCache) {
+               ccgSubSurf_free(smd->mCache);
+       }
+}      
+
 static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
 {
        SubsurfModifierData *smd = (SubsurfModifierData*) md;
-       int levels = useRenderParams?smd->renderLevels:smd->levels;
        Mesh *me = ob->data;
 
        if (dm) {
@@ -137,25 +121,23 @@ static void *subsurfModifier_applyModifier(ModifierData *md, Object *ob, Derived
                }
                dm->release(dm);
 
-               dm = subsurf_make_derived_from_dlm(dlm, smd->subdivType, levels);
+               dm = subsurf_make_derived_from_mesh(me, dlm, smd, useRenderParams, NULL);
                displistmesh_free(dlm);
 
                return dm;
        } else {
-               return subsurf_make_derived_from_mesh(me, smd->subdivType, levels, vertexCos);
+               return subsurf_make_derived_from_mesh(me, NULL, smd, useRenderParams, vertexCos);
        }
 }
 
 /* Build */
 
-static ModifierData *buildModifier_allocData(void)
+static void buildModifier_initData(ModifierData *md)
 {
-       BuildModifierData *bmd = allocModifierData(eModifierType_Build, sizeof(BuildModifierData));
+       BuildModifierData *bmd = (BuildModifierData*) md;
 
        bmd->start = 1.0;
        bmd->length = 100.0;
-
-       return (ModifierData*) bmd;
 }
 
 static int buildModifier_dependsOnTime(ModifierData *md)
@@ -354,8 +336,14 @@ static void *buildModifier_applyModifier(ModifierData *md, Object *ob, DerivedMe
        } else {
                ndlm->totvert = totvert*frac;
 
-               ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert, "build_mvert");
-               memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert);
+               if (bmd->randomize) {
+                       ndlm->mvert = MEM_dupallocN(mvert);
+                       BLI_array_randomize(ndlm->mvert, sizeof(*mvert), totvert, bmd->seed);
+               } else {
+                       ndlm->mvert = MEM_mallocN(sizeof(*ndlm->mvert)*ndlm->totvert, "build_mvert");
+                       memcpy(ndlm->mvert, mvert, sizeof(*mvert)*ndlm->totvert);
+               }
+
                if (vertexCos) {
                        for (i=0; i<ndlm->totvert; i++) {
                                VECCOPY(ndlm->mvert[i].co, vertexCos[i]);
@@ -373,14 +361,11 @@ static void *buildModifier_applyModifier(ModifierData *md, Object *ob, DerivedMe
 
 /* Mirror */
 
-static ModifierData *mirrorModifier_allocData(void)
+static void mirrorModifier_initData(ModifierData *md)
 {
-       MirrorModifierData *mmd = allocModifierData(eModifierType_Mirror, sizeof(MirrorModifierData));
+       MirrorModifierData *mmd = (MirrorModifierData*) md;
 
-       mmd->axis = 0;
        mmd->tolerance = 0.001;
-
-       return (ModifierData*) mmd;
 }
 
 static void *mirrorModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int useRenderParams)
@@ -602,60 +587,61 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type)
 
                memset(typeArr, 0, sizeof(typeArr));
 
+               /* Initialize and return the appropriate type info structure,
+                * assumes that modifier has:
+                *  name == typeName, 
+                *  structName == typeName + 'ModifierData'
+                */
+#define INIT_TYPE(typeName) \
+       (       strcpy(typeArr[eModifierType_##typeName].name, #typeName), \
+               strcpy(typeArr[eModifierType_##typeName].structName, #typeName "ModifierData"), \
+               typeArr[eModifierType_##typeName].structSize = sizeof(typeName##ModifierData), \
+               &typeArr[eModifierType_##typeName])
+
                mti = &typeArr[eModifierType_None];
                strcpy(mti->name, "None");
                strcpy(mti->structName, "ModifierData");
+               mti->structSize = sizeof(ModifierData);
                mti->type = eModifierType_None;
                mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_AcceptsCVs;
-               mti->allocData = noneModifier_allocData;
                mti->isDisabled = noneModifier_isDisabled;
 
-               mti = &typeArr[eModifierType_Curve];
-               strcpy(mti->name, "Curve");
-               strcpy(mti->structName, "CurveModifierData");
+               mti = INIT_TYPE(Curve);
                mti->type = eModifierTypeType_OnlyDeform;
                mti->flags = eModifierTypeFlag_AcceptsCVs;
-               mti->allocData = curveModifier_allocData;
                mti->isDisabled = curveModifier_isDisabled;
                mti->updateDepgraph = curveModifier_updateDepgraph;
                mti->deformVerts = curveModifier_deformVerts;
 
-               mti = &typeArr[eModifierType_Lattice];
-               strcpy(mti->name, "Lattice");
-               strcpy(mti->structName, "LatticeModifierData");
+               mti = INIT_TYPE(Lattice);
                mti->type = eModifierTypeType_OnlyDeform;
                mti->flags = eModifierTypeFlag_AcceptsCVs;
-               mti->allocData = latticeModifier_allocData;
                mti->isDisabled = latticeModifier_isDisabled;
                mti->updateDepgraph = latticeModifier_updateDepgraph;
                mti->deformVerts = latticeModifier_deformVerts;
 
-               mti = &typeArr[eModifierType_Subsurf];
-               strcpy(mti->name, "Subsurf");
-               strcpy(mti->structName, "SubsurfModifierData");
+               mti = INIT_TYPE(Subsurf);
                mti->type = eModifierTypeType_Constructive;
                mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping;
-               mti->allocData = subsurfModifier_allocData;
+               mti->initData = subsurfModifier_initData;
+               mti->freeData = subsurfModifier_freeData;
                mti->applyModifier = subsurfModifier_applyModifier;
 
-               mti = &typeArr[eModifierType_Build];
-               strcpy(mti->name, "Build");
-               strcpy(mti->structName, "BuildModifierData");
+               mti = INIT_TYPE(Build);
                mti->type = eModifierTypeType_Nonconstructive;
                mti->flags = eModifierTypeFlag_AcceptsMesh;
-               mti->allocData = buildModifier_allocData;
+               mti->initData = buildModifier_initData;
                mti->dependsOnTime = buildModifier_dependsOnTime;
                mti->applyModifier = buildModifier_applyModifier;
 
-               mti = &typeArr[eModifierType_Mirror];
-               strcpy(mti->name, "Mirror");
-               strcpy(mti->structName, "MirrorModifierData");
+               mti = INIT_TYPE(Mirror);
                mti->type = eModifierTypeType_Constructive;
                mti->flags = eModifierTypeFlag_AcceptsMesh;
-               mti->allocData = mirrorModifier_allocData;
+               mti->initData = mirrorModifier_initData;
                mti->applyModifier = mirrorModifier_applyModifier;
 
                typeArrInit = 0;
+#undef INIT_TYPE
        }
 
        if (type>=0 && type<NUM_MODIFIER_TYPES && typeArr[type].name[0]!='\0') {
@@ -665,6 +651,28 @@ ModifierTypeInfo *modifierType_get_info(ModifierType type)
        }
 }
 
+ModifierData *modifier_new(int type)
+{
+       ModifierTypeInfo *mti = modifierType_get_info(type);
+       ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
+
+       md->type = type;
+       md->mode = eModifierMode_RealtimeAndRender;
+
+       if (mti->initData) mti->initData(md);
+
+       return md;
+}
+
+void modifier_free(ModifierData *md) 
+{
+       ModifierTypeInfo *mti = modifierType_get_info(md->type);
+
+       if (mti->freeData) mti->freeData(md);
+
+       MEM_freeN(md);
+}
+
 int modifier_dependsOnTime(ModifierData *md) 
 {
        ModifierTypeInfo *mti = modifierType_get_info(md->type);
index 9b70f2923f76565e4e3a748c5c4949b5c9b7e008..05a09e8c0392d14cd733d086ad6d7d6b30ca4eb6 100644 (file)
@@ -95,6 +95,7 @@
 #include "BKE_library.h"
 #include "BKE_mesh.h"
 #include "BKE_mball.h"
+#include "BKE_modifier.h"
 #include "BKE_object.h"
 #include "BKE_property.h"
 #include "BKE_sca.h"
@@ -177,7 +178,8 @@ static void free_modifiers(ListBase *lb)
 
        while (md=lb->first) {
                BLI_remlink(lb, md);
-               MEM_freeN(md);
+
+               modifier_free(md);
        }
 }
 
index 39a451094bbfa1908620f22891f0ceae944749c8..4212efa5af27a037aa583aa1254105b2fa3a4e25 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 
 #include "BKE_bad_level_calls.h"
 
 #include "CCGSubSurf.h"
 
-typedef struct _SubSurf {
-       CCGSubSurf *subSurf;
-
-       int useAging;
-       int controlType;
-#define SUBSURF_CONTROLTYPE_MESH               1
-#define SUBSURF_CONTROLTYPE_EDITMESH   2
-
-               /* used by editmesh control type */
-       EditMesh *em;
-
-               /* used by mesh control type */
-       Mesh *me;
-
-       float (*vertCos)[3];
-       DispListMesh *dlm;
-} SubSurf;
-
 typedef struct _VertData {
        float co[3];
        float no[3];
@@ -99,13 +82,25 @@ static void arena_release(CCGAllocatorHDL a) {
        BLI_memarena_free(a);
 }
 
-static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels, int useArena) {
+static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useEdgeCreation, int useFlatSubdiv) {
        CCGMeshIFC ifc;
        CCGSubSurf *ccgSS;
-       CCGAllocatorIFC allocatorIFC, *allocatorIFCp;
-       CCGAllocatorHDL allocator;
 
-       if (ss->useAging) {
+       if (prevSS) {
+               int oldUseAging;
+
+               ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
+
+               if (oldUseAging!=useAging) {
+                       ccgSubSurf_free(prevSS);
+               } else {
+                       ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels);
+
+                       return prevSS;
+               }
+       }
+
+       if (useAging) {
                ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
        } else {
                ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 4;
@@ -113,58 +108,31 @@ static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels, int useArena) {
        ifc.vertDataSize = sizeof(VertData);
 
        if (useArena) {
+               CCGAllocatorIFC allocatorIFC;
+               CCGAllocatorHDL allocator = BLI_memarena_new((1<<16));
+
                allocatorIFC.alloc = arena_alloc;
                allocatorIFC.realloc = arena_realloc;
                allocatorIFC.free = arena_free;
                allocatorIFC.release = arena_release;
-               allocatorIFCp = &allocatorIFC;
-               allocator = BLI_memarena_new((1<<16));
 
-               ccgSS = ccgSubSurf_new(&ifc, ss, subdivLevels, allocatorIFCp, allocator);
+               ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator);
        } else {
-               ccgSS = ccgSubSurf_new(&ifc, ss, subdivLevels, NULL, NULL);
+               ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL);
        }
 
-       if (ss->useAging) {
+       if (useAging) {
                ccgSubSurf_setUseAgeCounts(ccgSS, 1, 4, 4, 4);
        }
+       if (useEdgeCreation) {
+               ccgSubSurf_setAllowEdgeCreation(ccgSS, 1, useFlatSubdiv?subdivLevels:0.0f);
+       }
 
        ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
 
        return ccgSS;
 }
 
-static SubSurf *subSurf_fromEditmesh(EditMesh *em, int subdivLevels, int useAging, int useArena) {
-       SubSurf *ss = MEM_mallocN(sizeof(*ss), "ss_em");
-
-       ss->useAging = useAging;
-       ss->controlType = SUBSURF_CONTROLTYPE_EDITMESH;
-       ss->subSurf = _getSubSurf(ss, subdivLevels, useArena);
-       ss->em = em;
-
-       return ss;
-}
-
-static SubSurf *subSurf_fromMesh(Mesh *me, int useFlatSubdiv, int subdivLevels, float (*vertCos)[3], DispListMesh *dlm) {
-       SubSurf *ss = MEM_mallocN(sizeof(*ss), "ss_m");
-
-       ss->controlType = SUBSURF_CONTROLTYPE_MESH;
-       ss->useAging=0;
-       ss->subSurf = _getSubSurf(ss, subdivLevels, 1);
-       ss->me = me;
-       ss->dlm = dlm;
-       ss->vertCos = vertCos;
-
-       ccgSubSurf_setAllowEdgeCreation(ss->subSurf, 1, useFlatSubdiv?subdivLevels:0.0f);
-
-       return ss;
-}
-
-static void subSurf_free(SubSurf *ss) {
-       ccgSubSurf_free(ss->subSurf);
-       MEM_freeN(ss);
-}
-
 static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) {
        CCGVert *v0 = ccgSubSurf_getEdgeVert0(ss, e);
        CCGVert *v1 = ccgSubSurf_getEdgeVert1(ss, e);
@@ -216,23 +184,35 @@ 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 *subSurf_createDispListMesh(SubSurf *ssm) {
-       CCGSubSurf *ss = ssm->subSurf;
+static DispListMesh *ss_to_displistmesh(CCGSubSurf *ss, int ssFromEditmesh, Mesh *inMe, DispListMesh *inDLM) {
        DispListMesh *dlm = MEM_callocN(sizeof(*dlm), "dlm");
-       TFace *tface = ssm->dlm?ssm->dlm->tface:ssm->me->tface;
-       MEdge *medge = ssm->dlm?ssm->dlm->medge:ssm->me->medge;
-       MFace *mface = ssm->dlm?ssm->dlm->mface:ssm->me->mface;
-       MCol *mcol = ssm->dlm?ssm->dlm->mcol:ssm->me->mcol;
        int edgeSize = ccgSubSurf_getEdgeSize(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
        int edgeIndexBase, edgeBase, faceIndexBase, faceBase;
        int i, j, k, S, x, y;
        int vertBase = 0;
-       MFace *mf;
+       TFace *tface = NULL;
+       MEdge *medge = NULL;
+       MFace *mface = NULL;
+       MCol *mcol = NULL;
        CCGVertIterator *vi;
        CCGEdgeIterator *ei;
        CCGFaceIterator *fi;
        
+       if (!ssFromEditmesh) {
+               if (inDLM) {
+                       tface = inDLM->tface;
+                       medge = inDLM->medge;
+                       mface = inDLM->mface;
+                       mcol = inDLM->mcol;
+               } else if (inMe) {
+                       tface = inMe->tface;
+                       medge = inMe->medge;
+                       mface = inMe->mface;
+                       mcol = inMe->mcol;
+               }
+       }
+
        dlm->totvert = ccgSubSurf_getNumFinalVerts(ss);
        dlm->totedge = ccgSubSurf_getNumFinalEdges(ss);
        dlm->totface = ccgSubSurf_getNumFinalFaces(ss);
@@ -240,10 +220,10 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
        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");
-       if ((ssm->controlType==SUBSURF_CONTROLTYPE_MESH) && tface) {
+       if (!ssFromEditmesh && tface) {
                dlm->tface = MEM_callocN(dlm->totface*sizeof(*dlm->tface), "dlm->tface");
                dlm->mcol = NULL;
-       } else if ((ssm->controlType==SUBSURF_CONTROLTYPE_MESH) && mcol) {
+       } else if (!ssFromEditmesh && mcol) {
                dlm->tface = NULL;
                dlm->mcol = MEM_mallocN(dlm->totface*4*sizeof(*dlm->mcol), "dlm->mcol");
        } else {
@@ -316,7 +296,7 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
                        med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
                        med->flag = ME_EDGEDRAW;
 
-                       if (ssm->controlType==SUBSURF_CONTROLTYPE_EDITMESH) {
+                       if (ssFromEditmesh) {
                                EditEdge *ee = ccgSubSurf_getEdgeEdgeHandle(ss, e);
 
                                if (ee->seam) {
@@ -380,19 +360,41 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
                float edge_data[4][6];
                float corner_data[4][6];
                float center_data[6] = {0};
-               int numDataComponents;
+               int numDataComponents = 0;
                TFace *origTFace = NULL;
-               MCol *origMCol = NULL;
                int mat_nr;
                int flag;
 
-               if (ssm->controlType==SUBSURF_CONTROLTYPE_MESH) {
+               if (!ssFromEditmesh) {
                        int origIdx = (int) ccgSubSurf_getFaceFaceHandle(ss, f);
-                       MFace *origMFace = &((MFace*) mface)[origIdx];
-                       if (tface)
-                               origTFace = &((TFace*)tface)[origIdx];
-                       if (mcol)
-                               origMCol = &mcol[origIdx*4];
+                       MFace *origMFace = &mface[origIdx];
+                       
+                       if (tface) {
+                               origTFace = &tface[origIdx];
+
+                               for (S=0; S<numVerts; S++) {
+                                       unsigned char *col = (unsigned char*) &origTFace->col[S];
+                                       corner_data[S][0] = col[0]/255.0f;
+                                       corner_data[S][1] = col[1]/255.0f;
+                                       corner_data[S][2] = col[2]/255.0f;
+                                       corner_data[S][3] = col[3]/255.0f;
+                                       corner_data[S][4] = origTFace->uv[S][0];
+                                       corner_data[S][5] = origTFace->uv[S][1];
+                               }
+                               numDataComponents = 6;
+                       } else if (mcol) {
+                               MCol *origMCol = &mcol[origIdx*4];
+
+                               for (S=0; S<numVerts; S++) {
+                                       unsigned char *col = (unsigned char*) &origMCol[S];
+                                       corner_data[S][0] = col[0]/255.0f;
+                                       corner_data[S][1] = col[1]/255.0f;
+                                       corner_data[S][2] = col[2]/255.0f;
+                                       corner_data[S][3] = col[3]/255.0f;
+                               }
+                               numDataComponents = 4;
+                       }
+
                        mat_nr = origMFace->mat_nr;
                        flag = origMFace->flag;
                } else {
@@ -401,30 +403,6 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
                        flag = ef->flag;
                }
 
-               if (origTFace) {
-                       for (S=0; S<numVerts; S++) {
-                               unsigned char *col = (unsigned char*) &origTFace->col[S];
-                               corner_data[S][0] = col[0]/255.0f;
-                               corner_data[S][1] = col[1]/255.0f;
-                               corner_data[S][2] = col[2]/255.0f;
-                               corner_data[S][3] = col[3]/255.0f;
-                               corner_data[S][4] = origTFace->uv[S][0];
-                               corner_data[S][5] = origTFace->uv[S][1];
-                       }
-                       numDataComponents = 6;
-               } else if (origMCol) {
-                       for (S=0; S<numVerts; S++) {
-                               unsigned char *col = (unsigned char*) &origMCol[S];
-                               corner_data[S][0] = col[0]/255.0f;
-                               corner_data[S][1] = col[1]/255.0f;
-                               corner_data[S][2] = col[2]/255.0f;
-                               corner_data[S][3] = col[3]/255.0f;
-                       }
-                       numDataComponents = 4;
-               } else {
-                       numDataComponents = 0;
-               }
-
                for (S=0; S<numVerts; S++) {
                        for (k=0; k<numDataComponents; k++) {
                                edge_data[S][k] = (corner_data[S][k] + corner_data[(S+1)%numVerts][k])*0.5f;
@@ -439,7 +417,7 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
                        int prevS= (S-1+numVerts)%numVerts;
                        for (y=0; y<gridSize-1; y++) {
                                for (x=0; x<gridSize-1; x++) {
-                                       mf = &dlm->mface[i];
+                                       MFace *mf = &dlm->mface[i];
                                        mf->v1 = getFaceIndex(ss, f, S, x+0, y+1, edgeSize, gridSize);
                                        mf->v2 = getFaceIndex(ss, f, S, x+1, y+1, edgeSize, gridSize);
                                        mf->v3 = getFaceIndex(ss, f, S, x+1, y+0, edgeSize, gridSize);
@@ -504,84 +482,89 @@ static DispListMesh *subSurf_createDispListMesh(SubSurf *ssm) {
        return dlm;
 }
 
-static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) {
-       float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss->subSurf);
+static void ss_sync_from_mesh(CCGSubSurf *ss, Mesh *me, DispListMesh *dlm, float (*vertexCos)[3], int useFlatSubdiv) {
+       float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
+       CCGVertHDL fVerts[4];
+       MVert *mvert = dlm?dlm->mvert:me->mvert;
+       MEdge *medge = dlm?dlm->medge:me->medge;
+       MFace *mface = dlm?dlm->mface:me->mface;
+       int totvert = dlm?dlm->totvert:me->totvert;
+       int totedge = dlm?dlm->totedge:me->totedge;
+       int totface = dlm?dlm->totface:me->totface;
+       int i;
+
+       ccgSubSurf_initFullSync(ss);
+
+       if (vertexCos) {
+               for (i=0; i<totvert; i++) {
+                       ccgSubSurf_syncVert(ss, (CCGVertHDL) i, vertexCos[i]);
+               }
+       } else {
+               for (i=0; i<totvert; i++) {
+                       ccgSubSurf_syncVert(ss, (CCGVertHDL) i, mvert[i].co);
+               }
+       }
 
-       ccgSubSurf_initFullSync(ss->subSurf);
+       if (medge) {
+               for (i=0; i<totedge; i++) {
+                       MEdge *med = &medge[i];
+                       float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
 
-       if (ss->controlType==SUBSURF_CONTROLTYPE_MESH) {
-               CCGVertHDL fVerts[4];
-               MVert *mvert = ss->dlm?ss->dlm->mvert:ss->me->mvert;
-               MEdge *medge = ss->dlm?ss->dlm->medge:ss->me->medge;
-               MFace *mface = ss->dlm?ss->dlm->mface:ss->me->mface;
-               int totvert = ss->dlm?ss->dlm->totvert:ss->me->totvert;
-               int totedge = ss->dlm?ss->dlm->totedge:ss->me->totedge;
-               int totface = ss->dlm?ss->dlm->totface:ss->me->totface;
-               int i;
+                       ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease);
+               }
+       } else {
+               for (i=0; i<totface; i++) {
+                       MFace *mf = &((MFace*) mface)[i];
 
-               if (ss->vertCos) {
-                       for (i=0; i<totvert; i++) {
-                               ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, ss->vertCos[i]);
-                       }
-               } else {
-                       for (i=0; i<totvert; i++) {
-                               ccgSubSurf_syncVert(ss->subSurf, (CCGVertHDL) i, mvert[i].co);
+                       if (!mf->v3) {
+                               ccgSubSurf_syncEdge(ss, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0);
                        }
                }
+       }
 
-               if (medge) {
-                       for (i=0; i<totedge; i++) {
-                               MEdge *med = &medge[i];
-                               float crease = useFlatSubdiv?creaseFactor:med->crease*creaseFactor/255.0f;
+       for (i=0; i<totface; i++) {
+               MFace *mf = &((MFace*) mface)[i];
 
-                               ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) med->v1, (CCGVertHDL) med->v2, crease);
-                       }
-               } else {
-                       for (i=0; i<totface; i++) {
-                               MFace *mf = &((MFace*) mface)[i];
+               if (mf->v3) {
+                       fVerts[0] = (CCGVertHDL) mf->v1;
+                       fVerts[1] = (CCGVertHDL) mf->v2;
+                       fVerts[2] = (CCGVertHDL) mf->v3;
+                       fVerts[3] = (CCGVertHDL) mf->v4;
 
-                               if (!mf->v3) {
-                                       ccgSubSurf_syncEdge(ss->subSurf, (CCGEdgeHDL) i, (CCGVertHDL) mf->v1, (CCGVertHDL) mf->v2, useFlatSubdiv?creaseFactor:0.0);
-                               }
-                       }
+                       ccgSubSurf_syncFace(ss, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts);
                }
+       }
 
-               for (i=0; i<totface; i++) {
-                       MFace *mf = &((MFace*) mface)[i];
+       ccgSubSurf_processSync(ss);
+}
 
-                       if (mf->v3) {
-                               fVerts[0] = (CCGVertHDL) mf->v1;
-                               fVerts[1] = (CCGVertHDL) mf->v2;
-                               fVerts[2] = (CCGVertHDL) mf->v3;
-                               fVerts[3] = (CCGVertHDL) mf->v4;
+void ss_sync_from_editmesh(CCGSubSurf *ss, EditMesh *em, int useFlatSubdiv)
+{
+       float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss);
+       EditVert *ev, *fVerts[4];
+       EditEdge *ee;
+       EditFace *ef;
 
-                               ccgSubSurf_syncFace(ss->subSurf, (CCGFaceHDL) i, fVerts[3]?4:3, fVerts);
-                       }
-               }
-       } else {
-               EditVert *ev, *fVerts[4];
-               EditEdge *ee;
-               EditFace *ef;
+       ccgSubSurf_initFullSync(ss);
 
-               for (ev=ss->em->verts.first; ev; ev=ev->next) {
-                       ccgSubSurf_syncVert(ss->subSurf, ev, ev->co);
-               }
+       for (ev=em->verts.first; ev; ev=ev->next) {
+               ccgSubSurf_syncVert(ss, ev, ev->co);
+       }
 
-               for (ee=ss->em->edges.first; ee; ee=ee->next) {
-                       ccgSubSurf_syncEdge(ss->subSurf, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor);
-               }
+       for (ee=em->edges.first; ee; ee=ee->next) {
+               ccgSubSurf_syncEdge(ss, ee, ee->v1, ee->v2, useFlatSubdiv?creaseFactor:ee->crease*creaseFactor);
+       }
 
-               for (ef=ss->em->faces.first; ef; ef=ef->next) {
-                       fVerts[0] = ef->v1;
-                       fVerts[1] = ef->v2;
-                       fVerts[2] = ef->v3;
-                       fVerts[3] = ef->v4;
+       for (ef=em->faces.first; ef; ef=ef->next) {
+               fVerts[0] = ef->v1;
+               fVerts[1] = ef->v2;
+               fVerts[2] = ef->v3;
+               fVerts[3] = ef->v4;
 
-                       ccgSubSurf_syncFace(ss->subSurf, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
-               }
+               ccgSubSurf_syncFace(ss, ef, ef->v4?4:3, (CCGVertHDL*) fVerts);
        }
 
-       ccgSubSurf_processSync(ss->subSurf);
+       ccgSubSurf_processSync(ss);
 }
 
 /***/
@@ -589,12 +572,12 @@ static void subSurf_sync(SubSurf *ss, int useFlatSubdiv) {
 typedef struct {
        DerivedMesh dm;
 
-       SubSurf *ss;
+       CCGSubSurf *ss;
 } CCGDerivedMesh;
 
 static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
@@ -641,17 +624,17 @@ static void ccgDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
 static int ccgDM_getNumVerts(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 
-       return ccgSubSurf_getNumFinalVerts(ccgdm->ss->subSurf);
+       return ccgSubSurf_getNumFinalVerts(ccgdm->ss);
 }
 static int ccgDM_getNumFaces(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 
-       return ccgSubSurf_getNumFinalFaces(ccgdm->ss->subSurf);
+       return ccgSubSurf_getNumFinalFaces(ccgdm->ss);
 }
 static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGVert *v = ccgSubSurf_getVert(ccgdm->ss->subSurf, vert);
-       float *co = ccgSubSurf_getVertData(ccgdm->ss->subSurf, v);
+       CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert);
+       float *co = ccgSubSurf_getVertData(ccgdm->ss, v);
 
        co_r[0] = co[0];
        co_r[1] = co[1];
@@ -660,7 +643,7 @@ static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
 static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 
-       return subSurf_createDispListMesh(ccgdm->ss);
+       return ss_to_displistmesh(ccgdm->ss, 1, NULL, NULL);
 }
 
 static void ccgDM_drawVerts(DerivedMesh *dm) {
@@ -668,11 +651,14 @@ static void ccgDM_drawVerts(DerivedMesh *dm) {
 }
 static void ccgDM_drawEdges(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
        int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
+       int useAging;
+
+       ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
 
        for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -682,7 +668,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
                if (eed->h!=0)
                        continue;
 
-               if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
+               if (useAging && !(G.f&G_BACKBUFSEL)) {
                        int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
                        glColor3ub(0, ageCol>0?ageCol:0, 0);
                }
@@ -695,7 +681,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
                glEnd();
        }
 
-       if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
+       if (useAging && !(G.f&G_BACKBUFSEL)) {
                glColor3ub(0, 0, 0);
        }
 
@@ -734,7 +720,7 @@ static void ccgDM_drawEdges(DerivedMesh *dm) {
 }
 static void ccgDM_drawMappedEdges(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
@@ -754,7 +740,7 @@ static void ccgDM_drawMappedEdges(DerivedMesh *dm) {
 }
 static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
@@ -778,7 +764,7 @@ static void ccgDM_drawLooseEdges(DerivedMesh *dm) {
 
 static void ccgDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int)) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
 
@@ -851,7 +837,7 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
 
 static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
 
        bglBegin(GL_POINTS);
@@ -869,7 +855,7 @@ static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void
 }
 static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
        CCGEdge *e = ccgSubSurf_getEdge(ss, edge);
        VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
@@ -884,9 +870,11 @@ static void ccgDM_drawMappedEdgeEM(DerivedMesh *dm, void *edge) {
 }
 static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
-       int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
+       int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
+
+       ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
 
        for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -895,7 +883,7 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void
 
                glBegin(GL_LINE_STRIP);
                if (!setDrawOptions || setDrawOptions(userData, edge)) {
-                       if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
+                       if (useAging && !(G.f&G_BACKBUFSEL)) {
                                int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
                                glColor3ub(0, ageCol>0?ageCol:0, 0);
                        }
@@ -912,9 +900,11 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void
 }
 static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void (*setDrawInterpOptions)(void *userData, EditEdge *edge, float t), void *userData) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
-       int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
+       int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss);
+
+       ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
 
        for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
                CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
@@ -926,7 +916,7 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)
                        for (i=0; i<edgeSize; i++) {
                                setDrawInterpOptions(userData, edge, (float) i/(edgeSize-1));
 
-                               if (ccgdm->ss->useAging && !(G.f&G_BACKBUFSEL)) {
+                               if (useAging && !(G.f&G_BACKBUFSEL)) {
                                        int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
                                        glColor3ub(0, ageCol>0?ageCol:0, 0);
                                }
@@ -939,7 +929,7 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)
 }
 static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss->subSurf;
+       CCGSubSurf *ss = ccgdm->ss;
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
 
@@ -970,12 +960,12 @@ static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void
 static void ccgDM_release(DerivedMesh *dm) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
 
-       subSurf_free(ccgdm->ss);
+       ccgSubSurf_free(ccgdm->ss);
 
        MEM_freeN(ccgdm);
 }
 
-static CCGDerivedMesh *getCCGDerivedMesh(SubSurf *ss) {
+static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss) {
        CCGDerivedMesh *ccgdm = MEM_mallocN(sizeof(*ccgdm), "ccgdm");
 
        ccgdm->dm.getMinMax = ccgDM_getMinMax;
@@ -1007,44 +997,53 @@ static CCGDerivedMesh *getCCGDerivedMesh(SubSurf *ss) {
 
 /***/
 
-DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, int subdivLevels, short type, DerivedMesh *oldDerived) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) oldDerived;
+DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, SubsurfModifierData *smd) {
+       int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
+       CCGSubSurf *ss = _getSubSurf(NULL, smd->levels, G.rt==52, 0, 0, useSimple);
 
-       if (!ccgdm || ccgSubSurf_getSubdivisionLevels(ccgdm->ss->subSurf)!=subdivLevels) {
-               if (ccgdm) {
-                       oldDerived->release(oldDerived);
-               }
+       ss_sync_from_editmesh(ss, em, useSimple);
 
-               ccgdm = getCCGDerivedMesh(subSurf_fromEditmesh(em, subdivLevels, G.rt==52, 0));
-       }
+       return (DerivedMesh*) getCCGDerivedMesh(ss);
+}
 
-       subSurf_sync(ccgdm->ss, type==ME_SIMPLE_SUBSURF);
+DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, DispListMesh *dlm, SubsurfModifierData *smd, int useRenderParams, float (*vertCos)[3]) {
+       int useSimple = smd->subdivType==ME_SIMPLE_SUBSURF;
 
-       return (DerivedMesh*) ccgdm;
-}
+               /* Do not use cache in render mode. */
+       if (useRenderParams) {
+               CCGSubSurf *ss = _getSubSurf(NULL, smd->renderLevels, 0, 1, 1, useSimple);
 
-DerivedMesh *subsurf_make_derived_from_dlm(DispListMesh *dlm, int subdivType, int subdivLevels) {
-       SubSurf *ss = subSurf_fromMesh(NULL, subdivType==ME_SIMPLE_SUBSURF, subdivLevels, NULL, dlm);
+               ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
 
-       subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
+               dlm = ss_to_displistmesh(ss, 0, me, dlm);
 
-       dlm = subSurf_createDispListMesh(ss);
-       
-       subSurf_free(ss);
-       
-       return derivedmesh_from_displistmesh(dlm);
-}
-DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, int subdivType, int subdivLevels, float (*vertCos)[3]) {
-       SubSurf *ss = subSurf_fromMesh(me, subdivType==ME_SIMPLE_SUBSURF, subdivLevels, vertCos, NULL);
-       DispListMesh *dlm;
+               ccgSubSurf_free(ss);
+               
+               return derivedmesh_from_displistmesh(dlm);
+       } else {
+               int useEdgeCreation = !(dlm?dlm->medge:me->medge);
+               int useIncremental = useEdgeCreation?0:smd->useIncrementalMesh;
+               CCGSubSurf *ss;
+               
+               if (!useIncremental && smd->mCache) {
+                       ccgSubSurf_free(smd->mCache);
+                       smd->mCache = NULL;
+               }
 
-       subSurf_sync(ss, subdivType==ME_SIMPLE_SUBSURF);
+               ss = _getSubSurf(smd->mCache, smd->levels, 0, 1, useEdgeCreation, useSimple);
 
-       dlm = subSurf_createDispListMesh(ss);
-       
-       subSurf_free(ss);
-       
-       return derivedmesh_from_displistmesh(dlm);
+               ss_sync_from_mesh(ss, me, dlm, vertCos, useSimple);
+
+               dlm = ss_to_displistmesh(ss, 0, me, dlm);
+
+               if (useIncremental) {
+                       smd->mCache = ss;
+               } else {
+                       ccgSubSurf_free(ss);
+               }
+               
+               return derivedmesh_from_displistmesh(dlm);
+       }
 }
 
 void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) 
@@ -1054,18 +1053,18 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
                 * calculated vert positions is incorrect for the verts 
                 * on the boundary of the mesh.
                 */
-       SubSurf *ss = subSurf_fromMesh(me, 0, 1, NULL, NULL);
+       CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0, 0);
        float edge_sum[3], face_sum[3];
        CCGVertIterator *vi;
 
-       subSurf_sync(ss, 0);
+       ss_sync_from_mesh(ss, me, NULL, NULL, 0);
 
-       vi = ccgSubSurf_getVertIterator(ss->subSurf);
+       vi = ccgSubSurf_getVertIterator(ss);
        for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
                CCGVert *v = ccgVertIterator_getCurrent(vi);
-               int idx = (int) ccgSubSurf_getVertVertHandle(ss->subSurf, v);
-               int N = ccgSubSurf_getVertNumEdges(ss->subSurf, v);
-               int numFaces = ccgSubSurf_getVertNumFaces(ss->subSurf, v);
+               int idx = (int) ccgSubSurf_getVertVertHandle(ss, v);
+               int N = ccgSubSurf_getVertNumEdges(ss, v);
+               int numFaces = ccgSubSurf_getVertNumFaces(ss, v);
                float *co;
                int i;
                 
@@ -1073,21 +1072,21 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
                face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
 
                for (i=0; i<N; i++) {
-                       CCGEdge *e = ccgSubSurf_getVertEdge(ss->subSurf, v, i);
-                       VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss->subSurf, e, 1));
+                       CCGEdge *e = ccgSubSurf_getVertEdge(ss, v, i);
+                       VecAddf(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1));
                }
                for (i=0; i<numFaces; i++) {
-                       CCGFace *f = ccgSubSurf_getVertFace(ss->subSurf, v, i);
-                       VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss->subSurf, f));
+                       CCGFace *f = ccgSubSurf_getVertFace(ss, v, i);
+                       VecAddf(face_sum, face_sum, ccgSubSurf_getFaceCenterData(ss, f));
                }
 
-               co = ccgSubSurf_getVertData(ss->subSurf, v);
+               co = ccgSubSurf_getVertData(ss, v);
                positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
                positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
                positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
        }
        ccgVertIterator_free(vi);
 
-       subSurf_free(ss);
+       ccgSubSurf_free(ss);
 }
 
index 54d2098ee1ac9a521a9a3751201903f60008057d..a5fcf32d76e7794d062d878481ad56caa8314a6c 100644 (file)
@@ -100,7 +100,10 @@ typedef struct EditMesh
        EditEdge *alledges, *curedge;
        EditFace *allfaces, *curface;
        
-       struct DerivedMesh *derived;
+               /* DerivedMesh caches... note that derived cage can be equivalent
+                * to derived final, care should be taken on release.
+                */
+       struct DerivedMesh *derivedCage, *derivedFinal;
 } EditMesh;
 
 #endif
index 8385535ed8b99de777560f7bc1a5e9ec5d69b60e..2b2cb8a1a3d43d657f01cf67fa268461ed13676c 100644 (file)
@@ -2112,23 +2112,46 @@ static void direct_link_mesh(FileData *fd, Mesh *mesh)
 
 /* ************ READ OBJECT ***************** */
 
-static void lib_link_modifier_data(FileData *fd, Object *ob, ModifierData *md)
+static void lib_link_modifiers(FileData *fd, Object *ob)
 {
-       if (md->type==eModifierType_Lattice) {
-               LatticeModifierData *lmd = (LatticeModifierData*) md;
-                       
-               lmd->object = newlibadr(fd, ob->id.lib, lmd->object);
-       } 
-       else if (md->type==eModifierType_Curve) {
-               CurveModifierData *cmd = (CurveModifierData*) md;
+       ModifierData *md;
+
+       for (md=ob->modifiers.first; md; md=md->next) {
+               if (md->type==eModifierType_Lattice) {
+                       LatticeModifierData *lmd = (LatticeModifierData*) md;
+                               
+                       lmd->object = newlibadr(fd, ob->id.lib, lmd->object);
+               } 
+               else if (md->type==eModifierType_Curve) {
+                       CurveModifierData *cmd = (CurveModifierData*) md;
+                               
+                       cmd->object = newlibadr(fd, ob->id.lib, cmd->object);
+               }
+       }
+
+               /* Patch subsurf modifier */
+       if (ob->type==OB_MESH) {
+               Mesh *me = ob->data;
+
+               if (me->flag&ME_SUBSURF) {
+                       SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
+
+                       smd->levels = me->subdiv;
+                       smd->renderLevels = me->subdivr;
+                       smd->subdivType = me->subsurftype;
                        
-               cmd->object = newlibadr(fd, ob->id.lib, cmd->object);
+                       BLI_addtail(&ob->modifiers, smd);
+
+                               /* Turn it off, so it won't get saved again with flag,
+                                * still could be an issue with lib-linked mesh.
+                                */
+                       me->flag ^= ME_SUBSURF; 
+               }
        }
 }
 
 static void lib_link_object(FileData *fd, Main *main)
 {
-       ModifierData *md;
        Object *ob;
        bSensor *sens;
        bController *cont;
@@ -2260,9 +2283,7 @@ static void lib_link_object(FileData *fd, Main *main)
                                hook->parent= newlibadr(fd, ob->id.lib, hook->parent);
                        }
 
-                       for (md=ob->modifiers.first; md; md= md->next) {
-                               lib_link_modifier_data(fd, ob, md);
-                       }
+                       lib_link_modifiers(fd, ob);
                }
                ob= ob->id.next;
        }
@@ -2289,6 +2310,21 @@ static void direct_link_pose(FileData *fd, bPose *pose) {
 
 }
 
+static void direct_link_modifiers(FileData *fd, ListBase *lb)
+{
+       ModifierData *md;
+
+       link_list(fd, lb);
+
+       for (md=lb->first; md; md=md->next) {
+               if (md->type==eModifierType_Subsurf) {
+                       SubsurfModifierData *smd = (SubsurfModifierData*) md;
+
+                       smd->emCache = smd->mCache = 0;
+               }
+       }
+}
+
 static void direct_link_object(FileData *fd, Object *ob)
 {
        PartEff *paf;
@@ -2304,7 +2340,6 @@ static void direct_link_object(FileData *fd, Object *ob)
        ob->pose= newdataadr(fd, ob->pose);
        direct_link_pose(fd, ob->pose);
 
-       link_list(fd, &ob->modifiers);
        link_list(fd, &ob->defbase);
        link_list(fd, &ob->nlastrips);
        link_list(fd, &ob->constraintChannels);
@@ -2327,8 +2362,7 @@ static void direct_link_object(FileData *fd, Object *ob)
                if(paf->type==EFF_BUILD) {
                        BuildEff *baf = (BuildEff*) paf;
                        PartEff *next = paf->next;
-                       ModifierTypeInfo *mti = modifierType_get_info(eModifierType_Build);
-                       BuildModifierData *bmd = (BuildModifierData*) mti->allocData();
+                       BuildModifierData *bmd = (BuildModifierData*) modifier_new(eModifierType_Build);
 
                        bmd->start = baf->sfra;
                        bmd->length = baf->len;
@@ -2408,6 +2442,8 @@ static void direct_link_object(FileData *fd, Object *ob)
                        }
                }
        }
+
+       direct_link_modifiers(fd, &ob->modifiers);
        
        ob->bb= NULL;
        ob->derivedDeform= NULL;
@@ -4767,7 +4803,6 @@ static void do_versions(FileData *fd, Main *main)
                        }
                }
        }
-       
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
 
index 5ebdd4d5a1a435a76bdc6f03b14a61a971c0058a..6d626a5d6a885745a8ab3cbd01737311a76261c1 100644 (file)
@@ -601,6 +601,10 @@ enum {
 #define B_RECALCAL             3411
 #define B_RECALC_DEFL  3412
 
+#define B_MDFR_BUTS                    3600
+
+#define B_MDFR_INCREMENTAl     3501
+
 /* *********************** */
 
 /* *********************** */
index 5eb00c4f21bf6a53bc552acdcda5e695d12b7e8a..8efad895e479a5722adbe2cd19381f7be5ec7790 100644 (file)
@@ -36,7 +36,9 @@ typedef struct ModifierData {
 typedef struct SubsurfModifierData {
        ModifierData modifier;
 
-       short subdivType, levels, renderLevels, pad;
+       short subdivType, levels, renderLevels, useIncrementalMesh;
+
+       void *emCache, *mCache;
 } SubsurfModifierData;
 
 typedef struct LatticeModifierData {
index b0917a1123db08dfa2b2ca7734ff7302b7919913..5008fc84e9d877123387f036154620ededa9b1bb 100644 (file)
@@ -318,9 +318,12 @@ void do_butspace(unsigned short event)
                do_uvautocalculationbuts(event);
        }
        else if(event<=B_EFFECTSBUTS) {
-               /*here we put the effects buttons do commands*/
                do_effects_panels(event);
        }
+       else if(event<=B_MDFR_BUTS) {
+               extern void do_modifier_panels(unsigned short event);
+               do_modifier_panels(event);
+       }
        else if(event==REDRAWVIEW3D) allqueue(event, 1);        // 1=do header too
        else if(event>REDRAWVIEW3D) allqueue(event, 0);
 }
index f437752a6770c381833cbef1b6896996bbf6233a..09db99e7bf57caca1b7f996620df83d8a0414f9a 100644 (file)
@@ -656,8 +656,6 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
 {
        uiBlock *block;
        float val;
-       /* Hope to support more than two subsurf algorithms */
-       char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
 
        block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win);
        if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
@@ -667,12 +665,7 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
        uiDefButS(block, NUM, B_DIFF, "Degr:",                          10,160,154,19, &me->smoothresh, 1, 80, 0, 0, "Defines maximum angle between face normals that 'Auto Smooth' will operate on");
 
        uiBlockBeginAlign(block);
-       uiBlockSetCol(block, TH_BUT_SETTING1);
-       uiDefButS(block, TOG|BIT|7, B_SUBSURFTYPE, "SubSurf",   10,134,70,19, &me->flag, 0, 0, 0, 0, "Treats the active object as a Subdivision Surface");
-       uiDefButS(block, MENU, B_SUBSURFTYPE, subsurfmenu,              80,134,84,19, &(me->subsurftype), 0, 0, 0, 0, "Selects type of Subsurf algorithm.");
        uiBlockSetCol(block, TH_AUTO);
-       uiDefButS(block, NUM, B_SUBSURFTYPE, "Subdiv:",         10, 114,110,19, &me->subdiv, 0, 6, 0, 0, "Defines the level of subdivision to display in real time interactively");
-       uiDefButS(block, NUM, B_DIFF, "",                               120,114, 44, 19, &me->subdivr, 0, 6, 0, 0, "Defines the level of subdivision to apply during rendering");
        uiDefButS(block, TOG|BIT|8, B_SUBSURFTYPE, "Optimal",   10, 94,154,19, &me->flag, 0, 0, 0, 0, "Only draws optimal wireframe");
 
        uiBlockBeginAlign(block);
index 204f580096e2f2a2e6521a35eeebc82bb59a9afd..5333bf1a61d3f24e8096bb84eee40eaeb26c6ccf 100644 (file)
@@ -1655,23 +1655,46 @@ static void object_softbodies(Object *ob)
 
 static int actModifier = 0;
 
-static void modifiers_add(void *ob_v, int type)
+void do_modifier_panels(unsigned short event)
 {
-       Object *ob = ob_v;
-       ModifierTypeInfo *mti = modifierType_get_info(type);
-
-       if (mti) {
-               ModifierData *md = mti->allocData();
-       
-               BLI_addtail(&ob->modifiers, md);
+       Object *ob = OBACT;
+       ModifierData *md;
+       int i;
 
-               actModifier = BLI_countlist(&ob->modifiers);
+       for (i=0, md=ob->modifiers.first; md && i<actModifier-1; i++)
+               md = md->next;
 
-               allqueue(REDRAWBUTSOBJECT, 0);
+       switch(event) {
+       case B_MDFR_INCREMENTAl:
+               if (md && md->type==eModifierType_Subsurf && ((SubsurfModifierData*)md)->useIncrementalMesh) {
+                       if (ob->type==OB_MESH) {
+                               Mesh *me = ob->data;
+
+                               if (!me->medge) {
+                                       if (okee("Requires mesh edges, create now?")) {
+                                               make_edges(me);
+                                       }
+                               }
+                       }
+               }
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+               allqueue(REDRAWVIEW3D, 0);
+               allqueue(REDRAWINFO, 1);        /* 1, because header->win==0! */
+               break;
        }
 }
 
+static void modifiers_add(void *ob_v, int type)
+{
+       Object *ob = ob_v;
+       BLI_addtail(&ob->modifiers, modifier_new(type));
+
+       actModifier = BLI_countlist(&ob->modifiers);
+
+       allqueue(REDRAWBUTSOBJECT, 0);
+       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+}
+
 static uiBlock *modifier_add_menu(void *ob_v)
 {
        Object *ob = ob_v;
@@ -1707,7 +1730,8 @@ static void modifiers_del(void *ob_v, void *arg2)
 
        if (md) {
                BLI_remlink(&ob->modifiers, md);
-               MEM_freeN(md);
+
+               modifier_free(md);
        }
 
        allqueue(REDRAWBUTSOBJECT, 0);
@@ -1819,7 +1843,8 @@ static void object_panel_modifiers(Object *ob)
                                char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
                                uiDefButS(block, NUM, B_MAKEDISP, "Levels:",            550, 320, 150,19, &smd->levels, 1, 6, 0, 0, "Number subdivisions to perform");
                                uiDefButS(block, NUM, B_MAKEDISP, "Render Levels:",             550, 300, 150,19, &smd->renderLevels, 1, 6, 0, 0, "Number subdivisions to perform when rendering");
-                               uiDefButS(block, MENU, B_MAKEDISP, subsurfmenu,         550,280,150,19, &(smd->subdivType), 0, 0, 0, 0, "Selects type of subdivision algorithm.");
+                               uiDefButS(block, MENU, B_MAKEDISP, subsurfmenu,         550,280,150,19, &smd->subdivType, 0, 0, 0, 0, "Selects type of subdivision algorithm.");
+                               uiDefButS(block, TOG, B_MDFR_INCREMENTAl, "Incremental", 550, 260,150,19,&smd->useIncrementalMesh, 0, 0, 1, 0, "Use incremental calculation, even outside of mesh mode");
                        } else if (md->type==eModifierType_Lattice) {
                                LatticeModifierData *lmd = (LatticeModifierData*) md;
                                uiDefIDPoinBut(block, modifier_testLatticeObj, B_CHANGEDEP, "Ob:",              550, 320, 120,19, &lmd->object, "Lattice object to deform with");
index 4c05139227c0100573378414a7fea544dc5a751f..20a6bb1df3a2439c063b7f7a4d67430fea98b34d 100644 (file)
@@ -1659,16 +1659,9 @@ static void draw_em_measure_stats(Object *ob, EditMesh *em)
        }
 }
 
-static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *baseDM, DerivedMesh *realDM, int dt)
+static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
 {
        Mesh *me = ob->data;
-       DerivedMesh *cageDM;
-
-       if(realDM && (me->flag&ME_OPT_EDGES)) {
-               cageDM = realDM;
-       } else {
-               cageDM = baseDM;
-       }
 
        if(dt>OB_WIRE) {
                glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
@@ -1676,11 +1669,7 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *baseDM, Derived
                glEnable(GL_LIGHTING);
                glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
 
-               if (realDM) {
-                       realDM->drawFacesSolid(realDM, set_gl_material);
-               } else {
-                       baseDM->drawFacesSolid(baseDM, set_gl_material);
-               }
+               finalDM->drawFacesSolid(finalDM, set_gl_material);
 
                glFrontFace(GL_CCW);
                glDisable(GL_LIGHTING);
@@ -1693,9 +1682,9 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *baseDM, Derived
                glDepthMask(0);
        } 
        else {
-               if (realDM && !(me->flag&ME_OPT_EDGES)) {
+               if (cageDM!=finalDM) {
                        BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7);
-                       realDM->drawEdges(realDM);
+                       finalDM->drawEdges(finalDM);
                }
        }
        
@@ -1918,13 +1907,14 @@ static void draw_mesh_object(Base *base, int dt)
        int has_alpha= 0;
        
        if(G.obedit && ob->data==G.obedit->data) {
-               DerivedMesh *baseDM = editmesh_get_derived_proxy();
-               DerivedMesh *realDM = editmesh_get_derived();
+               int cageNeedsFree, finalNeedsFree;
+               DerivedMesh *finalDM, *cageDM = editmesh_get_derived_cage_and_final(&finalDM, &cageNeedsFree, &finalNeedsFree);
 
                if(dt>OB_WIRE) init_gl_materials(ob);   // no transp in editmode, the fancy draw over goes bad then
-               draw_em_fancy(ob, G.editMesh, baseDM, realDM, dt);
+               draw_em_fancy(ob, G.editMesh, cageDM, finalDM, dt);
 
-               baseDM->release(baseDM);
+               if (cageNeedsFree) cageDM->release(cageDM);
+               if (finalNeedsFree) finalDM->release(finalDM);
        }
        else {
                BoundBox *bb = mesh_get_bb(me);
index 74437bc771b54fc0091d3f6ac03ae97c395c799e..8a1d108883422bbf17b9df7aaae50d9584cea56c 100644 (file)
@@ -500,16 +500,9 @@ void count_object(Object *ob, int sel)
                if(me) {
                        int totvert, totface;
                        
-                       /* note; do not make disp or get derived mesh here. spoils dependency order */
-                       if (me->flag & ME_SUBSURF) {
-                                       /* approximate counts, about right for a mesh entirely made 
-                                        * of quads and that is a closed 2-manifold.
-                                        */
-                               totvert= totface= me->totface*1<<(me->subdiv*2);
-                       } else {
-                               totvert= me->totvert;
-                               totface= me->totface;
-                       }
+                               // XXX fixme for modifier stack
+                       totvert= me->totvert;
+                       totface= me->totface;
                        
                        G.totvert+= totvert;
                        G.totface+= totface;
index 804b77abb8019499706dad5e58860ca38a813029..2e3ca06a9bbbb6f8d18458f37c2fb45801e364f9 100644 (file)
@@ -451,9 +451,15 @@ void free_editMesh(EditMesh *em)
        if(em->edges.first) free_edgelist(&em->edges);
        if(em->faces.first) free_facelist(&em->faces);
 
-       if(em->derived) {
-               em->derived->release(em->derived);
-               em->derived= NULL;
+       if(em->derivedFinal) {
+               if (em->derivedFinal!=em->derivedCage) {
+                       em->derivedFinal->release(em->derivedFinal);
+               }
+               em->derivedFinal= NULL;
+       }
+       if(em->derivedCage) {
+               em->derivedCage->release(em->derivedCage);
+               em->derivedCage= NULL;
        }
 
        /* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
@@ -699,7 +705,7 @@ void make_editMesh()
                }
 
        }
-
+       
        if(actkey && actkey->totelem!=me->totvert);
        else {
                unsigned int *mcol;
@@ -779,7 +785,7 @@ void make_editMesh()
        MEM_freeN(evlist);
 
        end_editmesh_fastmalloc();      // resets global function pointers
-
+       
        /* this creates coherent selections. also needed for older files */
        EM_selectmode_set();
        /* paranoia check to enforce hide rules */
@@ -1388,7 +1394,7 @@ void separate_mesh(void)
        emcopy.allverts= NULL;
        emcopy.alledges= NULL;
        emcopy.allfaces= NULL;
-       emcopy.derived= NULL;
+       emcopy.derivedFinal= emcopy.derivedCage= NULL;
        free_editMesh(&emcopy);
        
        em->verts= edve;
@@ -1554,7 +1560,7 @@ void separate_mesh_loose(void)
                        emcopy.allverts= NULL;
                        emcopy.alledges= NULL;
                        emcopy.allfaces= NULL;
-                       emcopy.derived= NULL;
+                       emcopy.derivedFinal= emcopy.derivedCage= NULL;
                        free_editMesh(&emcopy);
                        
                        em->verts= edve;