67
69
* There is also some ugliness with sculpt-specific code.
70
typedef struct Snapshot {
74
int BKE_brush_size_get;
72
typedef struct TexSnapshot {
73
GLuint overlay_texture;
78
int curve_changed_timestamp;
81
static int same_snap(Snapshot *snap, Brush *brush, ViewContext *vc)
82
static int same_tex_snap(TexSnapshot *snap, MTex *mtex, ViewContext *vc, bool col, float zoom)
83
MTex *mtex = &brush->mtex;
85
return (((mtex->tex) &&
86
equals_v3v3(mtex->ofs, snap->ofs) &&
87
equals_v3v3(mtex->size, snap->size) &&
88
mtex->rot == snap->rot) &&
90
/* make brush smaller shouldn't cause a resample */
91
((mtex->brush_map_mode == MTEX_MAP_MODE_VIEW &&
92
(BKE_brush_size_get(vc->scene, brush) <= snap->BKE_brush_size_get)) ||
93
(BKE_brush_size_get(vc->scene, brush) == snap->BKE_brush_size_get)) &&
95
(mtex->brush_map_mode == snap->brush_map_mode) &&
96
(vc->ar->winx == snap->winx) &&
97
(vc->ar->winy == snap->winy));
84
return (/* make brush smaller shouldn't cause a resample */
85
//(mtex->brush_map_mode != MTEX_MAP_MODE_VIEW ||
86
//(BKE_brush_size_get(vc->scene, brush) <= snap->BKE_brush_size_get)) &&
88
(mtex->brush_map_mode != MTEX_MAP_MODE_TILED ||
89
(vc->ar->winx == snap->winx &&
90
vc->ar->winy == snap->winy)) &&
91
(mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL ||
92
snap->old_zoom == zoom) &&
100
static void make_snap(Snapshot *snap, Brush *brush, ViewContext *vc)
97
static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom)
102
if (brush->mtex.tex) {
103
snap->brush_map_mode = brush->mtex.brush_map_mode;
104
copy_v3_v3(snap->ofs, brush->mtex.ofs);
105
copy_v3_v3(snap->size, brush->mtex.size);
106
snap->rot = brush->mtex.rot;
109
snap->brush_map_mode = -1;
110
snap->ofs[0] = snap->ofs[1] = snap->ofs[2] = -1;
111
snap->size[0] = snap->size[1] = snap->size[2] = -1;
115
snap->BKE_brush_size_get = BKE_brush_size_get(vc->scene, brush);
99
snap->old_zoom = zoom;
116
100
snap->winx = vc->ar->winx;
117
101
snap->winy = vc->ar->winy;
120
static int load_tex(Brush *br, ViewContext *vc)
104
static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary)
122
static GLuint overlay_texture = 0;
123
106
static int init = 0;
124
static int tex_changed_timestamp = -1;
125
static int curve_changed_timestamp = -1;
126
static Snapshot snap;
127
static int old_size = -1;
107
static TexSnapshot primary_snap = {0};
108
static TexSnapshot secondary_snap = {0};
111
MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex;
112
OverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags();
129
113
GLubyte *buffer = NULL;
135
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED && !br->mtex.tex) return 0;
118
GLenum format = col ? GL_RGBA : GL_ALPHA;
119
OverlayControlFlags invalid = (primary) ? (overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY) :
120
(overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY);
122
target = (primary) ? &primary_snap : &secondary_snap;
140
(!br->mtex.tex->preview ||
141
br->mtex.tex->preview->changed_timestamp[0] != tex_changed_timestamp)) ||
143
br->curve->changed_timestamp != curve_changed_timestamp ||
144
!same_snap(&snap, br, vc);
125
!target->overlay_texture ||
127
!same_tex_snap(target, mtex, vc, col, zoom);
147
130
struct ImagePool *pool = NULL;
149
if (br->mtex.tex && br->mtex.tex->preview)
150
tex_changed_timestamp = br->mtex.tex->preview->changed_timestamp[0];
153
curve_changed_timestamp = br->curve->changed_timestamp;
155
make_snap(&snap, br, vc);
157
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
131
/* stencil is rotated later */
132
const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ?
135
float radius = BKE_brush_size_get(vc->scene, br) * zoom;
137
make_tex_snap(target, vc, zoom);
139
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
158
140
int s = BKE_brush_size_get(vc->scene, br);
151
if (size < target->old_size)
152
size = target->old_size;
175
if (old_size != size) {
176
if (overlay_texture) {
177
glDeleteTextures(1, &overlay_texture);
157
if (target->old_size != size) {
158
if (target->overlay_texture) {
159
glDeleteTextures(1, &target->overlay_texture);
160
target->overlay_texture = 0;
165
target->old_size = size;
186
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
189
pool = BKE_image_pool_new();
168
buffer = MEM_mallocN(sizeof(GLubyte) * size * size * 4, "load_tex");
170
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
172
pool = BKE_image_pool_new();
191
174
#pragma omp parallel for schedule(static)
192
175
for (j = 0; j < size; j++) {
199
182
// largely duplicated from tex_strength
201
const float rotation = -br->mtex.rot;
202
float radius = BKE_brush_size_get(vc->scene, br);
203
184
int index = j * size + i;
207
187
x = (float)i / size;
208
188
y = (float)j / size;
213
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
190
if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
214
191
x *= vc->ar->winx / radius;
215
192
y *= vc->ar->winy / radius;
222
202
len = sqrtf(x * x + y * y);
224
if ((br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) || len <= 1) {
204
if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL) || len <= 1) {
225
205
/* it is probably worth optimizing for those cases where
226
206
* the texture is not rotated by skipping the calls to
227
207
* atan2, sqrtf, sin, and cos. */
228
if (br->mtex.tex && (rotation > 0.001f || rotation < -0.001f)) {
229
const float angle = atan2f(y, x) + rotation;
208
if (mtex->tex && (rotation > 0.001f || rotation < -0.001f)) {
209
const float angle = atan2f(y, x) + rotation;
231
211
x = len * cosf(angle);
232
212
y = len * sinf(angle);
235
x *= br->mtex.size[0];
236
y *= br->mtex.size[1];
238
x += br->mtex.ofs[0];
239
y += br->mtex.ofs[1];
241
avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y, pool) : 1;
243
avg += br->texture_sample_bias;
245
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW)
246
avg *= BKE_brush_curve_strength(br, len, 1); /* Falloff curve */
224
paint_get_tex_pixel_col(mtex, x, y, rgba, pool);
226
buffer[index * 4] = rgba[0] * 255;
227
buffer[index * 4 + 1] = rgba[1] * 255;
228
buffer[index * 4 + 2] = rgba[2] * 255;
229
buffer[index * 4 + 3] = rgba[3] * 255;
232
float avg = paint_get_tex_pixel(mtex, x, y, pool);
234
avg += br->texture_sample_bias;
236
/* clamp to avoid precision overflow */
237
CLAMP(avg, 0.0f, 1.0f);
238
buffer[index] = 255 - (GLubyte)(255 * avg);
243
buffer[index * 4] = 0;
244
buffer[index * 4 + 1] = 0;
245
buffer[index * 4 + 2] = 0;
246
buffer[index * 4 + 3] = 0;
256
BKE_image_pool_free(pool);
258
if (!target->overlay_texture)
259
glGenTextures(1, &target->overlay_texture);
262
size = target->old_size;
265
glBindTexture(GL_TEXTURE_2D, target->overlay_texture);
268
if (!init || (target->old_col != col)) {
269
glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, format, GL_UNSIGNED_BYTE, buffer);
273
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, format, GL_UNSIGNED_BYTE, buffer);
279
target->old_col = col;
282
glEnable(GL_TEXTURE_2D);
284
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
285
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
286
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
288
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
289
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
290
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
293
BKE_paint_reset_overlay_invalid(invalid);
298
static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
300
static GLuint overlay_texture = 0;
302
static int old_size = -1;
303
static int old_zoom = -1;
305
OverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags();
306
GLubyte *buffer = NULL;
314
(overlay_flags & PAINT_INVALID_OVERLAY_CURVE) ||
322
s = BKE_brush_size_get(vc->scene, br);
325
for (s >>= 1; s > 0; s >>= 1)
336
if (old_size != size) {
337
if (overlay_texture) {
338
glDeleteTextures(1, &overlay_texture);
346
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
348
curvemapping_initialize(br->curve);
350
#pragma omp parallel for schedule(static)
351
for (j = 0; j < size; j++) {
356
for (i = 0; i < size; i++) {
358
// largely duplicated from tex_strength
360
int index = j * size + i;
372
len = sqrtf(x * x + y * y);
375
float avg = BKE_brush_curve_strength_clamp(br, len, 1.0f); /* Falloff curve */
248
377
buffer[index] = 255 - (GLubyte)(255 * avg);
251
381
buffer[index] = 0;
284
411
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
285
412
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
287
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
288
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
289
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
414
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
415
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
417
BKE_paint_reset_overlay_invalid(PAINT_INVALID_OVERLAY_CURVE);
295
424
static int project_brush_radius(ViewContext *vc,
297
426
const float location[3])
381
510
/* Draw an overlay that shows what effect the brush's texture will
382
511
* have on brush strength */
383
/* TODO: sculpt only for now */
384
static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
385
ViewContext *vc, int x, int y)
512
static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush,
513
ViewContext *vc, int x, int y, float zoom, bool col, bool primary)
389
516
/* check for overlay mode */
390
if (!(brush->flag & BRUSH_TEXTURE_OVERLAY) ||
391
!(ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED)))
518
MTex *mtex = (primary) ? &brush->mtex : &brush->mask_mtex;
519
bool valid = (primary) ? (brush->overlay_flags & BRUSH_OVERLAY_PRIMARY) != 0 :
520
(brush->overlay_flags & BRUSH_OVERLAY_SECONDARY) != 0;
521
int overlay_alpha = (primary) ? brush->texture_overlay_alpha : brush->mask_overlay_alpha;
523
if (!(mtex->tex) || !((mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) ||
525
ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED))))
396
/* save lots of GL state
397
* TODO: check on whether all of these are needed? */
398
glPushAttrib(GL_COLOR_BUFFER_BIT |
400
GL_DEPTH_BUFFER_BIT |
404
GL_STENCIL_BUFFER_BIT |
409
if (load_tex(brush, vc)) {
530
if (load_tex(brush, vc, zoom, col, primary)) {
410
531
glEnable(GL_BLEND);
412
533
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
418
539
glLoadIdentity();
420
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
541
if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
421
542
/* brush rotation */
422
543
glTranslatef(0.5, 0.5, 0);
423
glRotatef((double)RAD2DEGF((brush->flag & BRUSH_RAKE) ?
424
ups->last_angle : ups->special_rotation),
544
glRotatef((double)RAD2DEGF(ups->brush_rotation),
426
546
glTranslatef(-0.5f, -0.5f, 0);
428
548
/* scale based on tablet pressure */
429
if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
549
if (primary && ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
430
550
glTranslatef(0.5f, 0.5f, 0);
431
551
glScalef(1.0f / ups->pressure_value, 1.0f / ups->pressure_value, 1);
432
552
glTranslatef(-0.5f, -0.5f, 0);
435
555
if (ups->draw_anchored) {
436
556
const float *aim = ups->anchored_initial_mouse;
437
const rcti *win = &vc->ar->winrct;
438
quad.xmin = aim[0] - ups->anchored_size - win->xmin;
439
quad.ymin = aim[1] - ups->anchored_size - win->ymin;
440
quad.xmax = aim[0] + ups->anchored_size - win->xmin;
441
quad.ymax = aim[1] + ups->anchored_size - win->ymin;
557
quad.xmin = aim[0] - ups->anchored_size;
558
quad.ymin = aim[1] - ups->anchored_size;
559
quad.xmax = aim[0] + ups->anchored_size;
560
quad.ymax = aim[1] + ups->anchored_size;
444
const int radius = BKE_brush_size_get(vc->scene, brush);
563
const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
445
564
quad.xmin = x - radius;
446
565
quad.ymin = y - radius;
447
566
quad.xmax = x + radius;
448
567
quad.ymax = y + radius;
570
else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
454
573
quad.xmax = BLI_rcti_size_x(&vc->ar->winrct);
455
574
quad.ymax = BLI_rcti_size_y(&vc->ar->winrct);
576
/* Stencil code goes here */
579
quad.xmin = -brush->stencil_dimension[0];
580
quad.ymin = -brush->stencil_dimension[1];
581
quad.xmax = brush->stencil_dimension[0];
582
quad.ymax = brush->stencil_dimension[1];
585
quad.xmin = -brush->mask_stencil_dimension[0];
586
quad.ymin = -brush->mask_stencil_dimension[1];
587
quad.xmax = brush->mask_stencil_dimension[0];
588
quad.ymax = brush->mask_stencil_dimension[1];
590
glMatrixMode(GL_MODELVIEW);
593
glTranslatef(brush->stencil_pos[0], brush->stencil_pos[1], 0);
595
glTranslatef(brush->mask_stencil_pos[0], brush->mask_stencil_pos[1], 0);
596
glRotatef(RAD2DEGF(mtex->rot), 0, 0, 1);
597
glMatrixMode(GL_TEXTURE);
600
/* set quad color. Colored overlay does not get blending */
605
overlay_alpha / 100.0f);
607
glColor4f(U.sculpt_paint_overlay_col[0],
608
U.sculpt_paint_overlay_col[1],
609
U.sculpt_paint_overlay_col[2],
610
overlay_alpha / 100.0f);
612
/* draw textured quad */
615
glVertex2f(quad.xmin, quad.ymin);
617
glVertex2f(quad.xmax, quad.ymin);
619
glVertex2f(quad.xmax, quad.ymax);
621
glVertex2f(quad.xmin, quad.ymax);
626
if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
627
glMatrixMode(GL_MODELVIEW);
633
/* Draw an overlay that shows what effect the brush's texture will
634
* have on brush strength */
635
static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush,
636
ViewContext *vc, int x, int y, float zoom)
639
/* check for overlay mode */
641
if (!(brush->overlay_flags & BRUSH_OVERLAY_CURSOR)) {
645
if (load_tex_cursor(brush, vc, zoom)) {
648
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
649
glDepthMask(GL_FALSE);
650
glDepthFunc(GL_ALWAYS);
652
/* scale based on tablet pressure */
653
if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
654
glTranslatef(0.5f, 0.5f, 0);
655
glScalef(1.0f / ups->pressure_value, 1.0f / ups->pressure_value, 1);
656
glTranslatef(-0.5f, -0.5f, 0);
659
if (ups->draw_anchored) {
660
const float *aim = ups->anchored_initial_mouse;
661
quad.xmin = aim[0] - ups->anchored_size;
662
quad.ymin = aim[1] - ups->anchored_size;
663
quad.xmax = aim[0] + ups->anchored_size;
664
quad.ymax = aim[1] + ups->anchored_size;
667
const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
668
quad.xmin = x - radius;
669
quad.ymin = y - radius;
670
quad.xmax = x + radius;
671
quad.ymax = y + radius;
459
674
glColor4f(U.sculpt_paint_overlay_col[0],
460
U.sculpt_paint_overlay_col[1],
461
U.sculpt_paint_overlay_col[2],
462
brush->texture_overlay_alpha / 100.0f);
675
U.sculpt_paint_overlay_col[1],
676
U.sculpt_paint_overlay_col[2],
677
brush->cursor_overlay_alpha / 100.0f);
464
679
/* draw textured quad */
465
680
glBegin(GL_QUADS);
472
687
glTexCoord2f(0, 1);
473
688
glVertex2f(quad.xmin, quad.ymax);
693
static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
694
ViewContext *vc, int x, int y, float zoom, PaintMode mode)
696
/* color means that primary brush texture is colured and secondary is used for alpha/mask control */
697
bool col = ELEM3(mode, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D, PAINT_VERTEX) ? true: false;
698
OverlayControlFlags flags = BKE_paint_get_overlay_flags();
699
/* save lots of GL state
700
* TODO: check on whether all of these are needed? */
701
glPushAttrib(GL_COLOR_BUFFER_BIT |
703
GL_DEPTH_BUFFER_BIT |
707
GL_STENCIL_BUFFER_BIT |
713
/* coloured overlay should be drawn separately */
715
if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY))
716
paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, true, true);
717
if (!(flags & PAINT_OVERLAY_OVERRIDE_SECONDARY))
718
paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, false, false);
719
if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR))
720
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
723
if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY))
724
paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, false, true);
725
if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR))
726
paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
516
766
Scene *scene = CTX_data_scene(C);
517
767
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
518
Paint *paint = paint_get_active_from_context(C);
519
Brush *brush = paint_brush(paint);
768
Paint *paint = BKE_paint_get_active_from_context(C);
769
Brush *brush = BKE_paint_brush(paint);
521
772
float final_radius;
522
773
float translation[2];
523
774
float outline_alpha, *outline_col;
777
/* check that brush drawing is enabled */
778
if (!(paint->flags & PAINT_SHOW_BRUSH))
781
/* can't use stroke vc here because this will be called during
782
* mouse over too, not just during a stroke */
783
view3d_set_viewcontext(C, &vc);
785
get_imapaint_zoom(C, &zoomx, &zoomy);
786
zoomx = max_ff(zoomx, zoomy);
787
mode = BKE_paintmode_get_active_from_context(C);
525
789
/* set various defaults */
526
790
translation[0] = x;
527
791
translation[1] = y;
528
792
outline_alpha = 0.5;
529
793
outline_col = brush->add_col;
530
final_radius = BKE_brush_size_get(scene, brush);
532
/* check that brush drawing is enabled */
533
if (!(paint->flags & PAINT_SHOW_BRUSH))
536
/* can't use stroke vc here because this will be called during
537
* mouse over too, not just during a stroke */
538
view3d_set_viewcontext(C, &vc);
794
final_radius = BKE_brush_size_get(scene, brush) * zoomx;
796
if (brush->flag & BRUSH_RAKE)
797
/* here, translation contains the mouse coordinates. */
798
paint_calculate_rake_rotation(ups, translation);
799
else if (!(brush->flag & BRUSH_ANCHORED))
800
ups->brush_rotation = 0.0;
803
paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode);
540
805
/* TODO: as sculpt and other paint modes are unified, this
541
806
* special mode of drawing will go away */
542
if (vc.obact->sculpt) {
807
if ((mode == PAINT_SCULPT) && vc.obact->sculpt) {
543
808
float location[3];
544
809
int pixel_radius, hit;
546
/* this is probably here so that rake takes into
547
* account the brush movements before the stroke
548
* starts, but this doesn't really belong in draw code
551
const float u = 0.5f;
552
const float v = 1 - u;
555
const float dx = ups->last_x - x;
556
const float dy = ups->last_y - y;
558
if (dx * dx + dy * dy >= r * r) {
559
ups->last_angle = atan2(dx, dy);
561
ups->last_x = u * ups->last_x + v * x;
562
ups->last_y = u * ups->last_y + v * y;
566
811
/* test if brush is over the mesh */
567
812
hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location);
570
paint_draw_alpha_overlay(ups, brush, &vc, x, y);
572
814
if (BKE_brush_use_locked_size(scene, brush))
573
815
BKE_brush_size_set(scene, brush, pixel_radius);