[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17103] branches/etch-a-ton/source/blender /src/editarmature_sketch.c: Gesture recognition:

Martin Poirier theeth at yahoo.com
Sun Oct 19 00:16:43 CEST 2008


Revision: 17103
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17103
Author:   theeth
Date:     2008-10-19 00:16:42 +0200 (Sun, 19 Oct 2008)

Log Message:
-----------
Gesture recognition:
- straight segments are extracted from the strock
- Cut gesture is now on straight strokes only

Trim Gesture:
- Two segments gesture. First segment indicates where the cut is, second indicates which side to trim.

Gesture / Stroke intersection bugfix: better code to deal with perspective (this is very brute force still).

Modified Paths:
--------------
    branches/etch-a-ton/source/blender/src/editarmature_sketch.c

Modified: branches/etch-a-ton/source/blender/src/editarmature_sketch.c
===================================================================
--- branches/etch-a-ton/source/blender/src/editarmature_sketch.c	2008-10-18 18:37:58 UTC (rev 17102)
+++ branches/etch-a-ton/source/blender/src/editarmature_sketch.c	2008-10-18 22:16:42 UTC (rev 17103)
@@ -428,6 +428,11 @@
 	}
 }
 
+void sk_replaceStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
+{
+	memcpy(stk->points + n, pt, sizeof(SK_Point));
+}
+
 void sk_insertStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
 {
 	int size = stk->nb_points - n;
@@ -450,6 +455,18 @@
 	stk->nb_points++;
 }
 
+void sk_trimStroke(SK_Stroke *stk, int start, int end)
+{
+	int size = end - start + 1;
+	
+	if (start > 0)
+	{
+		memmove(stk->points, stk->points + start, size * sizeof(SK_Point));
+	}
+	
+	stk->nb_points = size;
+}
+
 /* Apply reverse Chaikin filter to simplify the polyline
  * */
 void sk_filterStroke(SK_Stroke *stk, int start, int end)
@@ -1386,15 +1403,24 @@
 				if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
 				{
 					SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
+					float ray_start[3], ray_end[3];
+					short mval[2];
 					
 					isect->start = s_i;
 					isect->end = s_i + 1;
 					isect->stroke = stk;
-
-					VecSubf(isect->p, stk->points[s_i + 1].p, stk->points[s_i].p);
-					VecMulf(isect->p, lambda);
-					VecAddf(isect->p, isect->p, stk->points[s_i].p);
 					
+					mval[0] = (short)(vi[0]);
+					mval[1] = (short)(vi[1]);
+					viewline(mval, ray_start, ray_end);
+					
+					LineIntersectLine(	stk->points[s_i].p,
+										stk->points[s_i + 1].p,
+										ray_start,
+										ray_end,
+										isect->p,
+										vi);
+					
 					BLI_addtail(list, isect);
 
 					s_added++;
@@ -1409,8 +1435,38 @@
 	return added;
 }
 
-void sk_applyCutGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list)
+int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture)
 {
+	float CORRELATION_THRESHOLD = 0.995f;
+	float *vec;
+	int i, j;
+	
+	sk_appendStrokePoint(segments, &gesture->points[0]);
+	vec = segments->points[segments->nb_points - 1].p;
+
+	for (i = 1, j = 0; i < gesture->nb_points; i++)
+	{ 
+		float n[3];
+		
+		/* Calculate normal */
+		VecSubf(n, gesture->points[i].p, vec);
+		
+		if (calcStrokeCorrelation(gesture, j, i, vec, n) < CORRELATION_THRESHOLD)
+		{
+			j = i - 1;
+			sk_appendStrokePoint(segments, &gesture->points[j]);
+			vec = segments->points[segments->nb_points - 1].p;
+			segments->points[segments->nb_points - 1].type = PT_EXACT;
+		}
+	}
+
+	sk_appendStrokePoint(segments, &gesture->points[gesture->nb_points - 1]);
+	
+	return segments->nb_points - 1;
+}
+
+void sk_applyCutGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+{
 	SK_Intersection *isect;
 	
 	for (isect = list->first; isect; isect = isect->next)
@@ -1425,22 +1481,83 @@
 	}
 }
 
+int sk_detectTrimGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+{
+	float s1[3], s2[3];
+	float angle;
+	
+	VecSubf(s1, segments->points[1].p, segments->points[0].p);
+	VecSubf(s2, segments->points[2].p, segments->points[1].p);
+	
+	angle = VecAngle2(s1, s2);
+	
+	if (angle > 60 && angle < 120)
+	{
+		return 1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+void sk_applyTrimGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+{
+	SK_Intersection *isect;
+	float trim_dir[3];
+	
+	VecSubf(trim_dir, segments->points[2].p, segments->points[1].p);
+	
+	for (isect = list->first; isect; isect = isect->next)
+	{
+		SK_Point pt;
+		float stroke_dir[3];
+		
+		pt.type = PT_EXACT;
+		pt.mode = PT_PROJECT; /* take mode from neighbouring points */
+		VECCOPY(pt.p, isect->p);
+		
+		VecSubf(stroke_dir, isect->stroke->points[isect->end].p, isect->stroke->points[isect->start].p);
+		
+		/* same direction, trim end */
+		if (Inpf(stroke_dir, trim_dir) > 0)
+		{
+			sk_replaceStrokePoint(isect->stroke, &pt, isect->end);
+			sk_trimStroke(isect->stroke, 0, isect->end);
+		}
+		/* else, trim start */
+		else
+		{
+			sk_replaceStrokePoint(isect->stroke, &pt, isect->start);
+			sk_trimStroke(isect->stroke, isect->start, isect->stroke->nb_points - 1);
+		}
+	
+	}
+}
+
 void sk_applyGesture(SK_Sketch *sketch)
 {
-	ListBase list;
-	int added;
+	ListBase intersections;
+	SK_Stroke *segments = sk_createStroke();
+	int nb_intersections, nb_segments;
 	
-	list.first = list.last = NULL;
+	intersections.first = intersections.last = NULL;
 	
-	added = sk_getIntersections(&list, sketch, sketch->gesture);
+	nb_intersections = sk_getIntersections(&intersections, sketch, sketch->gesture);
+	nb_segments = sk_getSegments(segments, sketch->gesture);
 	
 	/* detect and apply */
-	if (added == 1)
+	if (nb_segments == 1 && nb_intersections == 1)
 	{
-		sk_applyCutGesture(sketch, sketch->gesture, &list);
+		sk_applyCutGesture(sketch, sketch->gesture, &intersections, segments);
 	}
+	else if (nb_segments == 2 && nb_intersections == 1 && sk_detectTrimGesture(sketch, sketch->gesture, &intersections, segments))
+	{
+		sk_applyTrimGesture(sketch, sketch->gesture, &intersections, segments);
+	}
 	
-	BLI_freelistN(&list);
+	sk_freeStroke(segments);
+	BLI_freelistN(&intersections);
 }
 
 /********************************************/
@@ -1468,7 +1585,7 @@
 	if (mode == -1)
 	{
 		for (stk = sketch->strokes.first; stk; stk = stk->next)
-		{sk_applyGesture(sketch);
+		{
 			stk->selected = 0;
 		}
 	}
@@ -1746,7 +1863,6 @@
 			{
 				/* apply gesture here */
 				sk_applyGesture(sketch);
-				printf("FOO!\n");
 			}
 	
 			sk_freeStroke(sketch->gesture);





More information about the Bf-blender-cvs mailing list