summaryrefslogtreecommitdiff
path: root/lib/elements/satin_column.py
diff options
context:
space:
mode:
authorKaalleen <36401965+kaalleen@users.noreply.github.com>2021-04-13 17:22:37 +0200
committerGitHub <noreply@github.com>2021-04-13 17:22:37 +0200
commit6af3473c96391ab58fa0746e12e99ef8b1e104ee (patch)
treeb90e0232c225771bd832fa506c829ba4a7853bdf /lib/elements/satin_column.py
parent6cef970c224f7979d57617407cb8ce7bba4644e5 (diff)
Extend Satin Rungs (#1130)
Co-authored-by: Lex Neva <github.com@lexneva.name>
Diffstat (limited to 'lib/elements/satin_column.py')
-rw-r--r--lib/elements/satin_column.py38
1 files changed, 31 insertions, 7 deletions
diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py
index 72b7ed0f..f86cc268 100644
--- a/lib/elements/satin_column.py
+++ b/lib/elements/satin_column.py
@@ -9,12 +9,13 @@ from itertools import chain
from inkex import paths
from shapely import affinity as shaffinity
from shapely import geometry as shgeo
+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 .validation import ValidationError
+from .validation import ValidationError, ValidationWarning
class SatinHasFillError(ValidationError):
@@ -52,13 +53,13 @@ class UnequalPointsError(ValidationError):
rung_message = _("Each rung should intersect both rails once.")
-class DanglingRungError(ValidationError):
+class DanglingRungWarning(ValidationWarning):
name = _("Rung doesn't intersect rails")
description = _("Satin column: A rung doesn't intersect both rails.") + " " + rung_message
class TooManyIntersectionsError(ValidationError):
- name = _("Rung intersects too many times")
+ name = _("Rungs intersects too many times")
description = _("Satin column: A rung intersects a rail more than once.") + " " + rung_message
@@ -211,6 +212,24 @@ class SatinColumn(EmbroideryElement):
@cache
def flattened_rungs(self):
"""The rungs, as LineStrings."""
+ rungs = []
+ for rung in self._raw_rungs:
+ # make sure each rung intersects both rails
+ if not rung.intersects(self.flattened_rails[0]) or not rung.intersects(self.flattened_rails[1]):
+ # the rung does not intersect both rails
+ # get nearest points on rungs
+ start = nearest_points(rung, self.flattened_rails[0])[1]
+ end = nearest_points(rung, self.flattened_rails[1])[1]
+ # extend from the nearest points just a little bit to make sure that we get an intersection
+ rung = shaffinity.scale(shgeo.LineString([start, end]), 1.01, 1.01)
+ rungs.append(rung)
+ else:
+ rungs.append(rung)
+ return tuple(rungs)
+
+ @property
+ @cache
+ def _raw_rungs(self):
return tuple(shgeo.LineString(self.flatten_subpath(rung)) for rung in self.rungs)
@property
@@ -356,6 +375,13 @@ class SatinColumn(EmbroideryElement):
return sections
+ def validation_warnings(self):
+ for rung in self._raw_rungs:
+ for rail in self.flattened_rails:
+ intersection = rung.intersection(rail)
+ if intersection.is_empty:
+ yield DanglingRungWarning(rung.interpolate(0.5, normalized=True))
+
def validation_errors(self):
# The node should have exactly two paths with no fill. Each
# path should have the same number of points, meaning that they
@@ -370,12 +396,10 @@ class SatinColumn(EmbroideryElement):
if len(self.rails[0]) != len(self.rails[1]):
yield UnequalPointsError(self.flattened_rails[0].interpolate(0.5, normalized=True))
else:
- for rung in self.flattened_rungs:
+ for rung in self._raw_rungs:
for rail in self.flattened_rails:
intersection = rung.intersection(rail)
- if intersection.is_empty:
- yield DanglingRungError(rung.interpolate(0.5, normalized=True))
- elif not isinstance(intersection, shgeo.Point):
+ if not intersection.is_empty and not isinstance(intersection, shgeo.Point):
yield TooManyIntersectionsError(rung.interpolate(0.5, normalized=True))
def reverse(self):