Skip to content

Commit 635975d

Browse files
committed
use pigment mode for smudge sampling
blend additive and subtractive methods limit sampling to small percentage of pixels
1 parent d180edd commit 635975d

File tree

6 files changed

+65
-40
lines changed

6 files changed

+65
-40
lines changed

brushmodes.c

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -446,42 +446,66 @@ void get_color_pixels_accumulate (uint16_t * mask,
446446
float * sum_r,
447447
float * sum_g,
448448
float * sum_b,
449-
float * sum_a
449+
float * sum_a,
450+
float paint
450451
) {
451452

452453

453-
// The sum of a 64x64 tile fits into a 32 bit integer, but the sum
454-
// of an arbitrary number of tiles may not fit. We assume that we
455-
// are processing a single tile at a time, so we can use integers.
456-
// But for the result we need floats.
454+
// Sample the canvas as additive and subtractive
455+
// According to paint parameter
456+
// Average the results normally
457+
// Only sample a random selection of pixels
457458

458-
uint32_t weight = 0;
459-
uint32_t r = 0;
460-
uint32_t g = 0;
461-
uint32_t b = 0;
462-
uint32_t a = 0;
459+
float avg_spectral[10] = {0};
460+
float avg_rgb[3] = {*sum_r, *sum_g, *sum_b};
461+
if (paint > 0.0f) {
462+
rgb_to_spectral(*sum_r, *sum_g, *sum_b, avg_spectral);
463+
}
463464

464465
while (1) {
465466
for (; mask[0]; mask++, rgba+=4) {
466-
uint32_t opa = mask[0];
467-
weight += opa;
468-
r += opa*rgba[0]/(1<<15);
469-
g += opa*rgba[1]/(1<<15);
470-
b += opa*rgba[2]/(1<<15);
471-
a += opa*rgba[3]/(1<<15);
472-
467+
// sample at least one pixel but then only 1%
468+
if (rand() % 100 != 0 && *sum_a > 0.0) {
469+
continue;
470+
}
471+
float a = (float)mask[0] * rgba[3] / (1<<30);
472+
float alpha_sums = a + *sum_a;
473+
*sum_weight += (float)mask[0] / (1<<15);
474+
float fac_a, fac_b;
475+
fac_a = fac_b = 1.0f;
476+
if (alpha_sums > 0.0f) {
477+
fac_a = a / alpha_sums;
478+
fac_b = 1.0 - fac_a;
479+
}
480+
if (paint > 0.0f) {
481+
float spectral[10] = {0};
482+
if (rgba[3] > 0) {
483+
rgb_to_spectral((float)rgba[0] / rgba[3], (float)rgba[1] / rgba[3], (float)rgba[2] / rgba[3], spectral);
484+
for (int i=0; i<10; i++) {
485+
avg_spectral[i] = fastpow(spectral[i], fac_a) * fastpow(avg_spectral[i], fac_b);
486+
}
487+
}
488+
}
489+
if (paint < 1.0f) {
490+
if (rgba[3] > 0) {
491+
for (int i=0; i<3; i++) {
492+
avg_rgb[i] = (float)rgba[i] * fac_a / rgba[3] + (float)avg_rgb[i] * fac_b;
493+
}
494+
}
495+
}
496+
*sum_a += a;
473497
}
498+
float spec_rgb[3] = {0};
499+
spectral_to_rgb(avg_spectral, spec_rgb);
500+
501+
*sum_r = spec_rgb[0] * paint + (1.0 - paint) * avg_rgb[0];
502+
*sum_g = spec_rgb[1] * paint + (1.0 - paint) * avg_rgb[1];
503+
*sum_b = spec_rgb[2] * paint + (1.0 - paint) * avg_rgb[2];
504+
474505
if (!mask[1]) break;
475506
rgba += mask[1];
476507
mask += 2;
477508
}
478-
479-
// convert integer to float outside the performance critical loop
480-
*sum_weight += weight;
481-
*sum_r += r;
482-
*sum_g += g;
483-
*sum_b += b;
484-
*sum_a += a;
485509
};
486510

487511

brushmodes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ void get_color_pixels_accumulate (uint16_t * mask,
6363
float * sum_r,
6464
float * sum_g,
6565
float * sum_b,
66-
float * sum_a
66+
float * sum_a,
67+
float paint
6768
);
6869

6970

mypaint-brush.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ mypaint_brush_set_state(MyPaintBrush *self, MyPaintBrushState i, float value)
828828
float smudge_radius = radius * fasterexp(self->settings_value[MYPAINT_BRUSH_SETTING_SMUDGE_RADIUS_LOG]);
829829
smudge_radius = CLAMP(smudge_radius, ACTUAL_RADIUS_MIN, ACTUAL_RADIUS_MAX);
830830

831-
mypaint_surface_get_color(surface, px, py, smudge_radius, &r, &g, &b, &a);
831+
mypaint_surface_get_color(surface, px, py, smudge_radius, &r, &g, &b, &a, self->settings_value[MYPAINT_BRUSH_SETTING_PAINT_MODE]);
832832

833833

834834
//don't draw unless the picked-up alpha is above a certain level

mypaint-surface.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,12 @@ void
4949
mypaint_surface_get_color(MyPaintSurface *self,
5050
float x, float y,
5151
float radius,
52-
float * color_r, float * color_g, float * color_b, float * color_a
52+
float * color_r, float * color_g, float * color_b, float * color_a,
53+
float paint
5354
)
5455
{
5556
assert(self->get_color);
56-
self->get_color(self, x, y, radius, color_r, color_g, color_b, color_a);
57+
self->get_color(self, x, y, radius, color_r, color_g, color_b, color_a, paint);
5758
}
5859

5960

@@ -98,7 +99,7 @@ mypaint_surface_unref(MyPaintSurface *self)
9899
float mypaint_surface_get_alpha (MyPaintSurface *self, float x, float y, float radius)
99100
{
100101
float color_r, color_g, color_b, color_a;
101-
mypaint_surface_get_color (self, x, y, radius, &color_r, &color_g, &color_b, &color_a);
102+
mypaint_surface_get_color (self, x, y, radius, &color_r, &color_g, &color_b, &color_a, 1.0);
102103
return color_a;
103104
}
104105

mypaint-surface.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ typedef struct MyPaintSurface MyPaintSurface;
2828
typedef void (*MyPaintSurfaceGetColorFunction) (MyPaintSurface *self,
2929
float x, float y,
3030
float radius,
31-
float * color_r, float * color_g, float * color_b, float * color_a
31+
float * color_r, float * color_g, float * color_b, float * color_a,
32+
float paint
3233
);
3334

3435
typedef int (*MyPaintSurfaceDrawDabFunction) (MyPaintSurface *self,
@@ -93,7 +94,8 @@ void
9394
mypaint_surface_get_color(MyPaintSurface *self,
9495
float x, float y,
9596
float radius,
96-
float * color_r, float * color_g, float * color_b, float * color_a
97+
float * color_r, float * color_g, float * color_b, float * color_a,
98+
float paint
9799
);
98100

99101

mypaint-tiled-surface.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,8 @@ int draw_dab (MyPaintSurface *surface, float x, float y,
776776

777777
void get_color (MyPaintSurface *surface, float x, float y,
778778
float radius,
779-
float * color_r, float * color_g, float * color_b, float * color_a
779+
float * color_r, float * color_g, float * color_b, float * color_a,
780+
float paint
780781
)
781782
{
782783
MyPaintTiledSurface *self = (MyPaintTiledSurface *)surface;
@@ -839,7 +840,7 @@ void get_color (MyPaintSurface *surface, float x, float y,
839840
#pragma omp critical
840841
{
841842
get_color_pixels_accumulate (mask, rgba_p,
842-
&sum_weight, &sum_r, &sum_g, &sum_b, &sum_a);
843+
&sum_weight, &sum_r, &sum_g, &sum_b, &sum_a, paint);
843844
}
844845

845846
mypaint_tiled_surface_tile_request_end(self, &request_data);
@@ -848,16 +849,12 @@ void get_color (MyPaintSurface *surface, float x, float y,
848849

849850
assert(sum_weight > 0.0f);
850851
sum_a /= sum_weight;
851-
sum_r /= sum_weight;
852-
sum_g /= sum_weight;
853-
sum_b /= sum_weight;
854-
855852
*color_a = sum_a;
856853
// now un-premultiply the alpha
857854
if (sum_a > 0.0f) {
858-
*color_r = sum_r / sum_a;
859-
*color_g = sum_g / sum_a;
860-
*color_b = sum_b / sum_a;
855+
*color_r = sum_r;
856+
*color_g = sum_g;
857+
*color_b = sum_b;
861858
} else {
862859
// it is all transparent, so don't care about the colors
863860
// (let's make them ugly so bugs will be visible)

0 commit comments

Comments
 (0)