75 std::optional<RandomNumberGenerator>
rng;
152 if (stroke && brush) {
195 immUniform2f(
"viewport_size", viewport_size[2], viewport_size[3]);
198 const float alpha = float(
paint->paint_cursor_col[3]) / 255.0f;
311 const float mouse_init[2],
313 const float pressure,
315 bool *r_location_is_set)
319 bool location_sampled =
false;
320 bool location_success =
false;
323 bool is_dry_run =
false;
324 bool do_random =
false;
325 bool do_random_mask =
false;
326 *r_location_is_set =
false;
385 do_random_mask =
true;
415 location_sampled =
true;
416 location_success =
true;
417 *r_location_is_set =
true;
459 if ((do_random || do_random_mask) && !stroke->
rng) {
471 if (do_random_mask) {
478 if (!location_sampled) {
481 location_success =
true;
482 *r_location_is_set =
true;
485 location_success =
true;
490 location_success =
true;
495 return location_success && !is_dry_run;
522 const float pressure,
524 float r_mouse_out[2])
538 if (factor != 1.0f) {
566 if (tablet && (pressure >= 0.99f) &&
579 if (tablet && (pressure < 0.0002f) &&
593 float3 world_space_position;
599 stroke->
vc.
obact->object_to_world(), world_space_position);
611 bool is_location_is_set;
613 C, brush, mode, stroke, mval, mouse_out, pressure, location, &is_location_is_set);
614 if (is_location_is_set) {
622 bool add_step =
true;
625 const float dash = float(dash_samples) / float(brush.
dash_samples);
677 r_pressure =
sample->pressure;
686 const float size_pressure,
687 const float spacing_pressure)
693 float size_clamp = 0.0f;
698 stroke->
vc, *scene, brush, last_object_space_position, size_pressure);
710 spacing = spacing * (1.5f - spacing_pressure);
728 return max_ff(FLT_EPSILON, size_clamp * spacing / 50.0f);
730 return max_ff(stroke->
zoom_2d, size_clamp * spacing / 50.0f);
739 const float clamped_spacing =
max_ff(spacing, 0.1f);
741 const int n = 100 / clamped_spacing;
742 const float h = clamped_spacing / 50.0f;
743 const float x0 =
x - 1;
746 for (
int i = 0;
i < n;
i++) {
747 float xx =
fabsf(x0 +
i * h);
759 const float spacing = br.
spacing * factor;
765 constexpr int m = 10;
768 for (
int i = 0;
i < m;
i++) {
771 max = std::max(overlap,
max);
783 const float pressure,
784 const float pressure_delta,
792 const float q = s * pressure_delta / (2.0f *
length);
793 const float pressure_fac = (1.0f + q) / (1.0f - q);
796 const float new_size_pressure = stroke->
last_pressure * pressure_fac;
800 C, scene, stroke, last_size_pressure, pressure);
802 C, scene, stroke, new_size_pressure, pressure);
804 return 0.5f * (last_spacing + new_spacing);
817 const float final_pressure)
829 float3 world_space_position_delta;
831 if (use_scene_spacing) {
832 float3 world_space_position;
834 C, world_space_position, final_mouse, stroke->
original);
836 world_space_position);
844 world_space_position_delta = {0.0f, 0.0f, 0.0f};
853 float pressure_delta = final_pressure - stroke->
last_pressure;
858 C, scene, stroke, pressure, pressure_delta,
length);
863 if (use_scene_spacing) {
864 float3 final_world_space_position;
865 world_space_position_delta =
math::normalize(world_space_position_delta);
866 final_world_space_position = world_space_position_delta * spacing +
878 spacing / no_pressure_spacing);
906 const int event_type)
909 PaintStroke *stroke = MEM_new<PaintStroke>(__func__);
933 stroke->
zoom_2d = std::max(zoomx, zoomy);
992 if (stroke ==
nullptr) {
1000 if (stroke->
timer) {
1026 stroke->
redraw(
C, stroke,
true);
1030 stroke->
done(
C, stroke);
1166#define PAINT_STROKE_MODAL_CANCEL 1
1174 static const char *name =
"Paint Stroke Modal";
1187 const int input_samples,
1190 const float pressure)
1197 sample->pressure = pressure;
1232 const float spacing,
1233 float *length_residue,
1247 float3 world_space_position_delta;
1248 float3 world_space_position_old;
1252 if (use_scene_spacing) {
1254 C, world_space_position_old, old_pos, stroke->
original);
1256 float3 world_space_position_new;
1258 C, world_space_position_new, new_pos, stroke->
original);
1261 world_space_position_old);
1263 world_space_position_new);
1265 world_space_position_delta = world_space_position_new - world_space_position_old;
1271 world_space_position_delta = {0.0f, 0.0f, 0.0f};
1279 mouse_delta = new_pos - old_pos;
1291 float spacing_final = spacing - *length_residue;
1292 length += *length_residue;
1293 *length_residue = 0.0;
1296 if (use_scene_spacing) {
1297 world_space_position_delta =
math::normalize(world_space_position_delta);
1298 const float3 final_world_space_position = world_space_position_delta * spacing_final +
1299 world_space_position_old;
1312 spacing_final = spacing;
1319 *length_residue =
length;
1359 float length_residue = 0.0f;
1364 bool do_rake =
false;
1366 for (
int j = 0; j < 2; j++) {
1369 pcp_next->bez.vec[0][j],
1370 pcp_next->bez.vec[1][j],
1380 for (
int j = 0; j < 2; j++) {
1383 pcp_next->bez.vec[0][j],
1384 pcp_next->bez.vec[1][j],
1393 const float rotation =
atan2f(tangents[2 * j + 1], tangents[2 * j]) + float(0.5f *
M_PI);
1412 C, op, stroke, spacing, &length_residue,
data + 2 * j,
data + 2 * (j + 1));
1417 C, op, stroke, spacing, &length_residue,
data + 2 * j,
data + 2 * (j + 1));
1467 bool first_dab =
false;
1468 bool first_modal =
false;
1469 bool redraw =
false;
1499 stroke->
tilt =
event->tablet.tilt;
1502#ifdef WITH_INPUT_NDOF
1515 *stroke_p =
nullptr;
1599 mouse = {float(event->
mval[0]), float(event->
mval[1])};
1603 *stroke_p =
nullptr;
1610 *stroke_p =
nullptr;
1621 mouse = {float(event->
mval[0]), float(event->
mval[1])};
1633 else if (first_modal ||
1678 if (redraw && stroke->
redraw) {
1679 stroke->
redraw(
C, stroke,
false);
1704 if (override_location) {
1760 stroke->
mode_data = std::move(mode_data);
void BKE_brush_jitter_pos(const Scene &scene, const Brush &brush, const float pos[2], float jitterpos[2])
bool BKE_brush_use_alpha_pressure(const Brush *brush)
void BKE_brush_randomize_texture_coords(UnifiedPaintSettings *ups, bool mask)
int BKE_brush_size_get(const Scene *scene, 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)
int BKE_brush_input_samples_get(const Scene *scene, 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)
ToolSettings * CTX_data_tool_settings(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)
void BKE_paint_set_overlay_override(eOverlayFlags flag)
void paint_update_brush_rake_rotation(UnifiedPaintSettings &ups, const Brush &brush, float rotation)
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Paint * BKE_paint_get_active_from_context(const bContext *C)
Brush * BKE_paint_brush(Paint *paint)
bool paint_calculate_rake_rotation(UnifiedPaintSettings &ups, const Brush &brush, const float mouse_pos[2], PaintMode paint_mode, bool stroke_has_started)
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_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_blend(eGPUBlend blend)
void GPU_line_smooth(bool enable)
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 float average(const float2 a)
ccl_device_inline float2 fabs(const float2 a)
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)
float object_space_radius_get(const ViewContext &vc, const Scene &scene, const Brush &brush, const float3 &location, const float scale_factor)
static void paint_draw_smooth_cursor(bContext *C, const blender::int2 &xy, const blender::float2 &, void *customdata)
bool paint_supports_texture(PaintMode mode)
static const bToolRef * brush_tool_get(const bContext *C)
void(*)(const bContext *C, PaintStroke *stroke, bool final) StrokeRedraw
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_jitter_pos(Scene &scene, const PaintStroke &stroke, const PaintMode mode, const Brush &brush, const float pressure, const float mval[2], float r_mouse_out[2])
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 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)
static void paint_draw_line_cursor(bContext *C, const blender::int2 &xy, const blender::float2 &, void *customdata)
static float paint_space_stroke_spacing_variable(bContext *C, const Scene *scene, PaintStroke *stroke, const float pressure, const float pressure_delta, const float length)
bool paint_brush_cursor_poll(bContext *C)
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 float paint_space_stroke_spacing(const bContext *C, const Scene *scene, PaintStroke *stroke, const float size_pressure, const float spacing_pressure)
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)
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)
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
char curves_sculpt_brush_type
struct PaintCurve * paint_curve
const ColorSpace * colorspace
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
float average_stroke_accum[3]
char do_linear_conversion
float anchored_initial_mouse[2]
float initial_pixel_radius
int average_stroke_counter
float size_pressure_value
const ColorSpaceHandle * colorspace
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)