~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/blenkernel/intern/brush.c

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * $Id: brush.c 30539 2010-07-20 13:42:27Z jwilkins $
3
 
 *
 
1
/*
4
2
 * ***** BEGIN GPL LICENSE BLOCK *****
5
3
 *
6
4
 * This program is free software; you can redistribute it and/or
27
25
 * ***** END GPL LICENSE BLOCK *****
28
26
 */
29
27
 
 
28
/** \file blender/blenkernel/intern/brush.c
 
29
 *  \ingroup bke
 
30
 */
 
31
 
 
32
 
30
33
#include <math.h>
31
34
#include <string.h>
32
35
 
35
38
#include "DNA_brush_types.h"
36
39
#include "DNA_color_types.h"
37
40
#include "DNA_scene_types.h"
 
41
#include "DNA_object_types.h"
38
42
#include "DNA_windowmanager_types.h"
39
43
 
40
44
#include "WM_types.h"
41
45
 
42
46
#include "RNA_access.h"
43
47
 
 
48
#include "BLI_bpath.h"
44
49
#include "BLI_math.h"
45
50
#include "BLI_blenlib.h"
46
51
#include "BLI_rand.h"
 
52
#include "BLI_utildefines.h"
47
53
 
48
54
#include "BKE_brush.h"
49
55
#include "BKE_colortools.h"
61
67
#include "RE_render_ext.h" /* externtex */
62
68
#include "RE_shader_ext.h"
63
69
 
64
 
/* Datablock add/copy/free/make_local */
65
 
 
66
 
Brush *add_brush(const char *name)
 
70
static void brush_set_defaults(Brush *brush)
67
71
{
68
 
        Brush *brush;
 
72
        brush->blend = 0;
 
73
        brush->flag = 0;
69
74
 
70
 
        brush= alloc_libblock(&G.main->brush, ID_BR, name);
 
75
        brush->ob_mode = OB_MODE_ALL_PAINT;
71
76
 
72
77
        /* BRUSH SCULPT TOOL SETTINGS */
73
 
        brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */
74
78
        brush->size= 35; /* radius of the brush in pixels */
75
79
        brush->alpha= 0.5f; /* brush strength/intensity probably variable should be renamed? */
76
80
        brush->autosmooth_factor= 0.0f;
77
81
        brush->crease_pinch_factor= 0.5f;
78
 
        brush->sculpt_plane = SCULPT_DISP_DIR_VIEW;
 
82
        brush->sculpt_plane = SCULPT_DISP_DIR_AREA;
79
83
        brush->plane_offset= 0.0f; /* how far above or below the plane that is found by averaging the faces */
80
84
        brush->plane_trim= 0.5f;
81
85
        brush->clone.alpha= 0.5f;
82
86
        brush->normal_weight= 0.0f;
 
87
        brush->flag |= BRUSH_ALPHA_PRESSURE;
83
88
 
84
89
        /* BRUSH PAINT TOOL SETTINGS */
85
90
        brush->rgb[0]= 1.0f; /* default rgb color of the brush when painting - white */
101
106
        default_mtex(&brush->mtex);
102
107
 
103
108
        brush->texture_sample_bias= 0; /* value to added to texture samples */
 
109
        brush->texture_overlay_alpha= 33;
104
110
 
105
111
        /* brush appearance  */
106
112
 
111
117
        brush->sub_col[0]= 0.39; /* subtract mode color is light blue */
112
118
        brush->sub_col[1]= 0.39;
113
119
        brush->sub_col[2]= 1.00;
 
120
}
 
121
 
 
122
/* Datablock add/copy/free/make_local */
 
123
 
 
124
Brush *add_brush(const char *name)
 
125
{
 
126
        Brush *brush;
 
127
 
 
128
        brush= alloc_libblock(&G.main->brush, ID_BR, name);
 
129
 
 
130
        /* enable fake user by default */
 
131
        brush->id.flag |= LIB_FAKEUSER;
 
132
 
 
133
        brush_set_defaults(brush);
 
134
 
 
135
        brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */
114
136
 
115
137
         /* the default alpha falloff curve */
116
138
        brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
117
139
 
118
 
        /* enable fake user by default */
119
 
        brush->id.flag |= LIB_FAKEUSER;
120
 
        brush_toggled_fake_user(brush);
121
 
 
122
140
        return brush;
123
141
}
124
142
 
126
144
{
127
145
        Brush *brushn;
128
146
        
129
 
        brushn= copy_libblock(brush);
 
147
        brushn= copy_libblock(&brush->id);
130
148
 
131
149
        if (brush->mtex.tex)
132
150
                id_us_plus((ID*)brush->mtex.tex);
134
152
        if (brush->icon_imbuf)
135
153
                brushn->icon_imbuf= IMB_dupImBuf(brush->icon_imbuf);
136
154
 
 
155
        brushn->preview = NULL;
 
156
 
137
157
        brushn->curve= curvemapping_copy(brush->curve);
138
158
 
139
159
        /* enable fake user by default */
140
160
        if (!(brushn->id.flag & LIB_FAKEUSER)) {
141
161
                brushn->id.flag |= LIB_FAKEUSER;
142
 
                brush_toggled_fake_user(brushn);
 
162
                brushn->id.us++;
143
163
        }
144
164
        
145
165
        return brushn;
159
179
        curvemapping_free(brush->curve);
160
180
}
161
181
 
 
182
static void extern_local_brush(Brush *brush)
 
183
{
 
184
        id_lib_extern((ID *)brush->mtex.tex);
 
185
        id_lib_extern((ID *)brush->clone.image);
 
186
}
 
187
 
162
188
void make_local_brush(Brush *brush)
163
189
{
 
190
 
164
191
        /* - only lib users: do nothing
165
 
                * - only local users: set flag
166
 
                * - mixed: make copy
167
 
                */
168
 
        
169
 
        Brush *brushn;
 
192
         * - only local users: set flag
 
193
         * - mixed: make copy
 
194
         */
 
195
 
 
196
        Main *bmain= G.main;
170
197
        Scene *scene;
171
 
        int local= 0, lib= 0;
172
 
 
173
 
        if(brush->id.lib==0) return;
174
 
 
175
 
        if(brush->clone.image) {
176
 
                /* special case: ima always local immediately */
177
 
                brush->clone.image->id.lib= 0;
178
 
                brush->clone.image->id.flag= LIB_LOCAL;
179
 
                new_id(0, (ID *)brush->clone.image, 0);
 
198
        int is_local= FALSE, is_lib= FALSE;
 
199
 
 
200
        if (brush->id.lib==NULL) return;
 
201
 
 
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);
180
207
        }
181
208
 
182
 
        for(scene= G.main->scene.first; scene; scene=scene->id.next)
183
 
                if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
184
 
                        if(scene->id.lib) lib= 1;
185
 
                        else local= 1;
 
209
        for (scene= bmain->scene.first; scene && ELEM(0, is_lib, is_local); scene=scene->id.next) {
 
210
                if (paint_brush(&scene->toolsettings->imapaint.paint)==brush) {
 
211
                        if (scene->id.lib) is_lib= TRUE;
 
212
                        else is_local= TRUE;
186
213
                }
 
214
        }
187
215
 
188
 
        if(local && lib==0) {
189
 
                brush->id.lib= 0;
190
 
                brush->id.flag= LIB_LOCAL;
191
 
                new_id(0, (ID *)brush, 0);
 
216
        if (is_local && is_lib == FALSE) {
 
217
                id_clear_lib_data(bmain, &brush->id);
 
218
                extern_local_brush(brush);
192
219
 
193
220
                /* enable fake user by default */
194
221
                if (!(brush->id.flag & LIB_FAKEUSER)) {
195
222
                        brush->id.flag |= LIB_FAKEUSER;
196
 
                        brush_toggled_fake_user(brush);
 
223
                        brush->id.us++;
197
224
                }
198
225
        }
199
 
        else if(local && lib) {
200
 
                brushn= copy_brush(brush);
201
 
                brushn->id.us= 1; /* only keep fake user */
202
 
                brushn->id.flag |= LIB_FAKEUSER;
 
226
        else if (is_local && is_lib) {
 
227
                Brush *brush_new= copy_brush(brush);
 
228
                brush_new->id.us= 1; /* only keep fake user */
 
229
                brush_new->id.flag |= LIB_FAKEUSER;
 
230
 
 
231
                /* Remap paths of new ID using old library as base. */
 
232
                BKE_id_lib_local_paths(bmain, brush->id.lib, &brush_new->id);
203
233
                
204
 
                for(scene= G.main->scene.first; scene; scene=scene->id.next)
205
 
                        if(paint_brush(&scene->toolsettings->imapaint.paint)==brush)
206
 
                                if(scene->id.lib==0) {
207
 
                                        paint_brush_set(&scene->toolsettings->imapaint.paint, brushn);
208
 
                                        brushn->id.us++;
209
 
                                        brush->id.us--;
 
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);
210
238
                                }
 
239
                        }
 
240
                }
 
241
        }
 
242
}
 
243
 
 
244
void brush_debug_print_state(Brush *br)
 
245
{
 
246
        /* create a fake brush and set it to the defaults */
 
247
        Brush def= {{NULL}};
 
248
        brush_set_defaults(&def);
 
249
        
 
250
#define BR_TEST(field, t)                                       \
 
251
        if (br->field != def.field)                             \
 
252
                printf("br->" #field " = %" #t ";\n", br->field)
 
253
 
 
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")
 
259
        
 
260
 
 
261
        /* print out any non-default brush state */
 
262
        BR_TEST(normal_weight, f);
 
263
 
 
264
        BR_TEST(blend, d);
 
265
        BR_TEST(size, d);
 
266
 
 
267
        /* br->flag */
 
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);
 
296
 
 
297
        BR_TEST(jitter, f);
 
298
        BR_TEST(spacing, d);
 
299
        BR_TEST(smooth_stroke_radius, d);
 
300
        BR_TEST(smooth_stroke_factor, f);
 
301
        BR_TEST(rate, f);
 
302
 
 
303
        BR_TEST(alpha, f);
 
304
 
 
305
        BR_TEST(sculpt_plane, d);
 
306
 
 
307
        BR_TEST(plane_offset, f);
 
308
 
 
309
        BR_TEST(autosmooth_factor, f);
 
310
 
 
311
        BR_TEST(crease_pinch_factor, f);
 
312
 
 
313
        BR_TEST(plane_trim, f);
 
314
 
 
315
        BR_TEST(texture_sample_bias, f);
 
316
        BR_TEST(texture_overlay_alpha, d);
 
317
 
 
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);
 
324
 
 
325
        printf("\n");
 
326
        
 
327
#undef BR_TEST
 
328
#undef BR_TEST_FLAG
 
329
}
 
330
 
 
331
void brush_reset_sculpt(Brush *br)
 
332
{
 
333
        /* enable this to see any non-default
 
334
         * settings used by a brush: */
 
335
        // brush_debug_print_state(br);
 
336
 
 
337
        brush_set_defaults(br);
 
338
        brush_curve_preset(br, CURVE_PRESET_SMOOTH);
 
339
 
 
340
        switch(br->sculpt_tool) {
 
341
        case SCULPT_TOOL_CLAY:
 
342
                br->flag |= BRUSH_FRONTFACE;
 
343
                break;
 
344
        case SCULPT_TOOL_CREASE:
 
345
                br->flag |= BRUSH_DIR_IN;
 
346
                br->alpha = 0.25;
 
347
                break;
 
348
        case SCULPT_TOOL_FILL:
 
349
                br->add_col[1] = 1;
 
350
                br->sub_col[0] = 0.25;
 
351
                br->sub_col[1] = 1;
 
352
                break;
 
353
        case SCULPT_TOOL_FLATTEN:
 
354
                br->add_col[1] = 1;
 
355
                br->sub_col[0] = 0.25;
 
356
                br->sub_col[1] = 1;
 
357
                break;
 
358
        case SCULPT_TOOL_INFLATE:
 
359
                br->add_col[0] = 0.750000;
 
360
                br->add_col[1] = 0.750000;
 
361
                br->add_col[2] = 0.750000;
 
362
                br->sub_col[0] = 0.250000;
 
363
                br->sub_col[1] = 0.250000;
 
364
                br->sub_col[2] = 0.250000;
 
365
                break;
 
366
        case SCULPT_TOOL_NUDGE:
 
367
                br->add_col[0] = 0.250000;
 
368
                br->add_col[1] = 1.000000;
 
369
                br->add_col[2] = 0.250000;
 
370
                break;
 
371
        case SCULPT_TOOL_PINCH:
 
372
                br->add_col[0] = 0.750000;
 
373
                br->add_col[1] = 0.750000;
 
374
                br->add_col[2] = 0.750000;
 
375
                br->sub_col[0] = 0.250000;
 
376
                br->sub_col[1] = 0.250000;
 
377
                br->sub_col[2] = 0.250000;
 
378
                break;
 
379
        case SCULPT_TOOL_SCRAPE:
 
380
                br->add_col[1] = 1.000000;
 
381
                br->sub_col[0] = 0.250000;
 
382
                br->sub_col[1] = 1.000000;
 
383
                break;
 
384
        case SCULPT_TOOL_ROTATE:
 
385
                br->alpha = 1.0;
 
386
                break;
 
387
        case SCULPT_TOOL_SMOOTH:
 
388
                br->flag &= ~BRUSH_SPACE_ATTEN;
 
389
                br->spacing = 5;
 
390
                br->add_col[0] = 0.750000;
 
391
                br->add_col[1] = 0.750000;
 
392
                br->add_col[2] = 0.750000;
 
393
                break;
 
394
        case SCULPT_TOOL_GRAB:
 
395
        case SCULPT_TOOL_SNAKE_HOOK:
 
396
        case SCULPT_TOOL_THUMB:
 
397
                br->size = 75;
 
398
                br->flag &= ~BRUSH_ALPHA_PRESSURE;
 
399
                br->flag &= ~BRUSH_SPACE;
 
400
                br->flag &= ~BRUSH_SPACE_ATTEN;
 
401
                br->add_col[0] = 0.250000;
 
402
                br->add_col[1] = 1.000000;
 
403
                br->add_col[2] = 0.250000;
 
404
                break;
 
405
        default:
 
406
                break;
211
407
        }
212
408
}
213
409
 
214
410
/* Library Operations */
215
 
 
216
 
int brush_set_nr(Brush **current_brush, int nr, const char *name)
217
 
{
218
 
        ID *idtest, *id;
219
 
        
220
 
        id= (ID*)(*current_brush);
221
 
        idtest= (ID*)BLI_findlink(&G.main->brush, nr-1);
222
 
        
223
 
        if(idtest==0) { /* new brush */
224
 
                if(id) idtest= (ID *)copy_brush((Brush *)id);
225
 
                else idtest= (ID *)add_brush(name);
226
 
                idtest->us--;
227
 
        }
228
 
        if(idtest!=id) {
229
 
                brush_delete(current_brush);
230
 
                *current_brush= (Brush *)idtest;
231
 
                id_us_plus(idtest);
232
 
 
233
 
                return 1;
234
 
        }
235
 
 
236
 
        return 0;
237
 
}
238
 
 
239
 
int brush_delete(Brush **current_brush)
240
 
{
241
 
        if (*current_brush) {
242
 
                (*current_brush)->id.us--;
243
 
                *current_brush= NULL;
244
 
 
245
 
                return 1;
246
 
        }
247
 
 
248
 
        return 0;
249
 
}
250
 
 
251
 
void brush_toggled_fake_user(Brush *brush)
252
 
{
253
 
        ID *id= (ID*)brush;
254
 
        if(id) {
255
 
                if(id->flag & LIB_FAKEUSER) {
256
 
                        id_us_plus(id);
257
 
                } else {
258
 
                        id->us--;
259
 
                }
260
 
        }
261
 
}
262
 
 
263
411
void brush_curve_preset(Brush *b, /*CurveMappingPreset*/int preset)
264
412
{
265
413
        CurveMap *cm = NULL;
266
414
 
267
 
        if(!b->curve)
 
415
        if (!b->curve)
268
416
                b->curve = curvemapping_add(1, 0, 0, 1, 1);
269
417
 
270
418
        cm = b->curve->cm;
271
419
        cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
272
420
 
273
421
        b->curve->preset = preset;
274
 
        curvemap_reset(cm, &b->curve->clipr, b->curve->preset);
 
422
        curvemap_reset(cm, &b->curve->clipr, b->curve->preset, CURVEMAP_SLOPE_NEGATIVE);
275
423
        curvemapping_changed(b->curve, 0);
276
424
}
277
425
 
278
 
static MTex *brush_active_texture(Brush *brush)
279
 
{
280
 
        if(brush)
281
 
                return &brush->mtex;
282
 
        return NULL;
283
 
}
284
 
 
285
426
int brush_texture_set_nr(Brush *brush, int nr)
286
427
{
287
428
        ID *idtest, *id=NULL;
289
430
        id= (ID *)brush->mtex.tex;
290
431
 
291
432
        idtest= (ID*)BLI_findlink(&G.main->tex, nr-1);
292
 
        if(idtest==0) { /* new tex */
293
 
                if(id) idtest= (ID *)copy_texture((Tex *)id);
 
433
        if (idtest==NULL) { /* new tex */
 
434
                if (id) idtest= (ID *)copy_texture((Tex *)id);
294
435
                else idtest= (ID *)add_texture("Tex");
295
436
                idtest->us--;
296
437
        }
297
 
        if(idtest!=id) {
 
438
        if (idtest!=id) {
298
439
                brush_texture_delete(brush);
299
440
 
300
441
                brush->mtex.tex= (Tex*)idtest;
308
449
 
309
450
int brush_texture_delete(Brush *brush)
310
451
{
311
 
        if(brush->mtex.tex)
 
452
        if (brush->mtex.tex)
312
453
                brush->mtex.tex->id.us--;
313
454
 
314
455
        return 1;
316
457
 
317
458
int brush_clone_image_set_nr(Brush *brush, int nr)
318
459
{
319
 
        if(brush && nr > 0) {
 
460
        if (brush && nr > 0) {
320
461
                Image *ima= (Image*)BLI_findlink(&G.main->image, nr-1);
321
462
 
322
 
                if(ima) {
 
463
                if (ima) {
323
464
                        brush_clone_image_delete(brush);
324
465
                        brush->clone.image= ima;
325
466
                        id_us_plus(&ima->id);
343
484
        return 0;
344
485
}
345
486
 
346
 
void brush_check_exists(Brush **brush, const char *name)
347
 
{
348
 
        if(*brush==NULL)
349
 
                brush_set_nr(brush, 1, name);
350
 
}
351
 
 
352
487
/* Brush Sampling */
353
 
void brush_sample_tex(Brush *brush, float *xy, float *rgba)
 
488
void brush_sample_tex(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], const int thread)
354
489
{
355
490
        MTex *mtex= &brush->mtex;
356
491
 
357
492
        if (mtex && mtex->tex) {
358
493
                float co[3], tin, tr, tg, tb, ta;
359
494
                int hasrgb;
360
 
                
361
 
                co[0]= xy[0]/(brush->size >> 1);
362
 
                co[1]= xy[1]/(brush->size >> 1);
 
495
                const int radius= brush_size(scene, brush);
 
496
 
 
497
                co[0]= xy[0]/radius;
 
498
                co[1]= xy[1]/radius;
363
499
                co[2]= 0.0f;
364
500
 
365
 
                hasrgb= externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
 
501
                hasrgb= externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread);
366
502
 
367
503
                if (hasrgb) {
368
504
                        rgba[0]= tr;
377
513
                        rgba[3]= 1.0f;
378
514
                }
379
515
        }
380
 
        else if (rgba)
 
516
        else {
381
517
                rgba[0]= rgba[1]= rgba[2]= rgba[3]= 1.0f;
 
518
        }
382
519
}
383
520
 
384
 
 
385
 
void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **outbuf)
 
521
/* TODO, use define for 'texfall' arg */
 
522
void brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction)
386
523
{
387
524
        ImBuf *ibuf;
388
 
        float xy[2], dist, rgba[4], *dstf;
 
525
        float xy[2], rgba[4], *dstf;
389
526
        int x, y, rowbytes, xoff, yoff, imbflag;
390
 
        int maxsize = brush->size >> 1;
391
 
        char *dst, crgb[3];
392
 
 
 
527
        const int radius= brush_size(scene, brush);
 
528
        unsigned char *dst, crgb[3];
 
529
        const float alpha= brush_alpha(scene, brush);
 
530
        float brush_rgb[3];
 
531
    
393
532
        imbflag= (flt)? IB_rectfloat: IB_rect;
394
 
        xoff = -size/2.0f + 0.5f;
395
 
        yoff = -size/2.0f + 0.5f;
396
 
        rowbytes= size*4;
 
533
        xoff = -bufsize/2.0f + 0.5f;
 
534
        yoff = -bufsize/2.0f + 0.5f;
 
535
        rowbytes= bufsize*4;
397
536
 
398
537
        if (*outbuf)
399
538
                ibuf= *outbuf;
400
539
        else
401
 
                ibuf= IMB_allocImBuf(size, size, 32, imbflag, 0);
 
540
                ibuf= IMB_allocImBuf(bufsize, bufsize, 32, imbflag);
402
541
 
403
542
        if (flt) {
 
543
                copy_v3_v3(brush_rgb, brush->rgb);
 
544
                if (use_color_correction) {
 
545
                        srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
 
546
                }
 
547
 
404
548
                for (y=0; y < ibuf->y; y++) {
405
549
                        dstf = ibuf->rect_float + y*rowbytes;
406
550
 
409
553
                                xy[1] = y + yoff;
410
554
 
411
555
                                if (texfall == 0) {
412
 
                                        dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
413
 
 
414
 
                                        VECCOPY(dstf, brush->rgb);
415
 
                                        dstf[3]= brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize);
 
556
                                        copy_v3_v3(dstf, brush_rgb);
 
557
                                        dstf[3]= alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius);
416
558
                                }
417
559
                                else if (texfall == 1) {
418
 
                                        brush_sample_tex(brush, xy, dstf);
 
560
                                        brush_sample_tex(scene, brush, xy, dstf, 0);
419
561
                                }
420
562
                                else {
421
 
                                        dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
422
 
 
423
 
                                        brush_sample_tex(brush, xy, rgba);
424
 
 
425
 
                                        dstf[0] = rgba[0]*brush->rgb[0];
426
 
                                        dstf[1] = rgba[1]*brush->rgb[1];
427
 
                                        dstf[2] = rgba[2]*brush->rgb[2];
428
 
                                        dstf[3] = rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize);
 
563
                                        brush_sample_tex(scene, brush, xy, rgba, 0);
 
564
                                        mul_v3_v3v3(dstf, rgba, brush_rgb);
 
565
                                        dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius);
429
566
                                }
430
567
                        }
431
568
                }
432
569
        }
433
570
        else {
434
 
                crgb[0]= FTOCHAR(brush->rgb[0]);
435
 
                crgb[1]= FTOCHAR(brush->rgb[1]);
436
 
                crgb[2]= FTOCHAR(brush->rgb[2]);
 
571
                float alpha_f; /* final float alpha to convert to char */
 
572
                rgb_float_to_uchar(crgb, brush->rgb);
437
573
 
438
574
                for (y=0; y < ibuf->y; y++) {
439
 
                        dst = (char*)ibuf->rect + y*rowbytes;
 
575
                        dst = (unsigned char *)ibuf->rect + y*rowbytes;
440
576
 
441
577
                        for (x=0; x < ibuf->x; x++, dst+=4) {
442
578
                                xy[0] = x + xoff;
443
579
                                xy[1] = y + yoff;
444
580
 
445
581
                                if (texfall == 0) {
446
 
                                        dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
 
582
                                        alpha_f = alpha * brush_curve_strength(brush, len_v2(xy), radius);
447
583
 
448
 
                                        dst[0]= crgb[0];
449
 
                                        dst[1]= crgb[1];
450
 
                                        dst[2]= crgb[2];
451
 
                                        dst[3]= FTOCHAR(brush->alpha*brush_curve_strength(brush, dist, maxsize));
 
584
                                        dst[0] = crgb[0];
 
585
                                        dst[1] = crgb[1];
 
586
                                        dst[2] = crgb[2];
 
587
                                        dst[3] = FTOCHAR(alpha_f);
452
588
                                }
453
589
                                else if (texfall == 1) {
454
 
                                        brush_sample_tex(brush, xy, rgba);
455
 
                                        dst[0]= FTOCHAR(rgba[0]);
456
 
                                        dst[1]= FTOCHAR(rgba[1]);
457
 
                                        dst[2]= FTOCHAR(rgba[2]);
458
 
                                        dst[3]= FTOCHAR(rgba[3]);
 
590
                                        brush_sample_tex(scene, brush, xy, rgba, 0);
 
591
                                        rgba_float_to_uchar(dst, rgba);
 
592
                                }
 
593
                                else if (texfall == 2) {
 
594
                                        brush_sample_tex(scene, brush, xy, rgba, 0);
 
595
                                        mul_v3_v3(rgba, brush->rgb);
 
596
                                        alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius);
 
597
 
 
598
                                        rgb_float_to_uchar(dst, rgba);
 
599
 
 
600
                                        dst[3] = FTOCHAR(alpha_f);
459
601
                                }
460
602
                                else {
461
 
                                        dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
 
603
                                        brush_sample_tex(scene, brush, xy, rgba, 0);
 
604
                                        alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius);
462
605
 
463
 
                                        brush_sample_tex(brush, xy, rgba);
464
 
                                        dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]);
465
 
                                        dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]);
466
 
                                        dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]);
467
 
                                        dst[3] = FTOCHAR(rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize));
 
606
                                        dst[0] = crgb[0];
 
607
                                        dst[1] = crgb[1];
 
608
                                        dst[2] = crgb[2];
 
609
                                        dst[3] = FTOCHAR(alpha_f);
468
610
                                }
469
611
                        }
470
612
                }
473
615
        *outbuf= ibuf;
474
616
}
475
617
 
 
618
/* Unified Size and Strength */
 
619
 
 
620
// XXX: be careful about setting size and unprojected radius
 
621
// because they depend on one another
 
622
// these functions do not set the other corresponding value
 
623
// this can lead to odd behavior if size and unprojected
 
624
// radius become inconsistent.
 
625
// the biggest problem is that it isn't possible to change
 
626
// unprojected radius because a view context is not
 
627
// available.  my ussual solution to this is to use the
 
628
// ratio of change of the size to change the unprojected
 
629
// radius.  Not completely convinced that is correct.
 
630
// In anycase, a better solution is needed to prevent
 
631
// inconsistency.
 
632
 
 
633
void brush_set_size(Scene *scene, Brush *brush, int size)
 
634
{
 
635
        UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
 
636
 
 
637
        if (ups->flag & UNIFIED_PAINT_SIZE)
 
638
                ups->size= size;
 
639
        else
 
640
                brush->size= size;
 
641
}
 
642
 
 
643
int brush_size(const Scene *scene, Brush *brush)
 
644
{
 
645
        UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
 
646
 
 
647
        return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
 
648
}
 
649
 
 
650
int brush_use_locked_size(const Scene *scene, Brush *brush)
 
651
{
 
652
        const short us_flag = scene->toolsettings->unified_paint_settings.flag;
 
653
 
 
654
        return (us_flag & UNIFIED_PAINT_SIZE) ?
 
655
                (us_flag & UNIFIED_PAINT_BRUSH_LOCK_SIZE) :
 
656
                (brush->flag & BRUSH_LOCK_SIZE);
 
657
}
 
658
 
 
659
int brush_use_size_pressure(const Scene *scene, Brush *brush)
 
660
{
 
661
        const short us_flag = scene->toolsettings->unified_paint_settings.flag;
 
662
 
 
663
        return (us_flag & UNIFIED_PAINT_SIZE) ?
 
664
                (us_flag & UNIFIED_PAINT_BRUSH_SIZE_PRESSURE) :
 
665
                (brush->flag & BRUSH_SIZE_PRESSURE);
 
666
}
 
667
 
 
668
int brush_use_alpha_pressure(const Scene *scene, Brush *brush)
 
669
{
 
670
        const short us_flag = scene->toolsettings->unified_paint_settings.flag;
 
671
 
 
672
        return (us_flag & UNIFIED_PAINT_ALPHA) ?
 
673
                (us_flag & UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE) :
 
674
                (brush->flag & BRUSH_ALPHA_PRESSURE);
 
675
}
 
676
 
 
677
void brush_set_unprojected_radius(Scene *scene, Brush *brush, float unprojected_radius)
 
678
{
 
679
        UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
 
680
 
 
681
        if (ups->flag & UNIFIED_PAINT_SIZE)
 
682
                ups->unprojected_radius= unprojected_radius;
 
683
        else
 
684
                brush->unprojected_radius= unprojected_radius;
 
685
}
 
686
 
 
687
float brush_unprojected_radius(const Scene *scene, Brush *brush)
 
688
{
 
689
        UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
 
690
 
 
691
        return (ups->flag & UNIFIED_PAINT_SIZE) ?
 
692
                ups->unprojected_radius :
 
693
                brush->unprojected_radius;
 
694
}
 
695
 
 
696
static void brush_set_alpha(Scene *scene, Brush *brush, float alpha)
 
697
{
 
698
        UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
 
699
 
 
700
        if (ups->flag & UNIFIED_PAINT_ALPHA)
 
701
                ups->alpha= alpha;
 
702
        else
 
703
                brush->alpha= alpha;
 
704
}
 
705
 
 
706
float brush_alpha(const Scene *scene, Brush *brush)
 
707
{
 
708
        UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
 
709
 
 
710
        return (ups->flag & UNIFIED_PAINT_ALPHA) ? ups->alpha : brush->alpha;
 
711
}
 
712
 
 
713
/* scale unprojected radius to reflect a change in the brush's 2D size */
 
714
void brush_scale_unprojected_radius(float *unprojected_radius,
 
715
                                                                        int new_brush_size,
 
716
                                                                        int old_brush_size)
 
717
{
 
718
        float scale = new_brush_size;
 
719
        /* avoid division by zero */
 
720
        if (old_brush_size != 0)
 
721
                scale /= (float)old_brush_size;
 
722
        (*unprojected_radius) *= scale;
 
723
}
 
724
 
 
725
/* scale brush size to reflect a change in the brush's unprojected radius */
 
726
void brush_scale_size(int *brush_size,
 
727
                                          float new_unprojected_radius,
 
728
                                          float old_unprojected_radius)
 
729
{
 
730
        float scale = new_unprojected_radius;
 
731
        /* avoid division by zero */
 
732
        if (old_unprojected_radius != 0)
 
733
                scale /= new_unprojected_radius;
 
734
        (*brush_size)= (int)((float)(*brush_size) * scale);
 
735
}
 
736
 
476
737
/* Brush Painting */
477
738
 
478
739
typedef struct BrushPainterCache {
479
740
        short enabled;
480
741
 
481
 
        int size;                       /* size override, if 0 uses brush->size */
 
742
        int size;                       /* size override, if 0 uses 2*brush_size(brush) */
482
743
        short flt;                      /* need float imbuf? */
483
744
        short texonly;          /* no alpha, color or fallof, only texture in imbuf */
484
745
 
492
753
} BrushPainterCache;
493
754
 
494
755
struct BrushPainter {
 
756
        Scene *scene;
495
757
        Brush *brush;
496
758
 
497
759
        float lastmousepos[2];  /* mouse position of last paint call */
515
777
        BrushPainterCache cache;
516
778
};
517
779
 
518
 
BrushPainter *brush_painter_new(Brush *brush)
 
780
BrushPainter *brush_painter_new(Scene *scene, Brush *brush)
519
781
{
520
782
        BrushPainter *painter= MEM_callocN(sizeof(BrushPainter), "BrushPainter");
521
783
 
522
784
        painter->brush= brush;
 
785
        painter->scene= scene;
523
786
        painter->firsttouch= 1;
524
787
        painter->cache.lastsize= -1; /* force ibuf create in refresh */
525
788
 
526
 
        painter->startsize = brush->size;
527
 
        painter->startalpha = brush->alpha;
 
789
        painter->startsize = brush_size(scene, brush);
 
790
        painter->startalpha = brush_alpha(scene, brush);
528
791
        painter->startjitter = brush->jitter;
529
792
        painter->startspacing = brush->spacing;
530
793
 
557
820
{
558
821
        Brush *brush = painter->brush;
559
822
 
560
 
        brush->size = painter->startsize;
561
 
        brush->alpha = painter->startalpha;
 
823
        brush_set_size(painter->scene, brush, painter->startsize);
 
824
        brush_set_alpha(painter->scene, brush, painter->startalpha);
562
825
        brush->jitter = painter->startjitter;
563
826
        brush->spacing = painter->startspacing;
564
827
 
568
831
        MEM_freeN(painter);
569
832
}
570
833
 
571
 
static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, int x, int y, int w, int h, int xt, int yt, float *pos)
 
834
static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
 
835
                                     int x, int y, int w, int h, int xt, int yt,
 
836
                                     const float pos[2])
572
837
{
 
838
        Scene *scene= painter->scene;
573
839
        Brush *brush= painter->brush;
574
840
        ImBuf *ibuf, *maskibuf, *texibuf;
575
841
        float *bf, *mf, *tf, *otf=NULL, xoff, yoff, xy[2], rgba[4];
576
 
        char *b, *m, *t, *ot= NULL;
 
842
        unsigned char *b, *m, *t, *ot= NULL;
577
843
        int dotexold, origx= x, origy= y;
 
844
        const int radius= brush_size(painter->scene, brush);
578
845
 
579
 
        xoff = -brush->size/2.0f + 0.5f;
580
 
        yoff = -brush->size/2.0f + 0.5f;
 
846
        xoff = -radius + 0.5f;
 
847
        yoff = -radius + 0.5f;
581
848
        xoff += (int)pos[0] - (int)painter->startpaintpos[0];
582
849
        yoff += (int)pos[1] - (int)painter->startpaintpos[1];
583
850
 
587
854
 
588
855
        dotexold = (oldtexibuf != NULL);
589
856
 
 
857
        /* not sure if it's actually needed or it's a mistake in coords/sizes
 
858
         * calculation in brush_painter_fixed_tex_partial_update(), but without this
 
859
         * limitation memory gets corrupted at fast strokes with quite big spacing (sergey) */
 
860
        w = MIN2(w, ibuf->x);
 
861
        h = MIN2(h, ibuf->y);
 
862
 
590
863
        if (painter->cache.flt) {
591
864
                for (; y < h; y++) {
592
865
                        bf = ibuf->rect_float + (y*ibuf->x + origx)*4;
598
871
 
599
872
                        for (x=origx; x < w; x++, bf+=4, mf+=4, tf+=4) {
600
873
                                if (dotexold) {
601
 
                                        VECCOPY(tf, otf);
 
874
                                        copy_v3_v3(tf, otf);
602
875
                                        tf[3] = otf[3];
603
876
                                        otf += 4;
604
877
                                }
606
879
                                        xy[0] = x + xoff;
607
880
                                        xy[1] = y + yoff;
608
881
 
609
 
                                        brush_sample_tex(brush, xy, tf);
 
882
                                        brush_sample_tex(scene, brush, xy, tf, 0);
610
883
                                }
611
884
 
612
885
                                bf[0] = tf[0]*mf[0];
618
891
        }
619
892
        else {
620
893
                for (; y < h; y++) {
621
 
                        b = (char*)ibuf->rect + (y*ibuf->x + origx)*4;
622
 
                        t = (char*)texibuf->rect + (y*texibuf->x + origx)*4;
623
 
                        m = (char*)maskibuf->rect + (y*maskibuf->x + origx)*4;
 
894
                        b = (unsigned char *)ibuf->rect + (y*ibuf->x + origx)*4;
 
895
                        t = (unsigned char *)texibuf->rect + (y*texibuf->x + origx)*4;
 
896
                        m = (unsigned char *)maskibuf->rect + (y*maskibuf->x + origx)*4;
624
897
 
625
898
                        if (dotexold)
626
 
                                ot = (char*)oldtexibuf->rect + ((y - origy + yt)*oldtexibuf->x + xt)*4;
 
899
                                ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt)*oldtexibuf->x + xt)*4;
627
900
 
628
901
                        for (x=origx; x < w; x++, b+=4, m+=4, t+=4) {
629
902
                                if (dotexold) {
637
910
                                        xy[0] = x + xoff;
638
911
                                        xy[1] = y + yoff;
639
912
 
640
 
                                        brush_sample_tex(brush, xy, rgba);
641
 
                                        t[0]= FTOCHAR(rgba[0]);
642
 
                                        t[1]= FTOCHAR(rgba[1]);
643
 
                                        t[2]= FTOCHAR(rgba[2]);
644
 
                                        t[3]= FTOCHAR(rgba[3]);
 
913
                                        brush_sample_tex(scene, brush, xy, rgba, 0);
 
914
                                        rgba_float_to_uchar(t, rgba);
645
915
                                }
646
916
 
647
917
                                b[0] = t[0]*m[0]/255;
653
923
        }
654
924
}
655
925
 
656
 
static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos)
 
926
static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, const float pos[2])
657
927
{
 
928
        const Scene *scene= painter->scene;
658
929
        Brush *brush= painter->brush;
659
930
        BrushPainterCache *cache= &painter->cache;
660
931
        ImBuf *oldtexibuf, *ibuf;
661
932
        int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
 
933
        const int diameter= 2*brush_size(scene, brush);
662
934
 
663
935
        imbflag= (cache->flt)? IB_rectfloat: IB_rect;
664
936
        if (!cache->ibuf)
665
 
                cache->ibuf= IMB_allocImBuf(brush->size, brush->size, 32, imbflag, 0);
 
937
                cache->ibuf= IMB_allocImBuf(diameter, diameter, 32, imbflag);
666
938
        ibuf= cache->ibuf;
667
939
 
668
940
        oldtexibuf= cache->texibuf;
669
 
        cache->texibuf= IMB_allocImBuf(brush->size, brush->size, 32, imbflag, 0);
 
941
        cache->texibuf= IMB_allocImBuf(diameter, diameter, 32, imbflag);
670
942
 
671
943
        if (oldtexibuf) {
672
944
                srcx= srcy= 0;
706
978
                brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
707
979
}
708
980
 
709
 
static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
 
981
static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
710
982
{
 
983
        const Scene *scene= painter->scene;
711
984
        Brush *brush= painter->brush;
712
985
        BrushPainterCache *cache= &painter->cache;
713
986
        MTex *mtex= &brush->mtex;
714
987
        int size;
715
988
        short flt;
 
989
        const int diameter= 2*brush_size(scene, brush);
 
990
        const float alpha= brush_alpha(scene, brush);
716
991
 
717
 
        if ((brush->size != cache->lastsize) || (brush->alpha != cache->lastalpha)
718
 
                || (brush->jitter != cache->lastjitter)) {
 
992
        if (diameter != cache->lastsize ||
 
993
                alpha != cache->lastalpha ||
 
994
                brush->jitter != cache->lastjitter)
 
995
        {
719
996
                if (cache->ibuf) {
720
997
                        IMB_freeImBuf(cache->ibuf);
721
998
                        cache->ibuf= NULL;
726
1003
                }
727
1004
 
728
1005
                flt= cache->flt;
729
 
                size= (cache->size)? cache->size: brush->size;
 
1006
                size= (cache->size)? cache->size: diameter;
730
1007
 
731
 
                if (!(mtex && mtex->tex) || (mtex->tex->type==0)) {
732
 
                        brush_imbuf_new(brush, flt, 0, size, &cache->ibuf);
733
 
                }
734
 
                else if (brush->flag & BRUSH_FIXED_TEX) {
735
 
                        brush_imbuf_new(brush, flt, 0, size, &cache->maskibuf);
 
1008
                if (brush->flag & BRUSH_FIXED_TEX) {
 
1009
                        brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
736
1010
                        brush_painter_fixed_tex_partial_update(painter, pos);
737
1011
                }
738
1012
                else
739
 
                        brush_imbuf_new(brush, flt, 2, size, &cache->ibuf);
 
1013
                        brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
740
1014
 
741
 
                cache->lastsize= brush->size;
742
 
                cache->lastalpha= brush->alpha;
 
1015
                cache->lastsize= diameter;
 
1016
                cache->lastalpha= alpha;
743
1017
                cache->lastjitter= brush->jitter;
744
1018
        }
745
1019
        else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) {
758
1032
 
759
1033
static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pressure)
760
1034
{
761
 
        if (brush->flag & BRUSH_ALPHA_PRESSURE) 
762
 
                brush->alpha = MAX2(0.0, painter->startalpha*pressure);
763
 
        if (brush->flag & BRUSH_SIZE_PRESSURE)
764
 
                brush->size = MAX2(1.0, painter->startsize*pressure);
 
1035
        if (brush_use_alpha_pressure(painter->scene, brush)) 
 
1036
                brush_set_alpha(painter->scene, brush, MAX2(0.0f, painter->startalpha*pressure));
 
1037
        if (brush_use_size_pressure(painter->scene, brush))
 
1038
                brush_set_size(painter->scene, brush, MAX2(1.0f, painter->startsize*pressure));
765
1039
        if (brush->flag & BRUSH_JITTER_PRESSURE)
766
 
                brush->jitter = MAX2(0.0, painter->startjitter*pressure);
 
1040
                brush->jitter = MAX2(0.0f, painter->startjitter*pressure);
767
1041
        if (brush->flag & BRUSH_SPACING_PRESSURE)
768
 
                brush->spacing = MAX2(1.0, painter->startspacing*(1.5f-pressure));
 
1042
                brush->spacing = MAX2(1.0f, painter->startspacing*(1.5f-pressure));
769
1043
}
770
1044
 
771
 
void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
 
1045
void brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
772
1046
{
773
 
        if(brush->jitter){
 
1047
        int use_jitter= brush->jitter != 0;
 
1048
 
 
1049
        /* jitter-ed brush gives weird and unpredictable result for this
 
1050
         * kinds of stroke, so manyally disable jitter usage (sergey) */
 
1051
        use_jitter &= (brush->flag & (BRUSH_RESTORE_MESH|BRUSH_ANCHORED)) == 0;
 
1052
 
 
1053
        if (use_jitter) {
774
1054
                float rand_pos[2];
 
1055
                const int radius= brush_size(scene, brush);
 
1056
                const int diameter= 2*radius;
775
1057
 
776
1058
                // find random position within a circle of diameter 1
777
1059
                do {
779
1061
                        rand_pos[1] = BLI_frand()-0.5f;
780
1062
                } while (len_v2(rand_pos) > 0.5f);
781
1063
 
782
 
                jitterpos[0] = pos[0] + 2*rand_pos[0]*brush->size*brush->jitter;
783
 
                jitterpos[1] = pos[1] + 2*rand_pos[1]*brush->size*brush->jitter;
 
1064
                jitterpos[0] = pos[0] + 2*rand_pos[0]*diameter*brush->jitter;
 
1065
                jitterpos[1] = pos[1] + 2*rand_pos[1]*diameter*brush->jitter;
784
1066
        }
785
1067
        else {
786
 
                VECCOPY2D(jitterpos, pos);
 
1068
                copy_v2_v2(jitterpos, pos);
787
1069
        }
788
1070
}
789
1071
 
790
 
int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
 
1072
int brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2], double time, float pressure,
 
1073
                        void *user, int use_color_correction)
791
1074
{
 
1075
        Scene *scene= painter->scene;
792
1076
        Brush *brush= painter->brush;
793
1077
        int totpaintops= 0;
794
1078
 
795
1079
        if (pressure == 0.0f) {
796
 
                if(painter->lastpressure) // XXX - hack, operator misses
 
1080
                if (painter->lastpressure) // XXX - hack, operator misses
797
1081
                        pressure= painter->lastpressure;
798
1082
                else
799
1083
                        pressure = 1.0f;        /* zero pressure == not using tablet */
805
1089
 
806
1090
                brush_apply_pressure(painter, brush, pressure);
807
1091
                if (painter->cache.enabled)
808
 
                        brush_painter_refresh_cache(painter, pos);
 
1092
                        brush_painter_refresh_cache(painter, pos, use_color_correction);
809
1093
                totpaintops += func(user, painter->cache.ibuf, pos, pos);
810
1094
                
811
1095
                painter->lasttime= time;
819
1103
                double starttime, curtime= time;
820
1104
 
821
1105
                /* compute brush spacing adapted to brush size */
822
 
                spacing= brush->rate; //brush->size*brush->spacing*0.01f;
 
1106
                spacing= brush->rate; //radius*brush->spacing*0.01f;
823
1107
 
824
1108
                /* setup starting time, direction vector and accumulated time */
825
1109
                starttime= painter->accumtime;
850
1134
        else {
851
1135
                float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
852
1136
                float t, len, press;
 
1137
                const int radius= brush_size(scene, brush);
853
1138
 
854
 
                /* compute brush spacing adapted to brush size, spacing may depend
855
 
                   on pressure, so update it */
 
1139
                /* compute brush spacing adapted to brush radius, spacing may depend
 
1140
                 * on pressure, so update it */
856
1141
                brush_apply_pressure(painter, brush, painter->lastpressure);
857
 
                spacing= MAX2(1.0f, brush->size)*brush->spacing*0.01f;
 
1142
                spacing= MAX2(1.0f, radius)*brush->spacing*0.01f;
858
1143
 
859
1144
                /* setup starting distance, direction vector and accumulated distance */
860
1145
                startdistance= painter->accumdistance;
862
1147
                len= normalize_v2(dmousepos);
863
1148
                painter->accumdistance += len;
864
1149
 
865
 
                /* do paint op over unpainted distance */
866
 
                while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
867
 
                        step= spacing - startdistance;
868
 
                        paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
869
 
                        paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
870
 
 
871
 
                        t = step/len;
872
 
                        press= (1.0f-t)*painter->lastpressure + t*pressure;
873
 
                        brush_apply_pressure(painter, brush, press);
874
 
                        spacing= MAX2(1.0f, brush->size)*brush->spacing*0.01f;
875
 
 
876
 
                        brush_jitter_pos(brush, paintpos, finalpos);
 
1150
                if (brush->flag & BRUSH_SPACE) {
 
1151
                        /* do paint op over unpainted distance */
 
1152
                        while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
 
1153
                                step= spacing - startdistance;
 
1154
                                paintpos[0]= painter->lastmousepos[0] + dmousepos[0]*step;
 
1155
                                paintpos[1]= painter->lastmousepos[1] + dmousepos[1]*step;
 
1156
 
 
1157
                                t = step/len;
 
1158
                                press= (1.0f-t)*painter->lastpressure + t*pressure;
 
1159
                                brush_apply_pressure(painter, brush, press);
 
1160
                                spacing= MAX2(1.0f, radius)*brush->spacing*0.01f;
 
1161
 
 
1162
                                brush_jitter_pos(scene, brush, paintpos, finalpos);
 
1163
 
 
1164
                                if (painter->cache.enabled)
 
1165
                                        brush_painter_refresh_cache(painter, finalpos, use_color_correction);
 
1166
 
 
1167
                                totpaintops +=
 
1168
                                        func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
 
1169
 
 
1170
                                painter->lastpaintpos[0]= paintpos[0];
 
1171
                                painter->lastpaintpos[1]= paintpos[1];
 
1172
                                painter->accumdistance -= spacing;
 
1173
                                startdistance -= spacing;
 
1174
                        }
 
1175
                }
 
1176
                else {
 
1177
                        brush_jitter_pos(scene, brush, pos, finalpos);
877
1178
 
878
1179
                        if (painter->cache.enabled)
879
 
                                brush_painter_refresh_cache(painter, finalpos);
880
 
 
881
 
                        totpaintops +=
882
 
                                func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
883
 
 
884
 
                        painter->lastpaintpos[0]= paintpos[0];
885
 
                        painter->lastpaintpos[1]= paintpos[1];
886
 
                        painter->accumdistance -= spacing;
887
 
                        startdistance -= spacing;
 
1180
                                brush_painter_refresh_cache(painter, finalpos, use_color_correction);
 
1181
 
 
1182
                        totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
 
1183
 
 
1184
                        painter->lastpaintpos[0]= pos[0];
 
1185
                        painter->lastpaintpos[1]= pos[1];
 
1186
                        painter->accumdistance= 0;
888
1187
                }
889
1188
 
890
1189
                /* do airbrush paint ops, based on the number of paint ops left over
891
 
                   from regular painting. this is a temporary solution until we have
892
 
                   accurate time stamps for mouse move events */
 
1190
                 * from regular painting. this is a temporary solution until we have
 
1191
                 * accurate time stamps for mouse move events */
893
1192
                if (brush->flag & BRUSH_AIRBRUSH) {
894
1193
                        double curtime= time;
895
1194
                        double painttime= brush->rate*totpaintops;
900
1199
                        else
901
1200
                                painter->accumtime -= painttime;
902
1201
 
903
 
                        while (painter->accumtime >= brush->rate) {
 
1202
                        while (painter->accumtime >= (double)brush->rate) {
904
1203
                                brush_apply_pressure(painter, brush, pressure);
905
1204
 
906
 
                                brush_jitter_pos(brush, pos, finalpos);
 
1205
                                brush_jitter_pos(scene, brush, pos, finalpos);
907
1206
 
908
1207
                                if (painter->cache.enabled)
909
 
                                        brush_painter_refresh_cache(painter, finalpos);
 
1208
                                        brush_painter_refresh_cache(painter, finalpos, use_color_correction);
910
1209
 
911
1210
                                totpaintops +=
912
1211
                                        func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
913
 
                                painter->accumtime -= brush->rate;
 
1212
                                painter->accumtime -= (double)brush->rate;
914
1213
                        }
915
1214
 
916
1215
                        painter->lasttime= curtime;
921
1220
        painter->lastmousepos[1]= pos[1];
922
1221
        painter->lastpressure= pressure;
923
1222
 
924
 
        brush->alpha = painter->startalpha;
925
 
        brush->size = painter->startsize;
 
1223
        brush_set_alpha(scene, brush, painter->startalpha);
 
1224
        brush_set_size(scene, brush, painter->startsize);
926
1225
        brush->jitter = painter->startjitter;
927
1226
        brush->spacing = painter->startspacing;
928
1227
 
932
1231
/* Uses the brush curve control to find a strength value between 0 and 1 */
933
1232
float brush_curve_strength_clamp(Brush *br, float p, const float len)
934
1233
{
935
 
        if(p >= len)    return 0;
 
1234
        if (p >= len)   return 0;
936
1235
        else                    p= p/len;
937
1236
 
938
1237
        p= curvemapping_evaluateF(br->curve, 0, p);
939
 
        if(p < 0.0)                     p= 0.0f;
940
 
        else if(p > 1.0f)       p= 1.0f;
 
1238
        if (p < 0.0f)           p= 0.0f;
 
1239
        else if (p > 1.0f)      p= 1.0f;
941
1240
        return p;
942
1241
}
943
1242
/* same as above but can return negative values if the curve enables
944
1243
 * used for sculpt only */
945
1244
float brush_curve_strength(Brush *br, float p, const float len)
946
1245
{
947
 
    if(p >= len)
948
 
        p= 1.0f;
949
 
    else
950
 
        p= p/len;
 
1246
        if (p >= len)
 
1247
                p= 1.0f;
 
1248
        else
 
1249
                p= p/len;
951
1250
 
952
 
    return curvemapping_evaluateF(br->curve, 0, p);
 
1251
        return curvemapping_evaluateF(br->curve, 0, p);
953
1252
}
954
1253
 
955
1254
/* TODO: should probably be unified with BrushPainter stuff? */
957
1256
{
958
1257
        unsigned int *texcache = NULL;
959
1258
        MTex *mtex = &br->mtex;
960
 
        TexResult texres;
 
1259
        TexResult texres= {0};
961
1260
        int hasrgb, ix, iy;
962
1261
        int side = half_side * 2;
963
 
 
964
 
        memset(&texres, 0, sizeof(TexResult));
965
1262
        
966
 
        if(mtex->tex) {
 
1263
        if (mtex->tex) {
967
1264
                float x, y, step = 2.0 / side, co[3];
968
1265
 
969
1266
                texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
984
1281
                                 * intensity, so calculate one (formula from do_material_tex).
985
1282
                                 * if the texture didn't give an RGB value, copy the intensity across
986
1283
                                 */
987
 
                                if(hasrgb & TEX_RGB)
988
 
                                        texres.tin = (0.35 * texres.tr + 0.45 *
989
 
                                                                  texres.tg + 0.2 * texres.tb);
 
1284
                                if (hasrgb & TEX_RGB)
 
1285
                                        texres.tin = (0.35f * texres.tr + 0.45f *
 
1286
                                                                  texres.tg + 0.2f * texres.tb);
990
1287
 
991
 
                                texres.tin = texres.tin * 255.0;
 
1288
                                texres.tin = texres.tin * 255.0f;
992
1289
                                ((char*)texcache)[(iy*side+ix)*4] = (char)texres.tin;
993
1290
                                ((char*)texcache)[(iy*side+ix)*4+1] = (char)texres.tin;
994
1291
                                ((char*)texcache)[(iy*side+ix)*4+2] = (char)texres.tin;
1001
1298
}
1002
1299
 
1003
1300
/**** Radial Control ****/
1004
 
static struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
 
1301
struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
1005
1302
{
1006
1303
        ImBuf *im = MEM_callocN(sizeof(ImBuf), "radial control texture");
1007
1304
        unsigned int *texcache;
1013
1310
        im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect");
1014
1311
        im->x = im->y = side;
1015
1312
 
1016
 
        for(i=0; i<side; ++i) {
1017
 
                for(j=0; j<side; ++j) {
 
1313
        for (i=0; i<side; ++i) {
 
1314
                for (j=0; j<side; ++j) {
1018
1315
                        float magn= sqrt(pow(i - half, 2) + pow(j - half, 2));
1019
1316
                        im->rect_float[i*side + j]= brush_curve_strength_clamp(br, magn, half);
1020
1317
                }
1021
1318
        }
1022
1319
 
1023
1320
        /* Modulate curve with texture */
1024
 
        if(texcache) {
1025
 
                for(i=0; i<side; ++i) {
1026
 
                        for(j=0; j<side; ++j) {
 
1321
        if (texcache) {
 
1322
                for (i=0; i<side; ++i) {
 
1323
                        for (j=0; j<side; ++j) {
1027
1324
                                const int col= texcache[i*side+j];
1028
1325
                                im->rect_float[i*side+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
1029
1326
                        }
1034
1331
 
1035
1332
        return im;
1036
1333
}
1037
 
 
1038
 
void brush_radial_control_invoke(wmOperator *op, Brush *br, float size_weight)
1039
 
{
1040
 
        int mode = RNA_int_get(op->ptr, "mode");
1041
 
        float original_value= 0;
1042
 
 
1043
 
        if(mode == WM_RADIALCONTROL_SIZE)
1044
 
                original_value = sculpt_get_brush_size(br) * size_weight;
1045
 
        else if(mode == WM_RADIALCONTROL_STRENGTH)
1046
 
                original_value = sculpt_get_brush_alpha(br);
1047
 
        else if(mode == WM_RADIALCONTROL_ANGLE) {
1048
 
                MTex *mtex = brush_active_texture(br);
1049
 
                if(mtex)
1050
 
                        original_value = mtex->rot;
1051
 
        }
1052
 
 
1053
 
        RNA_float_set(op->ptr, "initial_value", original_value);
1054
 
        op->customdata = brush_gen_radial_control_imbuf(br);
1055
 
}
1056
 
 
1057
 
int brush_radial_control_exec(wmOperator *op, Brush *br, float size_weight)
1058
 
{
1059
 
        int mode = RNA_int_get(op->ptr, "mode");
1060
 
        float new_value = RNA_float_get(op->ptr, "new_value");
1061
 
        const float conv = 0.017453293;
1062
 
 
1063
 
        if(mode == WM_RADIALCONTROL_SIZE)
1064
 
                if (sculpt_get_lock_brush_size(br)) {
1065
 
                        float initial_value = RNA_float_get(op->ptr, "initial_value");
1066
 
                        const float unprojected_radius = sculpt_get_brush_unprojected_radius(br);
1067
 
                        sculpt_set_brush_unprojected_radius(br, unprojected_radius * new_value/initial_value * size_weight);
1068
 
                }
1069
 
                else
1070
 
                        sculpt_set_brush_size(br, new_value * size_weight);
1071
 
        else if(mode == WM_RADIALCONTROL_STRENGTH)
1072
 
                sculpt_set_brush_alpha(br, new_value);
1073
 
        else if(mode == WM_RADIALCONTROL_ANGLE) {
1074
 
                MTex *mtex = brush_active_texture(br);
1075
 
                if(mtex)
1076
 
                        mtex->rot = new_value * conv;
1077
 
        }
1078
 
 
1079
 
        return OPERATOR_FINISHED;
1080
 
}