Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Sat, 19 Nov 2016 15:28:39 +0000 (16:28 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Sat, 19 Nov 2016 15:28:39 +0000 (16:28 +0100)
Conflicts:
source/blender/blenloader/intern/versioning_270.c
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/editors/space_view3d/drawobject.c

1  2 
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
release/scripts/startup/bl_ui/properties_paint_common.py
source/blender/blenkernel/intern/library_remap.c
source/blender/blenloader/intern/versioning_270.c
source/blender/blenloader/intern/writefile.c
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/depsgraph/intern/builder/deg_builder_relations.h
source/blender/editors/space_view3d/drawobject.c

Simple merge
index 577c278e0e4f7c11c20b232d8223020d36f73c9e,25d78b73d5950caafbd7b1457ea55fb3b6564153..3fa3f037600367b35d084e8fc0cc6c18ca2ee307
@@@ -1367,26 -1467,10 +1367,33 @@@ void blo_do_versions_270(FileData *fd, 
                }
        }
  
+       if (!MAIN_VERSION_ATLEAST(main, 278, 4)) {
+               const float sqrt_3 = (float)M_SQRT3;
+               for (Brush *br = main->brush.first; br; br = br->id.next) {
+                       br->fill_threshold /= sqrt_3;
+               }
+       }
++
 +      {
 +              if (!DNA_struct_elem_find(fd->filesdna, "View3DDebug", "char", "background")) {
 +                      bScreen *screen;
 +
 +                      for (screen = main->screen.first; screen; screen = screen->id.next) {
 +                              ScrArea *sa;
 +                              for (sa = screen->areabase.first; sa; sa = sa->next) {
 +                                      SpaceLink *sl;
 +
 +                                      for (sl = sa->spacedata.first; sl; sl = sl->next) {
 +                                              switch (sl->spacetype) {
 +                                                      case SPACE_VIEW3D:
 +                                                      {
 +                                                              View3D *v3d = (View3D *)sl;
 +                                                              v3d->debug.background = V3D_DEBUG_BACKGROUND_NONE;
 +                                                      }
 +                                              }
 +                                      }
 +                              }
 +                      }
 +              }
 +      }
  }
index 1abce2e6b18ad344a2528c0f0f87bbea423fbcf9,4de82dd63e4a0ad2b5639bd31af2834581cf62cc..3cf510eef2597839918c8dfa60a44356b75eaae6
@@@ -55,9 -55,12 +55,11 @@@ extern "C" 
  #include "DNA_key_types.h"
  #include "DNA_lamp_types.h"
  #include "DNA_material_types.h"
+ #include "DNA_mask_types.h"
  #include "DNA_mesh_types.h"
  #include "DNA_meta_types.h"
+ #include "DNA_movieclip_types.h"
  #include "DNA_node_types.h"
 -#include "DNA_particle_types.h"
  #include "DNA_object_types.h"
  #include "DNA_rigidbody_types.h"
  #include "DNA_scene_types.h"
@@@ -782,207 -692,50 +685,6 @@@ void DepsgraphNodeBuilder::build_rigidb
        }
  }
  
- /* IK Solver Eval Steps */
- void DepsgraphNodeBuilder::build_ik_pose(Scene *scene, Object *ob, bPoseChannel *pchan, bConstraint *con)
- {
-       bKinematicConstraint *data = (bKinematicConstraint *)con->data;
-       /* Find the chain's root. */
-       bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
-       if (has_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name,
-                              DEG_OPCODE_POSE_IK_SOLVER))
-       {
-               return;
-       }
-       /* Operation node for evaluating/running IK Solver. */
-       add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name,
-                          DEPSOP_TYPE_SIM, function_bind(BKE_pose_iktree_evaluate, _1, scene, ob, rootchan),
-                          DEG_OPCODE_POSE_IK_SOLVER);
- }
- /* Spline IK Eval Steps */
- void DepsgraphNodeBuilder::build_splineik_pose(Scene *scene, Object *ob, bPoseChannel *pchan, bConstraint *con)
- {
-       bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
-       /* Find the chain's root. */
-       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.
-        */
-       add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name,
-                          DEPSOP_TYPE_SIM, function_bind(BKE_pose_splineik_evaluate, _1, scene, ob, rootchan),
-                          DEG_OPCODE_POSE_SPLINE_IK_SOLVER);
- }
- /* Pose/Armature Bones Graph */
- void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob)
 -void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob)
--{
-       bArmature *arm = (bArmature *)ob->data;
-       /* animation and/or drivers linking posebones to base-armature used to define them
-        * NOTE: AnimData here is really used to control animated deform properties,
-        *       which ideally should be able to be unique across different instances.
-        *       Eventually, we need some type of proxy/isolation mechanism in-between here
-        *       to ensure that we can use same rig multiple times in same scene...
-        */
-       build_animdata(&arm->id);
-       /* Rebuild pose if not up to date. */
-       if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
-               BKE_pose_rebuild_ex(ob, arm, false);
-               /* XXX: Without this animation gets lost in certain circumstances
-                * after loading file. Need to investigate further since it does
-                * not happen with simple scenes..
-                */
-               if (ob->adt) {
-                       ob->adt->recalc |= ADT_RECALC_ANIM;
-               }
-       }
-       /* speed optimization for animation lookups */
-       if (ob->pose) {
-               BKE_pose_channels_hash_make(ob->pose);
-               if (ob->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
-                       BKE_pose_update_constraint_flags(ob->pose);
-               }
-       }
-       /* Make sure pose is up-to-date with armature updates. */
-       add_operation_node(&arm->id,
-                          DEPSNODE_TYPE_PARAMETERS,
-                          DEPSOP_TYPE_EXEC,
-                          NULL,
-                          DEG_OPCODE_PLACEHOLDER,
-                          "Armature Eval");
--      /**
-        * Pose Rig Graph
-        * ==============
-        *
-        * Pose Component:
-        * - Mainly used for referencing Bone components.
-        * - This is where the evaluation operations for init/exec/cleanup
-        *   (ik) solvers live, and are later hooked up (so that they can be
-        *   interleaved during runtime) with bone-operations they depend on/affect.
-        * - init_pose_eval() and cleanup_pose_eval() are absolute first and last
-        *   steps of pose eval process. ALL bone operations must be performed
-        *   between these two...
 -       * Particle Systems Nodes
 -       * ======================
--       *
-        * Bone Component:
-        * - Used for representing each bone within the rig
-        * - Acts to encapsulate the evaluation operations (base matrix + parenting,
-        *   and constraint stack) so that they can be easily found.
-        * - Everything else which depends on bone-results hook up to the component only
-        *   so that we can redirect those to point at either the the post-IK/
-        *   post-constraint/post-matrix steps, as needed.
 -       * There are two types of nodes associated with representing
 -       * particle systems:
 -       *  1) Component (EVAL_PARTICLES) - This is the particle-system
 -       *     evaluation context for an object. It acts as the container
 -       *     for all the nodes associated with a particular set of particle
 -       *     systems.
 -       *  2) Particle System Eval Operation - This operation node acts as a
 -       *     blackbox evaluation step for one particle system referenced by
 -       *     the particle systems stack. All dependencies link to this operation.
--       */
-       /* pose eval context */
-       add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE,
-                          DEPSOP_TYPE_INIT, function_bind(BKE_pose_eval_init, _1, scene, ob, ob->pose), DEG_OPCODE_POSE_INIT);
-       add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE,
-                          DEPSOP_TYPE_POST, function_bind(BKE_pose_eval_flush, _1, scene, ob, ob->pose), DEG_OPCODE_POSE_DONE);
-       /* bones */
-       for (bPoseChannel *pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
-               /* node for bone eval */
-               add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
-                                  DEPSOP_TYPE_INIT, NULL, // XXX: BKE_pose_eval_bone_local
-                                  DEG_OPCODE_BONE_LOCAL);
-               add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
-                                  DEPSOP_TYPE_EXEC, function_bind(BKE_pose_eval_bone, _1, scene, ob, pchan), // XXX: BKE_pose_eval_bone_pose
-                                  DEG_OPCODE_BONE_POSE_PARENT);
-               add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
-                                  DEPSOP_TYPE_OUT, NULL, /* NOTE: dedicated noop for easier relationship construction */
-                                  DEG_OPCODE_BONE_READY);
-               add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
-                                  DEPSOP_TYPE_POST, function_bind(BKE_pose_bone_done, _1, pchan),
-                                  DEG_OPCODE_BONE_DONE);
-               /* constraints */
-               if (pchan->constraints.first != NULL) {
-                       build_pose_constraints(ob, pchan);
-               }
-               /**
-                * IK Solvers...
-                *
-                * - These require separate processing steps are pose-level
-                *   to be executed between chains of bones (i.e. once the
-                *   base transforms of a bunch of bones is done)
-                *
-                * Unsolved Issues:
-                * - Care is needed to ensure that multi-headed trees work out the same as in ik-tree building
-                * - Animated chain-lengths are a problem...
-                */
-               for (bConstraint *con = (bConstraint *)pchan->constraints.first; con; con = con->next) {
-                       switch (con->type) {
-                               case CONSTRAINT_TYPE_KINEMATIC:
-                                       build_ik_pose(scene, ob, pchan, con);
-                                       break;
-                               case CONSTRAINT_TYPE_SPLINEIK:
-                                       build_splineik_pose(scene, ob, pchan, con);
-                                       break;
-                               default:
-                                       break;
-                       }
-               }
-       }
- }
- void DepsgraphNodeBuilder::build_proxy_rig(Object *ob)
- {
-       ID *obdata = (ID *)ob->data;
-       build_animdata(obdata);
-       BLI_assert(ob->pose != NULL);
-       /* 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);
-       }
--
-       add_operation_node(&ob->id,
-                          DEPSNODE_TYPE_EVAL_POSE,
-                          DEPSOP_TYPE_INIT,
-                          function_bind(BKE_pose_eval_proxy_copy, _1, ob),
-                          DEG_OPCODE_POSE_INIT);
 -      /* component for all particle systems */
 -      ComponentDepsNode *psys_comp = add_component_node(&ob->id, DEPSNODE_TYPE_EVAL_PARTICLES);
--
-       for (bPoseChannel *pchan = (bPoseChannel *)ob->pose->chanbase.first;
-            pchan != NULL;
-            pchan = pchan->next)
-       {
-               add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
-                                  DEPSOP_TYPE_INIT, NULL,
-                                  DEG_OPCODE_BONE_LOCAL);
 -      /* particle systems */
 -      LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
 -              ParticleSettings *part = psys->part;
--
-               add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
-                                  DEPSOP_TYPE_EXEC, NULL,
-                                  DEG_OPCODE_BONE_READY);
 -              /* particle settings */
 -              // XXX: what if this is used more than once!
 -              build_animdata(&part->id);
--
-               add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
-                                  DEPSOP_TYPE_POST, NULL,
-                                  DEG_OPCODE_BONE_DONE);
 -              /* this particle system */
 -              // TODO: for now, this will just be a placeholder "ubereval" node
 -              add_operation_node(psys_comp,
 -                                 DEPSOP_TYPE_EXEC, function_bind(BKE_particle_system_eval,
 -                                                                 _1,
 -                                                                 scene,
 -                                                                 ob,
 -                                                                 psys),
 -                                 DEG_OPCODE_PSYS_EVAL,
 -                                 psys->name);
--      }
--
-       add_operation_node(&ob->id,
-                          DEPSNODE_TYPE_EVAL_POSE,
-                          DEPSOP_TYPE_POST,
-                          NULL,
-                          DEG_OPCODE_POSE_DONE);
 -      /* pointcache */
 -      // TODO...
--}
--
  /* Shapekeys */
  void DepsgraphNodeBuilder::build_shapekeys(Key *key)
  {
index bd62833846172d4ebaa5745b93936687e01566df,dadb7f8917fe8ff3bf330103fe1345532d4e3ff4..dca1da0979b56216f3d7af225b72bc4cb5378e1c
@@@ -55,9 -55,12 +55,11 @@@ extern "C" 
  #include "DNA_key_types.h"
  #include "DNA_lamp_types.h"
  #include "DNA_material_types.h"
+ #include "DNA_mask_types.h"
  #include "DNA_mesh_types.h"
  #include "DNA_meta_types.h"
+ #include "DNA_movieclip_types.h"
  #include "DNA_node_types.h"
 -#include "DNA_particle_types.h"
  #include "DNA_object_types.h"
  #include "DNA_rigidbody_types.h"
  #include "DNA_scene_types.h"
@@@ -1202,391 -1141,122 +1119,6 @@@ void DepsgraphRelationBuilder::build_ri
        }
  }
  
- /* IK Solver Eval Steps */
- void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
-                                              bPoseChannel *pchan,
-                                              bConstraint *con,
-                                              RootPChanMap *root_map)
 -void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
--{
-       bKinematicConstraint *data = (bKinematicConstraint *)con->data;
-       /* attach owner to IK Solver too
-        * - assume that owner is always part of chain
-        * - see notes on direction of rel below...
-        */
-       bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
-       OperationKey solver_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_IK_SOLVER);
-       /* IK target */
-       // XXX: this should get handled as part of the constraint code
-       if (data->tar != NULL) {
-               /* TODO(sergey): For until we'll store partial matricies in the depsgraph,
-                * we create dependency between target object and pose eval component.
-                *
-                * This way we ensuring the whole subtree is updated from scratch without
-                * need of intermediate matricies. This is an overkill, but good enough for
-                * testing IK solver.
-                */
-               // FIXME: geometry targets...
-               ComponentKey pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE);
-               if ((data->tar->type == OB_ARMATURE) && (data->subtarget[0])) {
-                       /* TODO(sergey): This is only for until granular update stores intermediate result. */
-                       if (data->tar != ob) {
-                               /* different armature - can just read the results */
-                               ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_BONE, data->subtarget);
-                               add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, con->name);
-                       }
-                       else {
-                               /* same armature - we'll use the ready state only, just in case this bone is in the chain we're solving */
-                               OperationKey target_key(&data->tar->id, DEPSNODE_TYPE_BONE, data->subtarget, DEG_OPCODE_BONE_DONE);
-                               add_relation(target_key, solver_key, DEPSREL_TYPE_TRANSFORM, con->name);
-                       }
-               }
-               else if (ELEM(data->tar->type, OB_MESH, OB_LATTICE) && (data->subtarget[0])) {
-                       /* vertex group target */
-                       /* NOTE: for now, we don't need to represent vertex groups separately... */
-                       ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_GEOMETRY);
-                       add_relation(target_key, solver_key, DEPSREL_TYPE_GEOMETRY_EVAL, con->name);
-                       if (data->tar->type == OB_MESH) {
-                               OperationDepsNode *node2 = find_operation_node(target_key);
-                               if (node2 != NULL) {
-                                       node2->customdata_mask |= CD_MASK_MDEFORMVERT;
-                               }
-                       }
-               }
-               else {
-                       /* Standard Object Target */
-                       ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_TRANSFORM);
-                       add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, con->name);
-               }
-               if ((data->tar == ob) && (data->subtarget[0])) {
-                       /* Prevent target's constraints from linking to anything from same
-                        * chain that it controls.
-                        */
-                       root_map->add_bone(data->subtarget, rootchan->name);
-               }
-       }
-       /* Pole Target */
-       // XXX: this should get handled as part of the constraint code
-       if (data->poletar != NULL) {
-               if ((data->poletar->type == OB_ARMATURE) && (data->polesubtarget[0])) {
-                       // XXX: same armature issues - ready vs done?
-                       ComponentKey target_key(&data->poletar->id, DEPSNODE_TYPE_BONE, data->polesubtarget);
-                       add_relation(target_key, solver_key, DEPSREL_TYPE_TRANSFORM, con->name);
-               }
-               else if (ELEM(data->poletar->type, OB_MESH, OB_LATTICE) && (data->polesubtarget[0])) {
-                       /* vertex group target */
-                       /* NOTE: for now, we don't need to represent vertex groups separately... */
-                       ComponentKey target_key(&data->poletar->id, DEPSNODE_TYPE_GEOMETRY);
-                       add_relation(target_key, solver_key, DEPSREL_TYPE_GEOMETRY_EVAL, con->name);
-                       if (data->poletar->type == OB_MESH) {
-                               OperationDepsNode *node2 = find_operation_node(target_key);
-                               if (node2 != NULL) {
-                                       node2->customdata_mask |= CD_MASK_MDEFORMVERT;
-                               }
-                       }
-               }
-               else {
-                       ComponentKey target_key(&data->poletar->id, DEPSNODE_TYPE_TRANSFORM);
-                       add_relation(target_key, solver_key, DEPSREL_TYPE_TRANSFORM, con->name);
-               }
-       }
-       DEG_DEBUG_PRINTF("\nStarting IK Build: pchan = %s, target = (%s, %s), segcount = %d\n",
-                        pchan->name, data->tar->id.name, data->subtarget, data->rootbone);
-       bPoseChannel *parchan = pchan;
-       /* exclude tip from chain? */
-       if (!(data->flag & CONSTRAINT_IK_TIP)) {
-               OperationKey tip_transforms_key(&ob->id, DEPSNODE_TYPE_BONE,
-                                               parchan->name, DEG_OPCODE_BONE_LOCAL);
-               add_relation(solver_key, tip_transforms_key,
-                            DEPSREL_TYPE_TRANSFORM, "IK Solver Result");
-               parchan = pchan->parent;
-       }
-       root_map->add_bone(parchan->name, rootchan->name);
-       OperationKey parchan_transforms_key(&ob->id, DEPSNODE_TYPE_BONE,
-                                           parchan->name, DEG_OPCODE_BONE_READY);
-       add_relation(parchan_transforms_key, solver_key,
-                    DEPSREL_TYPE_TRANSFORM, "IK Solver Owner");
-       /* Walk to the chain's root */
-       //size_t segcount = 0;
-       int segcount = 0;
-       while (parchan) {
-               /* Make IK-solver dependent on this bone's result,
-                * since it can only run after the standard results
-                * of the bone are know. Validate links step on the
-                * bone will ensure that users of this bone only
-                * grab the result with IK solver results...
-                */
-               if (parchan != pchan) {
-                       OperationKey parent_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY);
-                       add_relation(parent_key, solver_key, DEPSREL_TYPE_TRANSFORM, "IK Chain Parent");
-                       OperationKey done_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
-                       add_relation(solver_key, done_key, DEPSREL_TYPE_TRANSFORM, "IK Chain Result");
-               }
-               else {
-                       OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
-                       add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "IK Solver Result");
-               }
-               parchan->flag |= POSE_DONE;
-               root_map->add_bone(parchan->name, rootchan->name);
-               /* continue up chain, until we reach target number of items... */
-               DEG_DEBUG_PRINTF("  %d = %s\n", segcount, parchan->name);
-               segcount++;
-               if ((segcount == data->rootbone) || (segcount > 255)) break;  /* 255 is weak */
 -      TimeSourceKey time_src_key;
 -      OperationKey obdata_ubereval_key(&ob->id,
 -                                       DEPSNODE_TYPE_GEOMETRY,
 -                                       DEG_OPCODE_GEOMETRY_UBEREVAL);
--
-               parchan  = parchan->parent;
-       }
 -      /* particle systems */
 -      LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
 -              ParticleSettings *part = psys->part;
--
-       OperationKey flush_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
-       add_relation(solver_key, flush_key, DEPSREL_TYPE_OPERATION, "PoseEval Result-Bone Link");
- }
 -              /* particle settings */
 -              build_animdata(&part->id);
--
- /* Spline IK Eval Steps */
- void DepsgraphRelationBuilder::build_splineik_pose(Object *ob,
-                                                    bPoseChannel *pchan,
-                                                    bConstraint *con,
-                                                    RootPChanMap *root_map)
- {
-       bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
-       bPoseChannel *rootchan = BKE_armature_splineik_solver_find_root(pchan, data);
-       OperationKey transforms_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
-       OperationKey solver_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_SPLINE_IK_SOLVER);
 -              /* this particle system */
 -              OperationKey psys_key(&ob->id, DEPSNODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, psys->name);
--
-       /* attach owner to IK Solver too
-        * - assume that owner is always part of chain
-        * - see notes on direction of rel below...
-        */
-       add_relation(transforms_key, solver_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Solver Owner");
 -              /* XXX: if particle system is later re-enabled, we must do full rebuild? */
 -              if (!psys_check_enabled(ob, psys, G.is_rendering))
 -                      continue;
--
-       /* attach path dependency to solver */
-       if (data->tar) {
-               /* TODO(sergey): For until we'll store partial matricies in the depsgraph,
-                * we create dependency between target object and pose eval component.
-                * See IK pose for a bit more information.
 -              /* TODO(sergey): Are all particle systems depends on time?
 -               * Hair without dynamics i.e.
--               */
-               // TODO: the bigggest point here is that we need the curve PATH and not just the general geometry...
-               ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_GEOMETRY);
-               ComponentKey pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE);
-               add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, "[Curve.Path -> Spline IK] DepsRel");
-       }
-       pchan->flag |= POSE_DONE;
-       OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
-       add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Result");
-       root_map->add_bone(pchan->name, rootchan->name);
-       /* Walk to the chain's root */
-       //size_t segcount = 0;
-       int segcount = 0;
 -              add_relation(time_src_key, psys_key,
 -                           DEPSREL_TYPE_TIME,
 -                           "TimeSrc -> PSys");
--
-       for (bPoseChannel *parchan = pchan->parent; parchan; parchan = parchan->parent) {
-               /* Make Spline IK solver dependent on this bone's result,
-                * since it can only run after the standard results
-                * of the bone are know. Validate links step on the
-                * bone will ensure that users of this bone only
-                * grab the result with IK solver results...
 -              /* TODO(sergey): Currently particle update is just a placeholder,
 -               * hook it to the ubereval node so particle system is getting updated
 -               * on playback.
--               */
-               if (parchan != pchan) {
-                       OperationKey parent_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY);
-                       add_relation(parent_key, solver_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Solver Update");
 -              add_relation(psys_key,
 -                           obdata_ubereval_key,
 -                           DEPSREL_TYPE_OPERATION,
 -                           "PSys -> UberEval");
--
-                       OperationKey done_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
-                       add_relation(solver_key, done_key, DEPSREL_TYPE_TRANSFORM, "IK Chain Result");
 -#if 0
 -              if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) {
 -                      LINKLIST_FOREACH (ParticleTarget *, pt, &psys->targets) {
 -                              if (pt->ob && BLI_findlink(&pt->ob->particlesystem, pt->psys - 1)) {
 -                                      node2 = dag_get_node(dag, pt->ob);
 -                                      dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Targets");
 -                              }
 -                      }
--              }
-               parchan->flag |= POSE_DONE;
-               OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
-               add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Solver Result");
-               root_map->add_bone(parchan->name, rootchan->name);
-               /* continue up chain, until we reach target number of items... */
-               segcount++;
-               if ((segcount == data->chainlen) || (segcount > 255)) break;  /* 255 is weak */
-       }
-       OperationKey flush_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
-       add_relation(solver_key, flush_key, DEPSREL_TYPE_OPERATION, "PoseEval Result-Bone Link");
- }
- /* Pose/Armature Bones Graph */
- void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob)
- {
-       /* Armature-Data */
-       bArmature *arm = (bArmature *)ob->data;
-       // TODO: selection status?
-       /* attach links between pose operations */
-       OperationKey init_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT);
-       OperationKey flush_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
-       add_relation(init_key, flush_key, DEPSREL_TYPE_COMPONENT_ORDER, "[Pose Init -> Pose Cleanup]");
-       /* Make sure pose is up-to-date with armature updates. */
-       OperationKey armature_key(&arm->id,
-                                 DEPSNODE_TYPE_PARAMETERS,
-                                 DEG_OPCODE_PLACEHOLDER,
-                                 "Armature Eval");
-       add_relation(armature_key, init_key, DEPSREL_TYPE_COMPONENT_ORDER, "Data dependency");
-       if (needs_animdata_node(&ob->id)) {
-               ComponentKey animation_key(&ob->id, DEPSNODE_TYPE_ANIMATION);
-               add_relation(animation_key, init_key, DEPSREL_TYPE_OPERATION, "Rig Animation");
-       }
-       /* IK Solvers...
-        * - These require separate processing steps are pose-level
-        *   to be executed between chains of bones (i.e. once the
-        *   base transforms of a bunch of bones is done)
-        *
-        * - We build relations for these before the dependencies
-        *   between ops in the same component as it is necessary
-        *   to check whether such bones are in the same IK chain
-        *   (or else we get weird issues with either in-chain
-        *   references, or with bones being parented to IK'd bones)
-        *
-        * Unsolved Issues:
-        * - Care is needed to ensure that multi-headed trees work out the same as in ik-tree building
-        * - Animated chain-lengths are a problem...
-        */
-       RootPChanMap root_map;
-       bool pose_depends_on_local_transform = false;
-       for (bPoseChannel *pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
-               for (bConstraint *con = (bConstraint *)pchan->constraints.first; con; con = con->next) {
-                       switch (con->type) {
-                               case CONSTRAINT_TYPE_KINEMATIC:
-                                       build_ik_pose(ob, pchan, con, &root_map);
-                                       pose_depends_on_local_transform = true;
-                                       break;
-                               case CONSTRAINT_TYPE_SPLINEIK:
-                                       build_splineik_pose(ob, pchan, con, &root_map);
-                                       pose_depends_on_local_transform = true;
-                                       break;
--
-                               /* Constraints which needs world's matrix for transform.
-                                * TODO(sergey): More constraints here?
-                                */
-                               case CONSTRAINT_TYPE_ROTLIKE:
-                               case CONSTRAINT_TYPE_SIZELIKE:
-                               case CONSTRAINT_TYPE_LOCLIKE:
-                               case CONSTRAINT_TYPE_TRANSLIKE:
-                                       /* TODO(sergey): Add used space check. */
-                                       pose_depends_on_local_transform = true;
-                                       break;
 -              if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
 -                      node2 = dag_get_node(dag, part->dup_ob);
 -                      /* note that this relation actually runs in the wrong direction, the problem
 -                       * is that dupli system all have this (due to parenting), and the render
 -                       * engine instancing assumes particular ordering of objects in list */
 -                      dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualization");
 -                      if (part->dup_ob->type == OB_MBALL)
 -                              dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualization");
 -              }
--
-                               default:
-                                       break;
 -              if (part->ren_as == PART_DRAW_GR && part->dup_group) {
 -                      LINKLIST_FOREACH (GroupObject *, go, &part->dup_group->gobject) {
 -                              node2 = dag_get_node(dag, go->ob);
 -                              dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Group Visualization");
--                      }
--              }
-       }
-       //root_map.print_debug();
-       if (pose_depends_on_local_transform) {
-               /* TODO(sergey): Once partial updates are possible use relation between
-                * object transform and solver itself in it's build function.
-                */
-               ComponentKey pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE);
-               ComponentKey local_transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM);
-               add_relation(local_transform_key, pose_key, DEPSREL_TYPE_TRANSFORM, "Local Transforms");
-       }
-       /* links between operations for each bone */
-       for (bPoseChannel *pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
-               OperationKey bone_local_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
-               OperationKey bone_pose_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT);
-               OperationKey bone_ready_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
-               OperationKey bone_done_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
-               pchan->flag &= ~POSE_DONE;
 -#endif
--
-               /* pose init to bone local */
-               add_relation(init_key, bone_local_key, DEPSREL_TYPE_OPERATION, "PoseEval Source-Bone Link");
 -              /* collisions */
 -              if (part->type != PART_HAIR) {
 -                      add_collision_relations(psys_key, scene, ob, part->collision_group, ob->lay, true, "Particle Collision");
 -              }
--
-               /* local to pose parenting operation */
-               add_relation(bone_local_key, bone_pose_key, DEPSREL_TYPE_OPERATION, "Bone Local - PoseSpace Link");
 -              /* effectors */
 -              add_forcefield_relations(psys_key, scene, ob, psys, part->effector_weights, part->type == PART_HAIR, "Particle Field");
--
-               /* parent relation */
-               if (pchan->parent != NULL) {
-                       eDepsOperation_Code parent_key_opcode;
 -              /* boids */
 -              if (part->boids) {
 -                      LINKLIST_FOREACH (BoidState *, state, &part->boids->states) {
 -                              LINKLIST_FOREACH (BoidRule *, rule, &state->rules) {
 -                                      Object *ruleob = NULL;
 -                                      if (rule->type == eBoidRuleType_Avoid)
 -                                              ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
 -                                      else if (rule->type == eBoidRuleType_FollowLeader)
 -                                              ruleob = ((BoidRuleFollowLeader *)rule)->ob;
--
-                       /* NOTE: this difference in handling allows us to prevent lockups while ensuring correct poses for separate chains */
-                       if (root_map.has_common_root(pchan->name, pchan->parent->name)) {
-                               parent_key_opcode = DEG_OPCODE_BONE_READY;
-                       }
-                       else {
-                               parent_key_opcode = DEG_OPCODE_BONE_DONE;
 -                                      if (ruleob) {
 -                                              ComponentKey ruleob_key(&ruleob->id, DEPSNODE_TYPE_TRANSFORM);
 -                                              add_relation(ruleob_key, psys_key, DEPSREL_TYPE_TRANSFORM, "Boid Rule");
 -                                      }
 -                              }
--                      }
-                       OperationKey parent_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->parent->name, parent_key_opcode);
-                       add_relation(parent_key, bone_pose_key, DEPSREL_TYPE_TRANSFORM, "[Parent Bone -> Child Bone]");
--              }
-               /* constraints */
-               if (pchan->constraints.first != NULL) {
-                       /* constraints stack and constraint dependencies */
-                       build_constraints(scene, &ob->id, DEPSNODE_TYPE_BONE, pchan->name, &pchan->constraints, &root_map);
-                       /* pose -> constraints */
-                       OperationKey constraints_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_CONSTRAINTS);
-                       add_relation(bone_pose_key, constraints_key, DEPSREL_TYPE_OPERATION, "Constraints Stack");
--
-                       /* constraints -> ready */
-                       // TODO: when constraint stack is exploded, this step should occur before the first IK solver
-                       add_relation(constraints_key, bone_ready_key, DEPSREL_TYPE_OPERATION, "Constraints -> Ready");
-               }
-               else {
-                       /* pose -> ready */
-                       add_relation(bone_pose_key, bone_ready_key, DEPSREL_TYPE_OPERATION, "Pose -> Ready");
 -              if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
 -                      ComponentKey dup_ob_key(&part->dup_ob->id, DEPSNODE_TYPE_TRANSFORM);
 -                      add_relation(dup_ob_key,
 -                                   psys_key,
 -                                   DEPSREL_TYPE_TRANSFORM,
 -                                   "Particle Object Visualization");
--              }
-               /* bone ready -> done
-                * NOTE: For bones without IK, this is all that's needed.
-                *       For IK chains however, an additional rel is created from IK to done,
-                *       with transitive reduction removing this one...
-                */
-               add_relation(bone_ready_key, bone_done_key, DEPSREL_TYPE_OPERATION, "Ready -> Done");
-               /* assume that all bones must be done for the pose to be ready (for deformers) */
-               add_relation(bone_done_key, flush_key, DEPSREL_TYPE_OPERATION, "PoseEval Result-Bone Link");
--      }
- }
--
- void DepsgraphRelationBuilder::build_proxy_rig(Object *ob)
- {
-       OperationKey pose_init_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT);
-       OperationKey pose_done_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
-       for (bPoseChannel *pchan = (bPoseChannel *)ob->pose->chanbase.first;
-            pchan != NULL;
-            pchan = pchan->next)
-       {
-               OperationKey bone_local_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
-               OperationKey bone_ready_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
-               OperationKey bone_done_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
-               add_relation(pose_init_key, bone_local_key, DEPSREL_TYPE_OPERATION, "Pose Init -> Bone Local");
-               add_relation(bone_local_key, bone_ready_key, DEPSREL_TYPE_OPERATION, "Local -> Ready");
-               add_relation(bone_ready_key, bone_done_key, DEPSREL_TYPE_OPERATION, "Ready -> Done");
-               add_relation(bone_done_key, pose_done_key, DEPSREL_TYPE_OPERATION, "Bone Done -> Pose Done");
-       }
 -      /* Particle depends on the object transform, so that channel is to be ready
 -       * first.
 -       *
 -       * TODO(sergey): This relation should be altered once real granular update
 -       * is implemented.
 -       */
 -      ComponentKey transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM);
 -      add_relation(transform_key,
 -                   obdata_ubereval_key,
 -                   DEPSREL_TYPE_GEOMETRY_EVAL,
 -                   "Partcile Eval");
 -
 -      /* pointcache */
 -      // TODO...
--}
--
  /* Shapekeys */
  void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key)
  {
index 28dd63a7c1772393a9a8f7bd8d9fc296da367c8e,6e8485bee309af42fd435dabe5f22e340c94fc69..2326e212feb4c9227c4a9e4fc50989ceb19a9049
@@@ -220,9 -223,12 +223,12 @@@ struct DepsgraphRelationBuilde
        void build_texture_stack(ID *owner, MTex **texture_stack);
        void build_compositor(Scene *scene);
        void build_gpencil(ID *owner, bGPdata *gpd);
+       void build_cachefile(CacheFile *cache_file);
+       void build_mask(Mask *mask);
+       void build_movieclip(MovieClip *clip);
  
        void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name);
 -      void add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name);
 +      void add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, EffectorWeights *eff, bool add_absorption, const char *name);
  
        template <typename KeyType>
        OperationDepsNode *find_operation_node(const KeyType &key);
index 4ae5bdff5086a95b759f8344bb188f074b3e51ca,90d33dc59957e41d866e455b9fc8bcdaf2a11e80..45041620fea64ea866bbe0f73b4216e5acdb987f
@@@ -972,105 -631,105 +972,114 @@@ void drawaxes(const float viewmat_local
  
  
  /* Function to draw an Image on an empty Object */
- static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4])
+ static void draw_empty_image(Object *ob, const short dflag, const unsigned char ob_wire_col[4], StereoViews sview)
  {
        Image *ima = ob->data;
 -      ImBuf *ibuf;
 -      ImageUser iuser = *ob->iuser;
  
 -      /* Support multi-view */
 -      if (ima && (sview == STEREO_RIGHT_ID)) {
 -              iuser.multiview_eye = sview;
 -              iuser.flag |= IMA_SHOW_STEREO;
 -              BKE_image_multiview_index(ima, &iuser);
 -      }
 +      const float ob_alpha = ob->col[3];
 +      float width, height;
  
 -      ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
 +      int bindcode = 0;
  
 -      if (ibuf && (ibuf->rect == NULL) && (ibuf->rect_float != NULL)) {
 -              IMB_rect_from_float(ibuf);
 -      }
 +      if (ima) {
++              ImageUser iuser = *ob->iuser;
++
++              /* Support multi-view */
++              if (ima && (sview == STEREO_RIGHT_ID)) {
++                      iuser.multiview_eye = sview;
++                      iuser.flag |= IMA_SHOW_STEREO;
++                      BKE_image_multiview_index(ima, &iuser);
++              }
 -      int ima_x, ima_y;
 +              if (ob_alpha > 0.0f) {
-                       bindcode = GPU_verify_image(ima, ob->iuser, GL_TEXTURE_2D, 0, false, false, false);
++                      bindcode = GPU_verify_image(ima, &iuser, GL_TEXTURE_2D, 0, false, false, false);
 +                      /* don't bother drawing the image if alpha = 0 */
 +              }
  
 -      /* Get the buffer dimensions so we can fallback to fake ones */
 -      if (ibuf && ibuf->rect) {
 -              ima_x = ibuf->x;
 -              ima_y = ibuf->y;
 +              int w, h;
-               BKE_image_get_size(ima, ob->iuser, &w, &h);
++              BKE_image_get_size(ima, &iuser, &w, &h);
 +              width = w;
 +              height = h;
        }
        else {
 -              ima_x = 1;
 -              ima_y = 1;
 +              /* if no image, make it a 1x1 empty square, honor scale & offset */
 +              width = height = 1.0f;
        }
  
 -      float sca_x = 1.0f;
 -      float sca_y = 1.0f;
 +      const float aspect = height / width;
  
 -      /* Get the image aspect even if the buffer is invalid */
 -      if (ima) {
 -              if (ima->aspx > ima->aspy) {
 -                      sca_y = ima->aspy / ima->aspx;
 -              }
 -              else if (ima->aspx < ima->aspy) {
 -                      sca_x = ima->aspx / ima->aspy;
 -              }
 -      }
 +      float left = ob->ima_ofs[0];
 +      float right = ob->ima_ofs[0] + ob->empty_drawsize;
 +      float top = ob->ima_ofs[1] + ob->empty_drawsize * aspect;
 +      float bottom = ob->ima_ofs[1];
  
 -      /* Calculate the scale center based on object's origin */
 -      float ofs_x = ob->ima_ofs[0] * ima_x;
 -      float ofs_y = ob->ima_ofs[1] * ima_y;
 +      bool use_blend = false;
  
 -      glMatrixMode(GL_MODELVIEW);
 -      glPushMatrix();
 +      if (bindcode) {
 +              use_blend = ob_alpha < 1.0f || BKE_image_has_alpha(ima);
  
 -      /* Calculate Image scale */
 -      float scale = ob->empty_drawsize / max_ff((float)ima_x * sca_x, (float)ima_y * sca_y);
 +              if (use_blend) {
 +                      glEnable(GL_BLEND);
 +                      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 +              }
  
 -      /* Set the object scale */
 -      glScalef(scale * sca_x, scale * sca_y, 1.0f);
 +              VertexFormat *format = immVertexFormat();
 +              unsigned pos = add_attrib(format, "pos", GL_FLOAT, 2, KEEP_FLOAT);
 +              unsigned texCoord = add_attrib(format, "texCoord", GL_FLOAT, 2, KEEP_FLOAT);
 +              immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_MODULATE_ALPHA);
 +              immUniform1f("alpha", ob_alpha);
 +              immUniform1i("image", 0); /* default GL_TEXTURE0 unit */
  
 -      if (ibuf && ibuf->rect) {
 -              const bool use_clip = (U.glalphaclip != 1.0f);
 -              int zoomfilter = (U.gameflags & USER_DISABLE_MIPMAP) ? GL_NEAREST : GL_LINEAR;
 -              /* Setup GL params */
 -              glEnable(GL_BLEND);
 -              glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 +              immBegin(GL_TRIANGLE_FAN, 4);
 +              immAttrib2f(texCoord, 0.0f, 0.0f);
 +              immVertex2f(pos, left, bottom);
  
 -              if (use_clip) {
 -                      glEnable(GL_ALPHA_TEST);
 -                      glAlphaFunc(GL_GREATER, U.glalphaclip);
 -              }
 +              immAttrib2f(texCoord, 1.0f, 0.0f);
 +              immVertex2f(pos, right, bottom);
  
 -              /* Use the object color and alpha */
 -              glColor4fv(ob->col);
 +              immAttrib2f(texCoord, 1.0f, 1.0f);
 +              immVertex2f(pos, right, top);
  
 -              /* Draw the Image on the screen */
 -              glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, GL_UNSIGNED_BYTE, zoomfilter, ibuf->rect);
 +              immAttrib2f(texCoord, 0.0f, 1.0f);
 +              immVertex2f(pos, left, top);
 +              immEnd();
  
 -              glDisable(GL_BLEND);
 +              immUnbindProgram();
  
 -              if (use_clip) {
 -                      glDisable(GL_ALPHA_TEST);
 -                      glAlphaFunc(GL_ALWAYS, 0.0f);
 -              }
 +              glBindTexture(GL_TEXTURE_2D, 0); /* necessary? */
        }
  
 -      if ((dflag & DRAW_CONSTCOLOR) == 0) {
 -              glColor3ubv(ob_wire_col);
 +      /* Draw the image outline */
 +      glLineWidth(1.5f);
 +      unsigned pos = add_attrib(immVertexFormat(), "pos", GL_FLOAT, 2, KEEP_FLOAT);
 +
 +      const bool picking = dflag & DRAW_CONSTCOLOR;
 +      if (picking) {
 +              /* TODO: deal with picking separately, use this function just to draw */
 +              immBindBuiltinProgram(GPU_SHADER_3D_DEPTH_ONLY);
 +              if (use_blend) {
 +                      glDisable(GL_BLEND);
 +              }
 +
 +              imm_draw_line_box(pos, left, bottom, right, top);
        }
 +      else {
 +              immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
 +              immUniformColor3ubv(ob_wire_col);
 +              glEnable(GL_LINE_SMOOTH);
  
 -      /* Calculate the outline vertex positions */
 -      glBegin(GL_LINE_LOOP);
 -      glVertex2f(ofs_x, ofs_y);
 -      glVertex2f(ofs_x + ima_x, ofs_y);
 -      glVertex2f(ofs_x + ima_x, ofs_y + ima_y);
 -      glVertex2f(ofs_x, ofs_y + ima_y);
 -      glEnd();
 +              if (!use_blend) {
 +                      glEnable(GL_BLEND);
 +                      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 +              }
  
 -      /* Reset GL settings */
 -      glPopMatrix();
 +              imm_draw_line_box(pos, left, bottom, right, top);
 +
 +              glDisable(GL_LINE_SMOOTH);
 +              glDisable(GL_BLEND);
 +      }
  
 -      BKE_image_release_ibuf(ima, ibuf, NULL);
 +      immUnbindProgram();
  }
  
  static void circball_array_fill(float verts[CIRCLE_RESOL][3], const float cent[3], float rad, const float tmat[4][4])
@@@ -7685,10 -7718,10 +7694,10 @@@ void draw_object(Scene *scene, ARegion 
                        case OB_EMPTY:
                                if (!render_override) {
                                        if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
-                                               draw_empty_image(ob, dflag, ob_wire_col);
+                                               draw_empty_image(ob, dflag, ob_wire_col, v3d->multiview_eye);
                                        }
                                        else {
 -                                              drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype);
 +                                              drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, ob_wire_col);
                                        }
                                }
                                break;
@@@ -8420,10 -8498,10 +8429,10 @@@ void draw_object_instance(Scene *scene
                case OB_EMPTY:
                        if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
                                /* CONSTCOLOR == no wire outline */
-                               draw_empty_image(ob, DRAW_CONSTCOLOR, NULL);
+                               draw_empty_image(ob, DRAW_CONSTCOLOR, NULL, v3d->multiview_eye);
                        }
                        else {
 -                              drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype);
 +                              drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, NULL); /* TODO: use proper color */
                        }
                        break;
        }