Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/constraint.c146
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h4
2 files changed, 68 insertions, 82 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 6ffb3299869..aa09541c043 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -949,30 +949,9 @@ static void default_get_tarmat_full_bbone(struct Depsgraph *UNUSED(depsgraph),
} \
(void)0
-static void custom_space_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
+static bool is_custom_space_needed(bConstraint *con)
{
- func(con, (ID **)&con->space_object, false, userdata);
-}
-
-static int get_space_tar(bConstraint *con, ListBase *list)
-{
- if (!con || !list ||
- (con->ownspace != CONSTRAINT_SPACE_CUSTOM && con->tarspace != CONSTRAINT_SPACE_CUSTOM)) {
- return 0;
- }
- bConstraintTarget *ct;
- SINGLETARGET_GET_TARS(con, con->space_object, con->space_subtarget, ct, list);
- return 1;
-}
-
-static void flush_space_tar(bConstraint *con, ListBase *list, bool no_copy)
-{
- if (!con || !list ||
- (con->ownspace != CONSTRAINT_SPACE_CUSTOM && con->tarspace != CONSTRAINT_SPACE_CUSTOM)) {
- return;
- }
- bConstraintTarget *ct = (bConstraintTarget *)list->last;
- SINGLETARGET_FLUSH_TARS(con, con->space_object, con->space_subtarget, ct, list, no_copy);
+ return con->ownspace == CONSTRAINT_SPACE_CUSTOM || con->tarspace == CONSTRAINT_SPACE_CUSTOM;
}
/* --------- ChildOf Constraint ------------ */
@@ -1161,8 +1140,6 @@ static void trackto_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int trackto_get_tars(bConstraint *con, ListBase *list)
@@ -1174,7 +1151,7 @@ static int trackto_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -1188,7 +1165,6 @@ static void trackto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -1661,11 +1637,11 @@ static bConstraintTypeInfo CTI_LOCLIMIT = {
"Limit Location", /* name */
"bLocLimitConstraint", /* struct name */
NULL, /* free data */
- custom_space_id_looper, /* id looper */
+ NULL, /* id looper */
NULL, /* copy data */
NULL, /* new data */
- get_space_tar, /* get constraint targets */
- flush_space_tar, /* flush constraint targets */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
NULL, /* get target matrix */
loclimit_evaluate, /* evaluate */
};
@@ -1742,11 +1718,11 @@ static bConstraintTypeInfo CTI_ROTLIMIT = {
"Limit Rotation", /* name */
"bRotLimitConstraint", /* struct name */
NULL, /* free data */
- custom_space_id_looper, /* id looper */
+ NULL, /* id looper */
NULL, /* copy data */
NULL, /* new data */
- get_space_tar, /* get constraint targets */
- flush_space_tar, /* flush constraint targets */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
NULL, /* get target matrix */
rotlimit_evaluate, /* evaluate */
};
@@ -1809,11 +1785,11 @@ static bConstraintTypeInfo CTI_SIZELIMIT = {
"Limit Scale", /* name */
"bSizeLimitConstraint", /* struct name */
NULL, /* free data */
- custom_space_id_looper, /* id looper */
+ NULL, /* id looper */
NULL, /* copy data */
NULL, /* new data */
- get_space_tar, /* get constraint targets */
- flush_space_tar, /* flush constraint targets */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
NULL, /* get target matrix */
sizelimit_evaluate, /* evaluate */
};
@@ -1833,8 +1809,6 @@ static void loclike_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int loclike_get_tars(bConstraint *con, ListBase *list)
@@ -1846,7 +1820,7 @@ static int loclike_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -1860,7 +1834,6 @@ static void loclike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -1933,8 +1906,6 @@ static void rotlike_id_looper(bConstraint *con, ConstraintIDFunc func, void *use
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int rotlike_get_tars(bConstraint *con, ListBase *list)
@@ -1946,7 +1917,7 @@ static int rotlike_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -1960,7 +1931,6 @@ static void rotlike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -2114,8 +2084,6 @@ static void sizelike_id_looper(bConstraint *con, ConstraintIDFunc func, void *us
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int sizelike_get_tars(bConstraint *con, ListBase *list)
@@ -2127,7 +2095,7 @@ static int sizelike_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -2141,7 +2109,6 @@ static void sizelike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -2239,8 +2206,6 @@ static void translike_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int translike_get_tars(bConstraint *con, ListBase *list)
@@ -2252,7 +2217,7 @@ static int translike_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -2266,7 +2231,6 @@ static void translike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -2400,11 +2364,11 @@ static bConstraintTypeInfo CTI_SAMEVOL = {
"Maintain Volume", /* name */
"bSameVolumeConstraint", /* struct name */
NULL, /* free data */
- custom_space_id_looper, /* id looper */
+ NULL, /* id looper */
NULL, /* copy data */
samevolume_new_data, /* new data */
- get_space_tar, /* get constraint targets */
- flush_space_tar, /* flush constraint targets */
+ NULL, /* get constraint targets */
+ NULL, /* flush constraint targets */
NULL, /* get target matrix */
samevolume_evaluate, /* evaluate */
};
@@ -2810,8 +2774,6 @@ static void actcon_id_looper(bConstraint *con, ConstraintIDFunc func, void *user
/* action */
func(con, (ID **)&data->act, true, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int actcon_get_tars(bConstraint *con, ListBase *list)
@@ -2823,7 +2785,7 @@ static int actcon_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -2837,7 +2799,6 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -3338,8 +3299,6 @@ static void distlimit_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int distlimit_get_tars(bConstraint *con, ListBase *list)
@@ -3351,7 +3310,7 @@ static int distlimit_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -3365,7 +3324,6 @@ static void distlimit_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -3694,8 +3652,6 @@ static void minmax_id_looper(bConstraint *con, ConstraintIDFunc func, void *user
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int minmax_get_tars(bConstraint *con, ListBase *list)
@@ -3707,7 +3663,7 @@ static int minmax_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -3721,7 +3677,6 @@ static void minmax_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -4019,8 +3974,6 @@ static void transform_id_looper(bConstraint *con, ConstraintIDFunc func, void *u
/* target only */
func(con, (ID **)&data->tar, false, userdata);
-
- custom_space_id_looper(con, func, userdata);
}
static int transform_get_tars(bConstraint *con, ListBase *list)
@@ -4032,7 +3985,7 @@ static int transform_get_tars(bConstraint *con, ListBase *list)
/* standard target-getting macro for single-target constraints */
SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
- return 1 + get_space_tar(con, list);
+ return 1;
}
return 0;
@@ -4046,7 +3999,6 @@ static void transform_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
/* the following macro is used for all standard single-target constraints */
SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
- flush_space_tar(con, list, no_copy);
}
}
@@ -5582,6 +5534,19 @@ static void con_unlink_refs_cb(bConstraint *UNUSED(con),
}
}
+/** Helper function to invoke the id_looper callback, including custom space. */
+static void con_invoke_id_looper(const bConstraintTypeInfo *cti,
+ bConstraint *con,
+ ConstraintIDFunc func,
+ void *userdata)
+{
+ if (cti->id_looper) {
+ cti->id_looper(con, func, userdata);
+ }
+
+ func(con, (ID **)&con->space_object, false, userdata);
+}
+
void BKE_constraint_free_data_ex(bConstraint *con, bool do_id_user)
{
if (con->data) {
@@ -5594,8 +5559,8 @@ void BKE_constraint_free_data_ex(bConstraint *con, bool do_id_user)
}
/* unlink the referenced resources it uses */
- if (do_id_user && cti->id_looper) {
- cti->id_looper(con, con_unlink_refs_cb, NULL);
+ if (do_id_user) {
+ con_invoke_id_looper(cti, con, con_unlink_refs_cb, NULL);
}
}
@@ -5913,9 +5878,7 @@ void BKE_constraints_id_loop(ListBase *conlist, ConstraintIDFunc func, void *use
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
if (cti) {
- if (cti->id_looper) {
- cti->id_looper(con, func, userdata);
- }
+ con_invoke_id_looper(cti, con, func, userdata);
}
}
}
@@ -5967,16 +5930,14 @@ static void constraint_copy_data_ex(bConstraint *dst,
}
/* 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);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ con_invoke_id_looper(cti, 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);
- }
+ con_invoke_id_looper(cti, dst, con_extern_cb, NULL);
}
}
}
@@ -6208,6 +6169,15 @@ int BKE_constraint_targets_get(struct bConstraint *con, struct ListBase *r_targe
count = cti->get_constraint_targets(con, r_targets);
}
+ /* Add the custom target. */
+ if (is_custom_space_needed(con)) {
+ bConstraintTarget *ct;
+ SINGLETARGET_GET_TARS(con, con->space_object, con->space_subtarget, ct, r_targets);
+ ct->space = CONSTRAINT_SPACE_WORLD;
+ ct->flag |= CONSTRAINT_TAR_CUSTOM_SPACE;
+ count++;
+ }
+
return count;
}
@@ -6219,6 +6189,20 @@ void BKE_constraint_targets_flush(struct bConstraint *con, struct ListBase *targ
return;
}
+ /* Remove the custom target. */
+ bConstraintTarget *ct = (bConstraintTarget *)targets->last;
+
+ if (ct && (ct->flag & CONSTRAINT_TAR_CUSTOM_SPACE)) {
+ BLI_assert(is_custom_space_needed(con));
+
+ if (!no_copy) {
+ con->space_object = ct->tar;
+ BLI_strncpy(con->space_subtarget, ct->subtarget, sizeof(con->space_subtarget));
+ }
+
+ BLI_freelinkN(targets, ct);
+ }
+
/* Release the constraint-specific targets. */
if (cti->flush_constraint_targets) {
cti->flush_constraint_targets(con, targets, no_copy);
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index ad046cbe79a..8e0ce68f71a 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -105,8 +105,10 @@ typedef struct bConstraintTarget {
/* bConstraintTarget -> flag */
typedef enum eConstraintTargetFlag {
- /** temporary target-struct that needs to be freed after use */
+ /** Temporary target-struct that needs to be freed after use. */
CONSTRAINT_TAR_TEMP = (1 << 0),
+ /** Temporary target for the custom space reference. */
+ CONSTRAINT_TAR_CUSTOM_SPACE = (1 << 1),
} eConstraintTargetFlag;
/* bConstraintTarget/bConstraintOb -> type */