summaryrefslogtreecommitdiff
path: root/lib/elements
diff options
context:
space:
mode:
authorKaalleen <reni@allenka.de>2021-06-29 19:17:12 +0200
committerKaalleen <reni@allenka.de>2021-06-29 19:17:12 +0200
commitaa24b3a3a215cc536bdac94d8ace667f692ffc45 (patch)
tree98749fbc4ffbc6a06493b1066975b2b013bfc6ee /lib/elements
parentb6ce6ccd814fdbaa754c60ca69901dd1c855d8b6 (diff)
everywhere patterns
Diffstat (limited to 'lib/elements')
-rw-r--r--lib/elements/element.py48
-rw-r--r--lib/elements/satin_column.py35
2 files changed, 48 insertions, 35 deletions
diff --git a/lib/elements/element.py b/lib/elements/element.py
index 9b894d89..aa0c4795 100644
--- a/lib/elements/element.py
+++ b/lib/elements/element.py
@@ -9,6 +9,7 @@ from copy import deepcopy
import inkex
import tinycss2
from inkex import bezier
+from shapely import geometry as shgeo
from ..commands import find_commands
from ..i18n import _
@@ -330,6 +331,52 @@ class EmbroideryElement(object):
else:
return None
+ @cache
+ def get_patterns(self):
+ xpath = "./parent::svg:g/*[contains(@style, 'marker-start:url(#inkstitch-pattern-marker)')]"
+ patterns = self.node.xpath(xpath, namespaces=inkex.NSS)
+ line_strings = []
+ for pattern in patterns:
+ if pattern.tag not in EMBROIDERABLE_TAGS:
+ continue
+ d = pattern.get_path()
+ path = inkex.paths.Path(d).to_superpath()
+ path = apply_transforms(path, pattern)
+ path = self.flatten(path)
+ lines = [shgeo.LineString(p) for p in path]
+ for line in lines:
+ line_strings.append(line)
+ return shgeo.MultiLineString(line_strings)
+
+ def _apply_patterns(self, patches):
+ patterns = self.get_patterns()
+ if not patterns:
+ return patches
+
+ patch_points = []
+ for patch in patches:
+ for i, stitch in enumerate(patch.stitches):
+ patch_points.append(stitch)
+ if i == len(patch.stitches) - 1:
+ continue
+ intersection_points = self._get_pattern_points(stitch, patch.stitches[i+1], patterns)
+ for point in intersection_points:
+ patch_points.append(point)
+ patch.stitches = patch_points
+
+ def _get_pattern_points(self, first, second, patterns):
+ points = []
+ for pattern in patterns:
+ intersection = shgeo.LineString([first, second]).intersection(pattern)
+ if isinstance(intersection, shgeo.Point):
+ points.append(Point(intersection.x, intersection.y))
+ if isinstance(intersection, shgeo.MultiPoint):
+ for point in intersection:
+ points.append(Point(point.x, point.y))
+ # sort points after their distance to left
+ points.sort(key=lambda point: point.distance(first))
+ return points
+
def strip_control_points(self, subpath):
return [point for control_before, point, control_after in subpath]
@@ -362,6 +409,7 @@ class EmbroideryElement(object):
self.validate()
patches = self.to_patches(last_patch)
+ self._apply_patterns(patches)
for patch in patches:
patch.tie_modus = self.ties
diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py
index 77cb7d22..00a8500a 100644
--- a/lib/elements/satin_column.py
+++ b/lib/elements/satin_column.py
@@ -578,10 +578,6 @@ class SatinColumn(EmbroideryElement):
return SatinColumn(node)
def get_patterns(self):
- # TODO: which one is better?!?
- # All child groups of pattern
- # xpath = "./ancestor::svg:g//*[contains(@style, 'marker-start:url(#inkstitch-pattern-marker)')]"
- # Only direct siblings of pattern
xpath = "./parent::svg:g/*[contains(@style, 'marker-start:url(#inkstitch-pattern-marker)')]"
patterns = self.node.xpath(xpath, namespaces=NSS)
line_strings = []
@@ -828,20 +824,6 @@ class SatinColumn(EmbroideryElement):
return patch
- def do_pattern_satin(self, patterns):
- # elements with the attribute 'inkstitch:pattern' set to this elements id will cause extra stitches to be added
- patch = Patch(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)
- for point in self._get_pattern_points(left, right, patterns):
- patch.add_stitch(point)
- patch.add_stitch(right)
- if not i+1 >= len(sides[0]):
- for point in self._get_pattern_points(right, sides[0][i+1], patterns):
- patch.add_stitch(point)
- return patch
-
def do_split_stitch(self):
# stitches exceeding the maximum stitch length will be divided into equal parts through additional stitches
patch = Patch(color=self.color)
@@ -859,22 +841,8 @@ class SatinColumn(EmbroideryElement):
points, count = self._get_split_points(right, sides[0][i+1], count)
for point in points:
patch.add_stitch(point)
-
return patch
- def _get_pattern_points(self, left, right, patterns):
- points = []
- for pattern in patterns:
- intersection = shgeo.LineString([left, right]).intersection(pattern)
- if isinstance(intersection, shgeo.Point):
- points.append(Point(intersection.x, intersection.y))
- if isinstance(intersection, shgeo.MultiPoint):
- for point in intersection:
- points.append(Point(point.x, point.y))
- # sort points after their distance to left
- points.sort(key=lambda point: point.distance(left))
- return points
-
def _get_split_points(self, left, right, count=None):
points = []
distance = left.distance(right)
@@ -905,13 +873,10 @@ class SatinColumn(EmbroideryElement):
# zigzags sit on the contour walk underlay like rail ties on rails.
patch += self.do_zigzag_underlay()
- patterns = self.get_patterns()
if self.e_stitch:
patch += self.do_e_stitch()
elif self.split_stitch:
patch += self.do_split_stitch()
- elif self.get_patterns():
- patch += self.do_pattern_satin(patterns)
else:
patch += self.do_satin()