[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17960] branches/etch-a-ton/source/blender /src/editarmature_sketch.c: Cleaner code for gestures.
Martin Poirier
theeth at yahoo.com
Fri Dec 19 20:47:28 CET 2008
Revision: 17960
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17960
Author: theeth
Date: 2008-12-19 20:47:25 +0100 (Fri, 19 Dec 2008)
Log Message:
-----------
Cleaner code for gestures.
Command gesture (for flatten and cutout) now needs to intersect a line in two points and end in a pig tail (loop and intersect itself).
This is easier than the cross three times and self interesect once of before.
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-12-19 19:27:41 UTC (rev 17959)
+++ branches/etch-a-ton/source/blender/src/editarmature_sketch.c 2008-12-19 19:47:25 UTC (rev 17960)
@@ -140,6 +140,27 @@
int stride;
} SK_StrokeIterator;
+typedef struct SK_Gesture {
+ SK_Stroke *stk;
+ SK_Stroke *segments;
+
+ ListBase intersections;
+ ListBase self_intersections;
+
+ int nb_self_intersections;
+ int nb_intersections;
+ int nb_segments;
+} SK_Gesture;
+
+typedef int (*GestureDetectFct)(SK_Gesture*, SK_Sketch *);
+typedef void (*GestureApplyFct)(SK_Gesture*, SK_Sketch *);
+
+typedef struct SK_GestureAction {
+ char name[64];
+ GestureDetectFct detect;
+ GestureApplyFct apply;
+} SK_GestureAction;
+
SK_Sketch *GLOBAL_sketch = NULL;
SK_Point boneSnap;
@@ -156,6 +177,33 @@
SK_Point *sk_lastStrokePoint(SK_Stroke *stk);
+int sk_detectCutGesture(SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyCutGesture(SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectTrimGesture(SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyTrimGesture(SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectCommandGesture(SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyCommandGesture(SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectDeleteGesture(SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyDeleteGesture(SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectMergeGesture(SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyMergeGesture(SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectReverseGesture(SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyReverseGesture(SK_Gesture *gest, SK_Sketch *sketch);
+
+
+/******************** GESTURE ACTIONS ******************************/
+
+SK_GestureAction GESTURE_ACTIONS[] =
+ {
+ {"Cut", sk_detectCutGesture, sk_applyCutGesture},
+ {"Trim", sk_detectTrimGesture, sk_applyTrimGesture},
+ {"Command", sk_detectCommandGesture, sk_applyCommandGesture},
+ {"Delete", sk_detectDeleteGesture, sk_applyDeleteGesture},
+ {"Merge", sk_detectMergeGesture, sk_applyMergeGesture},
+ {"Reverse", sk_detectReverseGesture, sk_applyReverseGesture},
+ {"", NULL, NULL}
+ };
+
/******************** TEMPLATES UTILS *************************/
char *TEMPLATES_MENU = NULL;
@@ -2089,11 +2137,21 @@
return segments->nb_points - 1;
}
-void sk_applyCutGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+int sk_detectCutGesture(SK_Gesture *gest, SK_Sketch *sketch)
{
+ if (gest->nb_segments == 1 && gest->nb_intersections == 1)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+void sk_applyCutGesture(SK_Gesture *gest, SK_Sketch *sketch)
+{
SK_Intersection *isect;
- for (isect = list->first; isect; isect = isect->next)
+ for (isect = gest->intersections.first; isect; isect = isect->next)
{
SK_Point pt;
@@ -2105,34 +2163,35 @@
}
}
-int sk_detectTrimGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+int sk_detectTrimGesture(SK_Gesture *gest, SK_Sketch *sketch)
{
- float s1[3], s2[3];
- float angle;
+ if (gest->nb_segments == 2 && gest->nb_intersections == 1 && gest->nb_self_intersections == 0)
+ {
+ float s1[3], s2[3];
+ float angle;
+
+ VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p);
+ VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p);
+
+ angle = VecAngle2(s1, s2);
- 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;
+ if (angle > 60 && angle < 120)
+ {
+ return 1;
+ }
}
- else
- {
- return 0;
- }
+
+ return 0;
}
-void sk_applyTrimGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+void sk_applyTrimGesture(SK_Gesture *gest, SK_Sketch *sketch)
{
SK_Intersection *isect;
float trim_dir[3];
- VecSubf(trim_dir, segments->points[2].p, segments->points[1].p);
+ VecSubf(trim_dir, gest->segments->points[2].p, gest->segments->points[1].p);
- for (isect = list->first; isect; isect = isect->next)
+ for (isect = gest->intersections.first; isect; isect = isect->next)
{
SK_Point pt;
float stroke_dir[3];
@@ -2159,12 +2218,34 @@
}
}
-int sk_detectCommandGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+int sk_detectCommandGesture(SK_Gesture *gest, SK_Sketch *sketch)
{
- return 1;
+ if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 1)
+ {
+ SK_Intersection *isect, *self_isect;
+
+ /* get the the last intersection of the first pair */
+ for( isect = gest->intersections.first; isect; isect = isect->next )
+ {
+ if (isect->stroke == isect->next->stroke)
+ {
+ isect = isect->next;
+ break;
+ }
+ }
+
+ self_isect = gest->self_intersections.first;
+
+ if (isect && isect->gesture_index < self_isect->gesture_index)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
}
-void sk_applyCommandGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+void sk_applyCommandGesture(SK_Gesture *gest, SK_Sketch *sketch)
{
SK_Intersection *isect;
int command;
@@ -2172,63 +2253,55 @@
command = pupmenu("Action %t|Flatten %x1|Cut Out %x2");
if(command < 1) return;
- for (isect = list->first; isect; isect = isect->next)
+ for (isect = gest->intersections.first; isect; isect = isect->next)
{
- SK_Intersection *i2, *i3;
+ SK_Intersection *i2;
i2 = isect->next;
if (i2 && i2->stroke == isect->stroke)
{
- i3 = i2->next;
-
- if (i3 && i3->stroke == i2->stroke)
+ switch (command)
{
- switch (command)
- {
- case 1:
- sk_flattenStroke(isect->stroke, isect->before, i3->after);
- break;
- case 2:
- sk_cutoutStroke(isect->stroke, isect->after, i3->before, isect->p, i3->p);
- break;
- }
+ case 1:
+ sk_flattenStroke(isect->stroke, isect->before, i2->after);
+ break;
+ case 2:
+ sk_cutoutStroke(isect->stroke, isect->after, i2->before, isect->p, i2->p);
+ break;
+ }
- isect = i3;
- }
- else
- {
- isect = i2;
- }
+ isect = i2;
}
}
}
-int sk_detectDeleteGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+int sk_detectDeleteGesture(SK_Gesture *gest, SK_Sketch *sketch)
{
- 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 > 120)
+ if (gest->nb_segments == 2 && gest->nb_intersections == 2)
{
- return 1;
+ float s1[3], s2[3];
+ float angle;
+
+ VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p);
+ VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p);
+
+ angle = VecAngle2(s1, s2);
+
+ if (angle > 120)
+ {
+ return 1;
+ }
}
- else
- {
- return 0;
- }
+
+ return 0;
}
-void sk_applyDeleteGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+void sk_applyDeleteGesture(SK_Gesture *gest, SK_Sketch *sketch)
{
SK_Intersection *isect;
- for (isect = list->first; isect; isect = isect->next)
+ for (isect = gest->intersections.first; isect; isect = isect->next)
{
/* only delete strokes that are crossed twice */
if (isect->next && isect->next->stroke == isect->stroke)
@@ -2240,60 +2313,59 @@
}
}
-int sk_detectMergeGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+int sk_detectMergeGesture(SK_Gesture *gest, SK_Sketch *sketch)
{
- short start_val[2], end_val[2];
- short dist;
-
- project_short_noclip(gesture->points[0].p, start_val);
- project_short_noclip(gesture->points[gesture->nb_points - 1].p, end_val);
-
- dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1]));
-
- /* if gesture is a circle */
- if ( dist <= 20 )
+ if (gest->nb_segments > 2 && gest->nb_intersections == 2)
{
- SK_Intersection *isect;
+ short start_val[2], end_val[2];
+ short dist;
- /* check if it circled around an exact point */
- for (isect = list->first; isect; isect = isect->next)
+ project_short_noclip(gest->stk->points[0].p, start_val);
+ project_short_noclip(sk_lastStrokePoint(gest->stk)->p, end_val);
+
+ dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1]));
+
+ /* if gesture is a circle */
+ if ( dist <= 20 )
{
- /* only delete strokes that are crossed twice */
- if (isect->next && isect->next->stroke == isect->stroke)
+ SK_Intersection *isect;
+
+ /* check if it circled around an exact point */
+ for (isect = gest->intersections.first; isect; isect = isect->next)
{
- int start_index, end_index;
- int i;
-
- start_index = MIN2(isect->after, isect->next->after);
- end_index = MAX2(isect->before, isect->next->before);
-
- for (i = start_index; i <= end_index; i++)
+ /* only delete strokes that are crossed twice */
+ if (isect->next && isect->next->stroke == isect->stroke)
{
- if (isect->stroke->points[i].type == PT_EXACT)
+ int start_index, end_index;
+ int i;
+
+ start_index = MIN2(isect->after, isect->next->after);
+ end_index = MAX2(isect->before, isect->next->before);
+
+ for (i = start_index; i <= end_index; i++)
{
- return 1; /* at least one exact point found, stop detect here */
+ if (isect->stroke->points[i].type == PT_EXACT)
+ {
+ return 1; /* at least one exact point found, stop detect here */
+ }
}
+
+ /* skip next */
+ isect = isect->next;
}
-
- /* skip next */
- isect = isect->next;
}
}
-
- return 0;
}
- else
- {
- return 0;
- }
+
+ return 0;
}
-void sk_applyMergeGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
+void sk_applyMergeGesture(SK_Gesture *gest, SK_Sketch *sketch)
{
SK_Intersection *isect;
/* check if it circled around an exact point */
- for (isect = list->first; isect; isect = isect->next)
+ for (isect = gest->intersections.first; isect; isect = isect->next)
{
/* only merge strokes that are crossed twice */
if (isect->next && isect->next->stroke == isect->stroke)
@@ -2319,50 +2391,53 @@
}
}
-int sk_detectReverseGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list