add smoothness option for contour fill

pull/1803/head
Lex Neva 2022-08-25 23:10:16 -04:00
rodzic 0ace1ce72c
commit 8cead6e3d9
4 zmienionych plików z 31 dodań i 5 usunięć

Wyświetl plik

@ -137,6 +137,20 @@ class FillStitch(EmbroideryElement):
def avoid_self_crossing(self):
return self.get_boolean_param('avoid_self_crossing', False)
@property
@param('smoothness_mm', _('Smoothness'),
tooltip=_(
'Smooth the stitch path. Smoothness limits how far the smoothed stitch path ' +
'is allowed to deviate from the original path. Hint: a lower stitchc tolerance may be needed too.'
),
type='integer',
unit='mm',
default=0,
select_items=[('fill_method', 1)],
sort_index=5)
def smoothness(self):
return self.get_float_param('smoothness_mm', 0)
@property
@param('clockwise', _('Clockwise'), type='boolean', default=True, select_items=[('fill_method', 1)], sort_index=5)
def clockwise(self):
@ -651,9 +665,11 @@ class FillStitch(EmbroideryElement):
if self.contour_strategy == 0:
stitches = contour_fill.inner_to_outer(
tree,
polygon,
self.row_spacing,
self.max_stitch_length,
self.running_stitch_tolerance,
self.smoothness,
starting_point,
self.avoid_self_crossing
)

Wyświetl plik

@ -406,11 +406,16 @@ def _find_path_inner_to_outer(tree, node, offset, starting_point, avoid_self_cro
return LineString(result_coords)
def inner_to_outer(tree, offset, stitch_length, tolerance, starting_point, avoid_self_crossing):
def inner_to_outer(tree, polygon, offset, stitch_length, tolerance, smoothness, starting_point, avoid_self_crossing):
"""Fill a shape with spirals, from innermost to outermost."""
stitch_path = _find_path_inner_to_outer(tree, 'root', offset, starting_point, avoid_self_crossing)
points = [Stitch(*point) for point in stitch_path.coords]
if smoothness > 0:
smoothed = smooth_path(points, smoothness)
points = clamp_path_to_polygon(smoothed, polygon)
stitches = running_stitch(points, stitch_length, tolerance)
return stitches

Wyświetl plik

@ -66,6 +66,7 @@ inkstitch_attribs = [
'guided_fill_strategy',
'join_style',
'avoid_self_crossing',
'smoothness_mm',
'clockwise',
'reverse',
'expand_mm',

Wyświetl plik

@ -182,13 +182,17 @@ def smooth_path(path, smoothness=100.0):
coords = _remove_duplicate_coordinates(np.array(path))
num_points = len(coords)
# splprep's s parameter seems to depend on the number of points you pass
# as per the docs, so let's normalize it.
s = round(smoothness / 100 * num_points)
# s is explained in this issue: https://github.com/scipy/scipy/issues/11916
# the smoothness parameter limits how much the smoothed path can deviate
# from the original path. The standard deviation of the distance between
# the smoothed path and the original path is equal to the smoothness.
# In practical terms, if smoothness is 1mm, then the smoothed path can be
# up to 1mm away from the original path.
s = num_points * smoothness ** 2
# .T transposes the array (for some reason splprep expects
# [[x1, x2, ...], [y1, y2, ...]]
tck, fp, ier, msg = splprep(coords.T, s=s, nest=-1, full_output=1)
tck, fp, ier, msg = splprep(coords.T, s=s, k=3, nest=-1, full_output=1)
if ier > 0:
from ..debug import debug
debug.log(f"error {ier} smoothing path: {msg}")