GPv3: Add function to retrieve falloff factor for multi frame editing

This PR prepares GPv3 for calculating falloff factors when working in  multi frame editing mode.

The falloff popover is added to the UI.
A `float multi_frame_falloff` is added to `MutableDrawingInfo`. This is a factor from 0.0 to 1.0f.
A `retrieve_editable_drawings_with_falloff()` is added to the utility functions, which retrieves the falloff factor for each drawing when
multi frame falloff is enabled.

To avoid a copy, the return type of  `retrieve_editable_drawings()` and friends is changed from
`Array<MutableDrawingInfo>` to `Vector<MutableDrawingInfo>`.

Pull Request: https://projects.blender.org/blender/blender/pulls/118108
This commit is contained in:
Sietse Brouwer
2024-02-13 12:04:45 +01:00
committed by Falk David
parent 888c4d0766
commit 2f0b293da3
11 changed files with 190 additions and 63 deletions
+32 -4
View File
@@ -827,13 +827,21 @@ class VIEW3D_HT_header(Header):
depress=(tool_settings.gpencil_selectmode_edit == 'STROKE'),
).mode = 'STROKE'
if object_mode == 'PAINT_GREASE_PENCIL':
row = layout.row(align=True)
row.prop(tool_settings, "use_gpencil_draw_additive", text="", icon='FREEZE')
if object_mode in {'PAINT_GREASE_PENCIL', 'EDIT', 'WEIGHT_PAINT'}:
row = layout.row(align=True)
row.prop(tool_settings, "use_grease_pencil_multi_frame_editing", text="")
if object_mode == 'PAINT_GREASE_PENCIL':
row = layout.row()
sub = row.row(align=True)
sub.prop(tool_settings, "use_gpencil_draw_additive", text="", icon='FREEZE')
if object_mode in {'EDIT', 'WEIGHT_PAINT'}:
sub = row.row(align=True)
sub.enabled = tool_settings.use_grease_pencil_multi_frame_editing
sub.popover(
panel="VIEW3D_PT_grease_pencil_multi_frame",
text="Multiframe",
)
# Grease Pencil (legacy)
if obj and obj.type == 'GPENCIL' and context.gpencil_data:
@@ -8004,6 +8012,25 @@ class VIEW3D_PT_gpencil_multi_frame(Panel):
layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True)
class VIEW3D_PT_grease_pencil_multi_frame(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "Multi Frame"
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
settings = tool_settings.gpencil_sculpt
col = layout.column(align=True)
col.prop(settings, "use_multiframe_falloff")
# Falloff curve
if settings.use_multiframe_falloff:
layout.template_curve_mapping(settings, "multiframe_falloff_curve", brush=True)
# Grease Pencil Object - Curve Editing tools
class VIEW3D_PT_gpencil_curve_edit(Panel):
bl_space_type = 'VIEW_3D'
@@ -9024,6 +9051,7 @@ classes = (
VIEW3D_PT_grease_pencil,
VIEW3D_PT_annotation_onion,
VIEW3D_PT_gpencil_multi_frame,
VIEW3D_PT_grease_pencil_multi_frame,
VIEW3D_PT_gpencil_curve_edit,
VIEW3D_PT_gpencil_sculpt_automasking,
VIEW3D_PT_quad_view,
@@ -228,7 +228,7 @@ static void grease_pencil_edit_batch_ensure(Object &object,
BLI_assert(cache->edit_points == nullptr && cache->edit_lines == nullptr);
/* Get the visible drawings. */
const Array<ed::greasepencil::DrawingInfo> drawings =
const Vector<ed::greasepencil::DrawingInfo> drawings =
ed::greasepencil::retrieve_visible_drawings(scene, grease_pencil);
const Span<const Layer *> layers = grease_pencil.layers();
@@ -422,7 +422,7 @@ static void grease_pencil_geom_batch_ensure(Object &object,
BLI_assert(cache->geom_batch == nullptr);
/* Get the visible drawings. */
const Array<ed::greasepencil::DrawingInfo> drawings =
const Vector<ed::greasepencil::DrawingInfo> drawings =
ed::greasepencil::retrieve_visible_drawings(scene, grease_pencil);
/* First, count how many vertices and triangles are needed for the whole object. Also record the
@@ -69,7 +69,7 @@ static int grease_pencil_stroke_smooth_exec(bContext *C, wmOperator *op)
}
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.points_num() == 0) {
@@ -231,7 +231,7 @@ static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op)
const float epsilon = RNA_float_get(op->ptr, "factor");
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.points_num() == 0) {
@@ -444,7 +444,7 @@ static int grease_pencil_delete_exec(bContext *C, wmOperator * /*op*/)
scene->toolsettings);
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask elements = ed::greasepencil::retrieve_editable_and_selected_elements(
@@ -587,7 +587,7 @@ static int grease_pencil_dissolve_exec(bContext *C, wmOperator *op)
const DissolveMode mode = DissolveMode(RNA_enum_get(op->ptr, "type"));
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (curves.points_num() == 0) {
@@ -760,7 +760,7 @@ static int grease_pencil_stroke_material_set_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
@@ -829,7 +829,7 @@ static int grease_pencil_cyclical_set_exec(bContext *C, wmOperator *op)
const CyclicalMode mode = CyclicalMode(RNA_enum_get(op->ptr, "type"));
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
if (mode == CyclicalMode::OPEN && !curves.attributes().contains("cyclic")) {
@@ -910,7 +910,7 @@ static int grease_pencil_set_active_material_exec(bContext *C, wmOperator * /*op
return OPERATOR_CANCELLED;
}
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
for (const MutableDrawingInfo &info : drawings) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
@@ -958,7 +958,7 @@ static int grease_pencil_set_uniform_thickness_exec(bContext *C, wmOperator *op)
const float radius = RNA_float_get(op->ptr, "thickness") * 0.5f;
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
@@ -1015,7 +1015,7 @@ static int grease_pencil_set_uniform_opacity_exec(bContext *C, wmOperator *op)
const float opacity = RNA_float_get(op->ptr, "opacity");
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
@@ -1070,7 +1070,7 @@ static int grease_pencil_stroke_switch_direction_exec(bContext *C, wmOperator *
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
@@ -1146,7 +1146,7 @@ static int grease_pencil_caps_set_exec(bContext *C, wmOperator *op)
const CapsMode mode = CapsMode(RNA_enum_get(op->ptr, "type"));
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
IndexMaskMemory memory;
@@ -1322,7 +1322,7 @@ static int grease_pencil_duplicate_exec(bContext *C, wmOperator * /*op*/)
scene->toolsettings);
std::atomic<bool> changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask elements = retrieve_editable_and_selected_elements(
@@ -1370,9 +1370,9 @@ static int grease_pencil_clean_loose_exec(bContext *C, wmOperator *op)
const int limit = RNA_int_get(op->ptr, "limit");
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene, grease_pencil);
threading::parallel_for_each(drawings, [&](MutableDrawingInfo &info) {
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
@@ -1436,7 +1436,7 @@ static int gpencil_stroke_subdivide_exec(bContext *C, wmOperator *op)
const bke::AttrDomain selection_domain = ED_grease_pencil_selection_domain_get(
scene->toolsettings);
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
@@ -1633,7 +1633,7 @@ static int grease_pencil_stroke_reorder_exec(bContext *C, wmOperator *op)
const ReorderDirection direction = ReorderDirection(RNA_enum_get(op->ptr, "direction"));
std::atomic<bool> changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask strokes = ed::greasepencil::retrieve_editable_and_selected_strokes(
@@ -1736,7 +1736,8 @@ static int grease_pencil_move_to_layer_exec(bContext *C, wmOperator *op)
}
/* Iterate through all the drawings at current scene frame. */
const Array<MutableDrawingInfo> drawings_src = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings_src = retrieve_editable_drawings(*scene,
grease_pencil);
for (const MutableDrawingInfo &info : drawings_src) {
bke::CurvesGeometry &curves_src = info.drawing.strokes_for_write();
IndexMaskMemory memory;
@@ -1903,8 +1904,8 @@ static bool grease_pencil_separate_selected(bContext &C,
GreasePencil &grease_pencil_dst = *static_cast<GreasePencil *>(object_dst->data);
/* Iterate through all the drawings at current scene frame. */
const Array<MutableDrawingInfo> drawings_src = retrieve_editable_drawings(scene,
grease_pencil_src);
const Vector<MutableDrawingInfo> drawings_src = retrieve_editable_drawings(scene,
grease_pencil_src);
for (const MutableDrawingInfo &info : drawings_src) {
bke::CurvesGeometry &curves_src = info.drawing.strokes_for_write();
IndexMaskMemory memory;
@@ -1973,7 +1974,7 @@ static bool grease_pencil_separate_layer(bContext &C,
grease_pencil_src.layers().first_index(layer_src), grease_pencil_src, grease_pencil_dst);
/* Iterate through all the drawings at current frame. */
const Array<MutableDrawingInfo> drawings_src = retrieve_editable_drawings_from_layer(
const Vector<MutableDrawingInfo> drawings_src = retrieve_editable_drawings_from_layer(
scene, grease_pencil_src, *layer_src);
for (const MutableDrawingInfo &info : drawings_src) {
bke::CurvesGeometry &curves_src = info.drawing.strokes_for_write();
@@ -2041,8 +2042,8 @@ static bool grease_pencil_separate_material(bContext &C,
false);
/* Iterate through all the drawings at current scene frame. */
const Array<MutableDrawingInfo> drawings_src = retrieve_editable_drawings(scene,
grease_pencil_src);
const Vector<MutableDrawingInfo> drawings_src = retrieve_editable_drawings(scene,
grease_pencil_src);
for (const MutableDrawingInfo &info : drawings_src) {
bke::CurvesGeometry &curves_src = info.drawing.strokes_for_write();
IndexMaskMemory memory;
@@ -2101,8 +2102,8 @@ static int grease_pencil_separate_exec(bContext *C, wmOperator *op)
switch (mode) {
case SeparateMode::SELECTED: {
/* Cancel if nothing selected. */
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene,
grease_pencil_src);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene,
grease_pencil_src);
const bool has_selection = std::any_of(
drawings.begin(), drawings.end(), [&](const MutableDrawingInfo &info) {
return ed::curves::has_anything_selected(info.drawing.strokes());
@@ -271,7 +271,7 @@ static int grease_pencil_material_lock_unselected_exec(bContext *C, wmOperator *
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
bool changed = false;
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
Set<int> materials_used;
@@ -36,7 +36,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
bke::AttrDomain selection_domain = ED_grease_pencil_selection_domain_get(scene->toolsettings);
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask selectable_elements = retrieve_editable_elements(
@@ -76,7 +76,7 @@ static int select_more_exec(bContext *C, wmOperator * /*op*/)
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask selectable_strokes = ed::greasepencil::retrieve_editable_strokes(
@@ -114,7 +114,7 @@ static int select_less_exec(bContext *C, wmOperator * /*op*/)
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask selectable_strokes = ed::greasepencil::retrieve_editable_strokes(
@@ -152,7 +152,7 @@ static int select_linked_exec(bContext *C, wmOperator * /*op*/)
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
IndexMaskMemory memory;
const IndexMask selectable_strokes = ed::greasepencil::retrieve_editable_strokes(
@@ -193,7 +193,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
bke::AttrDomain selection_domain = ED_grease_pencil_selection_domain_get(scene->toolsettings);
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
@@ -253,7 +253,7 @@ static int select_alternate_exec(bContext *C, wmOperator *op)
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
blender::ed::curves::select_alternate(info.drawing.strokes_for_write(), deselect_ends);
});
@@ -292,7 +292,7 @@ static int select_ends_exec(bContext *C, wmOperator *op)
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
const Array<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
const Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
@@ -7,6 +7,7 @@
*/
#include "BKE_attribute.hh"
#include "BKE_colortools.hh"
#include "BKE_grease_pencil.hh"
#include "BKE_material.h"
#include "BKE_scene.hh"
@@ -182,6 +183,53 @@ void DrawingPlacement::project(const Span<float2> src, MutableSpan<float3> dst)
});
}
static float get_multi_frame_falloff(const int frame_number,
const int center_frame,
const int min_frame,
const int max_frame,
const CurveMapping *falloff_curve)
{
if (falloff_curve == nullptr) {
return 1.0f;
}
/* Frame right of the center frame. */
if (frame_number > center_frame) {
const float frame_factor = 0.5f * float(center_frame - min_frame) / (frame_number - min_frame);
return BKE_curvemapping_evaluateF(falloff_curve, 0, frame_factor);
}
/* Frame left of the center frame. */
if (frame_number < center_frame) {
const float frame_factor = 0.5f * float(center_frame - frame_number) /
(max_frame - frame_number);
return BKE_curvemapping_evaluateF(falloff_curve, 0, frame_factor + 0.5f);
}
/* Frame at center. */
return BKE_curvemapping_evaluateF(falloff_curve, 0, 0.5f);
}
static std::pair<int, int> get_minmax_selected_frame_numbers(const GreasePencil &grease_pencil,
const int current_frame)
{
using namespace blender::bke::greasepencil;
int frame_min = current_frame;
int frame_max = current_frame;
Span<const Layer *> layers = grease_pencil.layers();
for (const int layer_i : layers.index_range()) {
const Layer &layer = *layers[layer_i];
if (!layer.is_editable()) {
continue;
}
for (const auto [frame_number, frame] : layer.frames().items()) {
if (frame_number != current_frame && frame.is_selected()) {
frame_min = math::min(frame_min, frame_number);
frame_max = math::min(frame_max, frame_number);
}
}
}
return std::pair<int, int>(frame_min, frame_max);
}
static Array<int> get_frame_numbers_for_layer(const bke::greasepencil::Layer &layer,
const int current_frame,
const bool use_multi_frame_editing)
@@ -197,8 +245,8 @@ static Array<int> get_frame_numbers_for_layer(const bke::greasepencil::Layer &la
return frame_numbers.as_span();
}
Array<MutableDrawingInfo> retrieve_editable_drawings(const Scene &scene,
GreasePencil &grease_pencil)
Vector<MutableDrawingInfo> retrieve_editable_drawings(const Scene &scene,
GreasePencil &grease_pencil)
{
using namespace blender::bke::greasepencil;
const int current_frame = scene.r.cfra;
@@ -217,15 +265,60 @@ Array<MutableDrawingInfo> retrieve_editable_drawings(const Scene &scene,
layer, current_frame, use_multi_frame_editing);
for (const int frame_number : frame_numbers) {
if (Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, frame_number)) {
editable_drawings.append({*drawing, layer_i, frame_number});
editable_drawings.append({*drawing, layer_i, frame_number, 1.0f});
}
}
}
return editable_drawings.as_span();
return editable_drawings;
}
Array<MutableDrawingInfo> retrieve_editable_drawings_from_layer(
Vector<MutableDrawingInfo> retrieve_editable_drawings_with_falloff(const Scene &scene,
GreasePencil &grease_pencil)
{
using namespace blender::bke::greasepencil;
const int current_frame = scene.r.cfra;
const ToolSettings *toolsettings = scene.toolsettings;
const bool use_multi_frame_editing = (toolsettings->gpencil_flags &
GP_USE_MULTI_FRAME_EDITING) != 0;
const bool use_multi_frame_falloff = use_multi_frame_editing &&
(toolsettings->gp_sculpt.flag &
GP_SCULPT_SETT_FLAG_FRAME_FALLOFF) != 0;
int center_frame;
std::pair<int, int> minmax_frame;
if (use_multi_frame_falloff) {
BKE_curvemapping_init(toolsettings->gp_sculpt.cur_falloff);
minmax_frame = get_minmax_selected_frame_numbers(grease_pencil, current_frame);
center_frame = math::clamp(current_frame, minmax_frame.first, minmax_frame.second);
}
Vector<MutableDrawingInfo> editable_drawings;
Span<const Layer *> layers = grease_pencil.layers();
for (const int layer_i : layers.index_range()) {
const Layer &layer = *layers[layer_i];
if (!layer.is_editable()) {
continue;
}
const Array<int> frame_numbers = get_frame_numbers_for_layer(
layer, current_frame, use_multi_frame_editing);
for (const int frame_number : frame_numbers) {
if (Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, frame_number)) {
const float falloff = use_multi_frame_falloff ?
get_multi_frame_falloff(frame_number,
center_frame,
minmax_frame.first,
minmax_frame.second,
toolsettings->gp_sculpt.cur_falloff) :
1.0f;
editable_drawings.append({*drawing, layer_i, frame_number, falloff});
}
}
}
return editable_drawings;
}
Vector<MutableDrawingInfo> retrieve_editable_drawings_from_layer(
const Scene &scene,
GreasePencil &grease_pencil,
const blender::bke::greasepencil::Layer &layer)
@@ -241,14 +334,16 @@ Array<MutableDrawingInfo> retrieve_editable_drawings_from_layer(
layer, current_frame, use_multi_frame_editing);
for (const int frame_number : frame_numbers) {
if (Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, frame_number)) {
editable_drawings.append({*drawing, layer.drawing_index_at(frame_number), frame_number});
editable_drawings.append(
{*drawing, layer.drawing_index_at(frame_number), frame_number, 1.0f});
}
}
return editable_drawings.as_span();
return editable_drawings;
}
Array<DrawingInfo> retrieve_visible_drawings(const Scene &scene, const GreasePencil &grease_pencil)
Vector<DrawingInfo> retrieve_visible_drawings(const Scene &scene,
const GreasePencil &grease_pencil)
{
using namespace blender::bke::greasepencil;
const int current_frame = scene.r.cfra;
@@ -272,7 +367,7 @@ Array<DrawingInfo> retrieve_visible_drawings(const Scene &scene, const GreasePen
}
}
return visible_drawings.as_span();
return visible_drawings;
}
static VectorSet<int> get_editable_material_indices(Object &object)
@@ -171,13 +171,16 @@ struct MutableDrawingInfo {
bke::greasepencil::Drawing &drawing;
const int layer_index;
const int frame_number;
const float multi_frame_falloff;
};
Array<MutableDrawingInfo> retrieve_editable_drawings(const Scene &scene,
GreasePencil &grease_pencil);
Array<MutableDrawingInfo> retrieve_editable_drawings_from_layer(
Vector<MutableDrawingInfo> retrieve_editable_drawings(const Scene &scene,
GreasePencil &grease_pencil);
Vector<MutableDrawingInfo> retrieve_editable_drawings_with_falloff(const Scene &scene,
GreasePencil &grease_pencil);
Vector<MutableDrawingInfo> retrieve_editable_drawings_from_layer(
const Scene &scene, GreasePencil &grease_pencil, const bke::greasepencil::Layer &layer);
Array<DrawingInfo> retrieve_visible_drawings(const Scene &scene,
const GreasePencil &grease_pencil);
Vector<DrawingInfo> retrieve_visible_drawings(const Scene &scene,
const GreasePencil &grease_pencil);
IndexMask retrieve_editable_strokes(Object &grease_pencil_object,
const bke::greasepencil::Drawing &drawing,
@@ -810,7 +810,7 @@ struct EraseOperationExecutor {
}
else {
/* Erase on all editable drawings. */
const Array<ed::greasepencil::MutableDrawingInfo> drawings =
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(
drawings, [&](const ed::greasepencil::MutableDrawingInfo &info) {
@@ -1194,7 +1194,7 @@ static bool do_lasso_select_grease_pencil(ViewContext *vc,
vc->scene->toolsettings);
bool changed = false;
const Array<ed::greasepencil::MutableDrawingInfo> drawings =
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings(*vc->scene, grease_pencil);
for (const ed::greasepencil::MutableDrawingInfo info : drawings) {
const bke::greasepencil::Layer &layer = *grease_pencil.layers()[info.layer_index];
@@ -3200,7 +3200,7 @@ static bool ed_grease_pencil_select_pick(bContext *C,
/* Collect editable drawings. */
const Object *ob_eval = DEG_get_evaluated_object(vc.depsgraph, const_cast<Object *>(vc.obedit));
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(vc.obedit->data);
const Array<ed::greasepencil::MutableDrawingInfo> drawings =
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings(*vc.scene, grease_pencil);
/* Get selection domain from tool settings. */
@@ -4224,7 +4224,7 @@ static bool do_grease_pencil_box_select(ViewContext *vc, const rcti *rect, const
scene->toolsettings);
bool changed = false;
const Array<ed::greasepencil::MutableDrawingInfo> drawings =
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings(*scene, grease_pencil);
for (const ed::greasepencil::MutableDrawingInfo info : drawings) {
const bke::greasepencil::Layer &layer = *grease_pencil.layers()[info.layer_index];
@@ -5089,7 +5089,7 @@ static bool grease_pencil_circle_select(ViewContext *vc,
vc->scene->toolsettings);
bool changed = false;
const Array<ed::greasepencil::MutableDrawingInfo> drawings =
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings(*vc->scene, grease_pencil);
for (const ed::greasepencil::MutableDrawingInfo info : drawings) {
const bke::greasepencil::Layer &layer = *grease_pencil.layers()[info.layer_index];
@@ -31,13 +31,13 @@ static void createTransGreasePencilVerts(bContext *C, TransInfo *t)
const bool use_connected_only = (t->flag & T_PROP_CONNECTED) != 0;
int total_number_of_drawings = 0;
Vector<Array<ed::greasepencil::MutableDrawingInfo>> all_drawings;
Vector<Vector<ed::greasepencil::MutableDrawingInfo>> all_drawings;
/* Count the number layers in all objects. */
for (const int i : trans_data_contrainers.index_range()) {
TransDataContainer &tc = trans_data_contrainers[i];
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(tc.obedit->data);
const Array<ed::greasepencil::MutableDrawingInfo> drawings =
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings(*scene, grease_pencil);
all_drawings.append(drawings);
total_number_of_drawings += drawings.size();
@@ -51,7 +51,7 @@ static void createTransGreasePencilVerts(bContext *C, TransInfo *t)
for (const int i : trans_data_contrainers.index_range()) {
TransDataContainer &tc = trans_data_contrainers[i];
const Array<ed::greasepencil::MutableDrawingInfo> drawings = all_drawings[i];
const Vector<ed::greasepencil::MutableDrawingInfo> drawings = all_drawings[i];
for (ed::greasepencil::MutableDrawingInfo info : drawings) {
if (use_proportional_edit) {
points_per_layer_per_object[layer_offset] = ed::greasepencil::retrieve_editable_points(
@@ -86,7 +86,7 @@ static void createTransGreasePencilVerts(bContext *C, TransInfo *t)
Span<const bke::greasepencil::Layer *> layers = grease_pencil.layers();
int layer_points_offset = 0;
const Array<ed::greasepencil::MutableDrawingInfo> drawings = all_drawings[i];
const Vector<ed::greasepencil::MutableDrawingInfo> drawings = all_drawings[i];
for (ed::greasepencil::MutableDrawingInfo info : drawings) {
const bke::greasepencil::Layer &layer = *layers[info.layer_index];
const float4x4 layer_space_to_world_space = layer.to_world_space(*object_eval);
@@ -143,7 +143,7 @@ static void recalcData_grease_pencil(TransInfo *t)
for (const TransDataContainer &tc : trans_data_contrainers) {
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(tc.obedit->data);
const Array<ed::greasepencil::MutableDrawingInfo> drawings =
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings(*scene, grease_pencil);
for (ed::greasepencil::MutableDrawingInfo info : drawings) {
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
@@ -815,7 +815,7 @@ static int gizmo_3d_foreach_selected(const bContext *C,
mat_local = float4x4(obedit->world_to_object) * float4x4(ob_iter->object_to_world);
}
const Array<ed::greasepencil::MutableDrawingInfo> drawings =
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(
drawings, [&](const ed::greasepencil::MutableDrawingInfo &info) {