Blender V4.5
sculpt_paint/grease_pencil_vertex_paint.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_math_color.hh"
6
8
9#include "BKE_brush.hh"
10#include "BKE_context.hh"
11#include "BKE_curves.hh"
12#include "BKE_grease_pencil.hh"
13#include "BKE_paint.hh"
14
16
18
19class VertexPaintOperation : public GreasePencilStrokeOperationCommon {
21
22 public:
23 void on_stroke_begin(const bContext &C, const InputSample &start_sample) override;
24 void on_stroke_extended(const bContext &C, const InputSample &extension_sample) override;
25 void on_stroke_done(const bContext & /*C*/) override {}
26};
27
29{
30 this->init_stroke(C, start_sample);
31 this->on_stroke_extended(C, start_sample);
32}
33
35 const InputSample &extension_sample)
36{
37 const Scene &scene = *CTX_data_scene(&C);
39 const Brush &brush = *BKE_paint_brush(&paint);
40 const bool invert = this->is_inverted(brush);
41
42 const bool use_selection_masking = GPENCIL_ANY_VERTEX_MASK(
44
45 const bool do_points = do_vertex_color_points(brush);
46 const bool do_fill = do_vertex_color_fill(brush);
47
48 float color_linear[3];
49 srgb_to_linearrgb_v3_v3(color_linear, BKE_brush_color_get(&scene, &paint, &brush));
50 const ColorGeometry4f mix_color(color_linear[0], color_linear[1], color_linear[2], 1.0f);
51
53 IndexMaskMemory memory;
54 const IndexMask point_selection = point_mask_for_stroke_operation(
55 params, use_selection_masking, memory);
56 if (!point_selection.is_empty() && do_points) {
57 Array<float2> view_positions = calculate_view_positions(params, point_selection);
58 MutableSpan<ColorGeometry4f> vertex_colors = params.drawing.vertex_colors_for_write();
59
60 if (invert) {
61 /* Erase vertex colors. */
62 point_selection.foreach_index(GrainSize(4096), [&](const int64_t point_i) {
63 const float influence = brush_point_influence(
64 scene, brush, view_positions[point_i], extension_sample, params.multi_frame_falloff);
65
66 ColorGeometry4f &color = vertex_colors[point_i];
67 color.a -= influence;
68 color.a = math::max(color.a, 0.0f);
69 });
70 }
71 else {
72 /* Mix brush color into vertex colors by influence using alpha over. */
73 point_selection.foreach_index(GrainSize(4096), [&](const int64_t point_i) {
74 const float influence = brush_point_influence(
75 scene, brush, view_positions[point_i], extension_sample, params.multi_frame_falloff);
76
77 ColorGeometry4f &color = vertex_colors[point_i];
78 color = math::interpolate(color, mix_color, influence);
79 });
80 }
81 }
82
83 const IndexMask fill_selection = fill_mask_for_stroke_operation(
84 params, use_selection_masking, memory);
85 if (!fill_selection.is_empty() && do_fill) {
86 const OffsetIndices<int> points_by_curve = params.drawing.strokes().points_by_curve();
87 Array<float2> view_positions = calculate_view_positions(params, point_selection);
88 MutableSpan<ColorGeometry4f> fill_colors = params.drawing.fill_colors_for_write();
89
90 if (invert) {
91 fill_selection.foreach_index(GrainSize(1024), [&](const int64_t curve_i) {
92 const IndexRange points = points_by_curve[curve_i];
93 const Span<float2> curve_view_positions = view_positions.as_span().slice(points);
94 const float influence = brush_fill_influence(
95 scene, brush, curve_view_positions, extension_sample, params.multi_frame_falloff);
96
97 ColorGeometry4f &color = fill_colors[curve_i];
98 color.a -= influence;
99 color.a = math::max(color.a, 0.0f);
100 });
101 }
102 else {
103 fill_selection.foreach_index(GrainSize(1024), [&](const int64_t curve_i) {
104 const IndexRange points = points_by_curve[curve_i];
105 const Span<float2> curve_view_positions = view_positions.as_span().slice(points);
106 const float influence = brush_fill_influence(
107 scene, brush, curve_view_positions, extension_sample, params.multi_frame_falloff);
108
109 ColorGeometry4f &color = fill_colors[curve_i];
110 color = math::interpolate(color, mix_color, influence);
111 });
112 }
113 }
114
115 return true;
116 });
117}
118
119std::unique_ptr<GreasePencilStrokeOperation> new_vertex_paint_operation(
120 const BrushStrokeMode stroke_mode)
121{
122 return std::make_unique<VertexPaintOperation>(stroke_mode);
123}
124
125} // namespace blender::ed::sculpt_paint::greasepencil
const float * BKE_brush_color_get(const Scene *scene, const Paint *paint, const Brush *brush)
Definition brush.cc:1128
Scene * CTX_data_scene(const bContext *C)
Low-level operations for curves.
Low-level operations for grease pencil.
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:467
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:636
void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
#define GPENCIL_ANY_VERTEX_MASK(flag)
eGP_vertex_SelectMaskFlag
#define C
Definition RandGen.cpp:29
long long int int64_t
Span< T > as_span() const
Definition BLI_array.hh:232
void foreach_editable_drawing(const bContext &C, FunctionRef< bool(const GreasePencilStrokeParams &params, const DeltaProjectionFunc &projection_fn)> fn) const
void on_stroke_extended(const bContext &C, const InputSample &extension_sample) override
void on_stroke_begin(const bContext &C, const InputSample &start_sample) override
void foreach_index(Fn &&fn) const
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
Definition invert.h:11
IndexMask fill_mask_for_stroke_operation(const GreasePencilStrokeParams &params, bool use_selection_masking, IndexMaskMemory &memory)
std::unique_ptr< GreasePencilStrokeOperation > new_vertex_paint_operation(BrushStrokeMode stroke_mode)
IndexMask point_mask_for_stroke_operation(const GreasePencilStrokeParams &params, bool use_selection_masking, IndexMaskMemory &memory)
Array< float2 > calculate_view_positions(const GreasePencilStrokeParams &params, const IndexMask &selection)
float brush_point_influence(const Scene &scene, const Brush &brush, const float2 &co, const InputSample &sample, float multi_frame_falloff)
float brush_fill_influence(const Scene &scene, const Brush &brush, Span< float2 > fill_positions, const InputSample &sample, float multi_frame_falloff)
T interpolate(const T &a, const T &b, const FactorT &t)
T max(const T &a, const T &b)
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
Definition BLI_color.hh:342
BrushStrokeMode
struct ToolSettings * toolsettings
char gpencil_selectmode_vertex