19#ifndef DT_IOP_DRAWLAYER_BRUSH_PROFILE_H
20#define DT_IOP_DRAWLAYER_BRUSH_PROFILE_H
33 return fminf(fmaxf(
v, 0.0f), 1.0f);
45 const float smooth =
t *
t * (3.0f - 2.0f *
t);
56 const float inner,
const float w,
63 const float q_u = 0.5f * u * u - (2.0f / 3.0f) * u * u * u + 0.25f * u * u * u * u;
64 const float q_i = 0.5f * inner * inner - (2.0f / 3.0f) * inner * inner * inner
65 + 0.25f * inner * inner * inner * inner;
66 return base + (q_u - q_i) / (w * w);
71 const float s2 = s * s;
72 const float s3 = s2 * s;
73 const float s4 = s2 * s2;
74 const float s5 = s4 * s;
75 const float delta = w * (inner * (s - s3 + 0.5f * s4)
76 + w * (0.5f * s2 - 0.75f * s4 + 0.4f * s5));
82 const float l_u = 0.5f * u * u - (1.0f / 3.0f) * u * u * u;
83 const float l_i = 0.5f * inner * inner - (1.0f / 3.0f) * inner * inner * inner;
84 return base + (l_u - l_i) / w;
118 if(
out->gaussian)
return;
121 if(hardness >= 1.0f - 1e-6f)
126 const float min_inner = 0.5f / fmaxf(dab->
radius, 0.5f);
128 out->width = fmaxf(1.0f -
out->inner, 1e-6f);
135 if(norm2 >= 1.0f)
return 0.0f;
139 const float radius = sqrtf(norm2);
140 if(radius < 0.5f)
return 1.0f - 6.0f * norm2 + 6.0f * norm2 * radius;
141 const float inv_r = 1.0f - radius;
142 return 2.0f * inv_r * inv_r * inv_r;
145 if(pc->
flat)
return 1.0f;
147 const float radius = sqrtf(norm2);
148 if(radius <= pc->inner)
return 1.0f;
165 const float radius = sqrtf(norm2);
166 if(radius < 0.5f)
return 1.0f - 6.0f * norm2 + 6.0f * norm2 * radius;
167 const float inv_r = 1.0f - radius;
168 return 2.0f * inv_r * inv_r * inv_r;
172 if(hardness >= 1.0f - 1e-6f)
return 1.0f;
174 const float min_inner = 0.5f / fmaxf(dab->
radius, 0.5f);
176 const float radius = sqrtf(norm2);
177 if(radius <= inner)
return 1.0f;
191 if(u <= 0.0f)
return 0.0f;
195 if(u <= 0.5f)
return 0.5f * u * u - 1.5f * u * u * u * u + 1.2f * u * u * u * u * u;
196 const float u2 = u * u;
197 const float u3 =
u2 * u;
198 const float u4 =
u2 *
u2;
199 const float u5 = u4 * u;
200 return u2 - 2.0f * u3 + 1.5f * u4 - 0.4f * u5 - 0.0125f;
204 if(hardness >= 1.0f - 1e-6f)
return 0.5f * u * u;
205 const float min_inner = 0.5f / fmaxf(dab->
radius, 0.5f);
207 if(u <= inner)
return 0.5f * u * u;
208 const float w = fmaxf(1.0f - inner, 1e-6f);
209 const float base = 0.5f * inner * inner;
Dab-level brush rasterization API for drawlayer.
@ DT_DRAWLAYER_BRUSH_SHAPE_SIGMOIDAL
@ DT_DRAWLAYER_BRUSH_SHAPE_GAUSSIAN
@ DT_DRAWLAYER_BRUSH_SHAPE_LINEAR
@ DT_DRAWLAYER_BRUSH_SHAPE_QUADRATIC
static float dt_drawlayer_brush_profile_eval(const dt_drawlayer_brush_dab_t *dab, const float norm2)
Evaluate normalized brush profile at squared normalized radius.
static float dt_drawlayer_brush_mass_primitive_eval(const dt_drawlayer_brush_dab_t *dab, const float u_in)
Evaluate radial mass primitive from center to normalized radius u_in.
static float dt_drawlayer_brush_profile_clamp01(const float v)
Clamp scalar value to [0, 1].
static float dt_drawlayer_brush_transition_mass_primitive_eval(const int shape, const float u, const float inner, const float w, const float base)
Evaluate integrated mass primitive of transition zone by shape.
static float dt_drawlayer_brush_profile_eval_fast(const dt_drawlayer_brush_profile_const_t *pc, const float norm2)
Evaluate the profile against pre-resolved dab constants.
static void dt_drawlayer_brush_profile_prepare(const dt_drawlayer_brush_dab_t *dab, dt_drawlayer_brush_profile_const_t *out)
Resolve the per-dab half of the profile once.
static float dt_drawlayer_brush_transition_profile_eval(const int shape, const float t, const float inv_t)
Evaluate normalized edge-falloff transition profile by shape.
const dt_colormatrix_t dt_aligned_pixel_t out
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Fully resolved input dab descriptor.
The part of the profile that depends on the dab and not on the pixel.