diff --git a/source/blender/editors/curves/intern/curves_edit.cc b/source/blender/editors/curves/intern/curves_edit.cc index b7fc59004eb..8ff00a5f20b 100644 --- a/source/blender/editors/curves/intern/curves_edit.cc +++ b/source/blender/editors/curves/intern/curves_edit.cc @@ -12,6 +12,8 @@ #include "BKE_curves.hh" #include "BKE_curves_utils.hh" +#include "GEO_reorder.hh" + #include "ED_curves.hh" namespace blender::ed::curves { @@ -319,4 +321,9 @@ void resize_curves(bke::CurvesGeometry &curves, curves.tag_topology_changed(); } +void reorder_curves(bke::CurvesGeometry &curves, const Span old_by_new_indices_map) +{ + curves = geometry::reorder_curves_geometry(curves, old_by_new_indices_map, {}); +} + } // namespace blender::ed::curves diff --git a/source/blender/editors/include/ED_curves.hh b/source/blender/editors/include/ED_curves.hh index 36d5e4dbd56..d09a498c855 100644 --- a/source/blender/editors/include/ED_curves.hh +++ b/source/blender/editors/include/ED_curves.hh @@ -453,6 +453,12 @@ void add_curves(bke::CurvesGeometry &curves, Span new_sizes); void resize_curves(bke::CurvesGeometry &curves, const IndexMask &curves_to_resize, Span new_sizes); +/** + * Reorders the curves in \a curves. + * \param old_by_new_indices_map: An index mapping where each value is the target index for the + * reorder curves. + */ +void reorder_curves(bke::CurvesGeometry &curves, Span old_by_new_indices_map); /** \} */ diff --git a/source/blender/makesrna/intern/rna_curves_api.cc b/source/blender/makesrna/intern/rna_curves_api.cc index 989d24cf4ae..c01d6ca3a4f 100644 --- a/source/blender/makesrna/intern/rna_curves_api.cc +++ b/source/blender/makesrna/intern/rna_curves_api.cc @@ -21,6 +21,7 @@ # include "BKE_report.hh" # include "BLI_index_mask.hh" +# include "BLI_set.hh" # include "ED_curves.hh" @@ -122,6 +123,33 @@ bool rna_CurvesGeometry_resize_curves(blender::bke::CurvesGeometry &curves, return true; } +bool rna_CurvesGeometry_reorder_curves(blender::bke::CurvesGeometry &curves, + ReportList *reports, + const int *reorder_indices_ptr, + const int reorder_indices_num) +{ + using namespace blender; + const Span new_to_old_indices_map(reorder_indices_ptr, reorder_indices_num); + if (curves.curves_num() != reorder_indices_num) { + BKE_report( + reports, RPT_ERROR, "Length of reorder indices must be the same as the number of curves"); + return false; + } + if (std::any_of(new_to_old_indices_map.begin(), + new_to_old_indices_map.end(), + [&](const int index) { return !curves.curves_range().contains(index); })) + { + BKE_report(reports, RPT_ERROR, "Reorder indices must be valid"); + return false; + } + if (Set(new_to_old_indices_map).size() != reorder_indices_num) { + BKE_report(reports, RPT_ERROR, "Reorder indices must not have duplicates"); + return false; + } + ed::curves::reorder_curves(curves, new_to_old_indices_map); + return true; +} + bool rna_CurvesGeometry_set_types(blender::bke::CurvesGeometry &curves, ReportList *reports, const int type, @@ -198,6 +226,26 @@ static void rna_Curves_resize_curves(Curves *curves_id, } } +static void rna_Curves_reorder_curves(Curves *curves_id, + ReportList *reports, + const int *reorder_indices_ptr, + const int reorder_indices_num) +{ + using namespace blender; + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); + if (!rna_CurvesGeometry_reorder_curves( + curves, reports, reorder_indices_ptr, reorder_indices_num)) + { + return; + } + + /* Avoid updates for importers creating curves. */ + if (curves_id->id.us > 0) { + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_GEOM | ND_DATA, curves_id); + } +} + static void rna_Curves_set_types(Curves *curves_id, ReportList *reports, const int type, @@ -298,6 +346,21 @@ void RNA_api_curves(StructRNA *srna) 10000); RNA_def_parameter_flags(parm, PROP_DYNAMIC, ParameterFlag(0)); + func = RNA_def_function(srna, "reorder_curves", "rna_Curves_reorder_curves"); + RNA_def_function_ui_description(func, "Reorder the curves by the new indices."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_int_array(func, + "new_indices", + 1, + nullptr, + 0, + INT_MAX, + "New indices", + "The new index for each of the curves", + 0, + 10000); + RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED); + func = RNA_def_function(srna, "set_types", "rna_Curves_set_types"); RNA_def_function_ui_description(func, "Set the curve type. If indices are provided, set only the " diff --git a/source/blender/makesrna/intern/rna_curves_utils.hh b/source/blender/makesrna/intern/rna_curves_utils.hh index abe317d4623..bdb2e3d01c0 100644 --- a/source/blender/makesrna/intern/rna_curves_utils.hh +++ b/source/blender/makesrna/intern/rna_curves_utils.hh @@ -35,6 +35,11 @@ bool rna_CurvesGeometry_resize_curves(blender::bke::CurvesGeometry &curves, const int *indices_ptr, int indices_num); +bool rna_CurvesGeometry_reorder_curves(blender::bke::CurvesGeometry &curves, + ReportList *reports, + const int *reorder_indices_ptr, + int reorder_indices_num); + bool rna_CurvesGeometry_set_types(blender::bke::CurvesGeometry &curves, ReportList *reports, int type, diff --git a/source/blender/makesrna/intern/rna_grease_pencil_api.cc b/source/blender/makesrna/intern/rna_grease_pencil_api.cc index df61477bd15..9dc3be60b4e 100644 --- a/source/blender/makesrna/intern/rna_grease_pencil_api.cc +++ b/source/blender/makesrna/intern/rna_grease_pencil_api.cc @@ -108,6 +108,30 @@ static void rna_GreasePencilDrawing_resize_curves(ID *grease_pencil_id, } } +static void rna_GreasePencilDrawing_reorder_curves(ID *grease_pencil_id, + GreasePencilDrawing *drawing_ptr, + ReportList *reports, + const int *reorder_indices_ptr, + const int reorder_indices_num) +{ + using namespace blender; + bke::greasepencil::Drawing &drawing = drawing_ptr->wrap(); + bke::CurvesGeometry &curves = drawing.strokes_for_write(); + if (!rna_CurvesGeometry_reorder_curves( + curves, reports, reorder_indices_ptr, reorder_indices_num)) + { + return; + } + + drawing.tag_topology_changed(); + + /* Avoid updates for importers. */ + if (grease_pencil_id->us > 0) { + DEG_id_tag_update(grease_pencil_id, ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_GEOM | ND_DATA, grease_pencil_id); + } +} + static void rna_GreasePencilDrawing_set_types(ID *grease_pencil_id, GreasePencilDrawing *drawing_ptr, ReportList *reports, @@ -517,6 +541,21 @@ void RNA_api_grease_pencil_drawing(StructRNA *srna) 10000); RNA_def_parameter_flags(parm, PROP_DYNAMIC, ParameterFlag(0)); + func = RNA_def_function(srna, "reorder_strokes", "rna_GreasePencilDrawing_reorder_curves"); + RNA_def_function_ui_description(func, "Reorder the strokes by the new indices."); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS); + parm = RNA_def_int_array(func, + "new_indices", + 1, + nullptr, + 0, + INT_MAX, + "New indices", + "The new index for each of the strokes", + 0, + 10000); + RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED); + func = RNA_def_function(srna, "set_types", "rna_GreasePencilDrawing_set_types"); RNA_def_function_ui_description(func, "Set the curve type. If indices are provided, set only the "