summaryrefslogtreecommitdiff
path: root/lib/elements/satin_column.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/elements/satin_column.py')
-rw-r--r--lib/elements/satin_column.py54
1 files changed, 47 insertions, 7 deletions
diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py
index d72680b7..1f28cb45 100644
--- a/lib/elements/satin_column.py
+++ b/lib/elements/satin_column.py
@@ -14,7 +14,7 @@ from shapely.ops import nearest_points
from ..i18n import _
from ..svg import line_strings_to_csp, point_lists_to_csp
from ..utils import Point, cache, collapse_duplicate_point, cut
-from .element import EmbroideryElement, Patch, param
+from .element import EmbroideryElement, StitchGroup, param
from .validation import ValidationError, ValidationWarning
@@ -81,6 +81,14 @@ class SatinColumn(EmbroideryElement):
return self.get_boolean_param("e_stitch")
@property
+ @param('max_stitch_length_mm',
+ _('Maximum stitch length'),
+ tooltip=_('Maximum stitch length for split stitches.'),
+ type='float', unit="mm")
+ def max_stitch_length(self):
+ return self.get_float_param("max_stitch_length_mm") or None
+
+ @property
def color(self):
return self.get_style("stroke")
@@ -708,7 +716,7 @@ class SatinColumn(EmbroideryElement):
# other.
forward, back = self.plot_points_on_rails(self.contour_underlay_stitch_length,
-self.contour_underlay_inset)
- return Patch(color=self.color, stitches=(forward + list(reversed(back))))
+ return StitchGroup(color=self.color, stitches=(forward + list(reversed(back))))
def do_center_walk(self):
# Center walk underlay is just a running stitch down and back on the
@@ -717,7 +725,7 @@ class SatinColumn(EmbroideryElement):
# Do it like contour underlay, but inset all the way to the center.
forward, back = self.plot_points_on_rails(self.center_walk_underlay_stitch_length,
-100000)
- return Patch(color=self.color, stitches=(forward + list(reversed(back))))
+ return StitchGroup(color=self.color, stitches=(forward + list(reversed(back))))
def do_zigzag_underlay(self):
# zigzag underlay, usually done at a much lower density than the
@@ -730,7 +738,7 @@ class SatinColumn(EmbroideryElement):
# "German underlay" described here:
# http://www.mrxstitch.com/underlay-what-lies-beneath-machine-embroidery/
- patch = Patch(color=self.color)
+ patch = StitchGroup(color=self.color)
sides = self.plot_points_on_rails(self.zigzag_underlay_spacing / 2.0,
-self.zigzag_underlay_inset)
@@ -756,7 +764,10 @@ class SatinColumn(EmbroideryElement):
# print >> dbg, "satin", self.zigzag_spacing, self.pull_compensation
- patch = Patch(color=self.color)
+ if self.max_stitch_length:
+ return self.do_split_stitch()
+
+ patch = StitchGroup(color=self.color)
sides = self.plot_points_on_rails(self.zigzag_spacing, self.pull_compensation)
@@ -774,7 +785,7 @@ class SatinColumn(EmbroideryElement):
# print >> dbg, "satin", self.zigzag_spacing, self.pull_compensation
- patch = Patch(color=self.color)
+ patch = StitchGroup(color=self.color)
sides = self.plot_points_on_rails(self.zigzag_spacing, self.pull_compensation)
@@ -787,6 +798,35 @@ class SatinColumn(EmbroideryElement):
return patch
+ def do_split_stitch(self):
+ # stitches exceeding the maximum stitch length will be divided into equal parts through additional stitches
+ patch = StitchGroup(color=self.color)
+ sides = self.plot_points_on_rails(self.zigzag_spacing, self.pull_compensation)
+ for i, (left, right) in enumerate(zip(*sides)):
+ patch.add_stitch(left)
+ points, count = self._get_split_points(left, right)
+ for point in points:
+ patch.add_stitch(point)
+ patch.add_stitch(right)
+ # it is possible that the way back has a different length from the first
+ # but it looks ugly if the points differ too much
+ # so let's make sure they have at least the same amount of divisions
+ if not i+1 >= len(sides[0]):
+ points, count = self._get_split_points(right, sides[0][i+1], count)
+ for point in points:
+ patch.add_stitch(point)
+ return patch
+
+ def _get_split_points(self, left, right, count=None):
+ points = []
+ distance = left.distance(right)
+ split_count = count or int(-(-distance // self.max_stitch_length))
+ for i in range(split_count):
+ line = shgeo.LineString((left, right))
+ split_point = line.interpolate((i+1)/split_count, normalized=True)
+ points.append(Point(split_point.x, split_point.y))
+ return [points, split_count]
+
def to_patches(self, last_patch):
# Stitch a variable-width satin column, zig-zagging between two paths.
@@ -794,7 +834,7 @@ class SatinColumn(EmbroideryElement):
# beziers. The boundary points between beziers serve as "checkpoints",
# allowing the user to control how the zigzags flow around corners.
- patch = Patch(color=self.color)
+ patch = StitchGroup(color=self.color)
if self.center_walk_underlay:
patch += self.do_center_walk()