Blender V4.3
grease_pencil_paint_common.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_brush.hh"
6#include "BKE_colortools.hh"
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 "BLI_index_mask.hh"
14#include "BLI_math_vector.hh"
15#include "BLI_task.hh"
16
18
19#include "DNA_brush_types.h"
21#include "DNA_screen_types.h"
22#include "DNA_view3d_types.h"
23
24#include "ED_grease_pencil.hh"
25#include "ED_view3d.hh"
26
28
29#include <iostream>
30
32
34{
35 using namespace blender::bke::greasepencil;
36
37 const Scene &scene = *CTX_data_scene(&C);
38 Object &ob_orig = *CTX_data_active_object(&C);
39 GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob_orig.data);
41 const Brush &brush = *BKE_paint_brush(&paint);
42 const bool active_layer_only = ((brush.gpencil_settings->flag & GP_BRUSH_ACTIVE_LAYER_ONLY) !=
43 0);
44
45 if (active_layer_only) {
46 /* Apply only to the drawing at the current frame of the active layer. */
47 if (!grease_pencil.has_active_layer()) {
48 return {};
49 }
50 const Layer &active_layer = *grease_pencil.get_active_layer();
52 scene, grease_pencil, active_layer);
53 }
54
55 /* Apply to all editable drawings. */
57}
58
76
77float brush_radius(const Scene &scene, const Brush &brush, const float pressure = 1.0f)
78{
79 float radius = BKE_brush_size_get(&scene, &brush);
80 if (BKE_brush_use_size_pressure(&brush)) {
82 }
83 return radius;
84}
85
86float brush_point_influence(const Scene &scene,
87 const Brush &brush,
88 const float2 &co,
89 const InputSample &sample,
90 const float multi_frame_falloff)
91{
92 const float radius = brush_radius(scene, brush, sample.pressure);
93 /* Basic strength factor from brush settings. */
94 const float brush_pressure = BKE_brush_use_alpha_pressure(&brush) ? sample.pressure : 1.0f;
95 const float influence_base = BKE_brush_alpha_get(&scene, &brush) * brush_pressure *
96 multi_frame_falloff;
97
98 /* Distance falloff. */
99 const int2 mval_i = int2(math::round(sample.mouse_position));
100 const float distance = math::distance(mval_i, int2(co));
101 /* Apply Brush curve. */
102 const float brush_falloff = BKE_brush_curve_strength(&brush, distance, radius);
103
104 return influence_base * brush_falloff;
105}
106
108{
109 int j = verts.size() - 1;
110 bool isect = false;
111 float distance = FLT_MAX;
112 for (int i = 0; i < verts.size(); i++) {
113 /* Based on implementation of #isect_point_poly_v2. */
114 if (((verts[i].y > pt.y) != (verts[j].y > pt.y)) &&
115 (pt.x <
116 (verts[j].x - verts[i].x) * (pt.y - verts[i].y) / (verts[j].y - verts[i].y) + verts[i].x))
117 {
118 isect = !isect;
119 }
120 distance = math::min(distance, math::distance(pt, verts[i]));
121 j = i;
122 }
123 return isect ? 0.0f : distance;
124}
125
126float brush_fill_influence(const Scene &scene,
127 const Brush &brush,
128 const Span<float2> fill_positions,
129 const InputSample &sample,
130 const float multi_frame_falloff)
131{
132 const float radius = brush_radius(scene, brush, sample.pressure);
133 /* Basic strength factor from brush settings. */
134 const float brush_pressure = BKE_brush_use_alpha_pressure(&brush) ? sample.pressure : 1.0f;
135 const float influence_base = BKE_brush_alpha_get(&scene, &brush) * brush_pressure *
136 multi_frame_falloff;
137
138 /* Distance falloff. */
139 const float distance = closest_distance_to_surface_2d(sample.mouse_position, fill_positions);
140 /* Apply Brush curve. */
141 const float brush_falloff = BKE_brush_curve_strength(&brush, distance, radius);
142
143 return influence_base * brush_falloff;
144}
145
147 const Brush &brush,
148 const float2 &mouse_position,
149 const float pressure,
150 const float multi_frame_falloff,
151 const IndexMask &selection,
152 const Span<float2> view_positions,
153 Vector<float> &influences,
154 IndexMaskMemory &memory)
155{
156 if (selection.is_empty()) {
157 return {};
158 }
159
160 const float radius = brush_radius(scene, brush, pressure);
161 const float radius_squared = radius * radius;
162 const float brush_pressure = BKE_brush_use_alpha_pressure(&brush) ? pressure : 1.0f;
163 const float influence_base = BKE_brush_alpha_get(&scene, &brush) * brush_pressure *
164 multi_frame_falloff;
165 const int2 mval_i = int2(math::round(mouse_position));
166
167 Array<float> all_influences(selection.min_array_size());
168 const IndexMask influence_mask = IndexMask::from_predicate(
169 selection, GrainSize(4096), memory, [&](const int point) {
170 /* Distance falloff. */
171 const float distance_squared = math::distance_squared(int2(view_positions[point]), mval_i);
172 if (distance_squared > radius_squared) {
173 all_influences[point] = 0.0f;
174 return false;
175 }
176 /* Apply Brush curve. */
177 const float brush_falloff = BKE_brush_curve_strength(
178 &brush, math::sqrt(distance_squared), radius);
179 all_influences[point] = influence_base * brush_falloff;
180 return all_influences[point] > 0.0f;
181 });
182 influences.resize(influence_mask.size());
183 array_utils::gather(all_influences.as_span(), influence_mask, influences.as_mutable_span());
184
185 return influence_mask;
186}
187
188bool is_brush_inverted(const Brush &brush, const BrushStrokeMode stroke_mode)
189{
190 /* The basic setting is the brush's setting. During runtime, the user can hold down the Ctrl key
191 * to invert the basic behavior. */
192 return bool(brush.flag & BRUSH_DIR_IN) ^ (stroke_mode == BrushStrokeMode::BRUSH_STROKE_INVERT);
193}
194
196 const Object &object,
197 const bke::greasepencil::Layer &layer)
198{
199 const float4x4 view_to_world = float4x4(params.rv3d.viewinv);
200 const float4x4 layer_to_world = layer.to_world_space(object);
201 const float4x4 world_to_layer = math::invert(layer_to_world);
202
203 auto screen_to_world = [=](const float3 &world_pos, const float2 &screen_delta) {
204 const float zfac = ED_view3d_calc_zfac(&params.rv3d, world_pos);
205 float3 world_delta;
206 ED_view3d_win_to_delta(&params.region, screen_delta, zfac, world_delta);
207 return world_delta;
208 };
209
210 switch (params.toolsettings.gp_sculpt.lock_axis) {
211 case GP_LOCKAXIS_VIEW: {
212 const float3 world_normal = view_to_world.z_axis();
213 return [=](const float3 &position, const float2 &screen_delta) {
214 const float3 world_pos = math::transform_point(layer_to_world, position);
215 const float3 world_delta = screen_to_world(world_pos, screen_delta);
216 const float3 layer_delta = math::transform_direction(
217 world_to_layer, world_delta - world_normal * math::dot(world_delta, world_normal));
218 return position + layer_delta;
219 };
220 }
221 case GP_LOCKAXIS_X: {
222 return [=](const float3 &position, const float2 &screen_delta) {
223 const float3 world_pos = math::transform_point(layer_to_world, position);
224 const float3 world_delta = screen_to_world(world_pos, screen_delta);
225 const float3 layer_delta = math::transform_direction(
226 world_to_layer, float3(0.0f, world_delta.y, world_delta.z));
227 return position + layer_delta;
228 };
229 }
230 case GP_LOCKAXIS_Y: {
231 return [=](const float3 &position, const float2 &screen_delta) {
232 const float3 world_pos = math::transform_point(layer_to_world, position);
233 const float3 world_delta = screen_to_world(world_pos, screen_delta);
234 const float3 layer_delta = math::transform_direction(
235 world_to_layer, float3(world_delta.x, 0.0f, world_delta.z));
236 return position + layer_delta;
237 };
238 }
239 case GP_LOCKAXIS_Z: {
240 return [=](const float3 &position, const float2 &screen_delta) {
241 const float3 world_pos = math::transform_point(layer_to_world, position);
242 const float3 world_delta = screen_to_world(world_pos, screen_delta);
243 const float3 layer_delta = math::transform_direction(
244 world_to_layer, float3(world_delta.x, world_delta.y, 0.0f));
245 return position + layer_delta;
246 };
247 }
248 case GP_LOCKAXIS_CURSOR: {
249 const float3 world_normal = params.scene.cursor.matrix<float3x3>().z_axis();
250 return [=](const float3 &position, const float2 &screen_delta) {
251 const float3 world_pos = math::transform_point(layer_to_world, position);
252 const float3 world_delta = screen_to_world(world_pos, screen_delta);
253 const float3 layer_delta = math::transform_direction(
254 world_to_layer, world_delta - world_normal * math::dot(world_delta, world_normal));
255 return position + layer_delta;
256 };
257 }
258 }
259
261 return [](const float3 &, const float2 &) { return float3(); };
262}
263
265 const Scene &scene,
266 Depsgraph &depsgraph,
267 ARegion &region,
268 RegionView3D &rv3d,
269 Object &object,
270 const int layer_index,
271 const int frame_number,
272 const float multi_frame_falloff,
274{
276 GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object.data);
277
278 const bke::greasepencil::Layer &layer = grease_pencil.layer(layer_index);
279 return {*scene.toolsettings,
280 region,
281 rv3d,
282 scene,
283 object,
284 ob_eval,
285 layer,
289 drawing};
290}
291
293 const bool use_masking,
294 IndexMaskMemory &memory)
295{
296
298 params.ob_orig, params.drawing, params.layer_index, memory) :
299 params.drawing.strokes().points_range());
300}
301
303 const bool use_masking,
304 IndexMaskMemory &memory)
305{
306
308 params.ob_orig, params.drawing, params.layer_index, memory) :
309 params.drawing.strokes().curves_range());
310}
311
313 const bool use_masking,
314 IndexMaskMemory &memory)
315{
317 params.ob_orig, params.drawing, params.layer_index, memory) :
318 params.drawing.strokes().curves_range());
319}
320
327
329 const IndexMask &selection)
330{
332
333 Array<float2> view_positions(deformation.positions.size());
334
335 /* Compute screen space positions. */
336 const float4x4 transform = params.layer.to_world_space(params.ob_eval);
337 selection.foreach_index(GrainSize(4096), [&](const int64_t point_i) {
339 &params.region,
340 math::transform_point(transform, deformation.positions[point_i]),
341 view_positions[point_i],
343 if (result != V3D_PROJ_RET_OK) {
344 view_positions[point_i] = float2(0);
345 }
346 });
347
348 return view_positions;
349}
350
352 const IndexMask &selection)
353{
354 const RegionView3D *rv3d = static_cast<RegionView3D *>(params.region.regiondata);
356
357 const VArray<float> radii = params.drawing.radii();
358 Array<float> view_radii(radii.size());
359 /* Compute screen space radii. */
360 const float4x4 transform = params.layer.to_world_space(params.ob_eval);
361 selection.foreach_index(GrainSize(4096), [&](const int64_t point_i) {
362 const float pixel_size = ED_view3d_pixel_size(
363 rv3d, math::transform_point(transform, deformation.positions[point_i]));
364 view_radii[point_i] = radii[point_i] / pixel_size;
365 });
366
367 return view_radii;
368}
369
371{
372 return brush.gpencil_settings != nullptr &&
374}
375
376bool do_vertex_color_fill(const Brush &brush)
377{
378 return brush.gpencil_settings != nullptr &&
380}
381
383{
384 return is_brush_inverted(brush, this->stroke_mode);
385}
386
388{
389 return input_sample.mouse_position - this->prev_mouse_position;
390}
391
393 const bContext &C, FunctionRef<bool(const GreasePencilStrokeParams &params)> fn) const
394{
395 using namespace blender::bke::greasepencil;
396
397 const Scene &scene = *CTX_data_scene(&C);
398 Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(&C);
399 ARegion &region = *CTX_wm_region(&C);
401 Object &object = *CTX_data_active_object(&C);
402 GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object.data);
403
404 std::atomic<bool> changed = false;
406 for (const int64_t i : drawings.index_range()) {
407 const MutableDrawingInfo &info = drawings[i];
409 scene,
410 depsgraph,
411 region,
412 rv3d,
413 object,
414 info.layer_index,
415 info.frame_number,
417 info.drawing);
418 if (fn(params)) {
419 changed = true;
420 }
421 }
422
423 if (changed) {
424 DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
425 WM_event_add_notifier(&C, NC_GEOM | ND_DATA, &grease_pencil);
426 }
427}
428
430 const bContext &C,
431 const GrainSize grain_size,
432 FunctionRef<bool(const GreasePencilStrokeParams &params)> fn) const
433{
434 using namespace blender::bke::greasepencil;
435
436 const Scene &scene = *CTX_data_scene(&C);
437 Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(&C);
438 ARegion &region = *CTX_wm_region(&C);
440 Object &object = *CTX_data_active_object(&C);
441 GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object.data);
442
443 std::atomic<bool> changed = false;
445 threading::parallel_for(drawings.index_range(), grain_size.value, [&](const IndexRange range) {
446 for (const int64_t i : range) {
447 const MutableDrawingInfo &info = drawings[i];
448 GreasePencilStrokeParams params = GreasePencilStrokeParams::from_context(
449 scene,
450 depsgraph,
451 region,
452 rv3d,
453 object,
454 info.layer_index,
455 info.frame_number,
456 info.multi_frame_falloff,
457 info.drawing);
458 if (fn(params)) {
459 changed = true;
460 }
461 }
462 });
463
464 if (changed) {
465 DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
466 WM_event_add_notifier(&C, NC_GEOM | ND_DATA, &grease_pencil);
467 }
468}
469
470void GreasePencilStrokeOperationCommon::foreach_editable_drawing(
471 const bContext &C,
473 const DeltaProjectionFunc &projection_fn)> fn) const
474{
475 using namespace blender::bke::greasepencil;
476
477 const Scene &scene = *CTX_data_scene(&C);
478 Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(&C);
479 ARegion &region = *CTX_wm_region(&C);
481 Object &object = *CTX_data_active_object(&C);
482 Object &object_eval = *DEG_get_evaluated_object(&depsgraph, &object);
483 GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object.data);
484
485 std::atomic<bool> changed = false;
487 threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
488 const Layer &layer = grease_pencil.layer(info.layer_index);
489
490 const GreasePencilStrokeParams params = GreasePencilStrokeParams::from_context(
491 scene,
492 depsgraph,
493 region,
494 rv3d,
495 object,
496 info.layer_index,
497 info.frame_number,
499 info.drawing);
500 const DeltaProjectionFunc projection_fn = get_screen_projection_fn(params, object_eval, layer);
501 if (fn(params, projection_fn)) {
502 changed = true;
503 }
504 });
505
506 if (changed) {
507 DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
508 WM_event_add_notifier(&C, NC_GEOM | ND_DATA, &grease_pencil);
509 }
510}
511
512void GreasePencilStrokeOperationCommon::init_stroke(const bContext &C,
513 const InputSample &start_sample)
514{
516 Brush &brush = *BKE_paint_brush(&paint);
517
518 init_brush(brush);
519
520 this->start_mouse_position = start_sample.mouse_position;
521 this->prev_mouse_position = start_sample.mouse_position;
522}
523
524void GreasePencilStrokeOperationCommon::stroke_extended(const InputSample &extension_sample)
525{
526 this->prev_mouse_position = extension_sample.mouse_position;
527}
528
529} // namespace blender::ed::sculpt_paint::greasepencil
bool BKE_brush_use_alpha_pressure(const Brush *brush)
Definition brush.cc:1096
int BKE_brush_size_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1075
float BKE_brush_curve_strength(eBrushCurvePreset preset, const CurveMapping *cumap, float distance, float brush_radius)
Definition brush.cc:1388
bool BKE_brush_use_size_pressure(const Brush *brush)
Definition brush.cc:1091
void BKE_brush_init_gpencil_settings(Brush *brush)
Definition brush.cc:563
float BKE_brush_alpha_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1153
float BKE_curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value)
void BKE_curvemapping_init(CurveMapping *cumap)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(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
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ GP_BRUSH_ACTIVE_LAYER_ONLY
@ BRUSH_DIR_IN
@ GPPAINT_MODE_STROKE
@ GPPAINT_MODE_FILL
@ GPPAINT_MODE_BOTH
@ GP_LOCKAXIS_X
@ GP_LOCKAXIS_VIEW
@ GP_LOCKAXIS_Y
@ GP_LOCKAXIS_Z
@ GP_LOCKAXIS_CURSOR
@ V3D_PROJ_TEST_NOP
Definition ED_view3d.hh:266
float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
eV3DProjStatus
Definition ED_view3d.hh:242
@ V3D_PROJ_RET_OK
Definition ED_view3d.hh:243
void ED_view3d_win_to_delta(const ARegion *region, const float xy_delta[2], float zfac, float r_out[3])
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3])
eV3DProjStatus ED_view3d_project_float_global(const ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
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 NC_GEOM
Definition WM_types.hh:360
#define ND_DATA
Definition WM_types.hh:475
Span< T > as_span() const
Definition BLI_array.hh:232
IndexRange index_range() const
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
void foreach_editable_drawing(const bContext &C, FunctionRef< bool(const GreasePencilStrokeParams &params)> fn) const
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
const Depsgraph * depsgraph
static float verts[][3]
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object *ob_eval, const Object &ob_orig, int layer_index, int frame)
IndexMask retrieve_editable_and_selected_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
IndexMask retrieve_editable_and_selected_fill_strokes(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
IndexMask retrieve_editable_and_selected_points(Object &object, const bke::greasepencil::Drawing &drawing, int layer_index, IndexMaskMemory &memory)
Vector< MutableDrawingInfo > retrieve_editable_drawings_from_layer_with_falloff(const Scene &scene, GreasePencil &grease_pencil, const blender::bke::greasepencil::Layer &layer)
Vector< MutableDrawingInfo > retrieve_editable_drawings_with_falloff(const Scene &scene, GreasePencil &grease_pencil)
bool is_brush_inverted(const Brush &brush, BrushStrokeMode stroke_mode)
float closest_distance_to_surface_2d(const float2 pt, const Span< float2 > verts)
Array< float > calculate_view_radii(const GreasePencilStrokeParams &params, const IndexMask &selection)
Vector< ed::greasepencil::MutableDrawingInfo > get_drawings_for_painting(const bContext &C)
IndexMask point_selection_mask(const GreasePencilStrokeParams &params, const bool use_masking, IndexMaskMemory &memory)
Array< float2 > calculate_view_positions(const GreasePencilStrokeParams &params, const IndexMask &selection)
IndexMask fill_selection_mask(const GreasePencilStrokeParams &params, const bool use_masking, IndexMaskMemory &memory)
IndexMask brush_point_influence_mask(const Scene &scene, const Brush &brush, const float2 &mouse_position, float pressure, float multi_frame_falloff, const IndexMask &selection, Span< float2 > view_positions, Vector< float > &influences, IndexMaskMemory &memory)
float brush_point_influence(const Scene &scene, const Brush &brush, const float2 &co, const InputSample &sample, float multi_frame_falloff)
IndexMask stroke_selection_mask(const GreasePencilStrokeParams &params, const bool use_masking, IndexMaskMemory &memory)
float brush_fill_influence(const Scene &scene, const Brush &brush, Span< float2 > fill_positions, const InputSample &sample, float multi_frame_falloff)
bke::crazyspace::GeometryDeformation get_drawing_deformation(const GreasePencilStrokeParams &params)
DeltaProjectionFunc get_screen_projection_fn(const GreasePencilStrokeParams &params, const Object &object, const bke::greasepencil::Layer &layer)
float brush_radius(const Scene &scene, const Brush &brush, float pressure)
std::function< float3(const float3 position, const float2 &screen_delta)> DeltaProjectionFunc
T sqrt(const T &a)
T distance(const T &a, const T &b)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
T min(const T &a, const T &b)
CartesianBasis invert(const CartesianBasis &basis)
T distance_squared(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
T round(const T &a)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void parallel_for_each(Range &&range, const Function &function)
Definition BLI_task.hh:58
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:95
MatBase< float, 4, 4 > float4x4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
float distance(float a, float b)
BrushStrokeMode
@ BRUSH_STROKE_INVERT
#define FLT_MAX
Definition stdcycles.h:14
__int64 int64_t
Definition stdint.h:89
struct CurveMapping * curve_sensitivity
struct CurveMapping * curve_strength
struct CurveMapping * curve_jitter
struct CurveMapping * curve_rand_pressure
struct CurveMapping * curve_rand_strength
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct CurveMapping * curve_rand_uv
struct CurveMapping * curve_rand_value
struct CurveMapping * curve
struct BrushGpencilSettings * gpencil_settings
static GreasePencilStrokeParams from_context(const Scene &scene, Depsgraph &depsgraph, ARegion &region, RegionView3D &rv3d, Object &object, int layer_index, int frame_number, float multi_frame_falloff, bke::greasepencil::Drawing &drawing)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)