== Sculpt/Paint Fixes ==

* Fix: unify strength and size did work consistently with other paint modes
* Fix: If [ and ] keys were used to resize a brush it was not possible to increase the size of the brush if it went under 10 pixels
* Fix: Made interpretation of brush size consistent across all modes, Texture/Image paint interpreted brush size as the diameter while all the other modes interpret it as radius
* Fix: The default spacing for vertex paint brushes was 3%, should be 10%
* Fix: due to fixes to unified strength, re-enabled 'Unify Size' by default
* Fix: Unified size and strength were stored in UserPrefs, moved this to ToolSettings
* Fix: The setting of pressure sensitivity was not unified when strength or size were unified.  Now the appropriate pressure sensitivity setting is also unified across all brushes when corresponding unification option is selected
* Fix: When using [ and ] to resize the brush it didn't immediately redraw
* Fix: fkey resizing/"re-strength-ing" was not working consistently accross all paint modes due to only sculpt mode having full support for unified size and strength, now it works properly.
* Fix: other paint modes did expose the ability to have a  custom brush colors, so I added the small bit of code to allow it.  Note: I made all of the other paint mode brushes white.  Note2: Actually, probably want to make the paint modes use the selected color for painting instead of a constant brush color.
* I had removed OPTYPE_REGISTER from some Sculpt/Paint operators but in this commit I add them back.  I'm not completely sure what this option does so I don't want to disturb it for now.
This commit is contained in:
Jason Wilkins 2010-07-22 18:56:46 +00:00
parent 528cce4313
commit 3b5b761a56
18 changed files with 6874 additions and 6518 deletions

@ -555,7 +555,6 @@ class VIEW3D_PT_tools_brush(PaintPanel):
# Sculpt Mode #
elif context.sculpt_object and brush:
edit = context.user_preferences.edit
col = layout.column()
@ -564,21 +563,12 @@ class VIEW3D_PT_tools_brush(PaintPanel):
row = col.row(align=True)
if edit.sculpt_paint_use_unified_size:
if edit.sculpt_paint_unified_lock_brush_size:
row.prop(edit, "sculpt_paint_unified_lock_brush_size", toggle=True, text="", icon='LOCKED')
row.prop(edit, "sculpt_paint_unified_unprojected_radius", text="Radius", slider=True)
else:
row.prop(edit, "sculpt_paint_unified_lock_brush_size", toggle=True, text="", icon='UNLOCKED')
row.prop(edit, "sculpt_paint_unified_size", text="Radius", slider=True)
if brush.use_locked_size:
row.prop(brush, "use_locked_size", toggle=True, text="", icon='LOCKED')
row.prop(brush, "unprojected_radius", text="Radius", slider=True)
else:
if brush.lock_brush_size:
row.prop(brush, "lock_brush_size", toggle=True, text="", icon='LOCKED')
row.prop(brush, "unprojected_radius", text="Radius", slider=True)
else:
row.prop(brush, "lock_brush_size", toggle=True, text="", icon='UNLOCKED')
row.prop(brush, "size", text="Radius", slider=True)
row.prop(brush, "use_locked_size", toggle=True, text="", icon='UNLOCKED')
row.prop(brush, "size", text="Radius", slider=True)
row.prop(brush, "use_size_pressure", toggle=True, text="")
@ -594,11 +584,7 @@ class VIEW3D_PT_tools_brush(PaintPanel):
else:
row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED')
if edit.sculpt_paint_use_unified_strength:
row.prop(edit, "sculpt_paint_unified_strength", text="Unified Strength", slider=True)
else:
row.prop(brush, "strength", text="Strength", slider=True)
row.prop(brush, "strength", text="Strength", slider=True)
row.prop(brush, "use_strength_pressure", text="")
@ -710,11 +696,11 @@ class VIEW3D_PT_tools_brush(PaintPanel):
col.prop(brush, "color", text="")
row = col.row(align=True)
row.prop(brush, "size", slider=True)
row.prop(brush, "size", text="Radius", slider=True)
row.prop(brush, "use_size_pressure", toggle=True, text="")
row = col.row(align=True)
row.prop(brush, "strength", slider=True)
row.prop(brush, "strength", text="Strength", slider=True)
row.prop(brush, "use_strength_pressure", toggle=True, text="")
row = col.row(align=True)
@ -735,12 +721,13 @@ class VIEW3D_PT_tools_brush(PaintPanel):
layout.prop(context.tool_settings, "auto_normalize", text="Auto Normalize")
col = layout.column()
row = col.row(align=True)
row.prop(brush, "size", slider=True)
row.prop(brush, "size", text="Radius", slider=True)
row.prop(brush, "use_size_pressure", toggle=True, text="")
row = col.row(align=True)
row.prop(brush, "strength", slider=True)
row.prop(brush, "strength", text="Strength", slider=True)
row.prop(brush, "use_strength_pressure", toggle=True, text="")
row = col.row(align=True)
@ -755,11 +742,11 @@ class VIEW3D_PT_tools_brush(PaintPanel):
col.prop(brush, "color", text="")
row = col.row(align=True)
row.prop(brush, "size", slider=True)
row.prop(brush, "size", text="Radius", slider=True)
row.prop(brush, "use_size_pressure", toggle=True, text="")
row = col.row(align=True)
row.prop(brush, "strength", slider=True)
row.prop(brush, "strength", text="Strength", slider=True)
row.prop(brush, "use_strength_pressure", toggle=True, text="")
# XXX - TODO
@ -1032,7 +1019,8 @@ class VIEW3D_PT_sculpt_options(PaintPanel):
wide_ui = context.region.width > narrowui
sculpt = context.tool_settings.sculpt
tool_settings = context.tool_settings
sculpt = tool_settings.sculpt
settings = self.paint_settings(context)
brush = settings.brush
@ -1040,10 +1028,9 @@ class VIEW3D_PT_sculpt_options(PaintPanel):
col = split.column()
edit = context.user_preferences.edit
col.label(text="Unified Settings:")
col.prop(edit, "sculpt_paint_use_unified_size", text="Size")
col.prop(edit, "sculpt_paint_use_unified_strength", text="Strength")
col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
if wide_ui:
col = split.column()
@ -1108,17 +1095,19 @@ class VIEW3D_PT_tools_brush_appearance(PaintPanel):
settings = self.paint_settings(context)
brush = settings.brush
if context.sculpt_object and context.tool_settings.sculpt:
col = layout.column();
col = layout.column();
#if brush.sculpt_tool in ('DRAW', 'INFLATE', 'CLAY', 'CLAY_TUBES', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE'):
if context.sculpt_object and context.tool_settings.sculpt:
#if brush.sculpt_tool in ('DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE', 'CLAY_TUBES'):
if brush.sculpt_tool in ('DRAW', 'INFLATE', 'CLAY', 'PINCH', 'CREASE', 'BLOB', 'FLATTEN', 'FILL', 'SCRAPE'):
col.prop(brush, "add_col", text="Add Color")
col.prop(brush, "sub_col", text="Subtract Color")
else:
col.prop(brush, "add_col", text="Color")
else:
col.prop(brush, "add_col", text="Color")
col.separator()
col.separator()
col = layout.column()
col.label(text="Icon:")
@ -1154,7 +1143,8 @@ class VIEW3D_PT_tools_weightpaint_options(View3DPanel):
def draw(self, context):
layout = self.layout
wpaint = context.tool_settings.weight_paint
tool_settings = context.tool_settings
wpaint = tool_settings.weight_paint
col = layout.column()
col.prop(wpaint, "all_faces")
@ -1167,6 +1157,10 @@ class VIEW3D_PT_tools_weightpaint_options(View3DPanel):
col.prop(mesh, "use_mirror_x")
col.prop(mesh, "use_mirror_topology")
col.label(text="Unified Settings:")
col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
# Commented out because the Apply button isn't an operator yet, making these settings useless
# col.label(text="Gamma:")
# col.prop(wpaint, "gamma", text="")
@ -1186,7 +1180,8 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel):
def draw(self, context):
layout = self.layout
vpaint = context.tool_settings.vertex_paint
tool_settings = context.tool_settings
vpaint = tool_settings.vertex_paint
col = layout.column()
#col.prop(vpaint, "mode", text="")
@ -1194,6 +1189,10 @@ class VIEW3D_PT_tools_vertexpaint(View3DPanel):
col.prop(vpaint, "normals")
col.prop(vpaint, "spray")
col.label(text="Unified Settings:")
col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
# Commented out because the Apply button isn't an operator yet, making these settings useless
# col.label(text="Gamma:")
# col.prop(vpaint, "gamma", text="")
@ -1272,6 +1271,23 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel):
sub.operator("image.save_dirty", text="Save All Edited")
class VIEW3D_PT_imagepaint_options(PaintPanel):
bl_label = "Options"
bl_default_closed = True
def poll(self, context):
return (context.texture_paint_object and context.tool_settings.image_paint)
def draw(self, context):
layout = self.layout
col = layout.column()
tool_settings = context.tool_settings
col.label(text="Unified Settings:")
col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
class VIEW3D_MT_tools_projectpaint_clone(bpy.types.Menu):
bl_label = "Clone Layer"
@ -1385,6 +1401,7 @@ classes = [
VIEW3D_PT_sculpt_options,
VIEW3D_PT_tools_vertexpaint,
VIEW3D_PT_tools_weightpaint_options,
VIEW3D_PT_imagepaint_options,
VIEW3D_PT_tools_projectpaint,
VIEW3D_MT_tools_projectpaint_clone,

@ -88,14 +88,24 @@ void brush_radial_control_invoke(struct wmOperator *op, struct Brush *br, float
int brush_radial_control_exec(struct wmOperator *op, struct Brush *br, float size_weight);
/* unified strength and size */
int sculpt_get_brush_size(struct Brush *brush);
void sculpt_set_brush_size(struct Brush *brush, int size);
int sculpt_get_lock_brush_size(struct Brush *brush);
float sculpt_get_brush_unprojected_radius(struct Brush *brush);
void sculpt_set_brush_unprojected_radius(struct Brush *brush, float unprojected_radius);
float sculpt_get_brush_alpha(struct Brush *brush);
void sculpt_set_brush_alpha(struct Brush *brush, float alpha);
int brush_size(struct Brush *brush);
void brush_set_size(struct Brush *brush, int value);
int brush_use_locked_size(struct Brush *brush);
void brush_set_use_locked_size(struct Brush *brush, int value);
int brush_use_alpha_pressure(struct Brush *brush);
void brush_set_use_alpha_pressure(struct Brush *brush, int value);
int brush_use_size_pressure(struct Brush *brush);
void brush_set_use_size_pressure(struct Brush *brush, int value);
float brush_unprojected_radius(struct Brush *brush);
void brush_set_unprojected_radius(struct Brush *brush, float value);
float brush_alpha(struct Brush *brush);
void brush_set_alpha(struct Brush *brush, float value);
#endif

@ -38,6 +38,7 @@
#include "DNA_windowmanager_types.h"
#include "WM_types.h"
#include "WM_api.h"
#include "RNA_access.h"
@ -357,9 +358,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;
const int radius= brush_size(brush);
co[0]= xy[0]/(brush->size >> 1);
co[1]= xy[1]/(brush->size >> 1);
co[0]= xy[0]/radius;
co[1]= xy[1]/radius;
co[2]= 0.0f;
hasrgb= externtex(mtex, co, &tin, &tr, &tg, &tb, &ta);
@ -382,23 +384,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++) {
@ -412,7 +415,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);
@ -425,7 +428,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);
}
}
}
@ -448,7 +451,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);
@ -464,7 +467,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));
}
}
}
@ -478,7 +481,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 brush_size(brush) */
short flt; /* need float imbuf? */
short texonly; /* no alpha, color or fallof, only texture in imbuf */
@ -523,8 +526,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;
@ -557,8 +560,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;
@ -575,9 +578,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];
@ -659,14 +663,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;
@ -713,9 +718,13 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
MTex *mtex= &brush->mtex;
int size;
short flt;
const int radius= brush_size(brush);
const float alpha= brush_alpha(brush);
if ((brush->size != cache->lastsize) || (brush->alpha != cache->lastalpha)
|| (brush->jitter != cache->lastjitter)) {
if (radius != cache->lastsize ||
alpha != cache->lastalpha ||
brush->jitter != cache->lastjitter)
{
if (cache->ibuf) {
IMB_freeImBuf(cache->ibuf);
cache->ibuf= NULL;
@ -726,7 +735,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: radius;
if (!(mtex && mtex->tex) || (mtex->tex->type==0)) {
brush_imbuf_new(brush, flt, 0, size, &cache->ibuf);
@ -738,8 +747,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= radius;
cache->lastalpha= alpha;
cache->lastjitter= brush->jitter;
}
else if ((brush->flag & BRUSH_FIXED_TEX) && mtex && mtex->tex) {
@ -758,10 +767,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)
@ -772,6 +781,7 @@ void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
{
if(brush->jitter){
float rand_pos[2];
const int radius= brush_size(brush);
// find random position within a circle of diameter 1
do {
@ -779,8 +789,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]*radius*brush->jitter;
jitterpos[1] = pos[1] + 2*rand_pos[1]*radius*brush->jitter;
}
else {
VECCOPY2D(jitterpos, pos);
@ -819,7 +829,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; //brush_size(brush)*brush->spacing*0.01f;
/* setup starting time, direction vector and accumulated time */
starttime= painter->accumtime;
@ -850,11 +860,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;
@ -871,7 +882,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);
@ -921,8 +932,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;
@ -1041,9 +1052,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)
@ -1061,15 +1072,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)
@ -1078,3 +1089,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;
}

@ -11050,6 +11050,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
/* GSOC Sculpt 2010 - Sanity check on Sculpt/Paint settings */
if (main->versionfile < 253) {
Scene *sce;
for (sce= main->brush.first; sce; sce= sce->id.next) {
if (sce->toolsettings->sculpt_paint_unified_alpha == 0)
sce->toolsettings->sculpt_paint_unified_alpha = 0.5f;
if (sce->toolsettings->sculpt_paint_unified_unprojected_radius == 0)
sce->toolsettings->sculpt_paint_unified_unprojected_radius = 0.125f;
if (sce->toolsettings->sculpt_paint_unified_size == 0)
sce->toolsettings->sculpt_paint_unified_size = 35;
}
}
/* put compatibility code here until next subversion bump */
{
}

File diff suppressed because it is too large Load Diff

@ -1521,17 +1521,4 @@ void init_userdef_do_versions(void)
/* this timer uses U */
// XXX reset_autosave();
/* GSOC Sculpt 2010 - Sanity check on Sculpt/Paint settings */
if (U.sculpt_paint_unified_alpha == 0)
U.sculpt_paint_unified_alpha = 0.5f;
if (U.sculpt_paint_unified_unprojected_radius == 0)
U.sculpt_paint_unified_unprojected_radius = 0.125f;
if (U.sculpt_paint_unified_size == 0)
U.sculpt_paint_unified_size = 35;
if (G.main->versionfile < 253 || (G.main->versionfile == 253 && G.main->subversionfile < 1))
U.sculpt_paint_settings &= ~SCULPT_PAINT_USE_UNIFIED_SIZE;
}

@ -1334,7 +1334,7 @@ float project_paint_uvpixel_mask(
// This only works when the opacity dosnt change while painting, stylus pressure messes with this
// so dont use it.
// if (ps->is_airbrush==0) mask *= ps->brush->alpha;
// if (ps->is_airbrush==0) mask *= brush_alpha(ps->brush);
return mask;
}
@ -2810,6 +2810,8 @@ static void project_paint_begin(ProjPaintState *ps)
MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
const int diameter= 2*brush_size(ps->brush);
/* ---- end defines ---- */
if(ps->source==PROJ_SRC_VIEW)
@ -3030,11 +3032,11 @@ static void project_paint_begin(ProjPaintState *ps)
if(ps->source==PROJ_SRC_VIEW) {
#ifdef PROJ_DEBUG_WINCLIP
CLAMP(ps->screenMin[0], (float)(-ps->brush->size), (float)(ps->winx + ps->brush->size));
CLAMP(ps->screenMax[0], (float)(-ps->brush->size), (float)(ps->winx + ps->brush->size));
CLAMP(ps->screenMin[0], (float)(-diameter), (float)(ps->winx + diameter));
CLAMP(ps->screenMax[0], (float)(-diameter), (float)(ps->winx + diameter));
CLAMP(ps->screenMin[1], (float)(-ps->brush->size), (float)(ps->winy + ps->brush->size));
CLAMP(ps->screenMax[1], (float)(-ps->brush->size), (float)(ps->winy + ps->brush->size));
CLAMP(ps->screenMin[1], (float)(-diameter), (float)(ps->winy + diameter));
CLAMP(ps->screenMax[1], (float)(-diameter), (float)(ps->winy + diameter));
#endif
}
else { /* reprojection, use bounds */
@ -3049,8 +3051,8 @@ static void project_paint_begin(ProjPaintState *ps)
ps->screen_width = ps->screenMax[0] - ps->screenMin[0];
ps->screen_height = ps->screenMax[1] - ps->screenMin[1];
ps->buckets_x = (int)(ps->screen_width / (((float)ps->brush->size) / PROJ_BUCKET_BRUSH_DIV));
ps->buckets_y = (int)(ps->screen_height / (((float)ps->brush->size) / PROJ_BUCKET_BRUSH_DIV));
ps->buckets_x = (int)(ps->screen_width / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
ps->buckets_y = (int)(ps->screen_height / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
/* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */
@ -3448,16 +3450,16 @@ static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
{
if(ps->source==PROJ_SRC_VIEW) {
float min_brush[2], max_brush[2];
float size_half = ((float)ps->brush->size) * 0.5f;
const float radius = (float)brush_size(ps->brush);
/* so we dont have a bucket bounds that is way too small to paint into */
// if (size_half < 1.0f) size_half = 1.0f; // this dosnt work yet :/
// if (radius < 1.0f) radius = 1.0f; // this doesn't work yet :/
min_brush[0] = mval_f[0] - size_half;
min_brush[1] = mval_f[1] - size_half;
min_brush[0] = mval_f[0] - radius;
min_brush[1] = mval_f[1] - radius;
max_brush[0] = mval_f[0] + size_half;
max_brush[1] = mval_f[1] + size_half;
max_brush[0] = mval_f[0] + radius;
max_brush[1] = mval_f[1] + radius;
/* offset to make this a valid bucket index */
project_paint_bucket_bounds(ps, min_brush, max_brush, ps->bucketMin, ps->bucketMax);
@ -3486,6 +3488,8 @@ static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2])
{
const int diameter= 2*brush_size(ps->brush);
if (ps->thread_tot > 1)
BLI_lock_thread(LOCK_CUSTOM1);
@ -3498,7 +3502,7 @@ static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf
project_bucket_bounds(ps, ps->context_bucket_x, ps->context_bucket_y, bucket_bounds);
if ( (ps->source != PROJ_SRC_VIEW) ||
project_bucket_isect_circle(ps->context_bucket_x, ps->context_bucket_y, mval, (float)(ps->brush->size * ps->brush->size), bucket_bounds)
project_bucket_isect_circle(ps->context_bucket_x, ps->context_bucket_y, mval, (float)(diameter*diameter), bucket_bounds)
) {
*bucket_index = ps->context_bucket_x + (ps->context_bucket_y * ps->buckets_x);
ps->context_bucket_x++;
@ -3685,7 +3689,6 @@ static void *do_projectpaint_thread(void *ph_v)
float rgba[4], alpha, dist_nosqrt, dist;
float brush_size_sqared;
float falloff;
int bucket_index;
int is_floatbuf = 0;
@ -3697,14 +3700,15 @@ static void *do_projectpaint_thread(void *ph_v)
float co[2];
float mask = 1.0f; /* airbrush wont use mask */
unsigned short mask_short;
float size_half = ((float)ps->brush->size) * 0.5f;
const float radius= (float)brush_size(ps->brush);
const float radius_squared= radius*radius; /* avoid a square root with every dist comparison */
short lock_alpha= ELEM(ps->brush->blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA) ? 0 : ps->brush->flag & BRUSH_LOCK_ALPHA;
LinkNode *smearPixels = NULL;
LinkNode *smearPixels_f = NULL;
MemArena *smearArena = NULL; /* mem arena for this brush projection only */
if (tool==PAINT_TOOL_SMEAR) {
pos_ofs[0] = pos[0] - lastpos[0];
pos_ofs[1] = pos[1] - lastpos[1];
@ -3712,9 +3716,6 @@ static void *do_projectpaint_thread(void *ph_v)
smearArena = BLI_memarena_new(1<<16, "paint smear arena");
}
/* avoid a square root with every dist comparison */
brush_size_sqared = (float)(ps->brush->size * ps->brush->size);
/* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */
while (project_bucket_iter_next(ps, &bucket_index, &bucket_bounds, pos)) {
@ -3735,7 +3736,7 @@ static void *do_projectpaint_thread(void *ph_v)
bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, NULL, projPixel->projCoSS[0], projPixel->projCoSS[1]);
if(projPixel->newColor.ch[3]) {
mask = ((float)projPixel->mask)/65535.0f;
blend_color_mix_accum(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (mask*projPixel->newColor.ch[3]));
blend_color_mix_accum(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask*projPixel->newColor.ch[3]));
}
}
@ -3750,9 +3751,11 @@ static void *do_projectpaint_thread(void *ph_v)
/*dist = len_v2v2(projPixel->projCoSS, pos);*/ /* correct but uses a sqrtf */
dist_nosqrt = Vec2Lenf_nosqrt(projPixel->projCoSS, pos);
/*if (dist < s->brush->size) {*/ /* correct but uses a sqrtf */
if (dist_nosqrt < brush_size_sqared && (dist=sqrtf(dist_nosqrt)) < size_half) {
falloff = brush_curve_strength_clamp(ps->brush, dist, size_half);
/*if (dist < radius) {*/ /* correct but uses a sqrtf */
if (dist_nosqrt <= radius_squared) {
dist=sqrtf(dist_nosqrt);
falloff = brush_curve_strength_clamp(ps->brush, dist, radius);
if (falloff > 0.0f) {
if (ps->is_texbrush) {
@ -3764,7 +3767,7 @@ static void *do_projectpaint_thread(void *ph_v)
if (ps->is_airbrush) {
/* for an aurbrush there is no real mask, so just multiply the alpha by it */
alpha *= falloff * ps->brush->alpha;
alpha *= falloff * brush_alpha(ps->brush);
mask = ((float)projPixel->mask)/65535.0f;
}
else {
@ -3772,7 +3775,7 @@ static void *do_projectpaint_thread(void *ph_v)
falloff = 1.0f - falloff;
falloff = 1.0f - (falloff * falloff);
mask_short = (unsigned short)(projPixel->mask * (ps->brush->alpha * falloff));
mask_short = (unsigned short)(projPixel->mask * (brush_alpha(ps->brush) * falloff));
if (mask_short > projPixel->mask_max) {
mask = ((float)mask_short)/65535.0f;
projPixel->mask_max = mask_short;
@ -4520,7 +4523,7 @@ typedef struct PaintOperation {
int first;
int prevmouse[2];
float prev_pressure; /* need this since we dont get tablet events for pressure change */
int brush_size_orig;
int orig_brush_size;
double starttime;
ViewContext vc;
@ -4653,7 +4656,7 @@ static int texture_paint_init(bContext *C, wmOperator *op)
if(pop->mode == PAINT_MODE_3D && (pop->s.tool == PAINT_TOOL_CLONE))
pop->s.tool = PAINT_TOOL_DRAW;
pop->s.blend = brush->blend;
pop->brush_size_orig= brush->size;
pop->orig_brush_size= brush_size(brush);
if(pop->mode != PAINT_MODE_2D) {
pop->s.ob = OBACT;
@ -4685,8 +4688,8 @@ static int texture_paint_init(bContext *C, wmOperator *op)
return 0;
/* Dont allow brush size below 2 */
if (brush->size <= 1)
brush->size = 2;
if (brush_size(brush) < 2)
brush_set_size(brush, 2);
/* allocate and initialize spacial data structures */
project_paint_begin(&pop->ps);
@ -4756,7 +4759,7 @@ static void paint_exit(bContext *C, wmOperator *op)
brush_painter_free(pop->painter);
if(pop->mode == PAINT_MODE_3D_PROJECT) {
pop->ps.brush->size = pop->brush_size_orig;
brush_set_size(pop->ps.brush, pop->orig_brush_size);
project_paint_end(&pop->ps);
}
@ -4827,7 +4830,7 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
/* special exception here for too high pressure values on first touch in
windows for some tablets, then we just skip first touch .. */
if ((pop->s.brush->flag & (BRUSH_ALPHA_PRESSURE|BRUSH_SIZE_PRESSURE|BRUSH_SPACING_PRESSURE)) && tablet && (pressure >= 0.99f))
if (tablet && (pressure >= 0.99f) && (pop->s.brush->flag & BRUSH_SPACING_PRESSURE) && brush_use_alpha_pressure(pop->s.brush) && brush_use_size_pressure(pop->s.brush))
return;
/* This can be removed once fixed properly in
@ -4946,9 +4949,14 @@ static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
static void brush_drawcursor(bContext *C, int x, int y, void *customdata)
{
Brush *brush= image_paint_brush(C);
Paint *paint= paint_get_active(CTX_data_scene(C));
if(brush) {
if(paint && brush) {
float zoomx, zoomy;
if(!(paint->flags & PAINT_SHOW_BRUSH))
return;
glPushMatrix();
glTranslatef((float)x, (float)y, 0.0f);
@ -4956,10 +4964,10 @@ static void brush_drawcursor(bContext *C, int x, int y, void *customdata)
if(get_imapaint_zoom(C, &zoomx, &zoomy))
glScalef(zoomx, zoomy, 1.0f);
glColor4ub(255, 255, 255, 128);
glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], 0.5f);
glEnable( GL_LINE_SMOOTH );
glEnable(GL_BLEND);
glutil_draw_lined_arc(0, (float)(M_PI*2.0), brush->size*0.5f, 40);
glutil_draw_lined_arc(0, (float)(M_PI*2.0), (float)brush_size(brush), 40);
glDisable(GL_BLEND);
glDisable( GL_LINE_SMOOTH );
@ -4986,7 +4994,7 @@ static int paint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *eve
ToolSettings *ts = CTX_data_scene(C)->toolsettings;
get_imapaint_zoom(C, &zoom, &zoom);
toggle_paint_cursor(C, !ts->imapaint.paintcursor);
brush_radial_control_invoke(op, paint_brush(&ts->imapaint.paint), 0.5f * zoom);
brush_radial_control_invoke(op, paint_brush(&ts->imapaint.paint), zoom);
return WM_radial_control_invoke(C, op, event);
}
@ -5006,7 +5014,7 @@ static int paint_radial_control_exec(bContext *C, wmOperator *op)
int ret;
char str[256];
get_imapaint_zoom(C, &zoom, &zoom);
ret = brush_radial_control_exec(op, brush, 2.0f / zoom);
ret = brush_radial_control_exec(op, brush, 1.0f / zoom);
WM_radial_control_string(op, str, 256);
WM_event_add_notifier(C, NC_BRUSH|NA_EDITED, brush);
@ -5313,14 +5321,14 @@ static int texture_paint_radial_control_invoke(bContext *C, wmOperator *op, wmEv
{
ToolSettings *ts = CTX_data_scene(C)->toolsettings;
toggle_paint_cursor(C, !ts->imapaint.paintcursor);
brush_radial_control_invoke(op, paint_brush(&ts->imapaint.paint), 0.5);
brush_radial_control_invoke(op, paint_brush(&ts->imapaint.paint), 1);
return WM_radial_control_invoke(C, op, event);
}
static int texture_paint_radial_control_exec(bContext *C, wmOperator *op)
{
Brush *brush = paint_brush(&CTX_data_scene(C)->toolsettings->imapaint.paint);
int ret = brush_radial_control_exec(op, brush, 2);
int ret = brush_radial_control_exec(op, brush, 1);
char str[256];
WM_radial_control_string(op, str, 256);
@ -5356,7 +5364,7 @@ void PAINT_OT_texture_paint_radial_control(wmOperatorType *ot)
ot->poll= texture_paint_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
}
@ -5425,8 +5433,8 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
/* override */
ps.is_texbrush= 0;
ps.is_airbrush= 1;
orig_brush_size= ps.brush->size;
ps.brush->size= 32; /* cover the whole image */
orig_brush_size= brush_size(ps.brush);
brush_set_size(ps.brush, 32); /* cover the whole image */
ps.tool= PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */
@ -5439,7 +5447,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
project_paint_begin(&ps);
if(ps.dm==NULL) {
ps.brush->size= orig_brush_size;
brush_set_size(ps.brush, orig_brush_size);
return OPERATOR_CANCELLED;
}
else {
@ -5463,7 +5471,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
project_paint_end(&ps);
scene->toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
ps.brush->size= orig_brush_size;
brush_set_size(ps.brush, orig_brush_size);
return OPERATOR_FINISHED;
}

@ -69,24 +69,44 @@ void BRUSH_OT_add(wmOperatorType *ot)
ot->exec= brush_add_exec;
/* flags */
ot->flag= OPTYPE_UNDO;
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
static int brush_scale_size_exec(bContext *C, wmOperator *op)
{
/*int type = RNA_enum_get(op->ptr, "type");*/
Paint *paint = paint_get_active(CTX_data_scene(C));
Brush *br = paint_brush(paint);
Object *ob = CTX_data_active_object(C);
float factor = RNA_float_get(op->ptr, "scalar");
Paint *paint= paint_get_active(CTX_data_scene(C));
Brush *brush= paint_brush(paint);
Object *ob= CTX_data_active_object(C);
float scalar= RNA_float_get(op->ptr, "scalar");
if (br) {
if (ob && (ob->mode & OB_MODE_SCULPT) && (U.sculpt_paint_settings & SCULPT_PAINT_USE_UNIFIED_SIZE)) {
U.sculpt_paint_unified_size *= factor;
if (brush) {
// pixel radius
{
const int old_size= brush_size(brush);
int size= (int)(scalar*old_size);
if (old_size == size)
if (scalar > 1) {
size++;
}
else if (scalar < 1) {
size--;
}
CLAMP(size, 1, 2000); // XXX magic number
brush_set_size(brush, size);
}
else {
br->size *= factor;
// unprojected radius
{
float unprojected_radius= scalar*brush_unprojected_radius(brush);
if (unprojected_radius < 0.001) // XXX magic number
unprojected_radius= 0.001f;
brush_set_unprojected_radius(brush, unprojected_radius);
}
}
@ -104,7 +124,7 @@ void BRUSH_OT_scale_size(wmOperatorType *ot)
ot->exec= brush_scale_size_exec;
/* flags */
ot->flag= OPTYPE_UNDO;
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_float(ot->srna, "scalar", 1, 0, 2, "Scalar", "Factor to scale brush size by", 0, 2);
}

@ -227,7 +227,7 @@ static int same_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
mtex->size[1] == snap->size[1] &&
mtex->size[2] == snap->size[2] &&
mtex->rot == snap->rot) &&
((mtex->brush_map_mode == MTEX_MAP_MODE_FIXED && sculpt_get_brush_size(brush) <= snap->brush_size) || (sculpt_get_brush_size(brush) == snap->brush_size)) && // make brush smaller shouldn't cause a resample
((mtex->brush_map_mode == MTEX_MAP_MODE_FIXED && brush_size(brush) <= snap->brush_size) || (brush_size(brush) == snap->brush_size)) && // make brush smaller shouldn't cause a resample
mtex->brush_map_mode == snap->brush_map_mode &&
vc->ar->winx == snap->winx &&
vc->ar->winy == snap->winy;
@ -248,7 +248,7 @@ static void make_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
snap->rot = -1;
}
snap->brush_size = sculpt_get_brush_size(brush);
snap->brush_size = brush_size(brush);
snap->winx = vc->ar->winx;
snap->winy = vc->ar->winy;
}
@ -289,7 +289,7 @@ int load_tex(Sculpt *sd, Brush* br, ViewContext* vc)
make_snap(&snap, br, vc);
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
int s = sculpt_get_brush_size(br);
int s = brush_size(br);
int r = 1;
for (s >>= 1; s > 0; s >>= 1)
@ -330,7 +330,7 @@ int load_tex(Sculpt *sd, Brush* br, ViewContext* vc)
// largely duplicated from tex_strength
const float rotation = -br->mtex.rot;
float diameter = sculpt_get_brush_size(br);
float radius = brush_size(br);
int index = j*size + i;
float x;
float avg;
@ -342,8 +342,8 @@ int load_tex(Sculpt *sd, Brush* br, ViewContext* vc)
y -= 0.5f;
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
x *= vc->ar->winx / diameter;
y *= vc->ar->winy / diameter;
x *= vc->ar->winx / radius;
y *= vc->ar->winy / radius;
}
else {
x *= 2;
@ -488,10 +488,10 @@ int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radius, floa
memcpy(viewport, stroke->mats.viewport, sizeof(int[4]));
if (stroke->vc.obact->sculpt && stroke->vc.obact->sculpt->pbvh && sculpt_stroke_get_location(C, stroke, location, window)) {
*pixel_radius = project_brush_radius(stroke->vc.rv3d, sculpt_get_brush_unprojected_radius(stroke->brush), location, &stroke->mats);
*pixel_radius = project_brush_radius(stroke->vc.rv3d, brush_unprojected_radius(stroke->brush), location, &stroke->mats);
if (*pixel_radius == 0)
*pixel_radius = sculpt_get_brush_size(stroke->brush);
*pixel_radius = brush_size(stroke->brush);
mul_m4_v3(stroke->vc.obact->sculpt->ob->obmat, location);
@ -501,7 +501,7 @@ int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radius, floa
Sculpt* sd = CTX_data_tool_settings(C)->sculpt;
Brush* brush = paint_brush(&sd->paint);
*pixel_radius = sculpt_get_brush_size(brush);
*pixel_radius = brush_size(brush);
hit = 0;
}
@ -556,7 +556,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *unused)
float* col;
float alpha;
float visual_strength = sculpt_get_brush_alpha(brush)*sculpt_get_brush_alpha(brush);
float visual_strength = brush_alpha(brush)*brush_alpha(brush);
const float min_alpha = 0.20f;
const float max_alpha = 0.80f;
@ -577,13 +577,13 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *unused)
}
}
if(!sculpt_get_lock_brush_size(brush) && !(paint->flags & PAINT_SHOW_BRUSH))
if(!brush_use_locked_size(brush) && !(paint->flags & PAINT_SHOW_BRUSH))
return;
hit = sculpt_get_brush_geometry(C, x, y, &pixel_radius, location, modelview, projection, viewport);
if (sculpt_get_lock_brush_size(brush))
sculpt_set_brush_size(brush, pixel_radius);
if (brush_use_locked_size(brush))
brush_set_size(brush, pixel_radius);
// XXX: no way currently to know state of pen flip or invert key modifier without starting a stroke
flip = 1;
@ -633,7 +633,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *unused)
glTranslatef(-0.5f, -0.5f, 0);
if (sd->draw_pressure && (brush->flag & BRUSH_SIZE_PRESSURE)) {
if (sd->draw_pressure && brush_use_size_pressure(brush)) {
glTranslatef(0.5f, 0.5f, 0);
glScalef(1.0f/sd->pressure_value, 1.0f/sd->pressure_value, 1);
glTranslatef(-0.5f, -0.5f, 0);
@ -662,17 +662,19 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *unused)
glVertex2f(sd->anchored_initial_mouse[0]-sd->anchored_size - vc.ar->winrct.xmin, sd->anchored_initial_mouse[1]+sd->anchored_size - vc.ar->winrct.ymin);
}
else {
const int radius= brush_size(brush);
glTexCoord2f(0, 0);
glVertex2f((float)x-sculpt_get_brush_size(brush), (float)y-sculpt_get_brush_size(brush));
glVertex2f((float)x-radius, (float)y-radius);
glTexCoord2f(1, 0);
glVertex2f((float)x+sculpt_get_brush_size(brush), (float)y-sculpt_get_brush_size(brush));
glVertex2f((float)x+radius, (float)y-radius);
glTexCoord2f(1, 1);
glVertex2f((float)x+sculpt_get_brush_size(brush), (float)y+sculpt_get_brush_size(brush));
glVertex2f((float)x+radius, (float)y+radius);
glTexCoord2f(0, 1);
glVertex2f((float)x-sculpt_get_brush_size(brush), (float)y+sculpt_get_brush_size(brush));
glVertex2f((float)x-radius, (float)y+radius);
}
}
else {
@ -702,7 +704,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *unused)
// XXX duplicated from brush_strength & paint_stroke_add_step, refactor later
//wmEvent* event = CTX_wm_window(C)->eventstate;
if (sd->draw_pressure && (brush->flag & BRUSH_ALPHA_PRESSURE))
if (sd->draw_pressure && brush_use_alpha_pressure(brush))
visual_strength *= sd->pressure_value;
// don't show effect of strength past the soft limit
@ -715,14 +717,14 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *unused)
if (brush->flag & BRUSH_ANCHORED)
unprojected_radius = unproject_brush_radius(CTX_data_active_object(C), &vc, location, 8);
else
unprojected_radius = unproject_brush_radius(CTX_data_active_object(C), &vc, location, sculpt_get_brush_size(brush));
unprojected_radius = unproject_brush_radius(CTX_data_active_object(C), &vc, location, brush_size(brush));
}
if (sd->draw_pressure && (brush->flag & BRUSH_SIZE_PRESSURE))
if (sd->draw_pressure && brush_use_size_pressure(brush))
unprojected_radius *= sd->pressure_value;
if (!sculpt_get_lock_brush_size(brush))
sculpt_set_brush_unprojected_radius(brush, unprojected_radius);
if (!brush_use_locked_size(brush))
brush_set_unprojected_radius(brush, unprojected_radius);
if(!(paint->flags & PAINT_SHOW_BRUSH))
return;
@ -754,7 +756,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *unused)
}
else {
glTranslatef((float)x, (float)y, 0.0f);
glutil_draw_lined_arc(0.0, M_PI*2.0, sculpt_get_brush_size(brush), 40);
glutil_draw_lined_arc(0.0, M_PI*2.0, brush_size(brush), 40);
glTranslatef(-(float)x, -(float)y, 0.0f);
}
@ -767,12 +769,12 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *unused)
if(!(paint->flags & PAINT_SHOW_BRUSH))
return;
glColor4ubv(paint_get_active(CTX_data_scene(C))->paint_cursor_col);
glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], 0.5f);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glTranslatef((float)x, (float)y, 0.0f);
glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40); // XXX: for now use the brushes size instead of potentially using the unified size because the feature has been enabled for sculpt
glutil_draw_lined_arc(0.0, M_PI*2.0, brush_size(brush), 40); // XXX: for now use the brushes size instead of potentially using the unified size because the feature has been enabled for sculpt
glTranslatef((float)-x, (float)-y, 0.0f);
glDisable(GL_BLEND);
@ -909,10 +911,10 @@ static int paint_space_stroke(bContext *C, wmOperator *op, wmEvent *event, const
if(event->custom == EVT_DATA_TABLET) {
wmTabletData *wmtab= event->customdata;
if(wmtab->Active != EVT_TABLET_NONE)
pressure = stroke->brush->flag & BRUSH_SIZE_PRESSURE ? wmtab->Pressure : 1;
pressure = brush_use_size_pressure(stroke->brush) ? wmtab->Pressure : 1;
}
scale = (sculpt_get_brush_size(stroke->brush)*pressure*stroke->brush->spacing/50.0f) / length;
scale = (brush_size(stroke->brush)*pressure*stroke->brush->spacing/50.0f) / length;
mul_v2_fl(vec, scale);
steps = (int)(1.0f / scale);

@ -229,7 +229,7 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot)
ot->exec= brush_curve_preset_exec;
ot->poll= brush_curve_preset_poll;
ot->flag= OPTYPE_UNDO;
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", "");
}

@ -663,7 +663,7 @@ static void vpaint_blend(VPaint *vp, unsigned int *col, unsigned int *colorig, u
unsigned int testcol=0, a;
char *cp, *ct, *co;
alpha= (int)(255.0*brush->alpha);
alpha= (int)(255.0*brush_alpha(brush));
if(brush->vertexpaint_tool==VP_MIX || brush->vertexpaint_tool==VP_BLUR) testcol= mcol_blend( *colorig, paintcol, alpha);
else if(brush->vertexpaint_tool==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha);
@ -733,23 +733,24 @@ static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, float vpimat[][3], fl
float fac, fac_2, size, dx, dy;
float alpha;
short vertco[2];
const int radius= brush_size(brush);
project_short_noclip(vc->ar, vert_nor, vertco);
dx= mval[0]-vertco[0];
dy= mval[1]-vertco[1];
if (brush->flag & BRUSH_SIZE_PRESSURE)
size = pressure * brush->size;
if (brush_use_size_pressure(brush))
size = pressure * radius;
else
size = brush->size;
size = radius;
fac_2= dx*dx + dy*dy;
if(fac_2 > size*size) return 0.f;
fac = sqrtf(fac_2);
alpha= brush->alpha * brush_curve_strength_clamp(brush, fac, size);
alpha= brush_alpha(brush) * brush_curve_strength_clamp(brush, fac, size);
if (brush->flag & BRUSH_ALPHA_PRESSURE)
if (brush_use_alpha_pressure(brush))
alpha *= pressure;
if(vp->flag & VP_NORMALS) {
@ -813,7 +814,7 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float
if((wp->flag & VP_SPRAY)==0) {
float testw=0.0f;
alpha= brush->alpha;
alpha= brush_alpha(brush);
if(tool==VP_MIX || tool==VP_BLUR)
testw = paintval*alpha + uw->weight*(1.0-alpha);
else if(tool==VP_ADD)
@ -1454,7 +1455,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* which faces are involved */
if(wp->flag & VP_AREA) {
totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush->size);
totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size(brush));
}
else {
indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]);
@ -1740,7 +1741,6 @@ void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
@ -1874,7 +1874,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* which faces are involved */
if(vp->flag & VP_AREA) {
totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush->size);
totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size(brush));
}
else {
indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]);

@ -589,9 +589,10 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather)
Brush *brush = paint_brush(&sd->paint);
/* Primary strength input; square it to make lower values more sensitive */
float alpha = sculpt_get_brush_alpha(brush)*sculpt_get_brush_alpha(brush);
const root_alpha = brush_alpha(brush);
float alpha = root_alpha*root_alpha;
float dir = brush->flag & BRUSH_DIR_IN ? -1 : 1;
float pressure = brush->flag & BRUSH_ALPHA_PRESSURE ? cache->pressure : 1;
float pressure = brush_use_alpha_pressure(brush) ? cache->pressure : 1;
float pen_flip = cache->pen_flip ? -1 : 1;
float invert = cache->invert ? -1 : 1;
float accum = integrate_overlap(brush);
@ -739,7 +740,7 @@ static float tex_strength(SculptSession *ss, Brush *br, float *point, const floa
else if(ss->texcache) {
float rotation = -mtex->rot;
float x, y, point_2d[3];
float diameter;
float radius;
/* if the active area is being applied for symmetry, flip it
across the symmetry axis and rotate it back to the orignal
@ -760,7 +761,7 @@ static float tex_strength(SculptSession *ss, Brush *br, float *point, const floa
point_2d[0] -= ss->cache->tex_mouse[0];
point_2d[1] -= ss->cache->tex_mouse[1];
diameter = ss->cache->pixel_radius; // use pressure adjusted size for fixed mode
radius = ss->cache->pixel_radius; // use pressure adjusted size for fixed mode
x = point_2d[0];
y = point_2d[1];
@ -768,7 +769,7 @@ static float tex_strength(SculptSession *ss, Brush *br, float *point, const floa
else /* else (mtex->brush_map_mode == MTEX_MAP_MODE_TILED),
leave the coordinates relative to the screen */
{
diameter = sculpt_get_brush_size(br); // use unadjusted size for tiled mode
radius = brush_size(br); // use unadjusted size for tiled mode
x = point_2d[0] - ss->cache->vc->ar->winrct.xmin;
y = point_2d[1] - ss->cache->vc->ar->winrct.ymin;
@ -782,8 +783,8 @@ static float tex_strength(SculptSession *ss, Brush *br, float *point, const floa
y -= 0.5f;
}
x *= ss->cache->vc->ar->winx / diameter;
y *= ss->cache->vc->ar->winy / diameter;
x *= ss->cache->vc->ar->winx / radius;
y *= ss->cache->vc->ar->winy / radius;
/* it is probably worth optimizing for those cases where
the texture is not rotated by skipping the calls to
@ -1253,8 +1254,8 @@ static void do_crease_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int
/* we divide out the squared alpha and multiply by the squared crease to give us the pinch strength */
if(sculpt_get_brush_alpha(brush) > 0.0f)
crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor/(sculpt_get_brush_alpha(brush)*sculpt_get_brush_alpha(brush));
if(brush_alpha(brush) > 0.0f)
crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor/(brush_alpha(brush)*brush_alpha(brush));
else
crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor;
@ -1807,7 +1808,12 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, SculptSession *ss, P
normalize_v3(an);
// fc
mul_v3_fl(fc, 1.0f / count);
if (count != 0) {
mul_v3_fl(fc, 1.0f / count);
}
else {
zero_v3(fc);
}
}
static void calc_sculpt_plane(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode, float an[3], float fc[3])
@ -2614,6 +2620,7 @@ static void do_symmetrical_brush_actions(Sculpt *sd, SculptSession *ss)
static void sculpt_update_tex(Sculpt *sd, SculptSession *ss)
{
Brush *brush = paint_brush(&sd->paint);
const int radius= brush_size(brush);
if(ss->texcache) {
MEM_freeN(ss->texcache);
@ -2621,9 +2628,9 @@ static void sculpt_update_tex(Sculpt *sd, SculptSession *ss)
}
/* Need to allocate a bigger buffer for bigger brush size */
ss->texcache_side = 2*sculpt_get_brush_size(brush);
ss->texcache_side = 2*radius;
if(!ss->texcache || ss->texcache_side > ss->texcache_actual) {
ss->texcache = brush_gen_texture_cache(brush, sculpt_get_brush_size(brush));
ss->texcache = brush_gen_texture_cache(brush, radius);
ss->texcache_actual = ss->texcache_side;
}
}
@ -2797,50 +2804,6 @@ static void sculpt_cache_free(StrokeCache *cache)
MEM_freeN(cache);
}
int sculpt_get_brush_size(Brush *brush)
{
return (U.sculpt_paint_settings & SCULPT_PAINT_USE_UNIFIED_SIZE) ? U.sculpt_paint_unified_size : brush->size;
}
void sculpt_set_brush_size(Brush *brush, int size)
{
if (U.sculpt_paint_settings & SCULPT_PAINT_USE_UNIFIED_SIZE)
U.sculpt_paint_unified_size = size;
else
brush->size = size;
}
int sculpt_get_lock_brush_size(Brush *brush)
{
return (U.sculpt_paint_settings & SCULPT_PAINT_USE_UNIFIED_SIZE) ? (U.sculpt_paint_settings & SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE) : (brush->flag & BRUSH_LOCK_SIZE);
}
float sculpt_get_brush_unprojected_radius(Brush *brush)
{
return (U.sculpt_paint_settings & SCULPT_PAINT_USE_UNIFIED_SIZE) ? U.sculpt_paint_unified_unprojected_radius : brush->unprojected_radius;
}
void sculpt_set_brush_unprojected_radius(Brush *brush, float unprojected_radius)
{
if (U.sculpt_paint_settings & SCULPT_PAINT_USE_UNIFIED_SIZE)
U.sculpt_paint_unified_unprojected_radius = unprojected_radius;
else
brush->unprojected_radius = unprojected_radius;
}
float sculpt_get_brush_alpha(Brush *brush)
{
return (U.sculpt_paint_settings & SCULPT_PAINT_USE_UNIFIED_ALPHA) ? U.sculpt_paint_unified_alpha : brush->alpha;
}
void sculpt_set_brush_alpha(Brush *brush, float alpha)
{
if (U.sculpt_paint_settings & SCULPT_PAINT_USE_UNIFIED_ALPHA)
U.sculpt_paint_unified_alpha = alpha;
else
brush->alpha = alpha;
}
/* Initialize the stroke cache invariants from operator properties */
static void sculpt_update_cache_invariants(bContext* C, Sculpt *sd, SculptSession *ss, wmOperator *op, wmEvent *event)
{
@ -3064,22 +3027,22 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, SculptSession
sd->pressure_value= cache->pressure;
cache->previous_pixel_radius = cache->pixel_radius;
cache->pixel_radius = sculpt_get_brush_size(brush);
cache->pixel_radius = brush_size(brush);
if(cache->first_time) {
if (!sculpt_get_lock_brush_size(brush)) {
cache->initial_radius= unproject_brush_radius(ss->ob, cache->vc, cache->true_location, sculpt_get_brush_size(brush));
sculpt_set_brush_unprojected_radius(brush, cache->initial_radius);
if (!brush_use_locked_size(brush)) {
cache->initial_radius= unproject_brush_radius(ss->ob, cache->vc, cache->true_location, brush_size(brush));
brush_set_unprojected_radius(brush, cache->initial_radius);
}
else {
cache->initial_radius= sculpt_get_brush_unprojected_radius(brush);
cache->initial_radius= brush_unprojected_radius(brush);
}
if (ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK))
cache->initial_radius *= 2.0f;
}
if(brush->flag & BRUSH_SIZE_PRESSURE) {
if(brush_use_size_pressure(brush)) {
cache->pixel_radius *= cache->pressure;
cache->radius= cache->initial_radius * cache->pressure;
}
@ -3290,7 +3253,7 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss)
/* Restore the mesh before continuing with anchored stroke */
if((brush->flag & BRUSH_ANCHORED) ||
(brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_SIZE_PRESSURE)) ||
(brush->sculpt_tool == SCULPT_TOOL_GRAB && brush_use_size_pressure(brush)) ||
(brush->flag & BRUSH_RESTORE_MESH))
{
StrokeCache *cache = ss->cache;
@ -3604,7 +3567,7 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
ot->exec= sculpt_set_persistent_base;
ot->poll= sculpt_mode_poll;
ot->flag= 0;//OPTYPE_REGISTER;
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
/**** Toggle operator for turning sculpt mode on or off ****/
@ -3685,7 +3648,7 @@ static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot)
ot->exec= sculpt_toggle_mode;
ot->poll= ED_operator_object_active;
ot->flag= 0;
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
void ED_operatortypes_sculpt()

@ -521,7 +521,7 @@ static void draw_image_view_tool(Scene *scene)
if(draw) {
getmouseco_areawin(mval);
radius= brush->size*G.sima->zoom/2;
radius= brush_size(brush)*G.sima->zoom;
fdrawXORcirc(mval[0], mval[1], radius);
if (brush->innerradius != 1.0) {

@ -726,6 +726,12 @@ typedef struct ToolSettings {
short proportional, prop_mode;
int auto_normalize, intpad; /*auto normalizing mode in wpaint*/
short sculpt_paint_settings; /* user preferences for sculpt and paint */
short pad;
int sculpt_paint_unified_size; /* unified radius of brush in pixels */
float sculpt_paint_unified_unprojected_radius;/* unified radius of brush in Blender units */
float sculpt_paint_unified_alpha; /* unified strength of brush */
} ToolSettings;
typedef struct bStats {
@ -1141,6 +1147,13 @@ typedef enum SculptFlags {
SCULPT_USE_OPENMP = (1<<7),
} SculptFlags;
/* sculpt_paint_settings */
#define SCULPT_PAINT_USE_UNIFIED_SIZE (1<<0)
#define SCULPT_PAINT_USE_UNIFIED_ALPHA (1<<1)
#define SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE (1<<2)
#define SCULPT_PAINT_UNIFIED_SIZE_PRESSURE (1<<3)
#define SCULPT_PAINT_UNIFIED_ALPHA_PRESSURE (1<<4)
/* ImagePaintSettings.flag */
#define IMAGEPAINT_DRAWING 1
#define IMAGEPAINT_DRAW_TOOL 2

@ -341,10 +341,10 @@ typedef struct UserDef {
short gp_settings;
short tb_leftmouse, tb_rightmouse;
struct SolidLight light[3];
short sculpt_paint_settings; /* user preferences for sculpt and paint */
short tw_hotspot, tw_flag, tw_handlesize, tw_size;
short textimeout,texcollectrate;
short wmdrawmethod; /* removed wmpad */
short pad2;
int memcachelimit;
int prefetchframes;
short frameserverport;
@ -375,10 +375,8 @@ typedef struct UserDef {
struct ColorBand coba_weight; /* from texture.h */
int sculpt_paint_unified_size; /* unified radius of brush in pixels */
float sculpt_paint_unified_unprojected_radius;/* unified radius of brush in Blender units */
float sculpt_paint_unified_alpha; /* unified strength of brush */
float sculpt_paint_overlay_col[3];
int pad3;
} UserDef;
extern UserDef U; /* from blenkernel blender.c */
@ -530,11 +528,6 @@ extern UserDef U; /* from blenkernel blender.c */
#define GP_PAINT_DOSMOOTH (1<<0)
#define GP_PAINT_DOSIMPLIFY (1<<1)
/* sculpt_paint_settings */
#define SCULPT_PAINT_USE_UNIFIED_SIZE (1<<0)
#define SCULPT_PAINT_USE_UNIFIED_ALPHA (1<<1)
#define SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE (1<<2)
/* color picker types */
#define USER_CP_CIRCLE 0
#define USER_CP_SQUARE_SV 1

@ -52,6 +52,7 @@ static void rna_Brush_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Brush *br= (Brush*)ptr->data;
WM_main_add_notifier(NC_BRUSH|NA_EDITED, br);
WM_main_add_notifier(NC_SPACE|ND_SPACE_VIEW3D, NULL);
}
static int rna_Brush_is_sculpt_brush(Brush *me, bContext *C)
@ -120,6 +121,78 @@ static void rna_Brush_icon_update(Main *bmain, Scene *scene, PointerRNA *ptr)
WM_main_add_notifier(NC_BRUSH|NA_EDITED, br);
}
static void rna_Brush_set_size(PointerRNA *ptr, int value)
{
Brush* me = (Brush*)(ptr->data);
brush_set_size(me, value);
}
static int rna_Brush_get_size(PointerRNA *ptr)
{
Brush* me = (Brush*)(ptr->data);
return brush_size(me);
}
static void rna_Brush_set_use_locked_size(PointerRNA *ptr, int value)
{
Brush* me = (Brush*)(ptr->data);
brush_set_use_locked_size(me, value);
}
static int rna_Brush_get_use_locked_size(PointerRNA *ptr)
{
Brush* me = (Brush*)(ptr->data);
return brush_use_locked_size(me);
}
static void rna_Brush_set_use_size_pressure(PointerRNA *ptr, int value)
{
Brush* me = (Brush*)(ptr->data);
brush_set_use_size_pressure(me, value);
}
static int rna_Brush_get_use_size_pressure(PointerRNA *ptr)
{
Brush* me = (Brush*)(ptr->data);
return brush_use_size_pressure(me);
}
static void rna_Brush_set_use_alpha_pressure(PointerRNA *ptr, int value)
{
Brush* me = (Brush*)(ptr->data);
brush_set_use_alpha_pressure(me, value);
}
static int rna_Brush_get_use_alpha_pressure(PointerRNA *ptr)
{
Brush* me = (Brush*)(ptr->data);
return brush_use_alpha_pressure(me);
}
static void rna_Brush_set_unprojected_radius(PointerRNA *ptr, float value)
{
Brush* me = (Brush*)(ptr->data);
brush_set_unprojected_radius(me, value);
}
static float rna_Brush_get_unprojected_radius(PointerRNA *ptr)
{
Brush* me = (Brush*)(ptr->data);
return brush_unprojected_radius(me);
}
static void rna_Brush_set_alpha(PointerRNA *ptr, float value)
{
Brush* me = (Brush*)(ptr->data);
brush_set_alpha(me, value);
}
static float rna_Brush_get_alpha(PointerRNA *ptr)
{
Brush* me = (Brush*)(ptr->data);
return brush_alpha(me);
}
#else
static void rna_def_brush_texture_slot(BlenderRNA *brna)
@ -415,15 +488,17 @@ static void rna_def_brush(BlenderRNA *brna)
/* number values */
prop= RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE);
RNA_def_property_int_funcs(prop, "rna_Brush_get_size", "rna_Brush_set_size", NULL);
RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS*10);
RNA_def_property_ui_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, 0);
RNA_def_property_ui_text(prop, "Size", "Radius of the brush in pixels");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 1, 0, 0);
RNA_def_property_ui_text(prop, "Surface Size", "Radius of brush in Blender units");
RNA_def_property_float_funcs(prop, "rna_Brush_get_unprojected_radius", "rna_Brush_set_unprojected_radius", NULL);
RNA_def_property_range(prop, 0.001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001, 1, 0, 0);
RNA_def_property_ui_text(prop, "Unprojected Radius", "Radius of brush in Blender units");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "jitter", PROP_FLOAT, PROP_NONE);
@ -464,6 +539,7 @@ static void rna_def_brush(BlenderRNA *brna)
prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "alpha");
RNA_def_property_float_funcs(prop, "rna_Brush_get_alpha", "rna_Brush_set_alpha", NULL);
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 0.001);
@ -532,6 +608,7 @@ static void rna_def_brush(BlenderRNA *brna)
prop= RNA_def_property(srna, "use_strength_pressure", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ALPHA_PRESSURE);
RNA_def_property_boolean_funcs(prop, "rna_Brush_get_use_alpha_pressure", "rna_Brush_set_use_alpha_pressure");
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength");
RNA_def_property_update(prop, 0, "rna_Brush_update");
@ -544,6 +621,7 @@ static void rna_def_brush(BlenderRNA *brna)
prop= RNA_def_property(srna, "use_size_pressure", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SIZE_PRESSURE);
RNA_def_property_boolean_funcs(prop, "rna_Brush_get_use_size_pressure", "rna_Brush_set_use_size_pressure");
RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0);
RNA_def_property_ui_text(prop, "Size Pressure", "Enable tablet pressure sensitivity for size");
RNA_def_property_update(prop, 0, "rna_Brush_update");
@ -622,7 +700,8 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Adaptive Spacing", "Space daubs according to surface orientation instead of screen space");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "lock_brush_size", PROP_BOOLEAN, PROP_NONE);
prop= RNA_def_property(srna, "use_locked_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Brush_get_use_locked_size", "rna_Brush_set_use_locked_size");
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_LOCK_SIZE);
RNA_def_property_ui_text(prop, "Use Blender Units", "When locked brush stays same size relative to object; when unlocked brush size is given in pixels");
RNA_def_property_update(prop, 0, "rna_Brush_update");

@ -1167,6 +1167,16 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, sketch_convert_items);
RNA_def_property_ui_text(prop, "Stroke conversion method", "Method used to convert stroke to bones");
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL);
/* Sculpt/Paint Unified Size and Strength */
prop= RNA_def_property(srna, "sculpt_paint_use_unified_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sculpt_paint_settings", SCULPT_PAINT_USE_UNIFIED_SIZE);
RNA_def_property_ui_text(prop, "Sculpt/Paint Use Unified Radius", "Instead of per brush radius, the radius is shared across brushes");
prop= RNA_def_property(srna, "sculpt_paint_use_unified_strength", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sculpt_paint_settings", SCULPT_PAINT_USE_UNIFIED_ALPHA);
RNA_def_property_ui_text(prop, "Sculpt/Paint Use Unified Strength", "Instead of per brush strength, the strength is shared across brushes");
}

@ -2195,35 +2195,6 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Sculpt/Paint Overlay Color", "Color of texture overlay");
prop= RNA_def_property(srna, "sculpt_paint_use_unified_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sculpt_paint_settings", SCULPT_PAINT_USE_UNIFIED_SIZE);
RNA_def_property_ui_text(prop, "Sculpt/Paint Use Unified Radius", "Instead of per brush radius, the radius is shared across brushes");
prop= RNA_def_property(srna, "sculpt_paint_use_unified_strength", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sculpt_paint_settings", SCULPT_PAINT_USE_UNIFIED_ALPHA);
RNA_def_property_ui_text(prop, "Sculpt/Paint Use Unified Strength", "Instead of per brush strength, the strength is shared across brushes");
prop= RNA_def_property(srna, "sculpt_paint_unified_lock_brush_size", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "sculpt_paint_settings", SCULPT_PAINT_UNIFIED_LOCK_BRUSH_SIZE);
RNA_def_property_ui_text(prop, "Sculpt/Paint Use Unified Blender Units", "When locked all brushes stay same size relative to object; when unlocked all brush sizes are given in pixels");
prop= RNA_def_property(srna, "sculpt_paint_unified_size", PROP_INT, PROP_DISTANCE);
RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS*10);
RNA_def_property_ui_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, 0);
RNA_def_property_ui_text(prop, "Sculpt/Paint Unified Size", "Unified radius of the brush in pixels");
prop= RNA_def_property(srna, "sculpt_paint_unified_unprojected_radius", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_range(prop, 0, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 1, 0, 0);
RNA_def_property_ui_text(prop, "Sculpt/Paint Unified Surface Size", "Unified radius of brush in Blender units");
prop= RNA_def_property(srna, "sculpt_paint_unified_strength", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "sculpt_paint_unified_alpha");
RNA_def_property_float_default(prop, 0.5f);
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.001, 0.001);
RNA_def_property_ui_text(prop, "Sculpt/Paint Unified Strength", "Unified power of effect of brushes when applied");
/* duplication linking */
prop= RNA_def_property(srna, "duplicate_mesh", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_MESH);