13#include "fmt/format.h"
79 std::optional<RandomNumberGenerator>
rng;
156 if (stroke && brush) {
199 immUniform2f(
"viewport_size", viewport_size[2], viewport_size[3]);
314 const float mouse_init[2],
316 const float pressure,
318 bool *r_location_is_set)
323 bool location_sampled =
false;
324 bool location_success =
false;
327 bool is_dry_run =
false;
328 bool do_random =
false;
329 bool do_random_mask =
false;
330 *r_location_is_set =
false;
391 do_random_mask =
true;
422 location_sampled =
true;
423 location_success =
true;
424 *r_location_is_set =
true;
466 if ((do_random || do_random_mask) && !stroke->
rng) {
478 if (do_random_mask) {
485 if (!location_sampled) {
488 location_success =
true;
489 *r_location_is_set =
true;
492 location_success =
true;
497 location_success =
true;
502 return location_success && !is_dry_run;
528 const float pressure,
530 float r_mouse_out[2])
544 if (factor != 1.0f) {
571 if (tablet && (pressure >= 0.99f) &&
584 if (tablet && (pressure < 0.0002f) &&
598 float3 world_space_position;
604 stroke->
vc.
obact->object_to_world(), world_space_position);
616 bool is_location_is_set;
618 C, brush, mode, stroke, mval, mouse_out, pressure, location, &is_location_is_set);
619 if (is_location_is_set) {
627 bool add_step =
true;
682 r_pressure =
sample->pressure;
690 const float size_factor,
691 const float pressure)
697 float size_clamp = 0.0f;
702 stroke->
vc, *
paint, brush, last_object_space_position, size_factor);
714 spacing = spacing * (1.5f - pressure);
732 return max_ff(FLT_EPSILON, size_clamp * spacing / 50.0f);
734 return max_ff(stroke->
zoom_2d, size_clamp * spacing / 50.0f);
750 const float clamped_spacing =
max_ff(spacing, 0.1f);
752 const int n = 100 / clamped_spacing;
753 const float h = clamped_spacing / 50.0f;
754 const float x0 =
x - 1;
757 for (
int i = 0;
i < n;
i++) {
758 float xx =
fabsf(x0 +
i * h);
770 const float spacing = br.
spacing * factor;
776 constexpr int m = 10;
779 for (
int i = 0;
i < m;
i++) {
782 max = std::max(overlap,
max);
793 const float pressure,
794 const float pressure_delta,
803 const float q = s * pressure_delta / (2.0f *
length);
804 const float pressure_fac = (1.0f + q) / (1.0f - q);
815 return 0.5f * (last_spacing + new_spacing);
828 const float final_pressure)
839 float3 world_space_position_delta;
841 if (use_scene_spacing) {
842 float3 world_space_position;
844 C, world_space_position, final_mouse, stroke->
original);
846 world_space_position);
854 world_space_position_delta = {0.0f, 0.0f, 0.0f};
863 float pressure_delta = final_pressure - stroke->
last_pressure;
868 C, stroke, pressure, pressure_delta,
length);
873 if (use_scene_spacing) {
874 float3 final_world_space_position;
875 world_space_position_delta =
math::normalize(world_space_position_delta);
876 final_world_space_position = world_space_position_delta * spacing +
888 *stroke->
brush, spacing / no_pressure_spacing);
909 return (
G.debug_value == 887);
921 const int event_type)
924 PaintStroke *stroke = MEM_new<PaintStroke>(__func__);
949 stroke->
zoom_2d = std::max(zoomx, zoomy);
1009 if (stroke ==
nullptr) {
1017 if (stroke->
timer) {
1046 stroke->
redraw(
C, stroke,
true);
1050 stroke->
done(
C, stroke);
1184#define PAINT_STROKE_MODAL_CANCEL 1
1192 static const char *
name =
"Paint Stroke Modal";
1205 const int input_samples,
1208 const float pressure)
1215 sample->pressure = pressure;
1250 const float spacing,
1251 float *length_residue,
1265 float3 world_space_position_delta;
1266 float3 world_space_position_old;
1270 if (use_scene_spacing) {
1272 C, world_space_position_old, old_pos, stroke->
original);
1274 float3 world_space_position_new;
1276 C, world_space_position_new, new_pos, stroke->
original);
1279 world_space_position_old);
1281 world_space_position_new);
1283 world_space_position_delta = world_space_position_new - world_space_position_old;
1289 world_space_position_delta = {0.0f, 0.0f, 0.0f};
1297 mouse_delta = new_pos - old_pos;
1309 float spacing_final = spacing - *length_residue;
1310 length += *length_residue;
1311 *length_residue = 0.0;
1314 if (use_scene_spacing) {
1315 world_space_position_delta =
math::normalize(world_space_position_delta);
1316 const float3 final_world_space_position = world_space_position_delta * spacing_final +
1317 world_space_position_old;
1330 spacing_final = spacing;
1337 *length_residue =
length;
1378 float length_residue = 0.0f;
1383 bool do_rake =
false;
1385 for (
int j = 0; j < 2; j++) {
1388 pcp_next->bez.vec[0][j],
1389 pcp_next->bez.vec[1][j],
1399 for (
int j = 0; j < 2; j++) {
1402 pcp_next->bez.vec[0][j],
1403 pcp_next->bez.vec[1][j],
1412 const float rotation =
atan2f(tangents[2 * j + 1], tangents[2 * j]) +
float(0.5f *
M_PI);
1433 no_pressure_spacing,
1436 data + 2 * (j + 1));
1441 C, op, stroke, no_pressure_spacing, &length_residue,
data + 2 * j,
data + 2 * (j + 1));
1491 bool first_dab =
false;
1492 bool first_modal =
false;
1493 bool redraw =
false;
1507 std::string msg = fmt::format(
"Tablet Pressure: {:.4f}", pressure);
1528 stroke->
tilt =
event->tablet.tilt;
1531#ifdef WITH_INPUT_NDOF
1544 *stroke_p =
nullptr;
1636 *stroke_p =
nullptr;
1643 *stroke_p =
nullptr;
1666 else if (first_modal ||
1711 if (redraw && stroke->
redraw) {
1712 stroke->
redraw(
C, stroke,
false);
1758 if (override_location) {
1811 stroke->
mode_data = std::move(mode_data);
bool BKE_brush_use_alpha_pressure(const Brush *brush)
float BKE_brush_curve_strength(eBrushCurvePreset preset, const CurveMapping *cumap, float distance, float brush_radius)
bool BKE_brush_use_size_pressure(const Brush *brush)
float BKE_brush_radius_get(const Paint *paint, const Brush *brush)
void BKE_brush_randomize_texture_coords(Paint *paint, bool mask)
void BKE_brush_jitter_pos(const Paint &paint, const Brush &brush, const float pos[2], float jitterpos[2])
int BKE_brush_input_samples_get(const Paint *paint, const Brush *brush)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(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)
wmWindowManager * CTX_wm_manager(const bContext *C)
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
void BKE_curve_forward_diff_tangent_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
ImBuf * BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool)
void BKE_image_pool_release_ibuf(Image *ima, ImBuf *ibuf, ImagePool *pool)
bool paint_calculate_rake_rotation(Paint &paint, const Brush &brush, const float mouse_pos[2], PaintMode paint_mode, bool stroke_has_started)
void BKE_paint_set_overlay_override(eOverlayFlags flag)
void paint_update_brush_rake_rotation(Paint &paint, const Brush &brush, float rotation)
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Paint * BKE_paint_get_active_from_paintmode(Scene *sce, PaintMode mode)
Paint * BKE_paint_get_active_from_context(const bContext *C)
Brush * BKE_paint_brush(Paint *paint)
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
MINLINE float max_ff(float a, float b)
MINLINE float square_f(float a)
void mul_m4_v3(const float M[4][4], float r[3])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float normalize_v2(float n[2])
MINLINE void zero_v3(float r[3])
Utility defines for timing/benchmarks.
#define TIMEIT_START_AVERAGED(var)
#define TIMEIT_END_AVERAGED(var)
@ SCULPT_BRUSH_TYPE_THUMB
@ SCULPT_BRUSH_TYPE_BOUNDARY
@ SCULPT_BRUSH_TYPE_CLOTH
@ SCULPT_BRUSH_TYPE_SNAKE_HOOK
@ SCULPT_BRUSH_TYPE_ELASTIC_DEFORM
@ SCULPT_BRUSH_TYPE_ROTATE
@ IMAGE_PAINT_BRUSH_TYPE_FILL
@ IMAGE_PAINT_BRUSH_TYPE_CLONE
@ BRUSH_CLOTH_DEFORM_GRAB
@ CURVES_SCULPT_BRUSH_TYPE_ADD
@ CURVES_SCULPT_BRUSH_TYPE_DENSITY
Object is a sort of wrapper for general info.
#define PAINT_MAX_INPUT_SAMPLES
@ TOOLREF_FLAG_USE_BRUSHES
void ED_workspace_status_text(bContext *C, const char *str)
void ED_view3d_project_v2(const ARegion *region, const float world[3], float r_region_co[2])
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
@ GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR
@ GPU_SHADER_3D_UNIFORM_COLOR
void GPU_line_smooth(bool enable)
void GPU_blend(GPUBlend blend)
void GPU_viewport_size_get_f(float coords[4])
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
#define RNA_BEGIN(sptr, itemptr, propname)
BMesh const char void * data
BPy_StructRNA * depsgraph
static T sum(const btAlignedObjectArray< T > &items)
static RandomNumberGenerator from_random_seed()
float length(VecOp< float, D >) RET
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
ccl_device_inline float2 fabs(const float2 a)
bool supports_size_pressure(const Brush &brush)
bool is_cloth_deform_brush(const Brush &brush)
bool stroke_get_location_bvh(bContext *C, float out[3], const float mval[2], const bool force_original)
void paint_stroke_jitter_pos(const PaintStroke &stroke, PaintMode mode, const Brush &brush, float pressure, const float mval[2], float r_mouse_out[2])
static float paint_space_stroke_spacing_variable(bContext *C, PaintStroke *stroke, const float pressure, const float pressure_delta, const float length)
static void paint_draw_line_cursor(bContext *, const blender::int2 &xy, const blender::float2 &, void *customdata)
static void paint_draw_smooth_cursor(bContext *C, const blender::int2 &xy, const blender::float2 &, void *customdata)
static float paint_space_stroke_spacing(const bContext *C, PaintStroke *stroke, const float size_factor, const float pressure)
bool paint_supports_texture(PaintMode mode)
static const bToolRef * brush_tool_get(const bContext *C)
void(*)(const bContext *C, PaintStroke *stroke, bool final) StrokeRedraw
static float paint_space_stroke_spacing_no_pressure(const bContext *C, PaintStroke *stroke)
wmOperatorStatus paint_stroke_exec(bContext *C, wmOperator *op, PaintStroke *stroke)
static int paint_space_stroke(bContext *C, wmOperator *op, PaintStroke *stroke, const float2 final_mouse, const float final_pressure)
bool paint_stroke_started(PaintStroke *stroke)
static bool sculpt_is_grab_tool(const Brush &br)
static float paint_stroke_overlapped_curve(const Brush &br, const float x, const float spacing)
static bool paint_stroke_use_jitter(const PaintMode mode, const Brush &brush, const bool invert)
void paint_stroke_cancel(bContext *C, wmOperator *op, PaintStroke *stroke)
bool paint_supports_dynamic_tex_coords(const Brush &br, PaintMode mode)
bool paint_supports_dynamic_size(const Brush &br, PaintMode mode)
static void stroke_done(const bContext *C, PaintStroke *stroke)
static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *stroke)
bool paint_stroke_flipped(PaintStroke *stroke)
static void paint_stroke_sample_average(const PaintStroke *stroke, PaintSample *average)
static bool print_pressure_status_enabled()
static float paint_stroke_integrate_overlap(const Brush &br, const float factor)
wmOperatorStatus paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintStroke **stroke_p)
bool(*)(bContext *C, float location[3], const float mouse[2], bool force_original) StrokeGetLocation
static bool paint_stroke_use_dash(const Brush &brush)
ViewContext * paint_stroke_view_context(PaintStroke *stroke)
bool paint_brush_cursor_poll(bContext *C)
float object_space_radius_get(const ViewContext &vc, const Paint &paint, const Brush &brush, const float3 &location, const float scale_factor)
static bool image_paint_brush_type_require_inbetween_mouse_events(const Brush &brush, const PaintMode mode)
static void paint_stroke_line_end(bContext *C, wmOperator *op, PaintStroke *stroke, const float2 mouse)
static bool image_paint_brush_type_require_location(const Brush &brush, const PaintMode mode)
static void paint_stroke_line_constrain(PaintStroke *stroke, float2 &mouse)
static bool curves_sculpt_brush_uses_spacing(const eBrushCurvesSculptType tool)
wmKeyMap * paint_stroke_modal_keymap(wmKeyConfig *keyconf)
bool(*)(bContext *C, wmOperator *op, const float mouse[2]) StrokeTestStart
bool paint_brush_update(bContext *C, const Brush &brush, PaintMode mode, PaintStroke *stroke, const float mouse_init[2], float mouse[2], float pressure, float r_location[3], bool *r_location_is_set)
void * paint_stroke_mode_data(PaintStroke *stroke)
void(*)(bContext *C, wmOperator *op, PaintStroke *stroke, PointerRNA *itemptr) StrokeUpdateStep
float paint_stroke_distance_get(PaintStroke *stroke)
static void paint_stroke_add_sample(PaintStroke *stroke, const int input_samples, const float x, const float y, const float pressure)
bool paint_space_stroke_enabled(const Brush &br, PaintMode mode)
static bool paint_smooth_stroke(PaintStroke *stroke, const PaintSample *sample, const PaintMode mode, float2 &r_mouse, float &r_pressure)
void paint_stroke_free(bContext *C, wmOperator *op, PaintStroke *stroke)
PaintStroke * paint_stroke_new(bContext *C, wmOperator *op, StrokeGetLocation get_location, StrokeTestStart test_start, StrokeUpdateStep update_step, StrokeRedraw redraw, StrokeDone done, int event_type)
static bool paint_stroke_use_scene_spacing(const Brush &brush, const PaintMode mode)
static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, PaintStroke *stroke, const float2 mval, float pressure)
static void paint_line_strokes_spacing(bContext *C, wmOperator *op, PaintStroke *stroke, const float spacing, float *length_residue, const float2 old_pos, const float2 new_pos)
void(*)(const bContext *C, PaintStroke *stroke) StrokeDone
static bool image_paint_brush_type_raycast_original(const Brush &brush, PaintMode)
bool paint_stroke_inverted(PaintStroke *stroke)
bool paint_brush_tool_poll(bContext *C)
void paint_stroke_set_mode_data(PaintStroke *stroke, std::unique_ptr< PaintModeData > mode_data)
bool paint_supports_smooth_stroke(PaintStroke *stroke, const Brush &br, PaintMode mode)
T length(const VecBase< T, Size > &a)
QuaternionBase< T > normalize_and_get_length(const QuaternionBase< T > &q, T &out_length)
T interpolate(const T &a, const T &b, const FactorT &t)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
T distance_squared(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
blender::VecBase< uint8_t, 4 > uchar4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
bool get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
#define PAINT_CURVE_NUM_SEGMENTS
#define PAINT_STROKE_MODAL_CANCEL
void RNA_collection_clear(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
int RNA_enum_get(PointerRNA *ptr, const char *name)
float smooth_stroke_factor
struct CurveMapping * curve_jitter
struct CurveMapping * curve_distance_falloff
char curves_sculpt_brush_type
struct PaintCurve * paint_curve
struct CurveMapping * curve_size
struct CurveMapping * curve_strength
const ColorSpace * colorspace
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
PaintRuntimeHandle * runtime
float initial_pixel_radius
blender::float2 anchored_initial_mouse
blender::float2 tex_mouse
float size_pressure_value
blender::float2 last_rake
const blender::ocio::ColorSpace * colorspace
blender::float2 mask_tex_mouse
bool do_linear_conversion
blender::float3 last_location
blender::float3 average_stroke_accum
int average_stroke_counter
float cached_size_pressure
UnifiedPaintSettings * ups
StrokeUpdateStep update_step
std::unique_ptr< PaintModeData > mode_data
StrokeGetLocation get_location
StrokeTestStart test_start
float3 last_world_space_position
float last_tablet_event_pressure
float3 last_scene_spacing_delta
std::optional< RandomNumberGenerator > rng
PaintSample samples[PAINT_MAX_INPUT_SAMPLES]
float2 last_mouse_position
wmEventModifierFlag modifier
void(* cancel)(bContext *C, wmOperator *op)
struct wmOperatorType * type
void WM_paint_cursor_tag_redraw(wmWindow *win, ARegion *)
float WM_event_tablet_data(const wmEvent *event, bool *r_pen_flip, float r_tilt[2])
bool WM_event_is_tablet(const wmEvent *event)
#define ISMOUSE_MOTION(event_type)
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
wmKeyMap * WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
bool WM_paint_cursor_end(wmPaintCursor *handle)
wmPaintCursor * WM_paint_cursor_activate(short space_type, short region_type, bool(*poll)(bContext *C), wmPaintCursorDraw draw, void *customdata)
wmTimer * WM_event_timer_add(wmWindowManager *wm, wmWindow *win, const wmEventType event_type, const double time_step)
void WM_event_timer_remove(wmWindowManager *wm, wmWindow *, wmTimer *timer)