Blender V4.3
grease_pencil_sculpt_smooth.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 "BKE_attribute.hh"
6
7#include "BKE_context.hh"
8#include "BKE_curves.hh"
10#include "BKE_paint.hh"
11
12#include "BLI_virtual_array.hh"
13#include "DNA_brush_enums.h"
14
15#include "GEO_smooth_curves.hh"
16
17#include "ED_grease_pencil.hh"
18#include "ED_view3d.hh"
19
20#include "WM_api.hh"
21#include "WM_types.hh"
22
24#include "paint_intern.hh"
25
27
29 private:
30 bool temp_smooth_;
31
32 public:
34
35 SmoothOperation(const BrushStrokeMode stroke_mode, const bool temp_smooth = false)
36 : GreasePencilStrokeOperationCommon(stroke_mode), temp_smooth_(temp_smooth)
37 {
38 }
39
40 void on_stroke_begin(const bContext &C, const InputSample &start_sample) override;
41 void on_stroke_extended(const bContext &C, const InputSample &extension_sample) override;
42 void on_stroke_done(const bContext & /*C*/) override {}
43};
44
45void SmoothOperation::on_stroke_begin(const bContext &C, const InputSample &start_sample)
46{
47 if (temp_smooth_) {
50 BLI_assert(brush != nullptr);
51
52 init_brush(*brush);
53
54 this->start_mouse_position = start_sample.mouse_position;
55 this->prev_mouse_position = start_sample.mouse_position;
56 }
57 else {
58 this->init_stroke(C, start_sample);
59 }
60}
61
62void SmoothOperation::on_stroke_extended(const bContext &C, const InputSample &extension_sample)
63{
64 const Scene &scene = *CTX_data_scene(&C);
65 const Brush &brush = [&]() -> const Brush & {
66 if (temp_smooth_) {
69 BLI_assert(brush != nullptr);
70 return *brush;
71 }
73 return *BKE_paint_brush(&paint);
74 }();
75 const int sculpt_mode_flag = brush.gpencil_settings->sculpt_mode_flag;
76
77 const bool is_masking = GPENCIL_ANY_SCULPT_MASK(
79
81 IndexMaskMemory selection_memory;
82 const IndexMask selection = point_selection_mask(params, is_masking, selection_memory);
83 if (selection.is_empty()) {
84 return false;
85 }
86
88 bke::CurvesGeometry &curves = params.drawing.strokes_for_write();
89 bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
90 const OffsetIndices points_by_curve = curves.points_by_curve();
91 const VArray<bool> cyclic = curves.cyclic();
92 const int iterations = 2;
93
94 const VArray<float> influences = VArray<float>::ForFunc(
95 view_positions.size(), [&](const int64_t point_) {
96 return brush_point_influence(
97 scene, brush, view_positions[point_], extension_sample, params.multi_frame_falloff);
98 });
99 Array<bool> selection_array(curves.points_num());
100 selection.to_bools(selection_array);
101 const VArray<bool> selection_varray = VArray<bool>::ForSpan(selection_array);
102
103 bool changed = false;
104 if (sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_POSITION) {
105 MutableSpan<float3> positions = curves.positions_for_write();
107 points_by_curve,
108 selection_varray,
109 cyclic,
110 iterations,
111 influences,
112 false,
113 false,
114 positions);
115 params.drawing.tag_positions_changed();
116 changed = true;
117 }
118 if (sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_STRENGTH) {
119 MutableSpan<float> opacities = params.drawing.opacities_for_write();
121 points_by_curve,
122 selection_varray,
123 cyclic,
124 iterations,
125 influences,
126 true,
127 false,
128 opacities);
129 changed = true;
130 }
131 if (sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_THICKNESS) {
132 const MutableSpan<float> radii = params.drawing.radii_for_write();
134 points_by_curve,
135 selection_varray,
136 cyclic,
137 iterations,
138 influences,
139 true,
140 false,
141 radii);
142 curves.tag_radii_changed();
143 changed = true;
144 }
145 if (sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_UV) {
147 "rotation", bke::AttrDomain::Point);
149 points_by_curve,
150 selection_varray,
151 cyclic,
152 iterations,
153 influences,
154 true,
155 false,
156 rotations.span);
157 rotations.finish();
158 changed = true;
159 }
160 return changed;
161 });
162 this->stroke_extended(extension_sample);
163}
164
165std::unique_ptr<GreasePencilStrokeOperation> new_smooth_operation(
166 const BrushStrokeMode stroke_mode, const bool temp_smooth)
167{
168 return std::make_unique<SmoothOperation>(stroke_mode, temp_smooth);
169}
170
171} // namespace blender::ed::sculpt_paint::greasepencil
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(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:477
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:649
Brush * BKE_paint_brush_from_essentials(Main *bmain, eObjectMode obmode, const char *name)
Definition paint.cc:789
#define BLI_assert(a)
Definition BLI_assert.h:50
@ GP_SCULPT_FLAGMODE_APPLY_UV
@ GP_SCULPT_FLAGMODE_APPLY_POSITION
@ GP_SCULPT_FLAGMODE_APPLY_THICKNESS
@ GP_SCULPT_FLAGMODE_APPLY_STRENGTH
#define GPENCIL_ANY_SCULPT_MASK(flag)
@ OB_MODE_SCULPT_GREASE_PENCIL
eGP_Sculpt_SelectMaskFlag
#define C
Definition RandGen.cpp:29
int64_t size() const
Definition BLI_array.hh:245
static VArray ForSpan(Span< T > values)
static VArray ForFunc(const int64_t size, GetFunc get_func)
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
void foreach_editable_drawing(const bContext &C, FunctionRef< bool(const GreasePencilStrokeParams &params)> fn) const
void on_stroke_extended(const bContext &C, const InputSample &extension_sample) override
SmoothOperation(const BrushStrokeMode stroke_mode, const bool temp_smooth=false)
void on_stroke_begin(const bContext &C, const InputSample &start_sample) override
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
IndexMask point_selection_mask(const GreasePencilStrokeParams &params, const bool use_masking, IndexMaskMemory &memory)
Array< float2 > calculate_view_positions(const GreasePencilStrokeParams &params, const IndexMask &selection)
std::unique_ptr< CurvesSculptStrokeOperation > new_smooth_operation()
void smooth_curve_attribute(const IndexMask &curves_to_smooth, const OffsetIndices< int > points_by_curve, const VArray< bool > &point_selection, const VArray< bool > &cyclic, int iterations, float influence, bool smooth_ends, bool keep_shape, GMutableSpan attribute_data)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
BrushStrokeMode
__int64 int64_t
Definition stdint.h:89
struct BrushGpencilSettings * gpencil_settings
struct ToolSettings * toolsettings
char gpencil_selectmode_sculpt