[fix] fix bezier when individual handles sit on points
bonus: prevent eternal while loop
This commit is contained in:
parent
963d89daf9
commit
04229fbc31
1 changed files with 68 additions and 29 deletions
97
butils.py
97
butils.py
|
@ -215,6 +215,34 @@ def calc_bezier_length(bezier_point_1, bezier_point_2, resolution=20):
|
|||
return length
|
||||
|
||||
|
||||
def get_real_beziers_and_lengths(bezier_spline_obj, resolution_factor):
|
||||
beziers = []
|
||||
lengths = []
|
||||
total_length = 0
|
||||
n_bezier_points = len(bezier_spline_obj.bezier_points)
|
||||
real_n_bezier_points = len(bezier_spline_obj.bezier_points)
|
||||
if bezier_spline_obj.use_cyclic_u:
|
||||
n_bezier_points += 1
|
||||
for i in range(0, n_bezier_points - 1):
|
||||
i_a = i % (n_bezier_points - 1)
|
||||
i_b = (i_a + 1) % real_n_bezier_points
|
||||
bezier = [
|
||||
bezier_spline_obj.bezier_points[i_a],
|
||||
bezier_spline_obj.bezier_points[i_b],
|
||||
]
|
||||
length = calc_bezier_length(
|
||||
bezier[0],
|
||||
bezier[1],
|
||||
int(bezier_spline_obj.resolution_u * resolution_factor),
|
||||
)
|
||||
total_length += length
|
||||
beziers.append(bezier)
|
||||
lengths.append(length)
|
||||
# if total_length > distance:
|
||||
# break
|
||||
return beziers, lengths, total_length
|
||||
|
||||
|
||||
def calc_point_on_bezier_spline(
|
||||
bezier_spline_obj, distance, output_tangent=False, resolution_factor=1.0
|
||||
):
|
||||
|
@ -241,6 +269,17 @@ def calc_point_on_bezier_spline(
|
|||
if distance <= 0:
|
||||
p = bezier_spline_obj.bezier_points[0]
|
||||
travel = (p.co - p.handle_left).normalized() * distance
|
||||
|
||||
# in case the handles sit on the points
|
||||
# we interpolate the travel from points of the bezier
|
||||
# if the bezier points sit on each other we have same issue
|
||||
# but that is then to be fixed in the bezier
|
||||
if p.handle_left == p.co and len(bezier_spline_obj.bezier_points) > 1:
|
||||
beziers, lengths, total_length = get_real_beziers_and_lengths(bezier_spline_obj,
|
||||
resolution_factor)
|
||||
travel_point = calc_point_on_bezier(beziers[0][1], beziers[0][0], 0.001)
|
||||
travel = travel_point.normalized() * distance
|
||||
|
||||
location = p.co + travel
|
||||
if output_tangent:
|
||||
p2 = bezier_spline_obj.bezier_points[1]
|
||||
|
@ -249,30 +288,8 @@ def calc_point_on_bezier_spline(
|
|||
else:
|
||||
return location
|
||||
|
||||
beziers = []
|
||||
lengths = []
|
||||
total_length = 0
|
||||
n_bezier_points = len(bezier_spline_obj.bezier_points)
|
||||
real_n_bezier_points = len(bezier_spline_obj.bezier_points)
|
||||
if bezier_spline_obj.use_cyclic_u:
|
||||
n_bezier_points += 1
|
||||
for i in range(0, n_bezier_points - 1):
|
||||
i_a = i % (n_bezier_points - 1)
|
||||
i_b = (i_a + 1) % real_n_bezier_points
|
||||
bezier = [
|
||||
bezier_spline_obj.bezier_points[i_a],
|
||||
bezier_spline_obj.bezier_points[i_b],
|
||||
]
|
||||
length = calc_bezier_length(
|
||||
bezier[0],
|
||||
bezier[1],
|
||||
int(bezier_spline_obj.resolution_u * resolution_factor),
|
||||
)
|
||||
total_length += length
|
||||
beziers.append(bezier)
|
||||
lengths.append(length)
|
||||
# if total_length > distance:
|
||||
# break
|
||||
beziers, lengths, total_length = get_real_beziers_and_lengths(bezier_spline_obj,
|
||||
resolution_factor)
|
||||
|
||||
iterated_distance = 0
|
||||
for i in range(0, len(beziers)):
|
||||
|
@ -290,7 +307,16 @@ def calc_point_on_bezier_spline(
|
|||
# if we are here, the point is outside the spline
|
||||
last_i = len(beziers) - 1
|
||||
p = beziers[last_i][1]
|
||||
|
||||
travel = (p.handle_right - p.co).normalized() * (distance - total_length)
|
||||
|
||||
# in case the handles sit on the points
|
||||
# we interpolate the travel from points of the bezier
|
||||
# if the bezier points sit on each other we have same issue
|
||||
# but that is then to be fixed in the bezier
|
||||
if p.handle_right == p.co and len(beziers) > 0:
|
||||
travel_point = calc_point_on_bezier(beziers[-1][1], beziers[-1][0], 0.001)
|
||||
travel = travel_point.normalized() * (distance - total_length)
|
||||
location = p.co + travel
|
||||
if output_tangent:
|
||||
tangent = calc_tangent_on_bezier(beziers[last_i][0], p, 1)
|
||||
|
@ -580,7 +606,7 @@ def update_available_fonts():
|
|||
f = abc3d_data.available_fonts.add()
|
||||
f.font_name = font_name
|
||||
f.face_name = face_name
|
||||
print(f"{__name__} added {font_name} {face_name}")
|
||||
print(f"{utils.prefix()}::update_available_fonts: {__name__} added {font_name} {face_name}")
|
||||
|
||||
|
||||
# def update_available_texts():
|
||||
|
@ -1474,26 +1500,39 @@ def set_text_on_curve(text_properties, reset_timeout_s=0.1, reset_depsgraph_n=4,
|
|||
mom, advance + glyph_advance, False, True
|
||||
)
|
||||
if psi == si:
|
||||
n_max = 100
|
||||
n = 0
|
||||
while (
|
||||
previous_location - new_location
|
||||
).length > glyph_advance and psi == si:
|
||||
).length > glyph_advance and psi == si and n < n_max:
|
||||
curve_compensation = curve_compensation - glyph_advance * 0.01
|
||||
new_location, si = calc_point_on_bezier_curve(
|
||||
tmp_new_location, si = calc_point_on_bezier_curve(
|
||||
mom,
|
||||
advance + glyph_advance + curve_compensation,
|
||||
output_tangent=False,
|
||||
output_spline_index=True,
|
||||
)
|
||||
if tmp_new_location == new_location:
|
||||
print(f"{utils.prefix()}::set_text_on_curve::compensate_curvature while loop overstaying welcome")
|
||||
break
|
||||
new_location = tmp_new_location
|
||||
n += 1
|
||||
n = 0
|
||||
while (
|
||||
previous_location - new_location
|
||||
).length < glyph_advance and psi == si:
|
||||
).length < glyph_advance and psi == si and n < n_max:
|
||||
curve_compensation = curve_compensation + glyph_advance * 0.01
|
||||
new_location, si = calc_point_on_bezier_curve(
|
||||
tmp_new_location, si = calc_point_on_bezier_curve(
|
||||
mom,
|
||||
advance + glyph_advance + curve_compensation,
|
||||
output_tangent=False,
|
||||
output_spline_index=True,
|
||||
)
|
||||
if tmp_new_location == new_location:
|
||||
print(f"{utils.prefix()}::set_text_on_curve::compensate_curvature while loop overstaying welcome")
|
||||
break
|
||||
new_location = tmp_new_location
|
||||
n += 1
|
||||
|
||||
advance = advance + glyph_advance + curve_compensation
|
||||
glyph_index += 1
|
||||
|
|
Loading…
Add table
Reference in a new issue