2.5
[blender.git] / source / blender / blenkernel / intern / modifier.c
index 2cb64896d87731340d7c4397e44feb7f9443f436..80a9f173d6ac119b23c9d0918fc9e670f5d41e90 100644 (file)
@@ -20,8 +20,6 @@
 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
 * All rights reserved.
 *
-* The Original Code is: all of this file.
-*
 * Contributor(s): Daniel Dunbar
 *                 Ton Roosendaal,
 *                 Ben Batt,
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_action_types.h"
 #include "DNA_armature_types.h"
+#include "DNA_camera_types.h"
 #include "DNA_cloth_types.h"
+#include "DNA_curve_types.h"
 #include "DNA_effect_types.h"
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
@@ -66,8 +67,6 @@
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_texture_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_camera_types.h"
 
 #include "BLI_editVert.h"
 
 
 #include "BKE_main.h"
 #include "BKE_anim.h"
-#include "BKE_bad_level_calls.h"
+#include "BKE_bmesh.h"
+// XXX #include "BKE_booleanops.h"
 #include "BKE_cloth.h"
 #include "BKE_collision.h"
+#include "BKE_cdderivedmesh.h"
 #include "BKE_curve.h"
 #include "BKE_customdata.h"
-#include "BKE_global.h"
-#include "BKE_cdderivedmesh.h"
 #include "BKE_DerivedMesh.h"
-#include "BKE_booleanops.h"
 #include "BKE_displist.h"
-#include "BKE_modifier.h"
+#include "BKE_fluidsim.h"
+#include "BKE_global.h"
+#include "BKE_multires.h"
 #include "BKE_lattice.h"
 #include "BKE_library.h"
-#include "BKE_subsurf.h"
-#include "BKE_object.h"
-#include "BKE_mesh.h"
-#include "BKE_softbody.h"
-#include "BKE_cloth.h"
 #include "BKE_material.h"
+#include "BKE_mesh.h"
+#include "BKE_modifier.h"
+#include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
+#include "BKE_softbody.h"
+#include "BKE_subsurf.h"
+#include "BKE_texture.h"
 #include "BKE_utildefines.h"
+
 #include "depsgraph_private.h"
-#include "BKE_bmesh.h"
+#include "BKE_deform.h"
+#include "BKE_shrinkwrap.h"
+#include "BKE_simple_deform.h"
 
-#include "LOD_DependKludge.h"
+//XXX #include "LOD_DependKludge.h"
 #include "LOD_decimation.h"
 
+// XXX
+static struct DerivedMesh *NewBooleanDerivedMesh() {return NULL;}
+
 #include "CCGSubSurf.h"
 
 #include "RE_shader_ext.h"
 
+//XXX #include "BIF_meshlaplacian.h"
+
+/* Utility */
+
+static int is_last_displist(Object *ob)
+{
+       Curve *cu = ob->data;
+       static int curvecount=0, totcurve=0;
+
+       if(curvecount == 0){
+               DispList *dl;
+
+               totcurve = 0;
+               for(dl=cu->disp.first; dl; dl=dl->next)
+                       totcurve++;
+       }
+
+       curvecount++;
+
+       if(curvecount == totcurve){
+               curvecount = 0;
+               return 1;
+       }
+
+       return 0;
+}
+
+static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos)[3], int orco)
+{
+       DerivedMesh *dm= NULL;
+
+       if(ob->type==OB_MESH) {
+               dm = CDDM_from_mesh((Mesh*)(ob->data), ob);
+
+               if(vertexCos) {
+                       CDDM_apply_vert_coords(dm, vertexCos);
+                       //CDDM_calc_normals(dm);
+               }
+               
+               if(orco)
+                       DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
+       }
+       else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)) {
+               Object *tmpobj;
+               Curve *tmpcu;
+
+               if(is_last_displist(ob)) {
+                       /* copies object and modifiers (but not the data) */
+                       tmpobj= copy_object(ob);
+                       tmpcu = (Curve *)tmpobj->data;
+                       tmpcu->id.us--;
+
+                       /* copies the data */
+                       tmpobj->data = copy_curve((Curve *) ob->data);
+
+                       makeDispListCurveTypes(scene, tmpobj, 1);
+                       nurbs_to_mesh(tmpobj);
+
+                       dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj);
+                       //CDDM_calc_normals(dm);
+
+                       free_libblock_us(&G.main->object, tmpobj);
+               }
+       }
+
+       return dm;
+}
+
 /***/
 
 static int noneModifier_isDisabled(ModifierData *md)
@@ -134,7 +209,7 @@ static void curveModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tcmd->name, cmd->name, 32);
 }
 
-CustomDataMask curveModifier_requiredDataMask(ModifierData *md)
+CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CurveModifierData *cmd = (CurveModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -163,7 +238,7 @@ static void curveModifier_foreachObjectLink(
 }
 
 static void curveModifier_updateDepgraph(
-                                        ModifierData *md, DagForest *forest,
+                                        ModifierData *md, DagForest *forest, Scene *scene,
       Object *ob, DagNode *obNode)
 {
        CurveModifierData *cmd = (CurveModifierData*) md;
@@ -178,11 +253,11 @@ static void curveModifier_updateDepgraph(
 
 static void curveModifier_deformVerts(
                                      ModifierData *md, Object *ob, DerivedMesh *derivedData,
-         float (*vertexCos)[3], int numVerts)
+         float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        CurveModifierData *cmd = (CurveModifierData*) md;
 
-       curve_deform_verts(cmd->object, ob, derivedData, vertexCos, numVerts,
+       curve_deform_verts(md->scene, cmd->object, ob, derivedData, vertexCos, numVerts,
                           cmd->name, cmd->defaxis);
 }
 
@@ -194,7 +269,7 @@ static void curveModifier_deformVertsEM(
 
        if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
 
-       curveModifier_deformVerts(md, ob, dm, vertexCos, numVerts);
+       curveModifier_deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0);
 
        if(!derivedData) dm->release(dm);
 }
@@ -210,7 +285,7 @@ static void latticeModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tlmd->name, lmd->name, 32);
 }
 
-CustomDataMask latticeModifier_requiredDataMask(ModifierData *md)
+CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        LatticeModifierData *lmd = (LatticeModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -238,7 +313,7 @@ static void latticeModifier_foreachObjectLink(
        walk(userData, ob, &lmd->object);
 }
 
-static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest,  Scene *scene,
                                           Object *ob, DagNode *obNode)
 {
        LatticeModifierData *lmd = (LatticeModifierData*) md;
@@ -267,7 +342,7 @@ static void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3])
 
 static void latticeModifier_deformVerts(
                                        ModifierData *md, Object *ob, DerivedMesh *derivedData,
-     float (*vertexCos)[3], int numVerts)
+     float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        LatticeModifierData *lmd = (LatticeModifierData*) md;
 
@@ -286,7 +361,7 @@ static void latticeModifier_deformVertsEM(
 
        if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
 
-       latticeModifier_deformVerts(md, ob, dm, vertexCos, numVerts);
+       latticeModifier_deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0);
 
        if(!derivedData) dm->release(dm);
 }
@@ -414,10 +489,10 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
        for(i = 0; i < maxFaces; ++i) faceMap[i] = i;
 
        if (ob) {
-               frac = bsystem_time(ob, (float)G.scene->r.cfra,
+               frac = bsystem_time(md->scene, ob, md->scene->r.cfra,
                                    bmd->start - 1.0f) / bmd->length;
        } else {
-               frac = G.scene->r.cfra - bmd->start / bmd->length;
+               frac = md->scene->r.cfra - bmd->start / bmd->length;
        }
        CLAMP(frac, 0.0, 1.0);
 
@@ -583,6 +658,361 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
                   return result;
 }
 
+/* Mask */
+
+static void maskModifier_copyData(ModifierData *md, ModifierData *target)
+{
+       MaskModifierData *mmd = (MaskModifierData*) md;
+       MaskModifierData *tmmd = (MaskModifierData*) target;
+       
+       strcpy(tmmd->vgroup, mmd->vgroup);
+}
+
+static CustomDataMask maskModifier_requiredDataMask(Object *ob, ModifierData *md)
+{
+       return (1 << CD_MDEFORMVERT);
+}
+
+static void maskModifier_foreachObjectLink(
+                                             ModifierData *md, Object *ob,
+          void (*walk)(void *userData, Object *ob, Object **obpoin),
+                 void *userData)
+{
+       MaskModifierData *mmd = (MaskModifierData *)md;
+       walk(userData, ob, &mmd->ob_arm);
+}
+
+static void maskModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
+                                          Object *ob, DagNode *obNode)
+{
+       MaskModifierData *mmd = (MaskModifierData *)md;
+
+       if (mmd->ob_arm) 
+       {
+               DagNode *armNode = dag_get_node(forest, mmd->ob_arm);
+               
+               dag_add_relation(forest, armNode, obNode,
+                               DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Mask Modifier");
+       }
+}
+
+static DerivedMesh *maskModifier_applyModifier(ModifierData *md, Object *ob,
+               DerivedMesh *derivedData,
+  int useRenderParams, int isFinalCalc)
+{
+       MaskModifierData *mmd= (MaskModifierData *)md;
+       DerivedMesh *dm= derivedData, *result= NULL;
+       GHash *vertHash=NULL, *edgeHash, *faceHash;
+       GHashIterator *hashIter;
+       MDeformVert *dvert= NULL;
+       int numFaces=0, numEdges=0, numVerts=0;
+       int maxVerts, maxEdges, maxFaces;
+       int i;
+       
+       /* Overview of Method:
+        *      1. Get the vertices that are in the vertexgroup of interest 
+        *      2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
+        *      3. Make a new mesh containing only the mapping data
+        */
+       
+       /* get original number of verts, edges, and faces */
+       maxVerts= dm->getNumVerts(dm);
+       maxEdges= dm->getNumEdges(dm);
+       maxFaces= dm->getNumFaces(dm);
+       
+       /* check if we can just return the original mesh 
+        *      - must have verts and therefore verts assigned to vgroups to do anything useful
+        */
+       if ( !(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
+                (maxVerts == 0) || (ob->defbase.first == NULL) )
+       {
+               return derivedData;
+       }
+       
+       /* if mode is to use selected armature bones, aggregate the bone groups */
+       if (mmd->mode == MOD_MASK_MODE_ARM) /* --- using selected bones --- */
+       {
+               GHash *vgroupHash, *boneHash;
+               Object *oba= mmd->ob_arm;
+               bPoseChannel *pchan;
+               bDeformGroup *def;
+               
+               /* check that there is armature object with bones to use, otherwise return original mesh */
+               if (ELEM(NULL, mmd->ob_arm, mmd->ob_arm->pose))
+                       return derivedData;             
+               
+               /* hashes for finding mapping of:
+                *      - vgroups to indicies -> vgroupHash  (string, int)
+                *      - bones to vgroup indices -> boneHash (index of vgroup, dummy)
+                */
+               vgroupHash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
+               boneHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
+               
+               /* build mapping of names of vertex groups to indices */
+               for (i = 0, def = ob->defbase.first; def; def = def->next, i++) 
+                       BLI_ghash_insert(vgroupHash, def->name, SET_INT_IN_POINTER(i));
+               
+               /* get selected-posechannel <-> vertexgroup index mapping */
+               for (pchan= oba->pose->chanbase.first; pchan; pchan= pchan->next) 
+               {
+                       /* check if bone is selected */
+                       // TODO: include checks for visibility too?
+                       // FIXME: the depsgraph needs extensions to make this work in realtime...
+                       if ( (pchan->bone) && (pchan->bone->flag & BONE_SELECTED) ) 
+                       {
+                               /* check if hash has group for this bone */
+                               if (BLI_ghash_haskey(vgroupHash, pchan->name)) 
+                               {
+                                       int defgrp_index= GET_INT_FROM_POINTER(BLI_ghash_lookup(vgroupHash, pchan->name));
+                                       
+                                       /* add index to hash (store under key only) */
+                                       BLI_ghash_insert(boneHash, SET_INT_IN_POINTER(defgrp_index), pchan);
+                               }
+                       }
+               }
+               
+               /* if no bones selected, free hashes and return original mesh */
+               if (BLI_ghash_size(boneHash) == 0)
+               {
+                       BLI_ghash_free(vgroupHash, NULL, NULL);
+                       BLI_ghash_free(boneHash, NULL, NULL);
+                       
+                       return derivedData;
+               }
+               
+               /* repeat the previous check, but for dverts */
+               dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
+               if (dvert == NULL)
+               {
+                       BLI_ghash_free(vgroupHash, NULL, NULL);
+                       BLI_ghash_free(boneHash, NULL, NULL);
+                       
+                       return derivedData;
+               }
+               
+               /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
+               vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
+               
+               /* add vertices which exist in vertexgroups into vertHash for filtering */
+               for (i = 0; i < maxVerts; i++) 
+               {
+                       MDeformWeight *def_weight = NULL;
+                       int j;
+                       
+                       for (j= 0; j < dvert[i].totweight; j++) 
+                       {
+                               if (BLI_ghash_haskey(boneHash, SET_INT_IN_POINTER(dvert[i].dw[j].def_nr))) 
+                               {
+                                       def_weight = &dvert[i].dw[j];
+                                       break;
+                               }
+                       }
+                       
+                       /* check if include vert in vertHash */
+                       if (mmd->flag & MOD_MASK_INV) {
+                               /* if this vert is in the vgroup, don't include it in vertHash */
+                               if (def_weight) continue;
+                       }
+                       else {
+                               /* if this vert isn't in the vgroup, don't include it in vertHash */
+                               if (!def_weight) continue;
+                       }
+                       
+                       /* add to ghash for verts (numVerts acts as counter for mapping) */
+                       BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
+                       numVerts++;
+               }
+               
+               /* free temp hashes */
+               BLI_ghash_free(vgroupHash, NULL, NULL);
+               BLI_ghash_free(boneHash, NULL, NULL);
+       }
+       else            /* --- Using Nominated VertexGroup only --- */ 
+       {
+               int defgrp_index = -1;
+               
+               /* get index of vertex group */
+               if (mmd->vgroup[0]) 
+               {
+                       bDeformGroup *def;
+                       
+                       /* find index by comparing names - SLOW... */
+                       for (i = 0, def = ob->defbase.first; def; def = def->next, i++) 
+                       {
+                               if (!strcmp(def->name, mmd->vgroup)) 
+                               {
+                                       defgrp_index = i;
+                                       break;
+                               }
+                       }
+               }
+               
+               /* get dverts */
+               if (defgrp_index >= 0)
+                       dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
+                       
+               /* if no vgroup (i.e. dverts) found, return the initial mesh */
+               if ((defgrp_index < 0) || (dvert == NULL))
+                       return dm;
+                       
+               /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
+               vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
+               
+               /* add vertices which exist in vertexgroup into ghash for filtering */
+               for (i = 0; i < maxVerts; i++) 
+               {
+                       MDeformWeight *def_weight = NULL;
+                       int j;
+                       
+                       for (j= 0; j < dvert[i].totweight; j++) 
+                       {
+                               if (dvert[i].dw[j].def_nr == defgrp_index) 
+                               {
+                                       def_weight = &dvert[i].dw[j];
+                                       break;
+                               }
+                       }
+                       
+                       /* check if include vert in vertHash */
+                       if (mmd->flag & MOD_MASK_INV) {
+                               /* if this vert is in the vgroup, don't include it in vertHash */
+                               if (def_weight) continue;
+                       }
+                       else {
+                               /* if this vert isn't in the vgroup, don't include it in vertHash */
+                               if (!def_weight) continue;
+                       }
+                       
+                       /* add to ghash for verts (numVerts acts as counter for mapping) */
+                       BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
+                       numVerts++;
+               }
+       }
+       
+       /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
+       edgeHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
+       faceHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
+       
+       /* loop over edges and faces, and do the same thing to 
+        * ensure that they only reference existing verts 
+        */
+       for (i = 0; i < maxEdges; i++) 
+       {
+               MEdge me;
+               dm->getEdge(dm, i, &me);
+               
+               /* only add if both verts will be in new mesh */
+               if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) &&
+                        BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)) )
+               {
+                       BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges));
+                       numEdges++;
+               }
+       }
+       for (i = 0; i < maxFaces; i++) 
+       {
+               MFace mf;
+               dm->getFace(dm, i, &mf);
+               
+               /* all verts must be available */
+               if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)) &&
+                        BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)) &&
+                        BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)) &&
+                       (mf.v4==0 || BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) )
+               {
+                       BLI_ghash_insert(faceHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numFaces));
+                       numFaces++;
+               }
+       }
+       
+       
+       /* now we know the number of verts, edges and faces, 
+        * we can create the new (reduced) mesh
+        */
+       result = CDDM_from_template(dm, numVerts, numEdges, numFaces);
+       
+       
+       /* using ghash-iterators, map data into new mesh */
+               /* vertices */
+       for ( hashIter = BLI_ghashIterator_new(vertHash);
+                 !BLI_ghashIterator_isDone(hashIter);
+                 BLI_ghashIterator_step(hashIter) ) 
+       {
+               MVert source;
+               MVert *dest;
+               int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
+               int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
+               
+               dm->getVert(dm, oldIndex, &source);
+               dest = CDDM_get_vert(result, newIndex);
+               
+               DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
+               *dest = source;
+       }
+       BLI_ghashIterator_free(hashIter);
+               
+               /* edges */
+       for ( hashIter = BLI_ghashIterator_new(edgeHash);
+                 !BLI_ghashIterator_isDone(hashIter);
+                 BLI_ghashIterator_step(hashIter) ) 
+       {
+               MEdge source;
+               MEdge *dest;
+               int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
+               int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
+               
+               dm->getEdge(dm, oldIndex, &source);
+               dest = CDDM_get_edge(result, newIndex);
+               
+               source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
+               source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
+               
+               DM_copy_edge_data(dm, result, oldIndex, newIndex, 1);
+               *dest = source;
+       }
+       BLI_ghashIterator_free(hashIter);
+       
+               /* faces */
+       for ( hashIter = BLI_ghashIterator_new(faceHash);
+                 !BLI_ghashIterator_isDone(hashIter);
+                 BLI_ghashIterator_step(hashIter) ) 
+       {
+               MFace source;
+               MFace *dest;
+               int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
+               int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
+               int orig_v4;
+               
+               dm->getFace(dm, oldIndex, &source);
+               dest = CDDM_get_face(result, newIndex);
+               
+               orig_v4 = source.v4;
+               
+               source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
+               source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
+               source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3)));
+               if (source.v4)
+                  source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4)));
+               
+               DM_copy_face_data(dm, result, oldIndex, newIndex, 1);
+               *dest = source;
+               
+               test_index_face(dest, &result->faceData, newIndex, (orig_v4 ? 4 : 3));
+       }
+       BLI_ghashIterator_free(hashIter);
+       
+       /* recalculate normals */
+       CDDM_calc_normals(result);
+       
+       /* free hashes */
+       BLI_ghash_free(vertHash, NULL, NULL);
+       BLI_ghash_free(edgeHash, NULL, NULL);
+       BLI_ghash_free(faceHash, NULL, NULL);
+       
+       /* return the new mesh */
+       return result;
+}
+
 /* Array */
 /* Array modifier: duplicates the object multiple times along an axis
 */
@@ -638,7 +1068,7 @@ static void arrayModifier_foreachObjectLink(
        walk(userData, ob, &amd->offset_ob);
 }
 
-static void arrayModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+static void arrayModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
                                         Object *ob, DagNode *obNode)
 {
        ArrayModifierData *amd = (ArrayModifierData*) md;
@@ -727,7 +1157,7 @@ static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
 }
 
 static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
-                                         Object *ob, DerivedMesh *dm,
+                                         Scene *scene, Object *ob, DerivedMesh *dm,
        int initFlags)
 {
        int i, j;
@@ -751,9 +1181,9 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
 
        /* need to avoid infinite recursion here */
        if(amd->start_cap && amd->start_cap != ob)
-               start_cap = mesh_get_derived_final(amd->start_cap, CD_MASK_MESH);
+               start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH);
        if(amd->end_cap && amd->end_cap != ob)
-               end_cap = mesh_get_derived_final(amd->end_cap, CD_MASK_MESH);
+               end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
 
        MTC_Mat4One(offset);
 
@@ -790,12 +1220,18 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
        if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
                Curve *cu = amd->curve_ob->data;
                if(cu) {
+                       float tmp_mat[3][3];
+                       float scale;
+                       
+                       object_to_mat3(amd->curve_ob, tmp_mat);
+                       scale = Mat3ToScalef(tmp_mat);
+                               
                        if(!cu->path) {
                                cu->flag |= CU_PATH; // needed for path & bevlist
-                               makeDispListCurveTypes(amd->curve_ob, 0);
+                               makeDispListCurveTypes(scene, amd->curve_ob, 0);
                        }
                        if(cu->path)
-                               length = cu->path->totdist;
+                               length = scale*cu->path->totdist;
                }
        }
 
@@ -1268,7 +1704,7 @@ static DerivedMesh *arrayModifier_applyModifier(
        DerivedMesh *result;
        ArrayModifierData *amd = (ArrayModifierData*) md;
 
-       result = arrayModifier_doArray(amd, ob, derivedData, 0);
+       result = arrayModifier_doArray(amd, md->scene, ob, derivedData, 0);
 
        if(result != derivedData)
                CDDM_calc_normals(result);
@@ -1315,7 +1751,7 @@ static void mirrorModifier_foreachObjectLink(
        walk(userData, ob, &mmd->mirror_ob);
 }
 
-static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
                                          Object *ob, DagNode *obNode)
 {
        MirrorModifierData *mmd = (MirrorModifierData*) md;
@@ -1772,6 +2208,8 @@ typedef struct SmoothMesh {
        DerivedMesh *dm;
        float threshold; /* the cosine of the smoothing angle */
        int flags;
+       MemArena *arena;
+       ListBase propagatestack, reusestack;
 } SmoothMesh;
 
 static SmoothVert *smoothvert_copy(SmoothVert *vert, SmoothMesh *mesh)
@@ -1854,6 +2292,9 @@ static void smoothmesh_free(SmoothMesh *mesh)
 
        for(i = 0; i < mesh->num_edges; ++i)
                BLI_linklist_free(mesh->edges[i].faces, NULL);
+       
+       if(mesh->arena)
+               BLI_memarena_free(mesh->arena);
 
        MEM_freeN(mesh->verts);
        MEM_freeN(mesh->edges);
@@ -2505,6 +2946,49 @@ static void split_single_vert(SmoothVert *vert, SmoothFace *face,
        face_replace_vert(face, &repdata);
 }
 
+typedef struct PropagateEdge {
+       struct PropagateEdge *next, *prev;
+       SmoothEdge *edge;
+       SmoothVert *vert;
+} PropagateEdge;
+
+static void push_propagate_stack(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh)
+{
+       PropagateEdge *pedge = mesh->reusestack.first;
+
+       if(pedge) {
+               BLI_remlink(&mesh->reusestack, pedge);
+       }
+       else {
+               if(!mesh->arena) {
+                       mesh->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+                       BLI_memarena_use_calloc(mesh->arena);
+               }
+
+               pedge = BLI_memarena_alloc(mesh->arena, sizeof(PropagateEdge));
+       }
+
+       pedge->edge = edge;
+       pedge->vert = vert;
+       BLI_addhead(&mesh->propagatestack, pedge);
+}
+
+static void pop_propagate_stack(SmoothEdge **edge, SmoothVert **vert, SmoothMesh *mesh)
+{
+       PropagateEdge *pedge = mesh->propagatestack.first;
+
+       if(pedge) {
+               *edge = pedge->edge;
+               *vert = pedge->vert;
+               BLI_remlink(&mesh->propagatestack, pedge);
+               BLI_addhead(&mesh->reusestack, pedge);
+       }
+       else {
+               *edge = NULL;
+               *vert = NULL;
+       }
+}
+
 static void split_edge(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh);
 
 static void propagate_split(SmoothEdge *edge, SmoothVert *vert,
@@ -2582,7 +3066,7 @@ static void split_edge(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh)
        if(!edge2) {
                /* didn't find a sharp or loose edge, so try the other vert */
                vert2 = other_vert(edge, vert);
-               propagate_split(edge, vert2, mesh);
+               push_propagate_stack(edge, vert2, mesh);
        } else if(!edge_is_loose(edge2)) {
                /* edge2 is not loose, so it must be sharp */
                SmoothEdge *copy_edge = smoothedge_copy(edge, mesh);
@@ -2611,11 +3095,11 @@ static void split_edge(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh)
                /* all copying and replacing is done; the mesh should be consistent.
                * now propagate the split to the vertices at either end
                */
-               propagate_split(copy_edge, other_vert(copy_edge, vert2), mesh);
-               propagate_split(copy_edge2, other_vert(copy_edge2, vert2), mesh);
+               push_propagate_stack(copy_edge, other_vert(copy_edge, vert2), mesh);
+               push_propagate_stack(copy_edge2, other_vert(copy_edge2, vert2), mesh);
 
                if(smoothedge_has_vert(edge, vert))
-                       propagate_split(edge, vert, mesh);
+                       push_propagate_stack(edge, vert, mesh);
        } else {
                /* edge2 is loose */
                SmoothEdge *copy_edge = smoothedge_copy(edge, mesh);
@@ -2638,10 +3122,10 @@ static void split_edge(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh)
                /* copying and replacing is done; the mesh should be consistent.
                * now propagate the split to the vertex at the other end
                */
-               propagate_split(copy_edge, other_vert(copy_edge, vert2), mesh);
+               push_propagate_stack(copy_edge, other_vert(copy_edge, vert2), mesh);
 
                if(smoothedge_has_vert(edge, vert))
-                       propagate_split(edge, vert, mesh);
+                       push_propagate_stack(edge, vert, mesh);
        }
 
        BLI_linklist_free(visited_faces, NULL);
@@ -2713,6 +3197,7 @@ static void tag_and_count_extra_edges(SmoothMesh *mesh, float split_angle,
 
 static void split_sharp_edges(SmoothMesh *mesh, float split_angle, int flags)
 {
+       SmoothVert *vert;
        int i;
        /* if normal1 dot normal2 < threshold, angle is greater, so split */
        /* FIXME not sure if this always works */
@@ -2725,10 +3210,16 @@ static void split_sharp_edges(SmoothMesh *mesh, float split_angle, int flags)
        for(i = 0; i < mesh->num_edges; i++) {
                SmoothEdge *edge = &mesh->edges[i];
 
-               if(edge_is_sharp(edge, flags, mesh->threshold))
+               if(edge_is_sharp(edge, flags, mesh->threshold)) {
                        split_edge(edge, edge->verts[0], mesh);
-       }
 
+                       do {
+                               pop_propagate_stack(&edge, &vert, mesh);
+                               if(edge && smoothedge_has_vert(edge, vert))
+                                       propagate_split(edge, vert, mesh);
+                       } while(edge);
+               }
+       }
 }
 
 static int count_bridge_verts(SmoothMesh *mesh)
@@ -2905,7 +3396,7 @@ static void bevelModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
 }
 
-CustomDataMask bevelModifier_requiredDataMask(ModifierData *md)
+CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        BevelModifierData *bmd = (BevelModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -2985,7 +3476,7 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
 }
 
-CustomDataMask displaceModifier_requiredDataMask(ModifierData *md)
+CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        DisplaceModifierData *dmd = (DisplaceModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -3039,7 +3530,7 @@ static int displaceModifier_isDisabled(ModifierData *md)
 }
 
 static void displaceModifier_updateDepgraph(
-                                           ModifierData *md, DagForest *forest,
+                                           ModifierData *md, DagForest *forest, Scene *scene,
         Object *ob, DagNode *obNode)
 {
        DisplaceModifierData *dmd = (DisplaceModifierData*) md;
@@ -3052,7 +3543,7 @@ static void displaceModifier_updateDepgraph(
        }
 }
 
-static void validate_layer_name(const CustomData *data, int type, char *name)
+static void validate_layer_name(const CustomData *data, int type, char *name, char *outname)
 {
        int index = -1;
 
@@ -3065,8 +3556,10 @@ static void validate_layer_name(const CustomData *data, int type, char *name)
                * deleted, so assign the active layer to name
                */
                index = CustomData_get_active_layer_index(data, CD_MTFACE);
-               strcpy(name, data->layers[index].name);
+               strcpy(outname, data->layers[index].name);
        }
+       else
+               strcpy(outname, name);
 }
 
 static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
@@ -3092,12 +3585,11 @@ static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
                        char *done = MEM_callocN(sizeof(*done) * numVerts,
                                        "get_texture_coords done");
                        int numFaces = dm->getNumFaces(dm);
+                       char uvname[32];
                        MTFace *tf;
 
-                       validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name);
-
-                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE,
-                                       dmd->uvlayer_name);
+                       validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname);
+                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
 
                        /* verts are given the UV from the first face that uses them */
                        for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
@@ -3261,7 +3753,7 @@ static void displaceModifier_do(
 
 static void displaceModifier_deformVerts(
                                         ModifierData *md, Object *ob, DerivedMesh *derivedData,
-      float (*vertexCos)[3], int numVerts)
+      float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm;
 
@@ -3328,7 +3820,7 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target)
        tumd->aspecty = umd->aspecty;
 }
 
-CustomDataMask uvprojectModifier_requiredDataMask(ModifierData *md)
+CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = 0;
 
@@ -3360,7 +3852,7 @@ static void uvprojectModifier_foreachIDLink(ModifierData *md, Object *ob,
 }
 
 static void uvprojectModifier_updateDepgraph(ModifierData *md,
-                                            DagForest *forest, Object *ob, DagNode *obNode)
+                                            DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
 {
        UVProjectModifierData *umd = (UVProjectModifierData*) md;
        int i;
@@ -3393,6 +3885,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
        Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
        int num_projectors = 0;
        float aspect;
+       char uvname[32];
        
        if(umd->aspecty != 0) aspect = umd->aspectx / umd->aspecty;
        else aspect = 1.0f;
@@ -3407,12 +3900,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
        if(!dm->getFaceDataArray(dm, CD_MTFACE)) return dm;
 
        /* make sure we're using an existing layer */
-       validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name);
+       validate_layer_name(&dm->faceData, CD_MTFACE, umd->uvlayer_name, uvname);
 
        /* make sure we are not modifying the original UV layer */
        tface = CustomData_duplicate_referenced_layer_named(&dm->faceData,
-                       CD_MTFACE,
-   umd->uvlayer_name);
+                       CD_MTFACE, uvname);
 
        numVerts = dm->getNumVerts(dm);
 
@@ -3637,11 +4129,11 @@ static DerivedMesh *decimateModifier_applyModifier(
                ModifierData *md, Object *ob, DerivedMesh *derivedData,
   int useRenderParams, int isFinalCalc)
 {
-       DecimateModifierData *dmd = (DecimateModifierData*) md;
+       // DecimateModifierData *dmd = (DecimateModifierData*) md;
        DerivedMesh *dm = derivedData, *result = NULL;
        MVert *mvert;
        MFace *mface;
-       LOD_Decimation_Info lod;
+       // LOD_Decimation_Info lod;
        int totvert, totface;
        int a, numTris;
 
@@ -3663,6 +4155,8 @@ static DerivedMesh *decimateModifier_applyModifier(
                goto exit;
        }
 
+       // XXX
+#if 0
        lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices");
        lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*totvert, "normals");
        lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*numTris, "trias");
@@ -3747,6 +4241,10 @@ static DerivedMesh *decimateModifier_applyModifier(
        MEM_freeN(lod.vertex_buffer);
        MEM_freeN(lod.vertex_normal_buffer);
        MEM_freeN(lod.triangle_index_buffer);
+#else
+       modifier_setError(md, "Modifier not working yet in 2.5.");
+       goto exit;
+#endif
 
 exit:
                return result;
@@ -3788,7 +4286,7 @@ int smoothModifier_isDisabled(ModifierData *md)
        return 0;
 }
 
-CustomDataMask smoothModifier_requiredDataMask(ModifierData *md)
+CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        SmoothModifierData *smd = (SmoothModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -3940,7 +4438,7 @@ static void smoothModifier_do(
 
 static void smoothModifier_deformVerts(
                                       ModifierData *md, Object *ob, DerivedMesh *derivedData,
-          float (*vertexCos)[3], int numVerts)
+          float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm;
 
@@ -4017,7 +4515,7 @@ int castModifier_isDisabled(ModifierData *md)
        return 0;
 }
 
-CustomDataMask castModifier_requiredDataMask(ModifierData *md)
+CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CastModifierData *cmd = (CastModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -4039,7 +4537,7 @@ static void castModifier_foreachObjectLink(
 }
 
 static void castModifier_updateDepgraph(
-                                       ModifierData *md, DagForest *forest, Object *ob,
+                                       ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
      DagNode *obNode)
 {
        CastModifierData *cmd = (CastModifierData*) md;
@@ -4520,7 +5018,7 @@ static void castModifier_cuboid_do(
 
 static void castModifier_deformVerts(
                                     ModifierData *md, Object *ob, DerivedMesh *derivedData,
-        float (*vertexCos)[3], int numVerts)
+        float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm = derivedData;
        CastModifierData *cmd = (CastModifierData *)md;
@@ -4628,7 +5126,7 @@ static void waveModifier_foreachIDLink(ModifierData *md, Object *ob,
 }
 
 static void waveModifier_updateDepgraph(
-                                       ModifierData *md, DagForest *forest, Object *ob,
+                                       ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
      DagNode *obNode)
 {
        WaveModifierData *wmd = (WaveModifierData*) md;
@@ -4648,7 +5146,7 @@ static void waveModifier_updateDepgraph(
        }
 }
 
-CustomDataMask waveModifier_requiredDataMask(ModifierData *md)
+CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        WaveModifierData *wmd = (WaveModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -4688,12 +5186,11 @@ static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
                        char *done = MEM_callocN(sizeof(*done) * numVerts,
                                        "get_texture_coords done");
                        int numFaces = dm->getNumFaces(dm);
+                       char uvname[32];
                        MTFace *tf;
 
-                       validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name);
-
-                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE,
-                                       wmd->uvlayer_name);
+                       validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname);
+                       tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
 
                        /* verts are given the UV from the first face that uses them */
                        for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
@@ -4753,15 +5250,15 @@ static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
        }
 }
 
-static void waveModifier_do(
-                           WaveModifierData *md, Object *ob, DerivedMesh *dm,
+static void waveModifier_do(WaveModifierData *md, 
+               Scene *scene, Object *ob, DerivedMesh *dm,
        float (*vertexCos)[3], int numVerts)
 {
        WaveModifierData *wmd = (WaveModifierData*) md;
        MVert *mvert = NULL;
        MDeformVert *dvert = NULL;
        int defgrp_index;
-       float ctime = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
+       float ctime = bsystem_time(scene, ob, (float)scene->r.cfra, 0.0);
        float minfac =
                        (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow));
        float lifefac = wmd->height;
@@ -4923,7 +5420,7 @@ static void waveModifier_do(
 
 static void waveModifier_deformVerts(
                                     ModifierData *md, Object *ob, DerivedMesh *derivedData,
-        float (*vertexCos)[3], int numVerts)
+        float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm;
        WaveModifierData *wmd = (WaveModifierData *)md;
@@ -4939,7 +5436,7 @@ static void waveModifier_deformVerts(
                CDDM_calc_normals(dm);
        }
 
-       waveModifier_do(wmd, ob, dm, vertexCos, numVerts);
+       waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
 
        if(dm != derivedData) dm->release(dm);
 }
@@ -4961,7 +5458,7 @@ static void waveModifier_deformVertsEM(
                CDDM_calc_normals(dm);
        }
 
-       waveModifier_do(wmd, ob, dm, vertexCos, numVerts);
+       waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
 
        if(dm != derivedData) dm->release(dm);
 }
@@ -4985,7 +5482,7 @@ static void armatureModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tamd->defgrp_name, amd->defgrp_name, 32);
 }
 
-CustomDataMask armatureModifier_requiredDataMask(ModifierData *md)
+CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = 0;
 
@@ -5013,7 +5510,7 @@ static void armatureModifier_foreachObjectLink(
 }
 
 static void armatureModifier_updateDepgraph(
-                                           ModifierData *md, DagForest *forest, Object *ob,
+                                           ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
         DagNode *obNode)
 {
        ArmatureModifierData *amd = (ArmatureModifierData*) md;
@@ -5028,7 +5525,7 @@ static void armatureModifier_updateDepgraph(
 
 static void armatureModifier_deformVerts(
                                         ModifierData *md, Object *ob, DerivedMesh *derivedData,
-      float (*vertexCos)[3], int numVerts)
+      float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        ArmatureModifierData *amd = (ArmatureModifierData*) md;
 
@@ -5099,7 +5596,7 @@ static void hookModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(thmd->name, hmd->name, 32);
 }
 
-CustomDataMask hookModifier_requiredDataMask(ModifierData *md)
+CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        HookModifierData *hmd = (HookModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -5134,7 +5631,7 @@ static void hookModifier_foreachObjectLink(
        walk(userData, ob, &hmd->object);
 }
 
-static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
                                        Object *ob, DagNode *obNode)
 {
        HookModifierData *hmd = (HookModifierData*) md;
@@ -5149,7 +5646,7 @@ static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest,
 
 static void hookModifier_deformVerts(
                                     ModifierData *md, Object *ob, DerivedMesh *derivedData,
-        float (*vertexCos)[3], int numVerts)
+        float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        HookModifierData *hmd = (HookModifierData*) md;
        float vec[3], mat[4][4];
@@ -5270,7 +5767,7 @@ static void hookModifier_deformVertsEM(
 
        if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
 
-       hookModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts);
+       hookModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
 
        if(!derivedData) dm->release(dm);
 }
@@ -5279,9 +5776,14 @@ static void hookModifier_deformVertsEM(
 
 static void softbodyModifier_deformVerts(
                                         ModifierData *md, Object *ob, DerivedMesh *derivedData,
-      float (*vertexCos)[3], int numVerts)
+      float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
+{
+       sbObjectStep(md->scene, ob, (float)md->scene->r.cfra, vertexCos, numVerts);
+}
+
+static int softbodyModifier_dependsOnTime(ModifierData *md)
 {
-       sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts);
+       return 1;
 }
 
 
@@ -5317,7 +5819,7 @@ static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob,
                        return derivedData;
        }
 
-       result = clothModifier_do(clmd, ob, derivedData, useRenderParams, isFinalCalc);
+       result = clothModifier_do(clmd, md->scene, ob, derivedData, useRenderParams, isFinalCalc);
 
        if(result)
        {
@@ -5328,7 +5830,7 @@ static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob,
 }
 
 static void clothModifier_updateDepgraph(
-                                        ModifierData *md, DagForest *forest, Object *ob,
+                                        ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
       DagNode *obNode)
 {
        ClothModifierData *clmd = (ClothModifierData*) md;
@@ -5337,7 +5839,7 @@ static void clothModifier_updateDepgraph(
        
        if(clmd)
        {
-               for(base = G.scene->base.first; base; base= base->next) 
+               for(base = scene->base.first; base; base= base->next) 
                {
                        Object *ob1= base->object;
                        if(ob1 != ob)
@@ -5353,7 +5855,7 @@ static void clothModifier_updateDepgraph(
        }
 }
 
-CustomDataMask clothModifier_requiredDataMask(ModifierData *md)
+CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = 0;
 
@@ -5462,7 +5964,7 @@ static int collisionModifier_dependsOnTime(ModifierData *md)
 
 static void collisionModifier_deformVerts(
                                          ModifierData *md, Object *ob, DerivedMesh *derivedData,
-       float (*vertexCos)[3], int numVerts)
+       float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        CollisionModifierData *collmd = (CollisionModifierData*) md;
        DerivedMesh *dm = NULL;
@@ -5485,14 +5987,14 @@ static void collisionModifier_deformVerts(
                CDDM_apply_vert_coords(dm, vertexCos);
                CDDM_calc_normals(dm);
                
-               current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
+               current_time = bsystem_time (md->scene,  ob, ( float ) md->scene->r.cfra, 0.0 );
                
                if(G.rt > 0)
                        printf("current_time %f, collmd->time %f\n", current_time, collmd->time);
                
                numverts = dm->getNumVerts ( dm );
                
-               if(current_time > collmd->time)
+               if((current_time > collmd->time)|| (BKE_ptcache_get_continue_physics()))
                {       
                        // check if mesh has changed
                        if(collmd->x && (numverts != collmd->numverts))
@@ -5589,6 +6091,81 @@ static void collisionModifier_deformVerts(
 }
 
 
+
+/* Surface */
+
+static void surfaceModifier_initData(ModifierData *md) 
+{
+       SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+       
+       surmd->bvhtree = NULL;
+}
+
+static void surfaceModifier_freeData(ModifierData *md)
+{
+       SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+       
+       if (surmd)
+       {
+               if(surmd->bvhtree) {
+                       free_bvhtree_from_mesh(surmd->bvhtree);
+                       MEM_freeN(surmd->bvhtree);
+               }
+
+               if(surmd->dm)
+                       surmd->dm->release(surmd->dm);
+               
+               surmd->bvhtree = NULL;
+               surmd->dm = NULL;
+       }
+}
+
+static int surfaceModifier_dependsOnTime(ModifierData *md)
+{
+       return 1;
+}
+
+static void surfaceModifier_deformVerts(
+                                         ModifierData *md, Object *ob, DerivedMesh *derivedData,
+       float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
+{
+       SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+       unsigned int numverts = 0, i = 0;
+       
+       if(surmd->dm)
+               surmd->dm->release(surmd->dm);
+
+       /* if possible use/create DerivedMesh */
+       if(derivedData) surmd->dm = CDDM_copy(derivedData);
+       else surmd->dm = get_original_dm(md->scene, ob, NULL, 0);
+       
+       if(!ob->pd)
+       {
+               printf("surfaceModifier_deformVerts: Should not happen!\n");
+               return;
+       }
+       
+       if(surmd->dm)
+       {
+               CDDM_apply_vert_coords(surmd->dm, vertexCos);
+               CDDM_calc_normals(surmd->dm);
+               
+               numverts = surmd->dm->getNumVerts ( surmd->dm );
+
+               /* convert to global coordinates */
+               for(i = 0; i<numverts; i++)
+                       Mat4MulVecfl(ob->obmat, CDDM_get_vert(surmd->dm, i)->co);
+
+               if(surmd->bvhtree)
+                       free_bvhtree_from_mesh(surmd->bvhtree);
+               else
+                       surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
+
+               bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
+       }
+}
+
+
 /* Boolean */
 
 static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -5618,7 +6195,7 @@ static void booleanModifier_foreachObjectLink(
 }
 
 static void booleanModifier_updateDepgraph(
-                                          ModifierData *md, DagForest *forest, Object *ob,
+                                          ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
        DagNode *obNode)
 {
        BooleanModifierData *bmd = (BooleanModifierData*) md;
@@ -5637,22 +6214,44 @@ static DerivedMesh *booleanModifier_applyModifier(
 {
        // XXX doesn't handle derived data
        BooleanModifierData *bmd = (BooleanModifierData*) md;
+       DerivedMesh *dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_BAREMESH);
 
        /* we do a quick sanity check */
-       if(((Mesh *)ob->data)->totface > 3
-                   && bmd->object && ((Mesh *)bmd->object->data)->totface > 3) {
-               DerivedMesh *result = NewBooleanDerivedMesh(bmd->object, ob,
+       if(dm && (derivedData->getNumFaces(derivedData) > 3)
+                   && bmd->object && dm->getNumFaces(dm) > 3) {
+               DerivedMesh *result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob,
                                1 + bmd->operation);
 
+               if(dm)
+                       dm->release(dm);
+
                /* if new mesh returned, return it; otherwise there was
                * an error, so delete the modifier object */
                if(result)
                        return result;
                else
                        bmd->object = NULL;
-                   }
+       }
+       
+       if(dm)
+                       dm->release(dm);
+
+       return derivedData;
+}
+
+CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
+{
+       CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
+
+       dataMask |= (1 << CD_MDEFORMVERT);
+       
+       /* particles only need this if they are after a non deform modifier, and
+       * the modifier stack will only create them in that case. */
+//     dataMask |= CD_MASK_ORIGSPACE;
 
-                   return derivedData;
+//     dataMask |= CD_MASK_ORCO;
+       
+       return dataMask;
 }
 
 /* Particles */
@@ -5688,12 +6287,30 @@ static void particleSystemModifier_copyData(ModifierData *md, ModifierData *targ
        tpsmd->psys = psmd->psys;
 }
 
-CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md)
+CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
-       CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
+       CustomDataMask dataMask = 0;
+       Material *ma;
+       MTex *mtex;
        int i;
 
+       if(!psmd->psys->part)
+               return 0;
+
+       ma= give_current_material(ob, psmd->psys->part->omat);
+       if(ma) {
+               for(i=0; i<MAX_MTEX; i++) {
+                       mtex=ma->mtex[i];
+                       if(mtex && (ma->septex & (1<<i))==0)
+                               if(mtex->pmapto && (mtex->texco & TEXCO_UV))
+                                       dataMask |= (1 << CD_MTFACE);
+               }
+       }
+
+       if(psmd->psys->part->tanfac!=0.0)
+               dataMask |= (1 << CD_MTFACE);
+
        /* ask for vertexgroups if we need them */
        for(i=0; i<PSYS_TOT_VG; i++){
                if(psmd->psys->vgroup[i]){
@@ -5710,38 +6327,15 @@ CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md)
        
        return dataMask;
 }
-static int is_last_displist(Object *ob)
-{
-       Curve *cu = ob->data;
-       static int curvecount=0, totcurve=0;
-
-       if(curvecount==0){
-               DispList *dl;
-
-               totcurve=0;
-               for(dl=cu->disp.first; dl; dl=dl->next){
-                       totcurve++;
-               }
-       }
 
-       curvecount++;
-
-       if(curvecount==totcurve){
-               curvecount=0;
-               return 1;
-       }
-
-       return 0;
-}
 /* saves the current emitter state for a particle system and calculates particles */
 static void particleSystemModifier_deformVerts(
                                               ModifierData *md, Object *ob, DerivedMesh *derivedData,
-           float (*vertexCos)[3], int numVerts)
+           float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm = derivedData;
        ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
        ParticleSystem * psys=0;
-       Mesh *me;
        int needsFree=0;
 
        if(ob->particlesystem.first)
@@ -5749,54 +6343,16 @@ static void particleSystemModifier_deformVerts(
        else
                return;
        
-       /* multires check */
-       if(ob->type == OB_MESH) {
-               me= (Mesh*)ob->data;
-               if(me->mr && me->mr->current != 1)
-                       modifier_setError(md,
-                               "Particles only supported on first multires level.");
-       }
-
        if(!psys_check_enabled(ob, psys))
                return;
 
-       if(dm==0){
-               if(ob->type==OB_MESH){
-                       dm = CDDM_from_mesh((Mesh*)(ob->data), ob);
+       if(dm==0) {
+               dm= get_original_dm(md->scene, ob, vertexCos, 1);
 
-                       CDDM_apply_vert_coords(dm, vertexCos);
-                       //CDDM_calc_normals(dm);
-                       
-                       DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
-
-                       needsFree=1;
-               }
-               else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)){
-                       Object *tmpobj;
-                       Curve *tmpcu;
-
-                       if(is_last_displist(ob)){
-                               /* copies object and modifiers (but not the data) */
-                               tmpobj= copy_object( ob );
-                               tmpcu = (Curve *)tmpobj->data;
-                               tmpcu->id.us--;
-
-                               /* copies the data */
-                               tmpobj->data = copy_curve( (Curve *) ob->data );
-
-                               makeDispListCurveTypes( tmpobj, 1 );
-                               nurbs_to_mesh( tmpobj );
-
-                               dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj);
-                               //CDDM_calc_normals(dm);
-
-                               free_libblock_us( &G.main->object, tmpobj );
+               if(!dm)
+                       return;
 
-                               needsFree=1;
-                       }
-                       else return;
-               }
-               else return;
+               needsFree= 1;
        }
 
        /* clear old dm */
@@ -5824,8 +6380,7 @@ static void particleSystemModifier_deformVerts(
                  psmd->dm->getNumFaces(psmd->dm)!=psmd->totdmface){
                /* in file read dm hasn't really changed but just wasn't saved in file */
 
-               psys->recalc |= PSYS_RECALC_HAIR;
-               psys->recalc |= PSYS_DISTR;
+               psys->recalc |= PSYS_RECALC_RESET;
                psmd->flag |= eParticleSystemFlag_DM_changed;
 
                psmd->totdmvert= psmd->dm->getNumVerts(psmd->dm);
@@ -5834,7 +6389,7 @@ static void particleSystemModifier_deformVerts(
                  }
 
                  if(psys){
-                         particle_system_update(ob,psys);
+                         particle_system_update(md->scene, ob, psys);
                          psmd->flag |= eParticleSystemFlag_psys_updated;
                          psmd->flag &= ~eParticleSystemFlag_DM_changed;
                  }
@@ -5882,7 +6437,7 @@ static int particleInstanceModifier_dependsOnTime(ModifierData *md)
        return 0;
 }
 static void particleInstanceModifier_updateDepgraph(ModifierData *md, DagForest *forest,
-               Object *ob, DagNode *obNode)
+                Scene *scene,Object *ob, DagNode *obNode)
 {
        ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
 
@@ -5950,23 +6505,15 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        maxvert=totvert*totpart;
        maxface=totface*totpart;
 
-       psys->lattice=psys_get_lattice(ob, psys);
+       psys->lattice=psys_get_lattice(md->scene, ob, psys);
 
        if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)){
-               float co[3];
-               for(i=0; i< totvert; i++){
-                       dm->getVertCo(dm,i,co);
-                       if(i==0){
-                               min_co=max_co=co[track];
-                       }
-                       else{
-                               if(co[track]<min_co)
-                                       min_co=co[track];
 
-                               if(co[track]>max_co)
-                                       max_co=co[track];
-                       }
-               }
+               float min_r[3], max_r[3];
+               INIT_MINMAX(min_r, max_r);
+               dm->getMinMax(dm, min_r, max_r);                
+               min_co=min_r[track];
+               max_co=max_r[track];
        }
 
        result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface);
@@ -5993,7 +6540,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
                        state.time=(mv->co[0]-min_co)/(max_co-min_co);
                        if(trackneg)
                                state.time=1.0f-state.time;
-                       psys_get_particle_on_path(pimd->ob,psys,first_particle + i/totvert,&state,1);
+                       psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1);
 
                        mv->co[0] = 0.0;
 
@@ -6015,7 +6562,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
                }
                else{
                        state.time=-1.0;
-                       psys_get_particle_state(pimd->ob,psys,i/totvert,&state,1);
+                       psys_get_particle_state(md->scene, pimd->ob, psys, i/totvert, &state,1);
                }       
 
                QuatMulVecf(state.rot,mv->co);
@@ -6067,8 +6614,8 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        CDDM_calc_normals(result);
 
        if(psys->lattice){
-               end_latt_deform();
-               psys->lattice=0;
+               end_latt_deform(psys->lattice);
+               psys->lattice= NULL;
        }
 
        return result;
@@ -6108,7 +6655,7 @@ static int explodeModifier_dependsOnTime(ModifierData *md)
 {
        return 1;
 }
-CustomDataMask explodeModifier_requiredDataMask(ModifierData *md)
+CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        ExplodeModifierData *emd= (ExplodeModifierData*) md;
        CustomDataMask dataMask = 0;
@@ -6119,22 +6666,6 @@ CustomDataMask explodeModifier_requiredDataMask(ModifierData *md)
        return dataMask;
 }
 
-/* this should really be put somewhere permanently */
-static float vert_weight(MDeformVert *dvert, int group)
-{
-       MDeformWeight *dw;
-       int i;
-       
-       if(dvert) {
-               dw= dvert->dw;
-               for(i= dvert->totweight; i>0; i--, dw++) {
-                       if(dw->def_nr == group) return dw->weight;
-                       if(i==1) break; /*otherwise dw will point to somewhere it shouldn't*/
-               }
-       }
-       return 0.0;
-}
-
 static void explodeModifier_createFacepa(ExplodeModifierData *emd,
                                         ParticleSystemModifierData *psmd,
       Object *ob, DerivedMesh *dm)
@@ -6178,7 +6709,7 @@ static void explodeModifier_createFacepa(ExplodeModifierData *emd,
                        for(i=0; i<totvert; i++){
                                val = BLI_frand();
                                val = (1.0f-emd->protect)*val + emd->protect*0.5f;
-                               if(val < vert_weight(dvert+i,emd->vgroup-1))
+                               if(val < deformvert_get_weight(dvert+i,emd->vgroup-1))
                                        vertpa[i] = -1;
                        }
                }
@@ -6187,7 +6718,7 @@ static void explodeModifier_createFacepa(ExplodeModifierData *emd,
        /* make tree of emitter locations */
        tree=BLI_kdtree_new(totpart);
        for(p=0,pa=psys->particles; p<totpart; p++,pa++){
-               psys_particle_on_dm(ob,psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
+               psys_particle_on_dm(psmd->dm,psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,0,0);
                BLI_kdtree_insert(tree, p, co, NULL);
        }
        BLI_kdtree_balance(tree);
@@ -6702,12 +7233,11 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
 
 }
 static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, 
-               ParticleSystemModifierData *psmd, Object *ob, 
+               ParticleSystemModifierData *psmd, Scene *scene, Object *ob, 
   DerivedMesh *to_explode)
 {
        DerivedMesh *explode, *dm=to_explode;
        MFace *mf=0;
-       MVert *dupvert=0;
        ParticleSettings *part=psmd->psys->part;
        ParticleData *pa=NULL, *pars=psmd->psys->particles;
        ParticleKey state;
@@ -6727,9 +7257,9 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        timestep= psys_get_timestep(part);
 
        if(part->flag & PART_GLOB_TIME)
-               cfra=bsystem_time(0,(float)G.scene->r.cfra,0.0);
+               cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
        else
-               cfra=bsystem_time(ob,(float)G.scene->r.cfra,0.0);
+               cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0);
 
        /* hash table for vertice <-> particle relations */
        vertpahash= BLI_edgehash_new();
@@ -6762,12 +7292,12 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
 
        /* the final duplicated vertices */
        explode= CDDM_from_template(dm, totdup, 0,totface);
-       dupvert= CDDM_get_verts(explode);
+       /*dupvert= CDDM_get_verts(explode);*/
 
        /* getting back to object space */
        Mat4Invert(imat,ob->obmat);
 
-       psmd->psys->lattice = psys_get_lattice(ob, psmd->psys);
+       psmd->psys->lattice = psys_get_lattice(scene, ob, psmd->psys);
 
        /* duplicate & displace vertices */
        ehi= BLI_edgehashIterator_new(vertpahash);
@@ -6791,11 +7321,11 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
                        pa= pars+i;
 
                        /* get particle state */
-                       psys_particle_on_emitter(ob, psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
+                       psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
                        Mat4MulVecfl(ob->obmat,loc0);
 
                        state.time=cfra;
-                       psys_get_particle_state(ob,psmd->psys,i,&state,1);
+                       psys_get_particle_state(scene, ob, psmd->psys, i, &state,1);
 
                        vertco=CDDM_get_vert(explode,v)->co;
                        
@@ -6847,7 +7377,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
 
                *mf = source;
 
-               test_index_face(mf, &explode->faceData, i, (mf->v4 ? 4 : 3));
+               test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3));
        }
 
        MEM_printmemlist_stats();
@@ -6860,8 +7390,8 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        CDDM_calc_normals(explode);
 
        if(psmd->psys->lattice){
-               end_latt_deform();
-               psmd->psys->lattice=0;
+               end_latt_deform(psmd->psys->lattice);
+               psmd->psys->lattice= NULL;
        }
 
        return explode;
@@ -6911,7 +7441,7 @@ static DerivedMesh * explodeModifier_applyModifier(
                                 if(emd->flag & eExplodeFlag_EdgeSplit){
                                         int *facepa = emd->facepa;
                                         DerivedMesh *splitdm=explodeModifier_splitEdges(emd,dm);
-                                        DerivedMesh *explode=explodeModifier_explodeMesh(emd,psmd,ob,splitdm);
+                                        DerivedMesh *explode=explodeModifier_explodeMesh(emd, psmd, md->scene, ob, splitdm);
 
                                         MEM_freeN(emd->facepa);
                                         emd->facepa=facepa;
@@ -6919,10 +7449,97 @@ static DerivedMesh * explodeModifier_applyModifier(
                                         return explode;
                                 }
                                 else
-                                        return explodeModifier_explodeMesh(emd,psmd,ob,derivedData);
+                                        return explodeModifier_explodeMesh(emd, psmd, md->scene, ob, derivedData);
+       }
+       return derivedData;
+}
+
+/* Fluidsim */
+static void fluidsimModifier_initData(ModifierData *md)
+{
+       FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
+       
+       fluidsim_init(fluidmd);
+}
+static void fluidsimModifier_freeData(ModifierData *md)
+{
+       FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
+       
+       fluidsim_free(fluidmd);
+}
+
+static void fluidsimModifier_copyData(ModifierData *md, ModifierData *target)
+{
+       FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
+       FluidsimModifierData *tfluidmd= (FluidsimModifierData*) target;
+       
+       if(tfluidmd->fss)
+               MEM_freeN(tfluidmd->fss);
+       
+       tfluidmd->fss = MEM_dupallocN(fluidmd->fss);
+}
+
+static DerivedMesh * fluidsimModifier_applyModifier(
+               ModifierData *md, Object *ob, DerivedMesh *derivedData,
+  int useRenderParams, int isFinalCalc)
+{
+       FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
+       DerivedMesh *result = NULL;
+       
+       /* check for alloc failing */
+       if(!fluidmd->fss)
+       {
+               fluidsimModifier_initData(md);
+               
+               if(!fluidmd->fss)
+                       return derivedData;
+       }
+
+       result = fluidsimModifier_do(fluidmd, md->scene, ob, derivedData, useRenderParams, isFinalCalc);
+
+       if(result) 
+       { 
+               return result; 
        }
+       
        return derivedData;
 }
+
+static void fluidsimModifier_updateDepgraph(
+               ModifierData *md, DagForest *forest, Scene *scene,
+      Object *ob, DagNode *obNode)
+{
+       FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
+       Base *base;
+
+       if(fluidmd && fluidmd->fss)
+       {
+               if(fluidmd->fss->type == OB_FLUIDSIM_DOMAIN)
+               {
+                       for(base = scene->base.first; base; base= base->next) 
+                       {
+                               Object *ob1= base->object;
+                               if(ob1 != ob)
+                               {
+                                       FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(ob1, eModifierType_Fluidsim);
+                                       
+                                       // only put dependancies from NON-DOMAIN fluids in here
+                                       if(fluidmdtmp && fluidmdtmp->fss && (fluidmdtmp->fss->type!=OB_FLUIDSIM_DOMAIN))
+                                       {
+                                               DagNode *curNode = dag_get_node(forest, ob1);
+                                               dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Fluidsim Object");
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+static int fluidsimModifier_dependsOnTime(ModifierData *md) 
+{
+       return 1;
+}
+
 /* MeshDeform */
 
 static void meshdeformModifier_initData(ModifierData *md)
@@ -6952,7 +7569,7 @@ static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target)
        tmmd->object = mmd->object;
 }
 
-CustomDataMask meshdeformModifier_requiredDataMask(ModifierData *md)
+CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
 {      
        MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -6981,7 +7598,7 @@ static void meshdeformModifier_foreachObjectLink(
 }
 
 static void meshdeformModifier_updateDepgraph(
-                                             ModifierData *md, DagForest *forest, Object *ob,
+                                             ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
           DagNode *obNode)
 {
        MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
@@ -7052,25 +7669,36 @@ static void meshdeformModifier_do(
       float (*vertexCos)[3], int numVerts)
 {
        MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
-       float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
-       float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
-       int a, b, totvert, totcagevert, defgrp_index;
+       Mesh *me= ob->data;
        DerivedMesh *tmpdm, *cagedm;
        MDeformVert *dvert = NULL;
        MDeformWeight *dw;
+       EditMesh *em = BKE_mesh_get_editmesh(me);
        MVert *cagemvert;
-
+       float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
+       float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
+       int a, b, totvert, totcagevert, defgrp_index;
+       
        if(!mmd->object || (!mmd->bindcos && !mmd->needbind))
                return;
        
        /* get cage derivedmesh */
-       if(mmd->object == G.obedit) {
-               tmpdm= editmesh_get_derived_cage_and_final(&cagedm, 0);
+       if(em) {
+               tmpdm= editmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0);
                if(tmpdm)
                        tmpdm->release(tmpdm);
+               BKE_mesh_end_editmesh(me, em);
        }
        else
                cagedm= mmd->object->derivedFinal;
+
+       /* if we don't have one computed, use derivedmesh from data
+        * without any modifiers */
+       if(!cagedm) {
+               cagedm= get_original_dm(md->scene, mmd->object, NULL, 0);
+               if(cagedm)
+                       cagedm->needsFree= 1;
+       }
        
        if(!cagedm)
                return;
@@ -7089,7 +7717,7 @@ static void meshdeformModifier_do(
                /* progress bar redraw can make this recursive .. */
                if(!recursive) {
                        recursive = 1;
-                       harmonic_coordinates_bind(mmd, vertexCos, numVerts, cagemat);
+                       //XXX harmonic_coordinates_bind(mmd, vertexCos, numVerts, cagemat);
                        recursive = 0;
                }
        }
@@ -7201,14 +7829,16 @@ static void meshdeformModifier_do(
 
 static void meshdeformModifier_deformVerts(
                                           ModifierData *md, Object *ob, DerivedMesh *derivedData,
-       float (*vertexCos)[3], int numVerts)
+       float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm;
 
-       if(!derivedData && ob->type==OB_MESH)
-               dm= CDDM_from_mesh(ob->data, ob);
-       else
-               dm= derivedData;
+       if (!derivedData) {
+               dm= get_original_dm(md->scene, ob, NULL, 0);
+               if (dm == NULL) return;
+       }
+       else dm= derivedData;
+
 
        modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
        
@@ -7235,6 +7865,289 @@ static void meshdeformModifier_deformVertsEM(
                dm->release(dm);
 }
 
+/* Multires */
+static void multiresModifier_initData(ModifierData *md)
+{
+       MultiresModifierData *mmd = (MultiresModifierData*)md;
+
+       mmd->lvl = mmd->totlvl = 1;
+}
+
+static void multiresModifier_freeData(ModifierData *md)
+{
+       MultiresModifierData *mmd = (MultiresModifierData*)md;
+
+       if(mmd->undo_verts)
+               MEM_freeN(mmd->undo_verts);
+}
+
+static void multiresModifier_copyData(ModifierData *md, ModifierData *target)
+{
+       MultiresModifierData *mmd = (MultiresModifierData*) md;
+       MultiresModifierData *tmmd = (MultiresModifierData*) target;
+
+       tmmd->totlvl = mmd->totlvl;
+       tmmd->lvl = mmd->lvl;
+}
+
+static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
+                                                  int useRenderParams, int isFinalCalc)
+{
+       MultiresModifierData *mmd = (MultiresModifierData*)md;
+       Mesh *me = get_mesh(ob);
+       DerivedMesh *final;
+
+       /* TODO: for now just skip a level1 mesh */
+       if(mmd->lvl == 1)
+               return dm;
+
+       final = multires_dm_create_from_derived(mmd, dm, me, useRenderParams, isFinalCalc);
+       if(mmd->undo_signal && mmd->undo_verts && mmd->undo_verts_tot == final->getNumVerts(final)) {
+               int i;
+               MVert *dst = CDDM_get_verts(final);
+               for(i = 0; i < mmd->undo_verts_tot; ++i) {
+                       VecCopyf(dst[i].co, mmd->undo_verts[i].co);
+               }
+               CDDM_calc_normals(final);
+
+               MultiresDM_mark_as_modified(final);
+
+               MEM_freeN(mmd->undo_verts);
+               mmd->undo_signal = 0;
+               mmd->undo_verts = NULL;
+       }
+
+       return final;
+}
+
+/* Shrinkwrap */
+
+static void shrinkwrapModifier_initData(ModifierData *md)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+       smd->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE;
+       smd->shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR;
+       smd->keepDist   = 0.0f;
+
+       smd->target             = NULL;
+       smd->auxTarget  = NULL;
+}
+
+static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
+{
+       ShrinkwrapModifierData *smd  = (ShrinkwrapModifierData*)md;
+       ShrinkwrapModifierData *tsmd = (ShrinkwrapModifierData*)target;
+
+       tsmd->target    = smd->target;
+       tsmd->auxTarget = smd->auxTarget;
+
+       strcpy(tsmd->vgroup_name, smd->vgroup_name);
+
+       tsmd->keepDist  = smd->keepDist;
+       tsmd->shrinkType= smd->shrinkType;
+       tsmd->shrinkOpts= smd->shrinkOpts;
+       tsmd->projAxis = smd->projAxis;
+       tsmd->subsurfLevels = smd->subsurfLevels;
+}
+
+CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
+       CustomDataMask dataMask = 0;
+
+       /* ask for vertexgroups if we need them */
+       if(smd->vgroup_name[0])
+               dataMask |= (1 << CD_MDEFORMVERT);
+
+       if(smd->shrinkType == MOD_SHRINKWRAP_PROJECT
+       && smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)
+               dataMask |= (1 << CD_MVERT);
+               
+       return dataMask;
+}
+
+static int shrinkwrapModifier_isDisabled(ModifierData *md)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+       return !smd->target;
+}
+
+
+static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+
+       walk(userData, ob, &smd->target);
+       walk(userData, ob, &smd->auxTarget);
+}
+
+static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
+{
+       DerivedMesh *dm = NULL;
+       CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md);
+
+       /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
+       if(dataMask)
+       {
+               if(derivedData) dm = CDDM_copy(derivedData);
+               else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
+               else if(ob->type==OB_LATTICE) dm = NULL;
+               else return;
+
+               if(dm != NULL && (dataMask & (1<<CD_MVERT)))
+               {
+                       CDDM_apply_vert_coords(dm, vertexCos);
+                       CDDM_calc_normals(dm);
+               }
+       }
+
+       shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
+
+       if(dm)
+               dm->release(dm);
+}
+
+static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+       DerivedMesh *dm = NULL;
+       CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md);
+
+       if(dataMask)
+       {
+               if(derivedData) dm = CDDM_copy(derivedData);
+               else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data);
+               else if(ob->type==OB_LATTICE) dm = NULL;
+               else return;
+
+               if(dm != NULL && (dataMask & (1<<CD_MVERT)))
+               {
+                       CDDM_apply_vert_coords(dm, vertexCos);
+                       CDDM_calc_normals(dm);
+               }
+       }
+
+       shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
+
+       if(dm)
+               dm->release(dm);
+}
+
+static void shrinkwrapModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
+{
+       ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
+
+       if (smd->target)
+               dag_add_relation(forest, dag_get_node(forest, smd->target),   obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
+
+       if (smd->auxTarget)
+               dag_add_relation(forest, dag_get_node(forest, smd->auxTarget), obNode, DAG_RL_OB_DATA | DAG_RL_DATA_DATA, "Shrinkwrap Modifier");
+}
+
+/* SimpleDeform */
+static void simpledeformModifier_initData(ModifierData *md)
+{
+       SimpleDeformModifierData *smd = (SimpleDeformModifierData*) md;
+
+       smd->mode = MOD_SIMPLEDEFORM_MODE_TWIST;
+       smd->axis = 0;
+
+       smd->origin   =  NULL;
+       smd->factor   =  0.35f;
+       smd->limit[0] =  0.0f;
+       smd->limit[1] =  1.0f;
+}
+
+static void simpledeformModifier_copyData(ModifierData *md, ModifierData *target)
+{
+       SimpleDeformModifierData *smd  = (SimpleDeformModifierData*)md;
+       SimpleDeformModifierData *tsmd = (SimpleDeformModifierData*)target;
+
+       tsmd->mode      = smd->mode;
+       tsmd->axis  = smd->axis;
+       tsmd->origin= smd->origin;
+       tsmd->factor= smd->factor;
+       memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit));
+}
+
+static CustomDataMask simpledeformModifier_requiredDataMask(Object *ob, ModifierData *md)
+{
+       SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
+       CustomDataMask dataMask = 0;
+
+       /* ask for vertexgroups if we need them */
+       if(smd->vgroup_name[0])
+               dataMask |= (1 << CD_MDEFORMVERT);
+
+       return dataMask;
+}
+
+static void simpledeformModifier_foreachObjectLink(ModifierData *md, Object *ob, void (*walk)(void *userData, Object *ob, Object **obpoin), void *userData)
+{
+       SimpleDeformModifierData *smd  = (SimpleDeformModifierData*)md;
+       walk(userData, ob, &smd->origin);
+}
+
+static void simpledeformModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
+{
+       SimpleDeformModifierData *smd  = (SimpleDeformModifierData*)md;
+
+       if (smd->origin)
+               dag_add_relation(forest, dag_get_node(forest, smd->origin), obNode, DAG_RL_OB_DATA, "SimpleDeform Modifier");
+}
+
+static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
+{
+       DerivedMesh *dm = NULL;
+       CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md);
+
+       /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
+       if(dataMask)
+       {
+               if(derivedData) dm = CDDM_copy(derivedData);
+               else if(ob->type==OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
+               else if(ob->type==OB_LATTICE) dm = NULL;
+               else return;
+
+               if(dm != NULL && (dataMask & CD_MVERT))
+               {
+                       CDDM_apply_vert_coords(dm, vertexCos);
+                       CDDM_calc_normals(dm);
+               }
+       }
+
+       SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts);
+
+       if(dm)
+               dm->release(dm);
+
+}
+
+static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+       DerivedMesh *dm = NULL;
+       CustomDataMask dataMask = simpledeformModifier_requiredDataMask(ob, md);
+
+       /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
+       if(dataMask)
+       {
+               if(derivedData) dm = CDDM_copy(derivedData);
+               else if(ob->type==OB_MESH) dm = CDDM_from_editmesh(editData, ob->data);
+               else if(ob->type==OB_LATTICE) dm = NULL;
+               else return;
+
+               if(dm != NULL && (dataMask & CD_MVERT))
+               {
+                       CDDM_apply_vert_coords(dm, vertexCos);
+                       CDDM_calc_normals(dm);
+               }
+       }
+
+       SimpleDeformModifier_do((SimpleDeformModifierData*)md, ob, dm, vertexCos, numVerts);
+
+       if(dm)
+               dm->release(dm);
+}
+
 /***/
 
 static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
@@ -7313,6 +8226,15 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->copyData = buildModifier_copyData;
                mti->dependsOnTime = buildModifier_dependsOnTime;
                mti->applyModifier = buildModifier_applyModifier;
+               
+               mti = INIT_TYPE(Mask);
+               mti->type = eModifierTypeType_Nonconstructive;
+               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               mti->copyData = maskModifier_copyData;
+               mti->requiredDataMask= maskModifier_requiredDataMask;
+               mti->foreachObjectLink = maskModifier_foreachObjectLink;
+               mti->updateDepgraph = maskModifier_updateDepgraph;
+               mti->applyModifier = maskModifier_applyModifier;
 
                mti = INIT_TYPE(Array);
                mti->type = eModifierTypeType_Constructive;
@@ -7467,6 +8389,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->flags = eModifierTypeFlag_AcceptsCVs
                                | eModifierTypeFlag_RequiresOriginalData;
                mti->deformVerts = softbodyModifier_deformVerts;
+               mti->dependsOnTime = softbodyModifier_dependsOnTime;
        
                mti = INIT_TYPE(Cloth);
                mti->type = eModifierTypeType_Nonconstructive;
@@ -7489,16 +8412,24 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->deformVerts = collisionModifier_deformVerts;
                // mti->copyData = collisionModifier_copyData;
 
+               mti = INIT_TYPE(Surface);
+               mti->type = eModifierTypeType_OnlyDeform;
+               mti->initData = surfaceModifier_initData;
+               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               mti->dependsOnTime = surfaceModifier_dependsOnTime;
+               mti->freeData = surfaceModifier_freeData; 
+               mti->deformVerts = surfaceModifier_deformVerts;
+
                mti = INIT_TYPE(Boolean);
                mti->type = eModifierTypeType_Nonconstructive;
                mti->flags = eModifierTypeFlag_AcceptsMesh
-                               | eModifierTypeFlag_RequiresOriginalData
                                | eModifierTypeFlag_UsesPointCache;
                mti->copyData = booleanModifier_copyData;
                mti->isDisabled = booleanModifier_isDisabled;
                mti->applyModifier = booleanModifier_applyModifier;
                mti->foreachObjectLink = booleanModifier_foreachObjectLink;
                mti->updateDepgraph = booleanModifier_updateDepgraph;
+               mti->requiredDataMask = booleanModifier_requiredDataMask;
 
                mti = INIT_TYPE(MeshDeform);
                mti->type = eModifierTypeType_OnlyDeform;
@@ -7555,6 +8486,54 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->dependsOnTime = explodeModifier_dependsOnTime;
                mti->requiredDataMask = explodeModifier_requiredDataMask;
                mti->applyModifier = explodeModifier_applyModifier;
+               
+               mti = INIT_TYPE(Fluidsim);
+               mti->type = eModifierTypeType_Nonconstructive
+                               | eModifierTypeFlag_RequiresOriginalData;
+               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               mti->initData = fluidsimModifier_initData;
+               mti->freeData = fluidsimModifier_freeData;
+               mti->copyData = fluidsimModifier_copyData;
+               mti->dependsOnTime = fluidsimModifier_dependsOnTime;
+               mti->applyModifier = fluidsimModifier_applyModifier;
+               mti->updateDepgraph = fluidsimModifier_updateDepgraph;
+
+               mti = INIT_TYPE(Shrinkwrap);
+               mti->type = eModifierTypeType_OnlyDeform;
+               mti->flags = eModifierTypeFlag_AcceptsMesh
+                               | eModifierTypeFlag_AcceptsCVs
+                               | eModifierTypeFlag_SupportsEditmode
+                               | eModifierTypeFlag_EnableInEditmode;
+               mti->initData = shrinkwrapModifier_initData;
+               mti->copyData = shrinkwrapModifier_copyData;
+               mti->requiredDataMask = shrinkwrapModifier_requiredDataMask;
+               mti->isDisabled = shrinkwrapModifier_isDisabled;
+               mti->foreachObjectLink = shrinkwrapModifier_foreachObjectLink;
+               mti->deformVerts = shrinkwrapModifier_deformVerts;
+               mti->deformVertsEM = shrinkwrapModifier_deformVertsEM;
+               mti->updateDepgraph = shrinkwrapModifier_updateDepgraph;
+
+               mti = INIT_TYPE(SimpleDeform);
+               mti->type = eModifierTypeType_OnlyDeform;
+               mti->flags = eModifierTypeFlag_AcceptsMesh
+                               | eModifierTypeFlag_AcceptsCVs                          
+                               | eModifierTypeFlag_SupportsEditmode
+                               | eModifierTypeFlag_EnableInEditmode;
+               mti->initData = simpledeformModifier_initData;
+               mti->copyData = simpledeformModifier_copyData;
+               mti->requiredDataMask = simpledeformModifier_requiredDataMask;
+               mti->deformVerts = simpledeformModifier_deformVerts;
+               mti->deformVertsEM = simpledeformModifier_deformVertsEM;
+               mti->foreachObjectLink = simpledeformModifier_foreachObjectLink;
+               mti->updateDepgraph = simpledeformModifier_updateDepgraph;
+
+               mti = INIT_TYPE(Multires);
+               mti->type = eModifierTypeType_Constructive;
+               mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_RequiresOriginalData;
+               mti->initData = multiresModifier_initData;
+               mti->freeData = multiresModifier_freeData;
+               mti->copyData = multiresModifier_copyData;
+               mti->applyModifier = multiresModifier_applyModifier;
 
                typeArrInit = 0;
 #undef INIT_TYPE
@@ -7637,8 +8616,6 @@ void modifiers_clearErrors(Object *ob)
                        qRedraw = 1;
                }
        }
-
-       if (qRedraw) allqueue(REDRAWBUTSEDIT, 0);
 }
 
 void modifiers_foreachObjectLink(Object *ob, ObjectWalkFunc walk,
@@ -7704,7 +8681,6 @@ void modifier_setError(ModifierData *md, char *format, ...)
 
        md->error = BLI_strdup(buffer);
 
-       allqueue(REDRAWBUTSEDIT, 0);
 }
 
 /* used for buttons, to find out if the 'draw deformed in editmode' option is
@@ -7761,7 +8737,20 @@ int modifiers_isParticleEnabled(Object *ob)
        return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
 }
 
-LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
+int modifier_isEnabled(ModifierData *md, int required_mode)
+{
+       ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+       if((md->mode & required_mode) != required_mode) return 0;
+       if(mti->isDisabled && mti->isDisabled(md)) return 0;
+       if(md->mode & eModifierMode_DisableTemporary) return 0;
+       if(required_mode & eModifierMode_Editmode)
+               if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0;
+       
+       return 1;
+}
+
+LinkNode *modifiers_calcDataMasks(Object *ob, ModifierData *md, CustomDataMask dataMask, int required_mode)
 {
        LinkNode *dataMasks = NULL;
        LinkNode *curr, *prev;
@@ -7771,9 +8760,11 @@ LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
                CustomDataMask mask = 0;
 
-               if(mti->requiredDataMask) mask = mti->requiredDataMask(md);
+               if(modifier_isEnabled(md, required_mode))
+                       if(mti->requiredDataMask)
+                               mask = mti->requiredDataMask(ob, md);
 
-               BLI_linklist_prepend(&dataMasks, (void *)mask);
+               BLI_linklist_prepend(&dataMasks, SET_INT_IN_POINTER(mask));
        }
 
        /* build the list of required data masks - each mask in the list must
@@ -7784,14 +8775,14 @@ LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
        */
        for(curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) {
                if(prev) {
-                       CustomDataMask prev_mask = (CustomDataMask)prev->link;
-                       CustomDataMask curr_mask = (CustomDataMask)curr->link;
+                       CustomDataMask prev_mask = (CustomDataMask)GET_INT_FROM_POINTER(prev->link);
+                       CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
 
-                       curr->link = (void *)(curr_mask | prev_mask);
+                       curr->link = SET_INT_IN_POINTER(curr_mask | prev_mask);
                } else {
-                       CustomDataMask curr_mask = (CustomDataMask)curr->link;
+                       CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
 
-                       curr->link = (void *)(curr_mask | dataMask);
+                       curr->link = SET_INT_IN_POINTER(curr_mask | dataMask);
                }
        }
 
@@ -7932,14 +8923,15 @@ int modifier_isDeformer(ModifierData *md)
        return 0;
 }
 
-int modifiers_isDeformed(Object *ob)
+int modifiers_isDeformed(Scene *scene, Object *ob)
 {
        ModifierData *md = modifiers_getVirtualModifierList(ob);
        
        for (; md; md=md->next) {
-               if(ob==G.obedit && (md->mode & eModifierMode_Editmode)==0);
-               else if(modifier_isDeformer(md))
-                       return 1;
+               if(ob==scene->obedit && (md->mode & eModifierMode_Editmode)==0);
+               else 
+                       if(modifier_isDeformer(md))
+                               return 1;
        }
        return 0;
 }
@@ -7972,9 +8964,12 @@ void modifier_freeTemporaryData(ModifierData *md)
        if(md->type == eModifierType_Armature) {
                ArmatureModifierData *amd= (ArmatureModifierData*)md;
 
-               if(amd->prevCos)
+               if(amd->prevCos) {
                        MEM_freeN(amd->prevCos);
+                       amd->prevCos= NULL;
+               }
        }
 }
 
 
+