Python: Add API function to reorder curves

The order of curves in a Grease Pencil drawing defines the
order in wich they are rendered, so it's important to be
able to change the order. Currently, there is not easy way
to do this from python.

This adds a new `reorder_curves` and `reorder_strokes`
function to reorder the curves in the curves geometry.

The function takes in an array of indices that are the
new indices for the curves (e.g. an index map).

`reorder_curves(new_indices=[...])`

Pull Request: https://projects.blender.org/blender/blender/pulls/130331
This commit is contained in:
Falk David
2024-12-03 16:23:31 +01:00
committed by Falk David
parent 66e090dcb4
commit a265b591be
5 changed files with 120 additions and 0 deletions

View File

@@ -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<int> old_by_new_indices_map)
{
curves = geometry::reorder_curves_geometry(curves, old_by_new_indices_map, {});
}
} // namespace blender::ed::curves

View File

@@ -453,6 +453,12 @@ void add_curves(bke::CurvesGeometry &curves, Span<int> new_sizes);
void resize_curves(bke::CurvesGeometry &curves,
const IndexMask &curves_to_resize,
Span<int> 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<int> old_by_new_indices_map);
/** \} */

View File

@@ -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<int> 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 "

View File

@@ -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,

View File

@@ -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 "