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
This commit is contained in:
parent
6b53e0adbc
commit
64a584b38a
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue