mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Refactor: Paint: Split stroke brush toggles from inversion
Historically, the `BrushStrokeMode` enum has been used to indicate a singular temporary property about the stroke. Toggles for using various different brush types (smoothing, mask, eraser) were combined with the generic idea of inverting a brush stroke. This leads to limitations, such as being unable to specify multiple properties at once (e.g. inversion & smoothing), as well as generally conflating two separate ideas. This commit makes the following changes to better represent how these modes are conceptually used in the paint systems: * Use `enum class` for `BrushStrokeMode` so it cannot be confused with the new `TemporaryBrushToggleType` `enum`. * The existing `BrushStrokeMode` only indicates whether a brush stroke is inverted or not. * The new `TemporaryBrushToggleType` represents the brush or brush type that is being used during the stroke. Note that this still does not allow us to decouple the idea of temporarily toggling a brush from the actual stroke itself, though this separation of concerns helps to move us in that direction. Pull Request: https://projects.blender.org/blender/blender/pulls/153056
This commit is contained in:
parent
0b422e45b1
commit
c946d9355b
20 changed files with 178 additions and 114 deletions
|
|
@ -4053,11 +4053,11 @@ def km_grease_pencil_brush_stroke(_params):
|
|||
items.extend([
|
||||
("grease_pencil.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
("grease_pencil.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'ERASE')]}),
|
||||
{"properties": [("brush_toggle", 'ERASE')]}),
|
||||
("grease_pencil.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
("grease_pencil.brush_stroke", {"type": 'ERASER', "value": 'PRESS'},
|
||||
{"properties": [("mode", 'ERASE')]}),
|
||||
{"properties": [("brush_toggle", 'ERASE')]}),
|
||||
# Increase/Decrease brush size
|
||||
("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True},
|
||||
{"properties": [("scalar", 0.9)]}),
|
||||
|
|
@ -4213,7 +4213,7 @@ def km_grease_pencil_sculpt_mode(params):
|
|||
("grease_pencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS',
|
||||
"ctrl": True}, {"properties": [("mode", 'INVERT')]}),
|
||||
("grease_pencil.sculpt_paint", {"type": 'LEFTMOUSE', "value": 'PRESS',
|
||||
"shift": True}, {"properties": [("mode", 'SMOOTH')]}),
|
||||
"shift": True}, {"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
# Selection mode
|
||||
("wm.context_toggle", {"type": 'ONE', "value": 'PRESS'},
|
||||
{"properties": [("data_path", "scene.tool_settings.use_gpencil_select_mask_point")]}),
|
||||
|
|
@ -4982,7 +4982,7 @@ def km_image_paint(params):
|
|||
("paint.image_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("paint.image_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
("paint.brush_colors_flip", {"type": 'X', "value": 'PRESS'}, None),
|
||||
("paint.grab_clone", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, None),
|
||||
("paint.sample_color",
|
||||
|
|
@ -5038,7 +5038,7 @@ def km_vertex_paint(params):
|
|||
("paint.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("paint.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
("paint.brush_colors_flip", {"type": 'X', "value": 'PRESS'}, None),
|
||||
("paint.sample_color", {"type": 'X', "value": 'PRESS', "shift": True}, {"properties": [("merged", False)]}),
|
||||
("paint.sample_color",
|
||||
|
|
@ -5100,7 +5100,7 @@ def km_weight_paint(params):
|
|||
("paint.weight_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("paint.weight_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
("paint.weight_sample", {"type": 'X', "value": 'PRESS', "shift": True}, None),
|
||||
("paint.weight_sample_group", {"type": 'X', "value": 'PRESS', "ctrl": True, "shift": True}, None),
|
||||
("paint.weight_gradient", {"type": 'A', "value": 'PRESS', "shift": True, "alt": True},
|
||||
|
|
@ -5226,9 +5226,9 @@ def km_sculpt(params):
|
|||
("sculpt.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("sculpt.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
("sculpt.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("mode", 'MASK')]}),
|
||||
{"properties": [("brush_toggle", 'MASK')]}),
|
||||
# Expand
|
||||
("sculpt.expand", {"type": 'A', "value": 'PRESS', "shift": True},
|
||||
{"properties": [
|
||||
|
|
@ -5429,7 +5429,7 @@ def km_sculpt_curves(params):
|
|||
("sculpt_curves.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("sculpt_curves.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
("curves.set_selection_domain", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("domain", 'POINT')]}),
|
||||
("curves.set_selection_domain", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("domain", 'CURVE')]}),
|
||||
*_template_paint_radial_control("curves_sculpt"),
|
||||
|
|
|
|||
|
|
@ -2814,7 +2814,7 @@ def km_vertex_paint(params):
|
|||
("paint.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("paint.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
# Colors
|
||||
("paint.sample_color", {"type": 'I', "value": 'PRESS'}, {"properties": [("merged", False)]}),
|
||||
("paint.sample_color", {"type": 'I', "value": 'PRESS', "shift": True}, {"properties": [("merged", True)]}),
|
||||
|
|
@ -2873,7 +2873,7 @@ def km_weight_paint(params):
|
|||
("paint.weight_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("paint.weight_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
# Weight
|
||||
("paint.weight_sample", {"type": 'I', "value": 'PRESS'}, None),
|
||||
("paint.weight_sample_group", {"type": 'I', "value": 'PRESS', "alt": True}, None),
|
||||
|
|
@ -2930,9 +2930,9 @@ def km_sculpt(params):
|
|||
("sculpt.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("sculpt.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
("sculpt.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("mode", 'MASK')]}),
|
||||
{"properties": [("brush_toggle", 'MASK')]}),
|
||||
# Expand
|
||||
("sculpt.expand", {"type": 'A', "value": 'PRESS', "shift": True},
|
||||
{"properties": [
|
||||
|
|
@ -3426,7 +3426,7 @@ def km_sculpt_curves(params):
|
|||
("sculpt_curves.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("sculpt_curves.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'SMOOTH')]}),
|
||||
{"properties": [("brush_toggle", 'SMOOTH')]}),
|
||||
# Selection modes
|
||||
("curves.set_selection_domain", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("domain", 'POINT')]}),
|
||||
("curves.set_selection_domain", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("domain", 'CURVE')]}),
|
||||
|
|
|
|||
|
|
@ -805,7 +805,7 @@ static bool use_add_density_mode(const BrushStrokeMode brush_mode,
|
|||
|
||||
const eBrushCurvesSculptDensityMode density_mode = eBrushCurvesSculptDensityMode(
|
||||
brush.curves_sculpt_settings->density_mode);
|
||||
const bool use_invert = brush_mode == BRUSH_STROKE_INVERT;
|
||||
const bool use_invert = brush_mode == BrushStrokeMode::Invert;
|
||||
|
||||
if (density_mode == BRUSH_CURVES_SCULPT_DENSITY_MODE_ADD) {
|
||||
return !use_invert;
|
||||
|
|
|
|||
|
|
@ -502,7 +502,8 @@ std::unique_ptr<CurvesSculptStrokeOperation> new_grow_shrink_operation(
|
|||
const Brush &brush = *BKE_paint_brush_for_read(&scene.toolsettings->curves_sculpt->paint);
|
||||
const bool use_scale_uniform = brush.curves_sculpt_settings->flag &
|
||||
BRUSH_CURVES_SCULPT_FLAG_SCALE_UNIFORM;
|
||||
const bool use_grow = (brush_mode == BRUSH_STROKE_INVERT) == ((brush.flag & BRUSH_DIR_IN) != 0);
|
||||
const bool use_grow = (brush_mode == BrushStrokeMode::Invert) ==
|
||||
((brush.flag & BRUSH_DIR_IN) != 0);
|
||||
|
||||
if (use_grow) {
|
||||
if (use_scale_uniform) {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ std::unique_ptr<CurvesSculptStrokeOperation> new_snake_hook_operation();
|
|||
std::unique_ptr<CurvesSculptStrokeOperation> new_grow_shrink_operation(BrushStrokeMode brush_mode,
|
||||
const Scene &scene);
|
||||
std::unique_ptr<CurvesSculptStrokeOperation> new_selection_paint_operation(
|
||||
BrushStrokeMode brush_mode, const Scene &scene);
|
||||
BrushStrokeMode brush_mode, BrushSwitchMode brush_switch_mode, const Scene &scene);
|
||||
std::unique_ptr<CurvesSculptStrokeOperation> new_pinch_operation(BrushStrokeMode brush_mode,
|
||||
const Scene &scene);
|
||||
std::unique_ptr<CurvesSculptStrokeOperation> new_smooth_operation();
|
||||
|
|
|
|||
|
|
@ -130,15 +130,16 @@ static std::unique_ptr<CurvesSculptStrokeOperation> start_brush_operation(
|
|||
const Object &object,
|
||||
const StrokeExtension &stroke_start)
|
||||
{
|
||||
const BrushStrokeMode mode = BrushStrokeMode(RNA_enum_get(op.ptr, "mode"));
|
||||
const auto mode = BrushStrokeMode(RNA_enum_get(op.ptr, "mode"));
|
||||
const auto brush_switch_mode = BrushSwitchMode(RNA_enum_get(op.ptr, "brush_toggle"));
|
||||
|
||||
const CurvesSculpt &curves_sculpt = *scene.toolsettings->curves_sculpt;
|
||||
const Brush &brush = *BKE_paint_brush_for_read(&curves_sculpt.paint);
|
||||
const eBrushCurvesSculptType brush_type = eBrushCurvesSculptType(brush.curves_sculpt_brush_type);
|
||||
if (mode == BRUSH_STROKE_SMOOTH) {
|
||||
if (brush_switch_mode == BrushSwitchMode::Smooth) {
|
||||
if (brush_type == CURVES_SCULPT_BRUSH_TYPE_SELECTION_PAINT) {
|
||||
/* The selection brush uses the BRUSH_STROKE_SMOOTH mode to indicate that the current
|
||||
* selection should be added to. It should not toggle to the smooth brush itself. */
|
||||
/* The selection brush uses the BrushSwitchMode::Smooth mode to indicate that the
|
||||
* current selection should be added to. It should not toggle to the smooth brush itself. */
|
||||
}
|
||||
else {
|
||||
return new_smooth_operation();
|
||||
|
|
@ -157,7 +158,7 @@ static std::unique_ptr<CurvesSculptStrokeOperation> start_brush_operation(
|
|||
case CURVES_SCULPT_BRUSH_TYPE_GROW_SHRINK:
|
||||
return new_grow_shrink_operation(mode, scene);
|
||||
case CURVES_SCULPT_BRUSH_TYPE_SELECTION_PAINT:
|
||||
return new_selection_paint_operation(mode, scene);
|
||||
return new_selection_paint_operation(mode, brush_switch_mode, scene);
|
||||
case CURVES_SCULPT_BRUSH_TYPE_PINCH:
|
||||
return new_pinch_operation(mode, scene);
|
||||
case CURVES_SCULPT_BRUSH_TYPE_SMOOTH:
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ std::unique_ptr<CurvesSculptStrokeOperation> new_pinch_operation(const BrushStro
|
|||
{
|
||||
const Brush &brush = *BKE_paint_brush_for_read(&scene.toolsettings->curves_sculpt->paint);
|
||||
|
||||
const bool invert_pinch = (brush_mode == BRUSH_STROKE_INVERT) !=
|
||||
const bool invert_pinch = (brush_mode == BrushStrokeMode::Invert) !=
|
||||
((brush.flag & BRUSH_DIR_IN) != 0);
|
||||
return std::make_unique<PinchOperation>(invert_pinch);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -391,12 +391,12 @@ void SelectionPaintOperation::on_stroke_extended(const PaintStroke &stroke,
|
|||
}
|
||||
|
||||
std::unique_ptr<CurvesSculptStrokeOperation> new_selection_paint_operation(
|
||||
const BrushStrokeMode brush_mode, const Scene &scene)
|
||||
const BrushStrokeMode brush_mode, const BrushSwitchMode brush_switch_mode, const Scene &scene)
|
||||
{
|
||||
Brush &brush = *BKE_paint_brush(&scene.toolsettings->curves_sculpt->paint);
|
||||
const bool use_select = ELEM(brush_mode, BRUSH_STROKE_INVERT) ==
|
||||
const bool use_select = ELEM(brush_mode, BrushStrokeMode::Invert) ==
|
||||
((brush.flag & BRUSH_DIR_IN) != 0);
|
||||
const bool clear_selection = use_select && brush_mode != BRUSH_STROKE_SMOOTH;
|
||||
const bool clear_selection = use_select && brush_switch_mode != BrushSwitchMode::Smooth;
|
||||
|
||||
return std::make_unique<SelectionPaintOperation>(use_select, clear_selection);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,11 +110,12 @@ static std::unique_ptr<GreasePencilStrokeOperation> get_stroke_operation(bContex
|
|||
const Paint *paint = BKE_paint_get_active_from_context(&C);
|
||||
const Brush &brush = *BKE_paint_brush_for_read(paint);
|
||||
const PaintMode mode = BKE_paintmode_get_active_from_context(&C);
|
||||
const BrushStrokeMode stroke_mode = BrushStrokeMode(RNA_enum_get(op->ptr, "mode"));
|
||||
const auto stroke_mode = BrushStrokeMode(RNA_enum_get(op->ptr, "mode"));
|
||||
const auto brush_switch_mode = BrushSwitchMode(RNA_enum_get(op->ptr, "brush_toggle"));
|
||||
|
||||
if (mode == PaintMode::GPencil) {
|
||||
if (eBrushGPaintType(brush.gpencil_brush_type) == GPAINT_BRUSH_TYPE_DRAW &&
|
||||
stroke_mode == BRUSH_STROKE_ERASE)
|
||||
brush_switch_mode == BrushSwitchMode::Erase)
|
||||
{
|
||||
/* Special case: We're using the draw tool but with the eraser mode, so create an erase
|
||||
* operation. */
|
||||
|
|
@ -130,12 +131,12 @@ static std::unique_ptr<GreasePencilStrokeOperation> get_stroke_operation(bContex
|
|||
/* Fill tool keymap uses the paint operator to draw fill guides. */
|
||||
return greasepencil::new_paint_operation(/* do_fill_guides = */ true);
|
||||
case GPAINT_BRUSH_TYPE_TINT:
|
||||
return greasepencil::new_tint_operation(stroke_mode == BRUSH_STROKE_ERASE);
|
||||
return greasepencil::new_tint_operation(brush_switch_mode == BrushSwitchMode::Erase);
|
||||
}
|
||||
}
|
||||
else if (mode == PaintMode::SculptGPencil) {
|
||||
|
||||
if (stroke_mode == BRUSH_STROKE_SMOOTH) {
|
||||
if (brush_switch_mode == BrushSwitchMode::Smooth) {
|
||||
return greasepencil::new_smooth_operation(stroke_mode, true);
|
||||
}
|
||||
switch (eBrushGPSculptType(brush.gpencil_sculpt_brush_type)) {
|
||||
|
|
@ -259,14 +260,14 @@ static wmOperatorStatus grease_pencil_brush_stroke_invoke(bContext *C,
|
|||
const wmEvent *event)
|
||||
{
|
||||
if (event->tablet.active == EVT_TABLET_ERASER) {
|
||||
RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_ERASE);
|
||||
RNA_enum_set(op->ptr, "brush_toggle", int(BrushSwitchMode::Erase));
|
||||
}
|
||||
|
||||
const bool use_duplicate_previous_key = [&]() -> bool {
|
||||
const Paint *paint = BKE_paint_get_active_from_context(C);
|
||||
const Brush &brush = *BKE_paint_brush_for_read(paint);
|
||||
const PaintMode mode = BKE_paintmode_get_active_from_context(C);
|
||||
const BrushStrokeMode stroke_mode = BrushStrokeMode(RNA_enum_get(op->ptr, "mode"));
|
||||
const auto brush_switch_mode = BrushSwitchMode(RNA_enum_get(op->ptr, "brush_toggle"));
|
||||
|
||||
if (mode == PaintMode::GPencil) {
|
||||
/* For the eraser and tint tool, we don't want auto-key to create an empty keyframe, so we
|
||||
|
|
@ -279,7 +280,7 @@ static wmOperatorStatus grease_pencil_brush_stroke_invoke(bContext *C,
|
|||
}
|
||||
/* Same for the temporary eraser when using the draw tool. */
|
||||
if (eBrushGPaintType(brush.gpencil_brush_type) == GPAINT_BRUSH_TYPE_DRAW &&
|
||||
stroke_mode == BRUSH_STROKE_ERASE)
|
||||
brush_switch_mode == BrushSwitchMode::Erase)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ bool is_brush_inverted(const Brush &brush, const BrushStrokeMode stroke_mode)
|
|||
{
|
||||
/* The basic setting is the brush's setting. During runtime, the user can hold down the Ctrl key
|
||||
* to invert the basic behavior. */
|
||||
return bool(brush.flag & BRUSH_DIR_IN) ^ (stroke_mode == BrushStrokeMode::BRUSH_STROKE_INVERT);
|
||||
return bool(brush.flag & BRUSH_DIR_IN) ^ (stroke_mode == BrushStrokeMode::Invert);
|
||||
}
|
||||
|
||||
DeltaProjectionFunc get_screen_projection_fn(const GreasePencilStrokeParams ¶ms,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class DrawWeightPaintOperation : public WeightPaintOperation {
|
|||
|
||||
/* Get the add/subtract mode of the draw brush. */
|
||||
this->invert_brush_weight = (this->brush->flag & BRUSH_DIR_IN) != 0;
|
||||
if (this->stroke_mode == BRUSH_STROKE_INVERT) {
|
||||
if (this->stroke_mode == BrushStrokeMode::Invert) {
|
||||
this->invert_brush_weight = !this->invert_brush_weight;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1607,7 +1607,7 @@ void paint_2d_stroke(void *ps,
|
|||
painter->firsttouch = false;
|
||||
}
|
||||
|
||||
void *paint_2d_new_stroke(bContext *C, wmOperator *op, int mode)
|
||||
void *paint_2d_new_stroke(bContext *C, wmOperator *op, const BrushStrokeMode mode)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
|
|
@ -1694,7 +1694,7 @@ void *paint_2d_new_stroke(bContext *C, wmOperator *op, int mode)
|
|||
paint_brush_init_tex(s->brush);
|
||||
|
||||
/* create painter */
|
||||
s->painter = brush_painter_2d_new(scene, paint, s->brush, mode == BRUSH_STROKE_INVERT);
|
||||
s->painter = brush_painter_2d_new(scene, paint, s->brush, mode == BrushStrokeMode::Invert);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,8 +50,12 @@ namespace ed::sculpt_paint::image::ops::paint {
|
|||
class AbstractPaintMode {
|
||||
public:
|
||||
virtual ~AbstractPaintMode() = default;
|
||||
virtual void *paint_new_stroke(
|
||||
bContext *C, wmOperator *op, Object *ob, const float mouse[2], int mode) = 0;
|
||||
virtual void *paint_new_stroke(bContext *C,
|
||||
wmOperator *op,
|
||||
Object *ob,
|
||||
const float mouse[2],
|
||||
BrushStrokeMode mode,
|
||||
BrushSwitchMode brush_switch_mode) = 0;
|
||||
virtual void paint_stroke(bContext *C,
|
||||
void *stroke_handle,
|
||||
float prev_mouse[2],
|
||||
|
|
@ -81,8 +85,12 @@ class AbstractPaintMode {
|
|||
|
||||
class ImagePaintMode : public AbstractPaintMode {
|
||||
public:
|
||||
void *paint_new_stroke(
|
||||
bContext *C, wmOperator *op, Object * /*ob*/, const float /*mouse*/[2], int mode) override
|
||||
void *paint_new_stroke(bContext *C,
|
||||
wmOperator *op,
|
||||
Object * /*ob*/,
|
||||
const float /*mouse*/[2],
|
||||
const BrushStrokeMode mode,
|
||||
const BrushSwitchMode /*brush_switch_mode*/) override
|
||||
{
|
||||
return paint_2d_new_stroke(C, op, mode);
|
||||
}
|
||||
|
|
@ -141,10 +149,14 @@ class ImagePaintMode : public AbstractPaintMode {
|
|||
|
||||
class ProjectionPaintMode : public AbstractPaintMode {
|
||||
public:
|
||||
void *paint_new_stroke(
|
||||
bContext *C, wmOperator * /*op*/, Object *ob, const float mouse[2], int mode) override
|
||||
void *paint_new_stroke(bContext *C,
|
||||
wmOperator * /*op*/,
|
||||
Object *ob,
|
||||
const float mouse[2],
|
||||
BrushStrokeMode mode,
|
||||
BrushSwitchMode brush_switch_mode) override
|
||||
{
|
||||
return paint_proj_new_stroke(C, ob, mouse, mode);
|
||||
return paint_proj_new_stroke(C, ob, mouse, mode, brush_switch_mode);
|
||||
}
|
||||
|
||||
void paint_stroke(bContext *C,
|
||||
|
|
@ -291,7 +303,8 @@ static std::unique_ptr<PaintOperation> texture_paint_init(bContext *C,
|
|||
ToolSettings *settings = scene->toolsettings;
|
||||
std::unique_ptr<PaintOperation> pop = std::make_unique<PaintOperation>();
|
||||
Brush *brush = BKE_paint_brush(&settings->imapaint.paint);
|
||||
int mode = RNA_enum_get(op->ptr, "mode");
|
||||
auto mode = BrushStrokeMode(RNA_enum_get(op->ptr, "mode"));
|
||||
auto brush_switch_mode = BrushSwitchMode(RNA_enum_get(op->ptr, "brush_toggle"));
|
||||
pop->vc = ED_view3d_viewcontext_init(C, depsgraph);
|
||||
|
||||
copy_v2_v2(pop->prevmouse, mouse);
|
||||
|
|
@ -315,7 +328,7 @@ static std::unique_ptr<PaintOperation> texture_paint_init(bContext *C,
|
|||
pop->mode = MEM_new<ImagePaintMode>("ImagePaintMode");
|
||||
}
|
||||
|
||||
pop->stroke_handle = pop->mode->paint_new_stroke(C, op, ob, mouse, mode);
|
||||
pop->stroke_handle = pop->mode->paint_new_stroke(C, op, ob, mouse, mode, brush_switch_mode);
|
||||
if (!pop->stroke_handle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -549,7 +562,7 @@ static wmOperatorStatus paint_exec(bContext *C, wmOperator *op)
|
|||
bool dummy;
|
||||
float dummy_location[3];
|
||||
|
||||
int stroke_mode = RNA_enum_get(op->ptr, "mode");
|
||||
BrushStrokeMode stroke_mode = BrushStrokeMode(RNA_enum_get(op->ptr, "mode"));
|
||||
float zoomx;
|
||||
float zoomy;
|
||||
get_imapaint_zoom(C, &zoomx, &zoomy);
|
||||
|
|
|
|||
|
|
@ -293,6 +293,7 @@ struct ProjPaintState {
|
|||
short brush_type;
|
||||
short blend;
|
||||
BrushStrokeMode mode;
|
||||
BrushSwitchMode brush_switch_mode;
|
||||
|
||||
float brush_size;
|
||||
Object *ob;
|
||||
|
|
@ -5085,7 +5086,7 @@ static void do_projectpaint_soften_f(ProjPaintState *ps,
|
|||
if (LIKELY(accum_tot != 0)) {
|
||||
mul_v4_fl(rgba, 1.0f / accum_tot);
|
||||
|
||||
if (ps->mode == BRUSH_STROKE_INVERT) {
|
||||
if (ps->mode == BrushStrokeMode::Invert) {
|
||||
/* subtract blurred image from normal image gives high pass filter */
|
||||
sub_v3_v3v3(rgba, projPixel->pixel.f_pt, rgba);
|
||||
|
||||
|
|
@ -5148,7 +5149,7 @@ static void do_projectpaint_soften(ProjPaintState *ps,
|
|||
|
||||
mul_v4_fl(rgba, 1.0f / accum_tot);
|
||||
|
||||
if (ps->mode == BRUSH_STROKE_INVERT) {
|
||||
if (ps->mode == BrushStrokeMode::Invert) {
|
||||
float rgba_pixel[4];
|
||||
|
||||
straight_uchar_to_premul_float(rgba_pixel, projPixel->pixel.ch_pt);
|
||||
|
|
@ -5905,7 +5906,7 @@ static void paint_proj_stroke_ps(const bContext * /*C*/,
|
|||
paint_brush_color_get(paint,
|
||||
brush,
|
||||
ps_handle->initial_hsv_jitter,
|
||||
ps->mode == BRUSH_STROKE_INVERT,
|
||||
ps->mode == BrushStrokeMode::Invert,
|
||||
distance,
|
||||
pressure,
|
||||
ps->paint_color_linear);
|
||||
|
|
@ -5940,7 +5941,7 @@ static void paint_proj_stroke_ps(const bContext * /*C*/,
|
|||
else if (ps->brush_type == IMAGE_PAINT_BRUSH_TYPE_MASK) {
|
||||
ps->stencil_value = brush->weight;
|
||||
|
||||
if ((ps->mode == BRUSH_STROKE_INVERT) ^
|
||||
if ((ps->mode == BrushStrokeMode::Invert) ^
|
||||
((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0))
|
||||
{
|
||||
ps->stencil_value = 1.0f - ps->stencil_value;
|
||||
|
|
@ -5997,28 +5998,33 @@ void paint_proj_stroke(const bContext *C,
|
|||
}
|
||||
|
||||
/* initialize project paint settings from context */
|
||||
static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int mode)
|
||||
static void project_state_init(bContext *C,
|
||||
Object *ob,
|
||||
ProjPaintState *ps,
|
||||
const BrushStrokeMode mode,
|
||||
const BrushSwitchMode brush_switch_mode)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ToolSettings *settings = scene->toolsettings;
|
||||
|
||||
/* brush */
|
||||
ps->mode = BrushStrokeMode(mode);
|
||||
ps->mode = mode;
|
||||
ps->brush_switch_mode = brush_switch_mode;
|
||||
ps->paint = BKE_paint_get_active_from_context(C);
|
||||
ps->brush = BKE_paint_brush(&settings->imapaint.paint);
|
||||
if (ps->brush) {
|
||||
Brush *brush = ps->brush;
|
||||
ps->brush_type = brush->image_brush_type;
|
||||
ps->blend = brush->blend;
|
||||
if (mode == BRUSH_STROKE_SMOOTH) {
|
||||
if (brush_switch_mode == BrushSwitchMode::Smooth) {
|
||||
ps->brush_type = IMAGE_PAINT_BRUSH_TYPE_SOFTEN;
|
||||
}
|
||||
/* only check for inversion for the soften brush, elsewhere,
|
||||
* a resident brush inversion flag can cause issues */
|
||||
if (ps->brush_type == IMAGE_PAINT_BRUSH_TYPE_SOFTEN) {
|
||||
ps->mode = (((ps->mode == BRUSH_STROKE_INVERT) ^ ((brush->flag & BRUSH_DIR_IN) != 0)) ?
|
||||
BRUSH_STROKE_INVERT :
|
||||
BRUSH_STROKE_NORMAL);
|
||||
ps->mode = (((ps->mode == BrushStrokeMode::Invert) ^ ((brush->flag & BRUSH_DIR_IN) != 0)) ?
|
||||
BrushStrokeMode::Invert :
|
||||
BrushStrokeMode::Normal);
|
||||
|
||||
ps->blurkernel = paint_new_blur_kernel(brush, true);
|
||||
}
|
||||
|
|
@ -6108,7 +6114,11 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
|
|||
ps->dither = settings->imapaint.dither;
|
||||
}
|
||||
|
||||
void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int mode)
|
||||
void *paint_proj_new_stroke(bContext *C,
|
||||
Object *ob,
|
||||
const float mouse[2],
|
||||
const BrushStrokeMode mode,
|
||||
const BrushSwitchMode brush_switch_mode)
|
||||
{
|
||||
ProjStrokeHandle *ps_handle;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
|
@ -6124,7 +6134,7 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m
|
|||
ps_handle->initial_hsv_jitter = seed_hsv_jitter();
|
||||
}
|
||||
|
||||
if (mode == BRUSH_STROKE_INVERT) {
|
||||
if (mode == BrushStrokeMode::Invert) {
|
||||
/* Bypass regular stroke logic. */
|
||||
if (ps_handle->brush->image_brush_type == IMAGE_PAINT_BRUSH_TYPE_CLONE) {
|
||||
view3d_operator_needs_gpu(C);
|
||||
|
|
@ -6166,7 +6176,7 @@ void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int m
|
|||
for (int i = 0; i < ps_handle->ps_views_tot; i++) {
|
||||
ProjPaintState *ps = ps_handle->ps_views[i];
|
||||
|
||||
project_state_init(C, ob, ps, mode);
|
||||
project_state_init(C, ob, ps, mode, brush_switch_mode);
|
||||
|
||||
if (ps->ob == nullptr) {
|
||||
ps_handle->ps_views_tot = i + 1;
|
||||
|
|
@ -6288,7 +6298,7 @@ static wmOperatorStatus texture_paint_camera_project_exec(bContext *C, wmOperato
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
project_state_init(C, ob, &ps, BRUSH_STROKE_NORMAL);
|
||||
project_state_init(C, ob, &ps, BrushStrokeMode::Normal, BrushSwitchMode::None);
|
||||
|
||||
if (image == nullptr) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Image could not be found");
|
||||
|
|
|
|||
|
|
@ -74,12 +74,17 @@ using ColorManagedDisplay = ocio::Display;
|
|||
|
||||
/* paint_stroke.cc */
|
||||
|
||||
enum BrushStrokeMode {
|
||||
BRUSH_STROKE_NORMAL,
|
||||
BRUSH_STROKE_INVERT,
|
||||
BRUSH_STROKE_SMOOTH,
|
||||
BRUSH_STROKE_ERASE,
|
||||
BRUSH_STROKE_MASK,
|
||||
enum class BrushStrokeMode : int8_t {
|
||||
Normal = 0,
|
||||
Invert = 1,
|
||||
};
|
||||
|
||||
/* Indicates a brush that the stroke will switch to for the duration of the stroke */
|
||||
enum class BrushSwitchMode : int8_t {
|
||||
None = 0,
|
||||
Smooth = 1,
|
||||
Erase = 2,
|
||||
Mask = 3,
|
||||
};
|
||||
|
||||
namespace ed::sculpt_paint {
|
||||
|
|
@ -160,7 +165,8 @@ struct PaintStroke : NonCopyable, NonMovable {
|
|||
float cached_size_pressure_ = 0.0f;
|
||||
/* last pressure will store last pressure value for use in interpolation for space strokes */
|
||||
float last_pressure_ = 0.0f;
|
||||
int stroke_mode_ = 0;
|
||||
BrushStrokeMode stroke_mode_ = BrushStrokeMode::Normal;
|
||||
BrushSwitchMode brush_switch_mode_ = BrushSwitchMode::None;
|
||||
|
||||
float last_tablet_event_pressure_ = 0.0f;
|
||||
|
||||
|
|
@ -207,7 +213,7 @@ struct PaintStroke : NonCopyable, NonMovable {
|
|||
|
||||
bool stroke_inverted() const
|
||||
{
|
||||
return stroke_mode_ == BRUSH_STROKE_INVERT;
|
||||
return stroke_mode_ == BrushStrokeMode::Invert;
|
||||
}
|
||||
|
||||
float stroke_distance() const
|
||||
|
|
@ -290,7 +296,7 @@ void paint_stroke_jitter_pos(Paint *paint,
|
|||
PaintMode mode,
|
||||
const Brush &brush,
|
||||
float pressure,
|
||||
int stroke_mode,
|
||||
BrushStrokeMode stroke_mode,
|
||||
float zoom_2d,
|
||||
const float mval[2],
|
||||
float r_mouse_out[2]);
|
||||
|
|
@ -307,7 +313,9 @@ bool paint_supports_dynamic_size(const Brush &br, PaintMode mode);
|
|||
* Return true if the brush size can change during paint (normally used for pressure).
|
||||
*/
|
||||
bool paint_supports_dynamic_tex_coords(const Brush &br, PaintMode mode);
|
||||
bool paint_supports_smooth_stroke(const Brush &brush, PaintMode mode, int stroke_mode);
|
||||
bool paint_supports_smooth_stroke(const Brush &brush,
|
||||
PaintMode mode,
|
||||
BrushSwitchMode brush_switch_mode);
|
||||
bool paint_supports_texture(PaintMode mode);
|
||||
|
||||
/**
|
||||
|
|
@ -445,7 +453,7 @@ void set_imapaintpartial(ImagePaintPartialRedraw *ippr);
|
|||
void imapaint_region_tiles(
|
||||
ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th);
|
||||
bool get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy);
|
||||
void *paint_2d_new_stroke(bContext *, wmOperator *, int mode);
|
||||
void *paint_2d_new_stroke(bContext *, wmOperator *, BrushStrokeMode mode);
|
||||
void paint_2d_redraw(const bContext *C, void *ps, bool final);
|
||||
void paint_2d_stroke_done(void *ps);
|
||||
void paint_2d_stroke(void *ps,
|
||||
|
|
@ -466,7 +474,11 @@ void paint_2d_bucket_fill(const bContext *C,
|
|||
void *ps);
|
||||
void paint_2d_gradient_fill(
|
||||
const bContext *C, Brush *br, const float mouse_init[2], const float mouse_final[2], void *ps);
|
||||
void *paint_proj_new_stroke(bContext *C, Object *ob, const float mouse[2], int mode);
|
||||
void *paint_proj_new_stroke(bContext *C,
|
||||
Object *ob,
|
||||
const float mouse[2],
|
||||
BrushStrokeMode mode,
|
||||
BrushSwitchMode brush_switch_mode);
|
||||
void paint_proj_stroke(const bContext *C,
|
||||
void *ps_handle_p,
|
||||
const float prev_pos[2],
|
||||
|
|
|
|||
|
|
@ -445,12 +445,12 @@ void paint_stroke_jitter_pos(Paint *paint,
|
|||
PaintMode mode,
|
||||
const Brush &brush,
|
||||
float pressure,
|
||||
int stroke_mode,
|
||||
BrushStrokeMode stroke_mode,
|
||||
float zoom_2d,
|
||||
const float mval[2],
|
||||
float r_mouse_out[2])
|
||||
{
|
||||
if (paint_stroke_use_jitter(mode, brush, stroke_mode == BRUSH_STROKE_INVERT)) {
|
||||
if (paint_stroke_use_jitter(mode, brush, stroke_mode == BrushStrokeMode::Invert)) {
|
||||
float factor = zoom_2d;
|
||||
|
||||
if (brush.flag & BRUSH_JITTER_PRESSURE) {
|
||||
|
|
@ -580,14 +580,14 @@ void PaintStroke::add_step(bContext *C, wmOperator *op, const float2 mval, float
|
|||
static bool paint_smooth_stroke(const Brush &brush,
|
||||
const PaintSample *sample,
|
||||
const PaintMode mode,
|
||||
const int stroke_mode,
|
||||
const BrushSwitchMode brush_switch_mode,
|
||||
float zoom_2d,
|
||||
float2 last_mouse_position,
|
||||
float last_pressure,
|
||||
float2 &r_mouse,
|
||||
float &r_pressure)
|
||||
{
|
||||
if (paint_supports_smooth_stroke(brush, mode, stroke_mode)) {
|
||||
if (paint_supports_smooth_stroke(brush, mode, brush_switch_mode)) {
|
||||
const float radius = brush.smooth_stroke_radius * zoom_2d;
|
||||
const float u = brush.smooth_stroke_factor;
|
||||
|
||||
|
|
@ -868,7 +868,8 @@ PaintStroke::PaintStroke(bContext *C, wmOperator *op, int event_type) : event_ty
|
|||
this->object = CTX_data_active_object(C);
|
||||
this->scene = CTX_data_scene(C);
|
||||
|
||||
stroke_mode_ = RNA_enum_get(op->ptr, "mode");
|
||||
stroke_mode_ = BrushStrokeMode(RNA_enum_get(op->ptr, "mode"));
|
||||
brush_switch_mode_ = BrushSwitchMode(RNA_enum_get(op->ptr, "brush_toggle"));
|
||||
|
||||
original_ = paint_brush_type_raycast_original(*this->brush,
|
||||
BKE_paintmode_get_active_from_context(C));
|
||||
|
|
@ -895,9 +896,9 @@ PaintStroke::PaintStroke(bContext *C, wmOperator *op, int event_type) : event_ty
|
|||
BKE_image_pool_release_ibuf(this->brush->mtex.tex->ima, tex_ibuf, nullptr);
|
||||
}
|
||||
|
||||
if (stroke_mode_ == BRUSH_STROKE_INVERT) {
|
||||
if (stroke_mode_ == BrushStrokeMode::Invert) {
|
||||
if (this->brush->flag & BRUSH_CURVE) {
|
||||
RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_NORMAL);
|
||||
RNA_enum_set(op->ptr, "mode", int(BrushStrokeMode::Normal));
|
||||
}
|
||||
}
|
||||
/* initialize here */
|
||||
|
|
@ -1050,13 +1051,15 @@ bool paint_supports_dynamic_size(const Brush &br, const PaintMode mode)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool paint_supports_smooth_stroke(const Brush &brush, const PaintMode mode, int stroke_mode)
|
||||
bool paint_supports_smooth_stroke(const Brush &brush,
|
||||
const PaintMode mode,
|
||||
const BrushSwitchMode brush_switch_mode)
|
||||
{
|
||||
/* The grease pencil draw tool needs to enable this when the `stroke_mode` is set to
|
||||
* `BRUSH_STROKE_SMOOTH`. */
|
||||
* `BrushSwitchMode::Smooth`. */
|
||||
if (mode == PaintMode::GPencil &&
|
||||
eBrushGPaintType(brush.gpencil_brush_type) == GPAINT_BRUSH_TYPE_DRAW &&
|
||||
stroke_mode == BRUSH_STROKE_SMOOTH)
|
||||
brush_switch_mode == BrushSwitchMode::Smooth)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1485,7 +1488,7 @@ wmOperatorStatus PaintStroke::modal(bContext *C, wmOperator *op, const wmEvent *
|
|||
* here. */
|
||||
br = BKE_paint_brush(paint);
|
||||
|
||||
if (paint_supports_smooth_stroke(*br, mode, stroke_mode_)) {
|
||||
if (paint_supports_smooth_stroke(*br, mode, brush_switch_mode_)) {
|
||||
|
||||
stroke_cursor_ = WM_paint_cursor_activate(
|
||||
SPACE_TYPE_ANY, RGN_TYPE_ANY, paint_brush_cursor_poll, paint_draw_smooth_cursor, this);
|
||||
|
|
@ -1518,14 +1521,14 @@ wmOperatorStatus PaintStroke::modal(bContext *C, wmOperator *op, const wmEvent *
|
|||
/* Handles shift-key active smooth toggling during a grease pencil stroke. */
|
||||
if (mode == PaintMode::GPencil) {
|
||||
if (event->modifier & KM_SHIFT) {
|
||||
stroke_mode_ = BRUSH_STROKE_SMOOTH;
|
||||
brush_switch_mode_ = BrushSwitchMode::Smooth;
|
||||
if (!stroke_cursor_) {
|
||||
stroke_cursor_ = WM_paint_cursor_activate(
|
||||
SPACE_TYPE_ANY, RGN_TYPE_ANY, paint_brush_cursor_poll, paint_draw_smooth_cursor, this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
stroke_mode_ = BRUSH_STROKE_NORMAL;
|
||||
stroke_mode_ = BrushStrokeMode::Normal;
|
||||
if (stroke_cursor_ != nullptr) {
|
||||
WM_paint_cursor_end(static_cast<wmPaintCursor *>(stroke_cursor_));
|
||||
stroke_cursor_ = nullptr;
|
||||
|
|
@ -1579,7 +1582,7 @@ wmOperatorStatus PaintStroke::modal(bContext *C, wmOperator *op, const wmEvent *
|
|||
if (paint_smooth_stroke(*this->brush,
|
||||
&sample_average,
|
||||
mode,
|
||||
stroke_mode_,
|
||||
brush_switch_mode_,
|
||||
zoom_2d_,
|
||||
this->last_mouse_position,
|
||||
last_pressure_,
|
||||
|
|
|
|||
|
|
@ -141,23 +141,32 @@ bool paint_get_tex_pixel(const MTex *mtex,
|
|||
void paint_stroke_operator_properties(wmOperatorType *ot)
|
||||
{
|
||||
static const EnumPropertyItem stroke_mode_items[] = {
|
||||
{BRUSH_STROKE_NORMAL, "NORMAL", 0, "Regular", "Apply brush normally"},
|
||||
{BRUSH_STROKE_INVERT,
|
||||
{int(BrushStrokeMode::Normal), "NORMAL", 0, "Regular", "Apply brush normally"},
|
||||
{int(BrushStrokeMode::Invert),
|
||||
"INVERT",
|
||||
0,
|
||||
"Invert",
|
||||
"Invert action of brush for duration of stroke"},
|
||||
{BRUSH_STROKE_SMOOTH,
|
||||
{0},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem temporary_brush_toggle_items[] = {
|
||||
{int(BrushSwitchMode::None), "None", 0, "None", "Apply brush normally"},
|
||||
{int(BrushSwitchMode::Smooth),
|
||||
"SMOOTH",
|
||||
0,
|
||||
"Smooth",
|
||||
"Switch brush to smooth mode for duration of stroke"},
|
||||
{BRUSH_STROKE_ERASE,
|
||||
"Switch to smooth brush for duration of stroke"},
|
||||
{int(BrushSwitchMode::Erase),
|
||||
"ERASE",
|
||||
0,
|
||||
"Erase",
|
||||
"Switch brush to erase mode for duration of stroke"},
|
||||
{BRUSH_STROKE_MASK, "MASK", 0, "Mask", "Switch brush to mask mode for duration of stroke"},
|
||||
"Switch to erase brush for duration of stroke"},
|
||||
{int(BrushSwitchMode::Mask),
|
||||
"MASK",
|
||||
0,
|
||||
"Mask",
|
||||
"Switch to mask brush for duration of stroke"},
|
||||
{0},
|
||||
};
|
||||
|
||||
|
|
@ -169,12 +178,21 @@ void paint_stroke_operator_properties(wmOperatorType *ot)
|
|||
prop = RNA_def_enum(ot->srna,
|
||||
"mode",
|
||||
stroke_mode_items,
|
||||
BRUSH_STROKE_NORMAL,
|
||||
int(BrushStrokeMode::Normal),
|
||||
"Stroke Mode",
|
||||
"Action taken when a paint stroke is made");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_enum(ot->srna,
|
||||
"brush_toggle",
|
||||
temporary_brush_toggle_items,
|
||||
int(BrushSwitchMode::None),
|
||||
"Temporary Brush Toggle Type",
|
||||
"Brush to use for duration of stroke");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
/* TODO: Pen flip logic should likely be combined into the stroke mode logic instead of being
|
||||
* an entirely separate concept. */
|
||||
prop = RNA_def_boolean(
|
||||
|
|
|
|||
|
|
@ -397,7 +397,6 @@ void update_cache_invariants(
|
|||
Object &ob = *stroke->object;
|
||||
float mat[3][3];
|
||||
float view_dir[3] = {0.0f, 0.0f, 1.0f};
|
||||
int mode;
|
||||
|
||||
/* VW paint needs to allocate stroke cache before update is called. */
|
||||
if (!ss.cache) {
|
||||
|
|
@ -416,9 +415,11 @@ void update_cache_invariants(
|
|||
zero_v2(cache->initial_mouse);
|
||||
}
|
||||
|
||||
mode = RNA_enum_get(op->ptr, "mode");
|
||||
cache->invert = mode == BRUSH_STROKE_INVERT;
|
||||
cache->alt_smooth = mode == BRUSH_STROKE_SMOOTH;
|
||||
const auto mode = BrushStrokeMode(RNA_enum_get(op->ptr, "mode"));
|
||||
cache->invert = mode == BrushStrokeMode::Invert;
|
||||
|
||||
const auto brush_switch_mode = BrushSwitchMode(RNA_enum_get(op->ptr, "brush_toggle"));
|
||||
cache->alt_smooth = brush_switch_mode == BrushSwitchMode::Smooth;
|
||||
/* not very nice, but with current events system implementation
|
||||
* we can't handle brush appearance inversion hotkey separately (sergey) */
|
||||
if (cache->invert) {
|
||||
|
|
@ -949,8 +950,8 @@ static std::unique_ptr<VPaintData> vpaint_init_vpaint(wmOperator *op,
|
|||
brush.falloff_angle,
|
||||
(brush.flag & BRUSH_FRONTFACE_FALLOFF) != 0);
|
||||
|
||||
vpd->paintcol = vpaint_get_current_col(vp,
|
||||
(RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_INVERT));
|
||||
vpd->paintcol = vpaint_get_current_col(
|
||||
vp, (BrushStrokeMode(RNA_enum_get(op->ptr, "mode")) == BrushStrokeMode::Invert));
|
||||
|
||||
vpd->is_texbrush = !(brush.vertex_brush_type == VPAINT_BRUSH_TYPE_BLUR) && brush.mtex.tex;
|
||||
|
||||
|
|
|
|||
|
|
@ -4269,15 +4269,14 @@ static void cache_paint_invariants_update(StrokeCache &cache, const Brush &brush
|
|||
* smooth). */
|
||||
static bool sculpt_needs_connectivity_info(const Sculpt &sd,
|
||||
const Brush &brush,
|
||||
const Object &object,
|
||||
int stroke_mode)
|
||||
const Object &object)
|
||||
{
|
||||
SculptSession &ss = *object.runtime->sculpt_session;
|
||||
const bke::pbvh::Tree *pbvh = bke::object::pbvh_get(object);
|
||||
if (pbvh && auto_mask::is_enabled(sd, object, &brush)) {
|
||||
return true;
|
||||
}
|
||||
return ((stroke_mode == BRUSH_STROKE_SMOOTH) || (ss.cache && ss.cache->alt_smooth) ||
|
||||
return ((ss.cache && ss.cache->alt_smooth) ||
|
||||
(brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_SMOOTH) || (brush.autosmooth_factor > 0) ||
|
||||
((brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_MASK) &&
|
||||
(brush.mask_tool == BRUSH_MASK_SMOOTH)) ||
|
||||
|
|
@ -4300,7 +4299,7 @@ void SCULPT_stroke_modifiers_check(
|
|||
using namespace blender::ed::sculpt_paint;
|
||||
SculptSession &ss = *ob.runtime->sculpt_session;
|
||||
|
||||
bool need_pmap = brush && sculpt_needs_connectivity_info(sd, *brush, ob, 0);
|
||||
bool need_pmap = brush && sculpt_needs_connectivity_info(sd, *brush, ob);
|
||||
if (ss.shapekey_active || ss.deform_modifiers_active ||
|
||||
(!BKE_sculptsession_use_pbvh_draw(&ob, rv3d) && need_pmap))
|
||||
{
|
||||
|
|
@ -4932,7 +4931,10 @@ struct SculptPaintStroke final : public PaintStroke {
|
|||
wm_ = CTX_wm_manager(C);
|
||||
}
|
||||
|
||||
void stroke_cache_init(BrushStrokeMode stroke_mode, bool pen_flip, const float mval[2]);
|
||||
void stroke_cache_init(BrushStrokeMode stroke_mode,
|
||||
BrushSwitchMode brush_switch_mode,
|
||||
bool pen_flip,
|
||||
const float mval[2]);
|
||||
void stroke_cache_update(PointerRNA *ptr);
|
||||
|
||||
bool get_location(float out[3], const float mouse[2], bool force_original) override;
|
||||
|
|
@ -5501,6 +5503,7 @@ bool color_supported_check(const Scene &scene, Object &object, ReportList *repor
|
|||
}
|
||||
|
||||
void SculptPaintStroke::stroke_cache_init(const BrushStrokeMode stroke_mode,
|
||||
const BrushSwitchMode brush_switch_mode,
|
||||
const bool pen_flip,
|
||||
const float mval[2])
|
||||
{
|
||||
|
|
@ -5539,9 +5542,9 @@ void SculptPaintStroke::stroke_cache_init(const BrushStrokeMode stroke_mode,
|
|||
cache->initial_normal = ss.cursor_sampled_normal.value_or(ss.cursor_normal);
|
||||
|
||||
cache->pen_flip = pen_flip;
|
||||
cache->invert = stroke_mode == BRUSH_STROKE_INVERT;
|
||||
cache->alt_smooth = stroke_mode == BRUSH_STROKE_SMOOTH;
|
||||
cache->alt_mask = stroke_mode == BRUSH_STROKE_MASK;
|
||||
cache->invert = stroke_mode == BrushStrokeMode::Invert;
|
||||
cache->alt_smooth = brush_switch_mode == BrushSwitchMode::Smooth;
|
||||
cache->alt_mask = brush_switch_mode == BrushSwitchMode::Mask;
|
||||
cache->normal_weight = brush->normal_weight;
|
||||
|
||||
/* Interpret invert as following normal, for grab brushes. */
|
||||
|
|
@ -5676,7 +5679,8 @@ bool SculptPaintStroke::test_start(wmOperator *op, const float mval[2])
|
|||
|
||||
ED_view3d_init_mats_rv3d(&ob, this->vc.rv3d);
|
||||
|
||||
stroke_cache_init((BrushStrokeMode)RNA_enum_get(op->ptr, "mode"),
|
||||
stroke_cache_init(BrushStrokeMode(RNA_enum_get(op->ptr, "mode")),
|
||||
BrushSwitchMode(RNA_enum_get(op->ptr, "brush_toggle")),
|
||||
RNA_boolean_get(op->ptr, "pen_flip"),
|
||||
mval);
|
||||
if (brush && brush_type_is_paint(brush->sculpt_brush_type)) {
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ struct StrokeCache {
|
|||
* Whether the modifier key that controls inverting brush behavior is active currently.
|
||||
* Generally signals a change in behavior for brushes.
|
||||
*
|
||||
* \see BrushStrokeMode::BRUSH_STROKE_INVERT.
|
||||
* \see BrushStrokeMode::Invert.
|
||||
*/
|
||||
bool invert = false;
|
||||
float pressure = 0.0f;
|
||||
|
|
@ -395,7 +395,7 @@ struct StrokeCache {
|
|||
* Whether the modifier key that controls smoothing is active currently.
|
||||
* Generally signals a change in behavior for different brushes.
|
||||
*
|
||||
* \see BrushStrokeMode::BRUSH_STROKE_SMOOTH.
|
||||
* \see BrushSwitchMode::Smooth.
|
||||
*/
|
||||
bool alt_smooth = false;
|
||||
|
||||
|
|
@ -403,7 +403,7 @@ struct StrokeCache {
|
|||
* Whether the modifier key that controls masking is active currently.
|
||||
* Switches the active brush to the mask brush during the stroke.
|
||||
*
|
||||
* \see BrushStrokeMode::BRUSH_STROKE_MASK.
|
||||
* \see BrushSwitchMode::Mask.
|
||||
*/
|
||||
bool alt_mask = false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue