Fix all remaining unified paint settings uses of current Scene.

Things like brush size and strength accessors now take a scene
parameter rather than guessing about which Scene's unified paint
settings to use.

Setting the size/strength through RNA can now be done separately for
the brush or the UnifiedPaintSettings.

The UI python code required updating to check whether the
size/strength controls should use brush or UnifiedPaintSettings RNA.

Radial control also required some updates to switch between the two
RNA sources.
This commit is contained in:
Nicholas Bishop 2012-01-14 23:54:51 +00:00
parent 046bf80881
commit 30e759c75b
12 changed files with 377 additions and 430 deletions

@ -476,16 +476,16 @@ class PaintPanel():
parent.prop(ups, "use_unified_strength", text="Strength") parent.prop(ups, "use_unified_strength", text="Strength")
@staticmethod @staticmethod
def prop_unified_size(parent, context, brush, prop_name, icon='NONE', text=""): def prop_unified_size(parent, context, brush, prop_name, icon='NONE', text="", slider=False):
ups = context.tool_settings.unified_paint_settings ups = context.tool_settings.unified_paint_settings
ptr = ups if ups.use_unified_size else brush ptr = ups if ups.use_unified_size else brush
parent.prop(ptr, prop_name, icon=icon, text=text) parent.prop(ptr, prop_name, icon=icon, text=text, slider=slider)
@staticmethod @staticmethod
def prop_unified_strength(parent, context, brush, prop_name, icon='NONE', text=""): def prop_unified_strength(parent, context, brush, prop_name, icon='NONE', text="", slider=False):
ups = context.tool_settings.unified_paint_settings ups = context.tool_settings.unified_paint_settings
ptr = ups if ups.use_unified_strength else brush ptr = ups if ups.use_unified_strength else brush
parent.prop(ptr, prop_name, icon=icon, text=text) parent.prop(ptr, prop_name, icon=icon, text=text, slider=slider)
class VIEW3D_PT_tools_brush(PaintPanel, Panel): class VIEW3D_PT_tools_brush(PaintPanel, Panel):
bl_label = "Brush" bl_label = "Brush"
@ -545,10 +545,10 @@ class VIEW3D_PT_tools_brush(PaintPanel, Panel):
if ((ups.use_unified_size and ups.use_locked_size) or if ((ups.use_unified_size and ups.use_locked_size) or
((not ups.use_unified_size) and brush.use_locked_size)): ((not ups.use_unified_size) and brush.use_locked_size)):
self.prop_unified_size(row, context, brush, "use_locked_size", icon='LOCKED') self.prop_unified_size(row, context, brush, "use_locked_size", icon='LOCKED')
row.prop(brush, "unprojected_radius", text="Radius", slider=True) self.prop_unified_size(row, context, brush, "unprojected_radius", slider=True, text="Radius")
else: else:
self.prop_unified_size(row, context, brush, "use_locked_size", icon='UNLOCKED') self.prop_unified_size(row, context, brush, "use_locked_size", icon='UNLOCKED')
row.prop(brush, "size", slider=True) self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
self.prop_unified_size(row, context, brush, "use_pressure_size") self.prop_unified_size(row, context, brush, "use_pressure_size")
@ -563,12 +563,12 @@ class VIEW3D_PT_tools_brush(PaintPanel, Panel):
else: else:
row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED') row.prop(brush, "use_space_atten", toggle=True, text="", icon='UNLOCKED')
row.prop(brush, "strength", text="Strength", slider=True) self.prop_unified_strength(row, context, brush, "strength")
self.prop_unified_strength(row, context, brush, "use_pressure_strength") self.prop_unified_strength(row, context, brush, "use_pressure_strength")
if tool == 'ROTATE': if tool == 'ROTATE':
row = col.row(align=True) row = col.row(align=True)
row.prop(brush, "strength", text="Strength", slider=True) self.prop_unified_strength(row, context, brush, "strength")
self.prop_unified_strength(row, context, brush, "use_pressure_strength") self.prop_unified_strength(row, context, brush, "use_pressure_strength")
if tool != 'SMOOTH': if tool != 'SMOOTH':
@ -656,11 +656,11 @@ class VIEW3D_PT_tools_brush(PaintPanel, Panel):
col.prop(brush, "color", text="") col.prop(brush, "color", text="")
row = col.row(align=True) row = col.row(align=True)
row.prop(brush, "size", slider=True) self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
self.prop_unified_size(row, context, brush, "use_pressure_size") self.prop_unified_size(row, context, brush, "use_pressure_size")
row = col.row(align=True) row = col.row(align=True)
row.prop(brush, "strength", text="Strength", slider=True) self.prop_unified_strength(row, context, brush, "strength")
self.prop_unified_strength(row, context, brush, "use_pressure_strength") self.prop_unified_strength(row, context, brush, "use_pressure_strength")
row = col.row(align=True) row = col.row(align=True)
@ -682,11 +682,11 @@ class VIEW3D_PT_tools_brush(PaintPanel, Panel):
col = layout.column() col = layout.column()
row = col.row(align=True) row = col.row(align=True)
row.prop(brush, "size", slider=True) self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
self.prop_unified_size(row, context, brush, "use_pressure_size") self.prop_unified_size(row, context, brush, "use_pressure_size")
row = col.row(align=True) row = col.row(align=True)
row.prop(brush, "strength", text="Strength", slider=True) self.prop_unified_strength(row, context, brush, "strength")
self.prop_unified_strength(row, context, brush, "use_pressure_strength") self.prop_unified_strength(row, context, brush, "use_pressure_strength")
row = col.row(align=True) row = col.row(align=True)
@ -700,11 +700,11 @@ class VIEW3D_PT_tools_brush(PaintPanel, Panel):
col.prop(brush, "color", text="") col.prop(brush, "color", text="")
row = col.row(align=True) row = col.row(align=True)
row.prop(brush, "size", slider=True) self.prop_unified_size(row, context, brush, "size", slider=True, text="Radius")
self.prop_unified_size(row, context, brush, "use_pressure_size") self.prop_unified_size(row, context, brush, "use_pressure_size")
row = col.row(align=True) row = col.row(align=True)
row.prop(brush, "strength", text="Strength", slider=True) self.prop_unified_strength(row, context, brush, "strength")
self.prop_unified_strength(row, context, brush, "use_pressure_strength") self.prop_unified_strength(row, context, brush, "use_pressure_strength")
# XXX - TODO # XXX - TODO

@ -59,7 +59,8 @@ int brush_clone_image_set_nr(struct Brush *brush, int nr);
int brush_clone_image_delete(struct Brush *brush); int brush_clone_image_delete(struct Brush *brush);
/* jitter */ /* jitter */
void brush_jitter_pos(struct Brush *brush, float *pos, float *jitterpos); void brush_jitter_pos(const struct Scene *scene, struct Brush *brush,
float *pos, float *jitterpos);
/* brush curve */ /* brush curve */
void brush_curve_preset(struct Brush *b, /*enum CurveMappingPreset*/int preset); void brush_curve_preset(struct Brush *b, /*enum CurveMappingPreset*/int preset);
@ -67,8 +68,8 @@ float brush_curve_strength_clamp(struct Brush *br, float p, const float len);
float brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */ float brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */
/* sampling */ /* sampling */
void brush_sample_tex(struct Brush *brush, const float xy[2], float rgba[4], const int thread); void brush_sample_tex(const struct Scene *scene, struct Brush *brush, const float xy[2], float rgba[4], const int thread);
void brush_imbuf_new(struct Brush *brush, short flt, short texfalloff, int size, void brush_imbuf_new(const struct Scene *scene, struct Brush *brush, short flt, short texfalloff, int size,
struct ImBuf **imbuf, int use_color_correction); struct ImBuf **imbuf, int use_color_correction);
/* painting */ /* painting */
@ -92,18 +93,27 @@ struct ImBuf *brush_gen_radial_control_imbuf(struct Brush *br);
/* unified strength and size */ /* unified strength and size */
int brush_size(struct Brush *brush); int brush_size(const struct Scene *scene, struct Brush *brush);
void brush_set_size(struct Brush *brush, int value); void brush_set_size(struct Scene *scene, struct Brush *brush, int value);
float brush_unprojected_radius(const struct Scene *scene, struct Brush *brush);
void brush_set_unprojected_radius(struct Scene *scene, struct Brush *brush, float value);
float brush_alpha(const struct Scene *scene, struct Brush *brush);
int brush_use_locked_size(const struct Scene *scene, struct Brush *brush); int brush_use_locked_size(const struct Scene *scene, struct Brush *brush);
int brush_use_alpha_pressure(const struct Scene *scene, struct Brush *brush); int brush_use_alpha_pressure(const struct Scene *scene, struct Brush *brush);
int brush_use_size_pressure(const struct Scene *scene, struct Brush *brush); int brush_use_size_pressure(const struct Scene *scene, struct Brush *brush);
float brush_unprojected_radius(struct Brush *brush); /* scale unprojected radius to reflect a change in the brush's 2D size */
void brush_set_unprojected_radius(struct Brush *brush, float value); void brush_scale_unprojected_radius(float *unprojected_radius,
int new_brush_size,
int old_brush_size);
float brush_alpha(struct Brush *brush); /* scale brush size to reflect a change in the brush's unprojected radius */
void brush_set_alpha(struct Brush *brush, float value); void brush_scale_size(int *brush_size,
float new_unprojected_radius,
float old_unprojected_radius);
/* debugging only */ /* debugging only */
void brush_debug_print_state(struct Brush *br); void brush_debug_print_state(struct Brush *br);

@ -487,14 +487,14 @@ int brush_clone_image_delete(Brush *brush)
} }
/* Brush Sampling */ /* Brush Sampling */
void brush_sample_tex(Brush *brush, const float xy[2], float rgba[4], const int thread) void brush_sample_tex(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], const int thread)
{ {
MTex *mtex= &brush->mtex; MTex *mtex= &brush->mtex;
if (mtex && mtex->tex) { if (mtex && mtex->tex) {
float co[3], tin, tr, tg, tb, ta; float co[3], tin, tr, tg, tb, ta;
int hasrgb; int hasrgb;
const int radius= brush_size(brush); const int radius= brush_size(scene, brush);
co[0]= xy[0]/radius; co[0]= xy[0]/radius;
co[1]= xy[1]/radius; co[1]= xy[1]/radius;
@ -521,14 +521,14 @@ void brush_sample_tex(Brush *brush, const float xy[2], float rgba[4], const int
} }
/* TODO, use define for 'texfall' arg */ /* TODO, use define for 'texfall' arg */
void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction) void brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction)
{ {
ImBuf *ibuf; ImBuf *ibuf;
float xy[2], rgba[4], *dstf; float xy[2], rgba[4], *dstf;
int x, y, rowbytes, xoff, yoff, imbflag; int x, y, rowbytes, xoff, yoff, imbflag;
const int radius= brush_size(brush); const int radius= brush_size(scene, brush);
char *dst, crgb[3]; char *dst, crgb[3];
const float alpha= brush_alpha(brush); const float alpha= brush_alpha(scene, brush);
float brush_rgb[3]; float brush_rgb[3];
imbflag= (flt)? IB_rectfloat: IB_rect; imbflag= (flt)? IB_rectfloat: IB_rect;
@ -559,10 +559,10 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
dstf[3]= alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius); dstf[3]= alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius);
} }
else if (texfall == 1) { else if (texfall == 1) {
brush_sample_tex(brush, xy, dstf, 0); brush_sample_tex(scene, brush, xy, dstf, 0);
} }
else { else {
brush_sample_tex(brush, xy, rgba, 0); brush_sample_tex(scene, brush, xy, rgba, 0);
mul_v3_v3v3(dstf, rgba, brush_rgb); mul_v3_v3v3(dstf, rgba, brush_rgb);
dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius); dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, len_v2(xy), radius);
} }
@ -589,14 +589,14 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
dst[3] = FTOCHAR(alpha_f); dst[3] = FTOCHAR(alpha_f);
} }
else if (texfall == 1) { else if (texfall == 1) {
brush_sample_tex(brush, xy, rgba, 0); brush_sample_tex(scene, brush, xy, rgba, 0);
dst[0] = FTOCHAR(rgba[0]); dst[0] = FTOCHAR(rgba[0]);
dst[1] = FTOCHAR(rgba[1]); dst[1] = FTOCHAR(rgba[1]);
dst[2] = FTOCHAR(rgba[2]); dst[2] = FTOCHAR(rgba[2]);
dst[3] = FTOCHAR(rgba[3]); dst[3] = FTOCHAR(rgba[3]);
} }
else if (texfall == 2) { else if (texfall == 2) {
brush_sample_tex(brush, xy, rgba, 0); brush_sample_tex(scene, brush, xy, rgba, 0);
mul_v3_v3(rgba, brush->rgb); mul_v3_v3(rgba, brush->rgb);
alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius); alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius);
@ -606,7 +606,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
dst[3] = FTOCHAR(alpha_f); dst[3] = FTOCHAR(alpha_f);
} }
else { else {
brush_sample_tex(brush, xy, rgba, 0); brush_sample_tex(scene, brush, xy, rgba, 0);
alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius); alpha_f = rgba[3] * alpha * brush_curve_strength_clamp(brush, len_v2(xy), radius);
dst[0] = crgb[0]; dst[0] = crgb[0];
@ -621,6 +621,125 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
*outbuf= ibuf; *outbuf= ibuf;
} }
/* Unified Size and Strength */
// XXX: be careful about setting size and unprojected radius
// because they depend on one another
// these functions do not set the other corresponding value
// this can lead to odd behavior if size and unprojected
// radius become inconsistent.
// the biggest problem is that it isn't possible to change
// unprojected radius because a view context is not
// available. my ussual solution to this is to use the
// ratio of change of the size to change the unprojected
// radius. Not completely convinced that is correct.
// In anycase, a better solution is needed to prevent
// inconsistency.
void brush_set_size(Scene *scene, Brush *brush, int size)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
if (ups->flag & UNIFIED_PAINT_SIZE)
ups->size= size;
else
brush->size= size;
}
int brush_size(const Scene *scene, Brush *brush)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
}
int brush_use_locked_size(const Scene *scene, Brush *brush)
{
const short us_flag = scene->toolsettings->unified_paint_settings.flag;
return (us_flag & UNIFIED_PAINT_SIZE) ?
(us_flag & UNIFIED_PAINT_BRUSH_LOCK_SIZE) :
(brush->flag & BRUSH_LOCK_SIZE);
}
int brush_use_size_pressure(const Scene *scene, Brush *brush)
{
const short us_flag = scene->toolsettings->unified_paint_settings.flag;
return (us_flag & UNIFIED_PAINT_SIZE) ?
(us_flag & UNIFIED_PAINT_BRUSH_SIZE_PRESSURE) :
(brush->flag & BRUSH_SIZE_PRESSURE);
}
int brush_use_alpha_pressure(const Scene *scene, Brush *brush)
{
const short us_flag = scene->toolsettings->unified_paint_settings.flag;
return (us_flag & UNIFIED_PAINT_ALPHA) ?
(us_flag & UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE) :
(brush->flag & BRUSH_ALPHA_PRESSURE);
}
void brush_set_unprojected_radius(Scene *scene, Brush *brush, float unprojected_radius)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
if (ups->flag & UNIFIED_PAINT_SIZE)
ups->unprojected_radius= unprojected_radius;
else
brush->unprojected_radius= unprojected_radius;
}
float brush_unprojected_radius(const Scene *scene, Brush *brush)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
return (ups->flag & UNIFIED_PAINT_SIZE) ?
ups->unprojected_radius :
brush->unprojected_radius;
}
static void brush_set_alpha(Scene *scene, Brush *brush, float alpha)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
if (ups->flag & UNIFIED_PAINT_ALPHA)
ups->alpha= alpha;
else
brush->alpha= alpha;
}
float brush_alpha(const Scene *scene, Brush *brush)
{
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
return (ups->flag & UNIFIED_PAINT_ALPHA) ? ups->alpha : brush->alpha;
}
/* scale unprojected radius to reflect a change in the brush's 2D size */
void brush_scale_unprojected_radius(float *unprojected_radius,
int new_brush_size,
int old_brush_size)
{
float scale = new_brush_size;
/* avoid division by zero */
if(old_brush_size != 0)
scale /= (float)old_brush_size;
(*unprojected_radius) *= scale;
}
/* scale brush size to reflect a change in the brush's unprojected radius */
void brush_scale_size(int *brush_size,
float new_unprojected_radius,
float old_unprojected_radius)
{
float scale = new_unprojected_radius;
/* avoid division by zero */
if(old_unprojected_radius != 0)
scale /= new_unprojected_radius;
(*brush_size)= (int)((float)(*brush_size) * scale);
}
/* Brush Painting */ /* Brush Painting */
typedef struct BrushPainterCache { typedef struct BrushPainterCache {
@ -673,8 +792,8 @@ BrushPainter *brush_painter_new(Scene *scene, Brush *brush)
painter->firsttouch= 1; painter->firsttouch= 1;
painter->cache.lastsize= -1; /* force ibuf create in refresh */ painter->cache.lastsize= -1; /* force ibuf create in refresh */
painter->startsize = brush_size(brush); painter->startsize = brush_size(scene, brush);
painter->startalpha = brush_alpha(brush); painter->startalpha = brush_alpha(scene, brush);
painter->startjitter = brush->jitter; painter->startjitter = brush->jitter;
painter->startspacing = brush->spacing; painter->startspacing = brush->spacing;
@ -707,8 +826,8 @@ void brush_painter_free(BrushPainter *painter)
{ {
Brush *brush = painter->brush; Brush *brush = painter->brush;
brush_set_size(brush, painter->startsize); brush_set_size(painter->scene, brush, painter->startsize);
brush_set_alpha(brush, painter->startalpha); brush_set_alpha(painter->scene, brush, painter->startalpha);
brush->jitter = painter->startjitter; brush->jitter = painter->startjitter;
brush->spacing = painter->startspacing; brush->spacing = painter->startspacing;
@ -720,12 +839,13 @@ void brush_painter_free(BrushPainter *painter)
static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, int x, int y, int w, int h, int xt, int yt, float *pos) static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, int x, int y, int w, int h, int xt, int yt, float *pos)
{ {
Scene *scene= painter->scene;
Brush *brush= painter->brush; Brush *brush= painter->brush;
ImBuf *ibuf, *maskibuf, *texibuf; ImBuf *ibuf, *maskibuf, *texibuf;
float *bf, *mf, *tf, *otf=NULL, xoff, yoff, xy[2], rgba[4]; float *bf, *mf, *tf, *otf=NULL, xoff, yoff, xy[2], rgba[4];
char *b, *m, *t, *ot= NULL; char *b, *m, *t, *ot= NULL;
int dotexold, origx= x, origy= y; int dotexold, origx= x, origy= y;
const int radius= brush_size(brush); const int radius= brush_size(painter->scene, brush);
xoff = -radius + 0.5f; xoff = -radius + 0.5f;
yoff = -radius + 0.5f; yoff = -radius + 0.5f;
@ -763,7 +883,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i
xy[0] = x + xoff; xy[0] = x + xoff;
xy[1] = y + yoff; xy[1] = y + yoff;
brush_sample_tex(brush, xy, tf, 0); brush_sample_tex(scene, brush, xy, tf, 0);
} }
bf[0] = tf[0]*mf[0]; bf[0] = tf[0]*mf[0];
@ -794,7 +914,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i
xy[0] = x + xoff; xy[0] = x + xoff;
xy[1] = y + yoff; xy[1] = y + yoff;
brush_sample_tex(brush, xy, rgba, 0); brush_sample_tex(scene, brush, xy, rgba, 0);
t[0]= FTOCHAR(rgba[0]); t[0]= FTOCHAR(rgba[0]);
t[1]= FTOCHAR(rgba[1]); t[1]= FTOCHAR(rgba[1]);
t[2]= FTOCHAR(rgba[2]); t[2]= FTOCHAR(rgba[2]);
@ -812,11 +932,12 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf, i
static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos) static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float *pos)
{ {
const Scene *scene= painter->scene;
Brush *brush= painter->brush; Brush *brush= painter->brush;
BrushPainterCache *cache= &painter->cache; BrushPainterCache *cache= &painter->cache;
ImBuf *oldtexibuf, *ibuf; ImBuf *oldtexibuf, *ibuf;
int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2; int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
const int diameter= 2*brush_size(brush); const int diameter= 2*brush_size(scene, brush);
imbflag= (cache->flt)? IB_rectfloat: IB_rect; imbflag= (cache->flt)? IB_rectfloat: IB_rect;
if (!cache->ibuf) if (!cache->ibuf)
@ -866,13 +987,14 @@ static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float
static void brush_painter_refresh_cache(BrushPainter *painter, float *pos, int use_color_correction) static void brush_painter_refresh_cache(BrushPainter *painter, float *pos, int use_color_correction)
{ {
const Scene *scene= painter->scene;
Brush *brush= painter->brush; Brush *brush= painter->brush;
BrushPainterCache *cache= &painter->cache; BrushPainterCache *cache= &painter->cache;
MTex *mtex= &brush->mtex; MTex *mtex= &brush->mtex;
int size; int size;
short flt; short flt;
const int diameter= 2*brush_size(brush); const int diameter= 2*brush_size(scene, brush);
const float alpha= brush_alpha(brush); const float alpha= brush_alpha(scene, brush);
if (diameter != cache->lastsize || if (diameter != cache->lastsize ||
alpha != cache->lastalpha || alpha != cache->lastalpha ||
@ -891,11 +1013,11 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos, int u
size= (cache->size)? cache->size: diameter; size= (cache->size)? cache->size: diameter;
if (brush->flag & BRUSH_FIXED_TEX) { if (brush->flag & BRUSH_FIXED_TEX) {
brush_imbuf_new(brush, flt, 3, size, &cache->maskibuf, use_color_correction); brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
brush_painter_fixed_tex_partial_update(painter, pos); brush_painter_fixed_tex_partial_update(painter, pos);
} }
else else
brush_imbuf_new(brush, flt, 2, size, &cache->ibuf, use_color_correction); brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
cache->lastsize= diameter; cache->lastsize= diameter;
cache->lastalpha= alpha; cache->lastalpha= alpha;
@ -918,16 +1040,16 @@ void brush_painter_break_stroke(BrushPainter *painter)
static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pressure) static void brush_apply_pressure(BrushPainter *painter, Brush *brush, float pressure)
{ {
if (brush_use_alpha_pressure(painter->scene, brush)) if (brush_use_alpha_pressure(painter->scene, brush))
brush_set_alpha(brush, MAX2(0.0f, painter->startalpha*pressure)); brush_set_alpha(painter->scene, brush, MAX2(0.0f, painter->startalpha*pressure));
if (brush_use_size_pressure(painter->scene, brush)) if (brush_use_size_pressure(painter->scene, brush))
brush_set_size(brush, MAX2(1.0f, painter->startsize*pressure)); brush_set_size(painter->scene, brush, MAX2(1.0f, painter->startsize*pressure));
if (brush->flag & BRUSH_JITTER_PRESSURE) if (brush->flag & BRUSH_JITTER_PRESSURE)
brush->jitter = MAX2(0.0f, painter->startjitter*pressure); brush->jitter = MAX2(0.0f, painter->startjitter*pressure);
if (brush->flag & BRUSH_SPACING_PRESSURE) if (brush->flag & BRUSH_SPACING_PRESSURE)
brush->spacing = MAX2(1.0f, painter->startspacing*(1.5f-pressure)); brush->spacing = MAX2(1.0f, painter->startspacing*(1.5f-pressure));
} }
void brush_jitter_pos(Brush *brush, float pos[2], float jitterpos[2]) void brush_jitter_pos(const Scene *scene, Brush *brush, float pos[2], float jitterpos[2])
{ {
int use_jitter= brush->jitter != 0; int use_jitter= brush->jitter != 0;
@ -937,7 +1059,7 @@ void brush_jitter_pos(Brush *brush, float pos[2], float jitterpos[2])
if(use_jitter){ if(use_jitter){
float rand_pos[2]; float rand_pos[2];
const int radius= brush_size(brush); const int radius= brush_size(scene, brush);
const int diameter= 2*radius; const int diameter= 2*radius;
// find random position within a circle of diameter 1 // find random position within a circle of diameter 1
@ -956,6 +1078,7 @@ void brush_jitter_pos(Brush *brush, float pos[2], float jitterpos[2])
int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user, int use_color_correction) int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user, int use_color_correction)
{ {
Scene *scene= painter->scene;
Brush *brush= painter->brush; Brush *brush= painter->brush;
int totpaintops= 0; int totpaintops= 0;
@ -1017,7 +1140,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
else { else {
float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2]; float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
float t, len, press; float t, len, press;
const int radius= brush_size(brush); const int radius= brush_size(scene, brush);
/* compute brush spacing adapted to brush radius, spacing may depend /* compute brush spacing adapted to brush radius, spacing may depend
on pressure, so update it */ on pressure, so update it */
@ -1042,7 +1165,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
brush_apply_pressure(painter, brush, press); brush_apply_pressure(painter, brush, press);
spacing= MAX2(1.0f, radius)*brush->spacing*0.01f; spacing= MAX2(1.0f, radius)*brush->spacing*0.01f;
brush_jitter_pos(brush, paintpos, finalpos); brush_jitter_pos(scene, brush, paintpos, finalpos);
if (painter->cache.enabled) if (painter->cache.enabled)
brush_painter_refresh_cache(painter, finalpos, use_color_correction); brush_painter_refresh_cache(painter, finalpos, use_color_correction);
@ -1056,7 +1179,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
startdistance -= spacing; startdistance -= spacing;
} }
} else { } else {
brush_jitter_pos(brush, pos, finalpos); brush_jitter_pos(scene, brush, pos, finalpos);
if (painter->cache.enabled) if (painter->cache.enabled)
brush_painter_refresh_cache(painter, finalpos, use_color_correction); brush_painter_refresh_cache(painter, finalpos, use_color_correction);
@ -1084,7 +1207,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
while (painter->accumtime >= (double)brush->rate) { while (painter->accumtime >= (double)brush->rate) {
brush_apply_pressure(painter, brush, pressure); brush_apply_pressure(painter, brush, pressure);
brush_jitter_pos(brush, pos, finalpos); brush_jitter_pos(scene, brush, pos, finalpos);
if (painter->cache.enabled) if (painter->cache.enabled)
brush_painter_refresh_cache(painter, finalpos, use_color_correction); brush_painter_refresh_cache(painter, finalpos, use_color_correction);
@ -1102,8 +1225,8 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
painter->lastmousepos[1]= pos[1]; painter->lastmousepos[1]= pos[1];
painter->lastpressure= pressure; painter->lastpressure= pressure;
brush_set_alpha(brush, painter->startalpha); brush_set_alpha(scene, brush, painter->startalpha);
brush_set_size(brush, painter->startsize); brush_set_size(scene, brush, painter->startsize);
brush->jitter = painter->startjitter; brush->jitter = painter->startjitter;
brush->spacing = painter->startspacing; brush->spacing = painter->startspacing;
@ -1213,228 +1336,3 @@ struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
return im; return im;
} }
/* Unified Size and Strength */
/* XXX, wouldnt it be better to only pass the active scene?
* this can return any old scene! - campbell*/
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->unified_paint_settings.flag;
}
}
return 0;
}
// XXX: be careful about setting size and unprojected radius
// because they depend on one another
// these functions do not set the other corresponding value
// this can lead to odd behavior if size and unprojected
// radius become inconsistent.
// the biggest problem is that it isn't possible to change
// unprojected radius because a view context is not
// available. my ussual solution to this is to use the
// ratio of change of the size to change the unprojected
// radius. Not completely convinced that is correct.
// In anycase, a better solution is needed to prevent
// inconsistency.
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->unified_paint_settings.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->unified_paint_settings.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->unified_paint_settings.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->unified_paint_settings.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->unified_paint_settings.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->unified_paint_settings.unprojected_radius;
}
}
return 0.125f; // XXX magic number
}
void brush_set_size(Brush *brush, int size)
{
const short us_flag = unified_settings(brush);
if (us_flag & UNIFIED_PAINT_SIZE)
set_unified_size(brush, size);
else
brush->size= size;
//WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
}
int brush_size(Brush *brush)
{
const short us_flag = unified_settings(brush);
return (us_flag & UNIFIED_PAINT_SIZE) ? unified_size(brush) : brush->size;
}
int brush_use_locked_size(const Scene *scene, Brush *brush)
{
const short us_flag = scene->toolsettings->unified_paint_settings.flag;
return (us_flag & UNIFIED_PAINT_SIZE) ?
(us_flag & UNIFIED_PAINT_BRUSH_LOCK_SIZE) :
(brush->flag & BRUSH_LOCK_SIZE);
}
int brush_use_size_pressure(const Scene *scene, Brush *brush)
{
const short us_flag = scene->toolsettings->unified_paint_settings.flag;
return (us_flag & UNIFIED_PAINT_SIZE) ?
(us_flag & UNIFIED_PAINT_BRUSH_SIZE_PRESSURE) :
(brush->flag & BRUSH_SIZE_PRESSURE);
}
int brush_use_alpha_pressure(const Scene *scene, Brush *brush)
{
const short us_flag = scene->toolsettings->unified_paint_settings.flag;
return (us_flag & UNIFIED_PAINT_ALPHA) ?
(us_flag & UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE) :
(brush->flag & BRUSH_ALPHA_PRESSURE);
}
void brush_set_unprojected_radius(Brush *brush, float unprojected_radius)
{
const short us_flag = unified_settings(brush);
if (us_flag & UNIFIED_PAINT_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)
{
const short us_flag = unified_settings(brush);
return (us_flag & UNIFIED_PAINT_SIZE) ?
unified_unprojected_radius(brush) :
brush->unprojected_radius;
}
void brush_set_alpha(Brush *brush, float alpha)
{
const short us_flag = unified_settings(brush);
if (us_flag & UNIFIED_PAINT_ALPHA)
set_unified_alpha(brush, alpha);
else
brush->alpha= alpha;
//WM_main_add_notifier(NC_BRUSH|NA_EDITED, brush);
}
float brush_alpha(Brush *brush)
{
const short us_flag = unified_settings(brush);
return (us_flag & UNIFIED_PAINT_ALPHA) ?
unified_alpha(brush) :
brush->alpha;
}

@ -116,11 +116,11 @@ static void keymap_particle(wmKeyConfig *keyconf)
/* size radial control */ /* size radial control */
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.particle_edit.brush.size"); RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.particle_edit.brush.size");
/* size radial control */ /* size radial control */
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0); kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.particle_edit.brush.strength"); RNA_string_set(kmi->ptr, "data_path_primary", "tool_settings.particle_edit.brush.strength");
WM_keymap_add_menu(keymap, "VIEW3D_MT_particle_specials", WKEY, KM_PRESS, 0, 0); WM_keymap_add_menu(keymap, "VIEW3D_MT_particle_specials", WKEY, KM_PRESS, 0, 0);

@ -2937,7 +2937,7 @@ 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 */ 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); const int diameter= 2*brush_size(ps->scene, ps->brush);
/* ---- end defines ---- */ /* ---- end defines ---- */
@ -3580,7 +3580,7 @@ static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
{ {
if(ps->source==PROJ_SRC_VIEW) { if(ps->source==PROJ_SRC_VIEW) {
float min_brush[2], max_brush[2]; float min_brush[2], max_brush[2];
const float radius = (float)brush_size(ps->brush); const float radius = (float)brush_size(ps->scene, ps->brush);
/* so we dont have a bucket bounds that is way too small to paint into */ /* so we dont have a bucket bounds that is way too small to paint into */
// if (radius < 1.0f) radius = 1.0f; // this doesn't work yet :/ // if (radius < 1.0f) radius = 1.0f; // this doesn't work yet :/
@ -3618,7 +3618,7 @@ 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]) 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); const int diameter= 2*brush_size(ps->scene, ps->brush);
if (ps->thread_tot > 1) if (ps->thread_tot > 1)
BLI_lock_thread(LOCK_CUSTOM1); BLI_lock_thread(LOCK_CUSTOM1);
@ -3844,7 +3844,7 @@ static void *do_projectpaint_thread(void *ph_v)
float co[2]; float co[2];
float mask = 1.0f; /* airbrush wont use mask */ float mask = 1.0f; /* airbrush wont use mask */
unsigned short mask_short; unsigned short mask_short;
const float radius= (float)brush_size(ps->brush); const float radius= (float)brush_size(ps->scene, ps->brush);
const float radius_squared= radius*radius; /* avoid a square root with every dist comparison */ 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; short lock_alpha= ELEM(ps->brush->blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA) ? 0 : ps->brush->flag & BRUSH_LOCK_ALPHA;
@ -3903,7 +3903,7 @@ static void *do_projectpaint_thread(void *ph_v)
if (falloff > 0.0f) { if (falloff > 0.0f) {
if (ps->is_texbrush) { if (ps->is_texbrush) {
/* note, for clone and smear, we only use the alpha, could be a special function */ /* note, for clone and smear, we only use the alpha, could be a special function */
brush_sample_tex(ps->brush, projPixel->projCoSS, rgba, thread_index); brush_sample_tex(ps->scene, ps->brush, projPixel->projCoSS, rgba, thread_index);
alpha = rgba[3]; alpha = rgba[3];
} else { } else {
alpha = 1.0f; alpha = 1.0f;
@ -3911,7 +3911,7 @@ static void *do_projectpaint_thread(void *ph_v)
if (ps->is_airbrush) { if (ps->is_airbrush) {
/* for an aurbrush there is no real mask, so just multiply the alpha by it */ /* for an aurbrush there is no real mask, so just multiply the alpha by it */
alpha *= falloff * brush_alpha(ps->brush); alpha *= falloff * brush_alpha(ps->scene, ps->brush);
mask = ((float)projPixel->mask)/65535.0f; mask = ((float)projPixel->mask)/65535.0f;
} }
else { else {
@ -3919,7 +3919,7 @@ static void *do_projectpaint_thread(void *ph_v)
falloff = 1.0f - falloff; falloff = 1.0f - falloff;
falloff = 1.0f - (falloff * falloff); falloff = 1.0f - (falloff * falloff);
mask_short = (unsigned short)(projPixel->mask * (brush_alpha(ps->brush) * falloff)); mask_short = (unsigned short)(projPixel->mask * (brush_alpha(ps->scene, ps->brush) * falloff));
if (mask_short > projPixel->mask_max) { if (mask_short > projPixel->mask_max) {
mask = ((float)mask_short)/65535.0f; mask = ((float)mask_short)/65535.0f;
projPixel->mask_max = mask_short; projPixel->mask_max = mask_short;
@ -4801,7 +4801,7 @@ static int texture_paint_init(bContext *C, wmOperator *op)
if(pop->mode == PAINT_MODE_3D && (pop->s.tool == PAINT_TOOL_CLONE)) if(pop->mode == PAINT_MODE_3D && (pop->s.tool == PAINT_TOOL_CLONE))
pop->s.tool = PAINT_TOOL_DRAW; pop->s.tool = PAINT_TOOL_DRAW;
pop->s.blend = brush->blend; pop->s.blend = brush->blend;
pop->orig_brush_size= brush_size(brush); pop->orig_brush_size= brush_size(scene, brush);
if(pop->mode != PAINT_MODE_2D) { if(pop->mode != PAINT_MODE_2D) {
pop->s.ob = OBACT; pop->s.ob = OBACT;
@ -4837,8 +4837,8 @@ static int texture_paint_init(bContext *C, wmOperator *op)
return 0; return 0;
/* Dont allow brush size below 2 */ /* Dont allow brush size below 2 */
if (brush_size(brush) < 2) if (brush_size(scene, brush) < 2)
brush_set_size(brush, 2); brush_set_size(scene, brush, 2);
/* allocate and initialize spacial data structures */ /* allocate and initialize spacial data structures */
project_paint_begin(&pop->ps); project_paint_begin(&pop->ps);
@ -4922,7 +4922,7 @@ static void paint_exit(bContext *C, wmOperator *op)
brush_painter_free(pop->painter); brush_painter_free(pop->painter);
if(pop->mode == PAINT_MODE_3D_PROJECT) { if(pop->mode == PAINT_MODE_3D_PROJECT) {
brush_set_size(pop->ps.brush, pop->orig_brush_size); brush_set_size(scene, pop->ps.brush, pop->orig_brush_size);
paint_brush_exit_tex(pop->ps.brush); paint_brush_exit_tex(pop->ps.brush);
project_paint_end(&pop->ps); project_paint_end(&pop->ps);
@ -5111,12 +5111,13 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
#define PX_SIZE_FADE_MAX 12.0f #define PX_SIZE_FADE_MAX 12.0f
#define PX_SIZE_FADE_MIN 4.0f #define PX_SIZE_FADE_MIN 4.0f
Scene *scene= CTX_data_scene(C);
Brush *brush= image_paint_brush(C); Brush *brush= image_paint_brush(C);
Paint *paint= paint_get_active(CTX_data_scene(C)); Paint *paint= paint_get_active(scene);
if(paint && brush && paint->flags & PAINT_SHOW_BRUSH) { if(paint && brush && paint->flags & PAINT_SHOW_BRUSH) {
float zoomx, zoomy; float zoomx, zoomy;
const float size= (float)brush_size(brush); const float size= (float)brush_size(scene, brush);
const short use_zoom= get_imapaint_zoom(C, &zoomx, &zoomy); const short use_zoom= get_imapaint_zoom(C, &zoomx, &zoomy);
const float pixel_size= MAX2(size * zoomx, size * zoomy); const float pixel_size= MAX2(size * zoomx, size * zoomy);
float alpha= 0.5f; float alpha= 0.5f;
@ -5570,8 +5571,8 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
/* override */ /* override */
ps.is_texbrush= 0; ps.is_texbrush= 0;
ps.is_airbrush= 1; ps.is_airbrush= 1;
orig_brush_size= brush_size(ps.brush); orig_brush_size= brush_size(scene, ps.brush);
brush_set_size(ps.brush, 32); /* cover the whole image */ brush_set_size(scene, ps.brush, 32); /* cover the whole image */
ps.tool= PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */ ps.tool= PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */
@ -5584,7 +5585,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
project_paint_begin(&ps); project_paint_begin(&ps);
if(ps.dm==NULL) { if(ps.dm==NULL) {
brush_set_size(ps.brush, orig_brush_size); brush_set_size(scene, ps.brush, orig_brush_size);
return OPERATOR_CANCELLED; return OPERATOR_CANCELLED;
} }
else { else {
@ -5608,7 +5609,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
project_paint_end(&ps); project_paint_end(&ps);
scene->toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING; scene->toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
brush_set_size(ps.brush, orig_brush_size); brush_set_size(scene, ps.brush, orig_brush_size);
return OPERATOR_FINISHED; return OPERATOR_FINISHED;
} }

@ -89,7 +89,8 @@ static void BRUSH_OT_add(wmOperatorType *ot)
static int brush_scale_size_exec(bContext *C, wmOperator *op) static int brush_scale_size_exec(bContext *C, wmOperator *op)
{ {
Paint *paint= paint_get_active(CTX_data_scene(C)); Scene *scene = CTX_data_scene(C);
Paint *paint= paint_get_active(scene);
struct Brush *brush= paint_brush(paint); struct Brush *brush= paint_brush(paint);
// Object *ob= CTX_data_active_object(C); // Object *ob= CTX_data_active_object(C);
float scalar= RNA_float_get(op->ptr, "scalar"); float scalar= RNA_float_get(op->ptr, "scalar");
@ -97,7 +98,7 @@ static int brush_scale_size_exec(bContext *C, wmOperator *op)
if (brush) { if (brush) {
// pixel radius // pixel radius
{ {
const int old_size= brush_size(brush); const int old_size= brush_size(scene, brush);
int size= (int)(scalar*old_size); int size= (int)(scalar*old_size);
if (old_size == size) { if (old_size == size) {
@ -110,17 +111,17 @@ static int brush_scale_size_exec(bContext *C, wmOperator *op)
} }
CLAMP(size, 1, 2000); // XXX magic number CLAMP(size, 1, 2000); // XXX magic number
brush_set_size(brush, size); brush_set_size(scene, brush, size);
} }
// unprojected radius // unprojected radius
{ {
float unprojected_radius= scalar*brush_unprojected_radius(brush); float unprojected_radius= scalar*brush_unprojected_radius(scene, brush);
if (unprojected_radius < 0.001f) // XXX magic number if (unprojected_radius < 0.001f) // XXX magic number
unprojected_radius= 0.001f; unprojected_radius= 0.001f;
brush_set_unprojected_radius(brush, unprojected_radius); brush_set_unprojected_radius(scene, brush, unprojected_radius);
} }
} }
@ -475,7 +476,7 @@ typedef enum {
} RCFlags; } RCFlags;
static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path, static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path,
const char *output_name, const char *input_name) const char *output_name, const char *input_name)
{ {
char *path; char *path;
@ -485,21 +486,35 @@ static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path,
} }
static void set_brush_rc_props(PointerRNA *ptr, const char *paint, static void set_brush_rc_props(PointerRNA *ptr, const char *paint,
const char *prop, RCFlags flags) const char *prop, const char *secondary_prop,
RCFlags flags)
{ {
const char *ups_path = "tool_settings.unified_paint_settings";
char *brush_path; char *brush_path;
brush_path = BLI_sprintfN("tool_settings.%s.brush", paint); brush_path = BLI_sprintfN("tool_settings.%s.brush", paint);
set_brush_rc_path(ptr, brush_path, "data_path", prop); set_brush_rc_path(ptr, brush_path, "data_path_primary", prop);
if(secondary_prop) {
set_brush_rc_path(ptr, ups_path, "use_secondary", secondary_prop);
set_brush_rc_path(ptr, ups_path, "data_path_secondary", prop);
}
else {
RNA_string_set(ptr, "use_secondary", "");
RNA_string_set(ptr, "data_path_secondary", "");
}
set_brush_rc_path(ptr, brush_path, "color_path", "cursor_color_add"); set_brush_rc_path(ptr, brush_path, "color_path", "cursor_color_add");
set_brush_rc_path(ptr, brush_path, "rotation_path", "texture_slot.angle"); set_brush_rc_path(ptr, brush_path, "rotation_path", "texture_slot.angle");
RNA_string_set(ptr, "image_id", brush_path); RNA_string_set(ptr, "image_id", brush_path);
if(flags & RC_COLOR) if(flags & RC_COLOR)
set_brush_rc_path(ptr, brush_path, "fill_color_path", "color"); set_brush_rc_path(ptr, brush_path, "fill_color_path", "color");
else
RNA_string_set(ptr, "fill_color_path", "");
if(flags & RC_ZOOM) if(flags & RC_ZOOM)
RNA_string_set(ptr, "zoom_path", "space_data.zoom"); RNA_string_set(ptr, "zoom_path", "space_data.zoom");
else
RNA_string_set(ptr, "zoom_path", "");
MEM_freeN(brush_path); MEM_freeN(brush_path);
} }
@ -510,14 +525,14 @@ static void ed_keymap_paint_brush_radial_control(wmKeyMap *keymap, const char *p
wmKeyMapItem *kmi; wmKeyMapItem *kmi;
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0); kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, 0, 0);
set_brush_rc_props(kmi->ptr, paint, "size", flags); set_brush_rc_props(kmi->ptr, paint, "size", "use_unified_size", flags);
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0); kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0);
set_brush_rc_props(kmi->ptr, paint, "strength", flags); set_brush_rc_props(kmi->ptr, paint, "strength", "use_unified_strength", flags);
if(flags & RC_ROTATION) { if(flags & RC_ROTATION) {
kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0); kmi = WM_keymap_add_item(keymap, "WM_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0);
set_brush_rc_props(kmi->ptr, paint, "texture_slot.angle", flags); set_brush_rc_props(kmi->ptr, paint, "texture_slot.angle", NULL, flags);
} }
} }

@ -123,19 +123,19 @@ static int same_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
{ {
MTex* mtex = &brush->mtex; MTex* mtex = &brush->mtex;
return ( (mtex->tex) && return (((mtex->tex) &&
equals_v3v3(mtex->ofs, snap->ofs) && equals_v3v3(mtex->ofs, snap->ofs) &&
equals_v3v3(mtex->size, snap->size) && equals_v3v3(mtex->size, snap->size) &&
mtex->rot == snap->rot mtex->rot == snap->rot) &&
) &&
/* make brush smaller shouldn't cause a resample */ /* make brush smaller shouldn't cause a resample */
( (mtex->brush_map_mode == MTEX_MAP_MODE_FIXED && (brush_size(brush) <= snap->brush_size)) || ((mtex->brush_map_mode == MTEX_MAP_MODE_FIXED &&
(brush_size(brush) == snap->brush_size)) && (brush_size(vc->scene, brush) <= snap->brush_size)) ||
(brush_size(vc->scene, brush) == snap->brush_size)) &&
(mtex->brush_map_mode == snap->brush_map_mode) && (mtex->brush_map_mode == snap->brush_map_mode) &&
(vc->ar->winx == snap->winx) && (vc->ar->winx == snap->winx) &&
(vc->ar->winy == snap->winy); (vc->ar->winy == snap->winy));
} }
static void make_snap(Snapshot* snap, Brush* brush, ViewContext* vc) static void make_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
@ -153,7 +153,7 @@ static void make_snap(Snapshot* snap, Brush* brush, ViewContext* vc)
snap->rot = -1; snap->rot = -1;
} }
snap->brush_size = brush_size(brush); snap->brush_size = brush_size(vc->scene, brush);
snap->winx = vc->ar->winx; snap->winx = vc->ar->winx;
snap->winy = vc->ar->winy; snap->winy = vc->ar->winy;
} }
@ -198,7 +198,7 @@ static int load_tex(Sculpt *sd, Brush* br, ViewContext* vc)
make_snap(&snap, br, vc); make_snap(&snap, br, vc);
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) {
int s = brush_size(br); int s = brush_size(vc->scene, br);
int r = 1; int r = 1;
for (s >>= 1; s > 0; s >>= 1) for (s >>= 1; s > 0; s >>= 1)
@ -239,7 +239,7 @@ static int load_tex(Sculpt *sd, Brush* br, ViewContext* vc)
// largely duplicated from tex_strength // largely duplicated from tex_strength
const float rotation = -br->mtex.rot; const float rotation = -br->mtex.rot;
float radius = brush_size(br); float radius = brush_size(vc->scene, br);
int index = j*size + i; int index = j*size + i;
float x; float x;
float avg; float avg;
@ -373,6 +373,7 @@ static int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radiu
float location[3]) float location[3])
{ {
struct PaintStroke *stroke; struct PaintStroke *stroke;
const Scene *scene = CTX_data_scene(C);
float window[2]; float window[2];
int hit; int hit;
@ -384,11 +385,11 @@ static int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radiu
if(stroke->vc.obact->sculpt && stroke->vc.obact->sculpt->pbvh && if(stroke->vc.obact->sculpt && stroke->vc.obact->sculpt->pbvh &&
sculpt_stroke_get_location(C, stroke, location, window)) { sculpt_stroke_get_location(C, stroke, location, window)) {
*pixel_radius = project_brush_radius(stroke->vc.rv3d, *pixel_radius = project_brush_radius(stroke->vc.rv3d,
brush_unprojected_radius(stroke->brush), brush_unprojected_radius(scene, stroke->brush),
location, &stroke->mats); location, &stroke->mats);
if (*pixel_radius == 0) if (*pixel_radius == 0)
*pixel_radius = brush_size(stroke->brush); *pixel_radius = brush_size(scene, stroke->brush);
mul_m4_v3(stroke->vc.obact->obmat, location); mul_m4_v3(stroke->vc.obact->obmat, location);
@ -398,7 +399,7 @@ static int sculpt_get_brush_geometry(bContext* C, int x, int y, int* pixel_radiu
Sculpt* sd = CTX_data_tool_settings(C)->sculpt; Sculpt* sd = CTX_data_tool_settings(C)->sculpt;
Brush* brush = paint_brush(&sd->paint); Brush* brush = paint_brush(&sd->paint);
*pixel_radius = brush_size(brush); *pixel_radius = brush_size(scene, brush);
hit = 0; hit = 0;
} }
@ -468,7 +469,7 @@ static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush,
quad.ymax = aim[1]+sd->anchored_size - win->ymin; quad.ymax = aim[1]+sd->anchored_size - win->ymin;
} }
else { else {
const int radius= brush_size(brush); const int radius= brush_size(vc->scene, brush);
quad.xmin = x - radius; quad.xmin = x - radius;
quad.ymin = y - radius; quad.ymin = y - radius;
quad.xmax = x + radius; quad.xmax = x + radius;
@ -524,7 +525,7 @@ static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc,
if(brush->flag & BRUSH_ANCHORED) if(brush->flag & BRUSH_ANCHORED)
projected_radius = 8; projected_radius = 8;
else else
projected_radius = brush_size(brush); projected_radius = brush_size(vc->scene, brush);
} }
unprojected_radius = paint_calc_object_space_radius(vc, location, unprojected_radius = paint_calc_object_space_radius(vc, location,
projected_radius); projected_radius);
@ -533,7 +534,7 @@ static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc,
unprojected_radius *= sd->pressure_value; unprojected_radius *= sd->pressure_value;
if(!brush_use_locked_size(vc->scene, brush)) if(!brush_use_locked_size(vc->scene, brush))
brush_set_unprojected_radius(brush, unprojected_radius); brush_set_unprojected_radius(vc->scene, brush, unprojected_radius);
} }
static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
@ -551,7 +552,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
translation[1] = y; translation[1] = y;
outline_alpha = 0.5; outline_alpha = 0.5;
outline_col = brush->add_col; outline_col = brush->add_col;
final_radius = brush_size(brush); final_radius = brush_size(scene, brush);
/* check that brush drawing is enabled */ /* check that brush drawing is enabled */
if(!(paint->flags & PAINT_SHOW_BRUSH)) if(!(paint->flags & PAINT_SHOW_BRUSH))
@ -567,7 +568,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
float location[3]; float location[3];
int pixel_radius, hit; int pixel_radius, hit;
const float root_alpha = brush_alpha(brush); const float root_alpha = brush_alpha(scene, brush);
float visual_strength = root_alpha*root_alpha; float visual_strength = root_alpha*root_alpha;
const float min_alpha = 0.20f; const float min_alpha = 0.20f;
const float max_alpha = 0.80f; const float max_alpha = 0.80f;
@ -599,7 +600,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
paint_draw_alpha_overlay(sd, brush, &vc, x, y); paint_draw_alpha_overlay(sd, brush, &vc, x, y);
if(brush_use_locked_size(scene, brush)) if(brush_use_locked_size(scene, brush))
brush_set_size(brush, pixel_radius); brush_set_size(scene, brush, pixel_radius);
/* check if brush is subtracting, use different color then */ /* check if brush is subtracting, use different color then */
/* TODO: no way currently to know state of pen flip or /* TODO: no way currently to know state of pen flip or
@ -669,7 +670,8 @@ static float event_tablet_data(wmEvent *event, int *pen_flip)
/* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */ /* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */
static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2]) static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2])
{ {
Paint *paint = paint_get_active(CTX_data_scene(C)); Scene *scene = CTX_data_scene(C);
Paint *paint = paint_get_active(scene);
Brush *brush = paint_brush(paint); Brush *brush = paint_brush(paint);
PaintStroke *stroke = op->customdata; PaintStroke *stroke = op->customdata;
float mouse[3]; float mouse[3];
@ -686,7 +688,7 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
if(stroke->vc.obact->sculpt) { if(stroke->vc.obact->sculpt) {
float delta[2]; float delta[2];
brush_jitter_pos(brush, mouse_in, mouse); brush_jitter_pos(scene, brush, mouse_in, mouse);
/* XXX: meh, this is round about because /* XXX: meh, this is round about because
brush_jitter_pos isn't written in the best way to brush_jitter_pos isn't written in the best way to
@ -775,7 +777,7 @@ static int paint_space_stroke(bContext *C, wmOperator *op, wmEvent *event, const
pressure = event_tablet_data(event, NULL); pressure = event_tablet_data(event, NULL);
if(pressure > FLT_EPSILON) { if(pressure > FLT_EPSILON) {
scale = (brush_size(stroke->brush)*pressure*stroke->brush->spacing/50.0f) / length; scale = (brush_size(scene, stroke->brush)*pressure*stroke->brush->spacing/50.0f) / length;
if(scale > FLT_EPSILON) { if(scale > FLT_EPSILON) {
mul_v2_fl(vec, scale); mul_v2_fl(vec, scale);

@ -654,7 +654,7 @@ static unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fac)
return col; return col;
} }
static void vpaint_blend(VPaint *vp, unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha) static void vpaint_blend(Scene *scene, VPaint *vp, unsigned int *col, unsigned int *colorig, unsigned int paintcol, int alpha)
{ {
Brush *brush = paint_brush(&vp->paint); Brush *brush = paint_brush(&vp->paint);
@ -670,7 +670,7 @@ static void vpaint_blend(VPaint *vp, unsigned int *col, unsigned int *colorig, u
unsigned int testcol=0, a; unsigned int testcol=0, a;
char *cp, *ct, *co; char *cp, *ct, *co;
alpha= (int)(255.0f*brush_alpha(brush)); alpha= (int)(255.0f*brush_alpha(scene, brush));
if(brush->vertexpaint_tool==VP_MIX || brush->vertexpaint_tool==VP_BLUR) testcol= mcol_blend( *colorig, paintcol, alpha); 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); else if(brush->vertexpaint_tool==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha);
@ -787,7 +787,7 @@ static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc,
return 0.0f; return 0.0f;
} }
static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *dw_prev, float alpha, float paintval, int flip, int multipaint) static void wpaint_blend(Scene *scene, VPaint *wp, MDeformWeight *dw, MDeformWeight *dw_prev, float alpha, float paintval, int flip, int multipaint)
{ {
Brush *brush = paint_brush(&wp->paint); Brush *brush = paint_brush(&wp->paint);
int tool = brush->vertexpaint_tool; int tool = brush->vertexpaint_tool;
@ -832,7 +832,7 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *dw_prev,
if((wp->flag & VP_SPRAY)==0) { if((wp->flag & VP_SPRAY)==0) {
float testw=0.0f; float testw=0.0f;
alpha= brush_alpha(brush); alpha= brush_alpha(scene, brush);
if(tool==VP_MIX || tool==VP_BLUR) if(tool==VP_MIX || tool==VP_BLUR)
testw = paintval*alpha + dw_prev->weight*(1.0f-alpha); testw = paintval*alpha + dw_prev->weight*(1.0f-alpha);
else if(tool==VP_ADD) else if(tool==VP_ADD)
@ -1596,7 +1596,8 @@ static char *wpaint_make_validmap(Object *ob);
static void do_weight_paint_vertex( /* vars which remain the same for every vert */ static void do_weight_paint_vertex( /* vars which remain the same for every vert */
VPaint *wp, Object *ob, const WeightPaintInfo *wpi, Scene *scene, VPaint *wp, Object *ob,
const WeightPaintInfo *wpi,
/* vars which change on each stroke */ /* vars which change on each stroke */
const unsigned int index, float alpha, float paintweight const unsigned int index, float alpha, float paintweight
) )
@ -1685,7 +1686,7 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert
if ( (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) && if ( (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) &&
(wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags) == FALSE)) (wpi->lock_flags == NULL || has_locked_group(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags) == FALSE))
{ {
wpaint_blend(wp, dw, dw_prev, alpha, paintweight, wpi->do_flip, FALSE); wpaint_blend(scene, wp, dw, dw_prev, alpha, paintweight, wpi->do_flip, FALSE);
/* WATCH IT: take care of the ordering of applying mirror -> normalize, /* WATCH IT: take care of the ordering of applying mirror -> normalize,
* can give wrong results [#26193], least confusing if normalize is done last */ * can give wrong results [#26193], least confusing if normalize is done last */
@ -1750,7 +1751,7 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert
MDeformVert dv_copy= {NULL}; MDeformVert dv_copy= {NULL};
oldw = dw->weight; oldw = dw->weight;
wpaint_blend(wp, dw, dw_prev, alpha, paintweight, wpi->do_flip, wpi->do_multipaint && wpi->defbase_tot_sel >1); wpaint_blend(scene, wp, dw, dw_prev, alpha, paintweight, wpi->do_flip, wpi->do_multipaint && wpi->defbase_tot_sel >1);
neww = dw->weight; neww = dw->weight;
dw->weight = oldw; dw->weight = oldw;
@ -2091,7 +2092,7 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr) static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
{ {
const Scene *scene= CTX_data_scene(C); Scene *scene= CTX_data_scene(C);
ToolSettings *ts= CTX_data_tool_settings(C); ToolSettings *ts= CTX_data_tool_settings(C);
VPaint *wp= ts->wpaint; VPaint *wp= ts->wpaint;
Brush *brush = paint_brush(&wp->paint); Brush *brush = paint_brush(&wp->paint);
@ -2110,8 +2111,8 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
char *defbase_sel; char *defbase_sel;
const float pressure = RNA_float_get(itemptr, "pressure"); const float pressure = RNA_float_get(itemptr, "pressure");
const float brush_size_final = brush_size(brush) * (brush_use_size_pressure(scene, brush) ? pressure : 1.0f); const float brush_size_final = brush_size(scene, brush) * (brush_use_size_pressure(scene, brush) ? pressure : 1.0f);
const float brush_alpha_final = brush_alpha(brush) * (brush_use_alpha_pressure(scene, brush) ? pressure : 1.0f); const float brush_alpha_final = brush_alpha(scene, brush) * (brush_use_alpha_pressure(scene, brush) ? pressure : 1.0f);
/* intentionally dont initialize as NULL, make sure we initialize all members below */ /* intentionally dont initialize as NULL, make sure we initialize all members below */
WeightPaintInfo wpi; WeightPaintInfo wpi;
@ -2265,7 +2266,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*vidx, alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*vidx,
mval, brush_size_final, brush_alpha_final); mval, brush_size_final, brush_alpha_final);
if(alpha) { if(alpha) {
do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); do_weight_paint_vertex(scene, wp, ob, &wpi, vidx, alpha, paintweight);
} }
me->dvert[vidx].flag= 0; me->dvert[vidx].flag= 0;
} }
@ -2556,7 +2557,7 @@ static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob,
alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*(&mface->v1)[i], alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat, vpd->vertexcosnos+6*(&mface->v1)[i],
mval, brush_size_final, brush_alpha_final); mval, brush_size_final, brush_alpha_final);
if(alpha) { if(alpha) {
vpaint_blend(vp, mcol+i, mcolorig+i, vpd->paintcol, (int)(alpha*255.0f)); vpaint_blend(vc->scene, vp, mcol+i, mcolorig+i, vpd->paintcol, (int)(alpha*255.0f));
} }
} }
} }
@ -2577,8 +2578,8 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
float mval[2]; float mval[2];
const float pressure = RNA_float_get(itemptr, "pressure"); const float pressure = RNA_float_get(itemptr, "pressure");
const float brush_size_final = brush_size(brush) * (brush_use_size_pressure(scene, brush) ? pressure : 1.0f); const float brush_size_final = brush_size(scene, brush) * (brush_use_size_pressure(scene, brush) ? pressure : 1.0f);
const float brush_alpha_final = brush_alpha(brush) * (brush_use_alpha_pressure(scene, brush) ? pressure : 1.0f); const float brush_alpha_final = brush_alpha(scene, brush) * (brush_use_alpha_pressure(scene, brush) ? pressure : 1.0f);
RNA_float_get_array(itemptr, "mouse", mval); RNA_float_get_array(itemptr, "mouse", mval);
flip = RNA_boolean_get(itemptr, "pen_flip"); flip = RNA_boolean_get(itemptr, "pen_flip");

@ -543,13 +543,14 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache* cache)
special multiplier found experimentally to scale the strength factor. */ special multiplier found experimentally to scale the strength factor. */
static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather) static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather)
{ {
const Scene *scene = cache->vc->scene;
Brush *brush = paint_brush(&sd->paint); Brush *brush = paint_brush(&sd->paint);
/* Primary strength input; square it to make lower values more sensitive */ /* Primary strength input; square it to make lower values more sensitive */
const float root_alpha = brush_alpha(brush); const float root_alpha = brush_alpha(scene, brush);
float alpha = root_alpha*root_alpha; float alpha = root_alpha*root_alpha;
float dir = brush->flag & BRUSH_DIR_IN ? -1 : 1; float dir = brush->flag & BRUSH_DIR_IN ? -1 : 1;
float pressure = brush_use_alpha_pressure(cache->vc->scene, brush) ? cache->pressure : 1; float pressure = brush_use_alpha_pressure(scene, brush) ? cache->pressure : 1;
float pen_flip = cache->pen_flip ? -1 : 1; float pen_flip = cache->pen_flip ? -1 : 1;
float invert = cache->invert ? -1 : 1; float invert = cache->invert ? -1 : 1;
float accum = integrate_overlap(brush); float accum = integrate_overlap(brush);
@ -679,7 +680,7 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3],
else /* else (mtex->brush_map_mode == MTEX_MAP_MODE_TILED), else /* else (mtex->brush_map_mode == MTEX_MAP_MODE_TILED),
leave the coordinates relative to the screen */ leave the coordinates relative to the screen */
{ {
radius = brush_size(br); // use unadjusted size for tiled mode radius = brush_size(ss->cache->vc->scene, br); // use unadjusted size for tiled mode
x = point_2d[0]; x = point_2d[0];
y = point_2d[1]; y = point_2d[1];
@ -1167,6 +1168,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{ {
SculptSession *ss = ob->sculpt; SculptSession *ss = ob->sculpt;
const Scene *scene = ss->cache->vc->scene;
Brush *brush = paint_brush(&sd->paint); Brush *brush = paint_brush(&sd->paint);
float offset[3], area_normal[3]; float offset[3], area_normal[3];
float bstrength= ss->cache->bstrength; float bstrength= ss->cache->bstrength;
@ -1182,8 +1184,8 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
/* we divide out the squared alpha and multiply by the squared crease to give us the pinch strength */ /* we divide out the squared alpha and multiply by the squared crease to give us the pinch strength */
if(brush_alpha(brush) > 0.0f) if(brush_alpha(scene, brush) > 0.0f)
crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor/(brush_alpha(brush)*brush_alpha(brush)); crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor/(brush_alpha(scene, brush)*brush_alpha(scene, brush));
else else
crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor; crease_correction = brush->crease_pinch_factor*brush->crease_pinch_factor;
@ -2658,10 +2660,10 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob)
cache->first_time= 0; cache->first_time= 0;
} }
static void sculpt_update_tex(Sculpt *sd, SculptSession *ss) static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
{ {
Brush *brush = paint_brush(&sd->paint); Brush *brush = paint_brush(&sd->paint);
const int radius= brush_size(brush); const int radius= brush_size(scene, brush);
if(ss->texcache) { if(ss->texcache) {
MEM_freeN(ss->texcache); MEM_freeN(ss->texcache);
@ -3017,7 +3019,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
struct PaintStroke *stroke, struct PaintStroke *stroke,
PointerRNA *ptr) PointerRNA *ptr)
{ {
const Scene *scene = CTX_data_scene(C); Scene *scene = CTX_data_scene(C);
SculptSession *ss = ob->sculpt; SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache; StrokeCache *cache = ss->cache;
Brush *brush = paint_brush(&sd->paint); Brush *brush = paint_brush(&sd->paint);
@ -3052,15 +3054,15 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
sd->pressure_value= cache->pressure; sd->pressure_value= cache->pressure;
cache->previous_pixel_radius = cache->pixel_radius; cache->previous_pixel_radius = cache->pixel_radius;
cache->pixel_radius = brush_size(brush); cache->pixel_radius = brush_size(scene, brush);
if(cache->first_time) { if(cache->first_time) {
if (!brush_use_locked_size(scene, brush)) { if (!brush_use_locked_size(scene, brush)) {
cache->initial_radius= paint_calc_object_space_radius(cache->vc, cache->true_location, brush_size(brush)); cache->initial_radius= paint_calc_object_space_radius(cache->vc, cache->true_location, brush_size(scene, brush));
brush_set_unprojected_radius(brush, cache->initial_radius); brush_set_unprojected_radius(scene, brush, cache->initial_radius);
} }
else { else {
cache->initial_radius= brush_unprojected_radius(brush); cache->initial_radius= brush_unprojected_radius(scene, brush);
} }
} }
@ -3246,7 +3248,7 @@ int sculpt_stroke_get_location(bContext *C, struct PaintStroke *stroke, float ou
return srd.hit; return srd.hit;
} }
static void sculpt_brush_init_tex(Sculpt *sd, SculptSession *ss) static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
{ {
Brush *brush = paint_brush(&sd->paint); Brush *brush = paint_brush(&sd->paint);
MTex *mtex= &brush->mtex; MTex *mtex= &brush->mtex;
@ -3258,7 +3260,7 @@ static void sculpt_brush_init_tex(Sculpt *sd, SculptSession *ss)
/* TODO: Shouldn't really have to do this at the start of every /* TODO: Shouldn't really have to do this at the start of every
stroke, but sculpt would need some sort of notification when stroke, but sculpt would need some sort of notification when
changes are made to the texture. */ changes are made to the texture. */
sculpt_update_tex(sd, ss); sculpt_update_tex(scene, sd, ss);
} }
static int sculpt_brush_stroke_init(bContext *C, wmOperator *op) static int sculpt_brush_stroke_init(bContext *C, wmOperator *op)
@ -3272,7 +3274,7 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op)
int is_smooth= 0; int is_smooth= 0;
view3d_operator_needs_opengl(C); view3d_operator_needs_opengl(C);
sculpt_brush_init_tex(sd, ss); sculpt_brush_init_tex(scene, sd, ss);
is_smooth|= mode == BRUSH_STROKE_SMOOTH; is_smooth|= mode == BRUSH_STROKE_SMOOTH;
is_smooth|= brush->sculpt_tool == SCULPT_TOOL_SMOOTH; is_smooth|= brush->sculpt_tool == SCULPT_TOOL_SMOOTH;

@ -164,60 +164,21 @@ static void rna_Brush_icon_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Poi
static void rna_Brush_set_size(PointerRNA *ptr, int value) static void rna_Brush_set_size(PointerRNA *ptr, int value)
{ {
Brush* me = (Brush*)(ptr->data); Brush* brush = ptr->data;
float size= (float)brush_size(me); /* scale unprojected radius so it stays consistent with brush size */
float unprojected_radius; brush_scale_unprojected_radius(&brush->unprojected_radius,
value, brush->size);
// paranoia: previous checks should make sure we don't divide by zero brush->size= value;
assert(size != 0);
// set unprojected radius, so it remains consistent with size
unprojected_radius= (float)(brush_unprojected_radius(me) * value / size);
brush_set_unprojected_radius(me, unprojected_radius);
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_unprojected_radius(PointerRNA *ptr, float value) static void rna_Brush_set_unprojected_radius(PointerRNA *ptr, float value)
{ {
Brush* me = (Brush*)(ptr->data); Brush* brush = ptr->data;
float unprojected_radius= brush_unprojected_radius(me); /* scale brush size so it stays consistent with unprojected_radius */
int size; brush_scale_size(&brush->size, value, brush->unprojected_radius);
brush->unprojected_radius= value;
// paranoia: previous checks should make sure we don't divide by zero
assert(unprojected_radius != 0.0f);
// set size, so that it is consistent with unprojected_radius
size= (int)((float)brush_size(me) * value / unprojected_radius);
brush_set_size(me, size);
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);
} }
static EnumPropertyItem *rna_Brush_direction_itemf(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *UNUSED(free)) static EnumPropertyItem *rna_Brush_direction_itemf(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *UNUSED(free))
@ -412,14 +373,14 @@ static void rna_def_brush(BlenderRNA *brna)
/* number values */ /* number values */
prop= RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE); 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_int_funcs(prop, NULL, "rna_Brush_set_size", NULL);
RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS*10); 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_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, 0);
RNA_def_property_ui_text(prop, "Radius", "Radius of the brush in pixels"); RNA_def_property_ui_text(prop, "Radius", "Radius of the brush in pixels");
RNA_def_property_update(prop, 0, "rna_Brush_update"); RNA_def_property_update(prop, 0, "rna_Brush_update");
prop= RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_DISTANCE); prop= RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_funcs(prop, "rna_Brush_get_unprojected_radius", "rna_Brush_set_unprojected_radius", NULL); RNA_def_property_float_funcs(prop, NULL, "rna_Brush_set_unprojected_radius", NULL);
RNA_def_property_range(prop, 0.001, FLT_MAX); RNA_def_property_range(prop, 0.001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001, 1, 0, 0); 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_ui_text(prop, "Unprojected Radius", "Radius of brush in Blender units");
@ -463,7 +424,6 @@ static void rna_def_brush(BlenderRNA *brna)
prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR); prop= RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "alpha"); 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_float_default(prop, 0.5f);
RNA_def_property_range(prop, 0.0f, 10.0f); 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_range(prop, 0.0f, 1.0f, 0.001, 0.001);

@ -244,6 +244,7 @@ EnumPropertyItem image_color_depth_items[] = {
#include "BLI_threads.h" #include "BLI_threads.h"
#include "BLI_editVert.h" #include "BLI_editVert.h"
#include "BKE_brush.h"
#include "BKE_context.h" #include "BKE_context.h"
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_image.h" #include "BKE_image.h"
@ -1288,6 +1289,25 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons
} }
} }
static void rna_UnifiedPaintSettings_size_set(PointerRNA *ptr, int value)
{
UnifiedPaintSettings* ups = ptr->data;
/* scale unprojected radius so it stays consistent with brush size */
brush_scale_unprojected_radius(&ups->unprojected_radius,
value, ups->size);
ups->size= value;
}
static void rna_UnifiedPaintSettings_unprojected_radius_set(PointerRNA *ptr, float value)
{
UnifiedPaintSettings* ups = ptr->data;
/* scale brush size so it stays consistent with unprojected_radius */
brush_scale_size(&ups->size, value, ups->unprojected_radius);
ups->unprojected_radius= value;
}
/* note: without this, when Multi-Paint is activated/deactivated, the colors /* note: without this, when Multi-Paint is activated/deactivated, the colors
* will not change right away when multiple bones are selected, this function * will not change right away when multiple bones are selected, this function
* is not for general use and only for the few cases where changing scene * is not for general use and only for the few cases where changing scene
@ -1654,11 +1674,13 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
/* unified paint settings that override the equivalent settings /* unified paint settings that override the equivalent settings
from the active brush */ from the active brush */
prop= RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE); prop= RNA_def_property(srna, "size", PROP_INT, PROP_DISTANCE);
RNA_def_property_int_funcs(prop, NULL, "rna_UnifiedPaintSettings_size_set", NULL);
RNA_def_property_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS*10); 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_range(prop, 1, MAX_BRUSH_PIXEL_RADIUS, 1, 0);
RNA_def_property_ui_text(prop, "Radius", "Radius of the brush in pixels"); RNA_def_property_ui_text(prop, "Radius", "Radius of the brush in pixels");
prop= RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_DISTANCE); prop= RNA_def_property(srna, "unprojected_radius", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_funcs(prop, NULL, "rna_UnifiedPaintSettings_unprojected_radius_set", NULL);
RNA_def_property_range(prop, 0.001, FLT_MAX); RNA_def_property_range(prop, 0.001, FLT_MAX);
RNA_def_property_ui_range(prop, 0.001, 1, 0, 0); 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_ui_text(prop, "Unprojected Radius", "Radius of brush in Blender units");

@ -3083,23 +3083,35 @@ static void radial_control_paint_cursor(bContext *C, int x, int y, void *customd
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);
} }
typedef enum {
RC_PROP_ALLOW_MISSING = 1,
RC_PROP_REQUIRE_FLOAT = 2,
RC_PROP_REQUIRE_BOOL = 4,
} RCPropFlags;
/* attempt to retrieve the rna pointer/property from an rna path; /* attempt to retrieve the rna pointer/property from an rna path;
returns 0 for failure, 1 for success, and also 1 if property is not returns 0 for failure, 1 for success, and also 1 if property is not
set */ set */
static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op,
const char *name, PointerRNA *r_ptr, const char *name, PointerRNA *r_ptr,
PropertyRNA **r_prop, int req_float, PropertyRNA **r_prop, int req_length, RCPropFlags flags)
int req_length, int allow_missing)
{ {
PropertyRNA *unused_prop; PropertyRNA *unused_prop;
int len; int len;
char *str; char *str;
/* check flags */
if((flags & RC_PROP_REQUIRE_BOOL) && (flags & RC_PROP_REQUIRE_FLOAT)) {
BKE_reportf(op->reports, RPT_ERROR, "Property can't be both boolean and float");
return 0;
}
/* get an rna string path from the operator's properties */ /* get an rna string path from the operator's properties */
if(!(str = RNA_string_get_alloc(op->ptr, name, NULL, 0))) if(!(str = RNA_string_get_alloc(op->ptr, name, NULL, 0)))
return 1; return 1;
if(str[0] == '\0') { if(str[0] == '\0') {
if(r_prop) *r_prop = NULL;
MEM_freeN(str); MEM_freeN(str);
return 1; return 1;
} }
@ -3110,7 +3122,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op,
/* get rna from path */ /* get rna from path */
if(!RNA_path_resolve(ctx_ptr, str, r_ptr, r_prop)) { if(!RNA_path_resolve(ctx_ptr, str, r_ptr, r_prop)) {
MEM_freeN(str); MEM_freeN(str);
if(allow_missing) if(flags & RC_PROP_ALLOW_MISSING)
return 1; return 1;
else { else {
BKE_reportf(op->reports, RPT_ERROR, "Couldn't resolve path %s", name); BKE_reportf(op->reports, RPT_ERROR, "Couldn't resolve path %s", name);
@ -3118,9 +3130,12 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op,
} }
} }
/* if property is expected to be a float, check its type */ /* check property type */
if(req_float) { if(flags & (RC_PROP_REQUIRE_BOOL | RC_PROP_REQUIRE_FLOAT)) {
if(!(*r_prop) || (RNA_property_type(*r_prop) != PROP_FLOAT)) { PropertyType prop_type = RNA_property_type(*r_prop);
if(((flags & RC_PROP_REQUIRE_BOOL) && (prop_type != PROP_BOOLEAN)) ||
((flags & RC_PROP_REQUIRE_FLOAT) && prop_type != PROP_FLOAT)) {
MEM_freeN(str); MEM_freeN(str);
BKE_reportf(op->reports, RPT_ERROR, BKE_reportf(op->reports, RPT_ERROR,
"Property from path %s is not a float", name); "Property from path %s is not a float", name);
@ -3146,31 +3161,50 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op,
static int radial_control_get_properties(bContext *C, wmOperator *op) static int radial_control_get_properties(bContext *C, wmOperator *op)
{ {
RadialControl *rc = op->customdata; RadialControl *rc = op->customdata;
PointerRNA ctx_ptr; PointerRNA ctx_ptr, use_secondary_ptr;
PropertyRNA *use_secondary_prop;
const char *data_path;
RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr); RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr);
if(!radial_control_get_path(&ctx_ptr, op, "data_path", &rc->ptr, &rc->prop, 0, 0, 0)) /* check if we use primary or secondary path */
if(!radial_control_get_path(&ctx_ptr, op, "use_secondary",
&use_secondary_ptr, &use_secondary_prop,
0, (RC_PROP_ALLOW_MISSING|
RC_PROP_REQUIRE_BOOL))) {
return 0;
}
else {
if(use_secondary_prop &&
RNA_property_boolean_get(&use_secondary_ptr, use_secondary_prop))
data_path = "data_path_secondary";
else
data_path = "data_path_primary";
}
if(!radial_control_get_path(&ctx_ptr, op, data_path, &rc->ptr, &rc->prop, 0, 0))
return 0; return 0;
/* data path is required */ /* data path is required */
if(!rc->prop) if(!rc->prop)
return 0; return 0;
if(!radial_control_get_path(&ctx_ptr, op, "rotation_path", &rc->rot_ptr, &rc->rot_prop, 1, 0, 0)) if(!radial_control_get_path(&ctx_ptr, op, "rotation_path", &rc->rot_ptr, &rc->rot_prop, 0, RC_PROP_REQUIRE_FLOAT))
return 0; return 0;
if(!radial_control_get_path(&ctx_ptr, op, "color_path", &rc->col_ptr, &rc->col_prop, 1, 3, 0)) if(!radial_control_get_path(&ctx_ptr, op, "color_path", &rc->col_ptr, &rc->col_prop, 3, RC_PROP_REQUIRE_FLOAT))
return 0; return 0;
if(!radial_control_get_path(&ctx_ptr, op, "fill_color_path", &rc->fill_col_ptr, &rc->fill_col_prop, 1, 3, 0)) if(!radial_control_get_path(&ctx_ptr, op, "fill_color_path", &rc->fill_col_ptr, &rc->fill_col_prop, 3, RC_PROP_REQUIRE_FLOAT))
return 0; return 0;
/* slightly ugly; allow this property to not resolve /* slightly ugly; allow this property to not resolve
correctly. needed because 3d texture paint shares the same correctly. needed because 3d texture paint shares the same
keymap as 2d image paint */ keymap as 2d image paint */
if(!radial_control_get_path(&ctx_ptr, op, "zoom_path", &rc->zoom_ptr, &rc->zoom_prop, 1, 2, 1)) if(!radial_control_get_path(&ctx_ptr, op, "zoom_path",
&rc->zoom_ptr, &rc->zoom_prop, 2,
RC_PROP_REQUIRE_FLOAT|RC_PROP_ALLOW_MISSING))
return 0; return 0;
if(!radial_control_get_path(&ctx_ptr, op, "image_id", &rc->image_id_ptr, NULL, 0, 0, 0)) if(!radial_control_get_path(&ctx_ptr, op, "image_id", &rc->image_id_ptr, NULL, 0, 0))
return 0; return 0;
else if(rc->image_id_ptr.data) { else if(rc->image_id_ptr.data) {
/* extra check, pointer must be to an ID */ /* extra check, pointer must be to an ID */
@ -3363,7 +3397,9 @@ static void WM_OT_radial_control(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
/* all paths relative to the context */ /* all paths relative to the context */
RNA_def_string(ot->srna, "data_path", "", 0, "Data Path", "Path of property to be set by the radial control"); RNA_def_string(ot->srna, "data_path_primary", "", 0, "Primary Data Path", "Primary path of property to be set by the radial control");
RNA_def_string(ot->srna, "data_path_secondary", "", 0, "Secondary Data Path", "Secondary path of property to be set by the radial control");
RNA_def_string(ot->srna, "use_secondary", "", 0, "Use Secondary", "Path of property to select between the primary and secondary data paths");
RNA_def_string(ot->srna, "rotation_path", "", 0, "Rotation Path", "Path of property used to rotate the texture display"); RNA_def_string(ot->srna, "rotation_path", "", 0, "Rotation Path", "Path of property used to rotate the texture display");
RNA_def_string(ot->srna, "color_path", "", 0, "Color Path", "Path of property used to set the color of the control"); RNA_def_string(ot->srna, "color_path", "", 0, "Color Path", "Path of property used to set the color of the control");
RNA_def_string(ot->srna, "fill_color_path", "", 0, "Fill Color Path", "Path of property used to set the fill color of the control"); RNA_def_string(ot->srna, "fill_color_path", "", 0, "Fill Color Path", "Path of property used to set the fill color of the control");