Shape Keys
[blender-staging.git] / source / blender / blenkernel / intern / modifier.c
index f8795edc87828b7c1c5407bf2a79de4e6f0c6be9..a445b6986f622e876a76a32c451f539f0e6b47ba 100644 (file)
@@ -34,6 +34,7 @@
 *
 */
 
+#include "stddef.h"
 #include "string.h"
 #include "stdarg.h"
 #include "math.h"
@@ -59,6 +60,7 @@
 #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 "BLI_editVert.h"
 
-#include "MTC_matrixops.h"
-#include "MTC_vectorops.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"
@@ -90,6 +93,7 @@
 #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"
@@ -213,7 +217,7 @@ static void curveModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tcmd->name, cmd->name, 32);
 }
 
-CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CurveModifierData *cmd = (CurveModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -289,7 +293,7 @@ static void latticeModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tlmd->name, lmd->name, 32);
 }
 
-CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        LatticeModifierData *lmd = (LatticeModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -1103,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;
@@ -1185,11 +1189,11 @@ 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(scene, amd->start_cap, CD_MASK_MESH);
+               start_cap = amd->start_cap->derivedFinal;
        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");
@@ -1211,14 +1215,14 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                float result_mat[4][4];
 
                if(ob)
-                       MTC_Mat4Invert(obinv, ob->obmat);
+                       Mat4Invert(obinv, ob->obmat);
                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);
-               MTC_Mat4CpyMat4(offset, result_mat);
+               Mat4CpyMat4(offset, result_mat);
        }
 
        if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
@@ -1243,7 +1247,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
        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
@@ -1276,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) */ 
-                 MTC_Mat4One(final_offset);
+                 Mat4One(final_offset);
 
                  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;
@@ -1316,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);
-                                 MTC_Mat4MulVecfl(offset, tmp_co);
+                                 Mat4MulVecfl(offset, tmp_co);
 
                                  for(j = 0; j < maxVerts; j++) {
                                          /* if vertex already merged, don't use it */
@@ -1331,7 +1335,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                                                  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;
                                                  }
@@ -1349,7 +1353,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                                          *mv2 = *mv;
                                          numVerts++;
 
-                                         MTC_Mat4MulVecfl(offset, co);
+                                         Mat4MulVecfl(offset, co);
                                          VECCOPY(mv2->co, co);
                                  }
                          } else if(indexMap[i].merge != i && indexMap[i].merge_final) {
@@ -1770,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 */
-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 */
@@ -3181,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;
-                                                        float edge_angle_cos = MTC_dot3Float(face1->normal,
+                                                        float edge_angle_cos = Inpf(face1->normal,
                                                                         face2->normal);
 
                                                         if(edge_angle_cos < threshold) {
@@ -3400,7 +3404,7 @@ static void bevelModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tbmd->defgrp_name, bmd->defgrp_name, 32);
 }
 
-CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask bevelModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        BevelModifierData *bmd = (BevelModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -3480,7 +3484,7 @@ static void displaceModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32);
 }
 
-CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask displaceModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        DisplaceModifierData *dmd = (DisplaceModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -3824,7 +3828,7 @@ static void uvprojectModifier_copyData(ModifierData *md, ModifierData *target)
        tumd->aspecty = umd->aspecty;
 }
 
-CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask uvprojectModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = 0;
 
@@ -4050,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)
                                */
-                               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) {
-                                       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;
@@ -4277,7 +4281,7 @@ static void smoothModifier_copyData(ModifierData *md, ModifierData *target)
        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;
@@ -4290,7 +4294,7 @@ int smoothModifier_isDisabled(ModifierData *md)
        return 0;
 }
 
-CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask smoothModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        SmoothModifierData *smd = (SmoothModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -4507,7 +4511,7 @@ static void castModifier_copyData(ModifierData *md, ModifierData *target)
        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;
@@ -4519,7 +4523,7 @@ int castModifier_isDisabled(ModifierData *md)
        return 0;
 }
 
-CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask castModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CastModifierData *cmd = (CastModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -5150,7 +5154,7 @@ static void waveModifier_updateDepgraph(
        }
 }
 
-CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask waveModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        WaveModifierData *wmd = (WaveModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -5486,7 +5490,7 @@ static void armatureModifier_copyData(ModifierData *md, ModifierData *target)
        strncpy(tamd->defgrp_name, amd->defgrp_name, 32);
 }
 
-CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = 0;
 
@@ -5598,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);
+       strncpy(thmd->subtarget, hmd->subtarget, 32);
 }
 
-CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask hookModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        HookModifierData *hmd = (HookModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -5642,9 +5647,11 @@ static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest, Sce
 
        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");
        }
 }
 
@@ -5653,12 +5660,22 @@ static void hookModifier_deformVerts(
         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;
-
+       
+       /* 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);
-       Mat4MulSerie(mat, ob->imat, hmd->object->obmat, hmd->parentinv,
+       Mat4MulSerie(mat, ob->imat, dmat, hmd->parentinv,
                     NULL, NULL, NULL, NULL, NULL);
 
        /* vertex indices? */
@@ -5715,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;
@@ -5801,26 +5819,6 @@ static void smokeModifier_initData(ModifierData *md)
        smd->coll = NULL;
        smd->type = 0;
        smd->time = -1;
-       
-       /*
-       smd->fluid = NULL;
-       smd->maxres = 48;
-       smd->amplify = 4;
-       smd->omega = 0.5;
-       smd->time = 0;
-       smd->flags = 0;
-       smd->noise = MOD_SMOKE_NOISEWAVE;
-       smd->visibility = 1;
-       
-       // init 3dview buffer
-       smd->tvox = NULL;
-       smd->tray = NULL;
-       smd->tvoxbig = NULL;
-       smd->traybig = NULL;
-       smd->viewsettings = 0;
-       smd->bind = NULL;
-       smd->max_textures = 0;
-       */
 }
 
 static void smokeModifier_freeData(ModifierData *md)
@@ -5858,8 +5856,7 @@ static void smokeModifier_updateDepgraph(
                                         ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
       DagNode *obNode)
 {
-       SmokeModifierData *smd = (SmokeModifierData *) md;
-       /*
+       /*SmokeModifierData *smd = (SmokeModifierData *) md;
        if(smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
        {
                if(smd->domain->fluid_group)
@@ -5893,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->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)
@@ -5953,7 +5950,7 @@ static void clothModifier_updateDepgraph(
        }
 }
 
-CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask clothModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = 0;
 
@@ -5972,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);
-       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);
+       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->point_cache = BKE_ptcache_copy(clmd->point_cache);
+       tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches);
        tclmd->clothObject = NULL;
 }
 
@@ -5997,12 +5997,16 @@ static void clothModifier_freeData(ModifierData *md)
                
                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);
+               }
                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;
        }
 }
 
@@ -6210,7 +6214,8 @@ static void surfaceModifier_freeData(ModifierData *md)
                        MEM_freeN(surmd->bvhtree);
                }
 
-               surmd->dm->release(surmd->dm);
+               if(surmd->dm)
+                       surmd->dm->release(surmd->dm);
 
                if(surmd->x)
                        MEM_freeN(surmd->x);
@@ -6297,7 +6302,10 @@ static void surfaceModifier_deformVerts(
                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);
        }
 }
 
@@ -6350,7 +6358,7 @@ 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);
+       DerivedMesh *dm = bmd->object->derivedFinal;
 
        /* we do a quick sanity check */
        if(dm && (derivedData->getNumFaces(derivedData) > 3)
@@ -6375,7 +6383,7 @@ static DerivedMesh *booleanModifier_applyModifier(
        return derivedData;
 }
 
-CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask booleanModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
 
@@ -6423,7 +6431,7 @@ static void particleSystemModifier_copyData(ModifierData *md, ModifierData *targ
        tpsmd->psys = psmd->psys;
 }
 
-CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask particleSystemModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
        CustomDataMask dataMask = 0;
@@ -6605,6 +6613,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
 {
        DerivedMesh *dm = derivedData, *result;
        ParticleInstanceModifierData *pimd= (ParticleInstanceModifierData*) md;
+       ParticleSimulationData sim;
        ParticleSystem * psys=0;
        ParticleData *pa=0, *pars=0;
        MFace *mface, *orig_mface;
@@ -6639,6 +6648,11 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        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;
@@ -6666,7 +6680,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        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) || psys->pointcache->flag & PTCACHE_BAKED){
 
@@ -6700,10 +6714,8 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
                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) {
-                               /* just use some static collection of random numbers */
-                               /* TODO: use something else that's unique to each instanced object */
-                               pa = psys->particles + (i/totvert)%totpart;
-                               ran = pimd->random_position * 0.5 * (1.0f + pa->r_ave[0]);
+                               BLI_srandom(psys->seed + (i/totvert)%totpart);
+                               ran = pimd->random_position * BLI_frand();
                        }
 
                        if(pimd->flag & eParticleInstanceFlag_KeepShape) {
@@ -6718,7 +6730,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
                                mv->co[axis] = 0.0;
                        }
 
-                       psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1);
+                       psys_get_particle_on_path(&sim, first_particle + i/totvert, &state,1);
 
                        Normalize(state.vel);
                        
@@ -6740,7 +6752,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
                }
                else{
                        state.time=-1.0;
-                       psys_get_particle_state(md->scene, pimd->ob, psys, first_particle + i/totvert, &state,1);
+                       psys_get_particle_state(&sim, first_particle + i/totvert, &state,1);
                }       
 
                QuatMulVecf(state.rot,mv->co);
@@ -6838,7 +6850,7 @@ static int explodeModifier_dependsOnTime(ModifierData *md)
 {
        return 1;
 }
-CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask explodeModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        ExplodeModifierData *emd= (ExplodeModifierData*) md;
        CustomDataMask dataMask = 0;
@@ -7422,6 +7434,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        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;
@@ -7437,7 +7450,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        totvert= dm->getNumVerts(dm);
        totpart= psmd->psys->totpart;
 
-       timestep= psys_get_timestep(part);
+       timestep= psys_get_timestep(&sim);
 
        //if(part->flag & PART_GLOB_TIME)
                cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
@@ -7480,7 +7493,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        /* 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);
@@ -7508,7 +7521,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
                        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;
                        
@@ -7597,7 +7610,7 @@ static DerivedMesh * explodeModifier_applyModifier(
 {
        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;
@@ -7752,7 +7765,7 @@ static void meshdeformModifier_copyData(ModifierData *md, ModifierData *target)
        tmmd->object = mmd->object;
 }
 
-CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierData *md)
 {      
        MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -8077,14 +8090,13 @@ static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob,
                                                   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);
+       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);
@@ -8133,7 +8145,7 @@ static void shrinkwrapModifier_copyData(ModifierData *md, ModifierData *target)
        tsmd->subsurfLevels = smd->subsurfLevels;
 }
 
-CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
+static CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierData *md)
 {
        ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
        CustomDataMask dataMask = 0;
@@ -8331,6 +8343,52 @@ static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, Edi
                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];
@@ -8510,6 +8568,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->initData = smoothModifier_initData;
                mti->copyData = smoothModifier_copyData;
                mti->requiredDataMask = smoothModifier_requiredDataMask;
+               mti->isDisabled = smoothModifier_isDisabled;
                mti->deformVerts = smoothModifier_deformVerts;
                mti->deformVertsEM = smoothModifier_deformVertsEM;
 
@@ -8520,6 +8579,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                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;
@@ -8579,7 +8639,9 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->type = eModifierTypeType_OnlyDeform;
                mti->initData = smokeModifier_initData;
                mti->freeData = smokeModifier_freeData; 
-               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               mti->flags = eModifierTypeFlag_AcceptsMesh
+                               | eModifierTypeFlag_UsesPointCache
+                               | eModifierTypeFlag_Single;
                mti->deformVerts = smokeModifier_deformVerts;
                mti->dependsOnTime = smokeModifier_dependsOnTime;
                mti->updateDepgraph = smokeModifier_updateDepgraph;
@@ -8610,7 +8672,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                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;
@@ -8731,6 +8793,14 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                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
        }
@@ -8748,7 +8818,8 @@ ModifierData *modifier_new(int type)
 {
        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;
@@ -8773,6 +8844,15 @@ void modifier_free(ModifierData *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);
@@ -8885,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)
  */
-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. */
@@ -8996,11 +9076,11 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob)
        static ArmatureModifierData amd;
        static CurveModifierData cmd;
        static LatticeModifierData lmd;
+       static ShapeKeyModifierData smd;
        static int init = 1;
+       ModifierData *md;
 
        if (init) {
-               ModifierData *md;
-
                md = modifier_new(eModifierType_Armature);
                amd = *((ArmatureModifierData*) md);
                modifier_free(md);
@@ -9013,32 +9093,50 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob)
                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;
+               smd.modifier.mode |= eModifierMode_Virtual;
 
                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;
-                       amd.modifier.next = ob->modifiers.first;
+                       amd.modifier.next = md;
                        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;
-                       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;
-                       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
@@ -9115,6 +9213,8 @@ int modifier_isDeformer(ModifierData *md)
                return 1;
        if (md->type==eModifierType_Lattice)
                return 1;
+       if (md->type==eModifierType_ShapeKey)
+               return 1;
        
        return 0;
 }
@@ -9124,7 +9224,7 @@ int modifiers_isDeformed(Scene *scene, Object *ob)
        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;
@@ -9142,19 +9242,6 @@ int modifiers_indexInObject(Object *ob, ModifierData *md_seek)
        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) {