From 190334b47df46f0e912c873077163e6129e4cbae Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 5 Apr 2022 15:24:12 +0200 Subject: Curves: new Grow/Shrink brush This adds a new Grow/Shrink brush which is similar to the Length brush in the old hair system. * It's possible to switch between growing and shrinking by hold down ctrl and/or by changing the direction enum. * 3d brush is supported. * Different brush falloffs are supported. * Supports scaling curves uniformly or shrinking/extrapolating them. Extrapolation is linear only in this patch. * A minimum length settings helps to avoid creating zero-sized curves. Differential Revision: https://developer.blender.org/D14474 --- source/blender/blenlib/intern/math_geom.c | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'source/blender/blenlib/intern') diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 1b13493e00c..e7ccdeab80a 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -294,6 +294,66 @@ float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l return sqrtf(dist_squared_to_line_segment_v2(p, l1, l2)); } +float closest_seg_seg_v2(float r_closest_a[2], + float r_closest_b[2], + float *r_lambda_a, + float *r_lambda_b, + const float a1[2], + const float a2[2], + const float b1[2], + const float b2[2]) +{ + if (isect_seg_seg_v2_simple(a1, a2, b1, b2)) { + float intersection[2]; + isect_line_line_v2_point(a1, a2, b1, b2, intersection); + copy_v2_v2(r_closest_a, intersection); + copy_v2_v2(r_closest_b, intersection); + float tmp[2]; + *r_lambda_a = closest_to_line_v2(tmp, intersection, a1, a2); + *r_lambda_b = closest_to_line_v2(tmp, intersection, b1, b2); + const float min_dist_sq = len_squared_v2v2(r_closest_a, r_closest_b); + return min_dist_sq; + } + + float p1[2], p2[2], p3[2], p4[2]; + const float lambda1 = closest_to_line_segment_v2(p1, a1, b1, b2); + const float lambda2 = closest_to_line_segment_v2(p2, a2, b1, b2); + const float lambda3 = closest_to_line_segment_v2(p3, b1, a1, a2); + const float lambda4 = closest_to_line_segment_v2(p4, b2, a1, a2); + const float dist_sq1 = len_squared_v2v2(p1, a1); + const float dist_sq2 = len_squared_v2v2(p2, a2); + const float dist_sq3 = len_squared_v2v2(p3, b1); + const float dist_sq4 = len_squared_v2v2(p4, b2); + + const float min_dist_sq = min_ffff(dist_sq1, dist_sq2, dist_sq3, dist_sq4); + if (min_dist_sq == dist_sq1) { + copy_v2_v2(r_closest_a, a1); + copy_v2_v2(r_closest_b, p1); + *r_lambda_a = 0.0f; + *r_lambda_b = lambda1; + } + else if (min_dist_sq == dist_sq2) { + copy_v2_v2(r_closest_a, a2); + copy_v2_v2(r_closest_b, p2); + *r_lambda_a = 1.0f; + *r_lambda_b = lambda2; + } + else if (min_dist_sq == dist_sq3) { + copy_v2_v2(r_closest_a, p3); + copy_v2_v2(r_closest_b, b1); + *r_lambda_a = lambda3; + *r_lambda_b = 0.0f; + } + else { + BLI_assert(min_dist_sq == dist_sq4); + copy_v2_v2(r_closest_a, p4); + copy_v2_v2(r_closest_b, b2); + *r_lambda_a = lambda4; + *r_lambda_b = 1.0f; + } + return min_dist_sq; +} + float closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], -- cgit v1.2.3