GPencil: Improve Interpolate AutoFlip algorithm II

Improved the calculation of the distances and changed the variable names to make it more readable.

Still, there are some corner cases that could be not handled properly, but we keep as is to test more real drawings to analyze if the small number of corner cases needs to be fixed or not.
This commit is contained in:
Antonio Vazquez 2021-02-24 15:31:58 +01:00
parent 9243d286f4
commit 7bbf27891c
1 changed files with 43 additions and 16 deletions

View File

@ -177,44 +177,71 @@ static bool gpencil_stroke_need_flip(Depsgraph *depsgraph,
/* calculate parent matrix */
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
bGPDspoint *pt, pt_dummy_ps;
float v1a[2], v1b[2], v2a[2], v2b[2];
float v_from_start[2], v_to_start[2], v_from_end[2], v_to_end[2];
/* Line from start of strokes. */
pt = &gps_from->points[0];
gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v1a[0], &v1a[1]);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v_from_start[0], &v_from_start[1]);
pt = &gps_to->points[0];
gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v1b[0], &v1b[1]);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v_to_start[0], &v_to_start[1]);
/* Line from end of strokes. */
pt = &gps_from->points[gps_from->totpoints - 1];
gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v2a[0], &v2a[1]);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v_from_end[0], &v_from_end[1]);
pt = &gps_to->points[gps_to->totpoints - 1];
gpencil_point_to_parent_space(pt, diff_mat, &pt_dummy_ps);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v2b[0], &v2b[1]);
gpencil_point_to_xy_fl(gsc, gps_from, &pt_dummy_ps, &v_to_end[0], &v_to_end[1]);
if (isect_seg_seg_v2(v1a, v1b, v2a, v2b) == ISECT_LINE_LINE_CROSS) {
float v1[2], v2[2];
sub_v2_v2v2(v1, v1b, v1a);
sub_v2_v2v2(v2, v2b, v2a);
float angle = angle_v2v2(v1, v2);
const bool isect_lines = (isect_seg_seg_v2(v_from_start, v_to_start, v_from_end, v_to_end) ==
ISECT_LINE_LINE_CROSS);
/* If the vectors intersect or are almost parallel. */
if (isect_lines) {
/* For very sharp angles, check distance between extremes. */
float v1[2], v2[2];
sub_v2_v2v2(v1, v_to_start, v_from_start);
sub_v2_v2v2(v2, v_to_end, v_from_end);
float angle = angle_v2v2(v1, v2);
if (angle < DEG2RADF(15.0f)) {
float dist_start = len_squared_v2v2(v1a, v2a);
float dist_end = len_squared_v2v2(v1a, v2b);
if (dist_end < dist_start) {
return true;
/* Check the original stroke orientation using a point of destination stroke
* `(S)<--??-->(E) <--->`. */
float dist_start = len_squared_v2v2(v_from_start, v_to_start);
float dist_end = len_squared_v2v2(v_from_end, v_to_start);
/* Oriented with end nearer of destination stroke.
* `(S)--->(E) <--->` */
if (dist_start >= dist_end) {
dist_start = len_squared_v2v2(v_from_end, v_to_start);
dist_end = len_squared_v2v2(v_from_end, v_to_end);
/* `(S)--->(E) (E)<---(S)` */
return (dist_start >= dist_end);
}
else {
/* Oriented inversed with original stroke start near of destination stroke.
* `(E)<----(S) <--->` */
dist_start = len_squared_v2v2(v_from_start, v_to_start);
dist_end = len_squared_v2v2(v_from_start, v_to_end);
/* `(E)<---(S) (S)--->(E)` */
return (dist_start < dist_end);
}
return false;
}
return true;
}
else {
/* Check that both vectors have the same direction. */
float v1[2], v2[2];
sub_v2_v2v2(v1, v_from_end, v_from_start);
sub_v2_v2v2(v2, v_to_end, v_to_start);
if (((v1[0] > 0.0f && v2[0] < 0.0f) || (v1[0] < 0.0f && v2[0] > 0.0f)) &&
((v1[1] > 0.0f && v2[1] < 0.0f) || (v1[1] < 0.0f && v2[1] > 0.0f))) {
return true;
}
}
return false;
}