159
179
curvemapping_free(brush->curve);
182
static void extern_local_brush(Brush *brush)
184
id_lib_extern((ID *)brush->mtex.tex);
185
id_lib_extern((ID *)brush->clone.image);
162
188
void make_local_brush(Brush *brush)
164
191
/* - only lib users: do nothing
165
* - only local users: set flag
192
* - only local users: set flag
171
int local= 0, lib= 0;
173
if(brush->id.lib==0) return;
175
if(brush->clone.image) {
176
/* special case: ima always local immediately */
177
brush->clone.image->id.lib= 0;
178
brush->clone.image->id.flag= LIB_LOCAL;
179
new_id(0, (ID *)brush->clone.image, 0);
198
int is_local= FALSE, is_lib= FALSE;
200
if (brush->id.lib==NULL) return;
202
if (brush->clone.image) {
203
/* special case: ima always local immediately. Clone image should only
204
* have one user anyway. */
205
id_clear_lib_data(bmain, &brush->clone.image->id);
206
extern_local_brush(brush);
182
for(scene= G.main->scene.first; scene; scene=scene->id.next)
183
if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
184
if(scene->id.lib) lib= 1;
209
for (scene= bmain->scene.first; scene && ELEM(0, is_lib, is_local); scene=scene->id.next) {
210
if (paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
211
if (scene->id.lib) is_lib= TRUE;
188
if(local && lib==0) {
190
brush->id.flag= LIB_LOCAL;
191
new_id(0, (ID *)brush, 0);
216
if (is_local && is_lib == FALSE) {
217
id_clear_lib_data(bmain, &brush->id);
218
extern_local_brush(brush);
193
220
/* enable fake user by default */
194
221
if (!(brush->id.flag & LIB_FAKEUSER)) {
195
222
brush->id.flag |= LIB_FAKEUSER;
196
brush_toggled_fake_user(brush);
199
else if(local && lib) {
200
brushn= copy_brush(brush);
201
brushn->id.us= 1; /* only keep fake user */
202
brushn->id.flag |= LIB_FAKEUSER;
226
else if (is_local && is_lib) {
227
Brush *brush_new= copy_brush(brush);
228
brush_new->id.us= 1; /* only keep fake user */
229
brush_new->id.flag |= LIB_FAKEUSER;
231
/* Remap paths of new ID using old library as base. */
232
BKE_id_lib_local_paths(bmain, brush->id.lib, &brush_new->id);
204
for(scene= G.main->scene.first; scene; scene=scene->id.next)
205
if(paint_brush(&scene->toolsettings->imapaint.paint)==brush)
206
if(scene->id.lib==0) {
207
paint_brush_set(&scene->toolsettings->imapaint.paint, brushn);
234
for (scene= bmain->scene.first; scene; scene=scene->id.next) {
235
if (paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
236
if (scene->id.lib==NULL) {
237
paint_brush_set(&scene->toolsettings->imapaint.paint, brush_new);
244
void brush_debug_print_state(Brush *br)
246
/* create a fake brush and set it to the defaults */
248
brush_set_defaults(&def);
250
#define BR_TEST(field, t) \
251
if (br->field != def.field) \
252
printf("br->" #field " = %" #t ";\n", br->field)
254
#define BR_TEST_FLAG(_f) \
255
if ((br->flag & _f) && !(def.flag & _f)) \
256
printf("br->flag |= " #_f ";\n"); \
257
else if (!(br->flag & _f) && (def.flag & _f)) \
258
printf("br->flag &= ~" #_f ";\n")
261
/* print out any non-default brush state */
262
BR_TEST(normal_weight, f);
268
BR_TEST_FLAG(BRUSH_AIRBRUSH);
269
BR_TEST_FLAG(BRUSH_TORUS);
270
BR_TEST_FLAG(BRUSH_ALPHA_PRESSURE);
271
BR_TEST_FLAG(BRUSH_SIZE_PRESSURE);
272
BR_TEST_FLAG(BRUSH_JITTER_PRESSURE);
273
BR_TEST_FLAG(BRUSH_SPACING_PRESSURE);
274
BR_TEST_FLAG(BRUSH_FIXED_TEX);
275
BR_TEST_FLAG(BRUSH_RAKE);
276
BR_TEST_FLAG(BRUSH_ANCHORED);
277
BR_TEST_FLAG(BRUSH_DIR_IN);
278
BR_TEST_FLAG(BRUSH_SPACE);
279
BR_TEST_FLAG(BRUSH_SMOOTH_STROKE);
280
BR_TEST_FLAG(BRUSH_PERSISTENT);
281
BR_TEST_FLAG(BRUSH_ACCUMULATE);
282
BR_TEST_FLAG(BRUSH_LOCK_ALPHA);
283
BR_TEST_FLAG(BRUSH_ORIGINAL_NORMAL);
284
BR_TEST_FLAG(BRUSH_OFFSET_PRESSURE);
285
BR_TEST_FLAG(BRUSH_SPACE_ATTEN);
286
BR_TEST_FLAG(BRUSH_ADAPTIVE_SPACE);
287
BR_TEST_FLAG(BRUSH_LOCK_SIZE);
288
BR_TEST_FLAG(BRUSH_TEXTURE_OVERLAY);
289
BR_TEST_FLAG(BRUSH_EDGE_TO_EDGE);
290
BR_TEST_FLAG(BRUSH_RESTORE_MESH);
291
BR_TEST_FLAG(BRUSH_INVERSE_SMOOTH_PRESSURE);
292
BR_TEST_FLAG(BRUSH_RANDOM_ROTATION);
293
BR_TEST_FLAG(BRUSH_PLANE_TRIM);
294
BR_TEST_FLAG(BRUSH_FRONTFACE);
295
BR_TEST_FLAG(BRUSH_CUSTOM_ICON);
299
BR_TEST(smooth_stroke_radius, d);
300
BR_TEST(smooth_stroke_factor, f);
305
BR_TEST(sculpt_plane, d);
307
BR_TEST(plane_offset, f);
309
BR_TEST(autosmooth_factor, f);
311
BR_TEST(crease_pinch_factor, f);
313
BR_TEST(plane_trim, f);
315
BR_TEST(texture_sample_bias, f);
316
BR_TEST(texture_overlay_alpha, d);
318
BR_TEST(add_col[0], f);
319
BR_TEST(add_col[1], f);
320
BR_TEST(add_col[2], f);
321
BR_TEST(sub_col[0], f);
322
BR_TEST(sub_col[1], f);
323
BR_TEST(sub_col[2], f);
331
void brush_reset_sculpt(Brush *br)
333
/* enable this to see any non-default
334
* settings used by a brush: */
335
// brush_debug_print_state(br);
337
brush_set_defaults(br);
338
brush_curve_preset(br, CURVE_PRESET_SMOOTH);
340
switch(br->sculpt_tool) {
341
case SCULPT_TOOL_CLAY:
342
br->flag |= BRUSH_FRONTFACE;
344
case SCULPT_TOOL_CREASE:
345
br->flag |= BRUSH_DIR_IN;
348
case SCULPT_TOOL_FILL:
350
br->sub_col[0] = 0.25;
353
case SCULPT_TOOL_FLATTEN:
355
br->sub_col[0] = 0.25;
358
case SCULPT_TOOL_INFLATE:
359
br->add_col[0] = 0.750000;
360
br->add_col[1] = 0.750000;
361
br->add_col[2] = 0.750000;
362
br->sub_col[0] = 0.250000;
363
br->sub_col[1] = 0.250000;
364
br->sub_col[2] = 0.250000;
366
case SCULPT_TOOL_NUDGE:
367
br->add_col[0] = 0.250000;
368
br->add_col[1] = 1.000000;
369
br->add_col[2] = 0.250000;
371
case SCULPT_TOOL_PINCH:
372
br->add_col[0] = 0.750000;
373
br->add_col[1] = 0.750000;
374
br->add_col[2] = 0.750000;
375
br->sub_col[0] = 0.250000;
376
br->sub_col[1] = 0.250000;
377
br->sub_col[2] = 0.250000;
379
case SCULPT_TOOL_SCRAPE:
380
br->add_col[1] = 1.000000;
381
br->sub_col[0] = 0.250000;
382
br->sub_col[1] = 1.000000;
384
case SCULPT_TOOL_ROTATE:
387
case SCULPT_TOOL_SMOOTH:
388
br->flag &= ~BRUSH_SPACE_ATTEN;
390
br->add_col[0] = 0.750000;
391
br->add_col[1] = 0.750000;
392
br->add_col[2] = 0.750000;
394
case SCULPT_TOOL_GRAB:
395
case SCULPT_TOOL_SNAKE_HOOK:
396
case SCULPT_TOOL_THUMB:
398
br->flag &= ~BRUSH_ALPHA_PRESSURE;
399
br->flag &= ~BRUSH_SPACE;
400
br->flag &= ~BRUSH_SPACE_ATTEN;
401
br->add_col[0] = 0.250000;
402
br->add_col[1] = 1.000000;
403
br->add_col[2] = 0.250000;
214
410
/* Library Operations */
216
int brush_set_nr(Brush **current_brush, int nr, const char *name)
220
id= (ID*)(*current_brush);
221
idtest= (ID*)BLI_findlink(&G.main->brush, nr-1);
223
if(idtest==0) { /* new brush */
224
if(id) idtest= (ID *)copy_brush((Brush *)id);
225
else idtest= (ID *)add_brush(name);
229
brush_delete(current_brush);
230
*current_brush= (Brush *)idtest;
239
int brush_delete(Brush **current_brush)
241
if (*current_brush) {
242
(*current_brush)->id.us--;
243
*current_brush= NULL;
251
void brush_toggled_fake_user(Brush *brush)
255
if(id->flag & LIB_FAKEUSER) {
263
411
void brush_curve_preset(Brush *b, /*CurveMappingPreset*/int preset)
265
413
CurveMap *cm = NULL;
268
416
b->curve = curvemapping_add(1, 0, 0, 1, 1);
270
418
cm = b->curve->cm;
271
419
cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
273
421
b->curve->preset = preset;
274
curvemap_reset(cm, &b->curve->clipr, b->curve->preset);
422
curvemap_reset(cm, &b->curve->clipr, b->curve->preset, CURVEMAP_SLOPE_NEGATIVE);
275
423
curvemapping_changed(b->curve, 0);
278
static MTex *brush_active_texture(Brush *brush)
285
426
int brush_texture_set_nr(Brush *brush, int nr)
287
428
ID *idtest, *id=NULL;
381
517
rgba[0]= rgba[1]= rgba[2]= rgba[3]= 1.0f;
385
void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **outbuf)
521
/* TODO, use define for 'texfall' arg */
522
void brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction)
388
float xy[2], dist, rgba[4], *dstf;
525
float xy[2], rgba[4], *dstf;
389
526
int x, y, rowbytes, xoff, yoff, imbflag;
390
int maxsize = brush->size >> 1;
527
const int radius= brush_size(scene, brush);
528
unsigned char *dst, crgb[3];
529
const float alpha= brush_alpha(scene, brush);
393
532
imbflag= (flt)? IB_rectfloat: IB_rect;
394
xoff = -size/2.0f + 0.5f;
395
yoff = -size/2.0f + 0.5f;
533
xoff = -bufsize/2.0f + 0.5f;
534
yoff = -bufsize/2.0f + 0.5f;
401
ibuf= IMB_allocImBuf(size, size, 32, imbflag, 0);
540
ibuf= IMB_allocImBuf(bufsize, bufsize, 32, imbflag);
543
copy_v3_v3(brush_rgb, brush->rgb);
544
if (use_color_correction) {
545
srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
404
548
for (y=0; y < ibuf->y; y++) {
405
549
dstf = ibuf->rect_float + y*rowbytes;
409
553
xy[1] = y + yoff;
411
555
if (texfall == 0) {
412
dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
414
VECCOPY(dstf, brush->rgb);
415
dstf[3]= brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize);
556
copy_v3_v3(dstf, brush_rgb);
557
dstf[3]= alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius);
417
559
else if (texfall == 1) {
418
brush_sample_tex(brush, xy, dstf);
560
brush_sample_tex(scene, brush, xy, dstf, 0);
421
dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
423
brush_sample_tex(brush, xy, rgba);
425
dstf[0] = rgba[0]*brush->rgb[0];
426
dstf[1] = rgba[1]*brush->rgb[1];
427
dstf[2] = rgba[2]*brush->rgb[2];
428
dstf[3] = rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize);
563
brush_sample_tex(scene, brush, xy, rgba, 0);
564
mul_v3_v3v3(dstf, rgba, brush_rgb);
565
dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius);
434
crgb[0]= FTOCHAR(brush->rgb[0]);
435
crgb[1]= FTOCHAR(brush->rgb[1]);
436
crgb[2]= FTOCHAR(brush->rgb[2]);
571
float alpha_f; /* final float alpha to convert to char */
572
rgb_float_to_uchar(crgb, brush->rgb);
438
574
for (y=0; y < ibuf->y; y++) {
439
dst = (char*)ibuf->rect + y*rowbytes;
575
dst = (unsigned char *)ibuf->rect + y*rowbytes;
441
577
for (x=0; x < ibuf->x; x++, dst+=4) {
442
578
xy[0] = x + xoff;
443
579
xy[1] = y + yoff;
445
581
if (texfall == 0) {
446
dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
582
alpha_f = alpha * brush_curve_strength(brush, len_v2(xy), radius);
451
dst[3]= FTOCHAR(brush->alpha*brush_curve_strength(brush, dist, maxsize));
587
dst[3] = FTOCHAR(alpha_f);
453
589
else if (texfall == 1) {
454
brush_sample_tex(brush, xy, rgba);
455
dst[0]= FTOCHAR(rgba[0]);
456
dst[1]= FTOCHAR(rgba[1]);
457
dst[2]= FTOCHAR(rgba[2]);
458
dst[3]= FTOCHAR(rgba[3]);
590
brush_sample_tex(scene, brush, xy, rgba, 0);
591
rgba_float_to_uchar(dst, rgba);
593
else if (texfall == 2) {
594
brush_sample_tex(scene, brush, xy, rgba, 0);
595
mul_v3_v3(rgba, brush->rgb);
596
alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius);
598
rgb_float_to_uchar(dst, rgba);
600
dst[3] = FTOCHAR(alpha_f);
461
dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
603
brush_sample_tex(scene, brush, xy, rgba, 0);
604
alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius);
463
brush_sample_tex(brush, xy, rgba);
464
dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]);
465
dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]);
466
dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]);
467
dst[3] = FTOCHAR(rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize));
609
dst[3] = FTOCHAR(alpha_f);
618
/* Unified Size and Strength */
620
// XXX: be careful about setting size and unprojected radius
621
// because they depend on one another
622
// these functions do not set the other corresponding value
623
// this can lead to odd behavior if size and unprojected
624
// radius become inconsistent.
625
// the biggest problem is that it isn't possible to change
626
// unprojected radius because a view context is not
627
// available. my ussual solution to this is to use the
628
// ratio of change of the size to change the unprojected
629
// radius. Not completely convinced that is correct.
630
// In anycase, a better solution is needed to prevent
633
void brush_set_size(Scene *scene, Brush *brush, int size)
635
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
637
if (ups->flag & UNIFIED_PAINT_SIZE)
643
int brush_size(const Scene *scene, Brush *brush)
645
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
647
return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
650
int brush_use_locked_size(const Scene *scene, Brush *brush)
652
const short us_flag = scene->toolsettings->unified_paint_settings.flag;
654
return (us_flag & UNIFIED_PAINT_SIZE) ?
655
(us_flag & UNIFIED_PAINT_BRUSH_LOCK_SIZE) :
656
(brush->flag & BRUSH_LOCK_SIZE);
659
int brush_use_size_pressure(const Scene *scene, Brush *brush)
661
const short us_flag = scene->toolsettings->unified_paint_settings.flag;
663
return (us_flag & UNIFIED_PAINT_SIZE) ?
664
(us_flag & UNIFIED_PAINT_BRUSH_SIZE_PRESSURE) :
665
(brush->flag & BRUSH_SIZE_PRESSURE);
668
int brush_use_alpha_pressure(const Scene *scene, Brush *brush)
670
const short us_flag = scene->toolsettings->unified_paint_settings.flag;
672
return (us_flag & UNIFIED_PAINT_ALPHA) ?
673
(us_flag & UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE) :
674
(brush->flag & BRUSH_ALPHA_PRESSURE);
677
void brush_set_unprojected_radius(Scene *scene, Brush *brush, float unprojected_radius)
679
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
681
if (ups->flag & UNIFIED_PAINT_SIZE)
682
ups->unprojected_radius= unprojected_radius;
684
brush->unprojected_radius= unprojected_radius;
687
float brush_unprojected_radius(const Scene *scene, Brush *brush)
689
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
691
return (ups->flag & UNIFIED_PAINT_SIZE) ?
692
ups->unprojected_radius :
693
brush->unprojected_radius;
696
static void brush_set_alpha(Scene *scene, Brush *brush, float alpha)
698
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
700
if (ups->flag & UNIFIED_PAINT_ALPHA)
706
float brush_alpha(const Scene *scene, Brush *brush)
708
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
710
return (ups->flag & UNIFIED_PAINT_ALPHA) ? ups->alpha : brush->alpha;
713
/* scale unprojected radius to reflect a change in the brush's 2D size */
714
void brush_scale_unprojected_radius(float *unprojected_radius,
718
float scale = new_brush_size;
719
/* avoid division by zero */
720
if (old_brush_size != 0)
721
scale /= (float)old_brush_size;
722
(*unprojected_radius) *= scale;
725
/* scale brush size to reflect a change in the brush's unprojected radius */
726
void brush_scale_size(int *brush_size,
727
float new_unprojected_radius,
728
float old_unprojected_radius)
730
float scale = new_unprojected_radius;
731
/* avoid division by zero */
732
if (old_unprojected_radius != 0)
733
scale /= new_unprojected_radius;
734
(*brush_size)= (int)((float)(*brush_size) * scale);
476
737
/* Brush Painting */
478
739
typedef struct BrushPainterCache {
481
int size; /* size override, if 0 uses brush->size */
742
int size; /* size override, if 0 uses 2*brush_size(brush) */
482
743
short flt; /* need float imbuf? */
483
744
short texonly; /* no alpha, color or fallof, only texture in imbuf */
759
1033
static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pressure)
761
if (brush->flag & BRUSH_ALPHA_PRESSURE)
762
brush->alpha = MAX2(0.0, painter->startalpha*pressure);
763
if (brush->flag & BRUSH_SIZE_PRESSURE)
764
brush->size = MAX2(1.0, painter->startsize*pressure);
1035
if (brush_use_alpha_pressure(painter->scene, brush))
1036
brush_set_alpha(painter->scene, brush, MAX2(0.0f, painter->startalpha*pressure));
1037
if (brush_use_size_pressure(painter->scene, brush))
1038
brush_set_size(painter->scene, brush, MAX2(1.0f, painter->startsize*pressure));
765
1039
if (brush->flag & BRUSH_JITTER_PRESSURE)
766
brush->jitter = MAX2(0.0, painter->startjitter*pressure);
1040
brush->jitter = MAX2(0.0f, painter->startjitter*pressure);
767
1041
if (brush->flag & BRUSH_SPACING_PRESSURE)
768
brush->spacing = MAX2(1.0, painter->startspacing*(1.5f-pressure));
1042
brush->spacing = MAX2(1.0f, painter->startspacing*(1.5f-pressure));
771
void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
1045
void brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
1047
int use_jitter= brush->jitter != 0;
1049
/* jitter-ed brush gives weird and unpredictable result for this
1050
* kinds of stroke, so manyally disable jitter usage (sergey) */
1051
use_jitter &= (brush->flag & (BRUSH_RESTORE_MESH|BRUSH_ANCHORED)) == 0;
774
1054
float rand_pos[2];
1055
const int radius= brush_size(scene, brush);
1056
const int diameter= 2*radius;
776
1058
// find random position within a circle of diameter 1
862
1147
len= normalize_v2(dmousepos);
863
1148
painter->accumdistance += len;
865
/* do paint op over unpainted distance */
866
while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
867
step= spacing - startdistance;
868
paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
869
paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
872
press= (1.0f-t)*painter->lastpressure + t*pressure;
873
brush_apply_pressure(painter, brush, press);
874
spacing= MAX2(1.0f, brush->size)*brush->spacing*0.01f;
876
brush_jitter_pos(brush, paintpos, finalpos);
1150
if (brush->flag & BRUSH_SPACE) {
1151
/* do paint op over unpainted distance */
1152
while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
1153
step= spacing - startdistance;
1154
paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
1155
paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
1158
press= (1.0f-t)*painter->lastpressure + t*pressure;
1159
brush_apply_pressure(painter, brush, press);
1160
spacing= MAX2(1.0f, radius)*brush->spacing*0.01f;
1162
brush_jitter_pos(scene, brush, paintpos, finalpos);
1164
if (painter->cache.enabled)
1165
brush_painter_refresh_cache(painter, finalpos, use_color_correction);
1168
func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
1170
painter->lastpaintpos[0]= paintpos[0];
1171
painter->lastpaintpos[1]= paintpos[1];
1172
painter->accumdistance -= spacing;
1173
startdistance -= spacing;
1177
brush_jitter_pos(scene, brush, pos, finalpos);
878
1179
if (painter->cache.enabled)
879
brush_painter_refresh_cache(painter, finalpos);
882
func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
884
painter->lastpaintpos[0]= paintpos[0];
885
painter->lastpaintpos[1]= paintpos[1];
886
painter->accumdistance -= spacing;
887
startdistance -= spacing;
1180
brush_painter_refresh_cache(painter, finalpos, use_color_correction);
1182
totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
1184
painter->lastpaintpos[0]= pos[0];
1185
painter->lastpaintpos[1]= pos[1];
1186
painter->accumdistance= 0;
890
1189
/* do airbrush paint ops, based on the number of paint ops left over
891
from regular painting. this is a temporary solution until we have
892
accurate time stamps for mouse move events */
1190
* from regular painting. this is a temporary solution until we have
1191
* accurate time stamps for mouse move events */
893
1192
if (brush->flag & BRUSH_AIRBRUSH) {
894
1193
double curtime= time;
895
1194
double painttime= brush->rate*totpaintops;
1038
void brush_radial_control_invoke(wmOperator *op, Brush *br, float size_weight)
1040
int mode = RNA_int_get(op->ptr, "mode");
1041
float original_value= 0;
1043
if(mode == WM_RADIALCONTROL_SIZE)
1044
original_value = sculpt_get_brush_size(br) * size_weight;
1045
else if(mode == WM_RADIALCONTROL_STRENGTH)
1046
original_value = sculpt_get_brush_alpha(br);
1047
else if(mode == WM_RADIALCONTROL_ANGLE) {
1048
MTex *mtex = brush_active_texture(br);
1050
original_value = mtex->rot;
1053
RNA_float_set(op->ptr, "initial_value", original_value);
1054
op->customdata = brush_gen_radial_control_imbuf(br);
1057
int brush_radial_control_exec(wmOperator *op, Brush *br, float size_weight)
1059
int mode = RNA_int_get(op->ptr, "mode");
1060
float new_value = RNA_float_get(op->ptr, "new_value");
1061
const float conv = 0.017453293;
1063
if(mode == WM_RADIALCONTROL_SIZE)
1064
if (sculpt_get_lock_brush_size(br)) {
1065
float initial_value = RNA_float_get(op->ptr, "initial_value");
1066
const float unprojected_radius = sculpt_get_brush_unprojected_radius(br);
1067
sculpt_set_brush_unprojected_radius(br, unprojected_radius * new_value/initial_value * size_weight);
1070
sculpt_set_brush_size(br, new_value * size_weight);
1071
else if(mode == WM_RADIALCONTROL_STRENGTH)
1072
sculpt_set_brush_alpha(br, new_value);
1073
else if(mode == WM_RADIALCONTROL_ANGLE) {
1074
MTex *mtex = brush_active_texture(br);
1076
mtex->rot = new_value * conv;
1079
return OPERATOR_FINISHED;