Merge branch 'master' into blender2.8
authorCampbell Barton <ideasman42@gmail.com>
Mon, 19 Feb 2018 06:46:42 +0000 (17:46 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 19 Feb 2018 06:46:42 +0000 (17:46 +1100)
1  2 
source/blender/blenkernel/intern/scene.c
source/blender/bmesh/intern/bmesh_mesh_conv.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/editmesh_utils.c
source/blender/python/bmesh/bmesh_py_types.c

index 932f80c35d523c1858461cb32693626fb24f589f,423ed2af057ad698dd211b4d7216d54ca3afb9d7..899a911270f0383cd2fb8fbc671f91f4a7f552fa
@@@ -49,7 -49,6 +49,7 @@@
  #include "DNA_space_types.h"
  #include "DNA_view3d_types.h"
  #include "DNA_windowmanager_types.h"
 +#include "DNA_workspace_types.h"
  #include "DNA_gpencil_types.h"
  
  #include "BLI_math.h"
@@@ -68,8 -67,8 +68,8 @@@
  #include "BKE_action.h"
  #include "BKE_armature.h"
  #include "BKE_cachefile.h"
 +#include "BKE_collection.h"
  #include "BKE_colortools.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_editmesh.h"
  #include "BKE_fcurve.h"
  #include "BKE_freestyle.h"
@@@ -79,7 -78,6 +79,7 @@@
  #include "BKE_icons.h"
  #include "BKE_idprop.h"
  #include "BKE_image.h"
 +#include "BKE_layer.h"
  #include "BKE_library.h"
  #include "BKE_library_remap.h"
  #include "BKE_linestyle.h"
  #include "BKE_sequencer.h"
  #include "BKE_sound.h"
  #include "BKE_unit.h"
 +#include "BKE_workspace.h"
  #include "BKE_world.h"
  
  #include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_build.h"
 +#include "DEG_depsgraph_debug.h"
 +#include "DEG_depsgraph_query.h"
  
  #include "RE_engine.h"
  
  
  const char *RE_engine_id_BLENDER_RENDER = "BLENDER_RENDER";
  const char *RE_engine_id_BLENDER_GAME = "BLENDER_GAME";
 +const char *RE_engine_id_BLENDER_CLAY = "BLENDER_CLAY";
 +const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
  const char *RE_engine_id_CYCLES = "CYCLES";
  
  void free_avicodecdata(AviCodecData *acd)
@@@ -165,36 -157,25 +165,36 @@@ void BKE_scene_copy_data(Main *bmain, S
        const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
  
        sce_dst->ed = NULL;
 -      sce_dst->theDag = NULL;
 -      sce_dst->depsgraph = NULL;
 -      sce_dst->obedit = NULL;
 -      sce_dst->stats = NULL;
 +      sce_dst->depsgraph_hash = NULL;
        sce_dst->fps_info = NULL;
  
 -      BLI_duplicatelist(&(sce_dst->base), &(sce_src->base));
 -      for (Base *base_dst = sce_dst->base.first, *base_src = sce_src->base.first;
 -           base_dst;
 -           base_dst = base_dst->next, base_src = base_src->next)
 +      /* layers and collections */
 +      sce_dst->collection = MEM_dupallocN(sce_src->collection);
 +      SceneCollection *mc_src = BKE_collection_master(&sce_src->id);
 +      SceneCollection *mc_dst = BKE_collection_master(&sce_dst->id);
 +
 +      /* Recursively creates a new SceneCollection tree. */
 +      BKE_collection_copy_data(mc_dst, mc_src, flag_subdata);
 +
 +      IDPropertyTemplate val = {0};
 +      BLI_duplicatelist(&sce_dst->view_layers, &sce_src->view_layers);
 +      for (ViewLayer *view_layer_src = sce_src->view_layers.first, *view_layer_dst = sce_dst->view_layers.first;
 +           view_layer_src;
 +           view_layer_src = view_layer_src->next, view_layer_dst = view_layer_dst->next)
        {
 -              if (base_src == sce_src->basact) {
 -                      sce_dst->basact = base_dst;
 -              }
 +              BKE_view_layer_copy_data(view_layer_dst, view_layer_src, mc_dst, mc_src, flag_subdata);
 +      }
 +
 +      sce_dst->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
 +      if (sce_src->collection_properties) {
 +              IDP_MergeGroup_ex(sce_dst->collection_properties, sce_src->collection_properties, true, flag_subdata);
 +      }
 +      sce_dst->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
 +      if (sce_src->layer_properties) {
 +              IDP_MergeGroup_ex(sce_dst->layer_properties, sce_src->layer_properties, true, flag_subdata);
        }
  
        BLI_duplicatelist(&(sce_dst->markers), &(sce_src->markers));
 -      BLI_duplicatelist(&(sce_dst->transform_spaces), &(sce_src->transform_spaces));
 -      BLI_duplicatelist(&(sce_dst->r.layers), &(sce_src->r.layers));
        BLI_duplicatelist(&(sce_dst->r.views), &(sce_src->r.views));
        BKE_keyingsets_copy(&(sce_dst->keyingsets), &(sce_src->keyingsets));
  
                sce_dst->rigidbody_world = BKE_rigidbody_world_copy(sce_src->rigidbody_world, flag_subdata);
        }
  
 -      /* copy Freestyle settings */
 -      for (SceneRenderLayer *srl_dst = sce_dst->r.layers.first, *srl_src = sce_src->r.layers.first;
 -           srl_src;
 -           srl_dst = srl_dst->next, srl_src = srl_src->next)
 -      {
 -              if (srl_dst->prop != NULL) {
 -                      srl_dst->prop = IDP_CopyProperty_ex(srl_dst->prop, flag_subdata);
 -              }
 -              BKE_freestyle_config_copy(&srl_dst->freestyleConfig, &srl_src->freestyleConfig, flag_subdata);
 -      }
 -
        /* copy color management settings */
        BKE_color_managed_display_settings_copy(&sce_dst->display_settings, &sce_src->display_settings);
        BKE_color_managed_view_settings_copy(&sce_dst->view_settings, &sce_src->view_settings);
@@@ -297,14 -289,16 +297,14 @@@ Scene *BKE_scene_copy(Main *bmain, Scen
         * But for now, let's keep it well isolated here. */
        if (type == SCE_COPY_EMPTY) {
                ToolSettings *ts;
 -              ListBase rl, rv;
 +              ListBase rv;
  
                sce_copy = BKE_scene_add(bmain, sce->id.name + 2);
  
 -              rl = sce_copy->r.layers;
                rv = sce_copy->r.views;
                curvemapping_free_data(&sce_copy->r.mblur_shutter_curve);
                sce_copy->r = sce->r;
 -              sce_copy->r.layers = rl;
 -              sce_copy->r.actlay = 0;
 +              sce_copy->active_view_layer = 0;
                sce_copy->r.views = rv;
                sce_copy->unit = sce->unit;
                sce_copy->physics_settings = sce->physics_settings;
  
                if (type == SCE_COPY_FULL) {
                        /* Copy Freestyle LineStyle datablocks. */
 -                      for (SceneRenderLayer *srl_dst = sce_copy->r.layers.first; srl_dst; srl_dst = srl_dst->next) {
 -                              for (FreestyleLineSet *lineset = srl_dst->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
 +                      for (ViewLayer *view_layer_dst = sce_copy->view_layers.first; view_layer_dst; view_layer_dst = view_layer_dst->next) {
 +                              for (FreestyleLineSet *lineset = view_layer_dst->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
                                        if (lineset->linestyle) {
                                                /* XXX Not copying anim/actions here? */
                                                BKE_id_copy_ex(bmain, (ID *)lineset->linestyle, (ID **)&lineset->linestyle, 0, false);
@@@ -455,13 -449,17 +455,13 @@@ void BKE_scene_make_local(Main *bmain, 
  }
  
  /** Free (or release) any data used by this scene (does not free the scene itself). */
 -void BKE_scene_free(Scene *sce)
 +void BKE_scene_free_ex(Scene *sce, const bool do_id_user)
  {
 -      SceneRenderLayer *srl;
 -
        BKE_animdata_free((ID *)sce, false);
  
        /* check all sequences */
        BKE_sequencer_clear_scene_in_allseqs(G.main, sce);
  
 -      sce->basact = NULL;
 -      BLI_freelistN(&sce->base);
        BKE_sequencer_editing_free(sce);
  
        BKE_keyingsets_free(&sce->keyingsets);
                sce->r.ffcodecdata.properties = NULL;
        }
  
 -      for (srl = sce->r.layers.first; srl; srl = srl->next) {
 -              if (srl->prop != NULL) {
 -                      IDP_FreeProperty(srl->prop);
 -                      MEM_freeN(srl->prop);
 -              }
 -              BKE_freestyle_config_free(&srl->freestyleConfig);
 -      }
 -
        BLI_freelistN(&sce->markers);
 -      BLI_freelistN(&sce->transform_spaces);
 -      BLI_freelistN(&sce->r.layers);
        BLI_freelistN(&sce->r.views);
        
        if (sce->toolsettings) {
                sce->toolsettings = NULL;
        }
        
 -      DAG_scene_free(sce);
 -      if (sce->depsgraph)
 -              DEG_graph_free(sce->depsgraph);
 -      
 -      MEM_SAFE_FREE(sce->stats);
 +      BKE_scene_free_depsgraph_hash(sce);
 +
        MEM_SAFE_FREE(sce->fps_info);
  
        BKE_sound_destroy_scene(sce);
  
        BKE_previewimg_free(&sce->preview);
        curvemapping_free_data(&sce->r.mblur_shutter_curve);
 +
 +      for (ViewLayer *view_layer = sce->view_layers.first, *view_layer_next; view_layer; view_layer = view_layer_next) {
 +              view_layer_next = view_layer->next;
 +
 +              BLI_remlink(&sce->view_layers, view_layer);
 +              BKE_view_layer_free_ex(view_layer, do_id_user);
 +      }
 +
 +      /* Master Collection */
 +      BKE_collection_master_free(&sce->id, do_id_user);
 +      MEM_freeN(sce->collection);
 +      sce->collection = NULL;
 +
 +      /* LayerCollection engine settings. */
 +      if (sce->collection_properties) {
 +              IDP_FreeProperty(sce->collection_properties);
 +              MEM_freeN(sce->collection_properties);
 +              sce->collection_properties = NULL;
 +      }
 +
 +      /* Render engine setting. */
 +      if (sce->layer_properties) {
 +              IDP_FreeProperty(sce->layer_properties);
 +              MEM_freeN(sce->layer_properties);
 +              sce->layer_properties = NULL;
 +      }
 +}
 +
 +void BKE_scene_free(Scene *sce)
 +{
 +      BKE_scene_free_ex(sce, true);
  }
  
  void BKE_scene_init(Scene *sce)
         */
        sce->r.color_mgt_flag |= R_COLOR_MANAGEMENT;
  
 -      sce->r.gauss = 1.0;
 +      sce->r.gauss = 1.5f;
        
        /* deprecated but keep for upwards compat */
        sce->r.postgamma = 1.0;
        sce->r.ffcodecdata.audio_bitrate = 192;
        sce->r.ffcodecdata.audio_channels = 2;
  
 -      BLI_strncpy(sce->r.engine, RE_engine_id_BLENDER_RENDER, sizeof(sce->r.engine));
 +      BKE_viewrender_init(&sce->view_render);
  
        sce->audio.distance_model = 2.0f;
        sce->audio.doppler_factor = 1.0f;
        sce->r.osa = 8;
  
        /* note; in header_info.c the scene copy happens..., if you add more to renderdata it has to be checked there */
 -      BKE_scene_add_render_layer(sce, NULL);
  
        /* multiview - stereo */
        BKE_scene_add_render_view(sce, STEREO_LEFT_NAME);
        sce->gm.angulardeactthreshold = 1.0f;
        sce->gm.deactivationtime = 0.0f;
  
 -      sce->gm.flag = GAME_DISPLAY_LISTS;
 +      sce->gm.flag = 0;
        sce->gm.matmode = GAME_MAT_MULTITEX;
  
        sce->gm.obstacleSimulation = OBSTSIMULATION_NONE;
        sce->toolsettings->gpencil_v2d_align = GP_PROJECT_VIEWSPACE;
        sce->toolsettings->gpencil_seq_align = GP_PROJECT_VIEWSPACE;
        sce->toolsettings->gpencil_ima_align = GP_PROJECT_VIEWSPACE;
 +
 +      /* Master Collection */
 +      sce->collection = MEM_callocN(sizeof(SceneCollection), "Master Collection");
 +      BLI_strncpy(sce->collection->name, "Master Collection", sizeof(sce->collection->name));
 +
 +      /* Engine settings */
 +      IDPropertyTemplate val = {0};
 +      sce->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
 +      BKE_layer_collection_engine_settings_create(sce->collection_properties);
 +
 +      sce->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
 +      BKE_view_layer_engine_settings_create(sce->layer_properties);
 +
 +      BKE_view_layer_add(sce, "View Layer");
  }
  
  Scene *BKE_scene_add(Main *bmain, const char *name)
        return sce;
  }
  
 -Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
 +/**
 + * Check if there is any intance of the object in the scene
 + */
 +bool BKE_scene_object_find(Scene *scene, Object *ob)
  {
 -      Base *base;
 -
 -      for (base = scene->base.first; base; base = base->next) {
 -              if (STREQ(base->object->id.name + 2, name)) {
 -                      break;
 +      for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
 +              if (BLI_findptr(&view_layer->object_bases, ob, offsetof(Base, object))) {
 +                  return true;
                }
        }
 -
 -      return base;
 +      return false;
  }
  
 -Base *BKE_scene_base_find(Scene *scene, Object *ob)
 +Object *BKE_scene_object_find_by_name(Scene *scene, const char *name)
  {
 -      return BLI_findptr(&scene->base, ob, offsetof(Base, object));
 +      for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
 +              for (Base *base = view_layer->object_bases.first; base; base = base->next) {
 +                      if (STREQ(base->object->id.name + 2, name)) {
 +                              return base->object;
 +                      }
 +              }
 +      }
 +      return NULL;
  }
  
  /**
   * Sets the active scene, mainly used when running in background mode (``--scene`` command line argument).
   * This is also called to set the scene directly, bypassing windowing code.
 - * Otherwise #ED_screen_set_scene is used when changing scenes by the user.
 + * Otherwise #WM_window_change_active_scene is used when changing scenes by the user.
   */
  void BKE_scene_set_background(Main *bmain, Scene *scene)
  {
 -      Scene *sce;
 -      Base *base;
        Object *ob;
        Group *group;
 -      GroupObject *go;
 -      int flag;
        
        /* check for cyclic sets, for reading old files but also for definite security (py?) */
        BKE_scene_validate_setscene(bmain, scene);
        
 -      /* can happen when switching modes in other scenes */
 -      if (scene->obedit && !(scene->obedit->mode & OB_MODE_EDIT))
 -              scene->obedit = NULL;
 -
        /* deselect objects (for dataselect) */
        for (ob = bmain->object.first; ob; ob = ob->id.next)
                ob->flag &= ~(SELECT | OB_FROMGROUP);
  
        /* group flags again */
        for (group = bmain->group.first; group; group = group->id.next) {
 -              for (go = group->gobject.first; go; go = go->next) {
 -                      if (go->ob) {
 -                              go->ob->flag |= OB_FROMGROUP;
 -                      }
 +              FOREACH_GROUP_OBJECT(group, object)
 +              {
 +                      object->flag |= OB_FROMGROUP;
                }
 +              FOREACH_GROUP_OBJECT_END
        }
  
 -      /* sort baselist for scene and sets */
 -      for (sce = scene; sce; sce = sce->set)
 -              DAG_scene_relations_rebuild(bmain, sce);
 -
        /* copy layers and flags from bases to objects */
 -      for (base = scene->base.first; base; base = base->next) {
 -              ob = base->object;
 -              ob->lay = base->lay;
 -              
 -              /* group patch... */
 -              base->flag &= ~(OB_FROMGROUP);
 -              flag = ob->flag & (OB_FROMGROUP);
 -              base->flag |= flag;
 -              
 -              /* not too nice... for recovering objects with lost data */
 -              //if (ob->pose == NULL) base->flag &= ~OB_POSEMODE;
 -              ob->flag = base->flag;
 +      for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
 +              for (Base *base = view_layer->object_bases.first; base; base = base->next) {
 +                      ob = base->object;
 +                      /* group patch... */
 +                      BKE_scene_object_base_flag_sync_from_base(base);
 +              }
        }
        /* no full animation update, this to enable render code to work (render code calls own animation updates) */
  }
@@@ -1020,9 -998,8 +1020,9 @@@ Scene *BKE_scene_set_name(Main *bmain, 
  }
  
  /* Used by metaballs, return *all* objects (including duplis) existing in the scene (including scene's sets) */
 -int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
 -                             Scene **scene, int val, Base **base, Object **ob)
 +int BKE_scene_base_iter_next(
 +        const EvaluationContext *eval_ctx, SceneBaseIter *iter,
 +        Scene **scene, int val, Base **base, Object **ob)
  {
        bool run_again = true;
        
  
                        /* the first base */
                        if (iter->phase == F_START) {
 -                              *base = (*scene)->base.first;
 +                              ViewLayer *view_layer = eval_ctx->view_layer;
 +                              *base = view_layer->object_bases.first;
                                if (*base) {
                                        *ob = (*base)->object;
                                        iter->phase = F_SCENE;
                                }
                                else {
 -                                      /* exception: empty scene */
 +                                      /* exception: empty scene layer */
                                        while ((*scene)->set) {
                                                (*scene) = (*scene)->set;
 -                                              if ((*scene)->base.first) {
 -                                                      *base = (*scene)->base.first;
 +                                              ViewLayer *view_layer_set = BKE_view_layer_from_scene_get((*scene));
 +                                              if (view_layer_set->object_bases.first) {
 +                                                      *base = view_layer_set->object_bases.first;
                                                        *ob = (*base)->object;
                                                        iter->phase = F_SCENE;
                                                        break;
                                                        /* (*scene) is finished, now do the set */
                                                        while ((*scene)->set) {
                                                                (*scene) = (*scene)->set;
 -                                                              if ((*scene)->base.first) {
 -                                                                      *base = (*scene)->base.first;
 +                                                              ViewLayer *view_layer_set = BKE_view_layer_from_scene_get((*scene));
 +                                                              if (view_layer_set->object_bases.first) {
 +                                                                      *base = view_layer_set->object_bases.first;
                                                                        *ob = (*base)->object;
                                                                        break;
                                                                }
                                }
                                /* handle dupli's */
                                if (iter->dupob) {
 -                                      (*base)->flag |= OB_FROMDUPLI;
 +                                      (*base)->flag_legacy |= OB_FROMDUPLI;
                                        *ob = iter->dupob->ob;
                                        iter->phase = F_DUPLI;
  
                                }
                                else if (iter->phase == F_DUPLI) {
                                        iter->phase = F_SCENE;
 -                                      (*base)->flag &= ~OB_FROMDUPLI;
 +                                      (*base)->flag_legacy &= ~OB_FROMDUPLI;
                                        
                                        if (iter->dupli_refob) {
                                                /* Restore last object's real matrix. */
        return iter->phase;
  }
  
 -Object *BKE_scene_camera_find(Scene *sc)
 +Scene *BKE_scene_find_from_collection(const Main *bmain, const SceneCollection *scene_collection)
  {
 -      Base *base;
 -      
 -      for (base = sc->base.first; base; base = base->next)
 -              if (base->object->type == OB_CAMERA)
 -                      return base->object;
 +      for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
 +              for (ViewLayer *layer = scene->view_layers.first; layer; layer = layer->next) {
 +                      if (BKE_view_layer_has_collection(layer, scene_collection)) {
 +                              return scene;
 +                      }
 +              }
 +      }
  
        return NULL;
  }
@@@ -1261,14 -1233,49 +1261,14 @@@ char *BKE_scene_find_last_marker_name(S
        return best_marker ? best_marker->name : NULL;
  }
  
 -
 -Base *BKE_scene_base_add(Scene *sce, Object *ob)
 -{
 -      Base *b = MEM_callocN(sizeof(*b), __func__);
 -      BLI_addhead(&sce->base, b);
 -
 -      b->object = ob;
 -      b->flag = ob->flag;
 -      b->lay = ob->lay;
 -
 -      return b;
 -}
 -
 -void BKE_scene_base_unlink(Scene *sce, Base *base)
 +void BKE_scene_remove_rigidbody_object(Scene *scene, Object *ob)
  {
        /* remove rigid body constraint from world before removing object */
 -      if (base->object->rigidbody_constraint)
 -              BKE_rigidbody_remove_constraint(sce, base->object);
 +      if (ob->rigidbody_constraint)
 +              BKE_rigidbody_remove_constraint(scene, ob);
        /* remove rigid body object from world before removing object */
 -      if (base->object->rigidbody_object)
 -              BKE_rigidbody_remove_object(sce, base->object);
 -      
 -      BLI_remlink(&sce->base, base);
 -      if (sce->basact == base)
 -              sce->basact = NULL;
 -}
 -
 -void BKE_scene_base_deselect_all(Scene *sce)
 -{
 -      Base *b;
 -
 -      for (b = sce->base.first; b; b = b->next) {
 -              b->flag &= ~SELECT;
 -              b->object->flag = b->flag;
 -      }
 -}
 -
 -void BKE_scene_base_select(Scene *sce, Base *selbase)
 -{
 -      selbase->flag |= SELECT;
 -      selbase->object->flag = selbase->flag;
 -
 -      sce->basact = selbase;
 +      if (ob->rigidbody_object)
 +              BKE_rigidbody_remove_object(scene, ob);
  }
  
  /* checks for cycle, returns 1 if it's all OK */
@@@ -1320,6 -1327,109 +1320,6 @@@ void BKE_scene_frame_set(struct Scene *
        scene->r.cfra = (int)intpart;
  }
  
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -/* drivers support/hacks 
 - *  - this method is called from scene_update_tagged_recursive(), so gets included in viewport + render
 - *    - these are always run since the depsgraph can't handle non-object data
 - *    - these happen after objects are all done so that we can read in their final transform values,
 - *      though this means that objects can't refer to scene info for guidance...
 - */
 -static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
 -{
 -      SceneRenderLayer *srl;
 -      float ctime = BKE_scene_frame_get(scene);
 -      
 -      /* scene itself */
 -      if (scene->adt && scene->adt->drivers.first) {
 -              BKE_animsys_evaluate_animdata(scene, &scene->id, scene->adt, ctime, ADT_RECALC_DRIVERS);
 -      }
 -
 -      /* world */
 -      /* TODO: what about world textures? but then those have nodes too... */
 -      if (scene->world) {
 -              ID *wid = (ID *)scene->world;
 -              AnimData *adt = BKE_animdata_from_id(wid);
 -              
 -              if (adt && adt->drivers.first)
 -                      BKE_animsys_evaluate_animdata(scene, wid, adt, ctime, ADT_RECALC_DRIVERS);
 -      }
 -      
 -      /* nodes */
 -      if (scene->nodetree) {
 -              ID *nid = (ID *)scene->nodetree;
 -              AnimData *adt = BKE_animdata_from_id(nid);
 -              
 -              if (adt && adt->drivers.first)
 -                      BKE_animsys_evaluate_animdata(scene, nid, adt, ctime, ADT_RECALC_DRIVERS);
 -      }
 -
 -      /* world nodes */
 -      if (scene->world && scene->world->nodetree) {
 -              ID *nid = (ID *)scene->world->nodetree;
 -              AnimData *adt = BKE_animdata_from_id(nid);
 -              
 -              if (adt && adt->drivers.first)
 -                      BKE_animsys_evaluate_animdata(scene, nid, adt, ctime, ADT_RECALC_DRIVERS);
 -      }
 -
 -      /* freestyle */
 -      for (srl = scene->r.layers.first; srl; srl = srl->next) {
 -              FreestyleConfig *config = &srl->freestyleConfig;
 -              FreestyleLineSet *lineset;
 -
 -              for (lineset = config->linesets.first; lineset; lineset = lineset->next) {
 -                      if (lineset->linestyle) {
 -                              ID *lid = &lineset->linestyle->id;
 -                              AnimData *adt = BKE_animdata_from_id(lid);
 -
 -                              if (adt && adt->drivers.first)
 -                                      BKE_animsys_evaluate_animdata(scene, lid, adt, ctime, ADT_RECALC_DRIVERS);
 -                      }
 -              }
 -      }
 -}
 -
 -/* deps hack - do extra recalcs at end */
 -static void scene_depsgraph_hack(EvaluationContext *eval_ctx, Scene *scene, Scene *scene_parent)
 -{
 -      Base *base;
 -              
 -      scene->customdata_mask = scene_parent->customdata_mask;
 -      
 -      /* sets first, we allow per definition current scene to have
 -       * dependencies on sets, but not the other way around. */
 -      if (scene->set)
 -              scene_depsgraph_hack(eval_ctx, scene->set, scene_parent);
 -      
 -      for (base = scene->base.first; base; base = base->next) {
 -              Object *ob = base->object;
 -              
 -              if (ob->depsflag) {
 -                      int recalc = 0;
 -                      // printf("depshack %s\n", ob->id.name + 2);
 -                      
 -                      if (ob->depsflag & OB_DEPS_EXTRA_OB_RECALC)
 -                              recalc |= OB_RECALC_OB;
 -                      if (ob->depsflag & OB_DEPS_EXTRA_DATA_RECALC)
 -                              recalc |= OB_RECALC_DATA;
 -                      
 -                      ob->recalc |= recalc;
 -                      BKE_object_handle_update(eval_ctx, scene_parent, ob);
 -                      
 -                      if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP)) {
 -                              GroupObject *go;
 -                              
 -                              for (go = ob->dup_group->gobject.first; go; go = go->next) {
 -                                      if (go->ob)
 -                                              go->ob->recalc |= recalc;
 -                              }
 -                              BKE_group_handle_recalc_and_update(eval_ctx, scene_parent, ob, ob->dup_group);
 -                      }
 -              }
 -      }
 -}
 -#endif  /* WITH_LEGACY_DEPSGRAPH */
 -
  /* That's like really a bummer, because currently animation data for armatures
   * might want to use pose, and pose might be missing on the object.
   * This happens when changing visible layers, which leads to situations when
  static void scene_armature_depsgraph_workaround(Main *bmain)
  {
        Object *ob;
 -      if (BLI_listbase_is_empty(&bmain->armature) || !DAG_id_type_tagged(bmain, ID_OB)) {
 +      if (BLI_listbase_is_empty(&bmain->armature) || !DEG_id_type_tagged(bmain, ID_OB)) {
                return;
        }
        for (ob = bmain->object.first; ob; ob = ob->id.next) {
  }
  #endif
  
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -static void scene_rebuild_rbw_recursive(Scene *scene, float ctime)
 -{
 -      if (scene->set)
 -              scene_rebuild_rbw_recursive(scene->set, ctime);
 -
 -      if (BKE_scene_check_rigidbody_active(scene))
 -              BKE_rigidbody_rebuild_world(scene, ctime);
 -}
 -
 -static void scene_do_rb_simulation_recursive(Scene *scene, float ctime)
 -{
 -      if (scene->set)
 -              scene_do_rb_simulation_recursive(scene->set, ctime);
 -
 -      if (BKE_scene_check_rigidbody_active(scene))
 -              BKE_rigidbody_do_simulation(scene, ctime);
 -}
 -#endif
 -
 -/* Used to visualize CPU threads activity during threaded object update,
 - * would pollute STDERR with whole bunch of timing information which then
 - * could be parsed and nicely visualized.
 - */
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -#  undef DETAILED_ANALYSIS_OUTPUT
 -#else
 -/* ALWAYS KEEY DISABLED! */
 -#  undef DETAILED_ANALYSIS_OUTPUT
 -#endif
 -
 -/* Mballs evaluation uses BKE_scene_base_iter_next which calls
 - * duplilist for all objects in the scene. This leads to conflict
 - * accessing and writing same data from multiple threads.
 - *
 - * Ideally Mballs shouldn't do such an iteration and use DAG
 - * queries instead. For the time being we've got new DAG
 - * let's keep it simple and update mballs in a single thread.
 - */
 -#define MBALL_SINGLETHREAD_HACK
 -
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -typedef struct StatisicsEntry {
 -      struct StatisicsEntry *next, *prev;
 -      Object *object;
 -      double start_time;
 -      double duration;
 -} StatisicsEntry;
 -
 -typedef struct ThreadedObjectUpdateState {
 -      /* TODO(sergey): We might want this to be per-thread object. */
 -      EvaluationContext *eval_ctx;
 -      Scene *scene;
 -      Scene *scene_parent;
 -      double base_time;
 -
 -#ifdef MBALL_SINGLETHREAD_HACK
 -      bool has_mballs;
 -#endif
 -
 -      /* Execution statistics */
 -      bool has_updated_objects;
 -      ListBase *statistics;
 -} ThreadedObjectUpdateState;
 -
 -static void scene_update_object_add_task(void *node, void *user_data);
 -
 -static void scene_update_all_bases(EvaluationContext *eval_ctx, Scene *scene, Scene *scene_parent)
 -{
 -      Base *base;
 -
 -      for (base = scene->base.first; base; base = base->next) {
 -              Object *object = base->object;
 -
 -              BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, true);
 -
 -              if (object->dup_group && (object->transflag & OB_DUPLIGROUP))
 -                      BKE_group_handle_recalc_and_update(eval_ctx, scene_parent, object, object->dup_group);
 -
 -              /* always update layer, so that animating layers works (joshua july 2010) */
 -              /* XXX commented out, this has depsgraph issues anyway - and this breaks setting scenes
 -               * (on scene-set, the base-lay is copied to ob-lay (ton nov 2012) */
 -              // base->lay = ob->lay;
 -      }
 -}
 -
 -static void scene_update_object_func(TaskPool * __restrict pool, void *taskdata, int threadid)
 -{
 -/* Disable print for now in favor of summary statistics at the end of update. */
 -#define PRINT if (false) printf
 -
 -      ThreadedObjectUpdateState *state = (ThreadedObjectUpdateState *) BLI_task_pool_userdata(pool);
 -      void *node = taskdata;
 -      Object *object = DAG_get_node_object(node);
 -      EvaluationContext *eval_ctx = state->eval_ctx;
 -      Scene *scene = state->scene;
 -      Scene *scene_parent = state->scene_parent;
 -
 -#ifdef MBALL_SINGLETHREAD_HACK
 -      if (object && object->type == OB_MBALL) {
 -              state->has_mballs = true;
 -      }
 -      else
 -#endif
 -      if (object) {
 -              double start_time = 0.0;
 -              bool add_to_stats = false;
 -
 -              if (G.debug & G_DEBUG_DEPSGRAPH) {
 -                      if (object->recalc & OB_RECALC_ALL) {
 -                              printf("Thread %d: update object %s\n", threadid, object->id.name);
 -                      }
 -
 -                      start_time = PIL_check_seconds_timer();
 -
 -                      if (object->recalc & OB_RECALC_ALL) {
 -                              state->has_updated_objects = true;
 -                              add_to_stats = true;
 -                      }
 -              }
 -
 -              /* We only update object itself here, dupli-group will be updated
 -               * separately from main thread because of we've got no idea about
 -               * dependencies inside the group.
 -               */
 -              BKE_object_handle_update_ex(eval_ctx, scene_parent, object, scene->rigidbody_world, false);
 -
 -              /* Calculate statistics. */
 -              if (add_to_stats) {
 -                      StatisicsEntry *entry;
 -
 -                      entry = MEM_mallocN(sizeof(StatisicsEntry), "update thread statistics");
 -                      entry->object = object;
 -                      entry->start_time = start_time;
 -                      entry->duration = PIL_check_seconds_timer() - start_time;
 -
 -                      BLI_addtail(&state->statistics[threadid], entry);
 -              }
 -      }
 -      else {
 -              PRINT("Threda %d: update node %s\n", threadid,
 -                    DAG_get_node_name(scene, node));
 -      }
 -
 -      /* Update will decrease child's valency and schedule child with zero valency. */
 -      DAG_threaded_update_handle_node_updated(node, scene_update_object_add_task, pool);
 -
 -#undef PRINT
 -}
 -
 -static void scene_update_object_add_task(void *node, void *user_data)
 -{
 -      TaskPool *task_pool = user_data;
 -
 -      BLI_task_pool_push(task_pool, scene_update_object_func, node, false, TASK_PRIORITY_LOW);
 -}
 -
 -static void print_threads_statistics(ThreadedObjectUpdateState *state)
 -{
 -      int i, tot_thread;
 -      double finish_time;
 -
 -      if ((G.debug & G_DEBUG_DEPSGRAPH) == 0) {
 -              return;
 -      }
 -
 -#ifdef DETAILED_ANALYSIS_OUTPUT
 -      if (state->has_updated_objects) {
 -              tot_thread = BLI_system_thread_count();
 -
 -              fprintf(stderr, "objects update base time %f\n", state->base_time);
 -
 -              for (i = 0; i < tot_thread; i++) {
 -                      StatisicsEntry *entry;
 -                      for (entry = state->statistics[i].first;
 -                           entry;
 -                           entry = entry->next)
 -                      {
 -                              fprintf(stderr, "thread %d object %s start_time %f duration %f\n",
 -                                      i, entry->object->id.name + 2,
 -                                      entry->start_time, entry->duration);
 -                      }
 -                      BLI_freelistN(&state->statistics[i]);
 -              }
 -      }
 -#else
 -      finish_time = PIL_check_seconds_timer();
 -      tot_thread = BLI_system_thread_count();
 -      int total_objects = 0;
 -
 -      for (i = 0; i < tot_thread; i++) {
 -              int thread_total_objects = 0;
 -              double thread_total_time = 0.0;
 -              StatisicsEntry *entry;
 -
 -              if (state->has_updated_objects) {
 -                      /* Don't pollute output if no objects were updated. */
 -                      for (entry = state->statistics[i].first;
 -                           entry;
 -                           entry = entry->next)
 -                      {
 -                              thread_total_objects++;
 -                              thread_total_time += entry->duration;
 -                      }
 -
 -                      printf("Thread %d: total %d objects in %f sec.\n",
 -                             i,
 -                             thread_total_objects,
 -                             thread_total_time);
 -
 -                      for (entry = state->statistics[i].first;
 -                           entry;
 -                           entry = entry->next)
 -                      {
 -                              printf("  %s in %f sec\n", entry->object->id.name + 2, entry->duration);
 -                      }
 -
 -                      total_objects += thread_total_objects;
 -              }
 -
 -              BLI_freelistN(&state->statistics[i]);
 -      }
 -      if (state->has_updated_objects) {
 -              printf("Scene updated %d objects in %f sec\n",
 -                     total_objects,
 -                     finish_time - state->base_time);
 -      }
 -#endif
 -}
 -
 -static bool scene_need_update_objects(Main *bmain)
 -{
 -      return
 -              /* Object datablocks themselves (for OB_RECALC_OB) */
 -              DAG_id_type_tagged(bmain, ID_OB) ||
 -
 -              /* Objects data datablocks (for OB_RECALC_DATA) */
 -              DAG_id_type_tagged(bmain, ID_ME)  ||  /* Mesh */
 -              DAG_id_type_tagged(bmain, ID_CU)  ||  /* Curve */
 -              DAG_id_type_tagged(bmain, ID_MB)  ||  /* MetaBall */
 -              DAG_id_type_tagged(bmain, ID_LA)  ||  /* Lamp */
 -              DAG_id_type_tagged(bmain, ID_LT)  ||  /* Lattice */
 -              DAG_id_type_tagged(bmain, ID_CA)  ||  /* Camera */
 -              DAG_id_type_tagged(bmain, ID_KE)  ||  /* KE */
 -              DAG_id_type_tagged(bmain, ID_SPK) ||  /* Speaker */
 -              DAG_id_type_tagged(bmain, ID_AR);     /* Armature */
 -}
 -
 -static void scene_update_objects(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Scene *scene_parent)
 -{
 -      TaskScheduler *task_scheduler;
 -      TaskPool *task_pool;
 -      ThreadedObjectUpdateState state;
 -      bool need_singlethread_pass;
 -      bool need_free_scheduler;
 -
 -      /* Early check for whether we need to invoke all the task-based
 -       * things (spawn new ppol, traverse dependency graph and so on).
 -       *
 -       * Basically if there's no ID datablocks tagged for update which
 -       * corresponds to object->recalc flags (which are checked in
 -       * BKE_object_handle_update() then we do nothing here.
 -       */
 -      if (!scene_need_update_objects(bmain)) {
 -              return;
 -      }
 -
 -      state.eval_ctx = eval_ctx;
 -      state.scene = scene;
 -      state.scene_parent = scene_parent;
 -
 -      if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) {
 -              task_scheduler = BLI_task_scheduler_create(1);
 -              need_free_scheduler = true;
 -      }
 -      else {
 -              task_scheduler = BLI_task_scheduler_get();
 -              need_free_scheduler = false;
 -      }
 -
 -      /* Those are only needed when blender is run with --debug argument. */
 -      if (G.debug & G_DEBUG_DEPSGRAPH) {
 -              const int tot_thread = BLI_task_scheduler_num_threads(task_scheduler);
 -              state.statistics = MEM_callocN(tot_thread * sizeof(*state.statistics),
 -                                             "scene update objects stats");
 -              state.has_updated_objects = false;
 -              state.base_time = PIL_check_seconds_timer();
 -      }
 -
 -#ifdef MBALL_SINGLETHREAD_HACK
 -      state.has_mballs = false;
 -#endif
 -
 -      task_pool = BLI_task_pool_create(task_scheduler, &state);
 -
 -      DAG_threaded_update_begin(scene, scene_update_object_add_task, task_pool);
 -      BLI_task_pool_work_and_wait(task_pool);
 -      BLI_task_pool_free(task_pool);
 -
 -      if (G.debug & G_DEBUG_DEPSGRAPH) {
 -              print_threads_statistics(&state);
 -              MEM_freeN(state.statistics);
 -      }
 -
 -      /* We do single thread pass to update all the objects which are in cyclic dependency.
 -       * Such objects can not be handled by a generic DAG traverse and it's really tricky
 -       * to detect whether cycle could be solved or not.
 -       *
 -       * In this situation we simply update all remaining objects in a single thread and
 -       * it'll happen in the same exact order as it was in single-threaded DAG.
 -       *
 -       * We couldn't use threaded update for objects which are in cycle because they might
 -       * access data of each other which is being re-evaluated.
 -       *
 -       * Also, as was explained above, for now we also update all the mballs in single thread.
 -       *
 -       *                                                                   - sergey -
 -       */
 -      need_singlethread_pass = DAG_is_acyclic(scene) == false;
 -#ifdef MBALL_SINGLETHREAD_HACK
 -      need_singlethread_pass |= state.has_mballs;
 -#endif
 -
 -      if (need_singlethread_pass) {
 -              scene_update_all_bases(eval_ctx, scene, scene_parent);
 -      }
 -
 -      if (need_free_scheduler) {
 -              BLI_task_scheduler_free(task_scheduler);
 -      }
 -}
 -
 -static void scene_update_tagged_recursive(EvaluationContext *eval_ctx, Main *bmain, Scene *scene, Scene *scene_parent)
 -{
 -      scene->customdata_mask = scene_parent->customdata_mask;
 -
 -      /* sets first, we allow per definition current scene to have
 -       * dependencies on sets, but not the other way around. */
 -      if (scene->set)
 -              scene_update_tagged_recursive(eval_ctx, bmain, scene->set, scene_parent);
 -
 -      /* scene objects */
 -      scene_update_objects(eval_ctx, bmain, scene, scene_parent);
 -
 -      /* scene drivers... */
 -      scene_update_drivers(bmain, scene);
 -
 -      /* update masking curves */
 -      BKE_mask_update_scene(bmain, scene);
 -      
 -}
 -#endif  /* WITH_LEGACY_DEPSGRAPH */
 -
  static bool check_rendered_viewport_visible(Main *bmain)
  {
        wmWindowManager *wm = bmain->wm.first;
        wmWindow *window;
        for (window = wm->windows.first; window != NULL; window = window->next) {
 -              bScreen *screen = window->screen;
 +              const bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
 +              WorkSpace *workspace = BKE_workspace_active_get(window->workspace_hook);
 +              Scene *scene = window->scene;
 +              ViewRender *view_render = BKE_viewrender_get(scene, workspace);
                ScrArea *area;
 +              RenderEngineType *type = RE_engines_find(view_render->engine_id);
 +              if ((type->draw_engine != NULL) || (type->render_to_view == NULL)) {
 +                      continue;
 +              }
 +              const bool use_legacy = (type->flag & RE_USE_LEGACY_PIPELINE) != 0;
                for (area = screen->areabase.first; area != NULL; area = area->next) {
                        View3D *v3d = area->spacedata.first;
                        if (area->spacetype != SPACE_VIEW3D) {
                                continue;
                        }
 -                      if (v3d->drawtype == OB_RENDER) {
 +                      if (v3d->drawtype == OB_RENDER || !use_legacy) {
                                return true;
                        }
                }
        return false;
  }
  
 -static void prepare_mesh_for_viewport_render(Main *bmain, Scene *scene)
 +static void prepare_mesh_for_viewport_render(Main *bmain, const EvaluationContext *eval_ctx)
  {
        /* This is needed to prepare mesh to be used by the render
         * engine from the viewport rendering. We do loading here
         * call loading of the edit data for the mesh objects.
         */
  
 -      Object *obedit = scene->obedit;
 +      Object *obedit = OBEDIT_FROM_EVAL_CTX(eval_ctx);
        if (obedit) {
                Mesh *mesh = obedit->data;
                if ((obedit->type == OB_MESH) &&
                {
                        if (check_rendered_viewport_visible(bmain)) {
                                BMesh *bm = mesh->edit_btmesh->bm;
-                               BM_mesh_bm_to_me(bm, mesh, (&(struct BMeshToMeshParams){0}));
+                               BM_mesh_bm_to_me(
+                                       bm, mesh,
+                                       (&(struct BMeshToMeshParams){
+                                           .calc_object_remap = true,
+                                       }));
 -                              DAG_id_tag_update(&mesh->id, 0);
 +                              DEG_id_tag_update(&mesh->id, 0);
                        }
                }
        }
  }
  
 -void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *scene)
 -{
 -      Scene *sce_iter;
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      bool use_new_eval = !DEG_depsgraph_use_legacy();
 -#endif
 -
 -      /* keep this first */
 -      BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
 -
 -      /* (re-)build dependency graph if needed */
 -      for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set) {
 -              DAG_scene_relations_update(bmain, sce_iter);
 -              /* Uncomment this to check if dependency graph was properly tagged for update. */
 -#if 0
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -              if (use_new_eval)
 -#endif
 -              {
 -                      DAG_scene_relations_validate(bmain, sce_iter);
 -              }
 -#endif
 -      }
 -
 -      /* flush editing data if needed */
 -      prepare_mesh_for_viewport_render(bmain, scene);
 -
 -      /* flush recalc flags to dependencies */
 -      DAG_ids_flush_tagged(bmain);
 -
 -      /* removed calls to quick_cache, see pointcache.c */
 -      
 -      /* clear "LIB_TAG_DOIT" flag from all materials, to prevent infinite recursion problems later
 -       * when trying to find materials with drivers that need evaluating [#32017] 
 +/* TODO(sergey): This actually should become view_layer_graph or so.
 + * Same applies to update_for_newframe.
 + */
 +void BKE_scene_graph_update_tagged(EvaluationContext *eval_ctx,
 +                                   Depsgraph *depsgraph,
 +                                   Main *bmain,
 +                                   Scene *scene,
 +                                   ViewLayer *view_layer)
 +{
 +      /* TODO(sergey): Temporary solution for until pipeline.c is ported. */
 +      if (view_layer == NULL) {
 +              view_layer = DEG_get_evaluated_view_layer(depsgraph);
 +              BLI_assert(view_layer != NULL);
 +      }
 +      /* TODO(sergey): Some functions here are changing global state,
 +       * for example, clearing update tags from bmain.
         */
 -      BKE_main_id_tag_idcode(bmain, ID_MA, LIB_TAG_DOIT, false);
 -      BKE_main_id_tag_idcode(bmain, ID_LA, LIB_TAG_DOIT, false);
 -
 -      /* update all objects: drivers, matrices, displists, etc. flags set
 -       * by depgraph or manual, no layer check here, gets correct flushed
 -       *
 -       * in the future this should handle updates for all datablocks, not
 -       * only objects and scenes. - brecht */
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      if (!use_new_eval) {
 -              scene_update_tagged_recursive(eval_ctx, bmain, scene, scene);
 -      }
 -      else
 -#endif
 -      {
 -              DEG_evaluate_on_refresh(eval_ctx, scene->depsgraph, scene);
 -      }
 -
 -      /* update sound system animation (TODO, move to depsgraph) */
 -      BKE_sound_update_scene(bmain, scene);
 -
 -      /* extra call here to recalc scene animation (for sequencer) */
 -      {
 -              AnimData *adt = BKE_animdata_from_id(&scene->id);
 -              float ctime = BKE_scene_frame_get(scene);
 -              
 -              if (adt && (adt->recalc & ADT_RECALC_ANIM))
 -                      BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, 0);
 -      }
 -
 -      /* Extra call here to recalc material animation.
 -       *
 -       * Need to do this so changing material settings from the graph/dopesheet
 -       * will update stuff in the viewport.
 +      /* (Re-)build dependency graph if needed. */
 +      DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
 +      /* Uncomment this to check if graph was properly tagged for update. */
 +      // DEG_debug_graph_relations_validate(depsgraph, bmain, scene);
 +      /* Flush editing data if needed. */
 +      prepare_mesh_for_viewport_render(bmain, eval_ctx);
 +      /* Flush recalc flags to dependencies. */
 +      DEG_graph_flush_update(bmain, depsgraph);
 +      /* Update all objects: drivers, matrices, displists, etc. flags set
 +       * by depgraph or manual, no layer check here, gets correct flushed.
         */
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      if (!use_new_eval && DAG_id_type_tagged(bmain, ID_MA)) {
 -              Material *material;
 -              float ctime = BKE_scene_frame_get(scene);
 -
 -              for (material = bmain->mat.first;
 -                   material;
 -                   material = material->id.next)
 -              {
 -                      AnimData *adt = BKE_animdata_from_id(&material->id);
 -                      if (adt && (adt->recalc & ADT_RECALC_ANIM))
 -                              BKE_animsys_evaluate_animdata(scene, &material->id, adt, ctime, 0);
 -              }
 -      }
 -
 -      /* Also do the same for node trees. */
 -      if (!use_new_eval && DAG_id_type_tagged(bmain, ID_NT)) {
 -              float ctime = BKE_scene_frame_get(scene);
 -
 -              FOREACH_NODETREE(bmain, ntree, id)
 -              {
 -                      AnimData *adt = BKE_animdata_from_id(&ntree->id);
 -                      if (adt && (adt->recalc & ADT_RECALC_ANIM))
 -                              BKE_animsys_evaluate_animdata(scene, &ntree->id, adt, ctime, 0);
 -              }
 -              FOREACH_NODETREE_END
 -      }
 -#endif
 -
 -      /* notify editors and python about recalc */
 -      BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST);
 -
 +      DEG_evaluate_on_refresh(eval_ctx, depsgraph);
 +      /* Update sound system animation (TODO, move to depsgraph). */
 +      BKE_sound_update_scene(bmain, scene);
        /* Inform editors about possible changes. */
 -      DAG_ids_check_recalc(bmain, scene, false);
 -
 -      /* clear recalc flags */
 -      DAG_ids_clear_recalc(bmain);
 +      DEG_ids_check_recalc(bmain, depsgraph, scene, view_layer, false);
 +      /* Clear recalc flags. */
 +      DEG_ids_clear_recalc(bmain);
  }
  
  /* applies changes right away, does all sets too */
 -void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay)
 -{
 -      BKE_scene_update_for_newframe_ex(eval_ctx, bmain, sce, lay, false);
 -}
 -
 -void BKE_scene_update_for_newframe_ex(EvaluationContext *eval_ctx, Main *bmain, Scene *sce, unsigned int lay, bool do_invisible_flush)
 -{
 -      float ctime = BKE_scene_frame_get(sce);
 -      Scene *sce_iter;
 -#ifdef DETAILED_ANALYSIS_OUTPUT
 -      double start_time = PIL_check_seconds_timer();
 -#endif
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      bool use_new_eval = !DEG_depsgraph_use_legacy();
 -#else
 -      /* TODO(sergey): Pass to evaluation routines instead of storing layer in the dependency graph? */
 -      (void) do_invisible_flush;
 -#endif
 -
 -      DAG_editors_update_pre(bmain, sce, true);
 -
 -      /* keep this first */
 -      BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_PRE);
 -      BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
 -
 -      /* update animated image textures for particles, modifiers, gpu, etc,
 -       * call this at the start so modifiers with textures don't lag 1 frame */
 -      BKE_image_update_frame(bmain, sce->r.cfra);
 -      
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      /* rebuild rigid body worlds before doing the actual frame update
 -       * this needs to be done on start frame but animation playback usually starts one frame later
 -       * we need to do it here to avoid rebuilding the world on every simulation change, which can be very expensive
 +void BKE_scene_graph_update_for_newframe(EvaluationContext *eval_ctx,
 +                                         Depsgraph *depsgraph,
 +                                         Main *bmain,
 +                                         Scene *scene,
 +                                         ViewLayer *view_layer)
 +{
 +      /* TODO(sergey): Temporary solution for until pipeline.c is ported. */
 +      if (view_layer == NULL) {
 +              view_layer = DEG_get_evaluated_view_layer(depsgraph);
 +              BLI_assert(view_layer != NULL);
 +      }
 +      /* TODO(sergey): Some functions here are changing global state,
 +       * for example, clearing update tags from bmain.
         */
 -      if (!use_new_eval) {
 -              scene_rebuild_rbw_recursive(sce, ctime);
 -      }
 -#endif
 -      
 -      BKE_sound_set_cfra(sce->r.cfra);
 -      
 -      /* clear animation overrides */
 -      /* XXX TODO... */
 -
 -      for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set)
 -              DAG_scene_relations_update(bmain, sce_iter);
 -
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      if (!use_new_eval) {
 -              /* flush recalc flags to dependencies, if we were only changing a frame
 -               * this would not be necessary, but if a user or a script has modified
 -               * some datablock before BKE_scene_update_tagged was called, we need the flush */
 -              DAG_ids_flush_tagged(bmain);
 -
 -              /* Following 2 functions are recursive
 -               * so don't call within 'scene_update_tagged_recursive' */
 -              DAG_scene_update_flags(bmain, sce, lay, true, do_invisible_flush);   // only stuff that moves or needs display still
 -              BKE_mask_evaluate_all_masks(bmain, ctime, true);
 -      }
 -#endif
 -
 -      /* Update animated cache files for modifiers. */
 -      BKE_cachefile_update_frame(bmain, sce, ctime, (((double)sce->r.frs_sec) / (double)sce->r.frs_sec_base));
 -
 +      const float ctime = BKE_scene_frame_get(scene);
 +      /* Keep this first. */
 +      BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_FRAME_CHANGE_PRE);
 +      /* Update animated image textures for particles, modifiers, gpu, etc,
 +       * call this at the start so modifiers with textures don't lag 1 frame.
 +       */
 +      BKE_image_update_frame(bmain, scene->r.cfra);
 +      BKE_sound_set_cfra(scene->r.cfra);
 +      DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
 +      /* Update animated cache files for modifiers.
 +       *
 +       * TODO(sergey): Make this a depsgraph node?
 +       */
 +      BKE_cachefile_update_frame(bmain, scene, ctime,
 +                                 (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base));
  #ifdef POSE_ANIMATION_WORKAROUND
        scene_armature_depsgraph_workaround(bmain);
  #endif
 -
 -      /* All 'standard' (i.e. without any dependencies) animation is handled here,
 -       * with an 'local' to 'macro' order of evaluation. This should ensure that
 -       * settings stored nestled within a hierarchy (i.e. settings in a Texture block
 -       * can be overridden by settings from Scene, which owns the Texture through a hierarchy
 -       * such as Scene->World->MTex/Texture) can still get correctly overridden.
 +      /* Update all objects: drivers, matrices, displists, etc. flags set
 +       * by depgraph or manual, no layer check here, gets correct flushed.
         */
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      if (!use_new_eval) {
 -              BKE_animsys_evaluate_all_animation(bmain, sce, ctime);
 -              /*...done with recursive funcs */
 -      }
 -#endif
 -
 -      /* clear "LIB_TAG_DOIT" flag from all materials, to prevent infinite recursion problems later
 -       * when trying to find materials with drivers that need evaluating [#32017] 
 -       */
 -      BKE_main_id_tag_idcode(bmain, ID_MA, LIB_TAG_DOIT, false);
 -      BKE_main_id_tag_idcode(bmain, ID_LA, LIB_TAG_DOIT, false);
 -
 -      /* run rigidbody sim */
 -      /* NOTE: current position is so that rigidbody sim affects other objects, might change in the future */
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      if (!use_new_eval) {
 -              scene_do_rb_simulation_recursive(sce, ctime);
 -      }
 -#endif
 -      
 -      /* BKE_object_handle_update() on all objects, groups and sets */
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      if (use_new_eval) {
 -              DEG_evaluate_on_framechange(eval_ctx, bmain, sce->depsgraph, ctime, lay);
 -      }
 -      else {
 -              scene_update_tagged_recursive(eval_ctx, bmain, sce, sce);
 -      }
 -#else
 -      DEG_evaluate_on_framechange(eval_ctx, bmain, sce->depsgraph, ctime, lay);
 -#endif
 -
 -      /* update sound system animation (TODO, move to depsgraph) */
 -      BKE_sound_update_scene(bmain, sce);
 -
 -#ifdef WITH_LEGACY_DEPSGRAPH
 -      if (!use_new_eval) {
 -              scene_depsgraph_hack(eval_ctx, sce, sce);
 -      }
 -#endif
 -
 -      /* notify editors and python about recalc */
 -      BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
 -      BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
 -
 +      DEG_evaluate_on_framechange(eval_ctx, bmain, depsgraph, ctime);
 +      /* Update sound system animation (TODO, move to depsgraph). */
 +      BKE_sound_update_scene(bmain, scene);
 +      /* Notify editors and python about recalc. */
 +      BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_FRAME_CHANGE_POST);
        /* Inform editors about possible changes. */
 -      DAG_ids_check_recalc(bmain, sce, true);
 -
 +      DEG_ids_check_recalc(bmain, depsgraph, scene, view_layer, true);
        /* clear recalc flags */
 -      DAG_ids_clear_recalc(bmain);
 -
 -#ifdef DETAILED_ANALYSIS_OUTPUT
 -      fprintf(stderr, "frame update start_time %f duration %f\n", start_time, PIL_check_seconds_timer() - start_time);
 -#endif
 -}
 -
 -/* return default layer, also used to patch old files */
 -SceneRenderLayer *BKE_scene_add_render_layer(Scene *sce, const char *name)
 -{
 -      SceneRenderLayer *srl;
 -
 -      if (!name)
 -              name = DATA_("RenderLayer");
 -
 -      srl = MEM_callocN(sizeof(SceneRenderLayer), "new render layer");
 -      BLI_strncpy(srl->name, name, sizeof(srl->name));
 -      BLI_uniquename(&sce->r.layers, srl, DATA_("RenderLayer"), '.', offsetof(SceneRenderLayer, name), sizeof(srl->name));
 -      BLI_addtail(&sce->r.layers, srl);
 -
 -      /* note, this is also in render, pipeline.c, to make layer when scenedata doesnt have it */
 -      srl->lay = (1 << 20) - 1;
 -      srl->layflag = 0x7FFF;   /* solid ztra halo edge strand */
 -      srl->passflag = SCE_PASS_COMBINED | SCE_PASS_Z;
 -      srl->pass_alpha_threshold = 0.5f;
 -      BKE_freestyle_config_init(&srl->freestyleConfig);
 -
 -      return srl;
 -}
 -
 -bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *srl)
 -{
 -      const int act = BLI_findindex(&scene->r.layers, srl);
 -      Scene *sce;
 -
 -      if (act == -1) {
 -              return false;
 -      }
 -      else if ( (scene->r.layers.first == scene->r.layers.last) &&
 -                (scene->r.layers.first == srl))
 -      {
 -              /* ensure 1 layer is kept */
 -              return false;
 -      }
 -
 -      BKE_freestyle_config_free(&srl->freestyleConfig);
 -
 -      if (srl->prop) {
 -              IDP_FreeProperty(srl->prop);
 -              MEM_freeN(srl->prop);
 -      }
 -
 -      BLI_remlink(&scene->r.layers, srl);
 -      MEM_freeN(srl);
 -
 -      scene->r.actlay = 0;
 -
 -      for (sce = bmain->scene.first; sce; sce = sce->id.next) {
 -              if (sce->nodetree) {
 -                      bNode *node;
 -                      for (node = sce->nodetree->nodes.first; node; node = node->next) {
 -                              if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
 -                                      if (node->custom1 == act)
 -                                              node->custom1 = 0;
 -                                      else if (node->custom1 > act)
 -                                              node->custom1--;
 -                              }
 -                      }
 -              }
 -      }
 -
 -      return true;
 +      DEG_ids_clear_recalc(bmain);
  }
  
  /* return default view */
@@@ -1567,34 -2250,21 +1571,34 @@@ float get_render_aosss_error(const Rend
                return error;
  }
  
 -/* helper function for the SETLOOPER macro */
 -Base *_setlooper_base_step(Scene **sce_iter, Base *base)
 +/**
 +  * Helper function for the SETLOOPER and SETLOOPER_VIEW_LAYER macros
 +  *
 +  * It iterates over the bases of the active layer and then the bases
 +  * of the active layer of the background (set) scenes recursively.
 +  */
 +Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
  {
        if (base && base->next) {
 -              /* common case, step to the next */
 +              /* Common case, step to the next. */
                return base->next;
        }
 -      else if (base == NULL && (*sce_iter)->base.first) {
 -              /* first time looping, return the scenes first base */
 -              return (Base *)(*sce_iter)->base.first;
 +      else if ((base == NULL) && (view_layer != NULL)) {
 +              /* First time looping, return the scenes first base. */
 +              /* For the first loop we should get the layer from workspace when available. */
 +              if (view_layer->object_bases.first) {
 +                      return (Base *)view_layer->object_bases.first;
 +              }
 +              /* No base on this scene layer. */
 +              goto next_set;
        }
        else {
 -              /* reached the end, get the next base in the set */
 +next_set:
 +              /* Reached the end, get the next base in the set. */
                while ((*sce_iter = (*sce_iter)->set)) {
 -                      base = (Base *)(*sce_iter)->base.first;
 +                      ViewLayer *view_layer_set = BKE_view_layer_from_scene_get((*sce_iter));
 +                      base = (Base *)view_layer_set->object_bases.first;
 +
                        if (base) {
                                return base;
                        }
  
  bool BKE_scene_use_new_shading_nodes(const Scene *scene)
  {
 -      const RenderEngineType *type = RE_engines_find(scene->r.engine);
 -      return (type && type->flag & RE_USE_SHADING_NODES);
 +      return BKE_viewrender_use_new_shading_nodes(&scene->view_render);
  }
  
  bool BKE_scene_use_shading_nodes_custom(Scene *scene)
  {
 -      RenderEngineType *type = RE_engines_find(scene->r.engine);
 -      return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM);
 +      return BKE_viewrender_use_shading_nodes_custom(&scene->view_render);
  }
  
  bool BKE_scene_use_world_space_shading(Scene *scene)
  {
 -      const RenderEngineType *type = RE_engines_find(scene->r.engine);
 +      RenderEngineType *type = RE_engines_find(scene->view_render.engine_id);
        return ((scene->r.mode & R_USE_WS_SHADING) ||
                (type && (type->flag & RE_USE_SHADING_NODES)));
  }
  
  bool BKE_scene_use_spherical_stereo(Scene *scene)
  {
 -      RenderEngineType *type = RE_engines_find(scene->r.engine);
 -      return (type && type->flag & RE_USE_SPHERICAL_STEREO);
 +      return BKE_viewrender_use_spherical_stereo(&scene->view_render);
  }
  
 -bool BKE_scene_uses_blender_internal(const  Scene *scene)
 +bool BKE_scene_uses_blender_internal(const Scene *scene)
  {
 -      return STREQ(scene->r.engine, RE_engine_id_BLENDER_RENDER);
 +      return BKE_viewrender_uses_blender_internal(&scene->view_render);
  }
  
  bool BKE_scene_uses_blender_game(const Scene *scene)
  {
 -      return STREQ(scene->r.engine, RE_engine_id_BLENDER_GAME);
 +      return BKE_viewrender_uses_blender_game(&scene->view_render);
  }
  
 -void BKE_scene_base_flag_to_objects(struct Scene *scene)
 +bool BKE_scene_uses_blender_eevee(const Scene *scene)
  {
 -      Base *base = scene->base.first;
 +      return BKE_viewrender_uses_blender_eevee(&scene->view_render);
 +}
 +
 +void BKE_scene_base_flag_to_objects(ViewLayer *view_layer)
 +{
 +      Base *base = view_layer->object_bases.first;
  
        while (base) {
 -              base->object->flag = base->flag;
 +              BKE_scene_object_base_flag_sync_from_base(base);
                base = base->next;
        }
  }
  
 -void BKE_scene_base_flag_from_objects(struct Scene *scene)
 +void BKE_scene_object_base_flag_sync_from_base(Base *base)
  {
 -      Base *base = scene->base.first;
 +      Object *ob = base->object;
  
 -      while (base) {
 -              base->flag = base->object->flag;
 -              base = base->next;
 +      /* keep the object only flags untouched */
 +      int flag = ob->flag & OB_FROMGROUP;
 +
 +      ob->flag = base->flag;
 +      ob->flag |= flag;
 +
 +      if ((base->flag & BASE_SELECTED) != 0) {
 +              ob->flag |= SELECT;
 +      }
 +      else {
 +              ob->flag &= ~SELECT;
 +      }
 +}
 +
 +void BKE_scene_object_base_flag_sync_from_object(Base *base)
 +{
 +      Object *ob = base->object;
 +      base->flag = ob->flag;
 +
 +      if ((ob->flag & SELECT) != 0) {
 +              base->flag |= BASE_SELECTED;
 +              BLI_assert((base->flag & BASE_SELECTABLED) != 0);
 +      }
 +      else {
 +              base->flag &= ~BASE_SELECTED;
        }
  }
  
@@@ -1743,81 -2389,6 +1747,81 @@@ int BKE_render_preview_pixel_size(cons
        return r->preview_pixel_size;
  }
  
 +/* ***************************************************** */
 +/* render engine settings */
 +
 +ViewRender *BKE_viewrender_get(Scene *scene, WorkSpace *workspace)
 +{
 +      if (workspace == NULL || BKE_workspace_use_scene_settings_get(workspace)) {
 +              return &scene->view_render;
 +      }
 +      return BKE_workspace_view_render_get(workspace);
 +}
 +
 +/**
 + * Initialize a static created struct for WorkSpace and Scene to store the viewport
 + * related drawing data.
 + */
 +void BKE_viewrender_init(ViewRender *view_render)
 +{
 +      BLI_strncpy(view_render->engine_id, RE_engine_id_BLENDER_EEVEE, sizeof(view_render->engine_id));
 +}
 +
 +/**
 + * Do not free ViewRender itself since it's not even allocated.
 + */
 +void BKE_viewrender_free(ViewRender *UNUSED(view_render))
 +{
 +      /* Do nothing. */
 +}
 +
 +/**
 + * Copy used by libblock copying.
 + */
 +void BKE_viewrender_copy(ViewRender *to, const ViewRender *from)
 +{
 +      *to = *from;
 +}
 +
 +bool BKE_viewrender_use_new_shading_nodes(const ViewRender *view_render)
 +{
 +      RenderEngineType *type = RE_engines_find(view_render->engine_id);
 +      return (type && type->flag & RE_USE_SHADING_NODES);
 +}
 +
 +bool BKE_viewrender_use_shading_nodes_custom(const ViewRender *view_render)
 +{
 +      RenderEngineType *type = RE_engines_find(view_render->engine_id);
 +      return (type && type->flag & RE_USE_SHADING_NODES_CUSTOM);
 +}
 +
 +bool BKE_viewrender_use_spherical_stereo(const ViewRender *view_render)
 +{
 +      const char *engine_id = view_render->engine_id;
 +      RenderEngineType *type = RE_engines_find(engine_id);
 +      return (type && type->flag & RE_USE_SPHERICAL_STEREO);
 +}
 +
 +bool BKE_viewrender_uses_blender_internal(const ViewRender *view_render)
 +{
 +      const char *engine_id = view_render->engine_id;
 +      return STREQ(engine_id, RE_engine_id_BLENDER_RENDER);
 +}
 +
 +bool BKE_viewrender_uses_blender_game(const ViewRender *view_render)
 +{
 +      const char *engine_id = view_render->engine_id;
 +      return STREQ(engine_id, RE_engine_id_BLENDER_GAME);
 +}
 +
 +bool BKE_viewrender_uses_blender_eevee(const ViewRender *view_render)
 +{
 +      const char *engine_id = view_render->engine_id;
 +      return STREQ(engine_id, RE_engine_id_BLENDER_EEVEE);
 +}
 +
 +/* ***************************************************** */
 +
  /* Apply the needed correction factor to value, based on unit_type (only length-related are affected currently)
   * and unit->scale_length.
   */
@@@ -2123,106 -2694,3 +2127,106 @@@ int BKE_scene_multiview_num_videos_get(
                return BKE_scene_multiview_num_views_get(rd);
        }
  }
 +
 +/* Manipulation of depsgraph storage. */
 +
 +/* This is a key which identifies depsgraph. */
 +typedef struct DepsgraphKey {
 +      ViewLayer *view_layer;
 +      /* TODO(sergey): Need to include window somehow (same layer might be in a
 +       * different states in different windows).
 +       */
 +} DepsgraphKey;
 +
 +static unsigned int depsgraph_key_hash(const void *key_v)
 +{
 +      const DepsgraphKey *key = key_v;
 +      unsigned int hash = BLI_ghashutil_ptrhash(key->view_layer);
 +      /* TODO(sergey): Include hash from other fields in the key. */
 +      return hash;
 +}
 +
 +static bool depsgraph_key_compare(const void *key_a_v, const void *key_b_v)
 +{
 +      const DepsgraphKey *key_a = key_a_v;
 +      const DepsgraphKey *key_b = key_b_v;
 +      /* TODO(sergey): Compare rest of  */
 +      return !(key_a->view_layer == key_b->view_layer);
 +}
 +
 +static void depsgraph_key_free(void *key_v)
 +{
 +      DepsgraphKey *key = key_v;
 +      MEM_freeN(key);
 +}
 +
 +static void depsgraph_key_value_free(void *value)
 +{
 +      Depsgraph *depsgraph = value;
 +      DEG_graph_free(depsgraph);
 +}
 +
 +void BKE_scene_allocate_depsgraph_hash(Scene *scene)
 +{
 +      scene->depsgraph_hash = BLI_ghash_new(depsgraph_key_hash,
 +                                            depsgraph_key_compare,
 +                                            "Scene Depsgraph Hash");
 +}
 +
 +void BKE_scene_ensure_depsgraph_hash(Scene *scene)
 +{
 +      if (scene->depsgraph_hash == NULL) {
 +              BKE_scene_allocate_depsgraph_hash(scene);
 +      }
 +}
 +
 +void BKE_scene_free_depsgraph_hash(Scene *scene)
 +{
 +      if (scene->depsgraph_hash == NULL) {
 +              return;
 +      }
 +      BLI_ghash_free(scene->depsgraph_hash,
 +                     depsgraph_key_free,
 +                     depsgraph_key_value_free);
 +}
 +
 +/* Query depsgraph for a specific contexts. */
 +
 +Depsgraph *BKE_scene_get_depsgraph(Scene *scene,
 +                                   ViewLayer *view_layer,
 +                                   bool allocate)
 +{
 +      BLI_assert(scene != NULL);
 +      BLI_assert(view_layer != NULL);
 +      /* Make sure hash itself exists. */
 +      if (allocate) {
 +              BKE_scene_ensure_depsgraph_hash(scene);
 +      }
 +      if (scene->depsgraph_hash == NULL) {
 +              return NULL;
 +      }
 +      /* Either ensure item is in the hash or simply return NULL if it's not,
 +       * depending on whether caller wants us to create depsgraph or not.
 +       */
 +      DepsgraphKey key;
 +      key.view_layer = view_layer;
 +      Depsgraph *depsgraph;
 +      if (allocate) {
 +              DepsgraphKey **key_ptr;
 +              Depsgraph **depsgraph_ptr;
 +              if (!BLI_ghash_ensure_p_ex(scene->depsgraph_hash,
 +                                         &key,
 +                                         (void ***)&key_ptr,
 +                                         (void ***)&depsgraph_ptr))
 +              {
 +                      *key_ptr = MEM_mallocN(sizeof(DepsgraphKey), __func__);
 +                      **key_ptr = key;
 +                      *depsgraph_ptr = DEG_graph_new();
 +              }
 +              depsgraph = *depsgraph_ptr;
 +      }
 +      else {
 +              depsgraph = BLI_ghash_lookup(scene->depsgraph_hash, &key);
 +      }
 +      return depsgraph;
 +}
index 6cc1f37db439d337fad170085620cd9713320106,474b4656a6826b2bd1c9be9e7a17199fbfb95b31..fd32119cb5fa9f22d5d99ddc741cc278377c48b5
  #include "bmesh.h"
  #include "intern/bmesh_private.h" /* for element checking */
  
 -/**
 - * Currently this is only used for Python scripts
 - * which may fail to keep matching UV/TexFace layers.
 - *
 - * \note This should only perform any changes in exceptional cases,
 - * if we need this to be faster we could inline #BM_data_layer_add and only
 - * call #update_data_blocks once at the end.
 - */
 -void BM_mesh_cd_validate(BMesh *bm)
 -{
 -      int totlayer_mtex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
 -      int totlayer_uv = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
 -
 -      if (LIKELY(totlayer_mtex == totlayer_uv)) {
 -              /* pass */
 -      }
 -      else if (totlayer_mtex < totlayer_uv) {
 -              const int uv_index_first = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV);
 -              do {
 -                      const char *from_name =  bm->ldata.layers[uv_index_first + totlayer_mtex].name;
 -                      BM_data_layer_add_named(bm, &bm->pdata, CD_MTEXPOLY, from_name);
 -                      CustomData_set_layer_unique_name(&bm->pdata, totlayer_mtex);
 -              } while (totlayer_uv != ++totlayer_mtex);
 -      }
 -      else if (totlayer_uv < totlayer_mtex) {
 -              const int mtex_index_first = CustomData_get_layer_index(&bm->pdata, CD_MTEXPOLY);
 -              do {
 -                      const char *from_name = bm->pdata.layers[mtex_index_first + totlayer_uv].name;
 -                      BM_data_layer_add_named(bm, &bm->ldata, CD_MLOOPUV, from_name);
 -                      CustomData_set_layer_unique_name(&bm->ldata, totlayer_uv);
 -              } while (totlayer_mtex != ++totlayer_uv);
 -      }
 -
 -      BLI_assert(totlayer_mtex == totlayer_uv);
 -}
 -
  void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
  {
        const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
@@@ -207,7 -243,7 +207,7 @@@ void BM_mesh_bm_from_me
        BMEdge *e, **etable = NULL;
        BMFace *f, **ftable = NULL;
        float (*keyco)[3] = NULL;
 -      int totuv, totloops, i;
 +      int totloops, i;
  
        if (!me || !me->totvert) {
                if (me && is_new) { /*no verts? still copy customdata layout*/
                CustomData_copy(&me->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
                CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
                CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
 -
 -              /* make sure uv layer names are consisten */
 -              totuv = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
 -              for (i = 0; i < totuv; i++) {
 -                      int li = CustomData_get_layer_index_n(&bm->pdata, CD_MTEXPOLY, i);
 -                      CustomData_set_layer_name(&bm->ldata, CD_MLOOPUV, i, bm->pdata.layers[li].name);
 -              }
        }
  
        /* -------------------------------------------------------------------- */
@@@ -708,7 -751,7 +708,7 @@@ void BM_mesh_bm_to_me
        }
  
        /* patch hook indices and vertex parents */
-       if (ototvert > 0) {
+       if (params->calc_object_remap && (ototvert > 0)) {
                Object *ob;
                ModifierData *md;
                BMVert **vertMap = NULL;
                if (vertMap) MEM_freeN(vertMap);
        }
  
-       if (params->calc_tessface) {
-               BKE_mesh_tessface_calc(me);
-       }
-       BKE_mesh_update_customdata_pointers(me, params->calc_tessface);
+       BKE_mesh_update_customdata_pointers(me, false);
  
        {
                BMEditSelection *selected;
index ff1cd7224cd3f21b2811e7a2ee44ab71bb1137f3,c979a73e9645b70985d681b26fb1dd0885c5b74c..a71b03b6ff7a2f290d9600358b25c9193d33b9e6
  #include "BLI_rand.h"
  #include "BLI_sort_utils.h"
  
 +#include "BKE_layer.h"
  #include "BKE_material.h"
  #include "BKE_context.h"
  #include "BKE_deform.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_report.h"
  #include "BKE_texture.h"
  #include "BKE_main.h"
  #include "BKE_editmesh.h"
  
 +#include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_build.h"
 +
  #include "BLT_translation.h"
  
  #include "RNA_define.h"
@@@ -147,8 -144,6 +147,8 @@@ void MESH_OT_subdivide(wmOperatorType *
  
        RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, 1e3f, "Smoothness", "Smoothness factor", 0.0f, 1.0f);
  
 +      WM_operatortype_props_advanced_begin(ot);
 +
        RNA_def_boolean(ot->srna, "quadtri", 0, "Quad/Tri Mode", "Tries to prevent ngons");
        RNA_def_enum(ot->srna, "quadcorner", prop_mesh_cornervert_types, SUBD_CORNER_STRAIGHT_CUT,
                     "Quad Corner Type", "How to subdivide quad corners (anything other than Straight Cut will prevent ngons)");
@@@ -311,7 -306,7 +311,7 @@@ void EMBM_project_snap_verts(bContext *
        ED_view3d_init_mats_rv3d(obedit, ar->regiondata);
  
        struct SnapObjectContext *snap_context = ED_transform_snap_object_context_create_view3d(
 -              CTX_data_main(C), CTX_data_scene(C), 0,
 +              CTX_data_main(C), CTX_data_scene(C), CTX_data_view_layer(C), CTX_data_engine_type(C), 0,
                ar, CTX_wm_view3d(C));
  
        BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
@@@ -865,11 -860,9 +865,11 @@@ void MESH_OT_mark_seam(wmOperatorType *
        
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 -      
 +
        prop = RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
        RNA_def_property_flag(prop, PROP_SKIP_SAVE);
 +
 +      WM_operatortype_props_advanced_begin(ot);
  }
  
  static int edbm_mark_sharp_exec(bContext *C, wmOperator *op)
@@@ -1811,9 -1804,6 +1811,9 @@@ void MESH_OT_vertices_smooth(wmOperator
  
        RNA_def_float(ot->srna, "factor", 0.5f, -10.0f, 10.0f, "Smoothing", "Smoothing factor", 0.0f, 1.0f);
        RNA_def_int(ot->srna, "repeat", 1, 1, 1000, "Repeat", "Number of times to smooth the mesh", 1, 100);
 +
 +      WM_operatortype_props_advanced_begin(ot);
 +
        RNA_def_boolean(ot->srna, "xaxis", true, "X-Axis", "Smooth along the X axis");
        RNA_def_boolean(ot->srna, "yaxis", true, "Y-Axis", "Smooth along the Y axis");
        RNA_def_boolean(ot->srna, "zaxis", true, "Z-Axis", "Smooth along the Z axis");
@@@ -1897,9 -1887,6 +1897,9 @@@ void MESH_OT_vertices_smooth_laplacian(
                      "Lambda factor", "", 1e-7f, 1000.0f);
        RNA_def_float(ot->srna, "lambda_border", 5e-5f, 1e-7f, 1000.0f,
                      "Lambda factor in border", "", 1e-7f, 1000.0f);
 +
 +      WM_operatortype_props_advanced_begin(ot);
 +
        RNA_def_boolean(ot->srna, "use_x", true, "Smooth X Axis", "Smooth object along X axis");
        RNA_def_boolean(ot->srna, "use_y", true, "Smooth Y Axis", "Smooth object along Y axis");
        RNA_def_boolean(ot->srna, "use_z", true, "Smooth Z Axis", "Smooth object along Z axis");
@@@ -2355,9 -2342,6 +2355,9 @@@ void MESH_OT_merge(wmOperatorType *ot
        /* properties */
        ot->prop = RNA_def_enum(ot->srna, "type", merge_type_items, MESH_MERGE_CENTER, "Type", "Merge method to use");
        RNA_def_enum_funcs(ot->prop, merge_type_itemf);
 +
 +      WM_operatortype_props_advanced_begin(ot);
 +
        RNA_def_boolean(ot->srna, "uvs", false, "UVs", "Move UVs according to merge");
  }
  
@@@ -2469,7 -2453,7 +2469,7 @@@ static void shape_propagate(BMEditMesh 
        //TAG Mesh Objects that share this data
        for (base = scene->base.first; base; base = base->next) {
                if (base->object && base->object->data == me) {
 -                      DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
 +                      DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
                }
        }
  #endif
@@@ -3032,7 -3016,7 +3032,7 @@@ enum 
        MESH_SEPARATE_LOOSE    = 2,
  };
  
 -static Base *mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 +static Base *mesh_separate_tagged(Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base_old, BMesh *bm_old)
  {
        Base *base_new;
        Object *obedit = base_old->object;
        CustomData_bmesh_init_pool(&bm_new->ldata, bm_mesh_allocsize_default.totloop, BM_LOOP);
        CustomData_bmesh_init_pool(&bm_new->pdata, bm_mesh_allocsize_default.totface, BM_FACE);
  
 -      base_new = ED_object_add_duplicate(bmain, scene, base_old, USER_DUP_MESH);
 +      base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_old, USER_DUP_MESH);
        /* DAG_relations_tag_update(bmain); */ /* normally would call directly after but in this case delay recalc */
        assign_matarar(base_new->object, give_matarar(obedit), *give_totcolp(obedit)); /* new in 2.5 */
  
 -      ED_base_object_select(base_new, BA_SELECT);
 +      ED_object_base_select(base_new, BA_SELECT);
  
        BMO_op_callf(bm_old, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
                     "duplicate geom=%hvef dest=%p", BM_ELEM_TAG, bm_new);
        return base_new;
  }
  
 -static bool mesh_separate_selected(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 +static bool mesh_separate_selected(Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base_old, BMesh *bm_old)
  {
        /* we may have tags from previous operators */
        BM_mesh_elem_hflag_disable_all(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, false);
        /* sel -> tag */
        BM_mesh_elem_hflag_enable_test(bm_old, BM_FACE | BM_EDGE | BM_VERT, BM_ELEM_TAG, true, false, BM_ELEM_SELECT);
  
 -      return (mesh_separate_tagged(bmain, scene, base_old, bm_old) != NULL);
 +      return (mesh_separate_tagged(bmain, scene, view_layer, base_old, bm_old) != NULL);
  }
  
  /* flush a hflag to from verts to edges/faces */
@@@ -3186,7 -3170,7 +3186,7 @@@ static void mesh_separate_material_assi
        }
  }
  
 -static bool mesh_separate_material(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 +static bool mesh_separate_material(Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base_old, BMesh *bm_old)
  {
        BMFace *f_cmp, *f;
        BMIter iter;
                }
  
                /* Move selection into a separate object */
 -              base_new = mesh_separate_tagged(bmain, scene, base_old, bm_old);
 +              base_new = mesh_separate_tagged(bmain, scene, view_layer, base_old, bm_old);
                if (base_new) {
                        mesh_separate_material_assign_mat_nr(bmain, base_new->object, mat_nr);
                }
        return result;
  }
  
 -static bool mesh_separate_loose(Main *bmain, Scene *scene, Base *base_old, BMesh *bm_old)
 +static bool mesh_separate_loose(Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base_old, BMesh *bm_old)
  {
        int i;
        BMEdge *e;
                bm_mesh_hflag_flush_vert(bm_old, BM_ELEM_TAG);
  
                /* Move selection into a separate object */
 -              result |= (mesh_separate_tagged(bmain, scene, base_old, bm_old) != NULL);
 +              result |= (mesh_separate_tagged(bmain, scene, view_layer, base_old, bm_old) != NULL);
        }
  
        return result;
@@@ -3301,7 -3285,6 +3301,7 @@@ static int edbm_separate_exec(bContext 
  {
        Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
        const int type = RNA_enum_get(op->ptr, "type");
        int retval = 0;
        
                /* editmode separate */
                switch (type) {
                        case MESH_SEPARATE_SELECTED:
 -                              retval = mesh_separate_selected(bmain, scene, base, em->bm);
 +                              retval = mesh_separate_selected(bmain, scene, view_layer, base, em->bm);
                                break;
                        case MESH_SEPARATE_MATERIAL:
 -                              retval = mesh_separate_material(bmain, scene, base, em->bm);
 +                              retval = mesh_separate_material(bmain, scene, view_layer, base, em->bm);
                                break;
                        case MESH_SEPARATE_LOOSE:
 -                              retval = mesh_separate_loose(bmain, scene, base, em->bm);
 +                              retval = mesh_separate_loose(bmain, scene, view_layer, base, em->bm);
                                break;
                        default:
                                BLI_assert(0);
  
                                        switch (type) {
                                                case MESH_SEPARATE_MATERIAL:
 -                                                      retval_iter = mesh_separate_material(bmain, scene, base_iter, bm_old);
 +                                                      retval_iter = mesh_separate_material(bmain, scene, view_layer, base_iter, bm_old);
                                                        break;
                                                case MESH_SEPARATE_LOOSE:
 -                                                      retval_iter = mesh_separate_loose(bmain, scene, base_iter, bm_old);
 +                                                      retval_iter = mesh_separate_loose(bmain, scene, view_layer, base_iter, bm_old);
                                                        break;
                                                default:
                                                        BLI_assert(0);
                                        }
  
                                        if (retval_iter) {
-                                               BM_mesh_bm_to_me(bm_old, me, (&(struct BMeshToMeshParams){0}));
+                                               BM_mesh_bm_to_me(
+                                                       bm_old, me,
+                                                       (&(struct BMeshToMeshParams){
+                                                           .calc_object_remap = true,
+                                                       }));
  
 -                                              DAG_id_tag_update(&me->id, OB_RECALC_DATA);
 +                                              DEG_id_tag_update(&me->id, OB_RECALC_DATA);
                                                WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
                                        }
  
  
        if (retval) {
                /* delay depsgraph recalc until all objects are duplicated */
 -              DAG_relations_tag_update(bmain);
 +              DEG_relations_tag_update(bmain);
                WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
  
                return OPERATOR_FINISHED;
@@@ -5082,7 -5069,7 +5086,7 @@@ static void sort_bmelem_flag(Scene *sce
        }
  
        BM_mesh_remap(em->bm, map[0], map[1], map[2]);
 -/*    DAG_id_tag_update(ob->data, 0);*/
 +/*    DEG_id_tag_update(ob->data, 0);*/
  
        for (j = 3; j--; ) {
                if (map[j])
@@@ -5909,7 -5896,7 +5913,7 @@@ static int edbm_mark_freestyle_edge_exe
                }
        }
  
 -      DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
 +      DEG_id_tag_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
  
        return OPERATOR_FINISHED;
@@@ -5973,7 -5960,7 +5977,7 @@@ static int edbm_mark_freestyle_face_exe
                }
        }
  
 -      DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
 +      DEG_id_tag_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
  
        return OPERATOR_FINISHED;
index 132ac0d30b73bb5f72002e712f2ed8015211b3ce,c4440fa190ad463a6675b6d0e6c1d69227034cf7..7b727e75b559f2245c291d945d36466afc6d8406
@@@ -44,6 -44,7 +44,6 @@@
  #include "BKE_DerivedMesh.h"
  #include "BKE_context.h"
  #include "BKE_global.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_main.h"
  #include "BKE_mesh.h"
  #include "BKE_mesh_mapping.h"
@@@ -51,8 -52,6 +51,8 @@@
  #include "BKE_editmesh.h"
  #include "BKE_editmesh_bvh.h"
  
 +#include "DEG_depsgraph.h"
 +
  #include "BKE_object.h"  /* XXX. only for EDBM_mesh_load(). */
  
  #include "WM_api.h"
@@@ -368,7 -367,7 +368,7 @@@ void EDBM_mesh_make(ToolSettings *ts, O
  
  /**
   * \warning This can invalidate the #DerivedMesh cache of other objects (for linked duplicates).
 - * Most callers should run #DAG_id_tag_update on \a ob->data, see: T46738, T46913
 + * Most callers should run #DEG_id_tag_update on \a ob->data, see: T46738, T46913
   */
  void EDBM_mesh_load(Object *ob)
  {
                bm->shapenr = 1;
        }
  
-       BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){0}));
+       BM_mesh_bm_to_me(
+               bm, me, (&(struct BMeshToMeshParams){
+                   .calc_object_remap = true,
+               }));
  
  #ifdef USE_TESSFACE_DEFAULT
        BKE_mesh_tessface_calc(me);
@@@ -508,6 -510,7 +511,6 @@@ UvVertMap *BM_uv_vert_map_create
        /* vars from original func */
        UvVertMap *vmap;
        UvMapVert *buf;
 -      /* MTexPoly *tf; */ /* UNUSED */
        MLoopUV *luv;
        unsigned int a;
        int totverts, i, totuv, totfaces;
                        newvlist = v;
  
                        efa = BM_face_at_index(bm, v->f);
 -                      /* tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
                        
                        l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, v->tfindex);
                        luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
                        while (iterv) {
                                next = iterv->next;
                                efa = BM_face_at_index(bm, iterv->f);
 -                              /* tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY); */ /* UNUSED */
                                
                                l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex);
                                luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@@ -914,27 -919,29 +917,27 @@@ UvElement *BM_uv_element_get(UvElementM
  
  /* last_sel, use em->act_face otherwise get the last selected face in the editselections
   * at the moment, last_sel is mainly useful for making sure the space image dosnt flicker */
 -MTexPoly *EDBM_mtexpoly_active_get(BMEditMesh *em, BMFace **r_act_efa, const bool sloppy, const bool selected)
 +BMFace *EDBM_uv_active_face_get(BMEditMesh *em, const bool sloppy, const bool selected)
  {
        BMFace *efa = NULL;
        
 -      if (!EDBM_mtexpoly_check(em))
 +      if (!EDBM_uv_check(em))
                return NULL;
        
        efa = BM_mesh_active_face_get(em->bm, sloppy, selected);
  
        if (efa) {
 -              if (r_act_efa) *r_act_efa = efa;
 -              return CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 +              return efa;
        }
  
 -      if (r_act_efa) *r_act_efa = NULL;
        return NULL;
  }
  
  /* can we edit UV's for this mesh?*/
 -bool EDBM_mtexpoly_check(BMEditMesh *em)
 +bool EDBM_uv_check(BMEditMesh *em)
  {
        /* some of these checks could be a touch overkill */
 -      return em && em->bm->totface && CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY) &&
 +      return em && em->bm->totface &&
               CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV);
  }
  
@@@ -1013,7 -1020,7 +1016,7 @@@ void EDBM_verts_mirror_cache_begin_ex(B
        BM_mesh_elem_index_ensure(bm, BM_VERT);
  
        if (use_topology) {
 -              ED_mesh_mirrtopo_init(me, NULL, -1, &mesh_topo_store, true);
 +              ED_mesh_mirrtopo_init(me, NULL, &mesh_topo_store, true);
        }
        else {
                tree = BLI_kdtree_new(bm->totvert);
@@@ -1263,7 -1270,7 +1266,7 @@@ void EDBM_update_generic(BMEditMesh *em
  {
        Object *ob = em->ob;
        /* order of calling isn't important */
 -      DAG_id_tag_update(ob->data, OB_RECALC_DATA);
 +      DEG_id_tag_update(ob->data, OB_RECALC_DATA);
        WM_main_add_notifier(NC_GEOM | ND_DATA, ob->data);
  
        if (do_tessface) {
@@@ -1392,9 -1399,7 +1395,9 @@@ static void scale_point(float c1[3], co
        add_v3_v3(c1, p);
  }
  
 -bool BMBVH_EdgeVisible(struct BMBVHTree *tree, BMEdge *e, ARegion *ar, View3D *v3d, Object *obedit)
 +bool BMBVH_EdgeVisible(struct BMBVHTree *tree, BMEdge *e,
 +                       const struct Depsgraph *depsgraph,
 +                       ARegion *ar, View3D *v3d, Object *obedit)
  {
        BMFace *f;
        float co1[3], co2[3], co3[3], dir1[3], dir2[3], dir3[3];
        const float mval_f[2] = {ar->winx / 2.0f,
                                 ar->winy / 2.0f};
  
 -      ED_view3d_win_to_segment(ar, v3d, mval_f, origin, end, false);
 +      ED_view3d_win_to_segment(depsgraph, ar, v3d, mval_f, origin, end, false);
  
        invert_m4_m4(invmat, obedit->obmat);
        mul_m4_v3(invmat, origin);
index 629c3a3c7a33abcaf65ce45496079d33054e812e,2866683b89b81a1ea47dbebfb0c17c70738e7791..ec787768a57bb36bebe8273d537c03a486aee6bb
  #include "DNA_object_types.h"
  #include "DNA_material_types.h"
  
 -#include "BKE_depsgraph.h"
  #include "BKE_customdata.h"
  #include "BKE_DerivedMesh.h"
  
 +#include "DEG_depsgraph.h"
 +
  #include "bmesh.h"
  
  #include <Python.h>
@@@ -902,11 -901,18 +902,15 @@@ static PyObject *bpy_bmesh_to_mesh(BPy_
  
        bm = self->bm;
  
-       BM_mesh_bm_to_me(bm, me, (&(struct BMeshToMeshParams){0}));
 -      /* python won't ensure matching uv/mtex */
 -      BM_mesh_cd_validate(bm);
 -
+       BM_mesh_bm_to_me(
+               bm, me,
+               (&(struct BMeshToMeshParams){
+                   .calc_object_remap = true,
+               }));
  
        /* we could have the user do this but if they forget blender can easy crash
         * since the references arrays for the objects derived meshes are now invalid */
 -      DAG_id_tag_update(&me->id, OB_RECALC_DATA);
 +      DEG_id_tag_update(&me->id, OB_RECALC_DATA);
  
        Py_RETURN_NONE;
  }
@@@ -929,8 -935,6 +933,8 @@@ PyDoc_STRVAR(bpy_bmesh_from_object_doc
  );
  static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject *kw)
  {
 +      /* TODO: This doesn't work currently because of eval_ctx. */
 +#if 0
        static const char *kwlist[] = {"object", "scene", "deform", "render", "cage", "face_normals", NULL};
        PyObject *py_object;
        PyObject *py_scene;
        dm->release(dm);
  
        Py_RETURN_NONE;
 +#else
 +      UNUSED_VARS(self, args, kw);
 +#endif
 +      return NULL;
  }