[Bf-blender-cvs] [68bc675] master: Mask spline segment slide improvement

Sergey Sharybin noreply at git.blender.org
Fri Apr 4 12:44:16 CEST 2014


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);




More information about the Bf-blender-cvs mailing list