Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / multires.c
index 279c6eb0c8275fa2bd78f73766aec60974f764c2..22a335c7fd4d0df1c7fcb7d8fa7b0b9825018851 100644 (file)
 #include "BKE_pbvh.h"
 #include "BKE_ccg.h"
 #include "BKE_cdderivedmesh.h"
+#include "BKE_library.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
+#include "BKE_mesh_runtime.h"
 #include "BKE_modifier.h"
 #include "BKE_multires.h"
 #include "BKE_paint.h"
@@ -62,6 +64,8 @@
 
 #include "CCGSubSurf.h"
 
+#include "DEG_depsgraph_query.h"
+
 #include <math.h>
 #include <string.h>
 
@@ -277,14 +281,14 @@ static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
        return mdisps;
 }
 
-DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object *ob)
+DerivedMesh *get_multires_dm(struct Depsgraph *depsgraph, Scene *scene, MultiresModifierData *mmd, Object *ob)
 {
        ModifierData *md = (ModifierData *)mmd;
-       const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-       DerivedMesh *tdm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+       DerivedMesh *tdm = mesh_get_derived_deform(depsgraph, scene, ob, CD_MASK_BAREMESH);
        DerivedMesh *dm;
+       ModifierEvalContext mectx = {depsgraph, ob, MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY};
 
-       dm = mti->applyModifier(md, ob, tdm, MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY);
+       dm = modifier_applyModifier_DM_deprecated(md, &mectx, tdm);
        if (dm == tdm) {
                dm = CDDM_copy(tdm);
        }
@@ -292,6 +296,25 @@ DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object *ob
        return dm;
 }
 
+Mesh *get_multires_mesh(
+        struct Depsgraph *depsgraph,
+        Scene *scene,
+        MultiresModifierData *mmd,
+        Object *ob)
+{
+       Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+       Mesh *deformed_mesh = mesh_get_eval_deform(depsgraph, scene, ob_eval, CD_MASK_BAREMESH);
+       ModifierEvalContext modifier_ctx = {
+               .depsgraph = depsgraph,
+               .object = ob_eval,
+               .flag = MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY};
+       Mesh *result = modifier_applyModifier(&mmd->modifier, &modifier_ctx, deformed_mesh);
+       if (result == deformed_mesh) {
+               result = BKE_mesh_copy_for_eval(deformed_mesh);
+       }
+       return result;
+}
+
 MultiresModifierData *find_multires_modifier_before(Scene *scene, ModifierData *lastmd)
 {
        ModifierData *md;
@@ -336,17 +359,17 @@ MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob, bool use_f
        return mmd;
 }
 
-static int multires_get_level(Object *ob, MultiresModifierData *mmd,
-                              bool render, bool ignore_simplify)
+int multires_get_level(const Scene *scene, const Object *ob, const MultiresModifierData *mmd,
+                       bool render, bool ignore_simplify)
 {
        if (render)
-               return (mmd->modifier.scene) ? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->renderlvl, true) : mmd->renderlvl;
+               return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->renderlvl, true) : mmd->renderlvl;
        else if (ob->mode == OB_MODE_SCULPT)
                return mmd->sculptlvl;
        else if (ignore_simplify)
                return mmd->lvl;
        else
-               return (mmd->modifier.scene) ? get_render_subsurf_level(&mmd->modifier.scene->r, mmd->lvl, false) : mmd->lvl;
+               return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->lvl, false) : mmd->lvl;
 }
 
 void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
@@ -398,68 +421,6 @@ void multires_force_render_update(Object *ob)
                multires_force_update(ob);
 }
 
-int multiresModifier_reshapeFromDM(Scene *scene, MultiresModifierData *mmd,
-                                   Object *ob, DerivedMesh *srcdm)
-{
-       DerivedMesh *mrdm = get_multires_dm(scene, mmd, ob);
-
-       if (mrdm && srcdm && mrdm->getNumVerts(mrdm) == srcdm->getNumVerts(srcdm)) {
-               multires_mvert_to_ss(mrdm, srcdm->getVertArray(srcdm));
-
-               multires_dm_mark_as_modified(mrdm, MULTIRES_COORDS_MODIFIED);
-               multires_force_update(ob);
-
-               mrdm->release(mrdm);
-
-               return 1;
-       }
-
-       if (mrdm) mrdm->release(mrdm);
-
-       return 0;
-}
-
-/* Returns 1 on success, 0 if the src's totvert doesn't match */
-int multiresModifier_reshape(Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
-{
-       DerivedMesh *srcdm = mesh_get_derived_final(scene, src, CD_MASK_BAREMESH);
-       return multiresModifier_reshapeFromDM(scene, mmd, dst, srcdm);
-}
-
-int multiresModifier_reshapeFromDeformMod(Scene *scene, MultiresModifierData *mmd,
-                                          Object *ob, ModifierData *md)
-{
-       const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-       DerivedMesh *dm, *ndm;
-       int numVerts, result;
-       float (*deformedVerts)[3];
-
-       if (multires_get_level(ob, mmd, false, true) == 0)
-               return 0;
-
-       /* Create DerivedMesh for deformation modifier */
-       dm = get_multires_dm(scene, mmd, ob);
-       numVerts = dm->getNumVerts(dm);
-       deformedVerts = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "multiresReshape_deformVerts");
-
-       dm->getVertCos(dm, deformedVerts);
-       mti->deformVerts(md, ob, dm, deformedVerts, numVerts, 0);
-
-       ndm = CDDM_copy(dm);
-       CDDM_apply_vert_coords(ndm, deformedVerts);
-
-       MEM_freeN(deformedVerts);
-       dm->release(dm);
-
-       /* Reshaping */
-       result = multiresModifier_reshapeFromDM(scene, mmd, ob, ndm);
-
-       /* Cleanup */
-       ndm->release(ndm);
-
-       return result;
-}
-
 /* reset the multires levels to match the number of mdisps */
 static int get_levels_from_disps(Object *ob)
 {
@@ -680,10 +641,10 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
 }
 
 /* (direction = 1) for delete higher, (direction = 0) for lower (not implemented yet) */
-void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int direction)
+void multiresModifier_del_levels(MultiresModifierData *mmd, Scene *scene, Object *ob, int direction)
 {
        Mesh *me = BKE_mesh_from_object(ob);
-       int lvl = multires_get_level(ob, mmd, false, true);
+       int lvl = multires_get_level(scene, ob, mmd, false, true);
        int levels = mmd->totlvl - lvl;
        MDisps *mdisps;
 
@@ -700,7 +661,7 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int dire
        multires_set_tot_level(ob, mmd, lvl);
 }
 
-static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, bool alloc_paint_mask)
+static DerivedMesh *multires_dm_create_local(Scene *scene, Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple, bool alloc_paint_mask)
 {
        MultiresModifierData mmd = {{NULL}};
        MultiresFlags flags = MULTIRES_USE_LOCAL_MMD;
@@ -714,29 +675,44 @@ static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lv
        if (alloc_paint_mask)
                flags |= MULTIRES_ALLOC_PAINT_MASK;
 
-       return multires_make_derived_from_derived(dm, &mmd, ob, flags);
+       return multires_make_derived_from_derived(dm, &mmd, scene, ob, flags);
 }
 
-static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv, int alloc_paint_mask)
+static DerivedMesh *subsurf_dm_create_local(
+        Scene *scene, Object *ob, DerivedMesh *dm,
+        int lvl,
+        bool is_simple, bool is_optimal, bool is_plain_uv, bool alloc_paint_mask,
+        bool for_render)
 {
        SubsurfModifierData smd = {{NULL}};
        SubsurfFlags flags = 0;
 
        smd.levels = smd.renderLevels = lvl;
-       if (!plain_uv)
-               smd.flags |= eSubsurfModifierFlag_SubsurfUv;
-       if (simple)
+       smd.quality = 3;
+       if (!is_plain_uv) {
+               smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
+       }
+       else {
+               smd.uv_smooth = SUBSURF_UV_SMOOTH_NONE;
+       }
+       if (is_simple) {
                smd.subdivType = ME_SIMPLE_SUBSURF;
-       if (optimal)
+       }
+       if (is_optimal) {
                smd.flags |= eSubsurfModifierFlag_ControlEdges;
+       }
 
-       if (ob->mode & OB_MODE_EDIT)
+       if (ob->mode & OB_MODE_EDIT) {
                flags |= SUBSURF_IN_EDIT_MODE;
-
-       if (alloc_paint_mask)
+       }
+       if (alloc_paint_mask) {
                flags |= SUBSURF_ALLOC_PAINT_MASK;
+       }
+       if (for_render) {
+               flags |= SUBSURF_USE_RENDER_PARAMS;
+       }
 
-       return subsurf_make_derived_from_derived(dm, &smd, NULL, flags);
+       return subsurf_make_derived_from_derived(dm, &smd, scene, NULL, flags);
 }
 
 
@@ -750,7 +726,7 @@ static float v3_dist_from_plane(float v[3], float center[3], float no[3])
        return dot_v3v3(s, no);
 }
 
-void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
+void multiresModifier_base_apply(MultiresModifierData *mmd, Scene *scene, Object *ob)
 {
        DerivedMesh *cddm, *dispdm, *origdm;
        Mesh *me;
@@ -772,7 +748,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
        /* generate highest level with displacements */
        cddm = CDDM_from_mesh(me);
        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
-       dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0, 0);
+       dispdm = multires_dm_create_local(scene, ob, cddm, totlvl, totlvl, 0, 0);
        cddm->release(cddm);
 
        /* copy the new locations of the base verts into the mesh */
@@ -868,7 +844,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
        /* subdivide the mesh to highest level without displacements */
        cddm = CDDM_from_mesh(me);
        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
-       origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
+       origdm = subsurf_dm_create_local(scene, ob, cddm, totlvl, 0, 0, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, 0, false);
        cddm->release(cddm);
 
        /* calc disps */
@@ -878,7 +854,9 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
        dispdm->release(dispdm);
 }
 
-static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl, int updateblock, int simple)
+static void multires_subdivide(
+        MultiresModifierData *mmd, Scene *scene, Object *ob,
+        int totlvl, int updateblock, int simple)
 {
        Mesh *me = ob->data;
        MDisps *mdisps;
@@ -907,11 +885,11 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
                /* create subsurf DM from original mesh at high level */
                cddm = CDDM_from_mesh(me);
                DM_set_only_copy(cddm, CD_MASK_BAREMESH);
-               highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
+               highdm = subsurf_dm_create_local(scene, ob, cddm, totlvl, simple, 0, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, has_mask, false);
                ss = ((CCGDerivedMesh *)highdm)->ss;
 
                /* create multires DM from original mesh at low level */
-               lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, has_mask);
+               lowdm = multires_dm_create_local(scene, ob, cddm, lvl, lvl, simple, has_mask);
                BLI_assert(lowdm != cddm);
                cddm->release(cddm);
 
@@ -961,9 +939,9 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
        multires_set_tot_level(ob, mmd, totlvl);
 }
 
-void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updateblock, int simple)
+void multiresModifier_subdivide(MultiresModifierData *mmd, Scene *scene, Object *ob, int updateblock, int simple)
 {
-       multires_subdivide(mmd, ob, mmd->totlvl + 1, updateblock, simple);
+       multires_subdivide(mmd, scene, ob, mmd->totlvl + 1, updateblock, simple);
 }
 
 static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3])
@@ -1196,7 +1174,7 @@ static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh *dm
        }
 }
 
-void multires_modifier_update_mdisps(struct DerivedMesh *dm)
+void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
        Object *ob;
@@ -1228,11 +1206,11 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
                        else cddm = CDDM_from_mesh(me);
                        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
 
-                       highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
+                       highdm = subsurf_dm_create_local(scene, ob, cddm, totlvl, mmd->simple, 0, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, has_mask, false);
                        ss = ((CCGDerivedMesh *)highdm)->ss;
 
                        /* create multires DM from original mesh and displacements */
-                       lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, has_mask);
+                       lowdm = multires_dm_create_local(scene, ob, cddm, lvl, totlvl, mmd->simple, has_mask);
                        cddm->release(cddm);
 
                        /* gather grid data */
@@ -1290,7 +1268,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
                        else cddm = CDDM_from_mesh(me);
                        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
 
-                       subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
+                       subdm = subsurf_dm_create_local(scene, ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, has_mask, false);
                        cddm->release(cddm);
 
                        multiresModifier_disp_run(dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl);
@@ -1332,126 +1310,6 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
        }
 }
 
-void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
-{
-       DerivedMesh *ccgdm = NULL, *subsurf = NULL;
-       CCGElem **gridData, **subGridData = NULL;
-       CCGKey key;
-       MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
-       MDisps *mdisps;
-       MultiresModifierData *mmd = get_multires_modifier(NULL, ob, 1);
-       int *gridOffset, totlvl;
-       int i, k, numGrids, gridSize, dGridSize, dSkip;
-
-       if (!mmd)
-               return;
-
-       mdisps = CustomData_get_layer(&dm->loopData, CD_MDISPS);
-
-       if (!mdisps) {
-               goto cleanup;
-       }
-
-       totlvl = mmd->totlvl;
-       ccgdm = multires_dm_create_local(ob, dm, totlvl, totlvl, mmd->simple, false);
-
-       subsurf = subsurf_dm_create_local(ob, dm, totlvl,
-                                         mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
-
-       numGrids = subsurf->getNumGrids(subsurf);
-       gridSize = subsurf->getGridSize(subsurf);
-       gridData = subsurf->getGridData(subsurf);
-       subsurf->getGridKey(subsurf, &key);
-
-       subGridData = MEM_calloc_arrayN(numGrids, sizeof(CCGElem *), "subGridData*");
-
-       for (i = 0; i < numGrids; i++) {
-               subGridData[i] = MEM_calloc_arrayN(key.elem_size, gridSize * gridSize, "subGridData");
-               memcpy(subGridData[i], gridData[i], key.elem_size * gridSize * gridSize);
-       }
-
-       /* numGrids = ccgdm->dm->getNumGrids((DerivedMesh *)ccgdm); */ /*UNUSED*/
-       gridSize = ccgdm->getGridSize((DerivedMesh *)ccgdm);
-       gridData = ccgdm->getGridData((DerivedMesh *)ccgdm);
-       gridOffset = ccgdm->getGridOffset((DerivedMesh *)ccgdm);
-
-       dGridSize = multires_side_tot[totlvl];
-       dSkip = (dGridSize - 1) / (gridSize - 1);
-
-       k = 0; /*current loop/mdisp index within the mloop array*/
-
-       /* TODO: Use BLI_task parallel range for that one too? */
-       for (i = 0; i < dm->numPolyData; ++i) {
-               const int numVerts = mpoly[i].totloop;
-               int S, x, y, gIndex = gridOffset[i];
-
-               for (S = 0; S < numVerts; ++S, ++gIndex, ++k) {
-                       MDisps *mdisp = &mdisps[mpoly[i].loopstart + S];
-                       /* CCGElem *grid = gridData[gIndex]; */ /* UNUSED */
-                       CCGElem *subgrid = subGridData[gIndex];
-                       float (*dispgrid)[3] = NULL;
-
-                       /* when adding new faces in edit mode, need to allocate disps */
-                       if (!mdisp->disps) {
-                               mdisp->totdisp = gridSize * gridSize;
-                               mdisp->level = totlvl;
-                               mdisp->disps = MEM_calloc_arrayN(mdisp->totdisp, 3 * sizeof(float), "disp in multires_set_space");
-                       }
-
-                       dispgrid = mdisp->disps;
-
-                       for (y = 0; y < gridSize; y++) {
-                               for (x = 0; x < gridSize; x++) {
-                                       float *data = dispgrid[dGridSize * y * dSkip + x * dSkip];
-                                       float *co = CCG_grid_elem_co(&key, subgrid, x, y);
-                                       float mat[3][3], dco[3];
-
-                                       /* construct tangent space matrix */
-                                       grid_tangent_matrix(mat, &key, x, y, subgrid);
-
-                                       /* convert to absolute coordinates in space */
-                                       if (from == MULTIRES_SPACE_TANGENT) {
-                                               mul_v3_m3v3(dco, mat, data);
-                                               add_v3_v3(dco, co);
-                                       }
-                                       else if (from == MULTIRES_SPACE_OBJECT) {
-                                               add_v3_v3v3(dco, co, data);
-                                       }
-                                       else if (from == MULTIRES_SPACE_ABSOLUTE) {
-                                               copy_v3_v3(dco, data);
-                                       }
-
-                                       /*now, convert to desired displacement type*/
-                                       if (to == MULTIRES_SPACE_TANGENT) {
-                                               invert_m3(mat);
-
-                                               sub_v3_v3(dco, co);
-                                               mul_v3_m3v3(data, mat, dco);
-                                       }
-                                       else if (to == MULTIRES_SPACE_OBJECT) {
-                                               sub_v3_v3(dco, co);
-                                               mul_v3_m3v3(data, mat, dco);
-                                       }
-                                       else if (to == MULTIRES_SPACE_ABSOLUTE) {
-                                               copy_v3_v3(data, dco);
-                                       }
-                               }
-                       }
-               }
-       }
-
-cleanup:
-       if (subsurf) {
-               subsurf->needsFree = 1;
-               subsurf->release(subsurf);
-       }
-
-       if (ccgdm) {
-               ccgdm->needsFree = 1;
-               ccgdm->release(ccgdm);
-       }
-}
-
 void multires_stitch_grids(Object *ob)
 {
        /* utility for smooth brush */
@@ -1473,6 +1331,7 @@ void multires_stitch_grids(Object *ob)
 
 DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm,
                                                 MultiresModifierData *mmd,
+                                                Scene *scene,
                                                 Object *ob,
                                                 MultiresFlags flags)
 {
@@ -1483,16 +1342,17 @@ DerivedMesh *multires_make_derived_from_derived(DerivedMesh *dm,
        CCGKey key;
        const bool render = (flags & MULTIRES_USE_RENDER_PARAMS) != 0;
        const bool ignore_simplify = (flags & MULTIRES_IGNORE_SIMPLIFY) != 0;
-       int lvl = multires_get_level(ob, mmd, render, ignore_simplify);
+       int lvl = multires_get_level(scene, ob, mmd, render, ignore_simplify);
        int i, gridSize, numGrids;
 
        if (lvl == 0)
                return dm;
 
-       result = subsurf_dm_create_local(ob, dm, lvl,
+       result = subsurf_dm_create_local(scene, ob, dm, lvl,
                                         mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges,
-                                        mmd->flags & eMultiresModifierFlag_PlainUv,
-                                        flags & MULTIRES_ALLOC_PAINT_MASK);
+                                        mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
+                                        flags & MULTIRES_ALLOC_PAINT_MASK,
+                                        render);
 
        if (!(flags & MULTIRES_USE_LOCAL_MMD)) {
                ccgdm = (CCGDerivedMesh *)result;
@@ -2168,7 +2028,7 @@ void multires_load_old(Object *ob, Mesh *me)
        BLI_insertlinkbefore(&ob->modifiers, md, mmd);
 
        for (i = 0; i < me->mr->level_count - 1; ++i)
-               multiresModifier_subdivide(mmd, ob, 1, 0);
+               multiresModifier_subdivide(mmd, NULL, ob, 1, 0);
 
        mmd->lvl = mmd->totlvl;
        orig = CDDM_from_mesh(me);
@@ -2177,7 +2037,7 @@ void multires_load_old(Object *ob, Mesh *me)
         *     reference subsurfed dm with this option, before calling multiresModifier_disp_run(),
         *     which implicitly expects both subsurfs from its first dm and oldGridData parameters to
         *     be of the same "format"! */
-       dm = multires_make_derived_from_derived(orig, mmd, ob, 0);
+       dm = multires_make_derived_from_derived(orig, mmd, NULL, ob, 0);
 
        multires_load_old_dm(dm, me, mmd->totlvl + 1);
 
@@ -2192,14 +2052,14 @@ void multires_load_old(Object *ob, Mesh *me)
 
 /* If 'ob_src' and 'ob_dst' both have multires modifiers, synchronize them
  * such that 'ob_dst' has the same total number of levels as 'ob_src'. */
-void multiresModifier_sync_levels_ex(Object *ob_dst, MultiresModifierData *mmd_src, MultiresModifierData *mmd_dst)
+void multiresModifier_sync_levels_ex(Scene *scene, Object *ob_dst, MultiresModifierData *mmd_src, MultiresModifierData *mmd_dst)
 {
        if (mmd_src->totlvl == mmd_dst->totlvl) {
                return;
        }
 
        if (mmd_src->totlvl > mmd_dst->totlvl) {
-               multires_subdivide(mmd_dst, ob_dst, mmd_src->totlvl, false, mmd_dst->simple);
+               multires_subdivide(mmd_dst, scene, ob_dst, mmd_src->totlvl, false, mmd_dst->simple);
        }
        else {
                multires_del_higher(mmd_dst, ob_dst, mmd_src->totlvl);
@@ -2221,7 +2081,7 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst)
        }
 
        if (mmd_src && mmd_dst) {
-               multiresModifier_sync_levels_ex(ob_dst, mmd_src, mmd_dst);
+               multiresModifier_sync_levels_ex(scene, ob_dst, mmd_src, mmd_dst);
        }
 }
 
@@ -2275,7 +2135,7 @@ static void multires_apply_smat_cb(
        }
 }
 
-static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
+static void multires_apply_smat(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float smat[3][3])
 {
        DerivedMesh *dm = NULL, *cddm = NULL, *subdm = NULL;
        CCGElem **gridData, **subGridData;
@@ -2300,10 +2160,10 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
        high_mmd.lvl = high_mmd.totlvl;
 
        /* unscaled multires with applied displacement */
-       subdm = get_multires_dm(scene, &high_mmd, ob);
+       subdm = get_multires_dm(depsgraph, scene, &high_mmd, ob);
 
        /* prepare scaled CDDM to create ccgDN */
-       cddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+       cddm = mesh_get_derived_deform(depsgraph, scene, ob, CD_MASK_BAREMESH);
 
        totvert = cddm->getNumVerts(cddm);
        vertCos = MEM_malloc_arrayN(totvert, sizeof(*vertCos), "multiresScale vertCos");
@@ -2314,7 +2174,7 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
        MEM_freeN(vertCos);
 
        /* scaled ccgDM for tangent space of object with applied scale */
-       dm = subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, 0);
+       dm = subsurf_dm_create_local(scene, ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, 0, false);
        cddm->release(cddm);
 
        gridSize = dm->getGridSize(dm);
@@ -2364,17 +2224,17 @@ int multires_mdisp_corners(MDisps *s)
        return 0;
 }
 
-void multiresModifier_scale_disp(Scene *scene, Object *ob)
+void multiresModifier_scale_disp(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
 {
        float smat[3][3];
 
        /* object's scale matrix */
        BKE_object_scale_to_mat3(ob, smat);
 
-       multires_apply_smat(scene, ob, smat);
+       multires_apply_smat(depsgraph, scene, ob, smat);
 }
 
-void multiresModifier_prepare_join(Scene *scene, Object *ob, Object *to_ob)
+void multiresModifier_prepare_join(struct Depsgraph *depsgraph, Scene *scene, Object *ob, Object *to_ob)
 {
        float smat[3][3], tmat[3][3], mat[3][3];
        multires_sync_levels(scene, to_ob, ob);
@@ -2385,7 +2245,7 @@ void multiresModifier_prepare_join(Scene *scene, Object *ob, Object *to_ob)
        BKE_object_scale_to_mat3(ob, smat);
        mul_m3_m3m3(mat, smat, tmat);
 
-       multires_apply_smat(scene, ob, mat);
+       multires_apply_smat(depsgraph, scene, ob, mat);
 }
 
 /* update multires data after topology changing */