diff options
-rw-r--r-- | source/blender/blenkernel/BKE_curve.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 24 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 7 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_stroke.c | 30 |
5 files changed, 57 insertions, 6 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 9de13ce9240..3ecd472f65b 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -120,6 +120,7 @@ void BKE_curve_bevel_make(struct Scene *scene, struct Object *ob, struct ListBa const bool for_render, const bool use_render_resolution); void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride); +void BKE_curve_forward_diff_tangent_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride); void BKE_curve_rect_from_textbox(const struct Curve *cu, const struct TextBox *tb, struct rctf *r_rect); diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 34b645ea62c..09ccc3dced7 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -144,6 +144,7 @@ float paint_grid_paint_mask(const struct GridPaintMask *gpm, unsigned level, /* stroke related */ void paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, struct Brush *brush, const float mouse_pos[2]); +void paint_update_brush_rake_rotation(struct UnifiedPaintSettings *ups, struct Brush *brush, float rotation); void BKE_paint_stroke_get_average(struct Scene *scene, struct Object *ob, float stroke[3]); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 30ceaea89b8..c27460b81c0 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1384,6 +1384,30 @@ void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float } } +/* forward differencing method for first derivative of cubic bezier curve */ +void BKE_curve_forward_diff_tangent_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride) +{ + float rt0, rt1, rt2, f; + int a; + + f = 1.0f / (float)it; + + rt0 = 3.0f * (q1 - q0); + rt1 = f * (3.0f * (q3 - q0) + 9.0f * (q1 - q2)); + rt2 = 6.0f * (q0 + q2)- 12.0f * q1; + + q0 = rt0; + q1 = f * (rt1 + rt2); + q2 = 2.0f * f * rt1; + + for (a = 0; a <= it; a++) { + *p = q0; + p = (float *)(((char *)p) + stride); + q0 += q1; + q1 += q2; + } +} + static void forward_diff_bezier_cotangent(const float p0[3], const float p1[3], const float p2[3], const float p3[3], float p[3], int it, int stride) { diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 1284ffda0ff..0bda740af53 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -519,7 +519,7 @@ float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level, /* threshold to move before updating the brush rotation */ #define RAKE_THRESHHOLD 20 -static void update_brush_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, float rotation) +void paint_update_brush_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, float rotation) { if (brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) ups->brush_rotation = rotation; @@ -527,7 +527,6 @@ static void update_brush_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, ups->brush_rotation = 0.0f; if (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE) - /* here, translation contains the mouse coordinates. */ ups->brush_rotation_sec = rotation; else ups->brush_rotation_sec = 0.0f; @@ -549,12 +548,12 @@ void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, cons ups->last_rake_angle = rotation; - update_brush_rake_rotation(ups, brush, rotation); + paint_update_brush_rake_rotation(ups, brush, rotation); } /* make sure we reset here to the last rotation to avoid accumulating * values in case a random rotation is also added */ else { - update_brush_rake_rotation(ups, brush, ups->last_rake_angle); + paint_update_brush_rake_rotation(ups, brush, ups->last_rake_angle); } } else { diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 2ae544706df..d5c3e7e7fab 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -347,7 +347,8 @@ static bool paint_brush_update(bContext *C, if (!stroke->brush_init) { copy_v2_v2(ups->last_rake, mouse_init); } - else { + /* curve strokes do their own rake calculation */ + else if (!(brush->flag & BRUSH_CURVE)) { paint_calculate_rake_rotation(ups, brush, mouse_init); } } @@ -954,6 +955,7 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str Brush *br = stroke->brush; if (br->flag & BRUSH_CURVE) { + UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; const Scene *scene = CTX_data_scene(C); const float spacing = paint_space_stroke_spacing(scene, stroke, 1.0f, 1.0f); PaintCurve *pc = br->paint_curve; @@ -974,29 +976,53 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str for (i = 0; i < pc->tot_points - 1; i++, pcp++) { int j; float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2]; + float tangents[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2]; PaintCurvePoint *pcp_next = pcp + 1; + bool do_rake = false; - for (j = 0; j < 2; j++) + for (j = 0; j < 2; j++) { BKE_curve_forward_diff_bezier( pcp->bez.vec[1][j], pcp->bez.vec[2][j], pcp_next->bez.vec[0][j], pcp_next->bez.vec[1][j], data + j, PAINT_CURVE_NUM_SEGMENTS, sizeof(float[2])); + } + if ((br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) || + (br->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) + { + do_rake = true; + for (j = 0; j < 2; j++) { + BKE_curve_forward_diff_tangent_bezier( + pcp->bez.vec[1][j], + pcp->bez.vec[2][j], + pcp_next->bez.vec[0][j], + pcp_next->bez.vec[1][j], + tangents + j, PAINT_CURVE_NUM_SEGMENTS, sizeof(float[2])); + } + } for (j = 0; j < PAINT_CURVE_NUM_SEGMENTS; j++) { + float rotation = 0.0f; + if (do_rake) { + normalize_v2_v2(&tangents[2 * j], &tangents[2 * j]); + rotation = atan2f(tangents[2 * j], tangents[2 * j + 1]); + } + if (!stroke->stroke_started) { stroke->last_pressure = 1.0; copy_v2_v2(stroke->last_mouse_position, data + 2 * j); stroke->stroke_started = stroke->test_start(C, op, stroke->last_mouse_position); if (stroke->stroke_started) { + paint_update_brush_rake_rotation(ups, br, rotation); paint_brush_stroke_add_step(C, op, data + 2 * j, 1.0); paint_line_strokes_spacing(C, op, stroke, spacing, &length_residue, data + 2 * j, data + 2 * (j + 1)); } } else { + paint_update_brush_rake_rotation(ups, br, rotation); paint_line_strokes_spacing(C, op, stroke, spacing, &length_residue, data + 2 * j, data + 2 * (j + 1)); } } |