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/BKE_constraint.h2
-rw-r--r--source/blender/blenkernel/intern/constraint.c78
-rw-r--r--source/blender/blenloader/intern/readfile.c15
-rw-r--r--source/blender/makesrna/intern/rna_animation.c2
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c4
-rw-r--r--source/blender/makesrna/intern/rna_nla.c2
6 files changed, 62 insertions, 41 deletions
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index f834ad5e774..b12ab538184 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -62,7 +62,7 @@ typedef struct bConstraintOb {
/* ---------------------------------------------------------------------------- */
/* Callback format for performing operations on ID-pointers for Constraints */
-typedef void (*ConstraintIDFunc)(struct bConstraint *con, struct ID **idpoin, void *userdata);
+typedef void (*ConstraintIDFunc)(struct bConstraint *con, struct ID **idpoin, short isReference, void *userdata);
/* ....... */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 399aedc914f..a244fa96fda 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -781,7 +781,7 @@ static void childof_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
bChildOfConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int childof_get_tars (bConstraint *con, ListBase *list)
@@ -917,7 +917,7 @@ static void trackto_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
bTrackToConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int trackto_get_tars (bConstraint *con, ListBase *list)
@@ -1098,10 +1098,10 @@ static void kinematic_id_looper (bConstraint *con, ConstraintIDFunc func, void *
bKinematicConstraint *data= con->data;
/* chain target */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
/* poletarget */
- func(con, (ID**)&data->poletar, userdata);
+ func(con, (ID**)&data->poletar, FALSE, userdata);
}
static int kinematic_get_tars (bConstraint *con, ListBase *list)
@@ -1191,7 +1191,7 @@ static void followpath_id_looper (bConstraint *con, ConstraintIDFunc func, void
bFollowPathConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int followpath_get_tars (bConstraint *con, ListBase *list)
@@ -1541,7 +1541,7 @@ static void loclike_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
bLocateLikeConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int loclike_get_tars (bConstraint *con, ListBase *list)
@@ -1632,7 +1632,7 @@ static void rotlike_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
bChildOfConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int rotlike_get_tars (bConstraint *con, ListBase *list)
@@ -1745,7 +1745,7 @@ static void sizelike_id_looper (bConstraint *con, ConstraintIDFunc func, void *u
bSizeLikeConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int sizelike_get_tars (bConstraint *con, ListBase *list)
@@ -1835,7 +1835,7 @@ static void translike_id_looper (bConstraint *con, ConstraintIDFunc func, void *
bTransLikeConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int translike_get_tars (bConstraint *con, ListBase *list)
@@ -2007,10 +2007,10 @@ static void pycon_id_looper (bConstraint *con, ConstraintIDFunc func, void *user
/* targets */
for (ct= data->targets.first; ct; ct= ct->next)
- func(con, (ID**)&ct->tar, userdata);
+ func(con, (ID**)&ct->tar, FALSE, userdata);
/* script */
- func(con, (ID**)&data->text, userdata);
+ func(con, (ID**)&data->text, TRUE, userdata);
}
/* Whether this approach is maintained remains to be seen (aligorith) */
@@ -2107,10 +2107,10 @@ static void actcon_id_looper (bConstraint *con, ConstraintIDFunc func, void *use
bActionConstraint *data= con->data;
/* target */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
/* action */
- func(con, (ID**)&data->act, userdata);
+ func(con, (ID**)&data->act, TRUE, userdata);
}
static int actcon_get_tars (bConstraint *con, ListBase *list)
@@ -2273,7 +2273,7 @@ static void locktrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *
bLockTrackConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int locktrack_get_tars (bConstraint *con, ListBase *list)
@@ -2584,7 +2584,7 @@ static void distlimit_id_looper (bConstraint *con, ConstraintIDFunc func, void *
bDistLimitConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int distlimit_get_tars (bConstraint *con, ListBase *list)
@@ -2712,7 +2712,7 @@ static void stretchto_id_looper (bConstraint *con, ConstraintIDFunc func, void *
bStretchToConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int stretchto_get_tars (bConstraint *con, ListBase *list)
@@ -2887,7 +2887,7 @@ static void minmax_id_looper (bConstraint *con, ConstraintIDFunc func, void *use
bMinMaxConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int minmax_get_tars (bConstraint *con, ListBase *list)
@@ -3030,8 +3030,8 @@ static void rbj_id_looper (bConstraint *con, ConstraintIDFunc func, void *userda
bRigidBodyJointConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
- func(con, (ID**)&data->child, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
+ func(con, (ID**)&data->child, FALSE, userdata);
}
static int rbj_get_tars (bConstraint *con, ListBase *list)
@@ -3083,7 +3083,7 @@ static void clampto_id_looper (bConstraint *con, ConstraintIDFunc func, void *us
bClampToConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int clampto_get_tars (bConstraint *con, ListBase *list)
@@ -3268,7 +3268,7 @@ static void transform_id_looper (bConstraint *con, ConstraintIDFunc func, void *
bTransformConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int transform_get_tars (bConstraint *con, ListBase *list)
@@ -3403,10 +3403,10 @@ static bConstraintTypeInfo CTI_TRANSFORM = {
static void shrinkwrap_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata)
{
- bShrinkwrapConstraint *data= con->data;
+ bShrinkwrapConstraint *data = con->data;
/* target only */
- func(con, (ID**)&data->target, userdata);
+ func(con, (ID**)&data->target, FALSE, userdata);
}
static int shrinkwrap_get_tars (bConstraint *con, ListBase *list)
@@ -3571,7 +3571,7 @@ static void damptrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *
bDampTrackConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int damptrack_get_tars (bConstraint *con, ListBase *list)
@@ -3717,7 +3717,7 @@ static void splineik_id_looper (bConstraint *con, ConstraintIDFunc func, void *u
bSplineIKConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int splineik_get_tars (bConstraint *con, ListBase *list)
@@ -3790,7 +3790,7 @@ static void pivotcon_id_looper (bConstraint *con, ConstraintIDFunc func, void *u
bPivotConstraint *data= con->data;
/* target only */
- func(con, (ID**)&data->tar, userdata);
+ func(con, (ID**)&data->tar, FALSE, userdata);
}
static int pivotcon_get_tars (bConstraint *con, ListBase *list)
@@ -3922,9 +3922,9 @@ static void followtrack_id_looper(bConstraint *con, ConstraintIDFunc func, void
{
bFollowTrackConstraint *data = con->data;
- func(con, (ID**)&data->clip, userdata);
- func(con, (ID**)&data->camera, userdata);
- func(con, (ID**)&data->depth_ob, userdata);
+ func(con, (ID**)&data->clip, TRUE, userdata);
+ func(con, (ID**)&data->camera, FALSE, userdata);
+ func(con, (ID**)&data->depth_ob, FALSE, userdata);
}
static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -4116,7 +4116,7 @@ static void camerasolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
{
bCameraSolverConstraint *data = con->data;
- func(con, (ID**)&data->clip, userdata);
+ func(con, (ID**)&data->clip, TRUE, userdata);
}
static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -4172,8 +4172,8 @@ static void objectsolver_id_looper(bConstraint *con, ConstraintIDFunc func, void
{
bObjectSolverConstraint *data= con->data;
- func(con, (ID**)&data->clip, userdata);
- func(con, (ID**)&data->camera, userdata);
+ func(con, (ID**)&data->clip, FALSE, userdata);
+ func(con, (ID**)&data->camera, FALSE, userdata);
}
static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -4535,12 +4535,20 @@ void id_loop_constraints(ListBase *conlist, ConstraintIDFunc func, void *userdat
/* ......... */
/* helper for copy_constraints(), to be used for making sure that ID's are valid */
-static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, void *UNUSED(userData))
+static void con_extern_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *UNUSED(userData))
{
if (*idpoin && (*idpoin)->lib)
id_lib_extern(*idpoin);
}
+/* helper for copy_constraints(), to be used for making sure that usercounts of copied ID's are fixed up */
+static void con_fix_copied_refs_cb(bConstraint *con, ID **idpoin, short isReference, void *UNUSED(userData))
+{
+ /* increment usercount if this is a reference type */
+ if ((*idpoin) && (isReference))
+ id_us_plus(*idpoin);
+}
+
/* duplicate all of the constraints in a constraint stack */
void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
{
@@ -4560,6 +4568,10 @@ void copy_constraints(ListBase *dst, const ListBase *src, int do_extern)
/* perform custom copying operations if needed */
if (cti->copy_data)
cti->copy_data(con, srccon);
+
+ /* fix usercounts for all referenced data in referenced data */
+ if (cti->id_looper)
+ cti->id_looper(con, con_fix_copied_refs_cb, NULL);
/* for proxies we don't want to make extern */
if (do_extern) {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 231c1ab8d03..ec7d58035b4 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2473,10 +2473,19 @@ typedef struct tConstraintLinkData {
ID *id;
} tConstraintLinkData;
/* callback function used to relink constraint ID-links */
-static void lib_link_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, void *userdata)
+static void lib_link_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, short isReference, void *userdata)
{
tConstraintLinkData *cld= (tConstraintLinkData *)userdata;
- *idpoin = newlibadr(cld->fd, cld->id->lib, *idpoin);
+
+ /* for reference types, we need to increment the usercounts on load... */
+ if (isReference) {
+ /* reference type - with usercount */
+ *idpoin = newlibadr_us(cld->fd, cld->id->lib, *idpoin);
+ }
+ else {
+ /* target type - no usercount needed */
+ *idpoin = newlibadr(cld->fd, cld->id->lib, *idpoin);
+ }
}
static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
@@ -8115,7 +8124,7 @@ typedef struct tConstraintExpandData {
Main *mainvar;
} tConstraintExpandData;
/* callback function used to expand constraint ID-links */
-static void expand_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, void *userdata)
+static void expand_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED(isReference), void *userdata)
{
tConstraintExpandData *ced= (tConstraintExpandData *)userdata;
expand_doit(ced->fd, ced->mainvar, *idpoin);
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 94ea79099c2..06352fd727c 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -837,7 +837,7 @@ void rna_def_animdata(BlenderRNA *brna)
/* Active Action */
prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
/* this flag as well as the dynamic test must be defined for this to be editable... */
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_REFCOUNT);
RNA_def_property_pointer_funcs(prop, NULL, "rna_AnimData_action_set", NULL, "rna_Action_id_poll");
RNA_def_property_editable_func(prop, "rna_AnimData_action_editable");
RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock");
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index e321e83dd61..b812c574a01 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -562,7 +562,7 @@ static void rna_def_constraint_python(BlenderRNA *brna)
prop = RNA_def_property(srna, "text", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Script", "The text object that contains the Python script");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_REFCOUNT);
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
prop = RNA_def_property(srna, "use_targets", PROP_BOOLEAN, PROP_NONE);
@@ -1097,7 +1097,7 @@ static void rna_def_constraint_action(BlenderRNA *brna)
prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "act");
RNA_def_property_ui_text(prop, "Action", "The constraining action");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_REFCOUNT);
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 8d262c58f9b..7ad13b8a6d1 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -459,7 +459,7 @@ static void rna_def_nlastrip(BlenderRNA *brna)
prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "act");
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Action_id_poll");
- RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_REFCOUNT);
RNA_def_property_editable_func(prop, "rna_NlaStrip_action_editable");
RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip");
RNA_def_property_update(prop, NC_ANIMATION|ND_NLA, NULL); /* this will do? */