diff --git a/__init__.py b/__init__.py index 74424a0..7d76097 100644 --- a/__init__.py +++ b/__init__.py @@ -244,6 +244,7 @@ class ABC3D_text_properties(bpy.types.PropertyGroup): compensate_curvature: bpy.props.BoolProperty( update=update_callback, name="Compensate Curvature", + description="Fixes curvature spacing issues for simple curves, don't use on curve with tiny loops.", default=True, ) ignore_orientation: bpy.props.BoolProperty( diff --git a/butils.py b/butils.py index 431bc43..1c2be12 100644 --- a/butils.py +++ b/butils.py @@ -245,6 +245,7 @@ def calc_point_on_bezier_spline(bezier_spline_obj, def calc_point_on_bezier_curve(bezier_curve_obj, distance, output_tangent = False, + output_spline_index = False, resolution_factor = 1.0): curve = bezier_curve_obj.data @@ -254,10 +255,25 @@ def calc_point_on_bezier_curve(bezier_curve_obj, resolution = int(spline.resolution_u * resolution_factor) length = spline.calc_length(resolution=resolution) if total_length + length > distance or i == len(curve.splines) - 1: - return calc_point_on_bezier_spline(spline, - (distance - total_length), - output_tangent, - resolution_factor) + if output_spline_index and output_tangent: + # return value from c_p_o_b_s is a tuple + # so we need to append tuple + tuple + return calc_point_on_bezier_spline(spline, + (distance - total_length), + output_tangent, + resolution_factor) + (i,) + if output_spline_index and not output_tangent: + # return value from c_p_o_b_s is a location vector + # so we need to append with a comma + return calc_point_on_bezier_spline(spline, + (distance - total_length), + output_tangent, + resolution_factor), i + else: + return calc_point_on_bezier_spline(spline, + (distance - total_length), + output_tangent, + resolution_factor) total_length += length # TODO: can this fail? @@ -677,18 +693,21 @@ def set_text_on_curve(text_properties, recursive=True): advance = text_properties.offset glyph_advance = 0 is_command = False + previous_spline_index = -1 for i, c in enumerate(text_properties.text): if c == '\\': is_command = True continue + is_newline = False if is_command: if c == 'n': + is_newline = True next_line_advance = get_next_line_advance(mom, advance, glyph_advance) if advance == next_line_advance: # self.report({'INFO'}, f"would like to add new line for {text_properties.text} please") print(f"would like to add new line for {text_properties.text} please") # TODO: add a new line - advance = next_line_advance + advance = next_line_advance + text_properties.offset continue is_command = False glyph_id = c @@ -721,7 +740,9 @@ def set_text_on_curve(text_properties, recursive=True): ob.constraints["Follow Path"].forward_axis = "FORWARD_X" ob.constraints["Follow Path"].up_axis = "UP_Y" elif distribution_type == 'CALCULATE': - location, tangent = calc_point_on_bezier_curve(mom, advance, True) + location, tangent, spline_index = calc_point_on_bezier_curve(mom, advance, True, True) + if spline_index != previous_spline_index: + is_newline = True ob.location = mom.matrix_world @ (location + text_properties.translation) if not text_properties.ignore_orientation: mask = [0] @@ -754,20 +775,28 @@ def set_text_on_curve(text_properties, recursive=True): # otherwise letters will be closer together the curvier the bezier is # this could be done more efficiently, but whatever curve_compensation = 0 - if distribution_type == 'CALCULATE': + if distribution_type == 'CALCULATE' and not is_newline: if text_properties.compensate_curvature and glyph_advance > 0: - previous_location = calc_point_on_bezier_curve(mom, advance, False) - new_location = calc_point_on_bezier_curve(mom, advance + glyph_advance, False) - while (previous_location - new_location).length > glyph_advance: - curve_compensation = curve_compensation - glyph_advance * 0.01 - new_location = calc_point_on_bezier_curve(mom, advance + glyph_advance + curve_compensation, False) - while (previous_location - new_location).length < glyph_advance: - curve_compensation = curve_compensation + glyph_advance * 0.01 - new_location = calc_point_on_bezier_curve(mom, advance + glyph_advance + curve_compensation, False) + previous_location, psi = calc_point_on_bezier_curve(mom, advance, False, True) + new_location, si = calc_point_on_bezier_curve(mom, advance + glyph_advance, False, True) + if psi == si: + while (previous_location - new_location).length > glyph_advance and psi == si: + curve_compensation = curve_compensation - glyph_advance * 0.01 + new_location, si = calc_point_on_bezier_curve(mom, + advance + glyph_advance + curve_compensation, + output_tangent=False, + output_spline_index=True) + while (previous_location - new_location).length < glyph_advance and psi == si: + curve_compensation = curve_compensation + glyph_advance * 0.01 + new_location, si = calc_point_on_bezier_curve(mom, + advance + glyph_advance + curve_compensation, + output_tangent=False, + output_spline_index=True) ob.scale = (scalor, scalor, scalor) advance = advance + glyph_advance + curve_compensation + previous_spline_index = spline_index if regenerate: mom.users_collection[0].objects.link(ob)