Fix [#22160] blender 2.5 alpha2 can't open file grass.blend from blenderguru
[blender.git] / source / blender / blenkernel / intern / brush.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <math.h>
31 #include <string.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_brush_types.h"
36 #include "DNA_color_types.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_windowmanager_types.h"
39
40 #include "WM_types.h"
41
42 #include "RNA_access.h"
43
44 #include "BLI_math.h"
45 #include "BLI_blenlib.h"
46 #include "BLI_rand.h"
47
48 #include "BKE_brush.h"
49 #include "BKE_colortools.h"
50 #include "BKE_global.h"
51 #include "BKE_image.h"
52 #include "BKE_library.h"
53 #include "BKE_main.h"
54 #include "BKE_paint.h"
55 #include "BKE_texture.h"
56
57
58
59 #include "IMB_imbuf.h"
60 #include "IMB_imbuf_types.h"
61
62 #include "RE_render_ext.h" /* externtex */
63 #include "RE_shader_ext.h"
64
65 /* Datablock add/copy/free/make_local */
66
67 Brush *add_brush(const char *name)
68 {
69         Brush *brush;
70
71         brush= alloc_libblock(&G.main->brush, ID_BR, name);
72
73         brush->rgb[0]= 1.0f;
74         brush->rgb[1]= 1.0f;
75         brush->rgb[2]= 1.0f;
76         brush->alpha= 0.2f;
77         brush->size= 25;
78         brush->spacing= 7.5f;
79         brush->smooth_stroke_radius= 75;
80         brush->smooth_stroke_factor= 0.9;
81         brush->rate= 0.1f;
82         brush->jitter= 0.0f;
83         brush->clone.alpha= 0.5;
84         brush->sculpt_tool = SCULPT_TOOL_DRAW;
85         brush->flag |= BRUSH_SPACE;
86
87         brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
88         
89         default_mtex(&brush->mtex);
90
91         /* enable fake user by default */
92         brush->id.flag |= LIB_FAKEUSER;
93         brush_toggled_fake_user(brush);
94         
95         return brush;   
96 }
97
98 Brush *copy_brush(Brush *brush)
99 {
100         Brush *brushn;
101         
102         brushn= copy_libblock(brush);
103
104         if(brush->mtex.tex) id_us_plus((ID*)brush->mtex.tex);
105         
106         brushn->curve= curvemapping_copy(brush->curve);
107
108         /* enable fake user by default */
109         if (!(brushn->id.flag & LIB_FAKEUSER)) {
110                 brushn->id.flag |= LIB_FAKEUSER;
111                 brush_toggled_fake_user(brushn);
112         }
113         
114         return brushn;
115 }
116
117 /* not brush itself */
118 void free_brush(Brush *brush)
119 {
120         if(brush->mtex.tex) brush->mtex.tex->id.us--;
121         
122         curvemapping_free(brush->curve);
123 }
124
125 void make_local_brush(Brush *brush)
126 {
127         /* - only lib users: do nothing
128                 * - only local users: set flag
129                 * - mixed: make copy
130                 */
131         
132         Brush *brushn;
133         Scene *scene;
134         int local= 0, lib= 0;
135
136         if(brush->id.lib==0) return;
137
138         if(brush->clone.image) {
139                 /* special case: ima always local immediately */
140                 brush->clone.image->id.lib= 0;
141                 brush->clone.image->id.flag= LIB_LOCAL;
142                 new_id(0, (ID *)brush->clone.image, 0);
143         }
144
145         for(scene= G.main->scene.first; scene; scene=scene->id.next)
146                 if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
147                         if(scene->id.lib) lib= 1;
148                         else local= 1;
149                 }
150         
151         if(local && lib==0) {
152                 brush->id.lib= 0;
153                 brush->id.flag= LIB_LOCAL;
154                 new_id(0, (ID *)brush, 0);
155
156                 /* enable fake user by default */
157                 if (!(brush->id.flag & LIB_FAKEUSER)) {
158                         brush->id.flag |= LIB_FAKEUSER;
159                         brush_toggled_fake_user(brush);
160                 }
161         }
162         else if(local && lib) {
163                 brushn= copy_brush(brush);
164                 brushn->id.us= 1; /* only keep fake user */
165                 brushn->id.flag |= LIB_FAKEUSER;
166                 
167                 for(scene= G.main->scene.first; scene; scene=scene->id.next)
168                         if(paint_brush(&scene->toolsettings->imapaint.paint)==brush)
169                                 if(scene->id.lib==0) {
170                                         paint_brush_set(&scene->toolsettings->imapaint.paint, brushn);
171                                         brushn->id.us++;
172                                         brush->id.us--;
173                                 }
174         }
175 }
176
177 /* Library Operations */
178
179 int brush_set_nr(Brush **current_brush, int nr, const char *name)
180 {
181         ID *idtest, *id;
182         
183         id= (ID*)(*current_brush);
184         idtest= (ID*)BLI_findlink(&G.main->brush, nr-1);
185         
186         if(idtest==0) { /* new brush */
187                 if(id) idtest= (ID *)copy_brush((Brush *)id);
188                 else idtest= (ID *)add_brush(name);
189                 idtest->us--;
190         }
191         if(idtest!=id) {
192                 brush_delete(current_brush);
193                 *current_brush= (Brush *)idtest;
194                 id_us_plus(idtest);
195
196                 return 1;
197         }
198
199         return 0;
200 }
201
202 int brush_delete(Brush **current_brush)
203 {
204         if (*current_brush) {
205                 (*current_brush)->id.us--;
206                 *current_brush= NULL;
207
208                 return 1;
209         }
210
211         return 0;
212 }
213
214 void brush_toggled_fake_user(Brush *brush)
215 {
216         ID *id= (ID*)brush;
217         if(id) {
218                 if(id->flag & LIB_FAKEUSER) {
219                         id_us_plus(id);
220                 } else {
221                         id->us--;
222                 }
223         }
224 }
225
226 void brush_curve_preset(Brush *b, /*CurveMappingPreset*/int preset)
227 {
228         CurveMap *cm = NULL;
229
230         if(!b->curve)
231                 b->curve = curvemapping_add(1, 0, 0, 1, 1);
232
233         cm = b->curve->cm;
234         cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
235
236         b->curve->preset = preset;
237         curvemap_reset(cm, &b->curve->clipr, b->curve->preset);
238         curvemapping_changed(b->curve, 0);
239 }
240
241 static MTex *brush_active_texture(Brush *brush)
242 {
243         if(brush)
244                 return &brush->mtex;
245         return NULL;
246 }
247
248 int brush_texture_set_nr(Brush *brush, int nr)
249 {
250         ID *idtest, *id=NULL;
251
252         id= (ID *)brush->mtex.tex;
253
254         idtest= (ID*)BLI_findlink(&G.main->tex, nr-1);
255         if(idtest==0) { /* new tex */
256                 if(id) idtest= (ID *)copy_texture((Tex *)id);
257                 else idtest= (ID *)add_texture("Tex");
258                 idtest->us--;
259         }
260         if(idtest!=id) {
261                 brush_texture_delete(brush);
262
263                 brush->mtex.tex= (Tex*)idtest;
264                 id_us_plus(idtest);
265
266                 return 1;
267         }
268
269         return 0;
270 }
271
272 int brush_texture_delete(Brush *brush)
273 {
274         if(brush->mtex.tex)
275                 brush->mtex.tex->id.us--;
276
277         return 1;
278 }
279
280 int brush_clone_image_set_nr(Brush *brush, int nr)
281 {
282         if(brush && nr > 0) {
283                 Image *ima= (Image*)BLI_findlink(&G.main->image, nr-1);
284
285                 if(ima) {
286                         brush_clone_image_delete(brush);
287                         brush->clone.image= ima;
288                         id_us_plus(&ima->id);
289                         brush->clone.offset[0]= brush->clone.offset[1]= 0.0f;
290
291                         return 1;
292                 }
293         }
294
295         return 0;
296 }
297
298 int brush_clone_image_delete(Brush *brush)
299 {
300         if (brush && brush->clone.image) {
301                 brush->clone.image->id.us--;
302                 brush->clone.image= NULL;
303                 return 1;
304         }
305
306         return 0;
307 }
308
309 void brush_check_exists(Brush **brush, const char *name)
310 {
311         if(*brush==NULL)
312                 brush_set_nr(brush, 1, name);
313 }
314
315 /* Brush Sampling */
316 void brush_sample_tex(Brush *brush, float *xy, float *rgba)
317 {
318         MTex *mtex= &brush->mtex;
319
320         if (mtex && mtex->tex) {
321                 float co[3], tin, tr, tg, tb, ta;
322                 int hasrgb;
323                 
324                 co[0]= xy[0]/(brush->size >> 1);
325                 co[1]= xy[1]/(brush->size >> 1);
326                 co[2]= 0.0f;
327
328                 hasrgb= externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
329
330                 if (hasrgb) {
331                         rgba[0]= tr;
332                         rgba[1]= tg;
333                         rgba[2]= tb;
334                         rgba[3]= ta;
335                 }
336                 else {
337                         rgba[0]= tin;
338                         rgba[1]= tin;
339                         rgba[2]= tin;
340                         rgba[3]= 1.0f;
341                 }
342         }
343         else if (rgba)
344                 rgba[0]= rgba[1]= rgba[2]= rgba[3]= 1.0f;
345 }
346
347
348 void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **outbuf)
349 {
350         ImBuf *ibuf;
351         float xy[2], dist, rgba[4], *dstf;
352         int x, y, rowbytes, xoff, yoff, imbflag;
353         int maxsize = brush->size >> 1;
354         char *dst, crgb[3];
355
356         imbflag= (flt)? IB_rectfloat: IB_rect;
357         xoff = -size/2.0f + 0.5f;
358         yoff = -size/2.0f + 0.5f;
359         rowbytes= size*4;
360
361         if (*outbuf)
362                 ibuf= *outbuf;
363         else
364                 ibuf= IMB_allocImBuf(size, size, 32, imbflag, 0);
365
366         if (flt) {
367                 for (y=0; y < ibuf->y; y++) {
368                         dstf = ibuf->rect_float + y*rowbytes;
369
370                         for (x=0; x < ibuf->x; x++, dstf+=4) {
371                                 xy[0] = x + xoff;
372                                 xy[1] = y + yoff;
373
374                                 if (texfall == 0) {
375                                         dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
376
377                                         VECCOPY(dstf, brush->rgb);
378                                         dstf[3]= brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize);
379                                 }
380                                 else if (texfall == 1) {
381                                         brush_sample_tex(brush, xy, dstf);
382                                 }
383                                 else {
384                                         dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
385
386                                         brush_sample_tex(brush, xy, rgba);
387
388                                         dstf[0] = rgba[0]*brush->rgb[0];
389                                         dstf[1] = rgba[1]*brush->rgb[1];
390                                         dstf[2] = rgba[2]*brush->rgb[2];
391                                         dstf[3] = rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize);
392                                 }
393                         }
394                 }
395         }
396         else {
397                 crgb[0]= FTOCHAR(brush->rgb[0]);
398                 crgb[1]= FTOCHAR(brush->rgb[1]);
399                 crgb[2]= FTOCHAR(brush->rgb[2]);
400
401                 for (y=0; y < ibuf->y; y++) {
402                         dst = (char*)ibuf->rect + y*rowbytes;
403
404                         for (x=0; x < ibuf->x; x++, dst+=4) {
405                                 xy[0] = x + xoff;
406                                 xy[1] = y + yoff;
407
408                                 if (texfall == 0) {
409                                         dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
410
411                                         dst[0]= crgb[0];
412                                         dst[1]= crgb[1];
413                                         dst[2]= crgb[2];
414                                         dst[3]= FTOCHAR(brush->alpha*brush_curve_strength(brush, dist, maxsize));
415                                 }
416                                 else if (texfall == 1) {
417                                         brush_sample_tex(brush, xy, rgba);
418                                         dst[0]= FTOCHAR(rgba[0]);
419                                         dst[1]= FTOCHAR(rgba[1]);
420                                         dst[2]= FTOCHAR(rgba[2]);
421                                         dst[3]= FTOCHAR(rgba[3]);
422                                 }
423                                 else {
424                                         dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
425
426                                         brush_sample_tex(brush, xy, rgba);
427                                         dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]);
428                                         dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]);
429                                         dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]);
430                                         dst[3] = FTOCHAR(rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize));
431                                 }
432                         }
433                 }
434         }
435
436         *outbuf= ibuf;
437 }
438
439 /* Brush Painting */
440
441 typedef struct BrushPainterCache {
442         short enabled;
443
444         int size;                       /* size override, if 0 uses brush->size */
445         short flt;                      /* need float imbuf? */
446         short texonly;          /* no alpha, color or fallof, only texture in imbuf */
447
448         int lastsize;
449         float lastalpha;
450         float lastjitter;
451
452         ImBuf *ibuf;
453         ImBuf *texibuf;
454         ImBuf *maskibuf;
455 } BrushPainterCache;
456
457 struct BrushPainter {
458         Brush *brush;
459
460         float lastmousepos[2];  /* mouse position of last paint call */
461
462         float accumdistance;    /* accumulated distance of brush since last paint op */
463         float lastpaintpos[2];  /* position of last paint op */
464         float startpaintpos[2]; /* position of first paint */
465
466         double accumtime;               /* accumulated time since last paint op (airbrush) */
467         double lasttime;                /* time of last update */
468
469         float lastpressure;
470
471         short firsttouch;               /* first paint op */
472
473         float startsize;
474         float startalpha;
475         float startjitter;
476         float startspacing;
477
478         BrushPainterCache cache;
479 };
480
481 BrushPainter *brush_painter_new(Brush *brush)
482 {
483         BrushPainter *painter= MEM_callocN(sizeof(BrushPainter), "BrushPainter");
484
485         painter->brush= brush;
486         painter->firsttouch= 1;
487         painter->cache.lastsize= -1; /* force ibuf create in refresh */
488
489         painter->startsize = brush->size;
490         painter->startalpha = brush->alpha;
491         painter->startjitter = brush->jitter;
492         painter->startspacing = brush->spacing;
493
494         return painter;
495 }
496
497 void brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
498 {
499         if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
500                 ((painter->cache.texonly != texonly) && texonly)) {
501                 if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
502                 if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
503                 painter->cache.ibuf= painter->cache.maskibuf= NULL;
504                 painter->cache.lastsize= -1; /* force ibuf create in refresh */
505         }
506
507         if (painter->cache.flt != flt) {
508                 if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
509                 painter->cache.texibuf= NULL;
510                 painter->cache.lastsize= -1; /* force ibuf create in refresh */
511         }
512
513         painter->cache.size= size;
514         painter->cache.flt= flt;
515         painter->cache.texonly= texonly;
516         painter->cache.enabled= 1;
517 }
518
519 void brush_painter_free(BrushPainter *painter)
520 {
521         Brush *brush = painter->brush;
522
523         brush->size = painter->startsize;
524         brush->alpha = painter->startalpha;
525         brush->jitter = painter->startjitter;
526         brush->spacing = painter->startspacing;
527
528         if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
529         if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
530         if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
531         MEM_freeN(painter);
532 }
533
534 static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, int x, int y, int w, int h, int xt, int yt, float *pos)
535 {
536         Brush *brush= painter->brush;
537         ImBuf *ibuf, *maskibuf, *texibuf;
538         float *bf, *mf, *tf, *otf=NULL, xoff, yoff, xy[2], rgba[4];
539         char *b, *m, *t, *ot= NULL;
540         int dotexold, origx= x, origy= y;
541
542         xoff = -brush->size/2.0f + 0.5f;
543         yoff = -brush->size/2.0f + 0.5f;
544         xoff += (int)pos[0] - (int)painter->startpaintpos[0];
545         yoff += (int)pos[1] - (int)painter->startpaintpos[1];
546
547         ibuf = painter->cache.ibuf;
548         texibuf = painter->cache.texibuf;
549         maskibuf = painter->cache.maskibuf;
550
551         dotexold = (oldtexibuf != NULL);
552
553         if (painter->cache.flt) {
554                 for (; y < h; y++) {
555                         bf = ibuf->rect_float + (y*ibuf->x + origx)*4;
556                         tf = texibuf->rect_float + (y*texibuf->x + origx)*4;
557                         mf = maskibuf->rect_float + (y*maskibuf->x + origx)*4;
558
559                         if (dotexold)
560                                 otf = oldtexibuf->rect_float + ((y - origy + yt)*oldtexibuf->x + xt)*4;
561
562                         for (x=origx; x < w; x++, bf+=4, mf+=4, tf+=4) {
563                                 if (dotexold) {
564                                         VECCOPY(tf, otf);
565                                         tf[3] = otf[3];
566                                         otf += 4;
567                                 }
568                                 else {
569                                         xy[0] = x + xoff;
570                                         xy[1] = y + yoff;
571
572                                         brush_sample_tex(brush, xy, tf);
573                                 }
574
575                                 bf[0] = tf[0]*mf[0];
576                                 bf[1] = tf[1]*mf[1];
577                                 bf[2] = tf[2]*mf[2];
578                                 bf[3] = tf[3]*mf[3];
579                         }
580                 }
581         }
582         else {
583                 for (; y < h; y++) {
584                         b = (char*)ibuf->rect + (y*ibuf->x + origx)*4;
585                         t = (char*)texibuf->rect + (y*texibuf->x + origx)*4;
586                         m = (char*)maskibuf->rect + (y*maskibuf->x + origx)*4;
587
588                         if (dotexold)
589                                 ot = (char*)oldtexibuf->rect + ((y - origy + yt)*oldtexibuf->x + xt)*4;
590
591                         for (x=origx; x < w; x++, b+=4, m+=4, t+=4) {
592                                 if (dotexold) {
593                                         t[0] = ot[0];
594                                         t[1] = ot[1];
595                                         t[2] = ot[2];
596                                         t[3] = ot[3];
597                                         ot += 4;
598                                 }
599                                 else {
600                                         xy[0] = x + xoff;
601                                         xy[1] = y + yoff;
602
603                                         brush_sample_tex(brush, xy, rgba);
604                                         t[0]= FTOCHAR(rgba[0]);
605                                         t[1]= FTOCHAR(rgba[1]);
606                                         t[2]= FTOCHAR(rgba[2]);
607                                         t[3]= FTOCHAR(rgba[3]);
608                                 }
609
610                                 b[0] = t[0]*m[0]/255;
611                                 b[1] = t[1]*m[1]/255;
612                                 b[2] = t[2]*m[2]/255;
613                                 b[3] = t[3]*m[3]/255;
614                         }
615                 }
616         }
617 }
618
619 static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos)
620 {
621         Brush *brush= painter->brush;
622         BrushPainterCache *cache= &painter->cache;
623         ImBuf *oldtexibuf, *ibuf;
624         int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
625
626         imbflag= (cache->flt)? IB_rectfloat: IB_rect;
627         if (!cache->ibuf)
628                 cache->ibuf= IMB_allocImBuf(brush->size, brush->size, 32, imbflag, 0);
629         ibuf= cache->ibuf;
630
631         oldtexibuf= cache->texibuf;
632         cache->texibuf= IMB_allocImBuf(brush->size, brush->size, 32, imbflag, 0);
633
634         if (oldtexibuf) {
635                 srcx= srcy= 0;
636                 destx= (int)painter->lastpaintpos[0] - (int)pos[0];
637                 desty= (int)painter->lastpaintpos[1] - (int)pos[1];
638                 w= oldtexibuf->x;
639                 h= oldtexibuf->y;
640
641                 IMB_rectclip(cache->texibuf, oldtexibuf, &destx, &desty, &srcx, &srcy, &w, &h);
642         }
643         else {
644                 srcx= srcy= 0;
645                 destx= desty= 0;
646                 w= h= 0;
647         }
648         
649         x1= destx;
650         y1= desty;
651         x2= destx+w;
652         y2= desty+h;
653
654         /* blend existing texture in new position */
655         if ((x1 < x2) && (y1 < y2))
656                 brush_painter_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
657
658         if (oldtexibuf)
659                 IMB_freeImBuf(oldtexibuf);
660
661         /* sample texture in new areas */
662         if ((0 < x1) && (0 < ibuf->y))
663                 brush_painter_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
664         if ((x2 < ibuf->x) && (0 < ibuf->y))
665                 brush_painter_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
666         if ((x1 < x2) && (0 < y1))
667                 brush_painter_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
668         if ((x1 < x2) && (y2 < ibuf->y))
669                 brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
670 }
671
672 static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
673 {
674         Brush *brush= painter->brush;
675         BrushPainterCache *cache= &painter->cache;
676         MTex *mtex= &brush->mtex;
677         int size;
678         short flt;
679
680         if ((brush->size != cache->lastsize) || (brush->alpha != cache->lastalpha)
681                 || (brush->jitter != cache->lastjitter)) {
682                 if (cache->ibuf) {
683                         IMB_freeImBuf(cache->ibuf);
684                         cache->ibuf= NULL;
685                 }
686                 if (cache->maskibuf) {
687                         IMB_freeImBuf(cache->maskibuf);
688                         cache->maskibuf= NULL;
689                 }
690
691                 flt= cache->flt;
692                 size= (cache->size)? cache->size: brush->size;
693
694                 if (!(mtex && mtex->tex) || (mtex->tex->type==0)) {
695                         brush_imbuf_new(brush, flt, 0, size, &cache->ibuf);
696                 }
697                 else if (brush->flag & BRUSH_FIXED_TEX) {
698                         brush_imbuf_new(brush, flt, 0, size, &cache->maskibuf);
699                         brush_painter_fixed_tex_partial_update(painter, pos);
700                 }
701                 else
702                         brush_imbuf_new(brush, flt, 2, size, &cache->ibuf);
703
704                 cache->lastsize= brush->size;
705                 cache->lastalpha= brush->alpha;
706                 cache->lastjitter= brush->jitter;
707         }
708         else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) {
709                 int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
710                 int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
711
712                 if ((dx != 0) || (dy != 0))
713                         brush_painter_fixed_tex_partial_update(painter, pos);
714         }
715 }
716
717 void brush_painter_break_stroke(BrushPainter *painter)
718 {
719         painter->firsttouch= 1;
720 }
721
722 static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pressure)
723 {
724         if (brush->flag & BRUSH_ALPHA_PRESSURE) 
725                 brush->alpha = MAX2(0.0, painter->startalpha*pressure);
726         if (brush->flag & BRUSH_SIZE_PRESSURE)
727                 brush->size = MAX2(1.0, painter->startsize*pressure);
728         if (brush->flag & BRUSH_JITTER_PRESSURE)
729                 brush->jitter = MAX2(0.0, painter->startjitter*pressure);
730         if (brush->flag & BRUSH_SPACING_PRESSURE)
731                 brush->spacing = MAX2(1.0, painter->startspacing*(1.5f-pressure));
732 }
733
734 static void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
735 {
736         if(brush->jitter){
737                 jitterpos[0] = pos[0] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2);
738                 jitterpos[1] = pos[1] + ((BLI_frand()-0.5f) * brush->size * brush->jitter * 2);
739         }
740         else {
741                 VECCOPY2D(jitterpos, pos);
742         }
743 }
744
745 int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
746 {
747         Brush *brush= painter->brush;
748         int totpaintops= 0;
749
750         if (pressure == 0.0f) {
751                 if(painter->lastpressure) // XXX - hack, operator misses
752                         pressure= painter->lastpressure;
753                 else
754                         pressure = 1.0f;        /* zero pressure == not using tablet */
755         }
756         if (painter->firsttouch) {
757                 /* paint exactly once on first touch */
758                 painter->startpaintpos[0]= pos[0];
759                 painter->startpaintpos[1]= pos[1];
760
761                 brush_apply_pressure(painter, brush, pressure);
762                 if (painter->cache.enabled)
763                         brush_painter_refresh_cache(painter, pos);
764                 totpaintops += func(user, painter->cache.ibuf, pos, pos);
765                 
766                 painter->lasttime= time;
767                 painter->firsttouch= 0;
768                 painter->lastpaintpos[0]= pos[0];
769                 painter->lastpaintpos[1]= pos[1];
770         }
771 #if 0
772         else if (painter->brush->flag & BRUSH_AIRBRUSH) {
773                 float spacing, step, paintpos[2], dmousepos[2], len;
774                 double starttime, curtime= time;
775
776                 /* compute brush spacing adapted to brush size */
777                 spacing= brush->rate; //brush->size*brush->spacing*0.01f;
778
779                 /* setup starting time, direction vector and accumulated time */
780                 starttime= painter->accumtime;
781                 sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
782                 len= normalize_v2(dmousepos);
783                 painter->accumtime += curtime - painter->lasttime;
784
785                 /* do paint op over unpainted time distance */
786                 while (painter->accumtime >= spacing) {
787                         step= (spacing - starttime)*len;
788                         paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
789                         paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
790
791                         if (painter->cache.enabled)
792                                 brush_painter_refresh_cache(painter);
793                         totpaintops += func(user, painter->cache.ibuf,
794                                 painter->lastpaintpos, paintpos);
795
796                         painter->lastpaintpos[0]= paintpos[0];
797                         painter->lastpaintpos[1]= paintpos[1];
798                         painter->accumtime -= spacing;
799                         starttime -= spacing;
800                 }
801                 
802                 painter->lasttime= curtime;
803         }
804 #endif
805         else {
806                 float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
807                 float t, len, press;
808
809                 /* compute brush spacing adapted to brush size, spacing may depend
810                    on pressure, so update it */
811                 brush_apply_pressure(painter, brush, painter->lastpressure);
812                 spacing= MAX2(1.0f, brush->size)*brush->spacing*0.01f;
813
814                 /* setup starting distance, direction vector and accumulated distance */
815                 startdistance= painter->accumdistance;
816                 sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
817                 len= normalize_v2(dmousepos);
818                 painter->accumdistance += len;
819
820                 /* do paint op over unpainted distance */
821                 while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
822                         step= spacing - startdistance;
823                         paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
824                         paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
825
826                         t = step/len;
827                         press= (1.0f-t)*painter->lastpressure + t*pressure;
828                         brush_apply_pressure(painter, brush, press);
829                         spacing= MAX2(1.0f, brush->size)*brush->spacing*0.01f;
830
831                         brush_jitter_pos(brush, paintpos, finalpos);
832
833                         if (painter->cache.enabled)
834                                 brush_painter_refresh_cache(painter, finalpos);
835
836                         totpaintops +=
837                                 func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
838
839                         painter->lastpaintpos[0]= paintpos[0];
840                         painter->lastpaintpos[1]= paintpos[1];
841                         painter->accumdistance -= spacing;
842                         startdistance -= spacing;
843                 }
844
845                 /* do airbrush paint ops, based on the number of paint ops left over
846                    from regular painting. this is a temporary solution until we have
847                    accurate time stamps for mouse move events */
848                 if (brush->flag & BRUSH_AIRBRUSH) {
849                         double curtime= time;
850                         double painttime= brush->rate*totpaintops;
851
852                         painter->accumtime += curtime - painter->lasttime;
853                         if (painter->accumtime <= painttime)
854                                 painter->accumtime= 0.0;
855                         else
856                                 painter->accumtime -= painttime;
857
858                         while (painter->accumtime >= brush->rate) {
859                                 brush_apply_pressure(painter, brush, pressure);
860
861                                 brush_jitter_pos(brush, pos, finalpos);
862
863                                 if (painter->cache.enabled)
864                                         brush_painter_refresh_cache(painter, finalpos);
865
866                                 totpaintops +=
867                                         func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
868                                 painter->accumtime -= brush->rate;
869                         }
870
871                         painter->lasttime= curtime;
872                 }
873         }
874
875         painter->lastmousepos[0]= pos[0];
876         painter->lastmousepos[1]= pos[1];
877         painter->lastpressure= pressure;
878
879         brush->alpha = painter->startalpha;
880         brush->size = painter->startsize;
881         brush->jitter = painter->startjitter;
882         brush->spacing = painter->startspacing;
883
884         return totpaintops;
885 }
886
887 /* Uses the brush curve control to find a strength value between 0 and 1 */
888 float brush_curve_strength_clamp(Brush *br, float p, const float len)
889 {
890         if(p >= len)    p= 1.0f;
891         else                    p= p/len;
892
893         p= curvemapping_evaluateF(br->curve, 0, p);
894         if(p < 0.0)                     p= 0.0f;
895         else if(p > 1.0f)       p= 1.0f;
896         return p;
897 }
898 /* same as above but can return negative values if the curve enables
899  * used for sculpt only */
900 float brush_curve_strength(Brush *br, float p, const float len)
901 {
902         if(p >= len)    p= 1.0f;
903         else                    p= p/len;
904         return curvemapping_evaluateF(br->curve, 0, p);
905 }
906
907 /* TODO: should probably be unified with BrushPainter stuff? */
908 unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
909 {
910         unsigned int *texcache = NULL;
911         MTex *mtex = &br->mtex;
912         TexResult texres;
913         int hasrgb, ix, iy;
914         int side = half_side * 2;
915
916         memset(&texres, 0, sizeof(TexResult));
917         
918         if(mtex && mtex->tex) {
919                 float x, y, step = 2.0 / side, co[3];
920
921                 texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
922
923                 BKE_image_get_ibuf(mtex->tex->ima, NULL);
924                 
925                 /*do normalized cannonical view coords for texture*/
926                 for (y=-1.0, iy=0; iy<side; iy++, y += step) {
927                         for (x=-1.0, ix=0; ix<side; ix++, x += step) {
928                                 co[0]= x;
929                                 co[1]= y;
930                                 co[2]= 0.0f;
931                                 
932                                 /* This is copied from displace modifier code */
933                                 hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres);
934                         
935                                 /* if the texture gave an RGB value, we assume it didn't give a valid
936                                  * intensity, so calculate one (formula from do_material_tex).
937                                  * if the texture didn't give an RGB value, copy the intensity across
938                                  */
939                                 if(hasrgb & TEX_RGB)
940                                         texres.tin = (0.35 * texres.tr + 0.45 *
941                                                                   texres.tg + 0.2 * texres.tb);
942
943                                 texres.tin = texres.tin * 255.0;
944                                 ((char*)texcache)[(iy*side+ix)*4] = (char)texres.tin;
945                                 ((char*)texcache)[(iy*side+ix)*4+1] = (char)texres.tin;
946                                 ((char*)texcache)[(iy*side+ix)*4+2] = (char)texres.tin;
947                                 ((char*)texcache)[(iy*side+ix)*4+3] = (char)texres.tin;
948                         }
949                 }
950         }
951
952         return texcache;
953 }
954
955 /**** Radial Control ****/
956 static struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
957 {
958         ImBuf *im = MEM_callocN(sizeof(ImBuf), "radial control texture");
959         unsigned int *texcache;
960         int side = 128;
961         int half = side / 2;
962         int i, j;
963
964         texcache = brush_gen_texture_cache(br, half);
965         im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect");
966         im->x = im->y = side;
967
968         for(i=0; i<side; ++i) {
969                 for(j=0; j<side; ++j) {
970                         float magn= sqrt(pow(i - half, 2) + pow(j - half, 2));
971                         im->rect_float[i*side + j]= brush_curve_strength_clamp(br, magn, half);
972                 }
973         }
974
975         /* Modulate curve with texture */
976         if(texcache) {
977                 for(i=0; i<side; ++i) {
978                         for(j=0; j<side; ++j) {
979                                 const int col= texcache[i*side+j];
980                                 im->rect_float[i*side+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
981                         }
982                 }
983
984                 MEM_freeN(texcache);
985         }
986
987         return im;
988 }
989
990 void brush_radial_control_invoke(wmOperator *op, Brush *br, float size_weight)
991 {
992         int mode = RNA_int_get(op->ptr, "mode");
993         float original_value= 0;
994
995         if(mode == WM_RADIALCONTROL_SIZE)
996                 original_value = br->size * size_weight;
997         else if(mode == WM_RADIALCONTROL_STRENGTH)
998                 original_value = br->alpha;
999         else if(mode == WM_RADIALCONTROL_ANGLE) {
1000                 MTex *mtex = brush_active_texture(br);
1001                 if(mtex)
1002                         original_value = mtex->rot;
1003         }
1004
1005         RNA_float_set(op->ptr, "initial_value", original_value);
1006         op->customdata = brush_gen_radial_control_imbuf(br);
1007 }
1008
1009 int brush_radial_control_exec(wmOperator *op, Brush *br, float size_weight)
1010 {
1011         int mode = RNA_int_get(op->ptr, "mode");
1012         float new_value = RNA_float_get(op->ptr, "new_value");
1013         const float conv = 0.017453293;
1014
1015         if(mode == WM_RADIALCONTROL_SIZE)
1016                 br->size = new_value * size_weight;
1017         else if(mode == WM_RADIALCONTROL_STRENGTH)
1018                 br->alpha = new_value;
1019         else if(mode == WM_RADIALCONTROL_ANGLE) {
1020                 MTex *mtex = brush_active_texture(br);
1021                 if(mtex)
1022                         mtex->rot = new_value * conv;
1023         }
1024
1025         return OPERATOR_FINISHED;
1026 }