From 6a8f385d13ee77910923028e99b01c69adc9e4ba Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Wed, 19 Jun 2019 14:01:43 -0400 Subject: fix IndexError for single-path satin columns (fixes #366) --- lib/elements/satin_column.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/elements') diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py index bfa39384..4617860a 100644 --- a/lib/elements/satin_column.py +++ b/lib/elements/satin_column.py @@ -325,6 +325,9 @@ class SatinColumn(EmbroideryElement): self.fatal(_("satin column: object %s has a fill (but should not)") % node_id) if not self.rungs: + if len(self.rails) < 2: + self.fatal(_("satin column: object %(id)s has too few paths. A satin column should have at least two paths (the rails).") % dict(id=node_id)) + if len(self.rails[0]) != len(self.rails[1]): self.fatal(_("satin column: object %(id)s has two paths with an unequal number of points (%(length1)d and %(length2)d)") % dict(id=node_id, length1=len(self.rails[0]), length2=len(self.rails[1]))) -- cgit v1.2.3 From 68609cc912d76e8e51258eeea9999542cb2f0e94 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Wed, 19 Jun 2019 14:04:25 -0400 Subject: don't treat objects without stroke as SatinColumn (fixes #460) --- lib/elements/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/elements') diff --git a/lib/elements/utils.py b/lib/elements/utils.py index 87dfa877..5c71de2e 100644 --- a/lib/elements/utils.py +++ b/lib/elements/utils.py @@ -16,7 +16,7 @@ def node_to_elements(node): elif node.tag == SVG_PATH_TAG: element = EmbroideryElement(node) - if element.get_boolean_param("satin_column"): + if element.get_boolean_param("satin_column") and element.get_style("stroke"): return [SatinColumn(node)] else: elements = [] -- cgit v1.2.3 From ebb4ebb42ccc89631e6d5830460f455c86e97af7 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Wed, 19 Jun 2019 14:47:11 -0400 Subject: rework fill shape parsing code (fixes #469) --- lib/elements/fill.py | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'lib/elements') diff --git a/lib/elements/fill.py b/lib/elements/fill.py index 357adf4b..4bdfa3ff 100644 --- a/lib/elements/fill.py +++ b/lib/elements/fill.py @@ -104,34 +104,12 @@ class Fill(EmbroideryElement): @property @cache def shape(self): - poly_ary = [] - for sub_path in self.paths: - point_ary = [] - last_pt = None - for pt in sub_path: - if (last_pt is not None): - vp = (pt[0] - last_pt[0], pt[1] - last_pt[1]) - dp = math.sqrt(math.pow(vp[0], 2.0) + math.pow(vp[1], 2.0)) - # dbg.write("dp %s\n" % dp) - if (dp > 0.01): - # I think too-close points confuse shapely. - point_ary.append(pt) - last_pt = pt - else: - last_pt = pt - if len(point_ary) > 2: - poly_ary.append(point_ary) - - if not poly_ary: - self.fatal(_("shape %s is so small that it cannot be filled with stitches. Please make it bigger or delete it.") % self.node.get('id')) - # shapely's idea of "holes" are to subtract everything in the second set # from the first. So let's at least make sure the "first" thing is the # biggest path. - # TODO: actually figure out which things are holes and which are shells - poly_ary.sort(key=lambda point_list: shgeo.Polygon(point_list).area, reverse=True) - - polygon = shgeo.MultiPolygon([(poly_ary[0], poly_ary[1:])]) + paths = self.paths + paths.sort(key=lambda point_list: shgeo.Polygon(point_list).area, reverse=True) + polygon = shgeo.MultiPolygon([(paths[0], paths[1:])]) if not polygon.is_valid: self.fatal(_("shape is not valid. This can happen if the border crosses over itself.")) -- cgit v1.2.3 From 249c876ef559e8b2a614cb19caa426351fa43075 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Wed, 19 Jun 2019 15:20:43 -0400 Subject: better message for unconnected fill shapes (fixes #463) --- lib/elements/fill.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'lib/elements') diff --git a/lib/elements/fill.py b/lib/elements/fill.py index 4bdfa3ff..7ccf7b27 100644 --- a/lib/elements/fill.py +++ b/lib/elements/fill.py @@ -1,6 +1,7 @@ import math from shapely import geometry as shgeo +from shapely.validation import explain_validity from ..i18n import _ from ..stitches import legacy_fill @@ -112,7 +113,15 @@ class Fill(EmbroideryElement): polygon = shgeo.MultiPolygon([(paths[0], paths[1:])]) if not polygon.is_valid: - self.fatal(_("shape is not valid. This can happen if the border crosses over itself.")) + why = explain_validity(polygon) + + # I Wish this weren't so brittle... + if "Hole lies outside shell" in why: + self.fatal(_("this object is made up of unconnected shapes. This is not allowed because " + "Ink/Stitch doesn't know what order to stitch them in. Please break this " + "object up into separate shapes.")) + else: + self.fatal(_("shape is not valid. This can happen if the border crosses over itself.")) return polygon -- cgit v1.2.3 From 18f50a93eb50f910f9229ef20e2a620d07cc7ec4 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Sat, 22 Jun 2019 18:12:11 -0400 Subject: handle unicode node names (fixes #467) --- lib/elements/element.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/elements') diff --git a/lib/elements/element.py b/lib/elements/element.py index 10b1852a..a2658d88 100644 --- a/lib/elements/element.py +++ b/lib/elements/element.py @@ -283,5 +283,5 @@ class EmbroideryElement(object): # L10N used when showing an error message to the user such as # "Some Path (path1234): error: satin column: One or more of the rungs doesn't intersect both rails." - print >> sys.stderr, "%s: %s %s" % (name, _("error:"), message.encode("UTF-8")) + print >> sys.stderr, "%s: %s %s" % (name.encode("UTF-8"), _("error:"), message.encode("UTF-8")) sys.exit(1) -- cgit v1.2.3 From 54179d76bc4338c5089a6d826e4b36790b202e45 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Sat, 22 Jun 2019 19:05:57 -0400 Subject: fix style --- lib/elements/satin_column.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/elements') diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py index 4617860a..d3c4d3d3 100644 --- a/lib/elements/satin_column.py +++ b/lib/elements/satin_column.py @@ -326,7 +326,8 @@ class SatinColumn(EmbroideryElement): if not self.rungs: if len(self.rails) < 2: - self.fatal(_("satin column: object %(id)s has too few paths. A satin column should have at least two paths (the rails).") % dict(id=node_id)) + self.fatal(_("satin column: object %(id)s has too few paths. A satin column should have at least two paths (the rails).") % + dict(id=node_id)) if len(self.rails[0]) != len(self.rails[1]): self.fatal(_("satin column: object %(id)s has two paths with an unequal number of points (%(length1)d and %(length2)d)") % -- cgit v1.2.3 From e81e819602a3823ec344d412ba2e5213349fb2c4 Mon Sep 17 00:00:00 2001 From: Kaalleen <36401965+kaalleen@users.noreply.github.com> Date: Mon, 24 Jun 2019 18:54:43 +0200 Subject: fix unicode error message --- lib/elements/element.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/elements') diff --git a/lib/elements/element.py b/lib/elements/element.py index a2658d88..e85657cd 100644 --- a/lib/elements/element.py +++ b/lib/elements/element.py @@ -283,5 +283,6 @@ class EmbroideryElement(object): # L10N used when showing an error message to the user such as # "Some Path (path1234): error: satin column: One or more of the rungs doesn't intersect both rails." - print >> sys.stderr, "%s: %s %s" % (name.encode("UTF-8"), _("error:"), message.encode("UTF-8")) + error_msg = "%s: %s %s" % (name, _("error:"), message) + print >> sys.stderr, "%s" % (error_msg.encode("UTF-8")) sys.exit(1) -- cgit v1.2.3