2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r19323...
[blender.git] / source / blender / blenkernel / intern / modifier.c
index 566a139..6578fee 100644 (file)
@@ -20,8 +20,6 @@
 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
 * All rights reserved.
 *
-* The Original Code is: all of this file.
-*
 * Contributor(s): Daniel Dunbar
 *                 Ton Roosendaal,
 *                 Ben Batt,
@@ -77,9 +75,8 @@
 
 #include "BKE_main.h"
 #include "BKE_anim.h"
-#include "BKE_bad_level_calls.h"
 #include "BKE_bmesh.h"
-#include "BKE_booleanops.h"
+// XXX #include "BKE_booleanops.h"
 #include "BKE_cloth.h"
 #include "BKE_collision.h"
 #include "BKE_cdderivedmesh.h"
@@ -89,6 +86,7 @@
 #include "BKE_displist.h"
 #include "BKE_fluidsim.h"
 #include "BKE_global.h"
+#include "BKE_multires.h"
 #include "BKE_lattice.h"
 #include "BKE_library.h"
 #include "BKE_material.h"
 #include "BKE_shrinkwrap.h"
 #include "BKE_simple_deform.h"
 
-#include "LOD_DependKludge.h"
+//XXX #include "LOD_DependKludge.h"
 #include "LOD_decimation.h"
 
+// XXX
+static struct DerivedMesh *NewBooleanDerivedMesh() {return NULL;}
+
 #include "CCGSubSurf.h"
 
 #include "RE_shader_ext.h"
 
+//XXX #include "BIF_meshlaplacian.h"
+
 /***/
 
 static int noneModifier_isDisabled(ModifierData *md)
@@ -169,7 +172,7 @@ static void curveModifier_foreachObjectLink(
 }
 
 static void curveModifier_updateDepgraph(
-                                        ModifierData *md, DagForest *forest,
+                                        ModifierData *md, DagForest *forest, Scene *scene,
       Object *ob, DagNode *obNode)
 {
        CurveModifierData *cmd = (CurveModifierData*) md;
@@ -188,7 +191,7 @@ static void curveModifier_deformVerts(
 {
        CurveModifierData *cmd = (CurveModifierData*) md;
 
-       curve_deform_verts(cmd->object, ob, derivedData, vertexCos, numVerts,
+       curve_deform_verts(md->scene, cmd->object, ob, derivedData, vertexCos, numVerts,
                           cmd->name, cmd->defaxis);
 }
 
@@ -244,7 +247,7 @@ static void latticeModifier_foreachObjectLink(
        walk(userData, ob, &lmd->object);
 }
 
-static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+static void latticeModifier_updateDepgraph(ModifierData *md, DagForest *forest,  Scene *scene,
                                           Object *ob, DagNode *obNode)
 {
        LatticeModifierData *lmd = (LatticeModifierData*) md;
@@ -420,10 +423,10 @@ static DerivedMesh *buildModifier_applyModifier(ModifierData *md, Object *ob,
        for(i = 0; i < maxFaces; ++i) faceMap[i] = i;
 
        if (ob) {
-               frac = bsystem_time(ob, (float)G.scene->r.cfra,
+               frac = bsystem_time(md->scene, ob, md->scene->r.cfra,
                                    bmd->start - 1.0f) / bmd->length;
        } else {
-               frac = G.scene->r.cfra - bmd->start / bmd->length;
+               frac = md->scene->r.cfra - bmd->start / bmd->length;
        }
        CLAMP(frac, 0.0, 1.0);
 
@@ -613,7 +616,7 @@ static void maskModifier_foreachObjectLink(
        walk(userData, ob, &mmd->ob_arm);
 }
 
-static void maskModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+static void maskModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
                                           Object *ob, DagNode *obNode)
 {
        MaskModifierData *mmd = (MaskModifierData *)md;
@@ -999,7 +1002,7 @@ static void arrayModifier_foreachObjectLink(
        walk(userData, ob, &amd->offset_ob);
 }
 
-static void arrayModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+static void arrayModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
                                         Object *ob, DagNode *obNode)
 {
        ArrayModifierData *amd = (ArrayModifierData*) md;
@@ -1088,7 +1091,7 @@ static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
 }
 
 static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
-                                         Object *ob, DerivedMesh *dm,
+                                         Scene *scene, Object *ob, DerivedMesh *dm,
        int initFlags)
 {
        int i, j;
@@ -1112,9 +1115,9 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
 
        /* need to avoid infinite recursion here */
        if(amd->start_cap && amd->start_cap != ob)
-               start_cap = mesh_get_derived_final(amd->start_cap, CD_MASK_MESH);
+               start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH);
        if(amd->end_cap && amd->end_cap != ob)
-               end_cap = mesh_get_derived_final(amd->end_cap, CD_MASK_MESH);
+               end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
 
        MTC_Mat4One(offset);
 
@@ -1159,7 +1162,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
                                
                        if(!cu->path) {
                                cu->flag |= CU_PATH; // needed for path & bevlist
-                               makeDispListCurveTypes(amd->curve_ob, 0);
+                               makeDispListCurveTypes(scene, amd->curve_ob, 0);
                        }
                        if(cu->path)
                                length = scale*cu->path->totdist;
@@ -1635,7 +1638,7 @@ static DerivedMesh *arrayModifier_applyModifier(
        DerivedMesh *result;
        ArrayModifierData *amd = (ArrayModifierData*) md;
 
-       result = arrayModifier_doArray(amd, ob, derivedData, 0);
+       result = arrayModifier_doArray(amd, md->scene, ob, derivedData, 0);
 
        if(result != derivedData)
                CDDM_calc_normals(result);
@@ -1682,7 +1685,7 @@ static void mirrorModifier_foreachObjectLink(
        walk(userData, ob, &mmd->mirror_ob);
 }
 
-static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
                                          Object *ob, DagNode *obNode)
 {
        MirrorModifierData *mmd = (MirrorModifierData*) md;
@@ -3461,7 +3464,7 @@ static int displaceModifier_isDisabled(ModifierData *md)
 }
 
 static void displaceModifier_updateDepgraph(
-                                           ModifierData *md, DagForest *forest,
+                                           ModifierData *md, DagForest *forest, Scene *scene,
         Object *ob, DagNode *obNode)
 {
        DisplaceModifierData *dmd = (DisplaceModifierData*) md;
@@ -3782,7 +3785,7 @@ static void uvprojectModifier_foreachIDLink(ModifierData *md, Object *ob,
 }
 
 static void uvprojectModifier_updateDepgraph(ModifierData *md,
-                                            DagForest *forest, Object *ob, DagNode *obNode)
+                                            DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
 {
        UVProjectModifierData *umd = (UVProjectModifierData*) md;
        int i;
@@ -4055,6 +4058,8 @@ static void decimateModifier_copyData(ModifierData *md, ModifierData *target)
        tdmd->percent = dmd->percent;
 }
 
+//XXX
+#if 0 
 static DerivedMesh *decimateModifier_applyModifier(
                ModifierData *md, Object *ob, DerivedMesh *derivedData,
   int useRenderParams, int isFinalCalc)
@@ -4173,6 +4178,7 @@ static DerivedMesh *decimateModifier_applyModifier(
 exit:
                return result;
 }
+#endif
 
 /* Smooth */
 
@@ -4461,7 +4467,7 @@ static void castModifier_foreachObjectLink(
 }
 
 static void castModifier_updateDepgraph(
-                                       ModifierData *md, DagForest *forest, Object *ob,
+                                       ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
      DagNode *obNode)
 {
        CastModifierData *cmd = (CastModifierData*) md;
@@ -5050,7 +5056,7 @@ static void waveModifier_foreachIDLink(ModifierData *md, Object *ob,
 }
 
 static void waveModifier_updateDepgraph(
-                                       ModifierData *md, DagForest *forest, Object *ob,
+                                       ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
      DagNode *obNode)
 {
        WaveModifierData *wmd = (WaveModifierData*) md;
@@ -5175,15 +5181,15 @@ static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
        }
 }
 
-static void waveModifier_do(
-                           WaveModifierData *md, Object *ob, DerivedMesh *dm,
+static void waveModifier_do(WaveModifierData *md, 
+               Scene *scene, Object *ob, DerivedMesh *dm,
        float (*vertexCos)[3], int numVerts)
 {
        WaveModifierData *wmd = (WaveModifierData*) md;
        MVert *mvert = NULL;
        MDeformVert *dvert = NULL;
        int defgrp_index;
-       float ctime = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
+       float ctime = bsystem_time(scene, ob, (float)scene->r.cfra, 0.0);
        float minfac =
                        (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow));
        float lifefac = wmd->height;
@@ -5361,7 +5367,7 @@ static void waveModifier_deformVerts(
                CDDM_calc_normals(dm);
        }
 
-       waveModifier_do(wmd, ob, dm, vertexCos, numVerts);
+       waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
 
        if(dm != derivedData) dm->release(dm);
 }
@@ -5383,7 +5389,7 @@ static void waveModifier_deformVertsEM(
                CDDM_calc_normals(dm);
        }
 
-       waveModifier_do(wmd, ob, dm, vertexCos, numVerts);
+       waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts);
 
        if(dm != derivedData) dm->release(dm);
 }
@@ -5435,7 +5441,7 @@ static void armatureModifier_foreachObjectLink(
 }
 
 static void armatureModifier_updateDepgraph(
-                                           ModifierData *md, DagForest *forest, Object *ob,
+                                           ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
         DagNode *obNode)
 {
        ArmatureModifierData *amd = (ArmatureModifierData*) md;
@@ -5556,7 +5562,7 @@ static void hookModifier_foreachObjectLink(
        walk(userData, ob, &hmd->object);
 }
 
-static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest,
+static void hookModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
                                        Object *ob, DagNode *obNode)
 {
        HookModifierData *hmd = (HookModifierData*) md;
@@ -5703,7 +5709,7 @@ static void softbodyModifier_deformVerts(
                                         ModifierData *md, Object *ob, DerivedMesh *derivedData,
       float (*vertexCos)[3], int numVerts)
 {
-       sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts);
+       sbObjectStep(md->scene, ob, (float)md->scene->r.cfra, vertexCos, numVerts);
 }
 
 static int softbodyModifier_dependsOnTime(ModifierData *md)
@@ -5744,7 +5750,7 @@ static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob,
                        return derivedData;
        }
 
-       result = clothModifier_do(clmd, ob, derivedData, useRenderParams, isFinalCalc);
+       result = clothModifier_do(clmd, md->scene, ob, derivedData, useRenderParams, isFinalCalc);
 
        if(result)
        {
@@ -5755,7 +5761,7 @@ static DerivedMesh *clothModifier_applyModifier(ModifierData *md, Object *ob,
 }
 
 static void clothModifier_updateDepgraph(
-                                        ModifierData *md, DagForest *forest, Object *ob,
+                                        ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
       DagNode *obNode)
 {
        ClothModifierData *clmd = (ClothModifierData*) md;
@@ -5764,7 +5770,7 @@ static void clothModifier_updateDepgraph(
        
        if(clmd)
        {
-               for(base = G.scene->base.first; base; base= base->next) 
+               for(base = scene->base.first; base; base= base->next) 
                {
                        Object *ob1= base->object;
                        if(ob1 != ob)
@@ -5912,7 +5918,7 @@ static void collisionModifier_deformVerts(
                CDDM_apply_vert_coords(dm, vertexCos);
                CDDM_calc_normals(dm);
                
-               current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
+               current_time = bsystem_time (md->scene,  ob, ( float ) md->scene->r.cfra, 0.0 );
                
                if(G.rt > 0)
                        printf("current_time %f, collmd->time %f\n", current_time, collmd->time);
@@ -6016,6 +6022,80 @@ static void collisionModifier_deformVerts(
 }
 
 
+
+/* Surface */
+
+static void surfaceModifier_initData(ModifierData *md) 
+{
+       SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+       
+       surmd->bvhtree = NULL;
+}
+
+static void surfaceModifier_freeData(ModifierData *md)
+{
+       SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+       
+       if (surmd)
+       {
+               if(surmd->bvhtree) {
+                       free_bvhtree_from_mesh(surmd->bvhtree);
+                       MEM_freeN(surmd->bvhtree);
+               }
+
+               surmd->dm->release(surmd->dm);
+               
+               surmd->bvhtree = NULL;
+               surmd->dm = NULL;
+       }
+}
+
+static int surfaceModifier_dependsOnTime(ModifierData *md)
+{
+       return 1;
+}
+
+static void surfaceModifier_deformVerts(
+                                         ModifierData *md, Object *ob, DerivedMesh *derivedData,
+       float (*vertexCos)[3], int numVerts)
+{
+       SurfaceModifierData *surmd = (SurfaceModifierData*) md;
+       unsigned int numverts = 0, i = 0;
+       
+       if(surmd->dm)
+               surmd->dm->release(surmd->dm);
+
+       /* if possible use/create DerivedMesh */
+       if(derivedData) surmd->dm = CDDM_copy(derivedData);
+       else if(ob->type==OB_MESH) surmd->dm = CDDM_from_mesh(ob->data, ob);
+       
+       if(!ob->pd)
+       {
+               printf("surfaceModifier_deformVerts: Should not happen!\n");
+               return;
+       }
+       
+       if(surmd->dm)
+       {
+               CDDM_apply_vert_coords(surmd->dm, vertexCos);
+               CDDM_calc_normals(surmd->dm);
+               
+               numverts = surmd->dm->getNumVerts ( surmd->dm );
+
+               /* convert to global coordinates */
+               for(i = 0; i<numverts; i++)
+                       Mat4MulVecfl(ob->obmat, CDDM_get_vert(surmd->dm, i)->co);
+
+               if(surmd->bvhtree)
+                       free_bvhtree_from_mesh(surmd->bvhtree);
+               else
+                       surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh");
+
+               bvhtree_from_mesh_faces(surmd->bvhtree, surmd->dm, 0.0, 2, 6);
+       }
+}
+
+
 /* Boolean */
 
 static void booleanModifier_copyData(ModifierData *md, ModifierData *target)
@@ -6045,7 +6125,7 @@ static void booleanModifier_foreachObjectLink(
 }
 
 static void booleanModifier_updateDepgraph(
-                                          ModifierData *md, DagForest *forest, Object *ob,
+                                          ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
        DagNode *obNode)
 {
        BooleanModifierData *bmd = (BooleanModifierData*) md;
@@ -6064,22 +6144,44 @@ static DerivedMesh *booleanModifier_applyModifier(
 {
        // XXX doesn't handle derived data
        BooleanModifierData *bmd = (BooleanModifierData*) md;
+       DerivedMesh *dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_BAREMESH);
 
        /* we do a quick sanity check */
-       if(((Mesh *)ob->data)->totface > 3
-                   && bmd->object && ((Mesh *)bmd->object->data)->totface > 3) {
-               DerivedMesh *result = NewBooleanDerivedMesh(bmd->object, ob,
+       if(dm && (derivedData->getNumFaces(derivedData) > 3)
+                   && bmd->object && dm->getNumFaces(dm) > 3) {
+               DerivedMesh *result = NewBooleanDerivedMesh(dm, bmd->object, derivedData, ob,
                                1 + bmd->operation);
 
+               if(dm)
+                       dm->release(dm);
+
                /* if new mesh returned, return it; otherwise there was
                * an error, so delete the modifier object */
                if(result)
                        return result;
                else
                        bmd->object = NULL;
-                   }
+       }
+       
+       if(dm)
+                       dm->release(dm);
 
-                   return derivedData;
+       return derivedData;
+}
+
+CustomDataMask booleanModifier_requiredDataMask(ModifierData *md)
+{
+       CustomDataMask dataMask = (1 << CD_MTFACE) + (1 << CD_MEDGE);
+
+       dataMask |= (1 << CD_MDEFORMVERT);
+       
+       /* particles only need this if they are after a non deform modifier, and
+       * the modifier stack will only create them in that case. */
+//     dataMask |= CD_MASK_ORIGSPACE;
+
+//     dataMask |= CD_MASK_ORCO;
+       
+       return dataMask;
 }
 
 /* Particles */
@@ -6168,7 +6270,6 @@ static void particleSystemModifier_deformVerts(
        DerivedMesh *dm = derivedData;
        ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md;
        ParticleSystem * psys=0;
-       Mesh *me;
        int needsFree=0;
 
        if(ob->particlesystem.first)
@@ -6176,14 +6277,6 @@ static void particleSystemModifier_deformVerts(
        else
                return;
        
-       /* multires check */
-       if(ob->type == OB_MESH) {
-               me= (Mesh*)ob->data;
-               if(me->mr && me->mr->current != 1)
-                       modifier_setError(md,
-                               "Particles only supported on first multires level.");
-       }
-
        if(!psys_check_enabled(ob, psys))
                return;
 
@@ -6211,7 +6304,7 @@ static void particleSystemModifier_deformVerts(
                                /* copies the data */
                                tmpobj->data = copy_curve( (Curve *) ob->data );
 
-                               makeDispListCurveTypes( tmpobj, 1 );
+                               makeDispListCurveTypes(md->scene, tmpobj, 1 );
                                nurbs_to_mesh( tmpobj );
 
                                dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj);
@@ -6261,7 +6354,7 @@ static void particleSystemModifier_deformVerts(
                  }
 
                  if(psys){
-                         particle_system_update(ob,psys);
+                         particle_system_update(md->scene, ob, psys);
                          psmd->flag |= eParticleSystemFlag_psys_updated;
                          psmd->flag &= ~eParticleSystemFlag_DM_changed;
                  }
@@ -6309,7 +6402,7 @@ static int particleInstanceModifier_dependsOnTime(ModifierData *md)
        return 0;
 }
 static void particleInstanceModifier_updateDepgraph(ModifierData *md, DagForest *forest,
-               Object *ob, DagNode *obNode)
+                Scene *scene,Object *ob, DagNode *obNode)
 {
        ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData*) md;
 
@@ -6377,11 +6470,12 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        maxvert=totvert*totpart;
        maxface=totface*totpart;
 
-       psys->lattice=psys_get_lattice(ob, psys);
+       psys->lattice=psys_get_lattice(md->scene, ob, psys);
 
        if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)){
 
                float min_r[3], max_r[3];
+               INIT_MINMAX(min_r, max_r);
                dm->getMinMax(dm, min_r, max_r);                
                min_co=min_r[track];
                max_co=max_r[track];
@@ -6411,7 +6505,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
                        state.time=(mv->co[0]-min_co)/(max_co-min_co);
                        if(trackneg)
                                state.time=1.0f-state.time;
-                       psys_get_particle_on_path(pimd->ob,psys,first_particle + i/totvert,&state,1);
+                       psys_get_particle_on_path(md->scene, pimd->ob, psys,first_particle + i/totvert, &state,1);
 
                        mv->co[0] = 0.0;
 
@@ -6433,7 +6527,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
                }
                else{
                        state.time=-1.0;
-                       psys_get_particle_state(pimd->ob,psys,i/totvert,&state,1);
+                       psys_get_particle_state(md->scene, pimd->ob, psys, i/totvert, &state,1);
                }       
 
                QuatMulVecf(state.rot,mv->co);
@@ -6485,8 +6579,8 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
        CDDM_calc_normals(result);
 
        if(psys->lattice){
-               end_latt_deform();
-               psys->lattice=0;
+               end_latt_deform(psys->lattice);
+               psys->lattice= NULL;
        }
 
        return result;
@@ -7104,7 +7198,7 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
 
 }
 static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd, 
-               ParticleSystemModifierData *psmd, Object *ob, 
+               ParticleSystemModifierData *psmd, Scene *scene, Object *ob, 
   DerivedMesh *to_explode)
 {
        DerivedMesh *explode, *dm=to_explode;
@@ -7128,9 +7222,9 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        timestep= psys_get_timestep(part);
 
        if(part->flag & PART_GLOB_TIME)
-               cfra=bsystem_time(0,(float)G.scene->r.cfra,0.0);
+               cfra=bsystem_time(scene, 0,(float)scene->r.cfra,0.0);
        else
-               cfra=bsystem_time(ob,(float)G.scene->r.cfra,0.0);
+               cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0);
 
        /* hash table for vertice <-> particle relations */
        vertpahash= BLI_edgehash_new();
@@ -7168,7 +7262,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        /* getting back to object space */
        Mat4Invert(imat,ob->obmat);
 
-       psmd->psys->lattice = psys_get_lattice(ob, psmd->psys);
+       psmd->psys->lattice = psys_get_lattice(scene, ob, psmd->psys);
 
        /* duplicate & displace vertices */
        ehi= BLI_edgehashIterator_new(vertpahash);
@@ -7192,11 +7286,11 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
                        pa= pars+i;
 
                        /* get particle state */
-                       psys_particle_on_emitter(psmd,part->from,pa->num,-1,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
+                       psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc0,nor,0,0,0,0);
                        Mat4MulVecfl(ob->obmat,loc0);
 
                        state.time=cfra;
-                       psys_get_particle_state(ob,psmd->psys,i,&state,1);
+                       psys_get_particle_state(scene, ob, psmd->psys, i, &state,1);
 
                        vertco=CDDM_get_vert(explode,v)->co;
                        
@@ -7248,7 +7342,7 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
 
                *mf = source;
 
-               test_index_face(mf, &explode->faceData, i, (mf->v4 ? 4 : 3));
+               test_index_face(mf, &explode->faceData, i, (orig_v4 ? 4 : 3));
        }
 
        MEM_printmemlist_stats();
@@ -7261,8 +7355,8 @@ static DerivedMesh * explodeModifier_explodeMesh(ExplodeModifierData *emd,
        CDDM_calc_normals(explode);
 
        if(psmd->psys->lattice){
-               end_latt_deform();
-               psmd->psys->lattice=0;
+               end_latt_deform(psmd->psys->lattice);
+               psmd->psys->lattice= NULL;
        }
 
        return explode;
@@ -7312,7 +7406,7 @@ static DerivedMesh * explodeModifier_applyModifier(
                                 if(emd->flag & eExplodeFlag_EdgeSplit){
                                         int *facepa = emd->facepa;
                                         DerivedMesh *splitdm=explodeModifier_splitEdges(emd,dm);
-                                        DerivedMesh *explode=explodeModifier_explodeMesh(emd,psmd,ob,splitdm);
+                                        DerivedMesh *explode=explodeModifier_explodeMesh(emd, psmd, md->scene, ob, splitdm);
 
                                         MEM_freeN(emd->facepa);
                                         emd->facepa=facepa;
@@ -7320,7 +7414,7 @@ static DerivedMesh * explodeModifier_applyModifier(
                                         return explode;
                                 }
                                 else
-                                        return explodeModifier_explodeMesh(emd,psmd,ob,derivedData);
+                                        return explodeModifier_explodeMesh(emd, psmd, md->scene, ob, derivedData);
        }
        return derivedData;
 }
@@ -7366,7 +7460,7 @@ static DerivedMesh * fluidsimModifier_applyModifier(
                        return derivedData;
        }
 
-       result = fluidsimModifier_do(fluidmd, ob, derivedData, useRenderParams, isFinalCalc);
+       result = fluidsimModifier_do(fluidmd, md->scene, ob, derivedData, useRenderParams, isFinalCalc);
 
        if(result) 
        { 
@@ -7377,7 +7471,7 @@ static DerivedMesh * fluidsimModifier_applyModifier(
 }
 
 static void fluidsimModifier_updateDepgraph(
-               ModifierData *md, DagForest *forest,
+               ModifierData *md, DagForest *forest, Scene *scene,
       Object *ob, DagNode *obNode)
 {
        FluidsimModifierData *fluidmd= (FluidsimModifierData*) md;
@@ -7387,7 +7481,7 @@ static void fluidsimModifier_updateDepgraph(
        {
                if(fluidmd->fss->type == OB_FLUIDSIM_DOMAIN)
                {
-                       for(base = G.scene->base.first; base; base= base->next) 
+                       for(base = scene->base.first; base; base= base->next) 
                        {
                                Object *ob1= base->object;
                                if(ob1 != ob)
@@ -7469,7 +7563,7 @@ static void meshdeformModifier_foreachObjectLink(
 }
 
 static void meshdeformModifier_updateDepgraph(
-                                             ModifierData *md, DagForest *forest, Object *ob,
+                                             ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
           DagNode *obNode)
 {
        MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
@@ -7540,22 +7634,25 @@ static void meshdeformModifier_do(
       float (*vertexCos)[3], int numVerts)
 {
        MeshDeformModifierData *mmd = (MeshDeformModifierData*) md;
-       float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
-       float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
-       int a, b, totvert, totcagevert, defgrp_index;
+       Mesh *me= ob->data;
        DerivedMesh *tmpdm, *cagedm;
        MDeformVert *dvert = NULL;
        MDeformWeight *dw;
+       EditMesh *em = BKE_mesh_get_editmesh(me);
        MVert *cagemvert;
-
+       float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
+       float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
+       int a, b, totvert, totcagevert, defgrp_index;
+       
        if(!mmd->object || (!mmd->bindcos && !mmd->needbind))
                return;
        
        /* get cage derivedmesh */
-       if(mmd->object == G.obedit) {
-               tmpdm= editmesh_get_derived_cage_and_final(&cagedm, 0);
+       if(em) {
+               tmpdm= editmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0);
                if(tmpdm)
                        tmpdm->release(tmpdm);
+               BKE_mesh_end_editmesh(me, em);
        }
        else
                cagedm= mmd->object->derivedFinal;
@@ -7577,7 +7674,7 @@ static void meshdeformModifier_do(
                /* progress bar redraw can make this recursive .. */
                if(!recursive) {
                        recursive = 1;
-                       harmonic_coordinates_bind(mmd, vertexCos, numVerts, cagemat);
+                       //XXX harmonic_coordinates_bind(mmd, vertexCos, numVerts, cagemat);
                        recursive = 0;
                }
        }
@@ -7723,6 +7820,58 @@ static void meshdeformModifier_deformVertsEM(
                dm->release(dm);
 }
 
+/* Multires */
+static void multiresModifier_initData(ModifierData *md)
+{
+       MultiresModifierData *mmd = (MultiresModifierData*)md;
+
+       mmd->lvl = mmd->totlvl = 1;
+}
+
+static void multiresModifier_freeData(ModifierData *md)
+{
+       MultiresModifierData *mmd = (MultiresModifierData*)md;
+
+       if(mmd->undo_verts)
+               MEM_freeN(mmd->undo_verts);
+}
+
+static void multiresModifier_copyData(ModifierData *md, ModifierData *target)
+{
+       MultiresModifierData *mmd = (MultiresModifierData*) md;
+       MultiresModifierData *tmmd = (MultiresModifierData*) target;
+
+       tmmd->totlvl = mmd->totlvl;
+       tmmd->lvl = mmd->lvl;
+}
+
+static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
+                                                  int useRenderParams, int isFinalCalc)
+{
+       MultiresModifierData *mmd = (MultiresModifierData*)md;
+       Mesh *me = get_mesh(ob);
+       DerivedMesh *final;
+
+       /* TODO: for now just skip a level1 mesh */
+       if(mmd->lvl == 1)
+               return dm;
+
+       final = multires_dm_create_from_derived(mmd, dm, me, useRenderParams, isFinalCalc);
+       if(mmd->undo_signal && mmd->undo_verts && mmd->undo_verts_tot == final->getNumVerts(final)) {
+               int i;
+               MVert *dst = CDDM_get_verts(final);
+               for(i = 0; i < mmd->undo_verts_tot; ++i) {
+                       VecCopyf(dst[i].co, mmd->undo_verts[i].co);
+               }
+               CDDM_calc_normals(final);
+
+               MEM_freeN(mmd->undo_verts);
+               mmd->undo_signal = 0;
+               mmd->undo_verts = NULL;
+       }
+
+       return final;
+}
 
 /* Shrinkwrap */
 
@@ -7805,7 +7954,7 @@ static void shrinkwrapModifier_deformVerts(ModifierData *md, Object *ob, Derived
                }
        }
 
-       shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, ob, dm, vertexCos, numVerts);
+       shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
 
        if(dm)
                dm->release(dm);
@@ -7830,13 +7979,13 @@ static void shrinkwrapModifier_deformVertsEM(ModifierData *md, Object *ob, EditM
                }
        }
 
-       shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, ob, dm, vertexCos, numVerts);
+       shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts);
 
        if(dm)
                dm->release(dm);
 }
 
-static void shrinkwrapModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
+static void shrinkwrapModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
 {
        ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md;
 
@@ -7891,7 +8040,7 @@ static void simpledeformModifier_foreachObjectLink(ModifierData *md, Object *ob,
        walk(userData, ob, &smd->origin);
 }
 
-static void simpledeformModifier_updateDepgraph(ModifierData *md, DagForest *forest, Object *ob, DagNode *obNode)
+static void simpledeformModifier_updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene, Object *ob, DagNode *obNode)
 {
        SimpleDeformModifierData *smd  = (SimpleDeformModifierData*)md;
 
@@ -8122,7 +8271,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->flags = eModifierTypeFlag_AcceptsMesh;
                mti->initData = decimateModifier_initData;
                mti->copyData = decimateModifier_copyData;
-               mti->applyModifier = decimateModifier_applyModifier;
+               //XXX mti->applyModifier = decimateModifier_applyModifier;
 
                mti = INIT_TYPE(Smooth);
                mti->type = eModifierTypeType_OnlyDeform;
@@ -8216,16 +8365,24 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->deformVerts = collisionModifier_deformVerts;
                // mti->copyData = collisionModifier_copyData;
 
+               mti = INIT_TYPE(Surface);
+               mti->type = eModifierTypeType_OnlyDeform;
+               mti->initData = surfaceModifier_initData;
+               mti->flags = eModifierTypeFlag_AcceptsMesh;
+               mti->dependsOnTime = surfaceModifier_dependsOnTime;
+               mti->freeData = surfaceModifier_freeData; 
+               mti->deformVerts = surfaceModifier_deformVerts;
+
                mti = INIT_TYPE(Boolean);
                mti->type = eModifierTypeType_Nonconstructive;
                mti->flags = eModifierTypeFlag_AcceptsMesh
-                               | eModifierTypeFlag_RequiresOriginalData
                                | eModifierTypeFlag_UsesPointCache;
                mti->copyData = booleanModifier_copyData;
                mti->isDisabled = booleanModifier_isDisabled;
                mti->applyModifier = booleanModifier_applyModifier;
                mti->foreachObjectLink = booleanModifier_foreachObjectLink;
                mti->updateDepgraph = booleanModifier_updateDepgraph;
+               mti->requiredDataMask = booleanModifier_requiredDataMask;
 
                mti = INIT_TYPE(MeshDeform);
                mti->type = eModifierTypeType_OnlyDeform;
@@ -8323,6 +8480,14 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
                mti->foreachObjectLink = simpledeformModifier_foreachObjectLink;
                mti->updateDepgraph = simpledeformModifier_updateDepgraph;
 
+               mti = INIT_TYPE(Multires);
+               mti->type = eModifierTypeType_Constructive;
+               mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_RequiresOriginalData;
+               mti->initData = multiresModifier_initData;
+               mti->freeData = multiresModifier_freeData;
+               mti->copyData = multiresModifier_copyData;
+               mti->applyModifier = multiresModifier_applyModifier;
+
                typeArrInit = 0;
 #undef INIT_TYPE
        }
@@ -8404,8 +8569,6 @@ void modifiers_clearErrors(Object *ob)
                        qRedraw = 1;
                }
        }
-
-       if (qRedraw) allqueue(REDRAWBUTSEDIT, 0);
 }
 
 void modifiers_foreachObjectLink(Object *ob, ObjectWalkFunc walk,
@@ -8471,7 +8634,6 @@ void modifier_setError(ModifierData *md, char *format, ...)
 
        md->error = BLI_strdup(buffer);
 
-       allqueue(REDRAWBUTSEDIT, 0);
 }
 
 /* used for buttons, to find out if the 'draw deformed in editmode' option is
@@ -8540,7 +8702,7 @@ LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
 
                if(mti->requiredDataMask) mask = mti->requiredDataMask(md);
 
-               BLI_linklist_prepend(&dataMasks, (void *)mask);
+               BLI_linklist_prepend(&dataMasks, SET_INT_IN_POINTER(mask));
        }
 
        /* build the list of required data masks - each mask in the list must
@@ -8551,14 +8713,14 @@ LinkNode *modifiers_calcDataMasks(ModifierData *md, CustomDataMask dataMask)
        */
        for(curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) {
                if(prev) {
-                       CustomDataMask prev_mask = (CustomDataMask)prev->link;
-                       CustomDataMask curr_mask = (CustomDataMask)curr->link;
+                       CustomDataMask prev_mask = (CustomDataMask)GET_INT_FROM_POINTER(prev->link);
+                       CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
 
-                       curr->link = (void *)(curr_mask | prev_mask);
+                       curr->link = SET_INT_IN_POINTER(curr_mask | prev_mask);
                } else {
-                       CustomDataMask curr_mask = (CustomDataMask)curr->link;
+                       CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
 
-                       curr->link = (void *)(curr_mask | dataMask);
+                       curr->link = SET_INT_IN_POINTER(curr_mask | dataMask);
                }
        }
 
@@ -8699,14 +8861,15 @@ int modifier_isDeformer(ModifierData *md)
        return 0;
 }
 
-int modifiers_isDeformed(Object *ob)
+int modifiers_isDeformed(Scene *scene, Object *ob)
 {
        ModifierData *md = modifiers_getVirtualModifierList(ob);
        
        for (; md; md=md->next) {
-               if(ob==G.obedit && (md->mode & eModifierMode_Editmode)==0);
-               else if(modifier_isDeformer(md))
-                       return 1;
+               if(ob==scene->obedit && (md->mode & eModifierMode_Editmode)==0);
+               else 
+                       if(modifier_isDeformer(md))
+                               return 1;
        }
        return 0;
 }