[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [47108] branches/soc-2011-tomato/source/ blender: many small improvements to adding points

Campbell Barton ideasman42 at gmail.com
Mon May 28 11:53:59 CEST 2012


Revision: 47108
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=47108
Author:   campbellbarton
Date:     2012-05-28 09:53:59 +0000 (Mon, 28 May 2012)
Log Message:
-----------
many small improvements to adding points
- splines are open by default (double ctrl+click closes them)
- adding new points can be done even when a point in the middle of the spline is selected.
- adding new points re-orients the handles of previous point. 
- fix for crash with open curve with one point only.

Workflow is Ctrl+Click about and double click to finish - works fast and gives nicer result then before.

Modified Paths:
--------------
    branches/soc-2011-tomato/source/blender/blenkernel/BKE_mask.h
    branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c
    branches/soc-2011-tomato/source/blender/editors/mask/mask_intern.h
    branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c

Modified: branches/soc-2011-tomato/source/blender/blenkernel/BKE_mask.h
===================================================================
--- branches/soc-2011-tomato/source/blender/blenkernel/BKE_mask.h	2012-05-28 09:20:04 UTC (rev 47107)
+++ branches/soc-2011-tomato/source/blender/blenkernel/BKE_mask.h	2012-05-28 09:53:59 UTC (rev 47108)
@@ -91,8 +91,10 @@
 void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene, const int do_newframe);
 void BKE_mask_parent_init(struct MaskParent *parent);
 void BKE_mask_calc_handle_adjacent_length(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point);
+void BKE_mask_calc_tangent_polyline(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point, float t[2]);
 void BKE_mask_calc_handle_point(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point);
-void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point);
+void BKE_mask_calc_handle_point_auto(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point,
+                                     const short do_recalc_length);
 void BKE_mask_get_handle_point_adjacent(struct Mask *mask, struct MaskSpline *spline, struct MaskSplinePoint *point,
                                         struct MaskSplinePoint **r_point_prev, struct MaskSplinePoint **r_point_next);
 void BKE_mask_calc_handles(struct Mask *mask);

Modified: branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c
===================================================================
--- branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c	2012-05-28 09:20:04 UTC (rev 47107)
+++ branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c	2012-05-28 09:53:59 UTC (rev 47108)
@@ -123,7 +123,7 @@
 	spline->tot_point = 1;
 
 	/* cyclic shapes are more usually used */
-	spline->flag |= MASK_SPLINE_CYCLIC;
+	// spline->flag |= MASK_SPLINE_CYCLIC; // disable because its not so nice for drawing. could be done differently
 
 	spline->weight_interp = MASK_SPLINE_INTERP_LINEAR;
 
@@ -855,7 +855,9 @@
 		next_bezt = &next_point->bezt;
 
 #if 1
-	BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0);
+	if (prev_bezt || next_bezt) {
+		BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0);
+	}
 #else
 	if (handle_type == HD_VECT) {
 		BKE_nurb_handle_calc(bezt, prev_bezt, next_bezt, 0);
@@ -922,6 +924,37 @@
 	*r_point_next = next_point;
 }
 
+/* calculates the tanget of a point by its previous and next
+ * (ignoring handles - as if its a poly line) */
+void BKE_mask_calc_tangent_polyline(Mask *mask, MaskSpline *spline, MaskSplinePoint *point, float t[2])
+{
+	float tvec_a[2], tvec_b[2];
+
+	MaskSplinePoint *prev_point, *next_point;
+
+	BKE_mask_get_handle_point_adjacent(mask, spline, point,
+	                                   &prev_point, &next_point);
+
+	if (prev_point) {
+		sub_v2_v2v2(tvec_a, point->bezt.vec[1], prev_point->bezt.vec[1]);
+		normalize_v2(tvec_a);
+	}
+	else {
+		zero_v2(tvec_a);
+	}
+
+	if (next_point) {
+		sub_v2_v2v2(tvec_b, next_point->bezt.vec[1], point->bezt.vec[1]);
+		normalize_v2(tvec_b);
+	}
+	else {
+		zero_v2(tvec_b);
+	}
+
+	add_v2_v2v2(t, tvec_a, tvec_b);
+	normalize_v2(t);
+}
+
 void BKE_mask_calc_handle_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *point)
 {
 	MaskSplinePoint *prev_point, *next_point;
@@ -945,7 +978,7 @@
 
 void BKE_mask_calc_handle_adjacent_length(Mask *mask, MaskSpline *spline, MaskSplinePoint *point)
 {
-	/* TODO! - make this aspect aware! */
+	/* TODO! - make this interpolate between siblings - not always midpoint! */
 	int   length_tot = 0;
 	float length_average = 0.0f;
 
@@ -977,11 +1010,14 @@
  *
  * Useful for giving sane defaults.
  */
-void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point)
+void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point,
+                                     const short do_recalc_length)
 {
-	/* TODO! - make this aspect aware! */
 	MaskSplinePoint *prev_point, *next_point;
 	const char h_back[2] = {point->bezt.h1, point->bezt.h2};
+	const float length_average = (do_recalc_length) ? 0.0f /* dummy value */ :
+	                                                 (len_v3v3(point->bezt.vec[0], point->bezt.vec[1]) +
+	                                                  len_v3v3(point->bezt.vec[1], point->bezt.vec[2])) / 2.0f;
 
 	BKE_mask_get_handle_point_adjacent(mask, spline, point,
 	                                   &prev_point, &next_point);
@@ -992,6 +1028,12 @@
 
 	point->bezt.h1 = h_back[0];
 	point->bezt.h2 = h_back[1];
+
+	/* preserve length by applying it back */
+	if (do_recalc_length == FALSE) {
+		enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
+		enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
+	}
 }
 
 void BKE_mask_calc_handles(Mask *mask)

Modified: branches/soc-2011-tomato/source/blender/editors/mask/mask_intern.h
===================================================================
--- branches/soc-2011-tomato/source/blender/editors/mask/mask_intern.h	2012-05-28 09:20:04 UTC (rev 47107)
+++ branches/soc-2011-tomato/source/blender/editors/mask/mask_intern.h	2012-05-28 09:53:59 UTC (rev 47108)
@@ -73,8 +73,6 @@
 
 int ED_mask_spline_select_check(struct MaskSplinePoint *points, int tot_point);
 int ED_mask_select_check(struct Mask *mask);
-void ED_mask_point_select_set(struct MaskSplinePoint *point, int action);
-void ED_mask_point_select_set_handle(struct MaskSplinePoint *point, int select);
 
 void ED_mask_select_toggle_all(struct Mask *mask, int action);
 void ED_mask_select_flush_all(struct Mask *mask);

Modified: branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c
===================================================================
--- branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c	2012-05-28 09:20:04 UTC (rev 47107)
+++ branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c	2012-05-28 09:53:59 UTC (rev 47108)
@@ -301,7 +301,7 @@
 	return FALSE;
 }
 
-static int find_nearest_diff_point(bContext *C, Mask *mask, float normal_co[2], int threshold, int feather,
+static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather,
                                    MaskObject **maskobj_r, MaskSpline **spline_r, MaskSplinePoint **point_r,
                                    float *u_r, float tangent[2])
 {
@@ -937,7 +937,7 @@
 		add_v2_v2(bezt->vec[0], vec);
 		sub_v2_v2(bezt->vec[2], vec);
 #else
-		BKE_mask_calc_handle_point_auto(mask, spline, new_point);
+		BKE_mask_calc_handle_point_auto(mask, spline, new_point, TRUE);
 		BKE_mask_calc_handle_adjacent_length(mask, spline, new_point);
 
 #endif
@@ -952,8 +952,23 @@
 
 /* **** add subdivide vertex **** */
 
-static int add_vertex_subdivide(bContext *C, Mask *mask, float co[2])
+static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index)
 {
+	MaskSplinePoint *new_point_array;
+
+	new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points");
+
+	memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1));
+	memcpy(new_point_array + point_index + 2, spline->points + point_index + 1,
+	       sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1));
+
+	MEM_freeN(spline->points);
+	spline->points = new_point_array;
+	spline->tot_point++;
+}
+
+static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2])
+{
 	MaskObject *maskobj;
 	MaskSpline *spline;
 	MaskSplinePoint *point = NULL;
@@ -961,23 +976,15 @@
 	float tangent[2];
 
 	if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &maskobj, &spline, &point, NULL, tangent)) {
-		MaskSplinePoint *new_point_array, *new_point;
+		MaskSplinePoint *new_point;
 		int point_index = point - spline->points;
 
 		ED_mask_select_toggle_all(mask, SEL_DESELECT);
 
-		new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points");
+		mask_spline_add_point_at_index(spline, point_index);
 
-		memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1));
-		memcpy(new_point_array + point_index + 2, spline->points + point_index + 1,
-		       sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1));
+		new_point = &spline->points[point_index + 1];
 
-		MEM_freeN(spline->points);
-		spline->points = new_point_array;
-		spline->tot_point++;
-
-		new_point = &new_point_array[point_index + 1];
-
 		setup_vertex_point(C, mask, spline, new_point, co, tangent, NULL, TRUE);
 
 		/* TODO - we could pass the spline! */
@@ -1036,18 +1043,121 @@
 	}
 }
 
-static int add_vertex_extrude(bContext *C, Mask *mask, float co[2])
+static int add_vertex_extrude(bContext *C, Mask *mask, const float co[2])
 {
 	MaskObject *maskobj;
 	MaskSpline *spline;
 	MaskSplinePoint *point;
 	MaskSplinePoint *new_point = NULL, *ref_point = NULL;
 
+	/* check on which side we want to add the point */
+	int point_index;
+	float tangent_point[2];
+	float tangent_co[2];
+	int do_cyclic_correct = FALSE;
+	int do_recalc_src = FALSE;  /* when extruding from endpoints only */
+	int do_prev;                /* use prev point rather then next?? */
+
 	ED_mask_select_toggle_all(mask, SEL_DESELECT);
 
 	maskobj = BKE_mask_object_active(mask);
 
 	if (!maskobj) {
+		return FALSE;
+	}
+	else {
+		finSelectedSplinePoint(maskobj, &spline, &point, TRUE);
+	}
+
+	point_index = (point - spline->points);
+
+	MASKPOINT_DESEL(point);
+
+	if ((spline->flag & MASK_SPLINE_CYCLIC) ||
+		(point_index > 0 && point_index != spline->tot_point - 1))
+	{
+		BKE_mask_calc_tangent_polyline(mask, spline, point, tangent_point);
+		sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]);
+
+		if (dot_v2v2(tangent_point, tangent_co) < 0.0f) {
+			do_prev = TRUE;
+		}
+		else {
+			do_prev = FALSE;
+		}
+	}
+	else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) {
+		do_prev = TRUE;
+		do_recalc_src = TRUE;
+	}
+	else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) {
+		do_prev = FALSE;
+		do_recalc_src = TRUE;
+	}
+	else {
+		/* should never get here */
+		BLI_assert(0);
+	}
+
+	/* use the point before the active one */
+	if (do_prev) {
+		point_index--;
+		if (point_index < 0) {
+			point_index += spline->tot_point; /* wrap index */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list