Python API: add methods for reordering constraints.
authorAlexander Gavrilov <angavrilov@gmail.com>
Wed, 4 Sep 2019 19:09:57 +0000 (22:09 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Wed, 4 Sep 2019 19:38:33 +0000 (22:38 +0300)
Order matters for constraints, but there was no way to change it.
The API follows other collections like idprops and node sockets.

source/blender/blenlib/BLI_listbase.h
source/blender/blenlib/intern/listbase.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_pose.c

index b8b62dd3451d8bd8910fb611be687056d72b256a..b027acb88da57249cbd81d29a5d12fabc64f5653 100644 (file)
@@ -93,6 +93,7 @@ void BLI_listbase_sort_r(ListBase *listbase,
                          int (*cmp)(void *, const void *, const void *),
                          void *thunk) ATTR_NONNULL(1, 2);
 bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL();
+bool BLI_listbase_move_index(ListBase *listbase, int from, int to) ATTR_NONNULL();
 void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1);
 int BLI_listbase_count_at_most(const struct ListBase *listbase,
                                const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
index 31d372945c64c1397d773c261c980215c806fdf3..631978f60fef19394e05ea78228ddd498fd34ca9 100644 (file)
@@ -503,6 +503,27 @@ bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step)
   return true;
 }
 
+/**
+ * Move the link at the index \a from to the position at index \a to.
+ *
+ * @return If the move was successful.
+ */
+bool BLI_listbase_move_index(ListBase *listbase, int from, int to)
+{
+  if (from == to) {
+    return false;
+  }
+
+  /* Find the link to move. */
+  void *link = BLI_findlink(listbase, from);
+
+  if (!link) {
+    return false;
+  }
+
+  return BLI_listbase_link_move(listbase, link, to - from);
+}
+
 /**
  * Removes and disposes of the entire contents of listbase using direct free(3).
  */
index c8a0d543b7078d4d492078884f59624f4c1f154b..6dd75100e71f4dd63cef396344da9094f6b6b4bb 100644 (file)
@@ -1410,6 +1410,22 @@ static void rna_Object_constraints_clear(Object *object, Main *bmain)
   WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, object);
 }
 
+static void rna_Object_constraints_move(
+    Object *object, Main *bmain, ReportList *reports, int from, int to)
+{
+  if (from == to) {
+    return;
+  }
+
+  if (!BLI_listbase_move_index(&object->constraints, from, to)) {
+    BKE_reportf(reports, RPT_ERROR, "Could not move constraint from index '%d' to '%d'", from, to);
+    return;
+  }
+
+  ED_object_constraint_tag_update(bmain, object, NULL);
+  WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT, object);
+}
+
 bool rna_Object_constraints_override_apply(Main *UNUSED(bmain),
                                            PointerRNA *ptr_dst,
                                            PointerRNA *ptr_src,
@@ -2041,6 +2057,15 @@ static void rna_def_object_constraints(BlenderRNA *brna, PropertyRNA *cprop)
   func = RNA_def_function(srna, "clear", "rna_Object_constraints_clear");
   RNA_def_function_flag(func, FUNC_USE_MAIN);
   RNA_def_function_ui_description(func, "Remove all constraint from this object");
+
+  func = RNA_def_function(srna, "move", "rna_Object_constraints_move");
+  RNA_def_function_ui_description(func, "Move a constraint to a different position");
+  RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
+  parm = RNA_def_int(
+      func, "from_index", -1, INT_MIN, INT_MAX, "From Index", "Index to move", 0, 10000);
+  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);
 }
 
 /* object.modifiers */
index 33d7d7d99cfc10ac41bf7d311ad53cf5af4400ae..2f460e79ec9bd96d6ea2c46c6aa884f128db9dd8 100644 (file)
@@ -601,6 +601,24 @@ static void rna_PoseChannel_constraints_remove(
   }
 }
 
+static void rna_PoseChannel_constraints_move(
+    ID *id, bPoseChannel *pchan, Main *bmain, ReportList *reports, int from, int to)
+{
+  Object *ob = (Object *)id;
+
+  if (from == to) {
+    return;
+  }
+
+  if (!BLI_listbase_move_index(&pchan->constraints, from, to)) {
+    BKE_reportf(reports, RPT_ERROR, "Could not move constraint from index '%d' to '%d'", from, to);
+    return;
+  }
+
+  ED_object_constraint_tag_update(bmain, ob, NULL);
+  WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT, ob);
+}
+
 bool rna_PoseChannel_constraints_override_apply(Main *UNUSED(bmain),
                                                 PointerRNA *ptr_dst,
                                                 PointerRNA *ptr_src,
@@ -929,6 +947,15 @@ static void rna_def_pose_channel_constraints(BlenderRNA *brna, PropertyRNA *cpro
   parm = RNA_def_pointer(func, "constraint", "Constraint", "", "Removed constraint");
   RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
   RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
+
+  func = RNA_def_function(srna, "move", "rna_PoseChannel_constraints_move");
+  RNA_def_function_ui_description(func, "Move a constraint to a different position");
+  RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_REPORTS);
+  parm = RNA_def_int(
+      func, "from_index", -1, INT_MIN, INT_MAX, "From Index", "Index to move", 0, 10000);
+  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);
 }
 
 static void rna_def_pose_channel(BlenderRNA *brna)