[Bf-blender-cvs] [64a584b38a7] master: Python API: add methods to allow copying of constraints.

Alexander Gavrilov noreply at git.blender.org
Thu Jun 25 12:02:50 CEST 2020


Commit: 64a584b38a73d4745e02620051592c5b05439647
Author: Alexander Gavrilov
Date:   Wed Jun 24 22:10:43 2020 +0300
Branches: master
https://developer.blender.org/rB64a584b38a73d4745e02620051592c5b05439647

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

===================================================================

M	source/blender/blenkernel/BKE_constraint.h
M	source/blender/blenkernel/intern/constraint.c
M	source/blender/makesrna/intern/rna_object.c
M	source/blender/makesrna/intern/rna_pose.c

===================================================================

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)



More information about the Bf-blender-cvs mailing list