[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