Merge branch 'master' into blender2.8
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 23 Nov 2017 10:42:06 +0000 (11:42 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 23 Nov 2017 10:47:47 +0000 (11:47 +0100)
12 files changed:
1  2 
source/blender/depsgraph/DEG_depsgraph_build.h
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_nodes.h
source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.h
source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
source/blender/depsgraph/intern/depsgraph.cc
source/blender/depsgraph/intern/depsgraph_build.cc
source/blender/depsgraph/intern/depsgraph_query.cc
source/blender/depsgraph/intern/eval/deg_eval_flush.cc
source/blender/depsgraph/intern/nodes/deg_node_component.cc

index c85c15e2aa2609b027bcca16fc50e9f67aea6fbc,b268822f659e5099e81c9cc080ab7b6c71434ede..334b15cc63886fdc18d0978bc16cbaff8df9bccb
@@@ -159,8 -164,9 +159,8 @@@ typedef bool (*DEG_CollobjFilterFunctio
  
  void DEG_add_collision_relations(struct DepsNodeHandle *handle,
                                   struct Scene *scene,
-                                  struct Object *ob,
+                                  struct Object *object,
                                   struct Group *group,
 -                                 int layer,
                                   unsigned int modifier_type,
                                   DEG_CollobjFilterFunction fn,
                                   bool dupli,
index ae6be5256dd0875bc60b480915fcc3710b60496b,60150eda0bf72ec3a84911b5b908a3017ecd9a3c..aea74af68614ca698d6f575b76c63e5ad0711ecf
@@@ -396,38 -309,48 +396,38 @@@ void DepsgraphNodeBuilder::build_group(
        }
  }
  
- void DepsgraphNodeBuilder::build_object(Object *ob,
 -void DepsgraphNodeBuilder::build_object(Base *base, Object *object)
++void DepsgraphNodeBuilder::build_object(Object *object,
 +                                        eDepsNode_LinkedState_Type linked_state)
  {
 -      const bool has_object = (object->id.tag & LIB_TAG_DOIT);
 -      IDDepsNode *id_node = (has_object)
 -              ? graph_->find_id_node(&object->id)
 -              : add_id_node(&object->id);
 -      /* Update node layers.
 -       * Do it for both new and existing ID nodes. This is so because several
 -       * bases might be sharing same object.
 -       */
 -      if (base != NULL) {
 -              id_node->layers |= base->lay;
 -      }
 -      if (object->type == OB_CAMERA) {
 -              /* Camera should always be updated, it used directly by viewport.
 -               *
 -               * TODO(sergey): Make it only for active scene camera.
 -               */
 -              id_node->layers |= (unsigned int)(-1);
 -      }
        /* Skip rest of components if the ID node was already there. */
-       if (ob->id.tag & LIB_TAG_DOIT) {
-               IDDepsNode *id_node = find_id_node(&ob->id);
 -      if (has_object) {
++      if (object->id.tag & LIB_TAG_DOIT) {
++              IDDepsNode *id_node = find_id_node(&object->id);
 +              id_node->linked_state = max(id_node->linked_state, linked_state);
                return;
        }
-       ob->id.tag |= LIB_TAG_DOIT;
+       object->id.tag |= LIB_TAG_DOIT;
 +
 +      /* Create ID node for object and begin init. */
-       IDDepsNode *id_node = add_id_node(&ob->id);
++      IDDepsNode *id_node = add_id_node(&object->id);
 +      id_node->linked_state = linked_state;
 +
-       ob->customdata_mask = 0;
+       object->customdata_mask = 0;
  
        /* Standard components. */
-       build_object_transform(ob);
+       build_object_transform(object);
  
-       if (ob->parent != NULL) {
-               build_object(ob->parent, linked_state);
+       if (object->parent != NULL) {
 -              build_object(NULL, object->parent);
++              build_object(object->parent, linked_state);
        }
-       if (ob->modifiers.first != NULL) {
+       if (object->modifiers.first != NULL) {
                BuilderWalkUserData data;
                data.builder = this;
-               modifiers_foreachObjectLink(ob, modifier_walk, &data);
+               modifiers_foreachObjectLink(object, modifier_walk, &data);
        }
-       if (ob->constraints.first != NULL) {
+       if (object->constraints.first != NULL) {
                BuilderWalkUserData data;
                data.builder = this;
-               BKE_constraints_id_loop(&ob->constraints, constraint_walk, &data);
+               BKE_constraints_id_loop(&object->constraints, constraint_walk, &data);
        }
  
        /* Object data. */
                                break;
  
                        case OB_CAMERA: /* Camera */
-                               build_camera(ob);
+                               build_camera(object);
                                break;
  
-                               build_lightprobe(ob);
 +                      case OB_LIGHTPROBE:
++                              build_lightprobe(object);
 +                              break;
 +
                        default:
                        {
-                               ID *obdata = (ID *)ob->data;
+                               ID *obdata = (ID *)object->data;
                                if ((obdata->tag & LIB_TAG_DOIT) == 0) {
                                        build_animdata(obdata);
                                }
        }
  
        /* Object that this is a proxy for. */
-       if (ob->proxy) {
-               ob->proxy->proxy_from = ob;
-               build_object(ob->proxy, DEG_ID_LINKED_INDIRECTLY);
+       if (object->proxy) {
+               object->proxy->proxy_from = object;
 -              build_object(base, object->proxy);
++              build_object(object->proxy, DEG_ID_LINKED_INDIRECTLY);
        }
  
        /* Object dupligroup. */
-       if (ob->dup_group != NULL) {
-               build_group(ob->dup_group);
+       if (object->dup_group != NULL) {
 -              build_group(base, object->dup_group);
++              build_group(object->dup_group);
        }
  }
  
- void DepsgraphNodeBuilder::build_object_transform(Object *ob)
+ void DepsgraphNodeBuilder::build_object_transform(Object *object)
  {
        OperationDepsNode *op_node;
-       Object *ob_cow = get_cow_datablock(ob);
 +      Scene *scene_cow = get_cow_datablock(scene_);
++      Object *ob_cow = get_cow_datablock(object);
  
        /* local transforms (from transform channels - loc/rot/scale + deltas) */
-       op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+       op_node = add_operation_node(&object->id, DEG_NODE_TYPE_TRANSFORM,
 -                                   function_bind(BKE_object_eval_local_transform, _1, scene_, object),
 +                                   function_bind(BKE_object_eval_local_transform,
 +                                                 _1,
 +                                                 scene_cow,
 +                                                 ob_cow),
                                     DEG_OPCODE_TRANSFORM_LOCAL);
        op_node->set_as_entry();
  
        /* object parent */
-       if (ob->parent != NULL) {
-               add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
 -      if (object->parent) {
++      if (object->parent != NULL) {
+               add_operation_node(&object->id, DEG_NODE_TYPE_TRANSFORM,
 -                                 function_bind(BKE_object_eval_parent, _1, scene_, object),
 +                                 function_bind(BKE_object_eval_parent,
 +                                               _1,
 +                                               scene_cow,
 +                                               ob_cow),
                                   DEG_OPCODE_TRANSFORM_PARENT);
        }
  
        /* object constraints */
-       if (ob->constraints.first != NULL) {
-               build_object_constraints(ob);
 -      if (object->constraints.first) {
++      if (object->constraints.first != NULL) {
+               build_object_constraints(object);
        }
  
 -      /* Temporary uber-update node, which does everything.
 -       * It is for the being we're porting old dependencies into the new system.
 -       * We'll get rid of this node as soon as all the granular update functions
 -       * are filled in.
 -       *
 -       * TODO(sergey): Get rid of this node.
 -       */
 +      /* Rest of transformation update. */
-       add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+       add_operation_node(&object->id, DEG_NODE_TYPE_TRANSFORM,
 -                         function_bind(BKE_object_eval_uber_transform, _1, scene_, object),
 +                         function_bind(BKE_object_eval_uber_transform,
 +                                       _1,
 +                                       scene_cow,
 +                                       ob_cow),
                           DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL);
  
        /* object transform is done */
-       op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+       op_node = add_operation_node(&object->id, DEG_NODE_TYPE_TRANSFORM,
 -                                   function_bind(BKE_object_eval_done, _1, object),
 +                                   function_bind(BKE_object_eval_done,
 +                                                 _1,
 +                                                 ob_cow),
                                     DEG_OPCODE_TRANSFORM_FINAL);
        op_node->set_as_exit();
  }
   *
   * -- Aligorith, August 2013
   */
- void DepsgraphNodeBuilder::build_object_constraints(Object *ob)
+ void DepsgraphNodeBuilder::build_object_constraints(Object *object)
  {
        /* create node for constraint stack */
-       add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+       add_operation_node(&object->id, DEG_NODE_TYPE_TRANSFORM,
 -                         function_bind(BKE_object_eval_constraints, _1, scene_, object),
 +                         function_bind(BKE_object_eval_constraints,
 +                                       _1,
 +                                       get_cow_datablock(scene_),
-                                        get_cow_datablock(ob)),
++                                       get_cow_datablock(object)),
                           DEG_OPCODE_TRANSFORM_CONSTRAINTS);
  }
  
@@@ -752,14 -638,9 +752,14 @@@ void DepsgraphNodeBuilder::build_rigidb
                                continue;
  
                        /* 2) create operation for flushing results */
 -                      /* object's transform component - where the rigidbody operation lives */
 +                      /* object's transform component - where the rigidbody operation
 +                       * lives. */
-                       add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+                       add_operation_node(&object->id, DEG_NODE_TYPE_TRANSFORM,
 -                                         function_bind(BKE_rigidbody_object_sync_transforms, _1, scene, object),
 +                                         function_bind(
 +                                                 BKE_rigidbody_object_sync_transforms,
 +                                                 _1,
 +                                                 scene_cow,
-                                                  get_cow_datablock(ob)),
++                                                 get_cow_datablock(object)),
                                           DEG_OPCODE_RIGIDBODY_TRANSFORM_COPY);
                }
        }
@@@ -784,12 -665,8 +784,12 @@@ void DepsgraphNodeBuilder::build_partic
  
        /* component for all particle systems */
        ComponentDepsNode *psys_comp =
-               add_component_node(&ob->id, DEG_NODE_TYPE_EVAL_PARTICLES);
+               add_component_node(&object->id, DEG_NODE_TYPE_EVAL_PARTICLES);
  
-       Object *ob_cow = get_cow_datablock(ob);
 +      /* TODO(sergey): Need to get COW of PSYS. */
 +      Scene *scene_cow = get_cow_datablock(scene_);
++      Object *ob_cow = get_cow_datablock(object);
 +
        add_operation_node(psys_comp,
                           function_bind(BKE_particle_system_eval_init,
                                         _1,
                           DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT);
  
        /* particle systems */
-       LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
+       LINKLIST_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
                ParticleSettings *part = psys->part;
  
 -              /* particle settings */
 -              // XXX: what if this is used more than once!
 -              build_animdata(&part->id);
 +              /* Build particle settings operations.
 +               *
 +               * NOTE: The call itself ensures settings are only build once.
 +               */
 +              build_particle_settings(part);
  
 -              /* this particle system */
 -              // TODO: for now, this will just be a placeholder "ubereval" node
 +              /* Update on particle settings change. */
 +              add_operation_node(psys_comp,
 +                                 function_bind(BKE_particle_system_settings_eval,
 +                                               _1,
 +                                               psys),
 +                                 DEG_OPCODE_PARTICLE_SETTINGS_EVAL,
 +                                 psys->name);
 +
 +              /* Particle system evaluation. */
                add_operation_node(psys_comp,
                                   NULL,
                                   DEG_OPCODE_PARTICLE_SYSTEM_EVAL,
@@@ -871,11 -717,10 +871,11 @@@ void DepsgraphNodeBuilder::build_shapek
  
  /* ObData Geometry Evaluation */
  // XXX: what happens if the datablock is shared!
- void DepsgraphNodeBuilder::build_obdata_geom(Object *ob)
+ void DepsgraphNodeBuilder::build_obdata_geom(Object *object)
  {
 -      ID *obdata = (ID *)object->data;
        OperationDepsNode *op_node;
-       Object *object_cow = get_cow_datablock(ob);
 +      Scene *scene_cow = get_cow_datablock(scene_);
++      Object *object_cow = get_cow_datablock(object);
  
        /* TODO(sergey): This way using this object's properties as driver target
         * works fine.
        }
  
        /* materials */
-       if (ob->totcol != 0) {
-               if (ob->type == OB_MESH) {
-                       add_operation_node(&ob->id,
 -      for (int a = 1; a <= object->totcol; a++) {
 -              Material *ma = give_current_material(object, a);
 -              if (ma != NULL) {
 -                      build_material(ma);
++      if (object->totcol != 0) {
++              if (object->type == OB_MESH) {
++                      add_operation_node(&object->id,
 +                                         DEG_NODE_TYPE_SHADING,
 +                                         function_bind(BKE_object_eval_update_shading,
 +                                                       _1,
 +                                                       object_cow),
 +                                         DEG_OPCODE_SHADING);
 +              }
 +
-               for (int a = 1; a <= ob->totcol; a++) {
-                       Material *ma = give_current_material(ob, a);
++              for (int a = 1; a <= object->totcol; a++) {
++                      Material *ma = give_current_material(object, a);
 +                      if (ma != NULL) {
 +                              build_material(ma);
 +                      }
                }
        }
  
                // add geometry collider relations
        }
  
-       ID *obdata = (ID *)ob->data;
++      ID *obdata = (ID *)object->data;
        if (obdata->tag & LIB_TAG_DOIT) {
                return;
        }
 +      obdata->tag |= LIB_TAG_DOIT;
 +      /* Make sure we've got an ID node before requesting CoW pointer. */
 +      (void) add_id_node((ID *)obdata);
 +      ID *obdata_cow = get_cow_id(obdata);
  
        /* ShapeKeys */
-       Key *key = BKE_key_from_object(ob);
+       Key *key = BKE_key_from_object(object);
        if (key) {
                build_shapekeys(key);
        }
                         */
                        Curve *cu = (Curve *)obdata;
                        if (cu->bevobj != NULL) {
 -                              build_object(NULL, cu->bevobj);
 +                              build_object(cu->bevobj, DEG_ID_LINKED_INDIRECTLY);
                        }
                        if (cu->taperobj != NULL) {
 -                              build_object(NULL, cu->taperobj);
 +                              build_object(cu->taperobj, DEG_ID_LINKED_INDIRECTLY);
                        }
-                       if (ob->type == OB_FONT && cu->textoncurve != NULL) {
+                       if (object->type == OB_FONT && cu->textoncurve != NULL) {
 -                              build_object(NULL, cu->textoncurve);
 +                              build_object(cu->textoncurve, DEG_ID_LINKED_INDIRECTLY);
                        }
                        break;
                }
  }
  
  /* Cameras */
- void DepsgraphNodeBuilder::build_camera(Object *ob)
+ void DepsgraphNodeBuilder::build_camera(Object *object)
  {
 -      /* TODO: Link scene-camera links in somehow... */
 +      /* Object itself. */
-       add_operation_node(&ob->id,
++      add_operation_node(&object->id,
 +                         DEG_NODE_TYPE_PARAMETERS,
 +                         NULL,
 +                         DEG_OPCODE_PARAMETERS_EVAL,
 +                         "Camera Parameters");
 +
 +      /* Object data. */
 +      /* TODO: Link scene-camera links in somehow. */
-       Camera *cam = (Camera *)ob->data;
+       Camera *cam = (Camera *)object->data;
        ID *camera_id = &cam->id;
        if (camera_id->tag & LIB_TAG_DOIT) {
                return;
  }
  
  /* Lamps */
- void DepsgraphNodeBuilder::build_lamp(Object *ob)
+ void DepsgraphNodeBuilder::build_lamp(Object *object)
  {
-       add_operation_node(&ob->id,
 +      /* Object itself. */
-       Lamp *la = (Lamp *)ob->data;
++      add_operation_node(&object->id,
 +                         DEG_NODE_TYPE_PARAMETERS,
 +                         NULL,
 +                         DEG_OPCODE_PARAMETERS_EVAL,
 +                         "Lamp Parameters");
 +
 +      /* Object data. */
+       Lamp *la = (Lamp *)object->data;
        ID *lamp_id = &la->id;
        if (lamp_id->tag & LIB_TAG_DOIT) {
                return;
index 76977aa7e5ba94e4658ce72d7b21ab4b91464b70,cd1355558ea360c315c1b4c88735022602f01a1e..a956c94a6824b425d6d5d6a5f868bce1e19cd2c9
@@@ -157,18 -118,14 +157,18 @@@ struct DepsgraphNodeBuilder 
                                               const char *name = "",
                                               int name_tag = -1);
  
 -      void build_scene(Scene *scene);
 -      void build_group(Base *base, Group *group);
 -      void build_object(Base *base, Object *object);
 +      void build_view_layer(Scene *scene,
 +                             ViewLayer *view_layer,
 +                             eDepsNode_LinkedState_Type linked_state);
 +      void build_group(Group *group);
-       void build_object(Object *ob,
++      void build_object(Object *object,
 +                        eDepsNode_LinkedState_Type linked_state);
-       void build_object_transform(Object *ob);
-       void build_object_constraints(Object *ob);
-       void build_pose_constraints(Object *ob, bPoseChannel *pchan);
+       void build_object_transform(Object *object);
+       void build_object_constraints(Object *object);
+       void build_pose_constraints(Object *object, bPoseChannel *pchan);
        void build_rigidbody(Scene *scene);
-       void build_particles(Object *ob);
+       void build_particles(Object *object);
 +      void build_particle_settings(ParticleSettings *part);
        void build_cloth(Object *object);
        void build_animdata(ID *id);
        OperationDepsNode *build_driver(ID *id, FCurve *fcurve);
index 82b20a0d23c1be75df00a6321beb928105f5a42e,caf6f60165c0b879a8dc21f9b74caa4f8cd21694..70dfb3b800799ce2d5dbcfe52f9907c610cd913f
@@@ -66,23 -64,16 +66,23 @@@ extern "C" 
  
  namespace DEG {
  
- void DepsgraphNodeBuilder::build_pose_constraints(Object *ob,
 -void DepsgraphNodeBuilder::build_pose_constraints(Object *object, bPoseChannel *pchan)
++void DepsgraphNodeBuilder::build_pose_constraints(Object *object,
 +                                                  bPoseChannel *pchan)
  {
        /* create node for constraint stack */
-       add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name,
+       add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
 -                         function_bind(BKE_pose_constraints_evaluate, _1, scene_, object, pchan),
 +                         function_bind(BKE_pose_constraints_evaluate,
 +                                       _1,
 +                                       get_cow_datablock(scene_),
-                                        get_cow_datablock(ob),
++                                       get_cow_datablock(object),
 +                                       pchan),
                           DEG_OPCODE_BONE_CONSTRAINTS);
  }
  
  /* IK Solver Eval Steps */
- void DepsgraphNodeBuilder::build_ik_pose(Object *ob,
 -void DepsgraphNodeBuilder::build_ik_pose(Object *object, bPoseChannel *pchan, bConstraint *con)
++void DepsgraphNodeBuilder::build_ik_pose(Object *object,
 +                                         bPoseChannel *pchan,
 +                                         bConstraint *con)
  {
        bKinematicConstraint *data = (bKinematicConstraint *)con->data;
  
        }
  
        /* Operation node for evaluating/running IK Solver. */
-       add_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
+       add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
 -                         function_bind(BKE_pose_iktree_evaluate, _1, scene_, object, rootchan),
 +                         function_bind(BKE_pose_iktree_evaluate,
 +                                       _1,
 +                                       get_cow_datablock(scene_),
-                                        get_cow_datablock(ob),
++                                       get_cow_datablock(object),
 +                                       rootchan),
                           DEG_OPCODE_POSE_IK_SOLVER);
  }
  
  /* Spline IK Eval Steps */
- void DepsgraphNodeBuilder::build_splineik_pose(Object *ob,
 -void DepsgraphNodeBuilder::build_splineik_pose(Object *object, bPoseChannel *pchan, bConstraint *con)
++void DepsgraphNodeBuilder::build_splineik_pose(Object *object,
 +                                               bPoseChannel *pchan,
 +                                               bConstraint *con)
  {
        bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
  
        bPoseChannel *rootchan = BKE_armature_splineik_solver_find_root(pchan, data);
  
        /* Operation node for evaluating/running Spline IK Solver.
 -       * Store the "root bone" of this chain in the solver, so it knows where to start.
 +       * Store the "root bone" of this chain in the solver, so it knows where to
 +       * start.
         */
-       add_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
+       add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
 -                         function_bind(BKE_pose_splineik_evaluate, _1, scene_, object, rootchan),
 +                         function_bind(BKE_pose_splineik_evaluate,
 +                                       _1,
 +                                       get_cow_datablock(scene_),
-                                        get_cow_datablock(ob),
++                                       get_cow_datablock(object),
 +                                       rootchan),
                           DEG_OPCODE_POSE_SPLINE_IK_SOLVER);
  }
  
@@@ -308,53 -247,42 +308,53 @@@ void DepsgraphNodeBuilder::build_rig(Ob
        }
  }
  
- void DepsgraphNodeBuilder::build_proxy_rig(Object *ob)
+ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
  {
-       ID *obdata = (ID *)ob->data;
+       ID *obdata = (ID *)object->data;
        OperationDepsNode *op_node;
-       Object *object_cow = get_cow_datablock(ob);
 -
 -      build_animdata(obdata);
 -
++      Object *object_cow = get_cow_datablock(object);
 +      /* Sanity check. */
-       BLI_assert(ob->pose != NULL);
+       BLI_assert(object->pose != NULL);
 -
 +      /* Animation. */
 +      build_animdata(obdata);
        /* speed optimization for animation lookups */
-       BKE_pose_channels_hash_make(ob->pose);
-       if (ob->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
-               BKE_pose_update_constraint_flags(ob->pose);
+       BKE_pose_channels_hash_make(object->pose);
+       if (object->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
+               BKE_pose_update_constraint_flags(object->pose);
        }
-       op_node = add_operation_node(&ob->id,
 -
+       op_node = add_operation_node(&object->id,
                                     DEG_NODE_TYPE_EVAL_POSE,
 -                                   function_bind(BKE_pose_eval_proxy_copy, _1, object),
 +                                   function_bind(BKE_pose_eval_proxy_copy,
 +                                                 _1,
 +                                                 object_cow),
                                     DEG_OPCODE_POSE_INIT);
        op_node->set_as_entry();
-       LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
 -
+       LINKLIST_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
 -              op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
 -                                           NULL, DEG_OPCODE_BONE_LOCAL);
 +              /* Local bone transform. */
-               op_node = add_operation_node(&ob->id,
++              op_node = add_operation_node(&object->id,
 +                                           DEG_NODE_TYPE_BONE,
 +                                           pchan->name,
 +                                           NULL,
 +                                           DEG_OPCODE_BONE_LOCAL);
                op_node->set_as_entry();
 -
 -              add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
 -                                 NULL, DEG_OPCODE_BONE_READY);
 -
 -              op_node = add_operation_node(&object->id, DEG_NODE_TYPE_BONE, pchan->name,
 -                                           NULL, DEG_OPCODE_BONE_DONE);
 +              /* Bone is ready for solvers. */
-               add_operation_node(&ob->id,
++              add_operation_node(&object->id,
 +                                 DEG_NODE_TYPE_BONE,
 +                                 pchan->name,
 +                                 NULL,
 +                                 DEG_OPCODE_BONE_READY);
 +              /* Bone is fully evaluated. */
-               op_node = add_operation_node(&ob->id,
++              op_node = add_operation_node(&object->id,
 +                                           DEG_NODE_TYPE_BONE,
 +                                           pchan->name,
 +                                           NULL,
 +                                           DEG_OPCODE_BONE_DONE);
                op_node->set_as_exit();
        }
-       op_node = add_operation_node(&ob->id,
 -
 -      op_node = add_operation_node(&object->id, DEG_NODE_TYPE_EVAL_POSE,
 -                                   NULL, DEG_OPCODE_POSE_DONE);
++      op_node = add_operation_node(&object->id,
 +                                   DEG_NODE_TYPE_EVAL_POSE,
 +                                   NULL,
 +                                   DEG_OPCODE_POSE_DONE);
        op_node->set_as_exit();
  }
  
index 6a9023b5b6a1dba1bae83511e8e091c6d2c78faf,3520c518c364d166915179272b1e909a7dd0573c..9da3046ff07e4d6c3a72187dc819ea6055e4380b
@@@ -328,10 -327,10 +328,10 @@@ void DepsgraphRelationBuilder::add_oper
        }
  }
  
- void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, bool dupli, const char *name)
 -void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *object, Group *group, int layer, bool dupli, const char *name)
++void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *object, Group *group, bool dupli, const char *name)
  {
        unsigned int numcollobj;
-       Object **collobjs = get_collisionobjects_ext(scene, ob, group, &numcollobj, eModifierType_Collision, dupli);
 -      Object **collobjs = get_collisionobjects_ext(scene, object, group, layer, &numcollobj, eModifierType_Collision, dupli);
++      Object **collobjs = get_collisionobjects_ext(scene, object, group, &numcollobj, eModifierType_Collision, dupli);
  
        for (unsigned int i = 0; i < numcollobj; i++)
        {
                MEM_freeN(collobjs);
  }
  
- void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name)
+ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, Scene *scene, Object *object, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name)
  {
-       ListBase *effectors = pdInitEffectors(NULL, scene, ob, psys, eff, false);
 -      ListBase *effectors = pdInitEffectors(scene, object, psys, eff, false);
++      ListBase *effectors = pdInitEffectors(NULL, scene, object, psys, eff, false);
  
        if (effectors) {
                for (EffectorCache *eff = (EffectorCache *)effectors->first; eff; eff = eff->next) {
                        }
  
                        if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
-                               add_collision_relations(key, scene, ob, NULL, true, "Force Absorption");
 -                              add_collision_relations(key, scene, object, NULL, eff->ob->lay, true, "Force Absorption");
++                              add_collision_relations(key, scene, object, NULL, true, "Force Absorption");
                        }
                }
        }
@@@ -548,17 -547,13 +548,17 @@@ void DepsgraphRelationBuilder::build_ob
                                break;
  
                        case OB_CAMERA: /* Camera */
-                               build_camera(ob);
+                               build_camera(object);
                                break;
-                               build_lightprobe(ob);
 +
 +                      case OB_LIGHTPROBE:
++                              build_lightprobe(object);
 +                              break;
                }
  
-               Key *key = BKE_key_from_object(ob);
+               Key *key = BKE_key_from_object(object);
                if (key != NULL) {
-                       ComponentKey geometry_key((ID *)ob->data, DEG_NODE_TYPE_GEOMETRY);
+                       ComponentKey geometry_key((ID *)object->data, DEG_NODE_TYPE_GEOMETRY);
                        ComponentKey key_key(&key->id, DEG_NODE_TYPE_GEOMETRY);
                        add_relation(key_key, geometry_key, "Shapekeys");
                }
@@@ -1012,10 -1007,13 +1012,10 @@@ void DepsgraphRelationBuilder::build_dr
                /* TODO: ideally, if this is for a constraint, it goes to said
                 * constraint.
                 */
-               Object *ob = (Object *)id;
+               Object *object = (Object *)id;
 -              char *bone_name;
 -
 -              bone_name = BLI_str_quoted_substrN(rna_path, "pose.bones[");
 +              char *bone_name = BLI_str_quoted_substrN(rna_path, "pose.bones[");
-               pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
+               pchan = BKE_pose_channel_find_name(object->pose, bone_name);
 -
 -              if (bone_name) {
 +              if (bone_name != NULL) {
                        MEM_freeN(bone_name);
                        bone_name = NULL;
                }
                        foreach (DepsRelation *rel, arm_node->outlinks) {
                                IDDepsNode *to_node = (IDDepsNode *)rel->to;
                                /* We only care about objects with pose data which use this. */
 -                              if (GS(to_node->id->name) == ID_OB) {
 -                                      Object *object = (Object *)to_node->id;
 -                                      /* NOTE: object->pose may be NULL. */
 -                                      bPoseChannel *pchan = BKE_pose_channel_find_name(
 -                                              object->pose, bone_name);
 +                              if (GS(to_node->id_orig->name) == ID_OB) {
-                                       Object *ob = (Object *)to_node->id_orig;
-                                       // NOTE: ob->pose may be NULL
-                                       bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose,
++                                      Object *object = (Object *)to_node->id_orig;
++                                      // NOTE: object->pose may be NULL
++                                      bPoseChannel *pchan = BKE_pose_channel_find_name(object->pose,
 +                                                                                       bone_name);
                                        if (pchan != NULL) {
-                                               OperationKey bone_key(&ob->id,
+                                               OperationKey bone_key(&object->id,
                                                                      DEG_NODE_TYPE_BONE,
                                                                      pchan->name,
                                                                      DEG_OPCODE_BONE_LOCAL);
@@@ -1374,41 -1359,17 +1374,41 @@@ void DepsgraphRelationBuilder::build_pa
        }
  
        /* particle systems */
-       LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
+       LINKLIST_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
                ParticleSettings *part = psys->part;
  
 -              /* particle settings */
 -              build_animdata(&part->id);
 -
 -              /* this particle system */
 -              OperationKey psys_key(&object->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PARTICLE_SYSTEM_EVAL, psys->name);
 +              /* Build particle settings relations.
 +               *
 +               * NOTE: The call itself ensures settings are only build once.
 +               */
 +              build_particle_settings(part);
 +
 +              /* This particle system. */
-               OperationKey psys_key(&ob->id,
++              OperationKey psys_key(&object->id,
 +                                    DEG_NODE_TYPE_EVAL_PARTICLES,
 +                                    DEG_OPCODE_PARTICLE_SYSTEM_EVAL,
 +                                    psys->name);
 +
 +              /* Update particle system when settings changes. */
 +              OperationKey particle_settings_key(&part->id,
 +                                                 DEG_NODE_TYPE_PARAMETERS,
 +                                                 DEG_OPCODE_PARTICLE_SETTINGS_EVAL);
 +              OperationKey particle_settings_recalc_clear_key(
 +                      &part->id,
 +                      DEG_NODE_TYPE_PARAMETERS,
 +                      DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR);
-               OperationKey psys_settings_key(&ob->id,
++              OperationKey psys_settings_key(&object->id,
 +                                             DEG_NODE_TYPE_EVAL_PARTICLES,
 +                                             DEG_OPCODE_PARTICLE_SETTINGS_EVAL,
 +                                             psys->name);
 +              add_relation(particle_settings_key, psys_settings_key, "Particle Settings Change");
 +              add_relation(psys_settings_key, psys_key, "Particle Settings Update");
 +              add_relation(psys_key,
 +                           particle_settings_recalc_clear_key,
 +                           "Particle Settings Recalc Clear");
  
                /* XXX: if particle system is later re-enabled, we must do full rebuild? */
-               if (!psys_check_enabled(ob, psys, G.is_rendering))
+               if (!psys_check_enabled(object, psys, G.is_rendering))
                        continue;
  
                add_relation(eval_init_key, psys_key, "Init -> PSys");
  
                /* collisions */
                if (part->type != PART_HAIR) {
 -                      add_collision_relations(psys_key, scene_, object, part->collision_group, object->lay, true, "Particle Collision");
 +                      add_collision_relations(psys_key,
 +                                              scene_,
-                                               ob,
++                                              object,
 +                                              part->collision_group,
 +                                              true,
 +                                              "Particle Collision");
                }
 -              else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd && psys->clmd->coll_parms) {
 -                      add_collision_relations(psys_key, scene_, object, psys->clmd->coll_parms->group, object->lay | scene_->lay, true, "Hair Collision");
 +              else if ((psys->flag & PSYS_HAIR_DYNAMICS) &&
 +                       psys->clmd != NULL &&
 +                       psys->clmd->coll_parms != NULL)
 +              {
 +                      add_collision_relations(psys_key,
 +                                              scene_,
-                                               ob,
++                                              object,
 +                                              psys->clmd->coll_parms->group,
 +                                              true,
 +                                              "Hair Collision");
                }
  
                /* effectors */
 -              add_forcefield_relations(psys_key, scene_, object, psys, part->effector_weights, part->type == PART_HAIR, "Particle Field");
 +              add_forcefield_relations(psys_key,
 +                                       scene_,
-                                        ob,
++                                       object,
 +                                       psys,
 +                                       part->effector_weights,
 +                                       part->type == PART_HAIR,
 +                                       "Particle Field");
  
                /* boids */
                if (part->boids) {
         * TODO(sergey): This relation should be altered once real granular update
         * is implemented.
         */
-       ComponentKey transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM);
+       ComponentKey transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM);
        add_relation(transform_key, obdata_ubereval_key, "Partcile Eval");
  
 -      /* pointcache */
 -      // TODO...
 +      /* TODO(sergey): Do we need a point cache operations here? */
 +}
 +
 +void DepsgraphRelationBuilder::build_particle_settings(ParticleSettings *part)
 +{
 +      ID *part_id = &part->id;
 +      if (part_id->tag & LIB_TAG_DOIT) {
 +              return;
 +      }
 +      part_id->tag |= LIB_TAG_DOIT;
 +
 +      /* Animation data relations. */
 +      build_animdata(&part->id);
 +
 +      OperationKey eval_key(part_id,
 +                            DEG_NODE_TYPE_PARAMETERS,
 +                            DEG_OPCODE_PARTICLE_SETTINGS_EVAL);
 +      OperationKey recalc_clear_key(part_id,
 +                                   DEG_NODE_TYPE_PARAMETERS,
 +                                   DEG_OPCODE_PARTICLE_SETTINGS_RECALC_CLEAR);
 +      add_relation(eval_key, recalc_clear_key, "Particle Settings Clear Recalc");
  }
  
  void DepsgraphRelationBuilder::build_cloth(Object *object,
@@@ -1576,23 -1499,13 +1576,23 @@@ void DepsgraphRelationBuilder::build_ob
        /* link components to each other */
        add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data");
  
-       OperationKey obdata_ubereval_key(&ob->id,
++      OperationKey obdata_ubereval_key(&object->id,
 +                                       DEG_NODE_TYPE_GEOMETRY,
 +                                       DEG_OPCODE_GEOMETRY_UBEREVAL);
 +
 +      /* Special case: modifiers and DerivedMesh creation queries scene for various
 +       * things like data mask to be used. We add relation here to ensure object is
 +       * never evaluated prior to Scene's CoW is ready.
 +       */
 +      OperationKey scene_key(&scene_->id,
 +                             DEG_NODE_TYPE_PARAMETERS,
 +                             DEG_OPCODE_PLACEHOLDER,
 +                             "Scene Eval");
 +      add_relation(scene_key, obdata_ubereval_key, "CoW Relation");
 +
        /* Modifiers */
-       if (ob->modifiers.first != NULL) {
-               LINKLIST_FOREACH (ModifierData *, md, &ob->modifiers) {
+       if (object->modifiers.first != NULL) {
 -              OperationKey obdata_ubereval_key(&object->id,
 -                                               DEG_NODE_TYPE_GEOMETRY,
 -                                               DEG_OPCODE_GEOMETRY_UBEREVAL);
 -
+               LINKLIST_FOREACH (ModifierData *, md, &object->modifiers) {
                        const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type);
  
                        if (mti->updateDepsgraph) {
        }
  
        /* materials */
-       if (ob->totcol) {
-               for (int a = 1; a <= ob->totcol; a++) {
-                       Material *ma = give_current_material(ob, a);
+       if (object->totcol) {
+               for (int a = 1; a <= object->totcol; a++) {
+                       Material *ma = give_current_material(object, a);
                        if (ma != NULL) {
                                build_material(ma);
-                               if (ob->type == OB_MESH) {
 +
-                                       OperationKey shading_key(&ob->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_SHADING);
++                              if (object->type == OB_MESH) {
 +                                      OperationKey material_key(&ma->id,
 +                                                                DEG_NODE_TYPE_SHADING,
 +                                                                DEG_OPCODE_MATERIAL_UPDATE);
++                                      OperationKey shading_key(&object->id, DEG_NODE_TYPE_SHADING, DEG_OPCODE_SHADING);
 +                                      add_relation(material_key, shading_key, "Material Update");
 +                              }
                        }
                }
        }
@@@ -1776,11 -1681,7 +1776,11 @@@ void DepsgraphRelationBuilder::build_ca
        }
        camera_id->tag |= LIB_TAG_DOIT;
  
-       ComponentKey object_parameters_key(&ob->id, DEG_NODE_TYPE_PARAMETERS);
 -      ComponentKey parameters_key(camera_id, DEG_NODE_TYPE_PARAMETERS);
++      ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS);
 +      ComponentKey camera_parameters_key(camera_id, DEG_NODE_TYPE_PARAMETERS);
 +
 +      add_relation(camera_parameters_key, object_parameters_key,
 +                   "Camera -> Object");
  
        if (needs_animdata_node(camera_id)) {
                ComponentKey animation_key(camera_id, DEG_NODE_TYPE_ANIMATION);
@@@ -1804,11 -1706,7 +1804,11 @@@ void DepsgraphRelationBuilder::build_la
        }
        lamp_id->tag |= LIB_TAG_DOIT;
  
-       ComponentKey object_parameters_key(&ob->id, DEG_NODE_TYPE_PARAMETERS);
 -      ComponentKey parameters_key(lamp_id, DEG_NODE_TYPE_PARAMETERS);
++      ComponentKey object_parameters_key(&object->id, DEG_NODE_TYPE_PARAMETERS);
 +      ComponentKey lamp_parameters_key(lamp_id, DEG_NODE_TYPE_PARAMETERS);
 +
 +      add_relation(lamp_parameters_key, object_parameters_key,
 +                   "Lamp -> Object");
  
        if (needs_animdata_node(lamp_id)) {
                ComponentKey animation_key(lamp_id, DEG_NODE_TYPE_ANIMATION);
  
        /* textures */
        build_texture_stack(la->mtex);
-               OperationKey ob_copy_on_write_key(&ob->id,
 +
 +      if (DEG_depsgraph_use_copy_on_write()) {
 +              /* Make sure copy on write of lamp data is always properly updated for
 +               * visible lamps.
 +               */
++              OperationKey ob_copy_on_write_key(&object->id,
 +                                                DEG_NODE_TYPE_COPY_ON_WRITE,
 +                                                DEG_OPCODE_COPY_ON_WRITE);
 +              OperationKey lamp_copy_on_write_key(lamp_id,
 +                                                  DEG_NODE_TYPE_COPY_ON_WRITE,
 +                                                  DEG_OPCODE_COPY_ON_WRITE);
 +              add_relation(lamp_copy_on_write_key, ob_copy_on_write_key, "Eval Order");
 +      }
  }
  
  void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
index b3e5ed9f7f90b3b9d04e6d2a5d430f3831750bd0,3be7472dbfce7ab239d5e1743e0ba140d68786ad..15d9f1db4dcbd93f3d9777cf9114c60069e70240
@@@ -186,10 -184,10 +186,10 @@@ struct DepsgraphRelationBuilde
                                      const DepsNodeHandle *handle,
                                      const char *description);
  
 -      void build_scene(Scene *scene);
 +      void build_view_layer(Scene *scene, ViewLayer *view_layer);
        void build_group(Object *object, Group *group);
-       void build_object(Object *ob);
-       void build_object_parent(Object *ob);
+       void build_object(Object *object);
+       void build_object_parent(Object *object);
        void build_constraints(ID *id,
                               eDepsNode_Type component_type,
                               const char *component_subdata,
        void build_driver(ID *id, FCurve *fcurve);
        void build_world(World *world);
        void build_rigidbody(Scene *scene);
-       void build_particles(Object *ob);
+       void build_particles(Object *object);
 +      void build_particle_settings(ParticleSettings *part);
        void build_cloth(Object *object, ModifierData *md);
-       void build_ik_pose(Object *ob,
+       void build_ik_pose(Object *object,
                           bPoseChannel *pchan,
                           bConstraint *con,
                           RootPChanMap *root_map);
  
        void add_collision_relations(const OperationKey &key,
                                     Scene *scene,
-                                    Object *ob,
+                                    Object *object,
                                     Group *group,
 -                                   int layer,
                                     bool dupli,
                                     const char *name);
        void add_forcefield_relations(const OperationKey &key,
                                      Scene *scene,
-                                     Object *ob,
+                                     Object *object,
                                      ParticleSystem *psys,
                                      EffectorWeights *eff,
 -                                    bool add_absorption,
 -                                    const char *name);
 +                                    bool add_absorption, const char *name);
 +
 +      struct LayerCollectionState {
 +              int index;
 +              OperationKey init_key;
 +              OperationKey done_key;
 +              OperationKey prev_key;
 +      };
 +      void build_layer_collection(LayerCollection *layer_collection,
 +                                  LayerCollectionState *state);
 +      void build_layer_collections(ListBase *layer_collections,
 +                                   LayerCollectionState *state);
 +      void build_view_layer_collections(ViewLayer *view_layer);
 +
 +      void build_copy_on_write_relations();
 +      void build_copy_on_write_relations(IDDepsNode *id_node);
  
        template <typename KeyType>
        OperationDepsNode *find_operation_node(const KeyType &key);
index 476e793d3f715c9450db84cb326c68db78ea4d8d,cdc98ad6b6a58f44e0112d8fa1f6da06c8a00908..49035f27daade41777522e59c50344e03cffc39d
@@@ -387,17 -387,21 +387,17 @@@ void DepsgraphRelationBuilder::build_ri
        }
  
        /* links between operations for each bone */
-       LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
-               OperationKey bone_local_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
-               OperationKey bone_pose_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT);
-               OperationKey bone_ready_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
-               OperationKey bone_done_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
+       LINKLIST_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
+               OperationKey bone_local_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
+               OperationKey bone_pose_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT);
+               OperationKey bone_ready_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
+               OperationKey bone_done_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
 -
                pchan->flag &= ~POSE_DONE;
 -
 -              /* pose init to bone local */
 +              /* Pose init to bone local. */
                add_relation(init_key, bone_local_key, "PoseEval Source-Bone Link");
 -
 -              /* local to pose parenting operation */
 +              /* Local to pose parenting operation. */
                add_relation(bone_local_key, bone_pose_key, "Bone Local - PoseSpace Link");
 -
 -              /* parent relation */
 +              /* Parent relation. */
                if (pchan->parent != NULL) {
                        eDepsOperation_Code parent_key_opcode;
  
                                parent_key_opcode = DEG_OPCODE_BONE_DONE;
                        }
  
-                       OperationKey parent_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->parent->name, parent_key_opcode);
+                       OperationKey parent_key(&object->id, DEG_NODE_TYPE_BONE, pchan->parent->name, parent_key_opcode);
                        add_relation(parent_key, bone_pose_key, "[Parent Bone -> Child Bone]");
                }
 -
 -              /* constraints */
 +              /* Buil constraints. */
                if (pchan->constraints.first != NULL) {
                        /* constraints stack and constraint dependencies */
-                       build_constraints(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, &pchan->constraints, &root_map);
+                       build_constraints(&object->id, DEG_NODE_TYPE_BONE, pchan->name, &pchan->constraints, &root_map);
  
                        /* pose -> constraints */
-                       OperationKey constraints_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_CONSTRAINTS);
+                       OperationKey constraints_key(&object->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_CONSTRAINTS);
                        add_relation(bone_pose_key, constraints_key, "Constraints Stack");
  
                        /* constraints -> ready */
index 34ca2244b3abfaa4c620eb688b311578f7539040,4b3d4190dcd53257056b4a46f050c4e076f4cb1b..e4e0247f25143399e46a67c64ac401c044ba2a74
@@@ -306,15 -314,16 +306,15 @@@ void DEG_relations_tag_update(Main *bma
  
  void DEG_add_collision_relations(DepsNodeHandle *handle,
                                   Scene *scene,
-                                  Object *ob,
+                                  Object *object,
                                   Group *group,
 -                                 int layer,
                                   unsigned int modifier_type,
                                   DEG_CollobjFilterFunction fn,
                                   bool dupli,
                                   const char *name)
  {
        unsigned int numcollobj;
-       Object **collobjs = get_collisionobjects_ext(scene, ob, group, &numcollobj, modifier_type, dupli);
 -      Object **collobjs = get_collisionobjects_ext(scene, object, group, layer, &numcollobj, modifier_type, dupli);
++      Object **collobjs = get_collisionobjects_ext(scene, object, group, &numcollobj, modifier_type, dupli);
  
        for (unsigned int i = 0; i < numcollobj; i++) {
                Object *ob1 = collobjs[i];
@@@ -337,7 -346,7 +337,7 @@@ void DEG_add_forcefield_relations(DepsN
                                    int skip_forcefield,
                                    const char *name)
  {
-       ListBase *effectors = pdInitEffectors(NULL, scene, ob, NULL, effector_weights, false);
 -      ListBase *effectors = pdInitEffectors(scene, object, NULL, effector_weights, false);
++      ListBase *effectors = pdInitEffectors(NULL, scene, object, NULL, effector_weights, false);
  
        if (effectors) {
                for (EffectorCache *eff = (EffectorCache*)effectors->first; eff; eff = eff->next) {
                                if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
                                        DEG_add_collision_relations(handle,
                                                                    scene,
-                                                                   ob,
+                                                                   object,
                                                                    NULL,
 -                                                                  eff->ob->lay,
                                                                    eModifierType_Collision,
                                                                    NULL,
                                                                    true,
index 9740e93ffec2302f2505338a0dd6e857ae5fbe76,e58a7a324072a11d6f4ff4c651fe3f49e32040f8..6ffdfeac644ee27bf9c887338dbf4044dd27f723
@@@ -83,251 -68,3 +83,251 @@@ short DEG_get_eval_flags_for_id(Depsgra
  
        return id_node->eval_flags;
  }
-       Object *ob = (Object *)id_node->id_cow;
-       BLI_assert(DEG::deg_validate_copy_on_write_datablock(&ob->id));
 +
 +Scene *DEG_get_evaluated_scene(Depsgraph *graph)
 +{
 +      DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
 +      Scene *scene_orig = deg_graph->scene;
 +      return reinterpret_cast<Scene *>(deg_graph->get_cow_id(&scene_orig->id));
 +}
 +
 +ViewLayer *DEG_get_evaluated_view_layer(Depsgraph *graph)
 +{
 +      DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
 +      Scene *scene_cow = DEG_get_evaluated_scene(graph);
 +      ViewLayer *view_layer_orig = deg_graph->view_layer;
 +      ViewLayer *view_layer_cow =
 +              (ViewLayer *)BLI_findstring(&scene_cow->view_layers,
 +                                           view_layer_orig->name,
 +                                           offsetof(ViewLayer, name));
 +      return view_layer_cow;
 +}
 +
 +Object *DEG_get_evaluated_object(Depsgraph *depsgraph, Object *object)
 +{
 +      return (Object *)DEG_get_evaluated_id(depsgraph, &object->id);
 +}
 +
 +ID *DEG_get_evaluated_id(struct Depsgraph *depsgraph, ID *id)
 +{
 +      /* TODO(sergey): This is a duplicate of Depsgraph::get_cow_id(),
 +       * but here we never do assert, since we don't know nature of the
 +       * incoming ID datablock.
 +       */
 +      DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph;
 +      DEG::IDDepsNode *id_node = deg_graph->find_id_node(id);
 +      if (id_node == NULL) {
 +              return id;
 +      }
 +      return id_node->id_cow;
 +}
 +
 +/* ************************ DEG ITERATORS ********************* */
 +
 +/**
 + * XXX (dfelinto/sergey) big hack, waiting for:
 + * "Reshuffle collections base flags evaluation, make it so object is gathering its base flags from collections."
 + *
 + * Returns false if object shouldn't be found (which should never happen in the final implementation
 + * and instead we should have a tag to the objects that were not directly part of the depsgraph).
 + *
 + * That means that the object is not in a collection but it's part of depsgraph, or the object is simply
 + * not in the current ViewLayer - Depsgraph at the moment includes all the ViewLayer in the Scene.
 + */
 +static bool deg_flush_base_flags_and_settings(
 +        DEGObjectsIteratorData *data, Object *ob_dst, Object *ob_src, const bool is_dupli)
 +{
 +      Base *base;
 +      Depsgraph *graph = data->graph;
 +      ViewLayer *view_layer = data->eval_ctx.view_layer;
 +      int flag = is_dupli ? BASE_FROMDUPLI : 0;
 +
 +      /* First attempt, see if object is in the current ViewLayer. */
 +      base = (Base *)BLI_findptr(&view_layer->object_bases, ob_src, offsetof(Base, object));
 +
 +      /* Next attempt, see if object is in one of the sets. */
 +      if (base == NULL) {
 +              Scene *scene_iter, *scene = DEG_get_evaluated_scene(graph);
 +              scene_iter = scene;
 +
 +              while ((scene_iter = (scene_iter)->set)) {
 +                      ViewLayer *view_layer_set = BKE_view_layer_from_scene_get(scene_iter);
 +                      base = (Base *)BLI_findptr(&view_layer_set->object_bases, ob_src, offsetof(Base, object));
 +                      if (base != NULL) {
 +                              flag |= BASE_FROM_SET;
 +                              flag &= ~(BASE_SELECTED | BASE_SELECTABLED);
 +                              break;
 +                      }
 +              }
 +      }
 +
 +      if (base == NULL) {
 +              return false;
 +      }
 +
 +      /* Make sure we have the base collection settings is already populated.
 +       * This will fail when BKE_layer_eval_layer_collection_pre hasn't run yet
 +       * Which usually means a missing call to DEG_id_tag_update(). */
 +      BLI_assert(!BLI_listbase_is_empty(&base->collection_properties->data.group));
 +
 +      ob_dst->base_flag = base->flag | flag;
 +      ob_dst->base_collection_properties = base->collection_properties;
 +      return true;
 +}
 +
 +static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
 +{
 +      DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data;
 +      while (data->dupli_object_next != NULL) {
 +              DupliObject *dob = data->dupli_object_next;
 +              Object *obd = dob->ob;
 +
 +              data->dupli_object_next = data->dupli_object_next->next;
 +
 +              /* Group duplis need to set ob matrices correct, for deform. so no_draw
 +               * is part handled.
 +               */
 +              if ((obd->transflag & OB_RENDER_DUPLI) == 0 && dob->no_draw) {
 +                      continue;
 +              }
 +
 +              if (obd->type == OB_MBALL) {
 +                      continue;
 +              }
 +
 +              data->dupli_object_current = dob;
 +
 +              /* Temporary object to evaluate. */
 +              data->temp_dupli_object = *dob->ob;
 +              data->temp_dupli_object.select_color = data->dupli_parent->select_color;
 +              copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
 +
 +              deg_flush_base_flags_and_settings(data,
 +                                                &data->temp_dupli_object,
 +                                                data->dupli_parent,
 +                                                true);
 +              iter->current = &data->temp_dupli_object;
 +              BLI_assert(DEG::deg_validate_copy_on_write_datablock(&data->temp_dupli_object.id));
 +              return true;
 +      }
 +
 +      return false;
 +}
 +
 +static void deg_objects_iterator_step(BLI_Iterator *iter, DEG::IDDepsNode *id_node)
 +{
 +      /* Reset the skip in case we are running from within a loop. */
 +      iter->skip = false;
 +
 +      DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data;
 +      const ID_Type id_type = GS(id_node->id_orig->name);
 +
 +      if (id_type != ID_OB) {
 +              iter->skip = true;
 +              return;
 +      }
 +
 +      switch (id_node->linked_state) {
 +              case DEG::DEG_ID_LINKED_DIRECTLY:
 +                      break;
 +              case DEG::DEG_ID_LINKED_VIA_SET:
 +                      if (data->flag & DEG_OBJECT_ITER_FLAG_SET) {
 +                              break;
 +                      }
 +                      else {
 +                              ATTR_FALLTHROUGH;
 +                      }
 +              case DEG::DEG_ID_LINKED_INDIRECTLY:
 +                      iter->skip = true;
 +                      return;
 +      }
 +
-       if (deg_flush_base_flags_and_settings(data, ob, ob, false) == false) {
++      Object *object = (Object *)id_node->id_cow;
++      BLI_assert(DEG::deg_validate_copy_on_write_datablock(&object->id));
 +
-       if ((data->flag & DEG_OBJECT_ITER_FLAG_DUPLI) && (ob->transflag & OB_DUPLI)) {
-               data->dupli_parent = ob;
-               data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, ob);
++      if (deg_flush_base_flags_and_settings(data, object, object, false) == false) {
 +              iter->skip = true;
 +              return;
 +      }
 +
-       iter->current = ob;
++      if ((data->flag & DEG_OBJECT_ITER_FLAG_DUPLI) && (object->transflag & OB_DUPLI)) {
++              data->dupli_parent = object;
++              data->dupli_list = object_duplilist(&data->eval_ctx, data->scene, object);
 +              data->dupli_object_next = (DupliObject *)data->dupli_list->first;
 +      }
 +
++      iter->current = object;
 +}
 +
 +void DEG_objects_iterator_begin(BLI_Iterator *iter, DEGObjectsIteratorData *data)
 +{
 +      Depsgraph *depsgraph = data->graph;
 +      DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
 +      const size_t num_id_nodes = deg_graph->id_nodes.size();
 +
 +      if (num_id_nodes == 0) {
 +              iter->valid = false;
 +              return;
 +      }
 +
 +      /* TODO(sergey): What evaluation type we want here? */
 +      DEG_evaluation_context_init(&data->eval_ctx, DAG_EVAL_RENDER);
 +      data->eval_ctx.view_layer = DEG_get_evaluated_view_layer(depsgraph);
 +
 +      iter->data = data;
 +      data->dupli_parent = NULL;
 +      data->dupli_list = NULL;
 +      data->dupli_object_next = NULL;
 +      data->dupli_object_current = NULL;
 +      data->scene = DEG_get_evaluated_scene(depsgraph);
 +      data->id_node_index = 0;
 +      data->num_id_nodes = num_id_nodes;
 +
 +      DEG::IDDepsNode *id_node = deg_graph->id_nodes[data->id_node_index];
 +      deg_objects_iterator_step(iter, id_node);
 +
 +      if (iter->skip) {
 +              DEG_objects_iterator_next(iter);
 +      }
 +}
 +
 +void DEG_objects_iterator_next(BLI_Iterator *iter)
 +{
 +      DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data;
 +      Depsgraph *depsgraph = data->graph;
 +      DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(depsgraph);
 +      do {
 +              if (data->dupli_list) {
 +                      if (deg_objects_dupli_iterator_next(iter)) {
 +                              return;
 +                      }
 +                      else {
 +                              free_object_duplilist(data->dupli_list);
 +                              data->dupli_parent = NULL;
 +                              data->dupli_list = NULL;
 +                              data->dupli_object_next = NULL;
 +                              data->dupli_object_current = NULL;
 +                      }
 +              }
 +
 +              ++data->id_node_index;
 +              if (data->id_node_index == data->num_id_nodes) {
 +                      iter->valid = false;
 +                      return;
 +              }
 +
 +              DEG::IDDepsNode *id_node = deg_graph->id_nodes[data->id_node_index];
 +              deg_objects_iterator_step(iter, id_node);
 +      } while (iter->skip);
 +}
 +
 +void DEG_objects_iterator_end(BLI_Iterator *iter)
 +{
 +#ifndef NDEBUG
 +      DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data;
 +      /* Force crash in case the iterator data is referenced and accessed down the line. (T51718) */
 +      memset(&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object));
 +#else
 +      (void) iter;
 +#endif
 +}
index 86e69458f4111598c7f302a7a4c1c7249062efdc,0adbadeebbad138619b0bdc80c12510751a1ccef..cbe00a987194319deec9591d73da90f88140ef5d
@@@ -147,20 -153,9 +147,20 @@@ void deg_graph_flush_updates(Main *bmai
                        }
  
                        if (comp_node->done != COMPONENT_STATE_DONE) {
-                               /* Currently this is needed to get ob->mesh to be replaced with
++                              /* Currently this is needed to get object->mesh to be replaced with
 +                               * original mesh (rather than being evaluated_mesh).
 +                               *
 +                               * TODO(sergey): This is something we need to avoid.
 +                               */
 +                              if (use_copy_on_write && comp_node->depends_on_cow()) {
 +                                      ComponentDepsNode *cow_comp =
 +                                              id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
 +                                      cow_comp->tag_update(graph);
 +                              }
 +
                                Object *object = NULL;
 -                              if (GS(id->name) == ID_OB) {
 -                                      object = (Object *)id;
 +                              if (GS(id_orig->name) == ID_OB) {
 +                                      object = (Object *)id_orig;
                                        if (id_node->done == 0) {
                                                ++num_flushed_objects;
                                        }