diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2020-06-24 22:10:43 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2020-06-25 12:10:18 +0300 |
commit | 64a584b38a73d4745e02620051592c5b05439647 (patch) | |
tree | 9d60be41bd088dc9ec9313305722bee184cdb9b4 /source/blender | |
parent | 6b53e0adbc5fee508da580bdb8feb596e36751bc (diff) |
Python API: add methods to allow copying of constraints.
Blender has an operator to do Copy & Paste of constraints between
objects and bones, but no simple method to do that directly via
the Python API is provided. This adds a copy() method to object
and pose bone constraint collections.
Differential Revision: https://developer.blender.org/D8112
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_constraint.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 45 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 26 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_pose.c | 30 |
4 files changed, 97 insertions, 9 deletions
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index 8fe3bd77a26..8d7fe875c37 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -145,6 +145,11 @@ struct bConstraint *BKE_constraint_duplicate_ex(struct bConstraint *src, const int flag, const bool do_extern); +struct bConstraint *BKE_constraint_copy_for_pose(struct Object *ob, + struct bPoseChannel *pchan, + struct bConstraint *src); +struct bConstraint *BKE_constraint_copy_for_object(struct Object *ob, struct bConstraint *src); + void BKE_constraints_free(struct ListBase *list); void BKE_constraints_free_ex(struct ListBase *list, bool do_id_user); void BKE_constraints_copy(struct ListBase *dst, const struct ListBase *src, bool do_extern); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index c5b70cf6924..74e3cc567ec 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -5448,18 +5448,11 @@ static bConstraint *add_new_constraint_internal(const char *name, short type) return con; } -/* if pchan is not NULL then assume we're adding a pose constraint */ -static bConstraint *add_new_constraint(Object *ob, - bPoseChannel *pchan, - const char *name, - short type) +/* Add a newly created constraint to the constraint list. */ +static void add_new_constraint_to_list(Object *ob, bPoseChannel *pchan, bConstraint *con) { - bConstraint *con; ListBase *list; - /* add the constraint */ - con = add_new_constraint_internal(name, type); - /* find the constraint stack - bone or object? */ list = (pchan) ? (&pchan->constraints) : (&ob->constraints); @@ -5481,6 +5474,20 @@ static bConstraint *add_new_constraint(Object *ob, /* make this constraint the active one */ BKE_constraints_active_set(list, con); } +} + +/* if pchan is not NULL then assume we're adding a pose constraint */ +static bConstraint *add_new_constraint(Object *ob, + bPoseChannel *pchan, + const char *name, + short type) +{ + bConstraint *con; + + /* add the constraint */ + con = add_new_constraint_internal(name, type); + + add_new_constraint_to_list(ob, pchan, con); /* set type+owner specific immutable settings */ /* TODO: does action constraint need anything here - i.e. spaceonce? */ @@ -5614,6 +5621,26 @@ bConstraint *BKE_constraint_duplicate_ex(bConstraint *src, const int flag, const return dst; } +/* Add a copy of the given constraint for the given bone */ +bConstraint *BKE_constraint_copy_for_pose(Object *ob, bPoseChannel *pchan, bConstraint *src) +{ + if (pchan == NULL) { + return NULL; + } + + bConstraint *new_con = BKE_constraint_duplicate_ex(src, 0, !ID_IS_LINKED(ob)); + add_new_constraint_to_list(ob, pchan, new_con); + return new_con; +} + +/* Add a copy of the given constraint for the given object */ +bConstraint *BKE_constraint_copy_for_object(Object *ob, bConstraint *src) +{ + bConstraint *new_con = BKE_constraint_duplicate_ex(src, 0, !ID_IS_LINKED(ob)); + add_new_constraint_to_list(ob, NULL, new_con); + return new_con; +} + /* 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) { diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 1f111474aa3..baa5b50104b 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1497,6 +1497,17 @@ static void rna_Object_constraints_move( WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT, object); } +static bConstraint *rna_Object_constraints_copy(Object *object, Main *bmain, PointerRNA *con_ptr) +{ + bConstraint *con = con_ptr->data; + bConstraint *new_con = BKE_constraint_copy_for_object(object, con); + + ED_object_constraint_tag_update(bmain, object, new_con); + WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_ADDED, object); + + return new_con; +} + bool rna_Object_constraints_override_apply(Main *UNUSED(bmain), PointerRNA *ptr_dst, PointerRNA *ptr_src, @@ -2217,6 +2228,21 @@ static void rna_def_object_constraints(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_int(func, "to_index", -1, INT_MIN, INT_MAX, "To Index", "Target index", 0, 10000); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + + func = RNA_def_function(srna, "copy", "rna_Object_constraints_copy"); + RNA_def_function_ui_description(func, "Add a new constraint that is a copy of the given one"); + RNA_def_function_flag(func, FUNC_USE_MAIN); + /* constraint to copy */ + parm = RNA_def_pointer(func, + "constraint", + "Constraint", + "", + "Constraint to copy - may belong to a different object"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); + /* return type */ + parm = RNA_def_pointer(func, "new_constraint", "Constraint", "", "New constraint"); + RNA_def_function_return(func, parm); } /* object.modifiers */ diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 8f28fc56712..8dd3670087a 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -637,6 +637,21 @@ static void rna_PoseChannel_constraints_move( WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT, ob); } +static bConstraint *rna_PoseChannel_constraints_copy(ID *id, + bPoseChannel *pchan, + Main *bmain, + PointerRNA *con_ptr) +{ + Object *ob = (Object *)id; + bConstraint *con = con_ptr->data; + bConstraint *new_con = BKE_constraint_copy_for_pose(ob, pchan, con); + + ED_object_constraint_dependency_tag_update(bmain, ob, new_con); + WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_ADDED, id); + + return new_con; +} + bool rna_PoseChannel_constraints_override_apply(Main *UNUSED(bmain), PointerRNA *ptr_dst, PointerRNA *ptr_src, @@ -978,6 +993,21 @@ static void rna_def_pose_channel_constraints(BlenderRNA *brna, PropertyRNA *cpro RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_int(func, "to_index", -1, INT_MIN, INT_MAX, "To Index", "Target index", 0, 10000); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + + func = RNA_def_function(srna, "copy", "rna_PoseChannel_constraints_copy"); + RNA_def_function_ui_description(func, "Add a new constraint that is a copy of the given one"); + RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_SELF_ID); + /* constraint to copy */ + parm = RNA_def_pointer(func, + "constraint", + "Constraint", + "", + "Constraint to copy - may belong to a different object"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); + /* return type */ + parm = RNA_def_pointer(func, "new_constraint", "Constraint", "", "New constraint"); + RNA_def_function_return(func, parm); } static void rna_def_pose_channel(BlenderRNA *brna) |