Blender V4.5
grease_pencil_sculpt_twist.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_rotation.h"
6
7#include "BKE_context.hh"
8#include "BKE_crazyspace.hh"
9#include "BKE_curves.hh"
10#include "BKE_grease_pencil.hh"
11#include "BKE_paint.hh"
12
13#include "ED_grease_pencil.hh"
14#include "ED_view3d.hh"
15
16#include "WM_api.hh"
17#include "WM_types.hh"
18
20#include "paint_intern.hh"
21
23
25 public:
27
28 void on_stroke_begin(const bContext &C, const InputSample &start_sample) override;
29 void on_stroke_extended(const bContext &C, const InputSample &extension_sample) override;
30 void on_stroke_done(const bContext & /*C*/) override {}
31};
32
33static float2 rotate_by_angle(const float2 &vec, const float angle)
34{
35 const float cos_angle = math::cos(angle);
36 const float sin_angle = math::sin(angle);
37 return float2(vec.x * cos_angle - vec.y * sin_angle, vec.x * sin_angle + vec.y * cos_angle);
38}
39
40void TwistOperation::on_stroke_begin(const bContext &C, const InputSample &start_sample)
41{
42 this->init_stroke(C, start_sample);
43 this->init_auto_masking(C, start_sample);
44}
45
46void TwistOperation::on_stroke_extended(const bContext &C, const InputSample &extension_sample)
47{
48 const Scene &scene = *CTX_data_scene(&C);
50 const Brush &brush = *BKE_paint_brush(&paint);
51 const bool invert = this->is_inverted(brush);
52
54 C,
56 const IndexMask &point_mask,
57 const DeltaProjectionFunc &projection_fn) {
59 Array<float2> view_positions = calculate_view_positions(params, point_mask);
60 bke::CurvesGeometry &curves = params.drawing.strokes_for_write();
61 MutableSpan<float3> positions = curves.positions_for_write();
62
63 const float2 mouse_pos = extension_sample.mouse_position;
64
65 point_mask.foreach_index(GrainSize(4096), [&](const int64_t point_i) {
66 const float2 &co = view_positions[point_i];
67 const float influence = brush_point_influence(
68 scene, brush, co, extension_sample, params.multi_frame_falloff);
69 if (influence <= 0.0f) {
70 return;
71 }
72
73 const float angle = DEG2RADF(invert ? -1.0f : 1.0f) * influence;
74 const float2 radial_offset = co - mouse_pos;
75 positions[point_i] += compute_orig_delta(projection_fn,
76 deformation,
77 point_i,
78 rotate_by_angle(radial_offset, angle) -
79 radial_offset);
80 });
81
82 params.drawing.tag_positions_changed();
83 return true;
84 });
85 this->stroke_extended(extension_sample);
86}
87
88std::unique_ptr<GreasePencilStrokeOperation> new_twist_operation(const BrushStrokeMode stroke_mode)
89{
90 return std::make_unique<TwistOperation>(stroke_mode);
91}
92
93} // namespace blender::ed::sculpt_paint::greasepencil
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
#define DEG2RADF(_deg)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
#define C
Definition RandGen.cpp:29
long long int int64_t
void foreach_editable_drawing_with_automask(const bContext &C, FunctionRef< bool(const GreasePencilStrokeParams &params, const IndexMask &points)> fn) const
void init_auto_masking(const bContext &C, const InputSample &start_sample)
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 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
static float2 rotate_by_angle(const float2 &vec, const float angle)
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)
bke::crazyspace::GeometryDeformation get_drawing_deformation(const GreasePencilStrokeParams &params)
std::unique_ptr< GreasePencilStrokeOperation > new_twist_operation(BrushStrokeMode stroke_mode)
float3 compute_orig_delta(const DeltaProjectionFunc &projection_fn, const bke::crazyspace::GeometryDeformation &deformation, int index, const float2 &screen_delta)
std::function< float3(const float3 position, const float2 &screen_delta)> DeltaProjectionFunc
T cos(const AngleRadianBase< T > &a)
T sin(const AngleRadianBase< T > &a)
VecBase< float, 2 > float2
BrushStrokeMode