From 3dbfebc42caada8bb969a936cfb7a9f8ad730ca6 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Fri, 30 Jan 2015 19:47:58 +0100 Subject: First version of constrained line strokes - there's some flickering still, will look into it later. --- source/blender/editors/sculpt_paint/paint_stroke.c | 64 ++++++++++++++++++---- 1 file changed, 54 insertions(+), 10 deletions(-) (limited to 'source/blender/editors/sculpt_paint/paint_stroke.c') diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index bb875d2ef00..79bf8c893df 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -122,6 +122,8 @@ typedef struct PaintStroke { float zoom_2d; int pen_flip; + + bool constrain_line; StrokeGetLocation get_location; StrokeTestStart test_start; @@ -654,10 +656,11 @@ PaintStroke *paint_stroke_new(bContext *C, get_imapaint_zoom(C, &zoomx, &zoomy); stroke->zoom_2d = max_ff(zoomx, zoomy); - if ((br->flag & BRUSH_CURVE) && - RNA_struct_property_is_set(op->ptr, "mode")) + if (stroke->stroke_mode == BRUSH_STROKE_INVERT) { - RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_NORMAL); + if (br->flag & (BRUSH_CURVE | BRUSH_LINE)) { + RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_NORMAL); + } } /* initialize here */ ups->overlap_factor = 1.0; @@ -996,6 +999,36 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str return false; } +static void paint_stroke_line_constrain (bContext *C, PaintStroke *stroke, float mouse[2]) { + if (stroke->constrain_line) { + wmWindow *win = CTX_wm_window(C); + ARegion *ar = CTX_wm_region(C); + float line[2]; + float angle, len, res; + + sub_v2_v2v2(line, mouse, stroke->last_mouse_position); + angle = atan2(line[1], line[0]); + len = len_v2(line); + + /* divide angle by PI/8 */ + angle = 4.0 * angle / M_PI; + + /* now take residue, if less than */ + res = angle - floor(angle); + + if (res <= 0.5) { + angle = floor(angle) * M_PI / 4.0; + } + else { + angle = (floor(angle) + 1.0) * M_PI / 4.0; + } + + line[0] = len * cos(angle) + stroke->last_mouse_position[0] + ar->winrct.xmin; + line[1] = len * sin(angle) + stroke->last_mouse_position[1] + ar->winrct.ymin; + + WM_cursor_warp(win, line[0], line[1]); + } +} int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event) { @@ -1069,7 +1102,9 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event) if (event->type == stroke->event_type && !first_modal) { if (event->val == KM_RELEASE) { - paint_stroke_line_end (C, op, stroke, sample_average.mouse); + copy_v2_fl2(mouse, event->mval[0], event->mval[1]); + paint_stroke_line_constrain(C, stroke, mouse); + paint_stroke_line_end (C, op, stroke, mouse); stroke_done(C, op); return OPERATOR_FINISHED; } @@ -1079,13 +1114,22 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event) stroke_done(C, op); return OPERATOR_FINISHED; } - else if ((br->flag & BRUSH_LINE) && stroke->stroke_started && - (first_modal || (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)))) - { - if ((br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) || (br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) { - copy_v2_v2(stroke->ups->last_rake, stroke->last_mouse_position); + else if (br->flag & BRUSH_LINE) { + if (event->ctrl) + stroke->constrain_line = true; + else + stroke->constrain_line = false; + + copy_v2_fl2(mouse, event->mval[0], event->mval[1]); + paint_stroke_line_constrain(C, stroke, mouse); + + if (stroke->stroke_started && (first_modal || (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)))) + { + if ((br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) || (br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) { + copy_v2_v2(stroke->ups->last_rake, stroke->last_mouse_position); + } + paint_calculate_rake_rotation(stroke->ups, br, mouse); } - paint_calculate_rake_rotation(stroke->ups, br, sample_average.mouse); } else if (first_modal || /* regular dabs */ -- cgit v1.2.3