Feature request for all paint systems that support it: Jittering in
absolute coordinates. This allows an artist to lower the brush radius while keeping the spread of the brush constant. A toggle under the jitter slider provides the option to switch between relative/absolute.
This commit is contained in:
@@ -698,8 +698,13 @@ class IMAGE_PT_paint(Panel, ImagePaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
if(brush.use_absolute_jitter):
|
||||
row.prop(brush, "jitter_absolute", slider=True)
|
||||
else:
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col.prop(brush, "use_absolute_jitter")
|
||||
|
||||
col.prop(brush, "blend", text="Blend")
|
||||
|
||||
|
||||
@@ -678,8 +678,13 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
if(brush.use_absolute_jitter):
|
||||
row.prop(brush, "jitter_absolute")
|
||||
else:
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col.prop(brush, "use_absolute_jitter")
|
||||
|
||||
col.prop(brush, "blend", text="Blend")
|
||||
|
||||
@@ -706,8 +711,13 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
|
||||
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
if(brush.use_absolute_jitter):
|
||||
row.prop(brush, "jitter_absolute")
|
||||
else:
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col.prop(brush, "use_absolute_jitter")
|
||||
|
||||
col.prop(brush, "vertex_tool", text="Blend")
|
||||
|
||||
@@ -828,8 +838,13 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
|
||||
col.separator()
|
||||
|
||||
row = col.row(align=True)
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
if(brush.use_absolute_jitter):
|
||||
row.prop(brush, "jitter_absolute")
|
||||
else:
|
||||
row.prop(brush, "jitter", slider=True)
|
||||
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
|
||||
|
||||
col.prop(brush, "use_absolute_jitter")
|
||||
|
||||
else:
|
||||
col.prop(brush, "use_airbrush")
|
||||
|
||||
@@ -791,7 +791,8 @@ void BKE_brush_scale_size(int *r_brush_size,
|
||||
|
||||
void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
|
||||
{
|
||||
int use_jitter = brush->jitter != 0;
|
||||
int use_jitter = (brush->flag & BRUSH_ABSOLUTE_JITTER) ?
|
||||
(brush->jitter_absolute != 0) : (brush->jitter != 0);
|
||||
|
||||
/* jitter-ed brush gives weird and unpredictable result for this
|
||||
* kinds of stroke, so manually disable jitter usage (sergey) */
|
||||
@@ -799,17 +800,26 @@ void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2],
|
||||
|
||||
if (use_jitter) {
|
||||
float rand_pos[2];
|
||||
const int radius = BKE_brush_size_get(scene, brush);
|
||||
const int diameter = 2 * radius;
|
||||
float spread;
|
||||
int diameter;
|
||||
|
||||
/* find random position within a circle of diameter 1 */
|
||||
do {
|
||||
rand_pos[0] = BLI_frand() - 0.5f;
|
||||
rand_pos[1] = BLI_frand() - 0.5f;
|
||||
} while (len_v2(rand_pos) > 0.5f);
|
||||
|
||||
jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * brush->jitter;
|
||||
jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * brush->jitter;
|
||||
|
||||
if (brush->flag & BRUSH_ABSOLUTE_JITTER) {
|
||||
diameter = 2 * brush->jitter_absolute;
|
||||
spread = 1.0;
|
||||
}
|
||||
else {
|
||||
diameter = 2 * BKE_brush_size_get(scene, brush);
|
||||
spread = brush->jitter;
|
||||
}
|
||||
/* find random position within a circle of diameter 1 */
|
||||
jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * spread;
|
||||
jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * spread;
|
||||
}
|
||||
else {
|
||||
copy_v2_v2(jitterpos, pos);
|
||||
|
||||
@@ -169,6 +169,10 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* copy last position -before- jittering, or space fill code
|
||||
* will create too many dabs */
|
||||
copy_v2_v2(stroke->last_mouse_position, mouse_in);
|
||||
|
||||
/* TODO: as sculpt and other paint modes are unified, this
|
||||
* separation will go away */
|
||||
if (paint_supports_jitter(mode)) {
|
||||
@@ -203,8 +207,6 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
|
||||
RNA_boolean_set(&itemptr, "pen_flip", pen_flip);
|
||||
RNA_float_set(&itemptr, "pressure", pressure);
|
||||
|
||||
copy_v2_v2(stroke->last_mouse_position, mouse_out);
|
||||
|
||||
stroke->update_step(C, stroke, &itemptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,8 @@ typedef struct Brush {
|
||||
int size; /* brush diameter */
|
||||
int flag; /* general purpose flag */
|
||||
float jitter; /* jitter the position of the brush */
|
||||
int jitter_absolute; /* absolute jitter in pixels */
|
||||
int pad;
|
||||
int spacing; /* spacing of paint operations */
|
||||
int smooth_stroke_radius; /* turning radius (in pixels) for smooth stroke */
|
||||
float smooth_stroke_factor; /* higher values limit fast changes in the stroke direction */
|
||||
@@ -137,7 +139,8 @@ typedef enum BrushFlags {
|
||||
|
||||
/* temporary flag which sets up automatically for correct brush
|
||||
* drawing when inverted modal operator is running */
|
||||
BRUSH_INVERTED = (1 << 29)
|
||||
BRUSH_INVERTED = (1 << 29),
|
||||
BRUSH_ABSOLUTE_JITTER = (1 << 30)
|
||||
} BrushFlags;
|
||||
|
||||
/* Brush.sculpt_tool */
|
||||
|
||||
@@ -637,6 +637,12 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Jitter", "Jitter the position of the brush while painting");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "jitter_absolute", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "jitter_absolute");
|
||||
RNA_def_property_range(prop, 0, 1000000);
|
||||
RNA_def_property_ui_text(prop, "Absolute Jitter", "Jitter the position of the brush while painting in pixels");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "spacing", PROP_INT, PROP_PERCENTAGE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "spacing");
|
||||
RNA_def_property_range(prop, 1, 1000);
|
||||
@@ -793,6 +799,11 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Rake", "Rotate the brush texture to match the stroke direction");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_absolute_jitter", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ABSOLUTE_JITTER);
|
||||
RNA_def_property_ui_text(prop, "Absolute Jitter", "Jittering happens in screen space, not relative to brush size");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_random_rotation", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RANDOM_ROTATION);
|
||||
RNA_def_property_ui_text(prop, "Random Rotation", "Rotate the brush texture at random");
|
||||
|
||||
Reference in New Issue
Block a user