2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenkernel/intern/brush.c
36 #include "MEM_guardedalloc.h"
38 #include "DNA_brush_types.h"
39 #include "DNA_color_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_windowmanager_types.h"
46 #include "RNA_access.h"
48 #include "BLI_bpath.h"
50 #include "BLI_blenlib.h"
52 #include "BLI_utildefines.h"
54 #include "BKE_brush.h"
55 #include "BKE_colortools.h"
56 #include "BKE_global.h"
57 #include "BKE_image.h"
58 #include "BKE_library.h"
60 #include "BKE_paint.h"
61 #include "BKE_texture.h"
62 #include "BKE_icons.h"
64 #include "IMB_imbuf.h"
65 #include "IMB_imbuf_types.h"
67 #include "RE_render_ext.h" /* externtex */
68 #include "RE_shader_ext.h"
70 static void brush_set_defaults(Brush *brush)
75 brush->ob_mode = OB_MODE_ALL_PAINT;
77 /* BRUSH SCULPT TOOL SETTINGS */
78 brush->size= 35; /* radius of the brush in pixels */
79 brush->alpha= 0.5f; /* brush strength/intensity probably variable should be renamed? */
80 brush->autosmooth_factor= 0.0f;
81 brush->crease_pinch_factor= 0.5f;
82 brush->sculpt_plane = SCULPT_DISP_DIR_AREA;
83 brush->plane_offset= 0.0f; /* how far above or below the plane that is found by averaging the faces */
84 brush->plane_trim= 0.5f;
85 brush->clone.alpha= 0.5f;
86 brush->normal_weight= 0.0f;
87 brush->flag |= BRUSH_ALPHA_PRESSURE;
89 /* BRUSH PAINT TOOL SETTINGS */
90 brush->rgb[0]= 1.0f; /* default rgb color of the brush when painting - white */
94 /* BRUSH STROKE SETTINGS */
95 brush->flag |= (BRUSH_SPACE|BRUSH_SPACE_ATTEN);
96 brush->spacing= 10; /* how far each brush dot should be spaced as a percentage of brush diameter */
98 brush->smooth_stroke_radius= 75;
99 brush->smooth_stroke_factor= 0.9f;
101 brush->rate= 0.1f; /* time delay between dots of paint or sculpting when doing airbrush mode */
105 /* BRUSH TEXTURE SETTINGS */
106 default_mtex(&brush->mtex);
108 brush->texture_sample_bias= 0; /* value to added to texture samples */
109 brush->texture_overlay_alpha= 33;
111 /* brush appearance */
113 brush->add_col[0]= 1.00; /* add mode color is light red */
114 brush->add_col[1]= 0.39;
115 brush->add_col[2]= 0.39;
117 brush->sub_col[0]= 0.39; /* subtract mode color is light blue */
118 brush->sub_col[1]= 0.39;
119 brush->sub_col[2]= 1.00;
122 /* Datablock add/copy/free/make_local */
124 Brush *add_brush(const char *name)
128 brush= alloc_libblock(&G.main->brush, ID_BR, name);
130 /* enable fake user by default */
131 brush->id.flag |= LIB_FAKEUSER;
133 brush_set_defaults(brush);
135 brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */
137 /* the default alpha falloff curve */
138 brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
143 Brush *copy_brush(Brush *brush)
147 brushn= copy_libblock(&brush->id);
150 id_us_plus((ID*)brush->mtex.tex);
152 if (brush->icon_imbuf)
153 brushn->icon_imbuf= IMB_dupImBuf(brush->icon_imbuf);
155 brushn->preview = NULL;
157 brushn->curve= curvemapping_copy(brush->curve);
159 /* enable fake user by default */
160 if (!(brushn->id.flag & LIB_FAKEUSER)) {
161 brushn->id.flag |= LIB_FAKEUSER;
168 /* not brush itself */
169 void free_brush(Brush *brush)
172 brush->mtex.tex->id.us--;
174 if (brush->icon_imbuf)
175 IMB_freeImBuf(brush->icon_imbuf);
177 BKE_previewimg_free(&(brush->preview));
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);
188 void make_local_brush(Brush *brush)
191 /* - only lib users: do nothing
192 * - only local users: set flag
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);
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;
216 if(is_local && is_lib == FALSE) {
217 id_clear_lib_data(bmain, &brush->id);
218 extern_local_brush(brush);
220 /* enable fake user by default */
221 if (!(brush->id.flag & LIB_FAKEUSER)) {
222 brush->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);
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:
336 brush_debug_print_state(br);
339 brush_set_defaults(br);
340 brush_curve_preset(br, CURVE_PRESET_SMOOTH);
342 switch(br->sculpt_tool) {
343 case SCULPT_TOOL_CLAY:
344 br->flag |= BRUSH_FRONTFACE;
346 case SCULPT_TOOL_CREASE:
347 br->flag |= BRUSH_DIR_IN;
350 case SCULPT_TOOL_FILL:
352 br->sub_col[0] = 0.25;
355 case SCULPT_TOOL_FLATTEN:
357 br->sub_col[0] = 0.25;
360 case SCULPT_TOOL_INFLATE:
361 br->add_col[0] = 0.750000;
362 br->add_col[1] = 0.750000;
363 br->add_col[2] = 0.750000;
364 br->sub_col[0] = 0.250000;
365 br->sub_col[1] = 0.250000;
366 br->sub_col[2] = 0.250000;
368 case SCULPT_TOOL_NUDGE:
369 br->add_col[0] = 0.250000;
370 br->add_col[1] = 1.000000;
371 br->add_col[2] = 0.250000;
373 case SCULPT_TOOL_PINCH:
374 br->add_col[0] = 0.750000;
375 br->add_col[1] = 0.750000;
376 br->add_col[2] = 0.750000;
377 br->sub_col[0] = 0.250000;
378 br->sub_col[1] = 0.250000;
379 br->sub_col[2] = 0.250000;
381 case SCULPT_TOOL_SCRAPE:
382 br->add_col[1] = 1.000000;
383 br->sub_col[0] = 0.250000;
384 br->sub_col[1] = 1.000000;
386 case SCULPT_TOOL_ROTATE:
389 case SCULPT_TOOL_SMOOTH:
390 br->flag &= ~BRUSH_SPACE_ATTEN;
392 br->add_col[0] = 0.750000;
393 br->add_col[1] = 0.750000;
394 br->add_col[2] = 0.750000;
396 case SCULPT_TOOL_GRAB:
397 case SCULPT_TOOL_SNAKE_HOOK:
398 case SCULPT_TOOL_THUMB:
400 br->flag &= ~BRUSH_ALPHA_PRESSURE;
401 br->flag &= ~BRUSH_SPACE;
402 br->flag &= ~BRUSH_SPACE_ATTEN;
403 br->add_col[0] = 0.250000;
404 br->add_col[1] = 1.000000;
405 br->add_col[2] = 0.250000;
412 /* Library Operations */
413 void brush_curve_preset(Brush *b, /*CurveMappingPreset*/int preset)
418 b->curve = curvemapping_add(1, 0, 0, 1, 1);
421 cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
423 b->curve->preset = preset;
424 curvemap_reset(cm, &b->curve->clipr, b->curve->preset, CURVEMAP_SLOPE_NEGATIVE);
425 curvemapping_changed(b->curve, 0);
428 int brush_texture_set_nr(Brush *brush, int nr)
430 ID *idtest, *id=NULL;
432 id= (ID *)brush->mtex.tex;
434 idtest= (ID*)BLI_findlink(&G.main->tex, nr-1);
435 if(idtest==NULL) { /* new tex */
436 if(id) idtest= (ID *)copy_texture((Tex *)id);
437 else idtest= (ID *)add_texture("Tex");
441 brush_texture_delete(brush);
443 brush->mtex.tex= (Tex*)idtest;
452 int brush_texture_delete(Brush *brush)
455 brush->mtex.tex->id.us--;
460 int brush_clone_image_set_nr(Brush *brush, int nr)
462 if(brush && nr > 0) {
463 Image *ima= (Image*)BLI_findlink(&G.main->image, nr-1);
466 brush_clone_image_delete(brush);
467 brush->clone.image= ima;
468 id_us_plus(&ima->id);
469 brush->clone.offset[0]= brush->clone.offset[1]= 0.0f;
478 int brush_clone_image_delete(Brush *brush)
480 if (brush && brush->clone.image) {
481 brush->clone.image->id.us--;
482 brush->clone.image= NULL;
490 void brush_sample_tex(Brush *brush, float *xy, float *rgba, const int thread)
492 MTex *mtex= &brush->mtex;
494 if (mtex && mtex->tex) {
495 float co[3], tin, tr, tg, tb, ta;
497 const int radius= brush_size(brush);
503 hasrgb= externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread);
519 rgba[0]= rgba[1]= rgba[2]= rgba[3]= 1.0f;
523 void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction)
526 float xy[2], dist, rgba[4], *dstf;
527 int x, y, rowbytes, xoff, yoff, imbflag;
528 const int radius= brush_size(brush);
530 const float alpha= brush_alpha(brush);
533 imbflag= (flt)? IB_rectfloat: IB_rect;
534 xoff = -bufsize/2.0f + 0.5f;
535 yoff = -bufsize/2.0f + 0.5f;
541 ibuf= IMB_allocImBuf(bufsize, bufsize, 32, imbflag);
544 copy_v3_v3(brush_rgb, brush->rgb);
545 if(use_color_correction){
546 srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
549 for (y=0; y < ibuf->y; y++) {
550 dstf = ibuf->rect_float + y*rowbytes;
552 for (x=0; x < ibuf->x; x++, dstf+=4) {
557 dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
559 copy_v3_v3(dstf, brush_rgb);
560 dstf[3]= alpha*brush_curve_strength_clamp(brush, dist, radius);
562 else if (texfall == 1) {
563 brush_sample_tex(brush, xy, dstf, 0);
566 dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
568 brush_sample_tex(brush, xy, rgba, 0);
569 mul_v3_v3v3(dstf, rgba, brush_rgb);
570 dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius);
576 crgb[0]= FTOCHAR(brush->rgb[0]);
577 crgb[1]= FTOCHAR(brush->rgb[1]);
578 crgb[2]= FTOCHAR(brush->rgb[2]);
580 for (y=0; y < ibuf->y; y++) {
581 dst = (char*)ibuf->rect + y*rowbytes;
583 for (x=0; x < ibuf->x; x++, dst+=4) {
588 dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
593 dst[3]= FTOCHAR(alpha*brush_curve_strength(brush, dist, radius));
595 else if (texfall == 1) {
596 brush_sample_tex(brush, xy, rgba, 0);
597 dst[0]= FTOCHAR(rgba[0]);
598 dst[1]= FTOCHAR(rgba[1]);
599 dst[2]= FTOCHAR(rgba[2]);
600 dst[3]= FTOCHAR(rgba[3]);
602 else if (texfall == 2) {
603 dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
605 brush_sample_tex(brush, xy, rgba, 0);
606 dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]);
607 dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]);
608 dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]);
609 dst[3] = FTOCHAR(rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius));
611 dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
613 brush_sample_tex(brush, xy, rgba, 0);
617 dst[3] = FTOCHAR(rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius));
628 typedef struct BrushPainterCache {
631 int size; /* size override, if 0 uses 2*brush_size(brush) */
632 short flt; /* need float imbuf? */
633 short texonly; /* no alpha, color or fallof, only texture in imbuf */
644 struct BrushPainter {
647 float lastmousepos[2]; /* mouse position of last paint call */
649 float accumdistance; /* accumulated distance of brush since last paint op */
650 float lastpaintpos[2]; /* position of last paint op */
651 float startpaintpos[2]; /* position of first paint */
653 double accumtime; /* accumulated time since last paint op (airbrush) */
654 double lasttime; /* time of last update */
658 short firsttouch; /* first paint op */
665 BrushPainterCache cache;
668 BrushPainter *brush_painter_new(Brush *brush)
670 BrushPainter *painter= MEM_callocN(sizeof(BrushPainter), "BrushPainter");
672 painter->brush= brush;
673 painter->firsttouch= 1;
674 painter->cache.lastsize= -1; /* force ibuf create in refresh */
676 painter->startsize = brush_size(brush);
677 painter->startalpha = brush_alpha(brush);
678 painter->startjitter = brush->jitter;
679 painter->startspacing = brush->spacing;
684 void brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
686 if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
687 ((painter->cache.texonly != texonly) && texonly)) {
688 if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
689 if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
690 painter->cache.ibuf= painter->cache.maskibuf= NULL;
691 painter->cache.lastsize= -1; /* force ibuf create in refresh */
694 if (painter->cache.flt != flt) {
695 if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
696 painter->cache.texibuf= NULL;
697 painter->cache.lastsize= -1; /* force ibuf create in refresh */
700 painter->cache.size= size;
701 painter->cache.flt= flt;
702 painter->cache.texonly= texonly;
703 painter->cache.enabled= 1;
706 void brush_painter_free(BrushPainter *painter)
708 Brush *brush = painter->brush;
710 brush_set_size(brush, painter->startsize);
711 brush_set_alpha(brush, painter->startalpha);
712 brush->jitter = painter->startjitter;
713 brush->spacing = painter->startspacing;
715 if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
716 if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
717 if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
721 static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, int x, int y, int w, int h, int xt, int yt, float *pos)
723 Brush *brush= painter->brush;
724 ImBuf *ibuf, *maskibuf, *texibuf;
725 float *bf, *mf, *tf, *otf=NULL, xoff, yoff, xy[2], rgba[4];
726 char *b, *m, *t, *ot= NULL;
727 int dotexold, origx= x, origy= y;
728 const int radius= brush_size(brush);
730 xoff = -radius + 0.5f;
731 yoff = -radius + 0.5f;
732 xoff += (int)pos[0] - (int)painter->startpaintpos[0];
733 yoff += (int)pos[1] - (int)painter->startpaintpos[1];
735 ibuf = painter->cache.ibuf;
736 texibuf = painter->cache.texibuf;
737 maskibuf = painter->cache.maskibuf;
739 dotexold = (oldtexibuf != NULL);
741 /* not sure if it's actually needed or it's a mistake in coords/sizes
742 calculation in brush_painter_fixed_tex_partial_update(), but without this
743 limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
744 w = MIN2(w, ibuf->x);
745 h = MIN2(h, ibuf->y);
747 if (painter->cache.flt) {
749 bf = ibuf->rect_float + (y*ibuf->x + origx)*4;
750 tf = texibuf->rect_float + (y*texibuf->x + origx)*4;
751 mf = maskibuf->rect_float + (y*maskibuf->x + origx)*4;
754 otf = oldtexibuf->rect_float + ((y - origy + yt)*oldtexibuf->x + xt)*4;
756 for (x=origx; x < w; x++, bf+=4, mf+=4, tf+=4) {
766 brush_sample_tex(brush, xy, tf, 0);
778 b = (char*)ibuf->rect + (y*ibuf->x + origx)*4;
779 t = (char*)texibuf->rect + (y*texibuf->x + origx)*4;
780 m = (char*)maskibuf->rect + (y*maskibuf->x + origx)*4;
783 ot = (char*)oldtexibuf->rect + ((y - origy + yt)*oldtexibuf->x + xt)*4;
785 for (x=origx; x < w; x++, b+=4, m+=4, t+=4) {
797 brush_sample_tex(brush, xy, rgba, 0);
798 t[0]= FTOCHAR(rgba[0]);
799 t[1]= FTOCHAR(rgba[1]);
800 t[2]= FTOCHAR(rgba[2]);
801 t[3]= FTOCHAR(rgba[3]);
804 b[0] = t[0]*m[0]/255;
805 b[1] = t[1]*m[1]/255;
806 b[2] = t[2]*m[2]/255;
807 b[3] = t[3]*m[3]/255;
813 static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos)
815 Brush *brush= painter->brush;
816 BrushPainterCache *cache= &painter->cache;
817 ImBuf *oldtexibuf, *ibuf;
818 int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
819 const int diameter= 2*brush_size(brush);
821 imbflag= (cache->flt)? IB_rectfloat: IB_rect;
823 cache->ibuf= IMB_allocImBuf(diameter, diameter, 32, imbflag);
826 oldtexibuf= cache->texibuf;
827 cache->texibuf= IMB_allocImBuf(diameter, diameter, 32, imbflag);
831 destx= (int)painter->lastpaintpos[0] - (int)pos[0];
832 desty= (int)painter->lastpaintpos[1] - (int)pos[1];
836 IMB_rectclip(cache->texibuf, oldtexibuf, &destx, &desty, &srcx, &srcy, &w, &h);
849 /* blend existing texture in new position */
850 if ((x1 < x2) && (y1 < y2))
851 brush_painter_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
854 IMB_freeImBuf(oldtexibuf);
856 /* sample texture in new areas */
857 if ((0 < x1) && (0 < ibuf->y))
858 brush_painter_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
859 if ((x2 < ibuf->x) && (0 < ibuf->y))
860 brush_painter_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
861 if ((x1 < x2) && (0 < y1))
862 brush_painter_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
863 if ((x1 < x2) && (y2 < ibuf->y))
864 brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
867 static void brush_painter_refresh_cache(BrushPainter *painter, float *pos, int use_color_correction)
869 Brush *brush= painter->brush;
870 BrushPainterCache *cache= &painter->cache;
871 MTex *mtex= &brush->mtex;
874 const int diameter= 2*brush_size(brush);
875 const float alpha= brush_alpha(brush);
877 if (diameter != cache->lastsize ||
878 alpha != cache->lastalpha ||
879 brush->jitter != cache->lastjitter)
882 IMB_freeImBuf(cache->ibuf);
885 if (cache->maskibuf) {
886 IMB_freeImBuf(cache->maskibuf);
887 cache->maskibuf= NULL;
891 size= (cache->size)? cache->size: diameter;
893 if (brush->flag & BRUSH_FIXED_TEX) {
894 brush_imbuf_new(brush, flt, 3, size, &cache->maskibuf, use_color_correction);
895 brush_painter_fixed_tex_partial_update(painter, pos);
898 brush_imbuf_new(brush, flt, 2, size, &cache->ibuf, use_color_correction);
900 cache->lastsize= diameter;
901 cache->lastalpha= alpha;
902 cache->lastjitter= brush->jitter;
904 else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) {
905 int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
906 int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
908 if ((dx != 0) || (dy != 0))
909 brush_painter_fixed_tex_partial_update(painter, pos);
913 void brush_painter_break_stroke(BrushPainter *painter)
915 painter->firsttouch= 1;
918 static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pressure)
920 if (brush_use_alpha_pressure(brush))
921 brush_set_alpha(brush, MAX2(0.0f, painter->startalpha*pressure));
922 if (brush_use_size_pressure(brush))
923 brush_set_size(brush, MAX2(1.0f, painter->startsize*pressure));
924 if (brush->flag & BRUSH_JITTER_PRESSURE)
925 brush->jitter = MAX2(0.0f, painter->startjitter*pressure);
926 if (brush->flag & BRUSH_SPACING_PRESSURE)
927 brush->spacing = MAX2(1.0f, painter->startspacing*(1.5f-pressure));
930 void brush_jitter_pos(Brush *brush, float pos[2], float jitterpos[2])
932 int use_jitter= brush->jitter != 0;
934 /* jitter-ed brush gives weird and unpredictable result for this
935 kinds of stroke, so manyally disable jitter usage (sergey) */
936 use_jitter&= (brush->flag & (BRUSH_RESTORE_MESH|BRUSH_ANCHORED)) == 0;
940 const int radius= brush_size(brush);
941 const int diameter= 2*radius;
943 // find random position within a circle of diameter 1
945 rand_pos[0] = BLI_frand()-0.5f;
946 rand_pos[1] = BLI_frand()-0.5f;
947 } while (len_v2(rand_pos) > 0.5f);
949 jitterpos[0] = pos[0] + 2*rand_pos[0]*diameter*brush->jitter;
950 jitterpos[1] = pos[1] + 2*rand_pos[1]*diameter*brush->jitter;
953 copy_v2_v2(jitterpos, pos);
957 int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user, int use_color_correction)
959 Brush *brush= painter->brush;
962 if (pressure == 0.0f) {
963 if(painter->lastpressure) // XXX - hack, operator misses
964 pressure= painter->lastpressure;
966 pressure = 1.0f; /* zero pressure == not using tablet */
968 if (painter->firsttouch) {
969 /* paint exactly once on first touch */
970 painter->startpaintpos[0]= pos[0];
971 painter->startpaintpos[1]= pos[1];
973 brush_apply_pressure(painter, brush, pressure);
974 if (painter->cache.enabled)
975 brush_painter_refresh_cache(painter, pos, use_color_correction);
976 totpaintops += func(user, painter->cache.ibuf, pos, pos);
978 painter->lasttime= time;
979 painter->firsttouch= 0;
980 painter->lastpaintpos[0]= pos[0];
981 painter->lastpaintpos[1]= pos[1];
984 else if (painter->brush->flag & BRUSH_AIRBRUSH) {
985 float spacing, step, paintpos[2], dmousepos[2], len;
986 double starttime, curtime= time;
988 /* compute brush spacing adapted to brush size */
989 spacing= brush->rate; //radius*brush->spacing*0.01f;
991 /* setup starting time, direction vector and accumulated time */
992 starttime= painter->accumtime;
993 sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
994 len= normalize_v2(dmousepos);
995 painter->accumtime += curtime - painter->lasttime;
997 /* do paint op over unpainted time distance */
998 while (painter->accumtime >= spacing) {
999 step= (spacing - starttime)*len;
1000 paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
1001 paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
1003 if (painter->cache.enabled)
1004 brush_painter_refresh_cache(painter);
1005 totpaintops += func(user, painter->cache.ibuf,
1006 painter->lastpaintpos, paintpos);
1008 painter->lastpaintpos[0]= paintpos[0];
1009 painter->lastpaintpos[1]= paintpos[1];
1010 painter->accumtime -= spacing;
1011 starttime -= spacing;
1014 painter->lasttime= curtime;
1018 float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
1019 float t, len, press;
1020 const int radius= brush_size(brush);
1022 /* compute brush spacing adapted to brush radius, spacing may depend
1023 on pressure, so update it */
1024 brush_apply_pressure(painter, brush, painter->lastpressure);
1025 spacing= MAX2(1.0f, radius)*brush->spacing*0.01f;
1027 /* setup starting distance, direction vector and accumulated distance */
1028 startdistance= painter->accumdistance;
1029 sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
1030 len= normalize_v2(dmousepos);
1031 painter->accumdistance += len;
1033 if (brush->flag & BRUSH_SPACE) {
1034 /* do paint op over unpainted distance */
1035 while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
1036 step= spacing - startdistance;
1037 paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
1038 paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
1041 press= (1.0f-t)*painter->lastpressure + t*pressure;
1042 brush_apply_pressure(painter, brush, press);
1043 spacing= MAX2(1.0f, radius)*brush->spacing*0.01f;
1045 brush_jitter_pos(brush, paintpos, finalpos);
1047 if (painter->cache.enabled)
1048 brush_painter_refresh_cache(painter, finalpos, use_color_correction);
1051 func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
1053 painter->lastpaintpos[0]= paintpos[0];
1054 painter->lastpaintpos[1]= paintpos[1];
1055 painter->accumdistance -= spacing;
1056 startdistance -= spacing;
1059 brush_jitter_pos(brush, pos, finalpos);
1061 if (painter->cache.enabled)
1062 brush_painter_refresh_cache(painter, finalpos, use_color_correction);
1064 totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
1066 painter->lastpaintpos[0]= pos[0];
1067 painter->lastpaintpos[1]= pos[1];
1068 painter->accumdistance= 0;
1071 /* do airbrush paint ops, based on the number of paint ops left over
1072 from regular painting. this is a temporary solution until we have
1073 accurate time stamps for mouse move events */
1074 if (brush->flag & BRUSH_AIRBRUSH) {
1075 double curtime= time;
1076 double painttime= brush->rate*totpaintops;
1078 painter->accumtime += curtime - painter->lasttime;
1079 if (painter->accumtime <= painttime)
1080 painter->accumtime= 0.0;
1082 painter->accumtime -= painttime;
1084 while (painter->accumtime >= (double)brush->rate) {
1085 brush_apply_pressure(painter, brush, pressure);
1087 brush_jitter_pos(brush, pos, finalpos);
1089 if (painter->cache.enabled)
1090 brush_painter_refresh_cache(painter, finalpos, use_color_correction);
1093 func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
1094 painter->accumtime -= (double)brush->rate;
1097 painter->lasttime= curtime;
1101 painter->lastmousepos[0]= pos[0];
1102 painter->lastmousepos[1]= pos[1];
1103 painter->lastpressure= pressure;
1105 brush_set_alpha(brush, painter->startalpha);
1106 brush_set_size(brush, painter->startsize);
1107 brush->jitter = painter->startjitter;
1108 brush->spacing = painter->startspacing;
1113 /* Uses the brush curve control to find a strength value between 0 and 1 */
1114 float brush_curve_strength_clamp(Brush *br, float p, const float len)
1116 if(p >= len) return 0;
1119 p= curvemapping_evaluateF(br->curve, 0, p);
1120 if(p < 0.0f) p= 0.0f;
1121 else if(p > 1.0f) p= 1.0f;
1124 /* same as above but can return negative values if the curve enables
1125 * used for sculpt only */
1126 float brush_curve_strength(Brush *br, float p, const float len)
1133 return curvemapping_evaluateF(br->curve, 0, p);
1136 /* TODO: should probably be unified with BrushPainter stuff? */
1137 unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
1139 unsigned int *texcache = NULL;
1140 MTex *mtex = &br->mtex;
1141 TexResult texres= {0};
1143 int side = half_side * 2;
1146 float x, y, step = 2.0 / side, co[3];
1148 texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
1150 BKE_image_get_ibuf(mtex->tex->ima, NULL);
1152 /*do normalized cannonical view coords for texture*/
1153 for (y=-1.0, iy=0; iy<side; iy++, y += step) {
1154 for (x=-1.0, ix=0; ix<side; ix++, x += step) {
1159 /* This is copied from displace modifier code */
1160 hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres);
1162 /* if the texture gave an RGB value, we assume it didn't give a valid
1163 * intensity, so calculate one (formula from do_material_tex).
1164 * if the texture didn't give an RGB value, copy the intensity across
1166 if(hasrgb & TEX_RGB)
1167 texres.tin = (0.35f * texres.tr + 0.45f *
1168 texres.tg + 0.2f * texres.tb);
1170 texres.tin = texres.tin * 255.0f;
1171 ((char*)texcache)[(iy*side+ix)*4] = (char)texres.tin;
1172 ((char*)texcache)[(iy*side+ix)*4+1] = (char)texres.tin;
1173 ((char*)texcache)[(iy*side+ix)*4+2] = (char)texres.tin;
1174 ((char*)texcache)[(iy*side+ix)*4+3] = (char)texres.tin;
1182 /**** Radial Control ****/
1183 struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
1185 ImBuf *im = MEM_callocN(sizeof(ImBuf), "radial control texture");
1186 unsigned int *texcache;
1188 int half = side / 2;
1191 texcache = brush_gen_texture_cache(br, half);
1192 im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect");
1193 im->x = im->y = side;
1195 for(i=0; i<side; ++i) {
1196 for(j=0; j<side; ++j) {
1197 float magn= sqrt(pow(i - half, 2) + pow(j - half, 2));
1198 im->rect_float[i*side + j]= brush_curve_strength_clamp(br, magn, half);
1202 /* Modulate curve with texture */
1204 for(i=0; i<side; ++i) {
1205 for(j=0; j<side; ++j) {
1206 const int col= texcache[i*side+j];
1207 im->rect_float[i*side+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
1211 MEM_freeN(texcache);
1217 /* Unified Size and Strength */
1219 /* XXX, wouldnt it be better to only pass the active scene?
1220 * this can return any old scene! - campbell*/
1222 static void set_unified_settings(Brush *brush, short flag, int value)
1225 for (sce= G.main->scene.first; sce; sce= sce->id.next) {
1226 if (sce->toolsettings &&
1228 paint_brush(&(sce->toolsettings->imapaint.paint)),
1229 paint_brush(&(sce->toolsettings->vpaint->paint)),
1230 paint_brush(&(sce->toolsettings->wpaint->paint)),
1231 paint_brush(&(sce->toolsettings->sculpt->paint))))
1234 sce->toolsettings->unified_paint_settings.flag |= flag;
1236 sce->toolsettings->unified_paint_settings.flag &= ~flag;
1241 static short unified_settings(Brush *brush)
1244 for (sce= G.main->scene.first; sce; sce= sce->id.next) {
1245 if (sce->toolsettings &&
1247 paint_brush(&(sce->toolsettings->imapaint.paint)),
1248 paint_brush(&(sce->toolsettings->vpaint->paint)),
1249 paint_brush(&(sce->toolsettings->wpaint->paint)),
1250 paint_brush(&(sce->toolsettings->sculpt->paint))))
1252 return sce->toolsettings->unified_paint_settings.flag;
1259 // XXX: be careful about setting size and unprojected radius
1260 // because they depend on one another
1261 // these functions do not set the other corresponding value
1262 // this can lead to odd behavior if size and unprojected
1263 // radius become inconsistent.
1264 // the biggest problem is that it isn't possible to change
1265 // unprojected radius because a view context is not
1266 // available. my ussual solution to this is to use the
1267 // ratio of change of the size to change the unprojected
1268 // radius. Not completely convinced that is correct.
1269 // In anycase, a better solution is needed to prevent
1272 static void set_unified_size(Brush *brush, int value)
1275 for (sce= G.main->scene.first; sce; sce= sce->id.next) {
1276 if (sce->toolsettings &&
1278 paint_brush(&(sce->toolsettings->imapaint.paint)),
1279 paint_brush(&(sce->toolsettings->vpaint->paint)),
1280 paint_brush(&(sce->toolsettings->wpaint->paint)),
1281 paint_brush(&(sce->toolsettings->sculpt->paint))))
1283 sce->toolsettings->unified_paint_settings.size= value;
1288 static int unified_size(Brush *brush)
1291 for (sce= G.main->scene.first; sce; sce= sce->id.next) {
1292 if (sce->toolsettings &&
1294 paint_brush(&(sce->toolsettings->imapaint.paint)),
1295 paint_brush(&(sce->toolsettings->vpaint->paint)),
1296 paint_brush(&(sce->toolsettings->wpaint->paint)),
1297 paint_brush(&(sce->toolsettings->sculpt->paint))))
1299 return sce->toolsettings->unified_paint_settings.size;
1303 return 35; // XXX magic number
1306 static void set_unified_alpha(Brush *brush, float value)
1309 for (sce= G.main->scene.first; sce; sce= sce->id.next) {
1310 if (sce->toolsettings &&
1312 paint_brush(&(sce->toolsettings->imapaint.paint)),
1313 paint_brush(&(sce->toolsettings->vpaint->paint)),
1314 paint_brush(&(sce->toolsettings->wpaint->paint)),
1315 paint_brush(&(sce->toolsettings->sculpt->paint))))
1317 sce->toolsettings->unified_paint_settings.alpha= value;
1322 static float unified_alpha(Brush *brush)
1325 for (sce= G.main->scene.first; sce; sce= sce->id.next) {
1326 if (sce->toolsettings &&
1328 paint_brush(&(sce->toolsettings->imapaint.paint)),
1329 paint_brush(&(sce->toolsettings->vpaint->paint)),
1330 paint_brush(&(sce->toolsettings->wpaint->paint)),
1331 paint_brush(&(sce->toolsettings->sculpt->paint))))
1333 return sce->toolsettings->unified_paint_settings.alpha;
1337 return 0.5f; // XXX magic number
1340 static void set_unified_unprojected_radius(Brush *brush, float value)
1343 for (sce= G.main->scene.first; sce; sce= sce->id.next) {
1344 if (sce->toolsettings &&
1346 paint_brush(&(sce->toolsettings->imapaint.paint)),
1347 paint_brush(&(sce->toolsettings->vpaint->paint)),
1348 paint_brush(&(sce->toolsettings->wpaint->paint)),
1349 paint_brush(&(sce->toolsettings->sculpt->paint))))
1351 sce->toolsettings->unified_paint_settings.unprojected_radius= value;
1356 static float unified_unprojected_radius(Brush *brush)
1359 for (sce= G.main->scene.first; sce; sce= sce->id.next) {
1360 if (sce->toolsettings &&
1362 paint_brush(&(sce->toolsettings->imapaint.paint)),
1363 paint_brush(&(sce->toolsettings->vpaint->paint)),
1364 paint_brush(&(sce->toolsettings->wpaint->paint)),
1365 paint_brush(&(sce->toolsettings->sculpt->paint))))
1367 return sce->toolsettings->unified_paint_settings.unprojected_radius;
1371 return 0.125f; // XXX magic number
1373 void brush_set_size(Brush *brush, int size)
1375 const short us_flag = unified_settings(brush);
1377 if (us_flag & UNIFIED_PAINT_SIZE)
1378 set_unified_size(brush, size);
1382 //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
1385 int brush_size(Brush *brush)
1387 const short us_flag = unified_settings(brush);
1389 return (us_flag & UNIFIED_PAINT_SIZE) ? unified_size(brush) : brush->size;
1392 void brush_set_use_locked_size(Brush *brush, int value)
1394 const short us_flag = unified_settings(brush);
1396 if (us_flag & UNIFIED_PAINT_SIZE) {
1397 set_unified_settings(brush, UNIFIED_PAINT_BRUSH_LOCK_SIZE, value);
1401 brush->flag |= BRUSH_LOCK_SIZE;
1403 brush->flag &= ~BRUSH_LOCK_SIZE;
1406 //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
1409 int brush_use_locked_size(Brush *brush)
1411 const short us_flag = unified_settings(brush);
1413 return (us_flag & UNIFIED_PAINT_SIZE) ?
1414 (us_flag & UNIFIED_PAINT_BRUSH_LOCK_SIZE) :
1415 (brush->flag & BRUSH_LOCK_SIZE);
1418 void brush_set_use_size_pressure(Brush *brush, int value)
1420 const short us_flag = unified_settings(brush);
1422 if (us_flag & UNIFIED_PAINT_SIZE) {
1423 set_unified_settings(brush, UNIFIED_PAINT_BRUSH_SIZE_PRESSURE, value);
1427 brush->flag |= BRUSH_SIZE_PRESSURE;
1429 brush->flag &= ~BRUSH_SIZE_PRESSURE;
1432 //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
1435 int brush_use_size_pressure(Brush *brush)
1437 const short us_flag = unified_settings(brush);
1439 return (us_flag & UNIFIED_PAINT_SIZE) ?
1440 (us_flag & UNIFIED_PAINT_BRUSH_SIZE_PRESSURE) :
1441 (brush->flag & BRUSH_SIZE_PRESSURE);
1444 void brush_set_use_alpha_pressure(Brush *brush, int value)
1446 const short us_flag = unified_settings(brush);
1448 if (us_flag & UNIFIED_PAINT_ALPHA) {
1449 set_unified_settings(brush, UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE, value);
1453 brush->flag |= BRUSH_ALPHA_PRESSURE;
1455 brush->flag &= ~BRUSH_ALPHA_PRESSURE;
1458 //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
1461 int brush_use_alpha_pressure(Brush *brush)
1463 const short us_flag = unified_settings(brush);
1465 return (us_flag & UNIFIED_PAINT_ALPHA) ?
1466 (us_flag & UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE) :
1467 (brush->flag & BRUSH_ALPHA_PRESSURE);
1470 void brush_set_unprojected_radius(Brush *brush, float unprojected_radius)
1472 const short us_flag = unified_settings(brush);
1474 if (us_flag & UNIFIED_PAINT_SIZE)
1475 set_unified_unprojected_radius(brush, unprojected_radius);
1477 brush->unprojected_radius= unprojected_radius;
1479 //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
1482 float brush_unprojected_radius(Brush *brush)
1484 const short us_flag = unified_settings(brush);
1486 return (us_flag & UNIFIED_PAINT_SIZE) ?
1487 unified_unprojected_radius(brush) :
1488 brush->unprojected_radius;
1491 void brush_set_alpha(Brush *brush, float alpha)
1493 const short us_flag = unified_settings(brush);
1495 if (us_flag & UNIFIED_PAINT_ALPHA)
1496 set_unified_alpha(brush, alpha);
1498 brush->alpha= alpha;
1500 //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
1503 float brush_alpha(Brush *brush)
1505 const short us_flag = unified_settings(brush);
1507 return (us_flag & UNIFIED_PAINT_ALPHA) ?
1508 unified_alpha(brush) :