diff options
| author | Lex Neva <github.com@lexneva.name> | 2019-02-15 20:51:10 -0500 |
|---|---|---|
| committer | Lex Neva <github.com@lexneva.name> | 2019-02-16 16:53:38 -0500 |
| commit | be7d0af82da95d64261351b6281153db1944c0b4 (patch) | |
| tree | 3ef502baf31583bbda92841291105443d659c532 | |
| parent | 4c7f8f32fd13cb41680efe9b9d478fab23dacfa0 (diff) | |
improve error message when trying to autofill tiny shapes
| -rw-r--r-- | lib/elements/auto_fill.py | 56 | ||||
| -rw-r--r-- | lib/exceptions.py | 2 | ||||
| -rw-r--r-- | lib/stitches/auto_fill.py | 19 |
3 files changed, 52 insertions, 25 deletions
diff --git a/lib/elements/auto_fill.py b/lib/elements/auto_fill.py index 486243ea..55292212 100644 --- a/lib/elements/auto_fill.py +++ b/lib/elements/auto_fill.py @@ -1,7 +1,9 @@ import math +import traceback from shapely import geometry as shgeo +from ..exceptions import InkstitchException from ..i18n import _ from ..stitches import auto_fill from ..utils import cache @@ -156,27 +158,41 @@ class AutoFill(Fill): starting_point = self.get_starting_point(last_patch) ending_point = self.get_ending_point() - if self.fill_underlay: - stitches.extend(auto_fill(self.underlay_shape, - self.fill_underlay_angle, - self.fill_underlay_row_spacing, - self.fill_underlay_row_spacing, - self.fill_underlay_max_stitch_length, + try: + if self.fill_underlay: + stitches.extend(auto_fill(self.underlay_shape, + self.fill_underlay_angle, + self.fill_underlay_row_spacing, + self.fill_underlay_row_spacing, + self.fill_underlay_max_stitch_length, + self.running_stitch_length, + self.staggers, + self.fill_underlay_skip_last, + starting_point)) + starting_point = stitches[-1] + + stitches.extend(auto_fill(self.fill_shape, + self.angle, + self.row_spacing, + self.end_row_spacing, + self.max_stitch_length, self.running_stitch_length, self.staggers, - self.fill_underlay_skip_last, - starting_point)) - starting_point = stitches[-1] - - stitches.extend(auto_fill(self.fill_shape, - self.angle, - self.row_spacing, - self.end_row_spacing, - self.max_stitch_length, - self.running_stitch_length, - self.staggers, - self.skip_last, - starting_point, - ending_point)) + self.skip_last, + starting_point, + ending_point)) + except InkstitchException, exc: + # for one of our exceptions, just print the message + self.fatal(_("Unable to autofill: ") + str(exc)) + except Exception, exc: + # for an uncaught exception, give a little more info so that they can create a bug report + message = "" + message += _("Error during autofill! This means that there is a problem with Ink/Stitch.") + message += "\n\n" + message += _("If you'd like to help us make Ink/Stitch better, please paste this whole message into a new issue at: https://github.com/inkstitch/inkstitch/issues/new") + message += "\n\n" + message += traceback.format_exc() + + self.fatal(message) return [Patch(stitches=stitches, color=self.color)] diff --git a/lib/exceptions.py b/lib/exceptions.py new file mode 100644 index 00000000..30e595ea --- /dev/null +++ b/lib/exceptions.py @@ -0,0 +1,2 @@ +class InkstitchException(Exception): + pass
\ No newline at end of file diff --git a/lib/stitches/auto_fill.py b/lib/stitches/auto_fill.py index c7e65473..1c0be0a0 100644 --- a/lib/stitches/auto_fill.py +++ b/lib/stitches/auto_fill.py @@ -5,13 +5,18 @@ import sys import networkx import shapely +from ..exceptions import InkstitchException from ..i18n import _ from ..utils.geometry import Point as InkstitchPoint, cut from .fill import intersect_region_with_grating, row_num, stitch_row from .running_stitch import running_stitch -class MaxQueueLengthExceeded(Exception): +class MaxQueueLengthExceeded(InkstitchException): + pass + + +class InvalidPath(InkstitchException): pass @@ -55,7 +60,7 @@ def auto_fill(shape, rows_of_segments = intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing) segments = [segment for row in rows_of_segments for segment in row] - graph = build_graph(shape, segments, angle, row_spacing) + graph = build_graph(shape, segments, angle, row_spacing, max_stitch_length) path = find_stitch_path(graph, segments, starting_point, ending_point) stitches.extend(path_to_stitches(graph, path, shape, angle, row_spacing, max_stitch_length, running_stitch_length, staggers, skip_last)) @@ -90,7 +95,7 @@ def project(shape, coords, outline_index): return outline.project(shapely.geometry.Point(*coords)) -def build_graph(shape, segments, angle, row_spacing): +def build_graph(shape, segments, angle, row_spacing, max_stitch_length): """build a graph representation of the grating segments This function builds a specialized graph (as in graph theory) that will @@ -173,8 +178,12 @@ def build_graph(shape, segments, angle, row_spacing): if i % 2 == edge_set: graph.add_edge(node1, node2, key="extra") - if not networkx.is_eulerian(graph): - raise Exception(_("Unable to autofill. This most often happens because your shape is made up of multiple sections that aren't connected.")) + if networkx.is_empty(graph) or not networkx.is_eulerian(graph): + if shape.area < max_stitch_length ** 2: + raise InvalidPath(_("This shape is so small that it cannot be filled with rows of stitches. " + "It would probably look best as a satin column or running stitch.")) + else: + raise InvalidPath(_("Cannot parse shape. This most often happens because your shape is made up of multiple sections that aren't connected.")) return graph |
