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