diff options
| -rw-r--r-- | lib/elements/fill_stitch.py | 8 | ||||
| -rw-r--r-- | lib/stitches/tangential_fill_stitch_line_creator.py | 29 | ||||
| -rw-r--r-- | lib/stitches/tangential_fill_stitch_pattern_creator.py | 12 | ||||
| -rw-r--r-- | lib/svg/tags.py | 1 |
4 files changed, 28 insertions, 22 deletions
diff --git a/lib/elements/fill_stitch.py b/lib/elements/fill_stitch.py index bc022ab3..2f8687a1 100644 --- a/lib/elements/fill_stitch.py +++ b/lib/elements/fill_stitch.py @@ -124,6 +124,11 @@ class FillStitch(EmbroideryElement): return self.get_boolean_param('avoid_self_crossing', False) @property + @param('clockwise', _('Clockwise'), type='boolean', default=True, select_items=[('fill_method', 1), ('fill_method', 2)], sort_index=2) + def clockwise(self): + return self.get_boolean_param('clockwise', True) + + @property @param('angle', _('Angle of lines of stitches'), tooltip=_('The angle increases in a counter-clockwise direction. 0 is horizontal. Negative angles are allowed.'), @@ -580,7 +585,8 @@ class FillStitch(EmbroideryElement): self.interlaced, self.tangential_strategy, shgeo.Point(starting_point), - self.avoid_self_crossing + self.avoid_self_crossing, + self.clockwise ) path = [InkstitchPoint(*p) for p in connectedLine] stitch_group = StitchGroup( diff --git a/lib/stitches/tangential_fill_stitch_line_creator.py b/lib/stitches/tangential_fill_stitch_line_creator.py index 61598b58..78213384 100644 --- a/lib/stitches/tangential_fill_stitch_line_creator.py +++ b/lib/stitches/tangential_fill_stitch_line_creator.py @@ -8,12 +8,12 @@ from shapely.geometry.polygon import LinearRing from shapely.geometry.polygon import orient from shapely.ops import polygonize +from .running_stitch import running_stitch +from ..stitch_plan import Stitch from ..stitches import constants from ..stitches import tangential_fill_stitch_pattern_creator -from ..stitch_plan import Stitch from ..utils import DotDict - -from .running_stitch import running_stitch +from ..utils.geometry import reverse_line_string class Tree(nx.DiGraph): @@ -59,15 +59,26 @@ def take_only_valid_linear_rings(rings): return LinearRing() -def make_tree_uniform_ccw(tree): +def orient_linear_ring(ring, clockwise=True): + # Unfortunately for us, Inkscape SVGs have an inverted Y coordinate. + # Normally we don't have to care about that, but in this very specific + # case, the meaning of is_ccw is flipped. It actually tests whether + # a ring is clockwise. That makes this logic super-confusing. + if ring.is_ccw != clockwise: + return reverse_line_string(ring) + else: + return ring + + +def make_tree_uniform(tree, clockwise=True): """ Since naturally holes have the opposite point ordering than non-holes we make all lines within the tree "root" uniform (having all the same ordering direction) """ - for node in nx.dfs_preorder_nodes(tree, 'root'): - if tree.nodes[node].type == "hole": - tree.nodes[node].val = LinearRing(reversed(tree.nodes[node].val.coords)) + + for node in tree.nodes.values(): + node.val = orient_linear_ring(node.val, clockwise) # Used to define which stitching strategy shall be used @@ -116,7 +127,7 @@ def check_and_prepare_tree_for_valid_spiral(tree): def offset_poly(poly, offset, join_style, stitch_distance, min_stitch_distance, offset_by_half, strategy, starting_point, # noqa: C901 - avoid_self_crossing): + avoid_self_crossing, clockwise): """ Takes a polygon (which can have holes) as input and creates offsetted versions until the polygon is filled with these smaller offsets. @@ -275,7 +286,7 @@ def offset_poly(poly, offset, join_style, stitch_distance, min_stitch_distance, tree.nodes[previous_hole].parent = current_poly tree.add_edge(current_poly, previous_hole) - make_tree_uniform_ccw(tree) + make_tree_uniform(tree, clockwise) if strategy == StitchingStrategy.INNER_TO_OUTER: connected_line = tangential_fill_stitch_pattern_creator.connect_raster_tree_from_inner_to_outer( diff --git a/lib/stitches/tangential_fill_stitch_pattern_creator.py b/lib/stitches/tangential_fill_stitch_pattern_creator.py index 9b59fa07..2556d58c 100644 --- a/lib/stitches/tangential_fill_stitch_pattern_creator.py +++ b/lib/stitches/tangential_fill_stitch_pattern_creator.py @@ -24,7 +24,6 @@ nearest_neighbor_tuple = namedtuple( ) -@debug.time def get_nearest_points_closer_than_thresh(travel_line, next_line, threshold): """ Find the first point along travel_line that is within threshold of next_line. @@ -108,7 +107,6 @@ def create_nearest_points_list( return children_nearest_points -@debug.time def connect_raster_tree_from_inner_to_outer(tree, node, offset, stitch_distance, min_stitch_distance, starting_point, offset_by_half, avoid_self_crossing, forward=True): """ @@ -213,13 +211,6 @@ def connect_raster_tree_from_inner_to_outer(tree, node, offset, stitch_distance, return LineString(result_coords) -def orient_linear_ring(ring): - if not ring.is_ccw: - return LinearRing(reversed(ring.coords)) - else: - return ring - - def reorder_linear_ring(ring, start): distances = ring - start start_index = np.argmin(np.linalg.norm(distances, axis=1)) @@ -245,9 +236,6 @@ def interpolate_linear_rings(ring1, ring2, max_stitch_length, start=None): Return value: Path interpolated between two LinearRings, as a LineString. """ - ring1 = orient_linear_ring(ring1) - ring2 = orient_linear_ring(ring2) - # Resample the two LinearRings so that they are the same number of points # long. Then take the corresponding points in each ring and interpolate # between them, gradually going more toward ring2. diff --git a/lib/svg/tags.py b/lib/svg/tags.py index 3f412c2e..02340aa5 100644 --- a/lib/svg/tags.py +++ b/lib/svg/tags.py @@ -57,6 +57,7 @@ inkstitch_attribs = [ 'join_style', 'interlaced', 'avoid_self_crossing', + 'clockwise', 'expand_mm', 'fill_underlay', 'fill_underlay_angle', |
