Commit: 59cfa73b180b4327427f65f7b9b7184e161f7498
Author: Alexander Gavrilov
Date:   Tue Jan 10 18:25:58 2023 +0200
Branches: temp-angavrilov
https://developer.blender.org/rB59cfa73b180b4327427f65f7b9b7184e161f7498

Python API: add a method for reordering modifiers.

Add an `object.modifiers.move()` method, similar to the one
for constraints and some other collections. Currently reordering
modifiers requires using operators, which depend on context.

The implementation is straightforward, except for the need to
make the severity of errors reported by the underlying editor
code into a parameter, so that the new Python API function
reports any problems as Python exceptions. I also turn
the negative index condition from an assert into an error.

Differential Revision: https://developer.blender.org/D16966

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

M       source/blender/editors/include/ED_object.h
M       source/blender/editors/object/object_modifier.cc
M       source/blender/editors/space_outliner/outliner_dragdrop.cc
M       source/blender/makesrna/intern/rna_object.c

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

diff --git a/source/blender/editors/include/ED_object.h 
b/source/blender/editors/include/ED_object.h
index 9e8d9636a29..23d6a4672a2 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -10,6 +10,7 @@
 #include "BLI_compiler_attrs.h"
 #include "DNA_object_enums.h"
 #include "DNA_userdef_enums.h"
+#include "DNA_windowmanager_types.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -534,12 +535,15 @@ bool ED_object_modifier_remove(struct ReportList *reports,
                                struct ModifierData *md);
 void ED_object_modifier_clear(struct Main *bmain, struct Scene *scene, struct 
Object *ob);
 bool ED_object_modifier_move_down(struct ReportList *reports,
+                                  eReportType error_type,
                                   struct Object *ob,
                                   struct ModifierData *md);
 bool ED_object_modifier_move_up(struct ReportList *reports,
+                                eReportType error_type,
                                 struct Object *ob,
                                 struct ModifierData *md);
 bool ED_object_modifier_move_to_index(struct ReportList *reports,
+                                      eReportType error_type,
                                       struct Object *ob,
                                       struct ModifierData *md,
                                       int index);
diff --git a/source/blender/editors/object/object_modifier.cc 
b/source/blender/editors/object/object_modifier.cc
index 57d62b3a95b..1fb8aa05e37 100644
--- a/source/blender/editors/object/object_modifier.cc
+++ b/source/blender/editors/object/object_modifier.cc
@@ -415,7 +415,10 @@ void ED_object_modifier_clear(Main *bmain, Scene *scene, 
Object *ob)
   DEG_relations_tag_update(bmain);
 }
 
-bool ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData 
*md)
+bool ED_object_modifier_move_up(ReportList *reports,
+                                eReportType error_type,
+                                Object *ob,
+                                ModifierData *md)
 {
   if (md->prev) {
     const ModifierTypeInfo *mti = 
BKE_modifier_get_info((ModifierType)md->type);
@@ -424,7 +427,7 @@ bool ED_object_modifier_move_up(ReportList *reports, Object 
*ob, ModifierData *m
       const ModifierTypeInfo *nmti = 
BKE_modifier_get_info((ModifierType)md->prev->type);
 
       if (nmti->flags & eModifierTypeFlag_RequiresOriginalData) {
-        BKE_report(reports, RPT_WARNING, "Cannot move above a modifier 
requiring original data");
+        BKE_report(reports, error_type, "Cannot move above a modifier 
requiring original data");
         return false;
       }
     }
@@ -432,14 +435,17 @@ bool ED_object_modifier_move_up(ReportList *reports, 
Object *ob, ModifierData *m
     BLI_listbase_swaplinks(&ob->modifiers, md, md->prev);
   }
   else {
-    BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the start of 
the list");
+    BKE_report(reports, error_type, "Cannot move modifier beyond the start of 
the list");
     return false;
   }
 
   return true;
 }
 
-bool ED_object_modifier_move_down(ReportList *reports, Object *ob, 
ModifierData *md)
+bool ED_object_modifier_move_down(ReportList *reports,
+                                  eReportType error_type,
+                                  Object *ob,
+                                  ModifierData *md)
 {
   if (md->next) {
     const ModifierTypeInfo *mti = 
BKE_modifier_get_info((ModifierType)md->type);
@@ -448,7 +454,7 @@ bool ED_object_modifier_move_down(ReportList *reports, 
Object *ob, ModifierData
       const ModifierTypeInfo *nmti = 
BKE_modifier_get_info((ModifierType)md->next->type);
 
       if (nmti->type != eModifierTypeType_OnlyDeform) {
-        BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming 
modifier");
+        BKE_report(reports, error_type, "Cannot move beyond a non-deforming 
modifier");
         return false;
       }
     }
@@ -456,22 +462,20 @@ bool ED_object_modifier_move_down(ReportList *reports, 
Object *ob, ModifierData
     BLI_listbase_swaplinks(&ob->modifiers, md, md->next);
   }
   else {
-    BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the end of 
the list");
+    BKE_report(reports, error_type, "Cannot move modifier beyond the end of 
the list");
     return false;
   }
 
   return true;
 }
 
-bool ED_object_modifier_move_to_index(ReportList *reports,
-                                      Object *ob,
-                                      ModifierData *md,
-                                      const int index)
+bool ED_object_modifier_move_to_index(
+    ReportList *reports, eReportType error_type, Object *ob, ModifierData *md, 
const int index)
 {
   BLI_assert(md != nullptr);
-  BLI_assert(index >= 0);
-  if (index >= BLI_listbase_count(&ob->modifiers)) {
-    BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the end of 
the stack");
+
+  if (index < 0 || index >= BLI_listbase_count(&ob->modifiers)) {
+    BKE_report(reports, error_type, "Cannot move modifier beyond the end of 
the stack");
     return false;
   }
 
@@ -480,7 +484,7 @@ bool ED_object_modifier_move_to_index(ReportList *reports,
   if (md_index < index) {
     /* Move modifier down in list. */
     for (; md_index < index; md_index++) {
-      if (!ED_object_modifier_move_down(reports, ob, md)) {
+      if (!ED_object_modifier_move_down(reports, error_type, ob, md)) {
         break;
       }
     }
@@ -488,7 +492,7 @@ bool ED_object_modifier_move_to_index(ReportList *reports,
   else {
     /* Move modifier up in list. */
     for (; md_index > index; md_index--) {
-      if (!ED_object_modifier_move_up(reports, ob, md)) {
+      if (!ED_object_modifier_move_up(reports, error_type, ob, md)) {
         break;
       }
     }
@@ -1518,7 +1522,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator 
*op)
   Object *ob = ED_object_active_context(C);
   ModifierData *md = edit_modifier_property_get(op, ob, 0);
 
-  if (!md || !ED_object_modifier_move_up(op->reports, ob, md)) {
+  if (!md || !ED_object_modifier_move_up(op->reports, RPT_WARNING, ob, md)) {
     return OPERATOR_CANCELLED;
   }
 
@@ -1563,7 +1567,7 @@ static int modifier_move_down_exec(bContext *C, 
wmOperator *op)
   Object *ob = ED_object_active_context(C);
   ModifierData *md = edit_modifier_property_get(op, ob, 0);
 
-  if (!md || !ED_object_modifier_move_down(op->reports, ob, md)) {
+  if (!md || !ED_object_modifier_move_down(op->reports, RPT_WARNING, ob, md)) {
     return OPERATOR_CANCELLED;
   }
 
@@ -1609,7 +1613,7 @@ static int modifier_move_to_index_exec(bContext *C, 
wmOperator *op)
   ModifierData *md = edit_modifier_property_get(op, ob, 0);
   int index = RNA_int_get(op->ptr, "index");
 
-  if (!(md && ED_object_modifier_move_to_index(op->reports, ob, md, index))) {
+  if (!(md && ED_object_modifier_move_to_index(op->reports, RPT_WARNING, ob, 
md, index))) {
     return OPERATOR_CANCELLED;
   }
 
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.cc 
b/source/blender/editors/space_outliner/outliner_dragdrop.cc
index 3b07c6da5fa..c1f31c80cb8 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.cc
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.cc
@@ -1027,8 +1027,11 @@ static void datastack_drop_reorder(bContext *C, 
ReportList *reports, StackDropDa
       }
       else {
         index = outliner_get_insert_index(drag_te, drop_te, insert_type, 
&ob->modifiers);
-        ED_object_modifier_move_to_index(
-            reports, ob, static_cast<ModifierData 
*>(drop_data->drag_directdata), index);
+        ED_object_modifier_move_to_index(reports,
+                                         RPT_WARNING,
+                                         ob,
+                                         static_cast<ModifierData 
*>(drop_data->drag_directdata),
+                                         index);
       }
       break;
     case TSE_CONSTRAINT:
diff --git a/source/blender/makesrna/intern/rna_object.c 
b/source/blender/makesrna/intern/rna_object.c
index 17d2310b262..e03b2cad2cb 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1759,6 +1759,23 @@ static void rna_Object_modifier_clear(Object *object, 
bContext *C)
   WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object);
 }
 
+static void rna_Object_modifier_move(
+    Object *object, Main *bmain, ReportList *reports, int from, int to)
+{
+  if (from == to) {
+    return;
+  }
+
+  ModifierData *md = BLI_findlink(&object->modifiers, from);
+
+  if (!md) {
+    BKE_reportf(reports, RPT_ERROR, "Invalid original modifier index '%d'", 
from);
+    return;
+  }
+
+  ED_object_modifier_move_to_index(reports, RPT_ERROR, object, md, to);
+}
+
 static PointerRNA rna_Object_active_modifier_get(PointerRNA *ptr)
 {
   Object *ob = (Object *)ptr->owner_id;
@@ -2635,6 +2652,16 @@ static void rna_def_object_modifiers(BlenderRNA *brna, 
PropertyRNA *cprop)
   RNA_def_function_flag(func, FUNC_USE_CONTEXT);
   RNA_def_function_ui_description(func, "Remove all modifiers from the 
object");
 
+  /* move a modifier */
+  func = RNA_def_function(srna, "move", "rna_Object_modifier_move");
+  RNA_def_function_ui_description(func, "Move a modifier 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);
+
   /* Active modifier. */
   prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
   RNA_def_property_struct_type(prop, "Modifier");

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to