kopia lustrzana https://github.com/inkstitch/inkstitch
add smoothness option for contour fill
rodzic
0ace1ce72c
commit
8cead6e3d9
|
@ -137,6 +137,20 @@ class FillStitch(EmbroideryElement):
|
||||||
def avoid_self_crossing(self):
|
def avoid_self_crossing(self):
|
||||||
return self.get_boolean_param('avoid_self_crossing', False)
|
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
|
@property
|
||||||
@param('clockwise', _('Clockwise'), type='boolean', default=True, select_items=[('fill_method', 1)], sort_index=5)
|
@param('clockwise', _('Clockwise'), type='boolean', default=True, select_items=[('fill_method', 1)], sort_index=5)
|
||||||
def clockwise(self):
|
def clockwise(self):
|
||||||
|
@ -651,9 +665,11 @@ class FillStitch(EmbroideryElement):
|
||||||
if self.contour_strategy == 0:
|
if self.contour_strategy == 0:
|
||||||
stitches = contour_fill.inner_to_outer(
|
stitches = contour_fill.inner_to_outer(
|
||||||
tree,
|
tree,
|
||||||
|
polygon,
|
||||||
self.row_spacing,
|
self.row_spacing,
|
||||||
self.max_stitch_length,
|
self.max_stitch_length,
|
||||||
self.running_stitch_tolerance,
|
self.running_stitch_tolerance,
|
||||||
|
self.smoothness,
|
||||||
starting_point,
|
starting_point,
|
||||||
self.avoid_self_crossing
|
self.avoid_self_crossing
|
||||||
)
|
)
|
||||||
|
|
|
@ -406,11 +406,16 @@ def _find_path_inner_to_outer(tree, node, offset, starting_point, avoid_self_cro
|
||||||
return LineString(result_coords)
|
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."""
|
"""Fill a shape with spirals, from innermost to outermost."""
|
||||||
|
|
||||||
stitch_path = _find_path_inner_to_outer(tree, 'root', offset, starting_point, avoid_self_crossing)
|
stitch_path = _find_path_inner_to_outer(tree, 'root', offset, starting_point, avoid_self_crossing)
|
||||||
points = [Stitch(*point) for point in stitch_path.coords]
|
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)
|
stitches = running_stitch(points, stitch_length, tolerance)
|
||||||
|
|
||||||
return stitches
|
return stitches
|
||||||
|
|
|
@ -66,6 +66,7 @@ inkstitch_attribs = [
|
||||||
'guided_fill_strategy',
|
'guided_fill_strategy',
|
||||||
'join_style',
|
'join_style',
|
||||||
'avoid_self_crossing',
|
'avoid_self_crossing',
|
||||||
|
'smoothness_mm',
|
||||||
'clockwise',
|
'clockwise',
|
||||||
'reverse',
|
'reverse',
|
||||||
'expand_mm',
|
'expand_mm',
|
||||||
|
|
|
@ -182,13 +182,17 @@ def smooth_path(path, smoothness=100.0):
|
||||||
coords = _remove_duplicate_coordinates(np.array(path))
|
coords = _remove_duplicate_coordinates(np.array(path))
|
||||||
num_points = len(coords)
|
num_points = len(coords)
|
||||||
|
|
||||||
# splprep's s parameter seems to depend on the number of points you pass
|
# s is explained in this issue: https://github.com/scipy/scipy/issues/11916
|
||||||
# as per the docs, so let's normalize it.
|
# the smoothness parameter limits how much the smoothed path can deviate
|
||||||
s = round(smoothness / 100 * num_points)
|
# 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
|
# .T transposes the array (for some reason splprep expects
|
||||||
# [[x1, x2, ...], [y1, y2, ...]]
|
# [[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:
|
if ier > 0:
|
||||||
from ..debug import debug
|
from ..debug import debug
|
||||||
debug.log(f"error {ier} smoothing path: {msg}")
|
debug.log(f"error {ier} smoothing path: {msg}")
|
||||||
|
|
Ładowanie…
Reference in New Issue