[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [46640] branches/soc-2011-tomato/source/ blender: fix for odd mask curve handle calculation

Campbell Barton ideasman42 at gmail.com
Mon May 14 21:41:28 CEST 2012


Revision: 46640
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46640
Author:   campbellbarton
Date:     2012-05-14 19:41:27 +0000 (Mon, 14 May 2012)
Log Message:
-----------
fix for odd mask curve handle calculation
- reuses auto handle calculation
- keeps handle length relate to surrounding handles

todo
- only works well when cyclic is off
- isnt aspect aware (looks like other tools are not aspect aware too)

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_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-14 17:23:37 UTC (rev 46639)
+++ branches/soc-2011-tomato/source/blender/blenkernel/BKE_mask.h	2012-05-14 19:41:27 UTC (rev 46640)
@@ -82,6 +82,12 @@
 void BKE_mask_evaluate_all_masks(struct Main *bmain, float ctime);
 void BKE_mask_update_scene(struct Main *bmain, struct Scene *scene);
 void BKE_mask_parent_init(struct MaskParent *parent);
+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,
+                                     const short do_length_match);
+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);
 
 #define MASKPOINT_ISSEL(p)  ( ((p)->bezt.f1 | (p)->bezt.f2 | (p)->bezt.f2) & SELECT)
 #define MASKPOINT_SEL(p)    { (p)->bezt.f1 |=  SELECT; (p)->bezt.f2 |=  SELECT; (p)->bezt.f3 |=  SELECT; } (void)0

Modified: branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c
===================================================================
--- branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c	2012-05-14 17:23:37 UTC (rev 46639)
+++ branches/soc-2011-tomato/source/blender/blenkernel/intern/mask.c	2012-05-14 19:41:27 UTC (rev 46640)
@@ -794,45 +794,128 @@
 	}
 }
 
-void BKE_mask_calc_handles(Mask *mask)
+void BKE_mask_get_handle_point_adjacent(Mask *UNUSED(mask), MaskSpline *spline, MaskSplinePoint *point,
+                                        MaskSplinePoint **r_point_prev, MaskSplinePoint **r_point_next)
 {
-	MaskShape *shape = mask->shapes.first;
+	MaskSplinePoint *prev_point, *next_point;
+	int i = (int)(point - spline->points);
 
-	while (shape) {
-		MaskSpline *spline = shape->splines.first;
-		int i;
+	BLI_assert(i >= i && i < spline->tot_point);
 
-		while (spline) {
-			for (i = 0; i < spline->tot_point; i++) {
-				MaskSplinePoint *point = &spline->points[i];
-				MaskSplinePoint *prev_point, *next_point;
+	if (i == 0) {
+		if (spline->flag & MASK_SPLINE_CYCLIC) {
+			prev_point = &spline->points[spline->tot_point - 1];
+		}
+		else {
+			prev_point = NULL;
+		}
+	}
+	else {
+		prev_point = point - 1;
+	}
 
-				if (i == 0) {
-					if (spline->flag & MASK_SPLINE_CYCLIC)
-						prev_point = &spline->points[spline->tot_point - 1];
-					else
-						prev_point = NULL;
-				}
-				else prev_point = point - 1;
+	if (i == spline->tot_point - 1) {
+		if (spline->flag & MASK_SPLINE_CYCLIC) {
+			next_point = &spline->points[0];
+		}
+		else {
+			next_point = NULL;
+		}
+	}
+	else {
+		next_point = point + 1;
+	}
 
-				if (i == spline->tot_point - 1) {
-					if (spline->flag & MASK_SPLINE_CYCLIC)
-						next_point = &spline->points[0];
-					else
-						next_point = NULL;
-				}
-				else next_point = point + 1;
+	*r_point_prev = prev_point;
+	*r_point_next = next_point;
+}
 
-				mask_calc_point_handle(point, prev_point, next_point);
-			}
+void BKE_mask_calc_handle_point(Mask *mask, MaskSpline *spline, MaskSplinePoint *point)
+{
+	MaskSplinePoint *prev_point, *next_point;
 
-			spline = spline->next;
+	BKE_mask_get_handle_point_adjacent(mask, spline, point,
+	                                   &prev_point, &next_point);
+
+	mask_calc_point_handle(point, prev_point, next_point);
+}
+
+static void enforce_dist_v2_v2fl(float v1[2], const float v2[2], const float dist)
+{
+	if (!equals_v2v2(v2, v1)) {
+		float nor[2];
+
+		sub_v2_v2v2(nor, v1, v2);
+		normalize_v2(nor);
+		madd_v2_v2v2fl(v1, v2, nor, dist);
+	}
+}
+
+/**
+ * \brief Resets auto handles even for non-auto bezier points
+ *
+ * Useful for giving sane defaults.
+ */
+void BKE_mask_calc_handle_point_auto(Mask *mask, MaskSpline *spline, MaskSplinePoint *point,
+                                     const short do_length_match)
+{
+	MaskSplinePoint *prev_point, *next_point;
+
+	const char h_back[2] = {point->bezt.h1, point->bezt.h2};
+
+	BKE_mask_get_handle_point_adjacent(mask, spline, point,
+	                                   &prev_point, &next_point);
+
+	point->bezt.h1 = HD_AUTO;
+	point->bezt.h2 = HD_AUTO;
+	mask_calc_point_handle(point, prev_point, next_point);
+
+	point->bezt.h1 = h_back[0];
+	point->bezt.h2 = h_back[1];
+	mask_calc_point_handle(point, prev_point, next_point);
+
+	/* TODO! - make this aspect aware! */
+	/* TODO! - not working right with cyclic curves, need to investigate! */
+	if (do_length_match) {
+		int   length_tot = 0;
+		float length_average = 0.0f;
+
+		if (prev_point) {
+			length_average += len_v2v2(prev_point->bezt.vec[0], prev_point->bezt.vec[1]);
+			length_tot++;
 		}
 
-		shape = shape->next;
+		if (next_point) {
+			length_average += len_v2v2(next_point->bezt.vec[2], next_point->bezt.vec[1]);
+			length_tot++;
+		}
+
+		if (length_tot) {
+			length_average /= (float)length_tot;
+
+			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)
+{
+	MaskShape *shape;
+
+	for (shape = mask->shapes.first; shape; shape = shape->next) {
+		MaskSpline *spline;
+
+		for (spline = shape->splines.first; spline; spline = spline->next) {
+			int i;
+
+			for (i = 0; i < spline->tot_point; i++) {
+				BKE_mask_calc_handle_point(mask, spline, &spline->points[i]);
+			}
+		}
+	}
+}
+
 void BKE_mask_evaluate(Mask *mask, float ctime)
 {
 	MaskShape *shape = mask->shapes.first;

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-14 17:23:37 UTC (rev 46639)
+++ branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c	2012-05-14 19:41:27 UTC (rev 46640)
@@ -480,9 +480,9 @@
 
 					if (feather_points)
 						MEM_freeN(feather_points);
+
+					MEM_freeN(diff_points);
 				}
-
-				MEM_freeN(diff_points);
 			}
 
 			spline = spline->next;
@@ -1148,6 +1148,9 @@
 		add_v2_v2(bezt->vec[2], vec);
 	}
 	else {
+
+		/* calculating auto handles works much nicer */
+#if 0
 		/* next points are aligning in the direction of previous/next point */
 		MaskSplinePoint *point;
 		float v1[2], v2[2], vec[2];
@@ -1192,6 +1195,11 @@
 
 		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, TRUE);
+
+#endif
+
 	}
 
 	BKE_mask_parent_init(&new_point->parent);




More information about the Bf-blender-cvs mailing list