Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / physics / particle_edit.c
index 41310f8..a87719a 100644 (file)
 #include "BLI_math.h"
 #include "BLI_lasso_2d.h"
 #include "BLI_listbase.h"
+#include "BLI_string.h"
 #include "BLI_kdtree.h"
 #include "BLI_rand.h"
 #include "BLI_utildefines.h"
 
 #include "BKE_context.h"
-#include "BKE_depsgraph.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_global.h"
 #include "BKE_object.h"
+#include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
 #include "BKE_modifier.h"
 #include "BKE_particle.h"
 #include "BKE_report.h"
+#include "BKE_scene.h"
 #include "BKE_bvhutils.h"
 #include "BKE_pointcache.h"
 
+#include "DEG_depsgraph.h"
+
 #include "BIF_gl.h"
-#include "BIF_glutil.h"
 
 #include "ED_object.h"
 #include "ED_physics.h"
 #include "ED_mesh.h"
 #include "ED_particle.h"
+#include "ED_screen.h"
 #include "ED_view3d.h"
 
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+
 #include "UI_resources.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
+#include "WM_message.h"
+#include "WM_toolsystem.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
 
+#include "DEG_depsgraph_query.h"
+
 #include "physics_intern.h"
 
 #include "particle_edit_utildefines.h"
 
 int PE_poll(bContext *C)
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        Object *ob= CTX_data_active_object(C);
 
-       if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT))
+       if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) {
                return 0;
-
-       return (PE_get_current(bmain, scene, ob) != NULL);
+       }
+       return (PE_get_current(scene, ob) != NULL);
 }
 
 int PE_hair_poll(bContext *C)
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        Object *ob= CTX_data_active_object(C);
        PTCacheEdit *edit;
 
-       if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT))
+       if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) {
                return 0;
-
-       edit= PE_get_current(bmain, scene, ob);
+       }
+       edit = PE_get_current(scene, ob);
 
        return (edit && edit->psys);
 }
@@ -186,12 +196,30 @@ static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *br
        return brush->size * U.pixelsize;
 }
 
+PTCacheEdit *PE_get_current_from_psys(ParticleSystem *psys)
+{
+       if (psys->part && psys->part->type == PART_HAIR) {
+               if ((psys->flag & PSYS_HAIR_DYNAMICS) != 0 &&
+                   (psys->pointcache->flag & PTCACHE_BAKED) != 0)
+               {
+                       return psys->pointcache->edit;
+               }
+               else {
+                       return psys->edit;
+               }
+       }
+       else if (psys->pointcache->flag & PTCACHE_BAKED) {
+               return psys->pointcache->edit;
+       }
+       return NULL;
+}
 
 /* always gets at least the first particlesystem even if PSYS_CURRENT flag is not set
  *
  * note: this function runs on poll, therefor it can runs many times a second
  * keep it fast! */
-static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int create)
+static PTCacheEdit *pe_get_current(
+        Depsgraph *depsgraph, Scene *scene, Object *ob, int create)
 {
        ParticleEditSettings *pset= PE_settings(scene);
        PTCacheEdit *edit = NULL;
@@ -204,7 +232,7 @@ static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int cr
        pset->scene = scene;
        pset->object = ob;
 
-       BKE_ptcache_ids_from_object(bmain, &pidlist, ob, NULL, 0);
+       BKE_ptcache_ids_from_object(&pidlist, ob, NULL, 0);
 
        /* in the case of only one editable thing, set pset->edittype accordingly */
        if (BLI_listbase_is_single(&pidlist)) {
@@ -230,18 +258,21 @@ static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int cr
                                if (psys->part && psys->part->type == PART_HAIR) {
                                        if (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) {
                                                if (create && !psys->pointcache->edit)
-                                                       PE_create_particle_edit(bmain, scene, ob, pid->cache, NULL);
+                                                       PE_create_particle_edit(depsgraph, scene, ob, pid->cache, NULL);
                                                edit = pid->cache->edit;
                                        }
                                        else {
-                                               if (create && !psys->edit && psys->flag & PSYS_HAIR_DONE)
-                                                       PE_create_particle_edit(bmain, scene, ob, NULL, psys);
+                                               if (create && !psys->edit) {
+                                                       if (psys->flag & PSYS_HAIR_DONE) {
+                                                               PE_create_particle_edit(depsgraph, scene, ob, NULL, psys);
+                                                       }
+                                               }
                                                edit = psys->edit;
                                        }
                                }
                                else {
                                        if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit)
-                                               PE_create_particle_edit(bmain, scene, ob, pid->cache, psys);
+                                               PE_create_particle_edit(depsgraph, scene, ob, pid->cache, psys);
                                        edit = pid->cache->edit;
                                }
 
@@ -252,7 +283,7 @@ static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int cr
                        if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) {
                                pset->flag |= PE_FADE_TIME;
                                // NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB;
-                               PE_create_particle_edit(bmain, scene, ob, pid->cache, NULL);
+                               PE_create_particle_edit(depsgraph, scene, ob, pid->cache, NULL);
                        }
                        edit = pid->cache->edit;
                        break;
@@ -261,7 +292,7 @@ static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int cr
                        if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) {
                                pset->flag |= PE_FADE_TIME;
                                // NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB;
-                               PE_create_particle_edit(bmain, scene, ob, pid->cache, NULL);
+                               PE_create_particle_edit(depsgraph, scene, ob, pid->cache, NULL);
                        }
                        edit = pid->cache->edit;
                        break;
@@ -276,20 +307,21 @@ static PTCacheEdit *pe_get_current(Main *bmain, Scene *scene, Object *ob, int cr
        return edit;
 }
 
-PTCacheEdit *PE_get_current(Main *bmain, Scene *scene, Object *ob)
+PTCacheEdit *PE_get_current(Scene *scene, Object *ob)
 {
-       return pe_get_current(bmain, scene, ob, 0);
+       return pe_get_current(NULL, scene, ob, 0);
 }
 
-PTCacheEdit *PE_create_current(Main *bmain, Scene *scene, Object *ob)
+PTCacheEdit *PE_create_current(Depsgraph *depsgraph, Scene *scene, Object *ob)
 {
-       return pe_get_current(bmain, scene, ob, 1);
+       return pe_get_current(depsgraph, scene, ob, 1);
 }
 
-void PE_current_changed(Main *bmain, Scene *scene, Object *ob)
+void PE_current_changed(Depsgraph *depsgraph, Scene *scene, Object *ob)
 {
-       if (ob->mode == OB_MODE_PARTICLE_EDIT)
-               PE_create_current(bmain, scene, ob);
+       if (ob->mode == OB_MODE_PARTICLE_EDIT) {
+               PE_create_current(depsgraph, scene, ob);
+       }
 }
 
 void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra)
@@ -331,14 +363,16 @@ static int pe_x_mirror(Object *ob)
 
 typedef struct PEData {
        ViewContext vc;
-       bglMats mats;
 
+       const bContext *context;
        Main *bmain;
        Scene *scene;
+       ViewLayer *view_layer;
        Object *ob;
-       DerivedMesh *dm;
+       Mesh *mesh;
        PTCacheEdit *edit;
        BVHTreeFromMesh shape_bvh;
+       Depsgraph *depsgraph;
 
        const int *mval;
        rcti *rect;
@@ -369,9 +403,11 @@ static void PE_set_data(bContext *C, PEData *data)
        memset(data, 0, sizeof(*data));
 
        data->bmain = CTX_data_main(C);
-       data->scene= CTX_data_scene(C);
-       data->ob= CTX_data_active_object(C);
-       data->edit= PE_get_current(data->bmain, data->scene, data->ob);
+       data->scene = CTX_data_scene(C);
+       data->view_layer = CTX_data_view_layer(C);
+       data->ob = CTX_data_active_object(C);
+       data->depsgraph = CTX_data_depsgraph(C);
+       data->edit = PE_get_current(data->scene, data->ob);
 }
 
 static void PE_set_view3d_data(bContext *C, PEData *data)
@@ -379,8 +415,6 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
        PE_set_data(C, data);
 
        ED_view3d_viewcontext_init(C, &data->vc);
-       /* note, the object argument means the modelview matrix does not account for the objects matrix, use viewmat rather than (obmat * viewmat) */
-       view3d_get_transformation(data->vc.ar, data->vc.rv3d, NULL, &data->mats);
 
        if (V3D_IS_ZBUF(data->vc.v3d)) {
                if (data->vc.v3d->flag & V3D_INVALID_BACKBUF) {
@@ -398,15 +432,15 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
 
 static bool PE_create_shape_tree(PEData *data, Object *shapeob)
 {
-       DerivedMesh *dm = shapeob->derivedFinal;
+       Mesh *mesh = BKE_object_get_evaluated_mesh(data->depsgraph, shapeob);
 
        memset(&data->shape_bvh, 0, sizeof(data->shape_bvh));
 
-       if (!dm) {
+       if (!mesh) {
                return false;
        }
 
-       return (bvhtree_from_mesh_get(&data->shape_bvh, dm, BVHTREE_FROM_LOOPTRI, 4) != NULL);
+       return (BKE_bvhtree_from_mesh_get(&data->shape_bvh, mesh, BVHTREE_FROM_LOOPTRI, 4) != NULL);
 }
 
 static void PE_free_shape_tree(PEData *data)
@@ -420,7 +454,6 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
 {
        View3D *v3d= data->vc.v3d;
        ViewDepths *vd = data->vc.rv3d->depths;
-       double ux, uy, uz;
        float depth;
 
        /* nothing to do */
@@ -436,9 +469,6 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
        }
 #endif
 
-       gluProject(co[0], co[1], co[2], data->mats.modelview, data->mats.projection,
-                  (GLint *)data->mats.viewport, &ux, &uy, &uz);
-
        /* check if screen_co is within bounds because brush_cut uses out of screen coords */
        if (screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) {
                BLI_assert(vd && vd->depths);
@@ -448,7 +478,10 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[
        else
                return 0;
 
-       if ((float)uz - 0.00001f > depth)
+       float win[3];
+       ED_view3d_project(data->vc.ar, co, win);
+
+       if (win[2] - 0.00001f > depth)
                return 0;
        else
                return 1;
@@ -640,7 +673,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
                                if (selected==0 || key->flag & PEK_SELECT) {
                                        if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
                                                if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
-                                                       psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat);
+                                                       psys_mat_hair_to_global(data->ob, psmd->mesh_final, psys->part->from, psys->particles + p, mat);
                                                        invert_m4_m4(imat, mat);
                                                }
 
@@ -655,7 +688,7 @@ static void foreach_mouse_hit_key(PEData *data, ForKeyMatFunc func, int selected
                                if (selected==0 || key->flag & PEK_SELECT) {
                                        if (key_inside_circle(data, data->rad, KEY_WCO, &data->dist)) {
                                                if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) {
-                                                       psys_mat_hair_to_global(data->ob, psmd->dm_final, psys->part->from, psys->particles + p, mat);
+                                                       psys_mat_hair_to_global(data->ob, psmd->mesh_final, psys->part->from, psys->particles + p, mat);
                                                        invert_m4_m4(imat, mat);
                                                }
 
@@ -742,7 +775,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
        psmd= psys_get_modifier(ob, psys);
        totpart= psys->totpart;
 
-       if (!psmd->dm_final)
+       if (!psmd->mesh_final)
                return;
 
        tree= BLI_kdtree_new(totpart);
@@ -750,7 +783,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
        /* insert particles into kd tree */
        LOOP_PARTICLES {
                key = pa->hair;
-               psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat);
+               psys_mat_hair_to_orco(ob, psmd->mesh_final, psys->part->from, pa, mat);
                copy_v3_v3(co, key->co);
                mul_m4_v3(mat, co);
                BLI_kdtree_insert(tree, p, co);
@@ -764,7 +797,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
 
        LOOP_PARTICLES {
                key = pa->hair;
-               psys_mat_hair_to_orco(ob, psmd->dm_final, psys->part->from, pa, mat);
+               psys_mat_hair_to_orco(ob, psmd->mesh_final, psys->part->from, pa, mat);
                copy_v3_v3(co, key->co);
                mul_m4_v3(mat, co);
                co[0] = -co[0];
@@ -790,7 +823,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
        BLI_kdtree_free(tree);
 }
 
-static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa)
+static void PE_mirror_particle(Object *ob, Mesh *mesh, ParticleSystem *psys, ParticleData *pa, ParticleData *mpa)
 {
        HairKey *hkey, *mhkey;
        PTCacheEditPoint *point, *mpoint;
@@ -841,8 +874,8 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys
        }
 
        /* mirror positions and tags */
-       psys_mat_hair_to_orco(ob, dm, psys->part->from, pa, mat);
-       psys_mat_hair_to_orco(ob, dm, psys->part->from, mpa, mmat);
+       psys_mat_hair_to_orco(ob, mesh, psys->part->from, pa, mat);
+       psys_mat_hair_to_orco(ob, mesh, psys->part->from, mpa, mmat);
        invert_m4_m4(immat, mmat);
 
        hkey=pa->hair;
@@ -879,7 +912,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
        edit= psys->edit;
        psmd= psys_get_modifier(ob, psys);
 
-       if (!psmd->dm_final)
+       if (!psmd->mesh_final)
                return;
 
        if (!edit->mirror_cache)
@@ -892,7 +925,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
         * to avoid doing mirror twice */
        LOOP_POINTS {
                if (point->flag & PEP_EDIT_RECALC) {
-                       PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL);
+                       PE_mirror_particle(ob, psmd->mesh_final, psys, psys->particles + p, NULL);
 
                        if (edit->mirror_cache[p] != -1)
                                edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC;
@@ -927,11 +960,11 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
        psys = edit->psys;
        psmd = psys_get_modifier(ob, psys);
 
-       if (!psmd->dm_final)
+       if (!psmd->mesh_final)
                return;
 
        LOOP_EDITED_POINTS {
-               psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles + p, hairmat);
+               psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles + p, hairmat);
 
                LOOP_KEYS {
                        mul_m4_v3(hairmat, key->co);
@@ -1074,14 +1107,14 @@ void recalc_lengths(PTCacheEdit *edit)
 }
 
 /* calculate a tree for finding nearest emitter's vertice */
-void recalc_emitter_field(Object *ob, ParticleSystem *psys)
+void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *ob, ParticleSystem *psys)
 {
-       DerivedMesh *dm=psys_get_modifier(ob, psys)->dm_final;
-       PTCacheEdit *edit= psys->edit;
+       Mesh *mesh = psys_get_modifier(ob, psys)->mesh_final;
+       PTCacheEdit *edit = psys->edit;
        float *vec, *nor;
        int i, totface /*, totvert*/;
 
-       if (!dm)
+       if (!mesh)
                return;
 
        if (edit->emitter_cosnos)
@@ -1089,7 +1122,7 @@ void recalc_emitter_field(Object *ob, ParticleSystem *psys)
 
        BLI_kdtree_free(edit->emitter_field);
 
-       totface=dm->getNumTessFaces(dm);
+       totface = mesh->totface;
        /*totvert=dm->getNumVerts(dm);*/ /*UNSUED*/
 
        edit->emitter_cosnos=MEM_callocN(totface*6*sizeof(float), "emitter cosnos");
@@ -1100,23 +1133,23 @@ void recalc_emitter_field(Object *ob, ParticleSystem *psys)
        nor=vec+3;
 
        for (i=0; i<totface; i++, vec+=6, nor+=6) {
-               MFace *mface=dm->getTessFaceData(dm, i, CD_MFACE);
+               MFace *mface = &mesh->mface[i];
                MVert *mvert;
 
-               mvert=dm->getVertData(dm, mface->v1, CD_MVERT);
+               mvert = &mesh->mvert[mface->v1];
                copy_v3_v3(vec, mvert->co);
                VECCOPY(nor, mvert->no);
 
-               mvert=dm->getVertData(dm, mface->v2, CD_MVERT);
+               mvert = &mesh->mvert[mface->v2];
                add_v3_v3v3(vec, vec, mvert->co);
                VECADD(nor, nor, mvert->no);
 
-               mvert=dm->getVertData(dm, mface->v3, CD_MVERT);
+               mvert = &mesh->mvert[mface->v3];
                add_v3_v3v3(vec, vec, mvert->co);
                VECADD(nor, nor, mvert->no);
 
                if (mface->v4) {
-                       mvert=dm->getVertData(dm, mface->v4, CD_MVERT);
+                       mvert = &mesh->mvert[mface->v4];
                        add_v3_v3v3(vec, vec, mvert->co);
                        VECADD(nor, nor, mvert->no);
 
@@ -1133,9 +1166,9 @@ void recalc_emitter_field(Object *ob, ParticleSystem *psys)
        BLI_kdtree_balance(edit->emitter_field);
 }
 
-static void PE_update_selection(Main *bmain, Scene *scene, Object *ob, int useflag)
+static void PE_update_selection(Depsgraph *depsgraph, Scene *scene, Object *ob, int useflag)
 {
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit = PE_get_current(scene, ob);
        HairKey *hkey;
        POINT_P; KEY_K;
 
@@ -1154,27 +1187,29 @@ static void PE_update_selection(Main *bmain, Scene *scene, Object *ob, int usefl
                }
        }
 
-       psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering);
+       psys_cache_edit_paths(depsgraph, scene, ob, edit, CFRA, G.is_rendering);
 
 
        /* disable update flag */
        LOOP_POINTS
                point->flag &= ~PEP_EDIT_RECALC;
+
+       DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE);
 }
 
-void update_world_cos(Object *ob, PTCacheEdit *edit)
+void update_world_cos(Depsgraph *UNUSED(depsgraph), Object *ob, PTCacheEdit *edit)
 {
        ParticleSystem *psys = edit->psys;
-       ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
+       ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
        POINT_P; KEY_K;
        float hairmat[4][4];
 
-       if (psys==0 || psys->edit==0 || psmd->dm_final==NULL)
+       if (psys == 0 || psys->edit == 0 || psmd->mesh_final == NULL)
                return;
 
        LOOP_POINTS {
                if (!(psys->flag & PSYS_GLOBAL_HAIR))
-                       psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, hairmat);
+                       psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles+p, hairmat);
 
                LOOP_KEYS {
                        copy_v3_v3(key->world_co, key->co);
@@ -1240,12 +1275,12 @@ static void update_velocities(PTCacheEdit *edit)
        }
 }
 
-void PE_update_object(Main *bmain, Scene *scene, Object *ob, int useflag)
+void PE_update_object(Depsgraph *depsgraph, Scene *scene, Object *ob, int useflag)
 {
        /* use this to do partial particle updates, not usable when adding or
         * removing, then a full redo is necessary and calling this may crash */
        ParticleEditSettings *pset= PE_settings(scene);
-       PTCacheEdit *edit = PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit = PE_get_current(scene, ob);
        POINT_P;
 
        if (!edit)
@@ -1264,13 +1299,13 @@ void PE_update_object(Main *bmain, Scene *scene, Object *ob, int useflag)
        if (pe_x_mirror(ob))
                PE_apply_mirror(ob, edit->psys);
        if (edit->psys)
-               update_world_cos(ob, edit);
+               update_world_cos(depsgraph, ob, edit);
        if (pset->flag & PE_AUTO_VELOCITY)
                update_velocities(edit);
        PE_hide_keys_time(scene, edit, CFRA);
 
        /* regenerate path caches */
-       psys_cache_edit_paths(scene, ob, edit, CFRA, G.is_rendering);
+       psys_cache_edit_paths(depsgraph, scene, ob, edit, CFRA, G.is_rendering);
 
        /* disable update flag */
        LOOP_POINTS {
@@ -1379,10 +1414,10 @@ static void select_action_apply(PTCacheEditPoint *point, PTCacheEditKey *key, in
 
 static int pe_select_all_exec(bContext *C, wmOperator *op)
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Object *ob= CTX_data_active_object(C);
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        POINT_P; KEY_K;
        int action = RNA_enum_get(op->ptr, "action");
 
@@ -1405,7 +1440,7 @@ static int pe_select_all_exec(bContext *C, wmOperator *op)
                }
        }
 
-       PE_update_selection(bmain, scene, ob, 1);
+       PE_update_selection(depsgraph, scene, ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
 
        return OPERATOR_FINISHED;
@@ -1432,11 +1467,10 @@ void PARTICLE_OT_select_all(wmOperatorType *ot)
 
 int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
 {
-       Main *bmain = CTX_data_main(C);
        PEData data;
        Scene *scene= CTX_data_scene(C);
        Object *ob= CTX_data_active_object(C);
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        POINT_P; KEY_K;
 
        if (!PE_start_edit(edit))
@@ -1463,7 +1497,7 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec
        else
                for_mouse_hit_keys(&data, toggle_key_select, 1);
 
-       PE_update_selection(bmain, scene, ob, 1);
+       PE_update_selection(data.depsgraph, scene, ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -1504,7 +1538,7 @@ static int select_roots_exec(bContext *C, wmOperator *op)
        data.select_action = action;
        foreach_point(&data, select_root);
 
-       PE_update_selection(data.bmain, data.scene, data.ob, 1);
+       PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -1569,7 +1603,7 @@ static int select_tips_exec(bContext *C, wmOperator *op)
        data.select_action = action;
        foreach_point(&data, select_tip);
 
-       PE_update_selection(data.bmain, data.scene, data.ob, 1);
+       PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -1624,7 +1658,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
 
        PE_set_data(C, &data);
        data.select_action = SEL_SELECT;
-       edit = PE_get_current(data.bmain, data.scene, data.ob);
+       edit = PE_get_current(data.scene, data.ob);
 
        rng = BLI_rng_new_srandom(seed);
 
@@ -1649,7 +1683,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
 
        BLI_rng_free(rng);
 
-       PE_update_selection(data.bmain, data.scene, data.ob, 1);
+       PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -1693,7 +1727,7 @@ static int select_linked_exec(bContext *C, wmOperator *op)
        data.select= !RNA_boolean_get(op->ptr, "deselect");
 
        for_mouse_hit_keys(&data, select_keys, 1);  /* nearest only */
-       PE_update_selection(data.bmain, data.scene, data.ob, 1);
+       PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -1740,10 +1774,9 @@ void PE_deselect_all_visible(PTCacheEdit *edit)
 
 int PE_border_select(bContext *C, rcti *rect, bool select, bool extend)
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        Object *ob= CTX_data_active_object(C);
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        PEData data;
 
        if (!PE_start_edit(edit))
@@ -1758,7 +1791,7 @@ int PE_border_select(bContext *C, rcti *rect, bool select, bool extend)
 
        for_mouse_hit_keys(&data, select_key, 0);
 
-       PE_update_selection(bmain, scene, ob, 1);
+       PE_update_selection(data.depsgraph, scene, ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
 
        return OPERATOR_FINISHED;
@@ -1768,10 +1801,9 @@ int PE_border_select(bContext *C, rcti *rect, bool select, bool extend)
 
 int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad)
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        Object *ob= CTX_data_active_object(C);
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        PEData data;
 
        if (!PE_start_edit(edit))
@@ -1784,7 +1816,7 @@ int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad)
 
        for_mouse_hit_keys(&data, select_key, 0);
 
-       PE_update_selection(bmain, scene, ob, 1);
+       PE_update_selection(data.depsgraph, scene, ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
 
        return OPERATOR_FINISHED;
@@ -1794,12 +1826,11 @@ int PE_circle_select(bContext *C, int selecting, const int mval[2], float rad)
 
 int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool extend, bool select)
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        Object *ob= CTX_data_active_object(C);
        ARegion *ar= CTX_wm_region(C);
        ParticleEditSettings *pset= PE_settings(scene);
-       PTCacheEdit *edit = PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit = PE_get_current(scene, ob);
        ParticleSystem *psys = edit->psys;
        ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
        POINT_P; KEY_K;
@@ -1821,7 +1852,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
 
        LOOP_VISIBLE_POINTS {
                if (edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR))
-                       psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + p, mat);
+                       psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles + p, mat);
 
                if (pset->selectmode==SCE_SELECT_POINT) {
                        LOOP_KEYS {
@@ -1873,7 +1904,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
                }
        }
 
-       PE_update_selection(bmain, scene, ob, 1);
+       PE_update_selection(data.depsgraph, scene, ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
 
        return OPERATOR_FINISHED;
@@ -1883,12 +1914,14 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool
 
 static int hide_exec(bContext *C, wmOperator *op)
 {
-       Main *bmain = CTX_data_main(C);
        Object *ob= CTX_data_active_object(C);
        Scene *scene= CTX_data_scene(C);
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
+
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        POINT_P; KEY_K;
 
+
        if (RNA_enum_get(op->ptr, "unselected")) {
                LOOP_UNSELECTED_POINTS {
                        point->flag |= PEP_HIDE;
@@ -1908,7 +1941,7 @@ static int hide_exec(bContext *C, wmOperator *op)
                }
        }
 
-       PE_update_selection(bmain, scene, ob, 1);
+       PE_update_selection(depsgraph, scene, ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
 
        return OPERATOR_FINISHED;
@@ -1936,10 +1969,10 @@ void PARTICLE_OT_hide(wmOperatorType *ot)
 
 static int reveal_exec(bContext *C, wmOperator *op)
 {
-       Main *bmain = CTX_data_main(C);
        Object *ob= CTX_data_active_object(C);
        Scene *scene= CTX_data_scene(C);
-       PTCacheEdit *edit = PE_get_current(bmain, scene, ob);
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        const bool select = RNA_boolean_get(op->ptr, "select");
        POINT_P; KEY_K;
 
@@ -1954,7 +1987,7 @@ static int reveal_exec(bContext *C, wmOperator *op)
                }
        }
 
-       PE_update_selection(bmain, scene, ob, 1);
+       PE_update_selection(depsgraph, scene, ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, ob);
 
        return OPERATOR_FINISHED;
@@ -2016,7 +2049,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
        PE_set_data(C, &data);
        foreach_point(&data, select_less_keys);
 
-       PE_update_selection(data.bmain, data.scene, data.ob, 1);
+       PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -2078,7 +2111,7 @@ static int select_more_exec(bContext *C, wmOperator *UNUSED(op))
        PE_set_data(C, &data);
        foreach_point(&data, select_more_keys);
 
-       PE_update_selection(data.bmain, data.scene, data.ob, 1);
+       PE_update_selection(data.depsgraph, data.scene, data.ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_SELECTED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -2114,9 +2147,10 @@ static void rekey_particle(PEData *data, int pa_index)
        float dval, sta, end;
        int k;
 
-       sim.scene= data->scene;
-       sim.ob= data->ob;
-       sim.psys= edit->psys;
+       sim.depsgraph = data->depsgraph;
+       sim.scene = data->scene;
+       sim.ob = data->ob;
+       sim.psys = edit->psys;
 
        pa->flag |= PARS_REKEY;
 
@@ -2175,7 +2209,7 @@ static int rekey_exec(bContext *C, wmOperator *op)
        foreach_selected_point(&data, rekey_particle);
 
        recalc_lengths(data.edit);
-       PE_update_object(data.bmain, data.scene, data.ob, 1);
+       PE_update_object(data.depsgraph, data.scene, data.ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -2200,11 +2234,11 @@ void PARTICLE_OT_rekey(wmOperatorType *ot)
        RNA_def_int(ot->srna, "keys_number", 2, 2, INT_MAX, "Number of Keys", "", 2, 100);
 }
 
-static void rekey_particle_to_time(Main *bmain, Scene *scene, Object *ob, int pa_index, float path_time)
+static void rekey_particle_to_time(const bContext *C, Scene *scene, Object *ob, int pa_index, float path_time)
 {
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        ParticleSystem *psys;
-       ParticleSimulationData sim= {0};
+       ParticleSimulationData sim = {0};
        ParticleData *pa;
        ParticleKey state;
        HairKey *new_keys, *key;
@@ -2215,9 +2249,10 @@ static void rekey_particle_to_time(Main *bmain, Scene *scene, Object *ob, int pa
 
        psys = edit->psys;
 
-       sim.scene= scene;
-       sim.ob= ob;
-       sim.psys= psys;
+       sim.depsgraph = CTX_data_depsgraph(C);
+       sim.scene = scene;
+       sim.ob = ob;
+       sim.psys = psys;
 
        pa= psys->particles + pa_index;
 
@@ -2262,7 +2297,7 @@ static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror)
                psmd= psys_get_modifier(ob, psys);
 
                LOOP_TAGGED_POINTS {
-                       PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL);
+                       PE_mirror_particle(ob, psmd->mesh_final, psys, psys->particles + p, NULL);
                }
        }
 
@@ -2342,7 +2377,7 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys)
 
                LOOP_POINTS {
                        LOOP_TAGGED_KEYS {
-                               PE_mirror_particle(ob, psmd->dm_final, psys, psys->particles + p, NULL);
+                               PE_mirror_particle(ob, psmd->mesh_final, psys, psys->particles + p, NULL);
                                break;
                        }
                }
@@ -2432,9 +2467,10 @@ static void subdivide_particle(PEData *data, int pa_index)
        short totnewkey=0;
        float endtime;
 
-       sim.scene= data->scene;
-       sim.ob= data->ob;
-       sim.psys= edit->psys;
+       sim.depsgraph = data->depsgraph;
+       sim.scene = data->scene;
+       sim.ob = data->ob;
+       sim.psys = edit->psys;
 
        for (k=0, ekey=point->keys; k<pa->totkey-1; k++, ekey++) {
                if (ekey->flag&PEK_SELECT && (ekey+1)->flag&PEK_SELECT)
@@ -2506,7 +2542,7 @@ static int subdivide_exec(bContext *C, wmOperator *UNUSED(op))
        foreach_point(&data, subdivide_particle);
 
        recalc_lengths(data.edit);
-       PE_update_object(data.bmain, data.scene, data.ob, 1);
+       PE_update_object(data.depsgraph, data.scene, data.ob, 1);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -2531,10 +2567,9 @@ void PARTICLE_OT_subdivide(wmOperatorType *ot)
 
 static int remove_doubles_exec(bContext *C, wmOperator *op)
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        Object *ob= CTX_data_active_object(C);
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        ParticleSystem *psys = edit->psys;
        ParticleSystemModifierData *psmd;
        KDTree *tree;
@@ -2557,7 +2592,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
 
                /* insert particles into kd tree */
                LOOP_SELECTED_POINTS {
-                       psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat);
+                       psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat);
                        copy_v3_v3(co, point->keys->co);
                        mul_m4_v3(mat, co);
                        BLI_kdtree_insert(tree, p, co);
@@ -2567,7 +2602,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
 
                /* tag particles to be removed */
                LOOP_SELECTED_POINTS {
-                       psys_mat_hair_to_object(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat);
+                       psys_mat_hair_to_object(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat);
                        copy_v3_v3(co, point->keys->co);
                        mul_m4_v3(mat, co);
 
@@ -2596,7 +2631,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
 
        BKE_reportf(op->reports, RPT_INFO, "Removed %d double particles", totremoved);
 
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
 
        return OPERATOR_FINISHED;
@@ -2624,11 +2659,10 @@ void PARTICLE_OT_remove_doubles(wmOperatorType *ot)
 
 static int weight_set_exec(bContext *C, wmOperator *op)
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        ParticleEditSettings *pset= PE_settings(scene);
        Object *ob= CTX_data_active_object(C);
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        ParticleSystem *psys = edit->psys;
        POINT_P;
        KEY_K;
@@ -2649,7 +2683,7 @@ static int weight_set_exec(bContext *C, wmOperator *op)
                }
        }
 
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
 
        return OPERATOR_FINISHED;
@@ -2681,24 +2715,27 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
        ParticleEditSettings *pset= PE_settings(scene);
        ParticleBrushData *brush;
 
-       if (pset->brushtype < 0)
+       if (pset->brushtype < 0) {
                return;
+       }
 
-       brush= &pset->brush[pset->brushtype];
+       brush = &pset->brush[pset->brushtype];
 
        if (brush) {
-               glPushMatrix();
+               unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+               immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 
-               glTranslatef((float)x, (float)y, 0.0f);
+               immUniformColor4ub(255, 255, 255, 128);
 
-               glColor4ub(255, 255, 255, 128);
                glEnable(GL_LINE_SMOOTH);
                glEnable(GL_BLEND);
-               glutil_draw_lined_arc(0.0, M_PI*2.0, pe_brush_size_get(scene, brush), 40);
+
+               imm_draw_circle_wire_2d(pos, (float)x, (float)y, pe_brush_size_get(scene, brush), 40);
+
                glDisable(GL_BLEND);
                glDisable(GL_LINE_SMOOTH);
 
-               glPopMatrix();
+               immUnbindProgram();
        }
 }
 
@@ -2755,7 +2792,7 @@ static int delete_exec(bContext *C, wmOperator *op)
                recalc_lengths(data.edit);
        }
 
-       DAG_id_tag_update(&data.ob->id, OB_RECALC_DATA);
+       DEG_id_tag_update(&data.ob->id, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob);
 
        return OPERATOR_FINISHED;
@@ -2782,11 +2819,12 @@ void PARTICLE_OT_delete(wmOperatorType *ot)
 
 /*************************** mirror operator **************************/
 
-static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged)
+static void PE_mirror_x(
+        Scene *scene, Object *ob, int tagged)
 {
        Mesh *me= (Mesh *)(ob->data);
        ParticleSystemModifierData *psmd;
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit = PE_get_current(scene, ob);
        ParticleSystem *psys = edit->psys;
        ParticleData *pa, *newpa, *new_pars;
        PTCacheEditPoint *newpoint, *new_points;
@@ -2799,17 +2837,17 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged)
                return;
 
        psmd= psys_get_modifier(ob, psys);
-       if (!psmd->dm_final)
+       if (!psmd->mesh_final)
                return;
 
-       const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly);
+       const bool use_dm_final_indices = (psys->part->use_modifier_stack && !psmd->mesh_final->runtime.deformed_only);
 
        /* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */
        BKE_mesh_tessface_ensure(me);
 
-       /* Note: In case psys uses DM tessface indices, we mirror final DM itself, not orig mesh. Avoids an (impossible)
-        *       dm -> orig -> dm tessface indices conversion... */
-       mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? psmd->dm_final : NULL);
+       /* Note: In case psys uses Mesh tessface indices, we mirror final Mesh itself, not orig mesh. Avoids an (impossible)
+        *       mesh -> orig -> mesh tessface indices conversion... */
+       mirrorfaces = mesh_get_x_mirror_faces__real_mesh(ob, NULL, use_dm_final_indices ? psmd->mesh_final : NULL);
 
        if (!edit->mirror_cache)
                PE_update_mirror_cache(ob, psys);
@@ -2823,7 +2861,7 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged)
                        if (point_is_selected(point)) {
                                if (edit->mirror_cache[p] != -1) {
                                        /* already has a mirror, don't need to duplicate */
-                                       PE_mirror_particle(ob, psmd->dm_final, psys, pa, NULL);
+                                       PE_mirror_particle(ob, psmd->mesh_final, psys, pa, NULL);
                                        continue;
                                }
                                else
@@ -2836,7 +2874,7 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged)
        }
 
        if (newtotpart != psys->totpart) {
-               MFace *mtessface = use_dm_final_indices ? psmd->dm_final->getTessFaceArray(psmd->dm_final) : me->mface;
+               MFace *mtessface = use_dm_final_indices ? psmd->mesh_final->mface : me->mface;
 
                /* allocate new arrays and copy existing */
                new_pars= MEM_callocN(newtotpart*sizeof(ParticleData), "ParticleData new");
@@ -2905,7 +2943,7 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged)
                        }
                        else {
                                newpa->num_dmcache = psys_particle_dm_face_lookup(
-                                                        psmd->dm_final, psmd->dm_deformed, newpa->num, newpa->fuv, NULL);
+                                                        psmd->mesh_final, psmd->mesh_original, newpa->num, newpa->fuv, NULL);
                        }
 
                        /* update edit key pointers */
@@ -2916,7 +2954,7 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged)
                        }
 
                        /* map key positions as mirror over x axis */
-                       PE_mirror_particle(ob, psmd->dm_final, psys, pa, newpa);
+                       PE_mirror_particle(ob, psmd->mesh_final, psys, pa, newpa);
 
                        newpa++;
                        newpoint++;
@@ -2932,16 +2970,15 @@ static void PE_mirror_x(Main *bmain, Scene *scene, Object *ob, int tagged)
 
 static int mirror_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
        Object *ob= CTX_data_active_object(C);
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
 
-       PE_mirror_x(bmain, scene, ob, 0);
+       PE_mirror_x(scene, ob, 0);
 
-       update_world_cos(ob, edit);
+       update_world_cos(CTX_data_depsgraph(C), ob, edit);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
 
        return OPERATOR_FINISHED;
 }
@@ -3074,7 +3111,7 @@ static void brush_cut(PEData *data, int pa_index)
                        edit->points[pa_index].flag |= PEP_TAG;
                }
                else {
-                       rekey_particle_to_time(data->bmain, data->scene, ob, pa_index, cut_time);
+                       rekey_particle_to_time(data->context, data->scene, ob, pa_index, cut_time);
                        edit->points[pa_index].flag |= PEP_EDIT_RECALC;
                }
        }
@@ -3127,7 +3164,7 @@ static void brush_puff(PEData *data, int point_index)
        }
 
        if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
-               psys_mat_hair_to_global(data->ob, data->dm, psys->part->from, psys->particles + point_index, mat);
+               psys_mat_hair_to_global(data->ob, data->mesh, psys->part->from, psys->particles + point_index, mat);
                invert_m4_m4(imat, mat);
        }
        else {
@@ -3322,34 +3359,39 @@ static void intersect_dm_quad_weights(const float v1[3], const float v2[3], cons
 }
 
 /* check intersection with a derivedmesh */
-static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm,
+static int particle_intersect_mesh(const bContext *C, Scene *scene, Object *ob, Mesh *mesh,
                                  float *vert_cos,
                                  const float co1[3], const float co2[3],
                                  float *min_d, int *min_face, float *min_w,
                                  float *face_minmax, float *pa_minmax,
                                  float radius, float *ipoint)
 {
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        MFace *mface= NULL;
        MVert *mvert= NULL;
        int i, totface, intersect=0;
        float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3], p_max[3];
        float cur_ipoint[3];
 
-       if (dm == NULL) {
+       if (mesh == NULL) {
                psys_disable_all(ob);
 
-               dm=mesh_get_derived_final(scene, ob, 0);
+               /* TODO(Sybren): port to Mesh when we have decided how to handle derivedFinal and derivedDeform */
+               DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, 0);
                if (dm == NULL)
-                       dm=mesh_get_derived_deform(scene, ob, 0);
+                       dm = mesh_get_derived_deform(depsgraph, scene, ob, 0);
 
                psys_enable_all(ob);
 
                if (dm == NULL)
                        return 0;
+
+               mesh = BKE_id_new_nomain(ID_ME, NULL);
+               DM_to_mesh(dm, mesh, ob, CD_MASK_EVERYTHING, false);
        }
 
        /* BMESH_ONLY, deform dm may not have tessface */
-       DM_ensure_tessface(dm);
+       BKE_mesh_tessface_ensure(mesh);
 
 
        if (pa_minmax==0) {
@@ -3362,9 +3404,9 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm,
                copy_v3_v3(p_max, pa_minmax+3);
        }
 
-       totface=dm->getNumTessFaces(dm);
-       mface=dm->getTessFaceDataArray(dm, CD_MFACE);
-       mvert=dm->getVertDataArray(dm, CD_MVERT);
+       totface = mesh->totface;
+       mface = mesh->mface;
+       mvert = mesh->mvert;
 
        /* lets intersect the faces */
        for (i=0; i<totface; i++, mface++) {
@@ -3453,11 +3495,12 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm,
        return intersect;
 }
 
-static int brush_add(PEData *data, short number)
+static int brush_add(const bContext *C, PEData *data, short number)
 {
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene= data->scene;
        Object *ob= data->ob;
-       DerivedMesh *dm;
+       Mesh *mesh;
        PTCacheEdit *edit = data->edit;
        ParticleSystem *psys= edit->psys;
        ParticleData *add_pars;
@@ -3482,6 +3525,7 @@ static int brush_add(PEData *data, short number)
 
        rng = BLI_rng_new_srandom(psys->seed+data->mval[0]+data->mval[1]);
 
+       sim.depsgraph = depsgraph;
        sim.scene= scene;
        sim.ob= ob;
        sim.psys= psys;
@@ -3489,13 +3533,13 @@ static int brush_add(PEData *data, short number)
 
        timestep= psys_get_timestep(&sim);
 
-       if (psys->part->use_modifier_stack || psmd->dm_final->deformedOnly) {
-               dm = psmd->dm_final;
+       if (psys->part->use_modifier_stack || psmd->mesh_final->runtime.deformed_only) {
+               mesh = psmd->mesh_final;
        }
        else {
-               dm = psmd->dm_deformed;
+               mesh = psmd->mesh_original;
        }
-       BLI_assert(dm);
+       BLI_assert(mesh);
 
        for (i=0; i<number; i++) {
                if (number>1) {
@@ -3515,23 +3559,23 @@ static int brush_add(PEData *data, short number)
 
                mco[0] = data->mval[0] + dmx;
                mco[1] = data->mval[1] + dmy;
-               ED_view3d_win_to_segment(data->vc.ar, data->vc.v3d, mco, co1, co2, true);
+               ED_view3d_win_to_segment(depsgraph, data->vc.ar, data->vc.v3d, mco, co1, co2, true);
 
                mul_m4_v3(imat, co1);
                mul_m4_v3(imat, co2);
                min_d=2.0;
 
                /* warning, returns the derived mesh face */
-               if (particle_intersect_dm(scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) {
-                       if (psys->part->use_modifier_stack && !psmd->dm_final->deformedOnly) {
+               if (particle_intersect_mesh(C, scene, ob, mesh, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) {
+                       if (psys->part->use_modifier_stack && !psmd->mesh_final->runtime.deformed_only) {
                                add_pars[n].num = add_pars[n].num_dmcache;
                                add_pars[n].num_dmcache = DMCACHE_ISCHILD;
                        }
-                       else if (dm == psmd->dm_deformed) {
+                       else if (mesh == psmd->mesh_original) {
                                /* Final DM is not same topology as orig mesh, we have to map num_dmcache to real final dm. */
                                add_pars[n].num = add_pars[n].num_dmcache;
                                add_pars[n].num_dmcache = psys_particle_dm_face_lookup(
-                                                             psmd->dm_final, psmd->dm_deformed,
+                                                             psmd->mesh_final, psmd->mesh_original,
                                                              add_pars[n].num, add_pars[n].fuv, NULL);
                        }
                        else {
@@ -3573,7 +3617,7 @@ static int brush_add(PEData *data, short number)
                        tree=BLI_kdtree_new(psys->totpart);
 
                        for (i=0, pa=psys->particles; i<totpart; i++, pa++) {
-                               psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0, 0);
+                               psys_particle_on_dm(psmd->mesh_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, cur_co, 0, 0, 0, 0);
                                BLI_kdtree_insert(tree, i, cur_co);
                        }
 
@@ -3617,7 +3661,7 @@ static int brush_add(PEData *data, short number)
                                int w, maxw;
                                float maxd, totw=0.0, weight[3];
 
-                               psys_particle_on_dm(psmd->dm_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0, 0);
+                               psys_particle_on_dm(psmd->mesh_final, psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co1, 0, 0, 0, 0);
                                maxw = BLI_kdtree_find_nearest_n(tree, co1, ptn, 3);
 
                                maxd= ptn[maxw-1].dist;
@@ -3682,7 +3726,7 @@ static int brush_add(PEData *data, short number)
                                }
                        }
                        for (k=0, hkey=pa->hair; k<pset->totaddkey; k++, hkey++) {
-                               psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat);
+                               psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat);
                                invert_m4_m4(imat, hairmat);
                                mul_m4_v3(imat, hkey->co);
                        }
@@ -3703,6 +3747,7 @@ static int brush_add(PEData *data, short number)
 
 typedef struct BrushEdit {
        Scene *scene;
+       ViewLayer *view_layer;
        Object *ob;
        PTCacheEdit *edit;
 
@@ -3716,11 +3761,11 @@ typedef struct BrushEdit {
 
 static int brush_edit_init(bContext *C, wmOperator *op)
 {
-       Main *bmain = CTX_data_main(C);
        Scene *scene= CTX_data_scene(C);
+       ViewLayer *view_layer = CTX_data_view_layer(C);
        Object *ob= CTX_data_active_object(C);
        ParticleEditSettings *pset= PE_settings(scene);
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        ARegion *ar= CTX_wm_region(C);
        BrushEdit *bedit;
        float min[3], max[3];
@@ -3730,7 +3775,7 @@ static int brush_edit_init(bContext *C, wmOperator *op)
 
        /* set the 'distance factor' for grabbing (used in comb etc) */
        INIT_MINMAX(min, max);
-       PE_minmax(bmain, scene, min, max);
+       PE_minmax(scene, view_layer, min, max);
        mid_v3_v3v3(min, min, max);
 
        bedit= MEM_callocN(sizeof(BrushEdit), "BrushEdit");
@@ -3738,6 +3783,7 @@ static int brush_edit_init(bContext *C, wmOperator *op)
        op->customdata= bedit;
 
        bedit->scene= scene;
+       bedit->view_layer = view_layer;
        bedit->ob= ob;
        bedit->edit= edit;
 
@@ -3753,6 +3799,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
 {
        Main *bmain = CTX_data_main(C);
        BrushEdit *bedit= op->customdata;
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene= bedit->scene;
        Object *ob= bedit->ob;
        PTCacheEdit *edit= bedit->edit;
@@ -3794,6 +3841,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
             (sqrtf(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0)) || bedit->first)
        {
                PEData data= bedit->data;
+               data.context = C; // TODO(mai): why isnt this set in bedit->data?
 
                view3d_operator_needs_opengl(C);
                selected= (short)count_selected_keys(scene, edit);
@@ -3871,7 +3919,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
                                case PE_BRUSH_PUFF:
                                {
                                        if (edit->psys) {
-                                               data.dm= psmd->dm_final;
+                                               data.mesh = psmd->mesh_final;
                                                data.mval= mval;
                                                data.rad= pe_brush_size_get(scene, brush);
                                                data.select= selected;
@@ -3894,7 +3942,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
                                        if (edit->psys && edit->psys->part->from==PART_FROM_FACE) {
                                                data.mval= mval;
 
-                                               added= brush_add(&data, brush->count);
+                                               added= brush_add(C, &data, brush->count);
 
                                                if (pset->flag & PE_KEEP_LENGTHS)
                                                        recalc_lengths(edit);
@@ -3927,7 +3975,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
                                case PE_BRUSH_WEIGHT:
                                {
                                        if (edit->psys) {
-                                               data.dm= psmd->dm_final;
+                                               data.mesh = psmd->mesh_final;
                                                data.mval= mval;
                                                data.rad= pe_brush_size_get(scene, brush);
 
@@ -3944,21 +3992,24 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
 
                        if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_CUT) && (added || removed)) {
                                if (pset->brushtype == PE_BRUSH_ADD && pe_x_mirror(ob))
-                                       PE_mirror_x(bmain, scene, ob, 1);
+                                       PE_mirror_x(scene, ob, 1);
 
-                               update_world_cos(ob, edit);
+                               update_world_cos(depsgraph, ob, edit);
                                psys_free_path_cache(NULL, edit);
-                               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+                               DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+                       }
+                       else {
+                               PE_update_object(depsgraph, scene, ob, 1);
                        }
-                       else
-                               PE_update_object(bmain, scene, ob, 1);
                }
 
                if (edit->psys) {
                        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
+                       BKE_particle_batch_cache_dirty(edit->psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
+                       DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
                }
                else {
-                       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+                       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                        WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
                }
 
@@ -4166,7 +4217,7 @@ static void shape_cut(PEData *data, int pa_index)
                        edit->points[pa_index].flag |= PEP_TAG;
                }
                else {
-                       rekey_particle_to_time(data->bmain, data->scene, ob, pa_index, cut_time);
+                       rekey_particle_to_time(data->context, data->scene, ob, pa_index, cut_time);
                        edit->points[pa_index].flag |= PEP_EDIT_RECALC;
                }
        }
@@ -4174,11 +4225,11 @@ static void shape_cut(PEData *data, int pa_index)
 
 static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Main *bmain = CTX_data_main(C);
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
        ParticleEditSettings *pset = PE_settings(scene);
-       PTCacheEdit *edit = PE_get_current(bmain, scene, ob);
+       PTCacheEdit *edit = PE_get_current(scene, ob);
        Object *shapeob = pset->shape_object;
        int selected = count_selected_keys(scene, edit);
        int lock_root = pset->flag & PE_LOCK_FIRST;
@@ -4209,18 +4260,21 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
                recalc_lengths(edit);
 
                if (removed) {
-                       update_world_cos(ob, edit);
+                       update_world_cos(depsgraph, ob, edit);
                        psys_free_path_cache(NULL, edit);
-                       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+                       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+               }
+               else {
+                       PE_update_object(data.depsgraph, scene, ob, 1);
                }
-               else
-                       PE_update_object(bmain, scene, ob, 1);
 
                if (edit->psys) {
                        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
+                       BKE_particle_batch_cache_dirty(edit->psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
+                       DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
                }
                else {
-                       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+                       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                        WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
                }
 
@@ -4249,10 +4303,10 @@ void PARTICLE_OT_shape_cut(wmOperatorType *ot)
 
 /************************ utilities ******************************/
 
-int PE_minmax(Main *bmain, Scene *scene, float min[3], float max[3])
+int PE_minmax(Scene *scene, ViewLayer *view_layer, float min[3], float max[3])
 {
-       Object *ob= OBACT;
-       PTCacheEdit *edit= PE_get_current(bmain, scene, ob);
+       Object *ob= OBACT(view_layer);
+       PTCacheEdit *edit= PE_get_current(scene, ob);
        ParticleSystem *psys;
        ParticleSystemModifierData *psmd = NULL;
        POINT_P; KEY_K;
@@ -4268,7 +4322,7 @@ int PE_minmax(Main *bmain, Scene *scene, float min[3], float max[3])
 
        LOOP_VISIBLE_POINTS {
                if (psys)
-                       psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles+p, mat);
+                       psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, psys->particles+p, mat);
 
                LOOP_SELECTED_KEYS {
                        copy_v3_v3(co, key->co);
@@ -4289,7 +4343,8 @@ int PE_minmax(Main *bmain, Scene *scene, float min[3], float max[3])
 /************************ particle edit toggle operator ************************/
 
 /* initialize needed data for bake edit */
-void PE_create_particle_edit(Main *bmain, Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys)
+void PE_create_particle_edit(
+        Depsgraph *depsgraph, Scene *scene, Object *ob, PointCache *cache, ParticleSystem *psys)
 {
        PTCacheEdit *edit;
        ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL;
@@ -4299,7 +4354,7 @@ void PE_create_particle_edit(Main *bmain, Scene *scene, Object *ob, PointCache *
        int totpoint;
 
        /* no psmd->dm happens in case particle system modifier is not enabled */
-       if (!(psys && psmd && psmd->dm_final) && !cache)
+       if (!(psys && psmd && psmd->mesh_final) && !cache)
                return;
 
        if (cache && cache->flag & PTCACHE_DISK_CACHE)
@@ -4346,7 +4401,7 @@ void PE_create_particle_edit(Main *bmain, Scene *scene, Object *ob, PointCache *
                                }
                                pa++;
                        }
-                       update_world_cos(ob, edit);
+                       update_world_cos(depsgraph, ob, edit);
                }
                else {
                        PTCacheMem *pm;
@@ -4389,8 +4444,9 @@ void PE_create_particle_edit(Main *bmain, Scene *scene, Object *ob, PointCache *
 
                recalc_lengths(edit);
                if (psys && !cache)
-                       recalc_emitter_field(ob, psys);
-               PE_update_object(bmain, scene, ob, 1);
+                       recalc_emitter_field(depsgraph, ob, psys);
+
+               PE_update_object(depsgraph, scene, ob, 1);
        }
 }
 
@@ -4412,7 +4468,8 @@ static int particle_edit_toggle_poll(bContext *C)
 
 static int particle_edit_toggle_exec(bContext *C, wmOperator *op)
 {
-       Main *bmain = CTX_data_main(C);
+       struct wmMsgBus *mbus = CTX_wm_message_bus(C);
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
        const int mode_flag = OB_MODE_PARTICLE_EDIT;
@@ -4426,13 +4483,23 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op)
 
        if (!is_mode_set) {
                PTCacheEdit *edit;
+
+               /* Particle edit mode requires original object to have all strands
+                * cached. A bit annoying to do update here, but is simpler than
+                * rewriting the while edit mode code.
+                */
+               ob->id.recalc |= (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+               BKE_scene_graph_update_tagged(depsgraph, CTX_data_main(C));
+               BKE_object_eval_transform_all(depsgraph, scene, ob);
+               BKE_object_handle_data_update(depsgraph, scene, ob);
                ob->mode |= mode_flag;
-               edit= PE_create_current(bmain, scene, ob);
+
+               edit= PE_create_current(depsgraph, scene, ob);
 
                /* mesh may have changed since last entering editmode.
                 * note, this may have run before if the edit data was just created, so could avoid this and speed up a little */
                if (edit && edit->psys)
-                       recalc_emitter_field(ob, edit->psys);
+                       recalc_emitter_field(depsgraph, ob, edit->psys);
 
                toggle_particle_cursor(C, 1);
                WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_PARTICLE, NULL);
@@ -4443,7 +4510,13 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op)
                WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
        }
 
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       // ED_workspace_object_mode_sync_from_object(wm, workspace, ob);
+
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA | DEG_TAG_COPY_ON_WRITE);
+
+       WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
+
+       WM_toolsystem_update_from_context_view3d(C);
 
        return OPERATOR_FINISHED;
 }
@@ -4484,7 +4557,7 @@ static int clear_edited_exec(bContext *C, wmOperator *UNUSED(op))
 
                        psys_reset(psys, PSYS_RESET_DEPSGRAPH);
                        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
-                       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+                       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                }
        }
        else { /* some operation might have protected hair from editing so let's clear the flag */
@@ -4492,7 +4565,7 @@ static int clear_edited_exec(bContext *C, wmOperator *UNUSED(op))
                psys->flag &= ~PSYS_GLOBAL_HAIR;
                psys->flag &= ~PSYS_EDITED;
                WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
-               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+               DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
        }
 
        return OPERATOR_FINISHED;
@@ -4593,22 +4666,24 @@ static void scale_points_to_length(PTCacheEdit *edit, float length)
 
 static int unify_length_exec(bContext *C, wmOperator *UNUSED(op))
 {
-       Main *bmain = CTX_data_main(C);
        Object *ob = CTX_data_active_object(C);
        Scene *scene = CTX_data_scene(C);
-       PTCacheEdit *edit = PE_get_current(bmain, scene, ob);
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
+
+       PTCacheEdit *edit = PE_get_current(scene, ob);
        float average_length = calculate_average_length(edit);
+
        if (average_length == 0.0f) {
                return OPERATOR_CANCELLED;
        }
        scale_points_to_length(edit, average_length);
 
-       PE_update_object(bmain, scene, ob, 1);
+       PE_update_object(depsgraph, scene, ob, 1);
        if (edit->psys) {
                WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
        }
        else {
-               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+               DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
        }