Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / constraint.c
index 7d86165899330f4afd5ca3047d385201bbab7279..5aa192d527ab729d04866bd449dfd8fc6d506167 100644 (file)
@@ -52,6 +52,7 @@
 #include "DNA_object_types.h"
 #include "DNA_action_types.h"
 #include "DNA_curve_types.h"
+#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 
 #include "DNA_lattice_types.h"
 #include "BKE_camera.h"
 #include "BKE_constraint.h"
 #include "BKE_curve.h"
-#include "BKE_displist.h"
 #include "BKE_deform.h"
-#include "BKE_DerivedMesh.h"    /* for geometry targets */
-#include "BKE_cdderivedmesh.h" /* for geometry targets */
-#include "BKE_object.h"
+#include "BKE_displist.h"
+#include "BKE_editmesh.h"
 #include "BKE_global.h"
-#include "BKE_library.h"
 #include "BKE_idprop.h"
-#include "BKE_shrinkwrap.h"
-#include "BKE_editmesh.h"
+#include "BKE_library.h"
+#include "BKE_mesh_runtime.h"
+#include "BKE_movieclip.h"
+#include "BKE_object.h"
 #include "BKE_scene.h"
+#include "BKE_shrinkwrap.h"
 #include "BKE_tracking.h"
-#include "BKE_movieclip.h"
 
 #include "BIK_api.h"
 
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
 #ifdef WITH_PYTHON
 #  include "BPY_extern.h"
 #endif
 /* Constraint Target Macros */
 #define VALID_CONS_TARGET(ct) ((ct) && (ct->tar))
 
-/* Workaround for cyclic depenndnecy with curves.
- * In such case curve_cache might not be ready yet,
- */
-#define CYCLIC_DEPENDENCY_WORKAROUND
-
 /* ************************ Constraints - General Utilities *************************** */
 /* These functions here don't act on any specific constraints, and are therefore should/will
  * not require any of the special function-pointers afforded by the relevant constraint
@@ -121,7 +119,7 @@ void BKE_constraint_unique_name(bConstraint *con, ListBase *list)
 
 /* package an object/bone for use in constraint evaluation */
 /* This function MEM_calloc's a bConstraintOb struct, that will need to be freed after evaluation */
-bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subdata, short datatype)
+bConstraintOb *BKE_constraints_make_evalob(Depsgraph *depsgraph, Scene *scene, Object *ob, void *subdata, short datatype)
 {
        bConstraintOb *cob;
 
@@ -130,6 +128,7 @@ bConstraintOb *BKE_constraints_make_evalob(Scene *scene, Object *ob, void *subda
 
        /* for system time, part of deglobalization, code nicer later with local time (ton) */
        cob->scene = scene;
+       cob->depsgraph = depsgraph;
 
        /* based on type of available data */
        switch (datatype) {
@@ -392,99 +391,104 @@ void BKE_constraint_mat_convertspace(
 /* function that sets the given matrix based on given vertex group in mesh */
 static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[4][4])
 {
-       DerivedMesh *dm = NULL;
+       /* when not in EditMode, use the 'final' evaluated mesh, depsgraph
+        * ensures we build with CD_MDEFORMVERT layer
+        */
+       Mesh *me_eval = ob->runtime.mesh_eval;
        BMEditMesh *em = BKE_editmesh_from_object(ob);
-       float vec[3] = {0.0f, 0.0f, 0.0f};
-       float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
+       float plane[3];
        float imat[3][3], tmat[3][3];
        const int defgroup = defgroup_name_index(ob, substring);
-       short freeDM = 0;
 
        /* initialize target matrix using target matrix */
        copy_m4_m4(mat, ob->obmat);
 
        /* get index of vertex group */
-       if (defgroup == -1) return;
-
-       /* get DerivedMesh */
-       if (em) {
-               /* target is in editmode, so get a special derived mesh */
-               dm = CDDM_from_editbmesh(em, false, false);
-               freeDM = 1;
-       }
-       else {
-               /* when not in EditMode, use the 'final' derived mesh, depsgraph
-                * ensures we build with CD_MDEFORMVERT layer
-                */
-               dm = (DerivedMesh *)ob->derivedFinal;
+       if (defgroup == -1) {
+               return;
        }
 
-       /* only continue if there's a valid DerivedMesh */
-       if (dm) {
-               MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
-               int numVerts = dm->getNumVerts(dm);
-               int i;
-               float co[3], nor[3];
+       float vec[3] = {0.0f, 0.0f, 0.0f};
+       float normal[3] = {0.0f, 0.0f, 0.0f};
+       float weightsum = 0.0f;
+       if (me_eval) {
+               MDeformVert *dvert = CustomData_get_layer(&me_eval->vdata, CD_MDEFORMVERT);
+               int numVerts = me_eval->totvert;
 
                /* check that dvert is a valid pointers (just in case) */
                if (dvert) {
                        MDeformVert *dv = dvert;
-                       float weightsum = 0.0f;
+                       MVert *mv = me_eval->mvert;
 
                        /* get the average of all verts with that are in the vertex-group */
-                       for (i = 0; i < numVerts; i++, dv++) {
+                       for (int i = 0; i < numVerts; i++, dv++, mv++) {
                                MDeformWeight *dw = defvert_find_index(dv, defgroup);
 
                                if (dw && dw->weight > 0.0f) {
-                                       dm->getVertCo(dm, i, co);
-                                       dm->getVertNo(dm, i, nor);
-                                       madd_v3_v3fl(vec, co, dw->weight);
+                                       float nor[3];
+                                       normal_short_to_float_v3(nor, mv->no);
+                                       madd_v3_v3fl(vec, mv->co, dw->weight);
                                        madd_v3_v3fl(normal, nor, dw->weight);
                                        weightsum += dw->weight;
                                }
                        }
+               }
+       }
+       else if (em) {
+               if (CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT)) {
+                       BMVert *v;
+                       BMIter iter;
 
-                       /* calculate averages of normal and coordinates */
-                       if (weightsum > 0) {
-                               mul_v3_fl(vec, 1.0f / weightsum);
-                               mul_v3_fl(normal, 1.0f / weightsum);
-                       }
-
+                       BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
+                               MDeformVert *dv = CustomData_bmesh_get(&em->bm->vdata, v->head.data, CD_MDEFORMVERT);
+                               MDeformWeight *dw = defvert_find_index(dv, defgroup);
 
-                       /* derive the rotation from the average normal:
-                        *              - code taken from transform_manipulator.c,
-                        *                      calc_manipulator_stats, V3D_MANIP_NORMAL case
-                        */
-                       /*      we need the transpose of the inverse for a normal... */
-                       copy_m3_m4(imat, ob->obmat);
+                               if (dw && dw->weight > 0.0f) {
+                                       madd_v3_v3fl(vec, v->co, dw->weight);
+                                       madd_v3_v3fl(normal, v->no, dw->weight);
+                                       weightsum += dw->weight;
+                               }
+                       }
+               }
+       }
+       else {
+               /* No valid edit or evaluated mesh, just abort. */
+               return;
+       }
 
-                       invert_m3_m3(tmat, imat);
-                       transpose_m3(tmat);
-                       mul_m3_v3(tmat, normal);
+       /* calculate averages of normal and coordinates */
+       if (weightsum > 0) {
+               mul_v3_fl(vec, 1.0f / weightsum);
+               mul_v3_fl(normal, 1.0f / weightsum);
+       }
 
-                       normalize_v3(normal);
-                       copy_v3_v3(plane, tmat[1]);
+       /* derive the rotation from the average normal:
+        *              - code taken from transform_gizmo.c,
+        *                      calc_gizmo_stats, V3D_MANIP_NORMAL case
+        */
+       /*      we need the transpose of the inverse for a normal... */
+       copy_m3_m4(imat, ob->obmat);
 
-                       cross_v3_v3v3(mat[0], normal, plane);
-                       if (len_squared_v3(mat[0]) < SQUARE(1e-3f)) {
-                               copy_v3_v3(plane, tmat[0]);
-                               cross_v3_v3v3(mat[0], normal, plane);
-                       }
+       invert_m3_m3(tmat, imat);
+       transpose_m3(tmat);
+       mul_m3_v3(tmat, normal);
 
-                       copy_v3_v3(mat[2], normal);
-                       cross_v3_v3v3(mat[1], mat[2], mat[0]);
+       normalize_v3(normal);
+       copy_v3_v3(plane, tmat[1]);
 
-                       normalize_m4(mat);
+       cross_v3_v3v3(mat[0], normal, plane);
+       if (len_squared_v3(mat[0]) < SQUARE(1e-3f)) {
+               copy_v3_v3(plane, tmat[0]);
+               cross_v3_v3v3(mat[0], normal, plane);
+       }
 
+       copy_v3_v3(mat[2], normal);
+       cross_v3_v3v3(mat[1], mat[2], mat[0]);
 
-                       /* apply the average coordinate as the new location */
-                       mul_v3_m4v3(mat[3], ob->obmat, vec);
-               }
-       }
+       normalize_m4(mat);
 
-       /* free temporary DerivedMesh created (in EditMode case) */
-       if (dm && freeDM)
-               dm->release(dm);
+       /* apply the average coordinate as the new location */
+       mul_v3_m4v3(mat[3], ob->obmat, vec);
 }
 
 /* function that sets the given matrix based on given vertex group in lattice */
@@ -689,7 +693,7 @@ static bConstraintTypeInfo CTI_CONSTRNAME = {
 /* This function should be used for the get_target_matrix member of all
  * constraints that are not picky about what happens to their target matrix.
  */
-static void default_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void default_get_tarmat(struct Depsgraph *UNUSED(depsgraph), bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
 {
        if (VALID_CONS_TARGET(ct))
                constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->flag, con->headtail);
@@ -1158,7 +1162,7 @@ static void kinematic_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
        }
 }
 
-static void kinematic_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void kinematic_get_tarmat(struct Depsgraph *UNUSED(depsgraph), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
 {
        bKinematicConstraint *data = con->data;
 
@@ -1245,7 +1249,9 @@ static void followpath_flush_tars(bConstraint *con, ListBase *list, bool no_copy
        }
 }
 
-static void followpath_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void followpath_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
+                                  bConstraint *con, bConstraintOb *UNUSED(cob),
+                                  bConstraintTarget *ct, float UNUSED(ctime))
 {
        bFollowPathConstraint *data = con->data;
 
@@ -1260,13 +1266,7 @@ static void followpath_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
                 *              currently for paths to work it needs to go through the bevlist/displist system (ton)
                 */
 
-#ifdef CYCLIC_DEPENDENCY_WORKAROUND
-               if (ct->tar->curve_cache == NULL) {
-                       BKE_displist_make_curveTypes(cob->scene, ct->tar, false);
-               }
-#endif
-
-               if (ct->tar->curve_cache->path && ct->tar->curve_cache->path->data) {
+               if (ct->tar->curve_cache && ct->tar->curve_cache->path && ct->tar->curve_cache->path->data) {
                        float quat[4];
                        if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
                                /* animated position along curve depending on time */
@@ -2028,21 +2028,19 @@ static void pycon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userd
 }
 
 /* Whether this approach is maintained remains to be seen (aligorith) */
-static void pycon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void pycon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
+                             bConstraint *con, bConstraintOb *UNUSED(cob),
+                             bConstraintTarget *ct, float UNUSED(ctime))
 {
 #ifdef WITH_PYTHON
        bPythonConstraint *data = con->data;
 #endif
 
        if (VALID_CONS_TARGET(ct)) {
-#ifdef CYCLIC_DEPENDENCY_WORKAROUND
-               /* special exception for curves - depsgraph issues */
-               if (ct->tar->type == OB_CURVE) {
-                       if (ct->tar->curve_cache == NULL) {
-                               BKE_displist_make_curveTypes(cob->scene, ct->tar, false);
-                       }
+               if (ct->tar->type == OB_CURVE && ct->tar->curve_cache == NULL) {
+                       unit_m4(ct->matrix);
+                       return;
                }
-#endif
 
                /* firstly calculate the matrix the normal way, then let the py-function override
                 * this matrix if it needs to do so
@@ -2146,7 +2144,7 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
        }
 }
 
-static void actcon_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
 {
        bActionConstraint *data = con->data;
 
@@ -3039,66 +3037,6 @@ static bConstraintTypeInfo CTI_MINMAX = {
        minmax_evaluate /* evaluate */
 };
 
-/* ------- RigidBody Joint ---------- */
-
-static void rbj_new_data(void *cdata)
-{
-       bRigidBodyJointConstraint *data = (bRigidBodyJointConstraint *)cdata;
-
-       /* removed code which set target of this constraint */
-       data->type = 1;
-}
-
-static void rbj_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
-{
-       bRigidBodyJointConstraint *data = con->data;
-
-       /* target only */
-       func(con, (ID **)&data->tar, false, userdata);
-       func(con, (ID **)&data->child, false, userdata);
-}
-
-static int rbj_get_tars(bConstraint *con, ListBase *list)
-{
-       if (con && list) {
-               bRigidBodyJointConstraint *data = con->data;
-               bConstraintTarget *ct;
-
-               /* standard target-getting macro for single-target constraints without subtargets */
-               SINGLETARGETNS_GET_TARS(con, data->tar, ct, list);
-
-               return 1;
-       }
-
-       return 0;
-}
-
-static void rbj_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
-{
-       if (con && list) {
-               bRigidBodyJointConstraint *data = con->data;
-               bConstraintTarget *ct = list->first;
-
-               /* the following macro is used for all standard single-target constraints */
-               SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, no_copy);
-       }
-}
-
-static bConstraintTypeInfo CTI_RIGIDBODYJOINT = {
-       CONSTRAINT_TYPE_RIGIDBODYJOINT, /* type */
-       sizeof(bRigidBodyJointConstraint), /* size */
-       "Rigid Body Joint", /* name */
-       "bRigidBodyJointConstraint", /* struct name */
-       NULL, /* free data */
-       rbj_id_looper, /* id looper */
-       NULL, /* copy data */
-       rbj_new_data, /* new data */
-       rbj_get_tars, /* get constraint targets */
-       rbj_flush_tars, /* flush constraint targets */
-       default_get_tarmat, /* get target matrix */
-       NULL /* evaluate - this is not solved here... is just an interface for game-engine */
-};
-
 /* -------- Clamp To ---------- */
 
 static void clampto_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
@@ -3135,16 +3073,10 @@ static void clampto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
        }
 }
 
-static void clampto_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void clampto_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
+                               bConstraint *UNUSED(con), bConstraintOb *UNUSED(cob),
+                               bConstraintTarget *ct, float UNUSED(ctime))
 {
-#ifdef CYCLIC_DEPENDENCY_WORKAROUND
-       if (VALID_CONS_TARGET(ct)) {
-               if (ct->tar->curve_cache == NULL) {
-                       BKE_displist_make_curveTypes(cob->scene, ct->tar, false);
-               }
-       }
-#endif
-
        /* technically, this isn't really needed for evaluation, but we don't know what else
         * might end up calling this...
         */
@@ -3478,23 +3410,23 @@ static void shrinkwrap_flush_tars(bConstraint *con, ListBase *list, bool no_copy
 }
 
 
-static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
 {
        bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data;
 
        if (VALID_CONS_TARGET(ct) && (ct->tar->type == OB_MESH) ) {
+
                bool fail = false;
                float co[3] = {0.0f, 0.0f, 0.0f};
 
                SpaceTransform transform;
-               /* TODO(sergey): use proper for_render flag here when known. */
-               DerivedMesh *target = object_get_derived_final(ct->tar, false);
+               Mesh *target_eval = mesh_get_eval_final(depsgraph, DEG_get_input_scene(depsgraph), ct->tar, CD_MASK_BAREMESH);
 
                BVHTreeFromMesh treeData = {NULL};
 
                unit_m4(ct->matrix);
 
-               if (target != NULL) {
+               if (target_eval != NULL) {
                        BLI_space_transform_from_matrices(&transform, cob->matrix, ct->tar->obmat);
 
                        switch (scon->shrinkType) {
@@ -3508,9 +3440,9 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
                                        nearest.dist_sq = FLT_MAX;
 
                                        if (scon->shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX)
-                                               bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_VERTS, 2);
+                                               BKE_bvhtree_from_mesh_get(&treeData, target_eval, BVHTREE_FROM_VERTS, 2);
                                        else
-                                               bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 2);
+                                               BKE_bvhtree_from_mesh_get(&treeData, target_eval, BVHTREE_FROM_LOOPTRI, 2);
 
                                        if (treeData.tree == NULL) {
                                                fail = true;
@@ -3562,7 +3494,7 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
                                                break;
                                        }
 
-                                       bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 4);
+                                       BKE_bvhtree_from_mesh_get(&treeData, target_eval, BVHTREE_FROM_LOOPTRI, 4);
                                        if (treeData.tree == NULL) {
                                                fail = true;
                                                break;
@@ -3837,16 +3769,10 @@ static void splineik_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
        }
 }
 
-static void splineik_get_tarmat(bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void splineik_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
+                                bConstraint *UNUSED(con), bConstraintOb *UNUSED(cob),
+                                bConstraintTarget *ct, float UNUSED(ctime))
 {
-#ifdef CYCLIC_DEPENDENCY_WORKAROUND
-       if (VALID_CONS_TARGET(ct)) {
-               if (ct->tar->curve_cache == NULL) {
-                       BKE_displist_make_curveTypes(cob->scene, ct->tar, false);
-               }
-       }
-#endif
-
        /* technically, this isn't really needed for evaluation, but we don't know what else
         * might end up calling this...
         */
@@ -4014,20 +3940,25 @@ static void followtrack_id_looper(bConstraint *con, ConstraintIDFunc func, void
 
 static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
 {
+       Depsgraph *depsgraph = cob->depsgraph;
        Scene *scene = cob->scene;
        bFollowTrackConstraint *data = con->data;
        MovieClip *clip = data->clip;
        MovieTracking *tracking;
        MovieTrackingTrack *track;
        MovieTrackingObject *tracking_object;
-       Object *camob = data->camera ? data->camera : scene->camera;
-       float ctime = BKE_scene_frame_get(scene);
+
+       Object *camob_eval = DEG_get_evaluated_object(
+                                depsgraph,
+                                data->camera ? data->camera : scene->camera);
+
+       float ctime = DEG_get_ctime(depsgraph);;
        float framenr;
 
        if (data->flag & FOLLOWTRACK_ACTIVECLIP)
                clip = scene->clip;
 
-       if (!clip || !data->track[0] || !camob)
+       if (!clip || !data->track[0] || !camob_eval)
                return;
 
        tracking = &clip->tracking;
@@ -4056,7 +3987,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
                        if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) {
                                float imat[4][4];
 
-                               copy_m4_m4(mat, camob->obmat);
+                               copy_m4_m4(mat, camob_eval->obmat);
 
                                BKE_tracking_camera_get_reconstructed_interpolate(tracking, tracking_object, framenr, imat);
                                invert_m4(imat);
@@ -4065,7 +3996,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
                                translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
                        }
                        else {
-                               BKE_tracking_get_camera_object_matrix(cob->scene, camob, mat);
+                               BKE_tracking_get_camera_object_matrix(depsgraph, cob->scene, camob_eval, mat);
 
                                mul_m4_m4m4(cob->matrix, obmat, mat);
                                translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
@@ -4077,7 +4008,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
                float aspect = (scene->r.xsch * scene->r.xasp) / (scene->r.ysch * scene->r.yasp);
                float len, d;
 
-               BKE_object_where_is_calc_mat4(scene, camob, mat);
+               BKE_object_where_is_calc_mat4(depsgraph, scene, camob_eval, mat);
 
                /* camera axis */
                vec[0] = 0.0f;
@@ -4145,7 +4076,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
                        }
 
                        BKE_camera_params_init(&params);
-                       BKE_camera_params_from_object(&params, camob);
+                       BKE_camera_params_from_object(&params, camob_eval);
 
                        if (params.is_ortho) {
                                vec[0] = params.ortho_scale * (pos[0] - 0.5f + params.shiftx);
@@ -4157,9 +4088,9 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
                                else
                                        vec[0] *= aspect;
 
-                               mul_v3_m4v3(disp, camob->obmat, vec);
+                               mul_v3_m4v3(disp, camob_eval->obmat, vec);
 
-                               copy_m4_m4(rmat, camob->obmat);
+                               copy_m4_m4(rmat, camob_eval->obmat);
                                zero_v3(rmat[3]);
                                mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
 
@@ -4177,10 +4108,10 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
                                else
                                        vec[0] *= aspect;
 
-                               mul_v3_m4v3(disp, camob->obmat, vec);
+                               mul_v3_m4v3(disp, camob_eval->obmat, vec);
 
                                /* apply camera rotation so Z-axis would be co-linear */
-                               copy_m4_m4(rmat, camob->obmat);
+                               copy_m4_m4(rmat, camob_eval->obmat);
                                zero_v3(rmat[3]);
                                mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
 
@@ -4189,9 +4120,9 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
 
                        if (data->depth_ob) {
                                Object *depth_ob = data->depth_ob;
-                               /* TODO(sergey): use proper for_render flag here when known. */
-                               DerivedMesh *target = object_get_derived_final(depth_ob, false);
-                               if (target) {
+                               Mesh *target_eval = mesh_get_eval_final(
+                                                       depsgraph, DEG_get_input_scene(depsgraph), depth_ob, CD_MASK_BAREMESH);
+                               if (target_eval) {
                                        BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
                                        BVHTreeRayHit hit;
                                        float ray_start[3], ray_end[3], ray_nor[3], imat[4][4];
@@ -4199,25 +4130,25 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
 
                                        invert_m4_m4(imat, depth_ob->obmat);
 
-                                       mul_v3_m4v3(ray_start, imat, camob->obmat[3]);
+                                       mul_v3_m4v3(ray_start, imat, camob_eval->obmat[3]);
                                        mul_v3_m4v3(ray_end, imat, cob->matrix[3]);
 
                                        sub_v3_v3v3(ray_nor, ray_end, ray_start);
                                        normalize_v3(ray_nor);
 
-                                       bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 4);
+                                       BKE_bvhtree_from_mesh_get(&treeData, target_eval, BVHTREE_FROM_LOOPTRI, 4);
 
                                        hit.dist = BVH_RAYCAST_DIST_MAX;
                                        hit.index = -1;
 
-                                       result = BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData);
+                                       result = BLI_bvhtree_ray_cast(
+                                                    treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData);
 
                                        if (result != -1) {
                                                mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co);
                                        }
 
                                        free_bvhtree_from_mesh(&treeData);
-                                       target->release(target);
                                }
                        }
                }
@@ -4258,6 +4189,7 @@ static void camerasolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
 
 static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
 {
+       Depsgraph *depsgraph = cob->depsgraph;
        Scene *scene = cob->scene;
        bCameraSolverConstraint *data = con->data;
        MovieClip *clip = data->clip;
@@ -4269,7 +4201,7 @@ static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
                float mat[4][4], obmat[4][4];
                MovieTracking *tracking = &clip->tracking;
                MovieTrackingObject *object = BKE_tracking_object_get_camera(tracking);
-               float ctime = BKE_scene_frame_get(scene);
+               float ctime = DEG_get_ctime(depsgraph);
                float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
 
                BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
@@ -4316,6 +4248,7 @@ static void objectsolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
 
 static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
 {
+       Depsgraph *depsgraph = cob->depsgraph;
        Scene *scene = cob->scene;
        bObjectSolverConstraint *data = con->data;
        MovieClip *clip = data->clip;
@@ -4335,10 +4268,10 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
 
                if (object) {
                        float mat[4][4], obmat[4][4], imat[4][4], cammat[4][4], camimat[4][4], parmat[4][4];
-                       float ctime = BKE_scene_frame_get(scene);
+                       float ctime = DEG_get_ctime(depsgraph);
                        float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
 
-                       BKE_object_where_is_calc_mat4(scene, camob, cammat);
+                       BKE_object_where_is_calc_mat4(depsgraph, scene, camob, cammat);
 
                        BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
 
@@ -4390,7 +4323,7 @@ static void transformcache_evaluate(bConstraint *con, bConstraintOb *cob, ListBa
                return;
        }
 
-       const float frame = BKE_scene_frame_get(scene);
+       const float frame = DEG_get_ctime(cob->depsgraph);
        const float time = BKE_cachefile_time_offset(cache_file, frame, FPS);
 
        BKE_cachefile_ensure_handle(G.main, cache_file);
@@ -4488,7 +4421,7 @@ static void constraints_init_typeinfo(void)
        constraintsTypeInfo[14] = &CTI_DISTLIMIT;        /* Limit Distance Constraint */
        constraintsTypeInfo[15] = &CTI_STRETCHTO;        /* StretchTo Constaint */
        constraintsTypeInfo[16] = &CTI_MINMAX;           /* Floor Constraint */
-       constraintsTypeInfo[17] = &CTI_RIGIDBODYJOINT;   /* RigidBody Constraint */
+       /* constraintsTypeInfo[17] = &CTI_RIGIDBODYJOINT; */  /* RigidBody Constraint - Deprecated */
        constraintsTypeInfo[18] = &CTI_CLAMPTO;          /* ClampTo Constraint */
        constraintsTypeInfo[19] = &CTI_TRANSFORM;        /* Transformation Constraint */
        constraintsTypeInfo[20] = &CTI_SHRINKWRAP;       /* Shrinkwrap Constraint */
@@ -4640,7 +4573,7 @@ static bConstraint *add_new_constraint_internal(const char *name, short type)
 
        /* Set up a generic constraint datablock */
        con->type = type;
-       con->flag |= CONSTRAINT_EXPAND;
+       con->flag |= CONSTRAINT_EXPAND | CONSTRAINT_STATICOVERRIDE_LOCAL;
        con->enforce = 1.0f;
 
        /* Determine a basic name, and info */
@@ -4767,6 +4700,43 @@ static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, bool i
                id_us_plus(*idpoin);
 }
 
+/** Copies a single constraint's data (\a dst must already be a shallow copy of \a src). */
+static void constraint_copy_data_ex(bConstraint *dst, bConstraint *src, const int flag, const bool do_extern)
+{
+       const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(src);
+
+       /* make a new copy of the constraint's data */
+       dst->data = MEM_dupallocN(dst->data);
+
+       /* only do specific constraints if required */
+       if (cti) {
+               /* perform custom copying operations if needed */
+               if (cti->copy_data)
+                       cti->copy_data(dst, src);
+
+               /* Fix usercounts for all referenced data that need it. */
+               if (cti->id_looper && (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+                       cti->id_looper(dst, con_fix_copied_refs_cb, NULL);
+               }
+
+               /* for proxies we don't want to make extern */
+               if (do_extern) {
+                       /* go over used ID-links for this constraint to ensure that they are valid for proxies */
+                       if (cti->id_looper)
+                               cti->id_looper(dst, con_extern_cb, NULL);
+               }
+       }
+}
+
+/** Allocate and duplicate a single constraint, ouside of any object/pose context. */
+bConstraint *BKE_constraint_duplicate_ex(bConstraint *src, const int flag, const bool do_extern)
+{
+       bConstraint *dst = MEM_dupallocN(src);
+       constraint_copy_data_ex(dst, src, flag, do_extern);
+       dst->next = dst->prev = NULL;
+       return dst;
+}
+
 /* duplicate all of the constraints in a constraint stack */
 void BKE_constraints_copy_ex(ListBase *dst, const ListBase *src, const int flag, bool do_extern)
 {
@@ -4776,29 +4746,7 @@ void BKE_constraints_copy_ex(ListBase *dst, const ListBase *src, const int flag,
        BLI_duplicatelist(dst, src);
 
        for (con = dst->first, srccon = src->first; con && srccon; srccon = srccon->next, con = con->next) {
-               const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
-
-               /* make a new copy of the constraint's data */
-               con->data = MEM_dupallocN(con->data);
-
-               /* only do specific constraints if required */
-               if (cti) {
-                       /* perform custom copying operations if needed */
-                       if (cti->copy_data)
-                               cti->copy_data(con, srccon);
-
-                       /* Fix usercounts for all referenced data that need it. */
-                       if (cti->id_looper && (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
-                               cti->id_looper(con, con_fix_copied_refs_cb, NULL);
-                       }
-
-                       /* for proxies we don't want to make extern */
-                       if (do_extern) {
-                               /* go over used ID-links for this constraint to ensure that they are valid for proxies */
-                               if (cti->id_looper)
-                                       cti->id_looper(con, con_extern_cb, NULL);
-                       }
-               }
+               constraint_copy_data_ex(con, srccon, flag, do_extern);
        }
 }
 
@@ -4895,7 +4843,7 @@ bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan)
  * None of the actual calculations of the matrices should be done here! Also, this function is
  * not to be used by any new constraints, particularly any that have multiple targets.
  */
-void BKE_constraint_target_matrix_get(Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
+void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph, Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
 {
        const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
        ListBase targets = {NULL, NULL};
@@ -4907,6 +4855,7 @@ void BKE_constraint_target_matrix_get(Scene *scene, bConstraint *con, int index,
                cob = MEM_callocN(sizeof(bConstraintOb), "tempConstraintOb");
                cob->type = ownertype;
                cob->scene = scene;
+               cob->depsgraph = depsgraph;
                switch (ownertype) {
                        case CONSTRAINT_OBTYPE_OBJECT: /* it is usually this case */
                        {
@@ -4946,7 +4895,7 @@ void BKE_constraint_target_matrix_get(Scene *scene, bConstraint *con, int index,
 
                if (ct) {
                        if (cti->get_target_matrix)
-                               cti->get_target_matrix(con, cob, ct, ctime);
+                               cti->get_target_matrix(depsgraph, con, cob, ct, ctime);
                        copy_m4_m4(mat, ct->matrix);
                }
 
@@ -4962,7 +4911,7 @@ void BKE_constraint_target_matrix_get(Scene *scene, bConstraint *con, int index,
 }
 
 /* Get the list of targets required for solving a constraint */
-void BKE_constraint_targets_for_solving_get(bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
+void BKE_constraint_targets_for_solving_get(struct Depsgraph *depsgraph, bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
 {
        const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
 
@@ -4980,7 +4929,7 @@ void BKE_constraint_targets_for_solving_get(bConstraint *con, bConstraintOb *cob
                 */
                if (cti->get_target_matrix) {
                        for (ct = targets->first; ct; ct = ct->next)
-                               cti->get_target_matrix(con, cob, ct, ctime);
+                               cti->get_target_matrix(depsgraph, con, cob, ct, ctime);
                }
                else {
                        for (ct = targets->first; ct; ct = ct->next)
@@ -4997,7 +4946,7 @@ void BKE_constraint_targets_for_solving_get(bConstraint *con, bConstraintOb *cob
  * BKE_constraints_make_evalob and BKE_constraints_clear_evalob should be called before and
  * after running this function, to sort out cob
  */
-void BKE_constraints_solve(ListBase *conlist, bConstraintOb *cob, float ctime)
+void BKE_constraints_solve(struct Depsgraph *depsgraph, ListBase *conlist, bConstraintOb *cob, float ctime)
 {
        bConstraint *con;
        float oldmat[4][4];
@@ -5032,7 +4981,7 @@ void BKE_constraints_solve(ListBase *conlist, bConstraintOb *cob, float ctime)
                BKE_constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false);
 
                /* prepare targets for constraint solving */
-               BKE_constraint_targets_for_solving_get(con, cob, &targets, ctime);
+               BKE_constraint_targets_for_solving_get(depsgraph, con, cob, &targets, ctime);
 
                /* Solve the constraint and put result in cob->matrix */
                cti->evaluate_constraint(con, cob, &targets);