Sketching: Gesture to flip stroke (circular arc intersecting the stroke twice).
Some name cleanup.
This commit is contained in:
@@ -98,8 +98,9 @@ typedef struct SK_Intersection
|
||||
{
|
||||
struct SK_Intersection *next, *prev;
|
||||
SK_Stroke *stroke;
|
||||
int start;
|
||||
int end;
|
||||
int before;
|
||||
int after;
|
||||
int gesture_index;
|
||||
float p[3];
|
||||
} SK_Intersection;
|
||||
|
||||
@@ -499,6 +500,22 @@ void sk_removeStroke(SK_Sketch *sketch, SK_Stroke *stk)
|
||||
sk_freeStroke(stk);
|
||||
}
|
||||
|
||||
void sk_reverseStroke(SK_Stroke *stk)
|
||||
{
|
||||
SK_Point *old_points = stk->points;
|
||||
int i = 0;
|
||||
|
||||
sk_allocStrokeBuffer(stk);
|
||||
|
||||
for (i = 0; i < stk->nb_points; i++)
|
||||
{
|
||||
sk_copyPoint(stk->points + i, old_points + stk->nb_points - 1 - i);
|
||||
}
|
||||
|
||||
MEM_freeN(old_points);
|
||||
}
|
||||
|
||||
|
||||
void sk_cancelStroke(SK_Sketch *sketch)
|
||||
{
|
||||
if (sketch->active_stroke != NULL)
|
||||
@@ -1577,8 +1594,9 @@ int sk_getSelfIntersections(ListBase *list, SK_Stroke *gesture)
|
||||
{
|
||||
SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
|
||||
|
||||
isect->start = s_i;
|
||||
isect->end = g_i + 1;
|
||||
isect->gesture_index = g_i;
|
||||
isect->before = s_i;
|
||||
isect->after = s_i + 1;
|
||||
isect->stroke = gesture;
|
||||
|
||||
VecSubf(isect->p, gesture->points[s_i + 1].p, gesture->points[s_i].p);
|
||||
@@ -1632,8 +1650,9 @@ int sk_getIntersections(ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture)
|
||||
float ray_start[3], ray_end[3];
|
||||
short mval[2];
|
||||
|
||||
isect->start = s_i;
|
||||
isect->end = s_i + 1;
|
||||
isect->gesture_index = g_i;
|
||||
isect->before = s_i;
|
||||
isect->after = s_i + 1;
|
||||
isect->stroke = stk;
|
||||
|
||||
mval[0] = (short)(vi[0]);
|
||||
@@ -1703,7 +1722,7 @@ void sk_applyCutGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, S
|
||||
pt.mode = PT_PROJECT; /* take mode from neighbouring points */
|
||||
VECCOPY(pt.p, isect->p);
|
||||
|
||||
sk_insertStrokePoint(isect->stroke, &pt, isect->end);
|
||||
sk_insertStrokePoint(isect->stroke, &pt, isect->after);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1743,19 +1762,19 @@ void sk_applyTrimGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list,
|
||||
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);
|
||||
VecSubf(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].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);
|
||||
sk_replaceStrokePoint(isect->stroke, &pt, isect->after);
|
||||
sk_trimStroke(isect->stroke, 0, isect->after);
|
||||
}
|
||||
/* else, trim start */
|
||||
else
|
||||
{
|
||||
sk_replaceStrokePoint(isect->stroke, &pt, isect->start);
|
||||
sk_trimStroke(isect->stroke, isect->start, isect->stroke->nb_points - 1);
|
||||
sk_replaceStrokePoint(isect->stroke, &pt, isect->before);
|
||||
sk_trimStroke(isect->stroke, isect->before, isect->stroke->nb_points - 1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1821,8 +1840,8 @@ int sk_detectMergeGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list,
|
||||
int start_index, end_index;
|
||||
int i;
|
||||
|
||||
start_index = MIN2(isect->end, isect->next->end);
|
||||
end_index = MAX2(isect->start, isect->next->start);
|
||||
start_index = MIN2(isect->after, isect->next->after);
|
||||
end_index = MAX2(isect->before, isect->next->before);
|
||||
|
||||
for (i = start_index; i <= end_index; i++)
|
||||
{
|
||||
@@ -1852,14 +1871,14 @@ void sk_applyMergeGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list,
|
||||
/* check if it circled around an exact point */
|
||||
for (isect = list->first; isect; isect = isect->next)
|
||||
{
|
||||
/* only delete strokes that are crossed twice */
|
||||
/* only merge strokes that are crossed twice */
|
||||
if (isect->next && isect->next->stroke == isect->stroke)
|
||||
{
|
||||
int start_index, end_index;
|
||||
int i;
|
||||
|
||||
start_index = MIN2(isect->end, isect->next->end);
|
||||
end_index = MAX2(isect->start, isect->next->start);
|
||||
start_index = MIN2(isect->after, isect->next->after);
|
||||
end_index = MAX2(isect->before, isect->next->before);
|
||||
|
||||
for (i = start_index; i <= end_index; i++)
|
||||
{
|
||||
@@ -1876,6 +1895,62 @@ void sk_applyMergeGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list,
|
||||
}
|
||||
}
|
||||
|
||||
int sk_detectReverseGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
|
||||
{
|
||||
SK_Intersection *isect;
|
||||
|
||||
/* check if it circled around an exact point */
|
||||
for (isect = list->first; isect; isect = isect->next)
|
||||
{
|
||||
/* only delete strokes that are crossed twice */
|
||||
if (isect->next && isect->next->stroke == isect->stroke)
|
||||
{
|
||||
float start_v[3], end_v[3];
|
||||
float angle;
|
||||
|
||||
if (isect->gesture_index < isect->next->gesture_index)
|
||||
{
|
||||
VecSubf(start_v, isect->p, gesture->points[0].p);
|
||||
VecSubf(end_v, sk_lastStrokePoint(gesture)->p, isect->next->p);
|
||||
}
|
||||
else
|
||||
{
|
||||
VecSubf(start_v, isect->next->p, gesture->points[0].p);
|
||||
VecSubf(end_v, sk_lastStrokePoint(gesture)->p, isect->p);
|
||||
}
|
||||
|
||||
angle = VecAngle2(start_v, end_v);
|
||||
|
||||
if (angle > 120)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* skip next */
|
||||
isect = isect->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sk_applyReverseGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list, SK_Stroke *segments)
|
||||
{
|
||||
SK_Intersection *isect;
|
||||
|
||||
for (isect = list->first; isect; isect = isect->next)
|
||||
{
|
||||
/* only reverse strokes that are crossed twice */
|
||||
if (isect->next && isect->next->stroke == isect->stroke)
|
||||
{
|
||||
sk_reverseStroke(isect->stroke);
|
||||
|
||||
/* skip next */
|
||||
isect = isect->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sk_applyGesture(SK_Sketch *sketch)
|
||||
{
|
||||
ListBase intersections;
|
||||
@@ -1907,6 +1982,10 @@ void sk_applyGesture(SK_Sketch *sketch)
|
||||
{
|
||||
sk_applyMergeGesture(sketch, sketch->gesture, &intersections, segments);
|
||||
}
|
||||
else if (nb_segments > 2 && nb_intersections == 2 && sk_detectReverseGesture(sketch, sketch->gesture, &intersections, segments))
|
||||
{
|
||||
sk_applyReverseGesture(sketch, sketch->gesture, &intersections, segments);
|
||||
}
|
||||
else if (nb_segments > 2 && nb_self_intersections == 1)
|
||||
{
|
||||
sk_convert(sketch);
|
||||
@@ -1916,7 +1995,6 @@ void sk_applyGesture(SK_Sketch *sketch)
|
||||
else if (nb_segments > 2 && nb_self_intersections == 2)
|
||||
{
|
||||
sk_deleteSelectedStrokes(sketch);
|
||||
BIF_undo_push("Convert Sketch");
|
||||
}
|
||||
|
||||
sk_freeStroke(segments);
|
||||
|
||||
Reference in New Issue
Block a user