Shape Keys
[blender-staging.git] / source / blender / blenkernel / intern / modifier.c
index 3ef7b82864c588881dd52d45eb1be4c1dcac3fac..a445b6986f622e876a76a32c451f539f0e6b47ba 100644 (file)
@@ -34,6 +34,7 @@
 *
 */
 
 *
 */
 
+#include "stddef.h"
 #include "string.h"
 #include "stdarg.h"
 #include "math.h"
 #include "string.h"
 #include "stdarg.h"
 #include "math.h"
 #include "DNA_cloth_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_effect_types.h"
 #include "DNA_cloth_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_effect_types.h"
+#include "DNA_group_types.h"
+#include "DNA_key_types.h"
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_material_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
+#include "DNA_object_fluidsim.h"
 #include "DNA_object_force.h"
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_object_force.h"
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_smoke_types.h"
 #include "DNA_texture_types.h"
 
 #include "BLI_editVert.h"
 
 #include "DNA_texture_types.h"
 
 #include "BLI_editVert.h"
 
-#include "MTC_matrixops.h"
-#include "MTC_vectorops.h"
+
+
 
 #include "BKE_main.h"
 #include "BKE_anim.h"
 
 #include "BKE_main.h"
 #include "BKE_anim.h"
+#include "BKE_action.h"
 #include "BKE_bmesh.h"
 // XXX #include "BKE_booleanops.h"
 #include "BKE_cloth.h"
 #include "BKE_bmesh.h"
 // XXX #include "BKE_booleanops.h"
 #include "BKE_cloth.h"
@@ -87,6 +93,7 @@
 #include "BKE_fluidsim.h"
 #include "BKE_global.h"
 #include "BKE_multires.h"
 #include "BKE_fluidsim.h"
 #include "BKE_global.h"
 #include "BKE_multires.h"
+#include "BKE_key.h"
 #include "BKE_lattice.h"
 #include "BKE_library.h"
 #include "BKE_material.h"
 #include "BKE_lattice.h"
 #include "BKE_library.h"
 #include "BKE_material.h"
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
+#include "BKE_smoke.h"
 #include "BKE_softbody.h"
 #include "BKE_subsurf.h"
 #include "BKE_texture.h"
 #include "BKE_softbody.h"
 #include "BKE_subsurf.h"
 #include "BKE_texture.h"
@@ -209,7 +217,7 @@ static void curveModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tcmd->name, cmd->name, 32);
 }
 
        strncpy(tcmd->name, cmd->name, 32);
 }
 
-CustomDataMask curveModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CurveModifierData *cmd = (CurveModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        CurveModifierData *cmd = (CurveModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -285,7 +293,7 @@ static void latticeModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tlmd->name, lmd->name, 32);
 }
 
        strncpy(tlmd->name, lmd->name, 32);
 }
 
-CustomDataMask latticeModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        LatticeModifierData *lmd = (LatticeModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        LatticeModifierData *lmd = (LatticeModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -668,7 +676,7 @@ static void maskModifier_copyData(ModifierData *md, ModifierData *target)
        strcpy(tmmd->vgroup, mmd->vgroup);
 }
 
        strcpy(tmmd->vgroup, mmd->vgroup);
 }
 
-static CustomDataMask maskModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask maskModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        return (1 << CD_MDEFORMVERT);
 }
 {
        return (1 << CD_MDEFORMVERT);
 }
@@ -1099,7 +1107,7 @@ static void arrayModifier_updateDepgraph(ModifierData *md, DagForest *forest, Sc
        }
 }
 
        }
 }
 
-float vertarray_size(MVert *mvert, int numVerts, int axis)
+static float vertarray_size(MVert *mvert, int numVerts, int axis)
 {
        int i;
        float min_co, max_co;
 {
        int i;
        float min_co, max_co;
@@ -1181,11 +1189,11 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
 
        /* need to avoid infinite recursion here */
        if(amd->start_cap && amd->start_cap != ob)
 
        /* need to avoid infinite recursion here */
        if(amd->start_cap && amd->start_cap != ob)
-               start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH);
+               start_cap = amd->start_cap->derivedFinal;
        if(amd->end_cap && amd->end_cap != ob)
        if(amd->end_cap && amd->end_cap != ob)
-               end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
+               end_cap = amd->end_cap->derivedFinal;
 
 
-       MTC_Mat4One(offset);
+       Mat4One(offset);
 
        indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm),
                               "indexmap");
 
        indexMap = MEM_callocN(sizeof(*indexMap) * dm->getNumVerts(dm),
                               "indexmap");
@@ -1207,14 +1215,14 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                float result_mat[4][4];
 
                if(ob)
                float result_mat[4][4];
 
                if(ob)
-                       MTC_Mat4Invert(obinv, ob->obmat);
+                       Mat4Invert(obinv, ob->obmat);
                else
                else
-                       MTC_Mat4One(obinv);
+                       Mat4One(obinv);
 
 
-               MTC_Mat4MulSerie(result_mat, offset,
+               Mat4MulSerie(result_mat, offset,
                                 obinv, amd->offset_ob->obmat,
      NULL, NULL, NULL, NULL, NULL);
                                 obinv, amd->offset_ob->obmat,
      NULL, NULL, NULL, NULL, NULL);
-               MTC_Mat4CpyMat4(offset, result_mat);
+               Mat4CpyMat4(offset, result_mat);
        }
 
        if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
        }
 
        if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
@@ -1239,7 +1247,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
        prescribed length */
        if(amd->fit_type == MOD_ARR_FITLENGTH
                  || amd->fit_type == MOD_ARR_FITCURVE) {
        prescribed length */
        if(amd->fit_type == MOD_ARR_FITLENGTH
                  || amd->fit_type == MOD_ARR_FITCURVE) {
-               float dist = sqrt(MTC_dot3Float(offset[3], offset[3]));
+               float dist = sqrt(Inpf(offset[3], offset[3]));
 
                if(dist > 1e-6f)
                        /* this gives length = first copy start to last copy end
 
                if(dist > 1e-6f)
                        /* this gives length = first copy start to last copy end
@@ -1272,11 +1280,11 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                  result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces);
 
                  /* calculate the offset matrix of the final copy (for merging) */ 
                  result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces);
 
                  /* calculate the offset matrix of the final copy (for merging) */ 
-                 MTC_Mat4One(final_offset);
+                 Mat4One(final_offset);
 
                  for(j=0; j < count - 1; j++) {
 
                  for(j=0; j < count - 1; j++) {
-                         MTC_Mat4MulMat4(tmp_mat, final_offset, offset);
-                         MTC_Mat4CpyMat4(final_offset, tmp_mat);
+                         Mat4MulMat4(tmp_mat, final_offset, offset);
+                         Mat4CpyMat4(final_offset, tmp_mat);
                  }
 
                  numVerts = numEdges = numFaces = 0;
                  }
 
                  numVerts = numEdges = numFaces = 0;
@@ -1312,7 +1320,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                          if((count > 1) && (amd->flags & MOD_ARR_MERGE)) {
                                  float tmp_co[3];
                                  VECCOPY(tmp_co, mv->co);
                          if((count > 1) && (amd->flags & MOD_ARR_MERGE)) {
                                  float tmp_co[3];
                                  VECCOPY(tmp_co, mv->co);
-                                 MTC_Mat4MulVecfl(offset, tmp_co);
+                                 Mat4MulVecfl(offset, tmp_co);
 
                                  for(j = 0; j < maxVerts; j++) {
                                          /* if vertex already merged, don't use it */
 
                                  for(j = 0; j < maxVerts; j++) {
                                          /* if vertex already merged, don't use it */
@@ -1327,7 +1335,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                                                  if(amd->flags & MOD_ARR_MERGEFINAL) {
                                                          VECCOPY(tmp_co, inMV->co);
                                                          inMV = &src_mvert[i];
                                                  if(amd->flags & MOD_ARR_MERGEFINAL) {
                                                          VECCOPY(tmp_co, inMV->co);
                                                          inMV = &src_mvert[i];
-                                                         MTC_Mat4MulVecfl(final_offset, tmp_co);
+                                                         Mat4MulVecfl(final_offset, tmp_co);
                                                          if(VecLenCompare(tmp_co, inMV->co, amd->merge_dist))
                                                                  indexMap[i].merge_final = 1;
                                                  }
                                                          if(VecLenCompare(tmp_co, inMV->co, amd->merge_dist))
                                                                  indexMap[i].merge_final = 1;
                                                  }
@@ -1345,7 +1353,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                                          *mv2 = *mv;
                                          numVerts++;
 
                                          *mv2 = *mv;
                                          numVerts++;
 
-                                         MTC_Mat4MulVecfl(offset, co);
+                                         Mat4MulVecfl(offset, co);
                                          VECCOPY(mv2->co, co);
                                  }
                          } else if(indexMap[i].merge != i && indexMap[i].merge_final) {
                                          VECCOPY(mv2->co, co);
                                  }
                          } else if(indexMap[i].merge != i && indexMap[i].merge_final) {
@@ -1766,7 +1774,7 @@ static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, S
 
 /* finds the best possible flipped name. For renaming; check for unique names afterwards */
 /* if strip_number: removes number extensions */
 
 /* finds the best possible flipped name. For renaming; check for unique names afterwards */
 /* if strip_number: removes number extensions */
-void vertgroup_flip_name (char *name, int strip_number)
+static void vertgroup_flip_name (char *name, int strip_number)
 {
        int     len;
        char    prefix[128]={""};   /* The part before the facing */
 {
        int     len;
        char    prefix[128]={""};   /* The part before the facing */
@@ -3177,7 +3185,7 @@ static void tag_and_count_extra_edges(SmoothMesh *mesh, float split_angle,
                                                         /* we know the edge has 2 faces, so check the angle */
                                                         SmoothFace *face1 = edge->faces->link;
                                                         SmoothFace *face2 = edge->faces->next->link;
                                                         /* we know the edge has 2 faces, so check the angle */
                                                         SmoothFace *face1 = edge->faces->link;
                                                         SmoothFace *face2 = edge->faces->next->link;
-                                                        float edge_angle_cos = MTC_dot3Float(face1->normal,
+                                                        float edge_angle_cos = Inpf(face1->normal,
                                                                         face2->normal);
 
                                                         if(edge_angle_cos < threshold) {
                                                                         face2->normal);
 
                                                         if(edge_angle_cos < threshold) {
@@ -3396,7 +3404,7 @@ static void bevelModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
 }
 
        strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
 }
 
-CustomDataMask bevelModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        BevelModifierData *bmd = (BevelModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        BevelModifierData *bmd = (BevelModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -3476,7 +3484,7 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
 }
 
        strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
 }
 
-CustomDataMask displaceModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        DisplaceModifierData *dmd = (DisplaceModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        DisplaceModifierData *dmd = (DisplaceModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -3543,7 +3551,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;
 
 {
        int index = -1;
 
@@ -3556,8 +3564,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);
                * 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,
 }
 
 static void get_texture_coords(DisplaceModifierData *dmd, Object *ob,
@@ -3583,12 +3593,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 *done = MEM_callocN(sizeof(*done) * numVerts,
                                        "get_texture_coords done");
                        int numFaces = dm->getNumFaces(dm);
+                       char uvname[32];
                        MTFace *tf;
 
                        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) {
 
                        /* verts are given the UV from the first face that uses them */
                        for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
@@ -3819,7 +3828,7 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target)
        tumd->aspecty = umd->aspecty;
 }
 
        tumd->aspecty = umd->aspecty;
 }
 
-CustomDataMask uvprojectModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = 0;
 
 {
        CustomDataMask dataMask = 0;
 
@@ -3884,6 +3893,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
        Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
        int num_projectors = 0;
        float aspect;
        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;
        
        if(umd->aspecty != 0) aspect = umd->aspectx / umd->aspecty;
        else aspect = 1.0f;
@@ -3898,12 +3908,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
        if(!dm->getFaceDataArray(dm, CD_MTFACE)) return dm;
 
        /* make sure we're using an existing layer */
        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,
 
        /* 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);
 
 
        numVerts = dm->getNumVerts(dm);
 
@@ -4045,11 +4054,11 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
                                /* find the projector which the face points at most directly
                                * (projector normal with largest dot product is best)
                                */
                                /* find the projector which the face points at most directly
                                * (projector normal with largest dot product is best)
                                */
-                               best_dot = MTC_dot3Float(projectors[0].normal, face_no);
+                               best_dot = Inpf(projectors[0].normal, face_no);
                                best_projector = &projectors[0];
 
                                for(j = 1; j < num_projectors; ++j) {
                                best_projector = &projectors[0];
 
                                for(j = 1; j < num_projectors; ++j) {
-                                       float tmp_dot = MTC_dot3Float(projectors[j].normal,
+                                       float tmp_dot = Inpf(projectors[j].normal,
                                                        face_no);
                                        if(tmp_dot > best_dot) {
                                                best_dot = tmp_dot;
                                                        face_no);
                                        if(tmp_dot > best_dot) {
                                                best_dot = tmp_dot;
@@ -4272,7 +4281,7 @@ static void smoothModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tsmd->defgrp_name, smd->defgrp_name, 32);
 }
 
        strncpy(tsmd->defgrp_name, smd->defgrp_name, 32);
 }
 
-int smoothModifier_isDisabled(ModifierData *md)
+static int smoothModifier_isDisabled(ModifierData *md)
 {
        SmoothModifierData *smd = (SmoothModifierData*) md;
        short flag;
 {
        SmoothModifierData *smd = (SmoothModifierData*) md;
        short flag;
@@ -4285,7 +4294,7 @@ int smoothModifier_isDisabled(ModifierData *md)
        return 0;
 }
 
        return 0;
 }
 
-CustomDataMask smoothModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        SmoothModifierData *smd = (SmoothModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        SmoothModifierData *smd = (SmoothModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -4502,7 +4511,7 @@ static void castModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32);
 }
 
        strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32);
 }
 
-int castModifier_isDisabled(ModifierData *md)
+static int castModifier_isDisabled(ModifierData *md)
 {
        CastModifierData *cmd = (CastModifierData*) md;
        short flag;
 {
        CastModifierData *cmd = (CastModifierData*) md;
        short flag;
@@ -4514,7 +4523,7 @@ int castModifier_isDisabled(ModifierData *md)
        return 0;
 }
 
        return 0;
 }
 
-CustomDataMask castModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CastModifierData *cmd = (CastModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        CastModifierData *cmd = (CastModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -5067,7 +5076,7 @@ static void waveModifier_initData(ModifierData *md)
        wmd->map_object = NULL;
        wmd->height= 0.5f;
        wmd->width= 1.5f;
        wmd->map_object = NULL;
        wmd->height= 0.5f;
        wmd->width= 1.5f;
-       wmd->speed= 0.5f;
+       wmd->speed= 0.25f;
        wmd->narrow= 1.5f;
        wmd->lifetime= 0.0f;
        wmd->damp= 10.0f;
        wmd->narrow= 1.5f;
        wmd->lifetime= 0.0f;
        wmd->damp= 10.0f;
@@ -5145,7 +5154,7 @@ static void waveModifier_updateDepgraph(
        }
 }
 
        }
 }
 
-CustomDataMask waveModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        WaveModifierData *wmd = (WaveModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        WaveModifierData *wmd = (WaveModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -5185,12 +5194,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 *done = MEM_callocN(sizeof(*done) * numVerts,
                                        "get_texture_coords done");
                        int numFaces = dm->getNumFaces(dm);
+                       char uvname[32];
                        MTFace *tf;
 
                        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) {
 
                        /* verts are given the UV from the first face that uses them */
                        for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
@@ -5482,7 +5490,7 @@ static void armatureModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tamd->defgrp_name, amd->defgrp_name, 32);
 }
 
        strncpy(tamd->defgrp_name, amd->defgrp_name, 32);
 }
 
-CustomDataMask armatureModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = 0;
 
 {
        CustomDataMask dataMask = 0;
 
@@ -5594,9 +5602,10 @@ static void hookModifier_copyData(ModifierData *md, ModifierData *target)
        thmd->indexar = MEM_dupallocN(hmd->indexar);
        memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv));
        strncpy(thmd->name, hmd->name, 32);
        thmd->indexar = MEM_dupallocN(hmd->indexar);
        memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv));
        strncpy(thmd->name, hmd->name, 32);
+       strncpy(thmd->subtarget, hmd->subtarget, 32);
 }
 
 }
 
-CustomDataMask hookModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        HookModifierData *hmd = (HookModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        HookModifierData *hmd = (HookModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -5638,9 +5647,11 @@ static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest, Sce
 
        if (hmd->object) {
                DagNode *curNode = dag_get_node(forest, hmd->object);
 
        if (hmd->object) {
                DagNode *curNode = dag_get_node(forest, hmd->object);
-
-               dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA,
-                       "Hook Modifier");
+               
+               if (hmd->subtarget[0])
+                       dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA|DAG_RL_DATA_DATA, "Hook Modifier");
+               else
+                       dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "Hook Modifier");
        }
 }
 
        }
 }
 
@@ -5649,12 +5660,22 @@ static void hookModifier_deformVerts(
         float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        HookModifierData *hmd = (HookModifierData*) md;
         float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        HookModifierData *hmd = (HookModifierData*) md;
-       float vec[3], mat[4][4];
+       bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
+       float vec[3], mat[4][4], dmat[4][4];
        int i;
        DerivedMesh *dm = derivedData;
        int i;
        DerivedMesh *dm = derivedData;
-
+       
+       /* get world-space matrix of target, corrected for the space the verts are in */
+       if (hmd->subtarget[0] && pchan) {
+               /* bone target if there's a matching pose-channel */
+               Mat4MulMat4(dmat, pchan->pose_mat, hmd->object->obmat);
+       }
+       else {
+               /* just object target */
+               Mat4CpyMat4(dmat, hmd->object->obmat);
+       }
        Mat4Invert(ob->imat, ob->obmat);
        Mat4Invert(ob->imat, ob->obmat);
-       Mat4MulSerie(mat, ob->imat, hmd->object->obmat, hmd->parentinv,
+       Mat4MulSerie(mat, ob->imat, dmat, hmd->parentinv,
                     NULL, NULL, NULL, NULL, NULL);
 
        /* vertex indices? */
                     NULL, NULL, NULL, NULL, NULL);
 
        /* vertex indices? */
@@ -5711,7 +5732,8 @@ static void hookModifier_deformVerts(
                                }
                        }
                }
                                }
                        }
                }
-       } else {        /* vertex group hook */
+       } 
+       else if(hmd->name[0]) { /* vertex group hook */
                bDeformGroup *curdef;
                Mesh *me = ob->data;
                int index = 0;
                bDeformGroup *curdef;
                Mesh *me = ob->data;
                int index = 0;
@@ -5786,6 +5808,79 @@ static int softbodyModifier_dependsOnTime(ModifierData *md)
        return 1;
 }
 
        return 1;
 }
 
+/* Smoke */
+
+static void smokeModifier_initData(ModifierData *md) 
+{
+       SmokeModifierData *smd = (SmokeModifierData*) md;
+       
+       smd->domain = NULL;
+       smd->flow = NULL;
+       smd->coll = NULL;
+       smd->type = 0;
+       smd->time = -1;
+}
+
+static void smokeModifier_freeData(ModifierData *md)
+{
+       SmokeModifierData *smd = (SmokeModifierData*) md;
+       
+       smokeModifier_free (smd);
+}
+
+static void smokeModifier_deformVerts(
+                                        ModifierData *md, Object *ob, DerivedMesh *derivedData,
+      float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
+{
+       SmokeModifierData *smd = (SmokeModifierData*) md;
+       DerivedMesh *dm = NULL;
+
+       if(derivedData) dm = derivedData;
+       else if(ob->type == OB_MESH) dm = CDDM_from_mesh(ob->data, ob);
+       else return;
+
+       CDDM_apply_vert_coords(dm, vertexCos);
+       CDDM_calc_normals(dm);
+
+       smokeModifier_do(smd, md->scene, ob, dm, useRenderParams, isFinalCalc);
+
+       if(dm != derivedData) dm->release(dm);
+}
+
+static int smokeModifier_dependsOnTime(ModifierData *md)
+{
+       return 1;
+}
+
+static void smokeModifier_updateDepgraph(
+                                        ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
+      DagNode *obNode)
+{
+       /*SmokeModifierData *smd = (SmokeModifierData *) md;
+       if(smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
+       {
+               if(smd->domain->fluid_group)
+               {
+                       GroupObject *go = NULL;
+                       
+                       for(go = smd->domain->fluid_group->gobject.first; go; go = go->next) 
+                       {
+                               if(go->ob)
+                               {
+                                       SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(go->ob, eModifierType_Smoke);
+                                       
+                                       // check for initialized smoke object
+                                       if(smd2 && (smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow)
+                                       {
+                                               DagNode *curNode = dag_get_node(forest, go->ob);
+                                               dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Smoke Flow");
+                                       }
+                               }
+                       }
+               }
+       }
+       */
+}
 
 /* Cloth */
 
 
 /* Cloth */
 
@@ -5795,7 +5890,7 @@ static void clothModifier_initData(ModifierData *md)
        
        clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
        clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
        
        clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
        clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
-       clmd->point_cache = BKE_ptcache_add();
+       clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
        
        /* check for alloc failing */
        if(!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
        
        /* check for alloc failing */
        if(!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
@@ -5855,7 +5950,7 @@ static void clothModifier_updateDepgraph(
        }
 }
 
        }
 }
 
-CustomDataMask clothModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = 0;
 
 {
        CustomDataMask dataMask = 0;
 
@@ -5874,12 +5969,15 @@ static void clothModifier_copyData(ModifierData *md, ModifierData *target)
                MEM_freeN(tclmd->sim_parms);
        if(tclmd->coll_parms)
                MEM_freeN(tclmd->coll_parms);
                MEM_freeN(tclmd->sim_parms);
        if(tclmd->coll_parms)
                MEM_freeN(tclmd->coll_parms);
-       if(tclmd->point_cache)
-               BKE_ptcache_free(tclmd->point_cache);
+       
+       BKE_ptcache_free_list(&tclmd->ptcaches);
+       tclmd->point_cache = NULL;
        
        tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
        
        tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
+       if(clmd->sim_parms->effector_weights)
+               tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
        tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
        tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
-       tclmd->point_cache = BKE_ptcache_copy(clmd->point_cache);
+       tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches);
        tclmd->clothObject = NULL;
 }
 
        tclmd->clothObject = NULL;
 }
 
@@ -5899,12 +5997,16 @@ static void clothModifier_freeData(ModifierData *md)
                
                cloth_free_modifier_extern (clmd);
                
                
                cloth_free_modifier_extern (clmd);
                
-               if(clmd->sim_parms)
+               if(clmd->sim_parms) {
+                       if(clmd->sim_parms->effector_weights)
+                               MEM_freeN(clmd->sim_parms->effector_weights);
                        MEM_freeN(clmd->sim_parms);
                        MEM_freeN(clmd->sim_parms);
+               }
                if(clmd->coll_parms)
                        MEM_freeN(clmd->coll_parms);    
                if(clmd->coll_parms)
                        MEM_freeN(clmd->coll_parms);    
-               if(clmd->point_cache)
-                       BKE_ptcache_free(clmd->point_cache);
+               
+               BKE_ptcache_free_list(&clmd->ptcaches);
+               clmd->point_cache = NULL;
        }
 }
 
        }
 }
 
@@ -6114,7 +6216,13 @@ static void surfaceModifier_freeData(ModifierData *md)
 
                if(surmd->dm)
                        surmd->dm->release(surmd->dm);
 
                if(surmd->dm)
                        surmd->dm->release(surmd->dm);
+
+               if(surmd->x)
+                       MEM_freeN(surmd->x);
                
                
+               if(surmd->v)
+                       MEM_freeN(surmd->v);
+
                surmd->bvhtree = NULL;
                surmd->dm = NULL;
        }
                surmd->bvhtree = NULL;
                surmd->dm = NULL;
        }
@@ -6127,7 +6235,7 @@ static int surfaceModifier_dependsOnTime(ModifierData *md)
 
 static void surfaceModifier_deformVerts(
                                          ModifierData *md, Object *ob, DerivedMesh *derivedData,
 
 static void surfaceModifier_deformVerts(
                                          ModifierData *md, Object *ob, DerivedMesh *derivedData,
-       float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
+           float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        SurfaceModifierData *surmd = (SurfaceModifierData*) md;
        unsigned int numverts = 0, i = 0;
 {
        SurfaceModifierData *surmd = (SurfaceModifierData*) md;
        unsigned int numverts = 0, i = 0;
@@ -6147,21 +6255,57 @@ static void surfaceModifier_deformVerts(
        
        if(surmd->dm)
        {
        
        if(surmd->dm)
        {
+               int init = 0;
+               float *vec;
+               MVert *x, *v;
+
                CDDM_apply_vert_coords(surmd->dm, vertexCos);
                CDDM_calc_normals(surmd->dm);
                
                numverts = surmd->dm->getNumVerts ( 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(numverts != surmd->numverts || surmd->x == NULL || surmd->v == NULL || md->scene->r.cfra != surmd->cfra+1) {
+                       if(surmd->x) {
+                               MEM_freeN(surmd->x);
+                               surmd->x = NULL;
+                       }
+                       if(surmd->v) {
+                               MEM_freeN(surmd->v);
+                               surmd->v = NULL;
+                       }
+
+                       surmd->x = MEM_callocN(numverts * sizeof(MVert), "MVert");
+                       surmd->v = MEM_callocN(numverts * sizeof(MVert), "MVert");
+
+                       surmd->numverts = numverts;
+
+                       init = 1;
+               }
+
+               /* convert to global coordinates and calculate velocity */
+               for(i = 0, x = surmd->x, v = surmd->v; i<numverts; i++, x++, v++) {
+                       vec = CDDM_get_vert(surmd->dm, i)->co;
+                       Mat4MulVecfl(ob->obmat, vec);
+
+                       if(init)
+                               v->co[0] = v->co[1] = v->co[2] = 0.0f;
+                       else
+                               VecSubf(v->co, vec, x->co);
+                       
+                       VecCopyf(x->co, vec);
+               }
+
+               surmd->cfra = md->scene->r.cfra;
 
                if(surmd->bvhtree)
                        free_bvhtree_from_mesh(surmd->bvhtree);
                else
                        surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
 
 
                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);
+               if(surmd->dm->getNumFaces(surmd->dm))
+                       bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
+               else
+                       bvhtree_from_mesh_edges(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
        }
 }
 
        }
 }
 
@@ -6214,7 +6358,7 @@ static DerivedMesh *booleanModifier_applyModifier(
 {
        // XXX doesn't handle derived data
        BooleanModifierData *bmd = (BooleanModifierData*) md;
 {
        // XXX doesn't handle derived data
        BooleanModifierData *bmd = (BooleanModifierData*) md;
-       DerivedMesh *dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_BAREMESH);
+       DerivedMesh *dm = bmd->object->derivedFinal;
 
        /* we do a quick sanity check */
        if(dm && (derivedData->getNumFaces(derivedData) > 3)
 
        /* we do a quick sanity check */
        if(dm && (derivedData->getNumFaces(derivedData) > 3)
@@ -6239,7 +6383,7 @@ static DerivedMesh *booleanModifier_applyModifier(
        return derivedData;
 }
 
        return derivedData;
 }
 
-CustomDataMask booleanModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
 
 {
        CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
 
@@ -6287,12 +6431,30 @@ static void particleSystemModifier_copyData(ModifierData *md, ModifierData *targ
        tpsmd->psys = psmd->psys;
 }
 
        tpsmd->psys = psmd->psys;
 }
 
-CustomDataMask particleSystemModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
 {
        ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
-       CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
+       CustomDataMask dataMask = 0;
+       Material *ma;
+       MTex *mtex;
        int i;
 
        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]){
        /* ask for vertexgroups if we need them */
        for(i=0; i<PSYS_TOT_VG; i++){
                if(psmd->psys->vgroup[i]){
@@ -6371,6 +6533,7 @@ static void particleSystemModifier_deformVerts(
                  }
 
                  if(psys){
                  }
 
                  if(psys){
+                         psmd->flag &= ~eParticleSystemFlag_psys_updated;
                          particle_system_update(md->scene, ob, psys);
                          psmd->flag |= eParticleSystemFlag_psys_updated;
                          psmd->flag &= ~eParticleSystemFlag_DM_changed;
                          particle_system_update(md->scene, ob, psys);
                          psmd->flag |= eParticleSystemFlag_psys_updated;
                          psmd->flag &= ~eParticleSystemFlag_DM_changed;
@@ -6402,6 +6565,8 @@ static void particleInstanceModifier_initData(ModifierData *md)
        pimd->flag = eParticleInstanceFlag_Parents|eParticleInstanceFlag_Unborn|
                        eParticleInstanceFlag_Alive|eParticleInstanceFlag_Dead;
        pimd->psys = 1;
        pimd->flag = eParticleInstanceFlag_Parents|eParticleInstanceFlag_Unborn|
                        eParticleInstanceFlag_Alive|eParticleInstanceFlag_Dead;
        pimd->psys = 1;
+       pimd->position = 1.0f;
+       pimd->axis = 2;
 
 }
 static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *target)
 
 }
 static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *target)
@@ -6412,6 +6577,8 @@ static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *ta
        tpimd->ob = pimd->ob;
        tpimd->psys = pimd->psys;
        tpimd->flag = pimd->flag;
        tpimd->ob = pimd->ob;
        tpimd->psys = pimd->psys;
        tpimd->flag = pimd->flag;
+       tpimd->position = pimd->position;
+       tpimd->random_position = pimd->random_position;
 }
 
 static int particleInstanceModifier_dependsOnTime(ModifierData *md) 
 }
 
 static int particleInstanceModifier_dependsOnTime(ModifierData *md) 
@@ -6446,13 +6613,15 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
 {
        DerivedMesh *dm = derivedData, *result;
        ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
 {
        DerivedMesh *dm = derivedData, *result;
        ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
+       ParticleSimulationData sim;
        ParticleSystem * psys=0;
        ParticleData *pa=0, *pars=0;
        MFace *mface, *orig_mface;
        MVert *mvert, *orig_mvert;
        int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0;
        ParticleSystem * psys=0;
        ParticleData *pa=0, *pars=0;
        MFace *mface, *orig_mface;
        MVert *mvert, *orig_mvert;
        int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0;
-       short track=ob->trackflag%3, trackneg;
+       short track=ob->trackflag%3, trackneg, axis = pimd->axis;
        float max_co=0.0, min_co=0.0, temp_co[3], cross[3];
        float max_co=0.0, min_co=0.0, temp_co[3], cross[3];
+       float *size=NULL;
 
        trackneg=((ob->trackflag>2)?1:0);
 
 
        trackneg=((ob->trackflag>2)?1:0);
 
@@ -6479,6 +6648,30 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        if(totpart==0)
                return derivedData;
 
        if(totpart==0)
                return derivedData;
 
+       sim.scene = md->scene;
+       sim.ob = pimd->ob;
+       sim.psys = psys;
+       sim.psmd = psys_get_modifier(pimd->ob, psys);
+
+       if(pimd->flag & eParticleInstanceFlag_UseSize) {
+               int p;
+               float *si;
+               si = size = MEM_callocN(totpart * sizeof(float), "particle size array");
+
+               if(pimd->flag & eParticleInstanceFlag_Parents) {
+                       for(p=0, pa= psys->particles; p<psys->totpart; p++, pa++, si++)
+                               *si = pa->size;
+               }
+
+               if(pimd->flag & eParticleInstanceFlag_Children) {
+                       ChildParticle *cpa = psys->child;
+
+                       for(p=0; p<psys->totchild; p++, cpa++, si++) {
+                               *si = psys_get_child_size(psys, cpa, 0.0f, NULL);
+                       }
+               }
+       }
+
        pars=psys->particles;
 
        totvert=dm->getNumVerts(dm);
        pars=psys->particles;
 
        totvert=dm->getNumVerts(dm);
@@ -6487,9 +6680,9 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        maxvert=totvert*totpart;
        maxface=totface*totpart;
 
        maxvert=totvert*totpart;
        maxface=totface*totpart;
 
-       psys->lattice=psys_get_lattice(md->scene, ob, psys);
+       psys->lattice=psys_get_lattice(&sim);
 
 
-       if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)){
+       if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED){
 
                float min_r[3], max_r[3];
                INIT_MINMAX(min_r, max_r);
 
                float min_r[3], max_r[3];
                INIT_MINMAX(min_r, max_r);
@@ -6514,40 +6707,57 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
 
                /*change orientation based on object trackflag*/
                VECCOPY(temp_co,mv->co);
 
                /*change orientation based on object trackflag*/
                VECCOPY(temp_co,mv->co);
-               mv->co[0]=temp_co[track];
-               mv->co[1]=temp_co[(track+1)%3];
-               mv->co[2]=temp_co[(track+2)%3];
+               mv->co[axis]=temp_co[track];
+               mv->co[(axis+1)%3]=temp_co[(track+1)%3];
+               mv->co[(axis+2)%3]=temp_co[(track+2)%3];
+
+               if((psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && pimd->flag & eParticleInstanceFlag_Path){
+                       float ran = 0.0f;
+                       if(pimd->random_position != 0.0f) {
+                               BLI_srandom(psys->seed + (i/totvert)%totpart);
+                               ran = pimd->random_position * BLI_frand();
+                       }
+
+                       if(pimd->flag & eParticleInstanceFlag_KeepShape) {
+                               state.time = pimd->position * (1.0f - ran);
+                       }
+                       else {
+                               state.time=(mv->co[axis]-min_co)/(max_co-min_co) * pimd->position * (1.0f - ran);
 
 
-               if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED) && pimd->flag & eParticleInstanceFlag_Path){
-                       state.time=(mv->co[0]-min_co)/(max_co-min_co);
-                       if(trackneg)
-                               state.time=1.0f-state.time;
-                       psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1);
+                               if(trackneg)
+                                       state.time=1.0f-state.time;
+                               
+                               mv->co[axis] = 0.0;
+                       }
 
 
-                       mv->co[0] = 0.0;
+                       psys_get_particle_on_path(&sim, first_particle + i/totvert, &state,1);
 
                        Normalize(state.vel);
                        
 
                        Normalize(state.vel);
                        
-                       if(state.vel[0] < -0.9999 || state.vel[0] > 0.9999) {
-                               state.rot[0] = 1.0;
+                       /* TODO: incremental rotations somehow */
+                       if(state.vel[axis] < -0.9999 || state.vel[axis] > 0.9999) {
+                               state.rot[0] = 1;
                                state.rot[1] = state.rot[2] = state.rot[3] = 0.0f;
                        }
                        else {
                                state.rot[1] = state.rot[2] = state.rot[3] = 0.0f;
                        }
                        else {
-                               /* a cross product of state.vel and a unit vector in x-direction */
-                               cross[0] = 0.0f;
-                               cross[1] = -state.vel[2];
-                               cross[2] = state.vel[1];
+                               float temp[3] = {0.0f,0.0f,0.0f};
+                               temp[axis] = 1.0f;
 
 
-                               /* state.vel[0] is the only component surviving from a dot product with a vector in x-direction*/
-                               VecRotToQuat(cross,saacos(state.vel[0]),state.rot);
+                               Crossf(cross, temp, state.vel);
+
+                               /* state.vel[axis] is the only component surviving from a dot product with the axis */
+                               VecRotToQuat(cross,saacos(state.vel[axis]),state.rot);
                        }
                        }
+
                }
                else{
                        state.time=-1.0;
                }
                else{
                        state.time=-1.0;
-                       psys_get_particle_state(md->scene, pimd->ob, psys, i/totvert, &state,1);
+                       psys_get_particle_state(&sim, first_particle + i/totvert, &state,1);
                }       
 
                QuatMulVecf(state.rot,mv->co);
                }       
 
                QuatMulVecf(state.rot,mv->co);
+               if(pimd->flag & eParticleInstanceFlag_UseSize)
+                       VecMulf(mv->co, size[i/totvert]);
                VECADD(mv->co,mv->co,state.co);
        }
 
                VECADD(mv->co,mv->co,state.co);
        }
 
@@ -6600,6 +6810,9 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
                psys->lattice= NULL;
        }
 
                psys->lattice= NULL;
        }
 
+       if(size)
+               MEM_freeN(size);
+
        return result;
 }
 static DerivedMesh *particleInstanceModifier_applyModifierEM(
        return result;
 }
 static DerivedMesh *particleInstanceModifier_applyModifierEM(
@@ -6637,7 +6850,7 @@ static int explodeModifier_dependsOnTime(ModifierData *md)
 {
        return 1;
 }
 {
        return 1;
 }
-CustomDataMask explodeModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        ExplodeModifierData *emd= (ExplodeModifierData*) md;
        CustomDataMask dataMask = 0;
 {
        ExplodeModifierData *emd= (ExplodeModifierData*) md;
        CustomDataMask dataMask = 0;
@@ -7221,6 +7434,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        DerivedMesh *explode, *dm=to_explode;
        MFace *mf=0;
        ParticleSettings *part=psmd->psys->part;
        DerivedMesh *explode, *dm=to_explode;
        MFace *mf=0;
        ParticleSettings *part=psmd->psys->part;
+       ParticleSimulationData sim = {scene, ob, psmd->psys, psmd};
        ParticleData *pa=NULL, *pars=psmd->psys->particles;
        ParticleKey state;
        EdgeHash *vertpahash;
        ParticleData *pa=NULL, *pars=psmd->psys->particles;
        ParticleKey state;
        EdgeHash *vertpahash;
@@ -7236,12 +7450,12 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        totvert= dm->getNumVerts(dm);
        totpart= psmd->psys->totpart;
 
        totvert= dm->getNumVerts(dm);
        totpart= psmd->psys->totpart;
 
-       timestep= psys_get_timestep(part);
+       timestep= psys_get_timestep(&sim);
 
 
-       if(part->flag & PART_GLOB_TIME)
+       //if(part->flag & PART_GLOB_TIME)
                cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
                cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
-       else
-               cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0);
+       //else
+       //      cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0);
 
        /* hash table for vertice <-> particle relations */
        vertpahash= BLI_edgehash_new();
 
        /* hash table for vertice <-> particle relations */
        vertpahash= BLI_edgehash_new();
@@ -7279,7 +7493,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        /* getting back to object space */
        Mat4Invert(imat,ob->obmat);
 
        /* getting back to object space */
        Mat4Invert(imat,ob->obmat);
 
-       psmd->psys->lattice = psys_get_lattice(scene, ob, psmd->psys);
+       psmd->psys->lattice = psys_get_lattice(&sim);
 
        /* duplicate & displace vertices */
        ehi= BLI_edgehashIterator_new(vertpahash);
 
        /* duplicate & displace vertices */
        ehi= BLI_edgehashIterator_new(vertpahash);
@@ -7307,7 +7521,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
                        Mat4MulVecfl(ob->obmat,loc0);
 
                        state.time=cfra;
                        Mat4MulVecfl(ob->obmat,loc0);
 
                        state.time=cfra;
-                       psys_get_particle_state(scene, ob, psmd->psys, i, &state,1);
+                       psys_get_particle_state(&sim, i, &state, 1);
 
                        vertco=CDDM_get_vert(explode,v)->co;
                        
 
                        vertco=CDDM_get_vert(explode,v)->co;
                        
@@ -7396,7 +7610,7 @@ static DerivedMesh * explodeModifier_applyModifier(
 {
        DerivedMesh *dm = derivedData;
        ExplodeModifierData *emd= (ExplodeModifierData*) md;
 {
        DerivedMesh *dm = derivedData;
        ExplodeModifierData *emd= (ExplodeModifierData*) md;
-       ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md);;
+       ParticleSystemModifierData *psmd=explodeModifier_findPrecedingParticlesystem(ob,md);
 
        if(psmd){
                ParticleSystem * psys=psmd->psys;
 
        if(psmd){
                ParticleSystem * psys=psmd->psys;
@@ -7551,7 +7765,7 @@ static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target)
        tmmd->object = mmd->object;
 }
 
        tmmd->object = mmd->object;
 }
 
-CustomDataMask meshdeformModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
 {      
        MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
        CustomDataMask dataMask = 0;
 {      
        MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -7815,10 +8029,12 @@ static void meshdeformModifier_deformVerts(
 {
        DerivedMesh *dm;
 
 {
        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 */
        
 
        modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
        
@@ -7874,14 +8090,13 @@ static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob,
                                                   int useRenderParams, int isFinalCalc)
 {
        MultiresModifierData *mmd = (MultiresModifierData*)md;
                                                   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;
 
        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);
+       final = multires_dm_create_from_derived(mmd, 0, dm, ob, useRenderParams, isFinalCalc);
        if(mmd->undo_signal && mmd->undo_verts && mmd->undo_verts_tot == final->getNumVerts(final)) {
                int i;
                MVert *dst = CDDM_get_verts(final);
        if(mmd->undo_signal && mmd->undo_verts && mmd->undo_verts_tot == final->getNumVerts(final)) {
                int i;
                MVert *dst = CDDM_get_verts(final);
@@ -7930,7 +8145,7 @@ static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
        tsmd->subsurfLevels = smd->subsurfLevels;
 }
 
        tsmd->subsurfLevels = smd->subsurfLevels;
 }
 
-CustomDataMask shrinkwrapModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -7964,7 +8179,7 @@ static void shrinkwrapModifier_foreachObjectLink(ModifierData *md, Object *ob, O
 static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm = NULL;
 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(md);
+       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)
 
        /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
        if(dataMask)
@@ -7990,7 +8205,7 @@ static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, Derived
 static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm = NULL;
 static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm = NULL;
-       CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(md);
+       CustomDataMask dataMask = shrinkwrapModifier_requiredDataMask(ob, md);
 
        if(dataMask)
        {
 
        if(dataMask)
        {
@@ -8049,7 +8264,7 @@ static void simpledeformModifier_copyData(ModifierData *md, ModifierData *target
        memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit));
 }
 
        memcpy(tsmd->limit, smd->limit, sizeof(tsmd->limit));
 }
 
-static CustomDataMask simpledeformModifier_requiredDataMask(ModifierData *md)
+static CustomDataMask simpledeformModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
        CustomDataMask dataMask = 0;
 {
        SimpleDeformModifierData *smd = (SimpleDeformModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -8078,7 +8293,7 @@ static void simpledeformModifier_updateDepgraph(ModifierData *md, DagForest *for
 static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
 {
        DerivedMesh *dm = NULL;
 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(md);
+       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)
 
        /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
        if(dataMask)
@@ -8105,7 +8320,7 @@ static void simpledeformModifier_deformVerts(ModifierData *md, Object *ob, Deriv
 static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm = NULL;
 static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
 {
        DerivedMesh *dm = NULL;
-       CustomDataMask dataMask = simpledeformModifier_requiredDataMask(md);
+       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)
 
        /* We implement requiredDataMask but thats not really usefull since mesh_calc_modifiers pass a NULL derivedData or without the modified vertexs applied */
        if(dataMask)
@@ -8128,6 +8343,52 @@ static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, Edi
                dm->release(dm);
 }
 
                dm->release(dm);
 }
 
+/* Shape Key */
+
+static void shapekeyModifier_deformVerts(
+                                        ModifierData *md, Object *ob, DerivedMesh *derivedData,
+      float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
+{
+       KeyBlock *kb= ob_get_keyblock(ob);
+       float (*deformedVerts)[3];
+
+       if(kb && kb->totelem == numVerts) {
+               deformedVerts= (float(*)[3])do_ob_key(md->scene, ob);
+               if(deformedVerts) {
+                       memcpy(vertexCos, deformedVerts, sizeof(float)*3*numVerts);
+                       MEM_freeN(deformedVerts);
+               }
+       }
+}
+
+static void shapekeyModifier_deformVertsEM(
+                                          ModifierData *md, Object *ob, EditMesh *editData,
+       DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+       Key *key= ob_get_key(ob);
+
+       if(key && key->type == KEY_RELATIVE)
+               shapekeyModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
+}
+
+static void shapekeyModifier_deformMatricesEM(
+                                             ModifierData *md, Object *ob, EditMesh *editData,
+          DerivedMesh *derivedData, float (*vertexCos)[3],
+                                            float (*defMats)[3][3], int numVerts)
+{
+       Key *key= ob_get_key(ob);
+       KeyBlock *kb= ob_get_keyblock(ob);
+       float scale[3][3];
+       int a;
+
+       if(kb && kb->totelem==numVerts && kb!=key->refkey) {
+               Mat3Scale(scale, kb->curval);
+
+               for(a=0; a<numVerts; a++)
+                       Mat3CpyMat3(defMats[a], scale);
+       }
+}
+
 /***/
 
 static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
 /***/
 
 static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
@@ -8307,6 +8568,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->initData = smoothModifier_initData;
                mti->copyData = smoothModifier_copyData;
                mti->requiredDataMask = smoothModifier_requiredDataMask;
                mti->initData = smoothModifier_initData;
                mti->copyData = smoothModifier_copyData;
                mti->requiredDataMask = smoothModifier_requiredDataMask;
+               mti->isDisabled = smoothModifier_isDisabled;
                mti->deformVerts = smoothModifier_deformVerts;
                mti->deformVertsEM = smoothModifier_deformVertsEM;
 
                mti->deformVerts = smoothModifier_deformVerts;
                mti->deformVertsEM = smoothModifier_deformVertsEM;
 
@@ -8317,6 +8579,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->initData = castModifier_initData;
                mti->copyData = castModifier_copyData;
                mti->requiredDataMask = castModifier_requiredDataMask;
                mti->initData = castModifier_initData;
                mti->copyData = castModifier_copyData;
                mti->requiredDataMask = castModifier_requiredDataMask;
+               mti->isDisabled = castModifier_isDisabled;
                mti->foreachObjectLink = castModifier_foreachObjectLink;
                mti->updateDepgraph = castModifier_updateDepgraph;
                mti->deformVerts = castModifier_deformVerts;
                mti->foreachObjectLink = castModifier_foreachObjectLink;
                mti->updateDepgraph = castModifier_updateDepgraph;
                mti->deformVerts = castModifier_deformVerts;
@@ -8367,15 +8630,28 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti = INIT_TYPE(Softbody);
                mti->type = eModifierTypeType_OnlyDeform;
                mti->flags = eModifierTypeFlag_AcceptsCVs
                mti = INIT_TYPE(Softbody);
                mti->type = eModifierTypeType_OnlyDeform;
                mti->flags = eModifierTypeFlag_AcceptsCVs
-                               | eModifierTypeFlag_RequiresOriginalData;
+                               | eModifierTypeFlag_RequiresOriginalData
+                               | eModifierTypeFlag_Single;
                mti->deformVerts = softbodyModifier_deformVerts;
                mti->dependsOnTime = softbodyModifier_dependsOnTime;
                mti->deformVerts = softbodyModifier_deformVerts;
                mti->dependsOnTime = softbodyModifier_dependsOnTime;
+               
+               mti = INIT_TYPE(Smoke);
+               mti->type = eModifierTypeType_OnlyDeform;
+               mti->initData = smokeModifier_initData;
+               mti->freeData = smokeModifier_freeData; 
+               mti->flags = eModifierTypeFlag_AcceptsMesh
+                               | eModifierTypeFlag_UsesPointCache
+                               | eModifierTypeFlag_Single;
+               mti->deformVerts = smokeModifier_deformVerts;
+               mti->dependsOnTime = smokeModifier_dependsOnTime;
+               mti->updateDepgraph = smokeModifier_updateDepgraph;
        
                mti = INIT_TYPE(Cloth);
                mti->type = eModifierTypeType_Nonconstructive;
                mti->initData = clothModifier_initData;
                mti->flags = eModifierTypeFlag_AcceptsMesh
        
                mti = INIT_TYPE(Cloth);
                mti->type = eModifierTypeType_Nonconstructive;
                mti->initData = clothModifier_initData;
                mti->flags = eModifierTypeFlag_AcceptsMesh
-                               | eModifierTypeFlag_UsesPointCache;
+                               | eModifierTypeFlag_UsesPointCache
+                               | eModifierTypeFlag_Single;
                mti->dependsOnTime = clothModifier_dependsOnTime;
                mti->freeData = clothModifier_freeData; 
                mti->requiredDataMask = clothModifier_requiredDataMask;
                mti->dependsOnTime = clothModifier_dependsOnTime;
                mti->freeData = clothModifier_freeData; 
                mti->requiredDataMask = clothModifier_requiredDataMask;
@@ -8386,7 +8662,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti = INIT_TYPE(Collision);
                mti->type = eModifierTypeType_OnlyDeform;
                mti->initData = collisionModifier_initData;
                mti = INIT_TYPE(Collision);
                mti->type = eModifierTypeType_OnlyDeform;
                mti->initData = collisionModifier_initData;
-               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               mti->flags = eModifierTypeFlag_AcceptsMesh
+                               | eModifierTypeFlag_Single;
                mti->dependsOnTime = collisionModifier_dependsOnTime;
                mti->freeData = collisionModifier_freeData; 
                mti->deformVerts = collisionModifier_deformVerts;
                mti->dependsOnTime = collisionModifier_dependsOnTime;
                mti->freeData = collisionModifier_freeData; 
                mti->deformVerts = collisionModifier_deformVerts;
@@ -8395,7 +8672,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti = INIT_TYPE(Surface);
                mti->type = eModifierTypeType_OnlyDeform;
                mti->initData = surfaceModifier_initData;
                mti = INIT_TYPE(Surface);
                mti->type = eModifierTypeType_OnlyDeform;
                mti->initData = surfaceModifier_initData;
-               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               mti->flags = eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_NoUserAdd;
                mti->dependsOnTime = surfaceModifier_dependsOnTime;
                mti->freeData = surfaceModifier_freeData; 
                mti->deformVerts = surfaceModifier_deformVerts;
                mti->dependsOnTime = surfaceModifier_dependsOnTime;
                mti->freeData = surfaceModifier_freeData; 
                mti->deformVerts = surfaceModifier_deformVerts;
@@ -8469,7 +8746,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                
                mti = INIT_TYPE(Fluidsim);
                mti->type = eModifierTypeType_Nonconstructive
                
                mti = INIT_TYPE(Fluidsim);
                mti->type = eModifierTypeType_Nonconstructive
-                               | eModifierTypeFlag_RequiresOriginalData;
+                               | eModifierTypeFlag_RequiresOriginalData
+                               | eModifierTypeFlag_Single;
                mti->flags = eModifierTypeFlag_AcceptsMesh;
                mti->initData = fluidsimModifier_initData;
                mti->freeData = fluidsimModifier_freeData;
                mti->flags = eModifierTypeFlag_AcceptsMesh;
                mti->initData = fluidsimModifier_initData;
                mti->freeData = fluidsimModifier_freeData;
@@ -8515,6 +8793,14 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->copyData = multiresModifier_copyData;
                mti->applyModifier = multiresModifier_applyModifier;
 
                mti->copyData = multiresModifier_copyData;
                mti->applyModifier = multiresModifier_applyModifier;
 
+               mti = INIT_TYPE(ShapeKey);
+               mti->type = eModifierTypeType_OnlyDeform;
+               mti->flags = eModifierTypeFlag_AcceptsCVs
+                               | eModifierTypeFlag_SupportsEditmode;
+               mti->deformVerts = shapekeyModifier_deformVerts;
+               mti->deformVertsEM = shapekeyModifier_deformVertsEM;
+               mti->deformMatricesEM = shapekeyModifier_deformMatricesEM;
+
                typeArrInit = 0;
 #undef INIT_TYPE
        }
                typeArrInit = 0;
 #undef INIT_TYPE
        }
@@ -8532,7 +8818,8 @@ ModifierData *modifier_new(int type)
 {
        ModifierTypeInfo *mti = modifierType_getInfo(type);
        ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
 {
        ModifierTypeInfo *mti = modifierType_getInfo(type);
        ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
-
+       
+       // FIXME: we need to make the name always be unique somehow...
        strcpy(md->name, mti->name);
 
        md->type = type;
        strcpy(md->name, mti->name);
 
        md->type = type;
@@ -8557,6 +8844,15 @@ void modifier_free(ModifierData *md)
        MEM_freeN(md);
 }
 
        MEM_freeN(md);
 }
 
+void modifier_unique_name(ListBase *modifiers, ModifierData *md)
+{
+       if (modifiers && md) {
+               ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+               
+               BLI_uniquename(modifiers, md, mti->name, '.', offsetof(ModifierData, name), sizeof(md->name));
+       }
+}
+
 int modifier_dependsOnTime(ModifierData *md) 
 {
        ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 int modifier_dependsOnTime(ModifierData *md) 
 {
        ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -8669,9 +8965,9 @@ void modifier_setError(ModifierData *md, char *format, ...)
  * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg
  * then is NULL)
  */
  * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg
  * then is NULL)
  */
-int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r)
+int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r, int virtual_)
 {
 {
-       ModifierData *md = ob->modifiers.first;
+       ModifierData *md = (virtual_)? modifiers_getVirtualModifierList(ob): ob->modifiers.first;
        int i, cageIndex = -1;
 
        /* Find the last modifier acting on the cage. */
        int i, cageIndex = -1;
 
        /* Find the last modifier acting on the cage. */
@@ -8717,7 +9013,20 @@ int modifiers_isParticleEnabled(Object *ob)
        return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
 }
 
        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;
 {
        LinkNode *dataMasks = NULL;
        LinkNode *curr, *prev;
@@ -8727,7 +9036,9 @@ LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
                CustomDataMask mask = 0;
 
                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, SET_INT_IN_POINTER(mask));
        }
 
                BLI_linklist_prepend(&dataMasks, SET_INT_IN_POINTER(mask));
        }
@@ -8765,11 +9076,11 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob)
        static ArmatureModifierData amd;
        static CurveModifierData cmd;
        static LatticeModifierData lmd;
        static ArmatureModifierData amd;
        static CurveModifierData cmd;
        static LatticeModifierData lmd;
+       static ShapeKeyModifierData smd;
        static int init = 1;
        static int init = 1;
+       ModifierData *md;
 
        if (init) {
 
        if (init) {
-               ModifierData *md;
-
                md = modifier_new(eModifierType_Armature);
                amd = *((ArmatureModifierData*) md);
                modifier_free(md);
                md = modifier_new(eModifierType_Armature);
                amd = *((ArmatureModifierData*) md);
                modifier_free(md);
@@ -8782,32 +9093,50 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob)
                lmd = *((LatticeModifierData*) md);
                modifier_free(md);
 
                lmd = *((LatticeModifierData*) md);
                modifier_free(md);
 
+               md = modifier_new(eModifierType_ShapeKey);
+               smd = *((ShapeKeyModifierData*) md);
+               modifier_free(md);
+
                amd.modifier.mode |= eModifierMode_Virtual;
                cmd.modifier.mode |= eModifierMode_Virtual;
                lmd.modifier.mode |= eModifierMode_Virtual;
                amd.modifier.mode |= eModifierMode_Virtual;
                cmd.modifier.mode |= eModifierMode_Virtual;
                lmd.modifier.mode |= eModifierMode_Virtual;
+               smd.modifier.mode |= eModifierMode_Virtual;
 
                init = 0;
        }
 
 
                init = 0;
        }
 
-       if (ob->parent) {
+       md = ob->modifiers.first;
+
+       if(ob->parent) {
                if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) {
                        amd.object = ob->parent;
                if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) {
                        amd.object = ob->parent;
-                       amd.modifier.next = ob->modifiers.first;
+                       amd.modifier.next = md;
                        amd.deformflag= ((bArmature *)(ob->parent->data))->deformflag;
                        amd.deformflag= ((bArmature *)(ob->parent->data))->deformflag;
-                       return &amd.modifier;
+                       md = &amd.modifier;
                } else if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) {
                        cmd.object = ob->parent;
                        cmd.defaxis = ob->trackflag + 1;
                } else if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) {
                        cmd.object = ob->parent;
                        cmd.defaxis = ob->trackflag + 1;
-                       cmd.modifier.next = ob->modifiers.first;
-                       return &cmd.modifier;
+                       cmd.modifier.next = md;
+                       md = &cmd.modifier;
                } else if(ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
                        lmd.object = ob->parent;
                } else if(ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
                        lmd.object = ob->parent;
-                       lmd.modifier.next = ob->modifiers.first;
-                       return &lmd.modifier;
+                       lmd.modifier.next = md;
+                       md = &lmd.modifier;
                }
        }
 
                }
        }
 
-       return ob->modifiers.first;
+       /* shape key modifier, not yet for curves */
+       if(ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) {
+               if(ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE))
+                       smd.modifier.mode |= eModifierMode_Editmode|eModifierMode_OnCage;
+               else
+                       smd.modifier.mode &= ~eModifierMode_Editmode|eModifierMode_OnCage;
+
+               smd.modifier.next = md;
+               md = &smd.modifier;
+       }
+
+       return md;
 }
 /* Takes an object and returns its first selected armature, else just its
  * armature
 }
 /* Takes an object and returns its first selected armature, else just its
  * armature
@@ -8884,6 +9213,8 @@ int modifier_isDeformer(ModifierData *md)
                return 1;
        if (md->type==eModifierType_Lattice)
                return 1;
                return 1;
        if (md->type==eModifierType_Lattice)
                return 1;
+       if (md->type==eModifierType_ShapeKey)
+               return 1;
        
        return 0;
 }
        
        return 0;
 }
@@ -8893,7 +9224,7 @@ int modifiers_isDeformed(Scene *scene, Object *ob)
        ModifierData *md = modifiers_getVirtualModifierList(ob);
        
        for (; md; md=md->next) {
        ModifierData *md = modifiers_getVirtualModifierList(ob);
        
        for (; md; md=md->next) {
-               if(ob==scene->obedit && (md->mode & eModifierMode_Editmode)==0);
+               if(ob->mode==OB_MODE_EDIT && (md->mode & eModifierMode_Editmode)==0);
                else 
                        if(modifier_isDeformer(md))
                                return 1;
                else 
                        if(modifier_isDeformer(md))
                                return 1;
@@ -8911,19 +9242,6 @@ int modifiers_indexInObject(Object *ob, ModifierData *md_seek)
        return i;
 }
 
        return i;
 }
 
-int modifiers_usesPointCache(Object *ob)
-{
-       ModifierData *md = ob->modifiers.first;
-
-       for (; md; md=md->next) {
-               ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-               if (mti->flags & eModifierTypeFlag_UsesPointCache) {
-                       return 1;
-               }
-       }
-       return 0;
-}
-
 void modifier_freeTemporaryData(ModifierData *md)
 {
        if(md->type == eModifierType_Armature) {
 void modifier_freeTemporaryData(ModifierData *md)
 {
        if(md->type == eModifierType_Armature) {