Commit: 68bc675af45bb35e671020b6de816e5b68dcb82d
Author: Sergey Sharybin
Date:   Fri Apr 4 16:43:20 2014 +0600
https://developer.blender.org/rB68bc675af45bb35e671020b6de816e5b68dcb82d

Mask spline segment slide improvement

This implements weighted slide of second handle, just the
same exact way as it works in Gimp.

===================================================================

M       source/blender/editors/mask/mask_ops.c

===================================================================

diff --git a/source/blender/editors/mask/mask_ops.c 
b/source/blender/editors/mask/mask_ops.c
index 1434542..2abfd9a 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -1016,8 +1016,8 @@ typedef struct SlideSplineCurvatureData {
        float u;
        bool accurate;
 
-       BezTriple *adjust_bezt;
-       BezTriple bezt_backup;
+       BezTriple *adjust_bezt, *other_bezt;
+       BezTriple bezt_backup, other_bezt_backup;
 
        float prev_mouse_coord[2];
        float prev_spline_coord[2];
@@ -1028,6 +1028,7 @@ typedef struct SlideSplineCurvatureData {
 static void cancel_slide_spline_curvature(SlideSplineCurvatureData *slide_data)
 {
        *slide_data->adjust_bezt = slide_data->bezt_backup;
+       *slide_data->other_bezt = slide_data->other_bezt_backup;
 }
 
 
@@ -1056,7 +1057,7 @@ static bool slide_spline_curvature_check(bContext *C, 
const wmEvent *event)
 }
 
 static SlideSplineCurvatureData *slide_spline_curvature_customdata(
-       bContext *C, wmOperator *op, const wmEvent *event)
+       bContext *C, const wmEvent *event)
 {
        const float threshold = 19;
 
@@ -1068,8 +1069,6 @@ static SlideSplineCurvatureData 
*slide_spline_curvature_customdata(
        float u, co[2];
        BezTriple *next_bezt;
 
-       (void) op;
-
        ED_mask_mouse_pos(CTX_wm_area(C), CTX_wm_region(C), event->mval, co);
 
        if (!ED_mask_find_nearest_diff_point(C, mask, co, threshold, false,
@@ -1101,13 +1100,16 @@ static SlideSplineCurvatureData 
*slide_spline_curvature_customdata(
        /* Depending to which end we're closer to adjust either left or right 
side of the spline. */
        if (u <= 0.5f) {
                slide_data->adjust_bezt = &point->bezt;
+               slide_data->other_bezt = next_bezt;
        }
        else {
                slide_data->adjust_bezt = next_bezt;
+               slide_data->other_bezt = &point->bezt;
        }
 
        /* Data needed for restoring state. */
        slide_data->bezt_backup = *slide_data->adjust_bezt;
+       slide_data->other_bezt_backup = *slide_data->other_bezt;
 
        /* Let's dont touch other side of the point for now, so set handle to 
FREE. */
        if (u < 0.5f) {
@@ -1124,11 +1126,14 @@ static SlideSplineCurvatureData 
*slide_spline_curvature_customdata(
        /* Change selection */
        ED_mask_select_toggle_all(mask, SEL_DESELECT);
        slide_data->adjust_bezt->f2 |= SELECT;
+       slide_data->other_bezt->f2 |= SELECT;
        if (u < 0.5f) {
                slide_data->adjust_bezt->f3 |= SELECT;
+               slide_data->other_bezt->f1 |= SELECT;
        }
        else {
                slide_data->adjust_bezt->f1 |= SELECT;
+               slide_data->other_bezt->f3 |= SELECT;
        }
        mask_layer->act_spline = spline;
        mask_layer->act_point = point;
@@ -1151,7 +1156,7 @@ static int slide_spline_curvature_invoke(bContext *C, 
wmOperator *op, const wmEv
                return OPERATOR_PASS_THROUGH;
        }
 
-       slide_data = slide_spline_curvature_customdata(C, op, event);
+       slide_data = slide_spline_curvature_customdata(C, event);
        if (slide_data != NULL) {
                op->customdata = slide_data;
                WM_event_add_modal_handler(C, op);
@@ -1162,6 +1167,38 @@ static int slide_spline_curvature_invoke(bContext *C, 
wmOperator *op, const wmEv
        return OPERATOR_PASS_THROUGH;
 }
 
+static void slide_spline_solve_P1(const float u,
+                                  const float B[2],
+                                  const float P0[0],
+                                  const float P2[0],
+                                  const float P3[0],
+                                  float solution[2])
+{
+       const float u2 = u * u, u3 = u * u * u;
+       const float v = 1.0f - u;
+       const float v2 = v * v, v3 = v * v * v;
+       const float inv_divider = 1.0f / (3.0f * v2 * u);
+       const float t = 3.0f * v * u2;
+       solution[0] = -(v3 * P0[0] + t * P2[0] + u3 * P3[0] - B[0]) * 
inv_divider;
+       solution[1] = -(v3 * P0[1] + t * P2[1] + u3 * P3[1] - B[1]) * 
inv_divider;
+}
+
+static void slide_spline_solve_P2(const float u,
+                                  const float B[2],
+                                  const float P0[0],
+                                  const float P1[0],
+                                  const float P3[0],
+                                  float solution[2])
+{
+       const float u2 = u * u, u3 = u * u * u;
+       const float v = 1.0f - u;
+       const float v2 = v * v, v3 = v * v * v;
+       const float inv_divider = 1.0f / (3.0f * v * u2);
+       const float t = 3.0f * v2 * u;
+       solution[0] = -(v3 * P0[0] + t * P1[0] + u3 * P3[0] - B[0]) * 
inv_divider;
+       solution[1] = -(v3 * P0[1] + t * P1[1] + u3 * P3[1] - B[1]) * 
inv_divider;
+}
+
 static int slide_spline_curvature_modal(bContext *C, wmOperator *op, const 
wmEvent *event)
 {
        SlideSplineCurvatureData *slide_data = (SlideSplineCurvatureData *) 
op->customdata;
@@ -1175,12 +1212,9 @@ static int slide_spline_curvature_modal(bContext *C, 
wmOperator *op, const wmEve
                        /* fall-through */  /* update CV position */
                case MOUSEMOVE:
                {
+                       const float margin = 0.2f;
                        float B[2], mouse_coord[2], delta[2];
                        float u = slide_data->u;
-                       float u2 = slide_data->u * slide_data->u;
-                       float u3 = slide_data->u * slide_data->u * 
slide_data->u;
-                       float v = 1.0f - slide_data->u;
-                       float v2 = v * v, v3 = v * v * v;;
 
                        /* Get coordinate spline is expected to go through. */
                        ED_mask_mouse_pos(CTX_wm_area(C), CTX_wm_region(C), 
event->mval, mouse_coord);
@@ -1193,22 +1227,66 @@ static int slide_spline_curvature_modal(bContext *C, 
wmOperator *op, const wmEve
                        copy_v2_v2(slide_data->prev_mouse_coord, mouse_coord);
 
                        if (u < 0.5f) {
-                               slide_data->adjust_bezt->vec[2][0] =
-                                       -(v3 * slide_data->P0[0] + 3.0f * v * 
u2 * slide_data->P2[0] + u3 * slide_data->P3[0] - B[0]) /
-                                       (3.0f * v2 * u);
+                               float oldP2[2];
+                               bool need_restore_P2 = false;
+
+                               if (u > margin) {
+                                       float solution[2];
+                                       float x = (u - margin) * 0.5f / (0.5f - 
margin);
+                                       float weight =  (3 * x * x - 2 * x * x 
* x);
+
+                                       slide_spline_solve_P2(u, B,
+                                                             slide_data->P0,
+                                                             slide_data->P1,
+                                                             slide_data->P3,
+                                                             solution);
+
+                                       copy_v2_v2(oldP2, slide_data->P2);
+                                       interp_v2_v2v2(slide_data->P2, 
slide_data->P2, solution, weight);
+                                       
copy_v2_v2(slide_data->other_bezt->vec[0], slide_data->P2);
+                                       need_restore_P2 = true;
+                               }
+
+                               slide_spline_solve_P1(u, B,
+                                                     slide_data->P0,
+                                                     slide_data->P2,
+                                                     slide_data->P3,
+                                                     
slide_data->adjust_bezt->vec[2]);
 
-                               slide_data->adjust_bezt->vec[2][1] =
-                                       -(v3 * slide_data->P0[1] + 3.0f * v * 
u2 * slide_data->P2[1] + u3 * slide_data->P3[1] - B[1]) /
-                                       (3.0f * v2 * u);
+                               if (need_restore_P2) {
+                                       copy_v2_v2(slide_data->P2, oldP2);
+                               }
                        }
                        else {
-                               slide_data->adjust_bezt->vec[0][0] =
-                                       -(v3 * slide_data->P0[0] + 3.0f * v2 * 
u * slide_data->P1[0] + u3 * slide_data->P3[0] - B[0]) /
-                                       (3.0f * v * u2);
+                               float oldP1[2];
+                               bool need_restore_P1 = false;
+
+                               if (u < 1.0f - margin) {
+                                       float solution[2];
+                                       float x = ((1.0f - u) - margin) * 0.5f 
/ (0.5f - margin);
+                                       float weight = 3 * x * x - 2 * x * x * 
x;
+
+                                       slide_spline_solve_P1(u, B,
+                                                             slide_data->P0,
+                                                             slide_data->P2,
+                                                             slide_data->P3,
+                                                             solution);
+
+                                       copy_v2_v2(oldP1, slide_data->P1);
+                                       interp_v2_v2v2(slide_data->P1, 
slide_data->P1, solution, weight);
+                                       
copy_v2_v2(slide_data->other_bezt->vec[2], slide_data->P1);
+                                       need_restore_P1 = true;
+                               }
+
+                               slide_spline_solve_P2(u, B,
+                                                     slide_data->P0,
+                                                     slide_data->P1,
+                                                     slide_data->P3,
+                                                     
slide_data->adjust_bezt->vec[0]);
 
-                               slide_data->adjust_bezt->vec[0][1] =
-                                       -(v3 * slide_data->P0[1] + 3.0f * v2 * 
u * slide_data->P1[1] + u3 * slide_data->P3[1] - B[1]) /
-                                       (3.0f * v * u2);
+                               if (need_restore_P1) {
+                                       copy_v2_v2(slide_data->P1, oldP1);
+                               }
                        }
 
                        WM_event_add_notifier(C, NC_MASK | NA_EDITED, 
slide_data->mask);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to