Blender V4.3
grease_pencil_weight_average.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
6
8
10 /* Get the average weight of all points in the brush buffer. */
11 float get_average_weight_in_brush_buffer(const Span<DrawingWeightData> drawing_weights)
12 {
13 float average_sum = 0.0f;
14 float point_num = 0;
15 for (const DrawingWeightData &drawing_weight : drawing_weights) {
16 for (const BrushPoint &point : drawing_weight.points_in_brush) {
17 average_sum += drawing_weight.deform_weights[point.drawing_point_index];
18 point_num++;
19 }
20 }
21
22 if (point_num == 0) {
23 return 0.0f;
24 }
25 return math::clamp(average_sum / point_num, 0.0f, 1.0f);
26 }
27
28 public:
29 void on_stroke_begin(const bContext &C, const InputSample &start_sample) override
30 {
31 using namespace blender::ed::greasepencil;
32
33 this->get_brush_settings(C, start_sample);
36
37 /* Get editable drawings grouped per frame number. When multi-frame editing is disabled, this
38 * is just one group for the current frame. When multi-frame editing is enabled, the selected
39 * keyframes are grouped per frame number. This way we can use Average on multiple layers
40 * together instead of on every layer individually. */
41 const Scene *scene = CTX_data_scene(&C);
42 Array<Vector<MutableDrawingInfo>> drawings_per_frame =
44
45 this->drawing_weight_data = Array<Array<DrawingWeightData>>(drawings_per_frame.size());
46
47 /* Get weight data for all drawings in this frame group. */
48 for (const int frame_group : drawings_per_frame.index_range()) {
49 const Vector<MutableDrawingInfo> &drawings = drawings_per_frame[frame_group];
50 this->init_weight_data_for_drawings(C, drawings, frame_group);
51 }
52 }
53
54 void on_stroke_extended(const bContext &C, const InputSample &extension_sample) override
55 {
56 using namespace blender::ed::greasepencil;
57
58 this->get_mouse_input_sample(extension_sample);
59
60 /* Iterate over the drawings grouped per frame number. Collect all stroke points under the
61 * brush and average them. */
62 std::atomic<bool> changed = false;
64 this->drawing_weight_data.index_range(), [&](const int frame_group) {
65 Array<DrawingWeightData> &drawing_weights = this->drawing_weight_data[frame_group];
66
67 /* For all layers at this key frame, collect the stroke points under the brush in a
68 * buffer. */
69 threading::parallel_for_each(drawing_weights, [&](DrawingWeightData &drawing_weight) {
70 for (const int point_index : drawing_weight.point_positions.index_range()) {
71 const float2 &co = drawing_weight.point_positions[point_index];
72
73 /* When the point is under the brush, add it to the brush point buffer. */
74 this->add_point_under_brush_to_brush_buffer(co, drawing_weight, point_index);
75 }
76 });
77
78 /* Get the average weight of the points in the brush buffer. */
79 const float average_weight = this->get_average_weight_in_brush_buffer(drawing_weights);
80
81 /* Apply the Average brush to all points in the brush buffer. */
82 threading::parallel_for_each(drawing_weights, [&](DrawingWeightData &drawing_weight) {
83 for (const BrushPoint &point : drawing_weight.points_in_brush) {
84 this->apply_weight_to_point(point, average_weight, drawing_weight);
85
86 /* Normalize weights of bone-deformed vertex groups to 1.0f. */
87 if (this->auto_normalize) {
88 normalize_vertex_weights(drawing_weight.deform_verts[point.drawing_point_index],
89 drawing_weight.active_vertex_group,
90 drawing_weight.locked_vgroups,
91 drawing_weight.bone_deformed_vgroups);
92 }
93 }
94
95 if (!drawing_weight.points_in_brush.is_empty()) {
96 changed = true;
97 drawing_weight.points_in_brush.clear();
98 }
99 });
100 });
101
102 if (changed) {
105 }
106 }
107
108 void on_stroke_done(const bContext & /*C*/) override {}
109};
110
111std::unique_ptr<GreasePencilStrokeOperation> new_weight_paint_average_operation()
112{
113 return std::make_unique<AverageWeightPaintOperation>();
114}
115
116} // namespace blender::ed::sculpt_paint::greasepencil
Scene * CTX_data_scene(const bContext *C)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
#define C
Definition RandGen.cpp:29
#define NC_GEOM
Definition WM_types.hh:360
#define ND_DATA
Definition WM_types.hh:475
int64_t size() const
Definition BLI_array.hh:245
IndexRange index_range() const
Definition BLI_array.hh:349
void on_stroke_begin(const bContext &C, const InputSample &start_sample) override
void on_stroke_extended(const bContext &C, const InputSample &extension_sample) override
void get_mouse_input_sample(const InputSample &input_sample, const float brush_widen_factor=1.0f)
void get_brush_settings(const bContext &C, const InputSample &start_sample)
void init_weight_data_for_drawings(const bContext &C, const Span< ed::greasepencil::MutableDrawingInfo > &drawings, const int frame_group)
void apply_weight_to_point(const BrushPoint &point, const float target_weight, DrawingWeightData &drawing_weight)
void normalize_vertex_weights(MDeformVert &dvert, const int active_vertex_group, const Span< bool > vertex_group_is_locked, const Span< bool > vertex_group_is_bone_deformed)
Array< Vector< MutableDrawingInfo > > retrieve_editable_drawings_grouped_per_frame(const Scene &scene, GreasePencil &grease_pencil)
std::unique_ptr< GreasePencilStrokeOperation > new_weight_paint_average_operation()
T clamp(const T &a, const T &min, const T &max)
void parallel_for_each(Range &&range, const Function &function)
Definition BLI_task.hh:58
void WM_event_add_notifier(const bContext *C, uint type, void *reference)