diff options
Diffstat (limited to 'source/blender/blenkernel/intern/brush.c')
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 612 |
1 files changed, 502 insertions, 110 deletions
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index c423d426e32..71a43994363 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -35,6 +35,7 @@ #include "DNA_brush_types.h" #include "DNA_color_types.h" #include "DNA_scene_types.h" +#include "DNA_object_types.h" #include "DNA_windowmanager_types.h" #include "WM_types.h" @@ -61,25 +62,24 @@ #include "RE_render_ext.h" /* externtex */ #include "RE_shader_ext.h" -/* Datablock add/copy/free/make_local */ - -Brush *add_brush(const char *name) +static void brush_set_defaults(Brush *brush) { - Brush *brush; + brush->blend = 0; + brush->flag = 0; - brush= alloc_libblock(&G.main->brush, ID_BR, name); + brush->ob_mode = (OB_MODE_SCULPT|OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT); /* BRUSH SCULPT TOOL SETTINGS */ - brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */ brush->size= 35; /* radius of the brush in pixels */ brush->alpha= 0.5f; /* brush strength/intensity probably variable should be renamed? */ brush->autosmooth_factor= 0.0f; brush->crease_pinch_factor= 0.5f; - brush->sculpt_plane = SCULPT_DISP_DIR_VIEW; + brush->sculpt_plane = SCULPT_DISP_DIR_AREA; brush->plane_offset= 0.0f; /* how far above or below the plane that is found by averaging the faces */ brush->plane_trim= 0.5f; brush->clone.alpha= 0.5f; brush->normal_weight= 0.0f; + brush->flag |= BRUSH_ALPHA_PRESSURE; /* BRUSH PAINT TOOL SETTINGS */ brush->rgb[0]= 1.0f; /* default rgb color of the brush when painting - white */ @@ -101,11 +101,10 @@ Brush *add_brush(const char *name) default_mtex(&brush->mtex); brush->texture_sample_bias= 0; /* value to added to texture samples */ + brush->texture_overlay_alpha= 33; /* brush appearance */ - brush->image_icon= NULL; - brush->add_col[0]= 1.00; /* add mode color is light red */ brush->add_col[1]= 0.39; brush->add_col[2]= 0.39; @@ -113,13 +112,25 @@ Brush *add_brush(const char *name) brush->sub_col[0]= 0.39; /* subtract mode color is light blue */ brush->sub_col[1]= 0.39; brush->sub_col[2]= 1.00; +} - /* the default alpha falloff curve */ - brush_curve_preset(brush, CURVE_PRESET_SMOOTH); +/* Datablock add/copy/free/make_local */ + +Brush *add_brush(const char *name) +{ + Brush *brush; + + brush= alloc_libblock(&G.main->brush, ID_BR, name); /* enable fake user by default */ brush->id.flag |= LIB_FAKEUSER; - brush_toggled_fake_user(brush); + + brush_set_defaults(brush); + + brush->sculpt_tool = SCULPT_TOOL_DRAW; /* sculpting defaults to the draw tool for new brushes */ + + /* the default alpha falloff curve */ + brush_curve_preset(brush, CURVE_PRESET_SMOOTH); return brush; } @@ -130,14 +141,18 @@ Brush *copy_brush(Brush *brush) brushn= copy_libblock(brush); - if(brush->mtex.tex) id_us_plus((ID*)brush->mtex.tex); - + if (brush->mtex.tex) + id_us_plus((ID*)brush->mtex.tex); + + if (brush->icon_imbuf) + brushn->icon_imbuf= IMB_dupImBuf(brush->icon_imbuf); + brushn->curve= curvemapping_copy(brush->curve); /* enable fake user by default */ if (!(brushn->id.flag & LIB_FAKEUSER)) { brushn->id.flag |= LIB_FAKEUSER; - brush_toggled_fake_user(brushn); + brushn->id.us++; } return brushn; @@ -146,7 +161,13 @@ Brush *copy_brush(Brush *brush) /* not brush itself */ void free_brush(Brush *brush) { - if(brush->mtex.tex) brush->mtex.tex->id.us--; + if (brush->mtex.tex) + brush->mtex.tex->id.us--; + + if (brush->icon_imbuf) + IMB_freeImBuf(brush->icon_imbuf); + + BKE_previewimg_free(&(brush->preview)); curvemapping_free(brush->curve); } @@ -176,7 +197,7 @@ void make_local_brush(Brush *brush) if(scene->id.lib) lib= 1; else local= 1; } - + if(local && lib==0) { brush->id.lib= 0; brush->id.flag= LIB_LOCAL; @@ -185,7 +206,7 @@ void make_local_brush(Brush *brush) /* enable fake user by default */ if (!(brush->id.flag & LIB_FAKEUSER)) { brush->id.flag |= LIB_FAKEUSER; - brush_toggled_fake_user(brush); + brush->id.us++; } } else if(local && lib) { @@ -203,55 +224,176 @@ void make_local_brush(Brush *brush) } } -/* Library Operations */ - -int brush_set_nr(Brush **current_brush, int nr, const char *name) +void brush_debug_print_state(Brush *br) { - ID *idtest, *id; + Brush def; + + /* create a fake brush and set it to the defaults */ + memset(&def, 0, sizeof(Brush)); + brush_set_defaults(&def); - id= (ID*)(*current_brush); - idtest= (ID*)BLI_findlink(&G.main->brush, nr-1); +#define BR_TEST(field, t) \ + if(br->field != def.field) \ + printf("br->" #field " = %" #t ";\n", br->field) + +#define BR_TEST_FLAG(_f) \ + if((br->flag & _f) && !(def.flag & _f)) \ + printf("br->flag |= " #_f ";\n"); \ + else if(!(br->flag & _f) && (def.flag & _f)) \ + printf("br->flag &= ~" #_f ";\n") - if(idtest==0) { /* new brush */ - if(id) idtest= (ID *)copy_brush((Brush *)id); - else idtest= (ID *)add_brush(name); - idtest->us--; - } - if(idtest!=id) { - brush_delete(current_brush); - *current_brush= (Brush *)idtest; - id_us_plus(idtest); - - return 1; - } - return 0; -} - -int brush_delete(Brush **current_brush) -{ - if (*current_brush) { - (*current_brush)->id.us--; - *current_brush= NULL; - - return 1; - } - - return 0; + /* print out any non-default brush state */ + BR_TEST(normal_weight, f); + + BR_TEST(blend, d); + BR_TEST(size, d); + + /* br->flag */ + BR_TEST_FLAG(BRUSH_AIRBRUSH); + BR_TEST_FLAG(BRUSH_TORUS); + BR_TEST_FLAG(BRUSH_ALPHA_PRESSURE); + BR_TEST_FLAG(BRUSH_SIZE_PRESSURE); + BR_TEST_FLAG(BRUSH_JITTER_PRESSURE); + BR_TEST_FLAG(BRUSH_SPACING_PRESSURE); + BR_TEST_FLAG(BRUSH_FIXED_TEX); + BR_TEST_FLAG(BRUSH_RAKE); + BR_TEST_FLAG(BRUSH_ANCHORED); + BR_TEST_FLAG(BRUSH_DIR_IN); + BR_TEST_FLAG(BRUSH_SPACE); + BR_TEST_FLAG(BRUSH_SMOOTH_STROKE); + BR_TEST_FLAG(BRUSH_PERSISTENT); + BR_TEST_FLAG(BRUSH_ACCUMULATE); + BR_TEST_FLAG(BRUSH_LOCK_ALPHA); + BR_TEST_FLAG(BRUSH_ORIGINAL_NORMAL); + BR_TEST_FLAG(BRUSH_OFFSET_PRESSURE); + BR_TEST_FLAG(BRUSH_SPACE_ATTEN); + BR_TEST_FLAG(BRUSH_ADAPTIVE_SPACE); + BR_TEST_FLAG(BRUSH_LOCK_SIZE); + BR_TEST_FLAG(BRUSH_TEXTURE_OVERLAY); + BR_TEST_FLAG(BRUSH_EDGE_TO_EDGE); + BR_TEST_FLAG(BRUSH_RESTORE_MESH); + BR_TEST_FLAG(BRUSH_INVERSE_SMOOTH_PRESSURE); + BR_TEST_FLAG(BRUSH_RANDOM_ROTATION); + BR_TEST_FLAG(BRUSH_PLANE_TRIM); + BR_TEST_FLAG(BRUSH_FRONTFACE); + BR_TEST_FLAG(BRUSH_CUSTOM_ICON); + + BR_TEST(jitter, f); + BR_TEST(spacing, d); + BR_TEST(smooth_stroke_radius, d); + BR_TEST(smooth_stroke_factor, f); + BR_TEST(rate, f); + + BR_TEST(alpha, f); + + BR_TEST(sculpt_plane, d); + + BR_TEST(plane_offset, f); + + BR_TEST(autosmooth_factor, f); + + BR_TEST(crease_pinch_factor, f); + + BR_TEST(plane_trim, f); + + BR_TEST(texture_sample_bias, f); + BR_TEST(texture_overlay_alpha, d); + + BR_TEST(add_col[0], f); + BR_TEST(add_col[1], f); + BR_TEST(add_col[2], f); + BR_TEST(sub_col[0], f); + BR_TEST(sub_col[1], f); + BR_TEST(sub_col[2], f); + + printf("\n"); + +#undef BR_TEST +#undef BR_TEST_FLAG } -void brush_toggled_fake_user(Brush *brush) +void brush_reset_sculpt(Brush *br) { - ID *id= (ID*)brush; - if(id) { - if(id->flag & LIB_FAKEUSER) { - id_us_plus(id); - } else { - id->us--; - } + /* enable this to see any non-default + settings used by a brush: + + brush_debug_print_state(br); + */ + + brush_set_defaults(br); + brush_curve_preset(br, CURVE_PRESET_SMOOTH); + + switch(br->sculpt_tool) { + case SCULPT_TOOL_CLAY: + br->flag |= BRUSH_FRONTFACE; + break; + case SCULPT_TOOL_CREASE: + br->flag |= BRUSH_DIR_IN; + br->alpha = 0.25; + break; + case SCULPT_TOOL_FILL: + br->add_col[1] = 1; + br->sub_col[0] = 0.25; + br->sub_col[1] = 1; + break; + case SCULPT_TOOL_FLATTEN: + br->add_col[1] = 1; + br->sub_col[0] = 0.25; + br->sub_col[1] = 1; + break; + case SCULPT_TOOL_INFLATE: + br->add_col[0] = 0.750000; + br->add_col[1] = 0.750000; + br->add_col[2] = 0.750000; + br->sub_col[0] = 0.250000; + br->sub_col[1] = 0.250000; + br->sub_col[2] = 0.250000; + break; + case SCULPT_TOOL_NUDGE: + br->add_col[0] = 0.250000; + br->add_col[1] = 1.000000; + br->add_col[2] = 0.250000; + break; + case SCULPT_TOOL_PINCH: + br->add_col[0] = 0.750000; + br->add_col[1] = 0.750000; + br->add_col[2] = 0.750000; + br->sub_col[0] = 0.250000; + br->sub_col[1] = 0.250000; + br->sub_col[2] = 0.250000; + break; + case SCULPT_TOOL_SCRAPE: + br->add_col[1] = 1.000000; + br->sub_col[0] = 0.250000; + br->sub_col[1] = 1.000000; + break; + case SCULPT_TOOL_ROTATE: + break; + case SCULPT_TOOL_SMOOTH: + br->flag &= ~BRUSH_SPACE_ATTEN; + br->spacing = 5; + br->add_col[0] = 0.750000; + br->add_col[1] = 0.750000; + br->add_col[2] = 0.750000; + break; + case SCULPT_TOOL_GRAB: + case SCULPT_TOOL_SNAKE_HOOK: + case SCULPT_TOOL_THUMB: + br->size = 75; + br->flag &= ~BRUSH_ALPHA_PRESSURE; + br->flag &= ~BRUSH_SPACE; + br->flag &= ~BRUSH_SPACE_ATTEN; + br->add_col[0] = 0.250000; + br->add_col[1] = 1.000000; + br->add_col[2] = 0.250000; + break; + default: + break; } } +/* Library Operations */ void brush_curve_preset(Brush *b, /*CurveMappingPreset*/int preset) { CurveMap *cm = NULL; @@ -263,7 +405,7 @@ void brush_curve_preset(Brush *b, /*CurveMappingPreset*/int preset) cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; b->curve->preset = preset; - curvemap_reset(cm, &b->curve->clipr, b->curve->preset); + curvemap_reset(cm, &b->curve->clipr, b->curve->preset, CURVEMAP_SLOPE_NEGATIVE); curvemapping_changed(b->curve, 0); } @@ -335,12 +477,6 @@ int brush_clone_image_delete(Brush *brush) return 0; } -void brush_check_exists(Brush **brush, const char *name) -{ - if(*brush==NULL) - brush_set_nr(brush, 1, name); -} - /* Brush Sampling */ void brush_sample_tex(Brush *brush, float *xy, float *rgba) { @@ -349,9 +485,10 @@ void brush_sample_tex(Brush *brush, float *xy, float *rgba) if (mtex && mtex->tex) { float co[3], tin, tr, tg, tb, ta; int hasrgb; - - co[0]= xy[0]/(brush->size >> 1); - co[1]= xy[1]/(brush->size >> 1); + const int radius= brush_size(brush); + + co[0]= xy[0]/radius; + co[1]= xy[1]/radius; co[2]= 0.0f; hasrgb= externtex(mtex, co, &tin, &tr, &tg, &tb, &ta); @@ -374,23 +511,24 @@ void brush_sample_tex(Brush *brush, float *xy, float *rgba) } -void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **outbuf) +void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf) { ImBuf *ibuf; float xy[2], dist, rgba[4], *dstf; int x, y, rowbytes, xoff, yoff, imbflag; - int maxsize = brush->size >> 1; + const int radius= brush_size(brush); char *dst, crgb[3]; + const float alpha= brush_alpha(brush); imbflag= (flt)? IB_rectfloat: IB_rect; - xoff = -size/2.0f + 0.5f; - yoff = -size/2.0f + 0.5f; - rowbytes= size*4; + xoff = -bufsize/2.0f + 0.5f; + yoff = -bufsize/2.0f + 0.5f; + rowbytes= bufsize*4; if (*outbuf) ibuf= *outbuf; else - ibuf= IMB_allocImBuf(size, size, 32, imbflag, 0); + ibuf= IMB_allocImBuf(bufsize, bufsize, 32, imbflag, 0); if (flt) { for (y=0; y < ibuf->y; y++) { @@ -404,7 +542,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]); VECCOPY(dstf, brush->rgb); - dstf[3]= brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize); + dstf[3]= alpha*brush_curve_strength_clamp(brush, dist, radius); } else if (texfall == 1) { brush_sample_tex(brush, xy, dstf); @@ -417,7 +555,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dstf[0] = rgba[0]*brush->rgb[0]; dstf[1] = rgba[1]*brush->rgb[1]; dstf[2] = rgba[2]*brush->rgb[2]; - dstf[3] = rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize); + dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius); } } } @@ -440,7 +578,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dst[0]= crgb[0]; dst[1]= crgb[1]; dst[2]= crgb[2]; - dst[3]= FTOCHAR(brush->alpha*brush_curve_strength(brush, dist, maxsize)); + dst[3]= FTOCHAR(alpha*brush_curve_strength(brush, dist, radius)); } else if (texfall == 1) { brush_sample_tex(brush, xy, rgba); @@ -456,7 +594,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o dst[0] = FTOCHAR(rgba[0]*brush->rgb[0]); dst[1] = FTOCHAR(rgba[1]*brush->rgb[1]); dst[2] = FTOCHAR(rgba[2]*brush->rgb[2]); - dst[3] = FTOCHAR(rgba[3]*brush->alpha*brush_curve_strength_clamp(brush, dist, maxsize)); + dst[3] = FTOCHAR(rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius)); } } } @@ -470,7 +608,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int size, ImBuf **o typedef struct BrushPainterCache { short enabled; - int size; /* size override, if 0 uses brush->size */ + int size; /* size override, if 0 uses 2*brush_size(brush) */ short flt; /* need float imbuf? */ short texonly; /* no alpha, color or fallof, only texture in imbuf */ @@ -515,8 +653,8 @@ BrushPainter *brush_painter_new(Brush *brush) painter->firsttouch= 1; painter->cache.lastsize= -1; /* force ibuf create in refresh */ - painter->startsize = brush->size; - painter->startalpha = brush->alpha; + painter->startsize = brush_size(brush); + painter->startalpha = brush_alpha(brush); painter->startjitter = brush->jitter; painter->startspacing = brush->spacing; @@ -549,8 +687,8 @@ void brush_painter_free(BrushPainter *painter) { Brush *brush = painter->brush; - brush->size = painter->startsize; - brush->alpha = painter->startalpha; + brush_set_size(brush, painter->startsize); + brush_set_alpha(brush, painter->startalpha); brush->jitter = painter->startjitter; brush->spacing = painter->startspacing; @@ -567,9 +705,10 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i float *bf, *mf, *tf, *otf=NULL, xoff, yoff, xy[2], rgba[4]; char *b, *m, *t, *ot= NULL; int dotexold, origx= x, origy= y; + const int radius= brush_size(brush); - xoff = -brush->size/2.0f + 0.5f; - yoff = -brush->size/2.0f + 0.5f; + xoff = -radius + 0.5f; + yoff = -radius + 0.5f; xoff += (int)pos[0] - (int)painter->startpaintpos[0]; yoff += (int)pos[1] - (int)painter->startpaintpos[1]; @@ -651,14 +790,15 @@ static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float BrushPainterCache *cache= &painter->cache; ImBuf *oldtexibuf, *ibuf; int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2; + const int diameter= 2*brush_size(brush); imbflag= (cache->flt)? IB_rectfloat: IB_rect; if (!cache->ibuf) - cache->ibuf= IMB_allocImBuf(brush->size, brush->size, 32, imbflag, 0); + cache->ibuf= IMB_allocImBuf(diameter, diameter, 32, imbflag, 0); ibuf= cache->ibuf; oldtexibuf= cache->texibuf; - cache->texibuf= IMB_allocImBuf(brush->size, brush->size, 32, imbflag, 0); + cache->texibuf= IMB_allocImBuf(diameter, diameter, 32, imbflag, 0); if (oldtexibuf) { srcx= srcy= 0; @@ -705,9 +845,13 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos) MTex *mtex= &brush->mtex; int size; short flt; + const int diameter= 2*brush_size(brush); + const float alpha= brush_alpha(brush); - if ((brush->size != cache->lastsize) || (brush->alpha != cache->lastalpha) - || (brush->jitter != cache->lastjitter)) { + if (diameter != cache->lastsize || + alpha != cache->lastalpha || + brush->jitter != cache->lastjitter) + { if (cache->ibuf) { IMB_freeImBuf(cache->ibuf); cache->ibuf= NULL; @@ -718,7 +862,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos) } flt= cache->flt; - size= (cache->size)? cache->size: brush->size; + size= (cache->size)? cache->size: diameter; if (!(mtex && mtex->tex) || (mtex->tex->type==0)) { brush_imbuf_new(brush, flt, 0, size, &cache->ibuf); @@ -730,8 +874,8 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos) else brush_imbuf_new(brush, flt, 2, size, &cache->ibuf); - cache->lastsize= brush->size; - cache->lastalpha= brush->alpha; + cache->lastsize= diameter; + cache->lastalpha= alpha; cache->lastjitter= brush->jitter; } else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) { @@ -750,10 +894,10 @@ void brush_painter_break_stroke(BrushPainter *painter) static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pressure) { - if (brush->flag & BRUSH_ALPHA_PRESSURE) - brush->alpha = MAX2(0.0, painter->startalpha*pressure); - if (brush->flag & BRUSH_SIZE_PRESSURE) - brush->size = MAX2(1.0, painter->startsize*pressure); + if (brush_use_alpha_pressure(brush)) + brush_set_alpha(brush, MAX2(0.0, painter->startalpha*pressure)); + if (brush_use_size_pressure(brush)) + brush_set_size(brush, MAX2(1.0, painter->startsize*pressure)); if (brush->flag & BRUSH_JITTER_PRESSURE) brush->jitter = MAX2(0.0, painter->startjitter*pressure); if (brush->flag & BRUSH_SPACING_PRESSURE) @@ -764,6 +908,8 @@ void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos) { if(brush->jitter){ float rand_pos[2]; + const int radius= brush_size(brush); + const int diameter= 2*radius; // find random position within a circle of diameter 1 do { @@ -771,8 +917,8 @@ void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos) rand_pos[1] = BLI_frand()-0.5f; } while (len_v2(rand_pos) > 0.5f); - jitterpos[0] = pos[0] + 2*rand_pos[0]*brush->size*brush->jitter; - jitterpos[1] = pos[1] + 2*rand_pos[1]*brush->size*brush->jitter; + jitterpos[0] = pos[0] + 2*rand_pos[0]*diameter*brush->jitter; + jitterpos[1] = pos[1] + 2*rand_pos[1]*diameter*brush->jitter; } else { VECCOPY2D(jitterpos, pos); @@ -811,7 +957,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl double starttime, curtime= time; /* compute brush spacing adapted to brush size */ - spacing= brush->rate; //brush->size*brush->spacing*0.01f; + spacing= brush->rate; //radius*brush->spacing*0.01f; /* setup starting time, direction vector and accumulated time */ starttime= painter->accumtime; @@ -842,11 +988,12 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl else { float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2]; float t, len, press; + const int radius= brush_size(brush); - /* compute brush spacing adapted to brush size, spacing may depend + /* compute brush spacing adapted to brush radius, spacing may depend on pressure, so update it */ brush_apply_pressure(painter, brush, painter->lastpressure); - spacing= MAX2(1.0f, brush->size)*brush->spacing*0.01f; + spacing= MAX2(1.0f, radius)*brush->spacing*0.01f; /* setup starting distance, direction vector and accumulated distance */ startdistance= painter->accumdistance; @@ -863,7 +1010,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl t = step/len; press= (1.0f-t)*painter->lastpressure + t*pressure; brush_apply_pressure(painter, brush, press); - spacing= MAX2(1.0f, brush->size)*brush->spacing*0.01f; + spacing= MAX2(1.0f, radius)*brush->spacing*0.01f; brush_jitter_pos(brush, paintpos, finalpos); @@ -913,8 +1060,8 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl painter->lastmousepos[1]= pos[1]; painter->lastpressure= pressure; - brush->alpha = painter->startalpha; - brush->size = painter->startsize; + brush_set_alpha(brush, painter->startalpha); + brush_set_size(brush, painter->startsize); brush->jitter = painter->startjitter; brush->spacing = painter->startspacing; @@ -1033,9 +1180,9 @@ void brush_radial_control_invoke(wmOperator *op, Brush *br, float size_weight) float original_value= 0; if(mode == WM_RADIALCONTROL_SIZE) - original_value = sculpt_get_brush_size(br) * size_weight; + original_value = brush_size(br) * size_weight; else if(mode == WM_RADIALCONTROL_STRENGTH) - original_value = sculpt_get_brush_alpha(br); + original_value = brush_alpha(br); else if(mode == WM_RADIALCONTROL_ANGLE) { MTex *mtex = brush_active_texture(br); if(mtex) @@ -1053,15 +1200,15 @@ int brush_radial_control_exec(wmOperator *op, Brush *br, float size_weight) const float conv = 0.017453293; if(mode == WM_RADIALCONTROL_SIZE) - if (sculpt_get_lock_brush_size(br)) { + if (brush_use_locked_size(br)) { float initial_value = RNA_float_get(op->ptr, "initial_value"); - const float unprojected_radius = sculpt_get_brush_unprojected_radius(br); - sculpt_set_brush_unprojected_radius(br, unprojected_radius * new_value/initial_value * size_weight); + const float unprojected_radius = brush_unprojected_radius(br); + brush_set_unprojected_radius(br, unprojected_radius * new_value/initial_value * size_weight); } else - sculpt_set_brush_size(br, new_value * size_weight); + brush_set_size(br, new_value * size_weight); else if(mode == WM_RADIALCONTROL_STRENGTH) - sculpt_set_brush_alpha(br, new_value); + brush_set_alpha(br, new_value); else if(mode == WM_RADIALCONTROL_ANGLE) { MTex *mtex = brush_active_texture(br); if(mtex) @@ -1070,3 +1217,248 @@ int brush_radial_control_exec(wmOperator *op, Brush *br, float size_weight) return OPERATOR_FINISHED; } + +/* Unified Size and Strength */ + +static void set_unified_settings(Brush *brush, short flag, int value) +{ + Scene *sce; + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->toolsettings && + ELEM4(brush, + paint_brush(&(sce->toolsettings->imapaint.paint)), + paint_brush(&(sce->toolsettings->vpaint->paint)), + paint_brush(&(sce->toolsettings->wpaint->paint)), + paint_brush(&(sce->toolsettings->sculpt->paint)))) + { + if (value) + sce->toolsettings->sculpt_paint_settings |= flag; + else + sce->toolsettings->sculpt_paint_settings &= ~flag; + } + } +} + +static short unified_settings(Brush *brush) +{ + Scene *sce; + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->toolsettings && + ELEM4(brush, + paint_brush(&(sce->toolsettings->imapaint.paint)), + paint_brush(&(sce->toolsettings->vpaint->paint)), + paint_brush(&(sce->toolsettings->wpaint->paint)), + paint_brush(&(sce->toolsettings->sculpt->paint)))) + { + return sce->toolsettings->sculpt_paint_settings; + } + } + + return 0; +} + +static void set_unified_size(Brush *brush, int value) +{ + Scene *sce; + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->toolsettings && + ELEM4(brush, + paint_brush(&(sce->toolsettings->imapaint.paint)), + paint_brush(&(sce->toolsettings->vpaint->paint)), + paint_brush(&(sce->toolsettings->wpaint->paint)), + paint_brush(&(sce->toolsettings->sculpt->paint)))) + { + sce->toolsettings->sculpt_paint_unified_size= value; + } + } +} + +static int unified_size(Brush *brush) +{ + Scene *sce; + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->toolsettings && + ELEM4(brush, + paint_brush(&(sce->toolsettings->imapaint.paint)), + paint_brush(&(sce->toolsettings->vpaint->paint)), + paint_brush(&(sce->toolsettings->wpaint->paint)), + paint_brush(&(sce->toolsettings->sculpt->paint)))) + { + return sce->toolsettings->sculpt_paint_unified_size; + } + } + + return 35; // XXX magic number +} + +static void set_unified_alpha(Brush *brush, float value) +{ + Scene *sce; + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->toolsettings && + ELEM4(brush, + paint_brush(&(sce->toolsettings->imapaint.paint)), + paint_brush(&(sce->toolsettings->vpaint->paint)), + paint_brush(&(sce->toolsettings->wpaint->paint)), + paint_brush(&(sce->toolsettings->sculpt->paint)))) + { + sce->toolsettings->sculpt_paint_unified_alpha= value; + } + } +} + +static float unified_alpha(Brush *brush) +{ + Scene *sce; + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->toolsettings && + ELEM4(brush, + paint_brush(&(sce->toolsettings->imapaint.paint)), + paint_brush(&(sce->toolsettings->vpaint->paint)), + paint_brush(&(sce->toolsettings->wpaint->paint)), + paint_brush(&(sce->toolsettings->sculpt->paint)))) + { + return sce->toolsettings->sculpt_paint_unified_alpha; + } + } + + return 0.5f; // XXX magic number +} + +static void set_unified_unprojected_radius(Brush *brush, float value) +{ + Scene *sce; + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->toolsettings && + ELEM4(brush, + paint_brush(&(sce->toolsettings->imapaint.paint)), + paint_brush(&(sce->toolsettings->vpaint->paint)), + paint_brush(&(sce->toolsettings->wpaint->paint)), + paint_brush(&(sce->toolsettings->sculpt->paint)))) + { + sce->toolsettings->sculpt_paint_unified_unprojected_radius= value; + } + } +} + +static float unified_unprojected_radius(Brush *brush) +{ + Scene *sce; + for (sce= G.main->scene.first; sce; sce= sce->id.next) { + if (sce->toolsettings && + ELEM4(brush, + paint_brush(&(sce->toolsettings->imapaint.paint)), + paint_brush(&(sce->toolsettings->vpaint->paint)), + paint_brush(&(sce->toolsettings->wpaint->paint)), + paint_brush(&(sce->toolsettings->sculpt->paint)))) + { + return sce->toolsettings->sculpt_paint_unified_unprojected_radius; + } + } + + return 0.125f; // XXX magic number +} +void brush_set_size(Brush *brush, int size) +{ + if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) + set_unified_size(brush, size); + else + brush->size= size; + + //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); +} + +int brush_size(Brush *brush) +{ + return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? unified_size(brush) : brush->size; +} + +void brush_set_use_locked_size(Brush *brush, int value) +{ + if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) { + set_unified_settings(brush, SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE, value); + } + else { + if (value) + brush->flag |= BRUSH_LOCK_SIZE; + else + brush->flag &= ~BRUSH_LOCK_SIZE; + } + + //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); +} + +int brush_use_locked_size(Brush *brush) +{ + return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE) : (brush->flag & BRUSH_LOCK_SIZE); +} + +void brush_set_use_size_pressure(Brush *brush, int value) +{ + if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) { + set_unified_settings(brush, SCULPT_PAINT_UNIFIED_SIZE_PRESSURE, value); + } + else { + if (value) + brush->flag |= BRUSH_SIZE_PRESSURE; + else + brush->flag &= ~BRUSH_SIZE_PRESSURE; + } + + //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); +} + +int brush_use_size_pressure(Brush *brush) +{ + return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_SIZE_PRESSURE) : (brush->flag & BRUSH_SIZE_PRESSURE); +} + +void brush_set_use_alpha_pressure(Brush *brush, int value) +{ + if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) { + set_unified_settings(brush, SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE, value); + } + else { + if (value) + brush->flag |= BRUSH_ALPHA_PRESSURE; + else + brush->flag &= ~BRUSH_ALPHA_PRESSURE; + } + + //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); +} + +int brush_use_alpha_pressure(Brush *brush) +{ + return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) ? (unified_settings(brush) & SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE) : (brush->flag & BRUSH_ALPHA_PRESSURE); +} + +void brush_set_unprojected_radius(Brush *brush, float unprojected_radius) +{ + if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) + set_unified_unprojected_radius(brush, unprojected_radius); + else + brush->unprojected_radius= unprojected_radius; + + //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); +} + +float brush_unprojected_radius(Brush *brush) +{ + return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_SIZE) ? unified_unprojected_radius(brush) : brush->unprojected_radius; +} + +void brush_set_alpha(Brush *brush, float alpha) +{ + if (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) + set_unified_alpha(brush, alpha); + else + brush->alpha= alpha; + + //WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush); +} + +float brush_alpha(Brush *brush) +{ + return (unified_settings(brush) & SCULPT_PAINT_USE_UNIFIED_ALPHA) ? unified_alpha(brush) : brush->alpha; +} |