From 0fcf8bb97ced8df552cd0283b4ea009b6ca42623 Mon Sep 17 00:00:00 2001 From: Andreas Date: Thu, 21 Oct 2021 16:24:40 +0200 Subject: added tangential and guided fill --- lib/stitches/fill.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index 21e35d83..4e1669e9 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -6,12 +6,11 @@ import math import shapely - -from ..stitch_plan import Stitch +from shapely.geometry.linestring import LineString from ..svg import PIXELS_PER_MM from ..utils import Point as InkstitchPoint from ..utils import cache - +from ..stitch_plan import Stitch def legacy_fill(shape, angle, row_spacing, end_row_spacing, max_stitch_length, flip, staggers, skip_last): rows_of_segments = intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing, flip) @@ -89,6 +88,65 @@ def stitch_row(stitches, beg, end, angle, row_spacing, max_stitch_length, stagge if (end - stitches[-1]).length() > 0.1 * PIXELS_PER_MM and not skip_last: stitches.append(end) +def extend_line(line, minx,maxx,miny,maxy): + line = line.simplify(0.01, False) + + upper_left = InkstitchPoint(minx, miny) + lower_right = InkstitchPoint(maxx, maxy) + length = (upper_left - lower_right).length() + + point1 = InkstitchPoint(*line.coords[0]) + point2 = InkstitchPoint(*line.coords[1]) + new_starting_point = point1-(point2-point1).unit()*length + + point3 = InkstitchPoint(*line.coords[-2]) + point4 = InkstitchPoint(*line.coords[-1]) + new_ending_point = point4+(point4-point3).unit()*length + + line = LineString([new_starting_point.as_tuple()]+line.coords[1:-1]+[new_ending_point.as_tuple()]) + + +def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing=None, flip=False): + + row_spacing = abs(row_spacing) + (minx, miny, maxx, maxy) = shape.bounds + upper_left = InkstitchPoint(minx, miny) + rows = [] + extend_line(line, minx,maxx,miny,maxy) #extend the line towards the ends to increase probability that all offsetted curves cross the shape + + line_offsetted = line + res = line_offsetted.intersection(shape) + while isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)) or (not res.is_empty and len(res.coords) > 1): + if isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)): + runs = [line_string.coords for line_string in res.geoms if (not line_string.is_empty and len(line_string.coords) > 1)] + else: + runs = [res.coords] + + runs.sort(key=lambda seg: (InkstitchPoint(*seg[0]) - upper_left).length()) + if flip: + runs.reverse() + runs = [tuple(reversed(run)) for run in runs] + + if row_spacing > 0: + rows.append(runs) + else: + rows.insert(0,runs) + line_offsetted = line_offsetted.parallel_offset(row_spacing,'left',5) + if row_spacing < 0: + line_offsetted.coords = line_offsetted.coords[::-1] + line_offsetted = line_offsetted.simplify(0.01, False) + res = line_offsetted.intersection(shape) + if row_spacing > 0 and not isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)): + if (res.is_empty or len(res.coords) == 1): + row_spacing = -row_spacing + #print("Set to right") + line_offsetted = line.parallel_offset(row_spacing,'left',5) + line_offsetted.coords = line_offsetted.coords[::-1] #using negative row spacing leads as a side effect to reversed offsetted lines - here we undo this + line_offsetted = line_offsetted.simplify(0.01, False) + res = line_offsetted.intersection(shape) + + return rows + def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=None, flip=False): # the max line length I'll need to intersect the whole shape is the diagonal -- cgit v1.2.3 From 125db3f83b3b330df757f7cc0faf6489b3cb348d Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 29 Oct 2021 16:18:22 +0200 Subject: Applied style guide --- lib/stitches/fill.py | 53 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 19 deletions(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index 4e1669e9..9a7254e2 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -12,8 +12,10 @@ from ..utils import Point as InkstitchPoint from ..utils import cache from ..stitch_plan import Stitch + def legacy_fill(shape, angle, row_spacing, end_row_spacing, max_stitch_length, flip, staggers, skip_last): - rows_of_segments = intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing, flip) + rows_of_segments = intersect_region_with_grating( + shape, angle, row_spacing, end_row_spacing, flip) groups_of_segments = pull_runs(rows_of_segments, shape, row_spacing) return [section_to_stitches(group, angle, row_spacing, max_stitch_length, staggers, skip_last) @@ -73,7 +75,8 @@ def stitch_row(stitches, beg, end, angle, row_spacing, max_stitch_length, stagge stitches.append(beg) - first_stitch = adjust_stagger(beg, angle, row_spacing, max_stitch_length, staggers) + first_stitch = adjust_stagger( + beg, angle, row_spacing, max_stitch_length, staggers) # we might have chosen our first stitch just outside this row, so move back in if (first_stitch - beg) * row_direction < 0: @@ -82,13 +85,15 @@ def stitch_row(stitches, beg, end, angle, row_spacing, max_stitch_length, stagge offset = (first_stitch - beg).length() while offset < segment_length: - stitches.append(Stitch(beg + offset * row_direction, tags=('fill_row'))) + stitches.append( + Stitch(beg + offset * row_direction, tags=('fill_row'))) offset += max_stitch_length if (end - stitches[-1]).length() > 0.1 * PIXELS_PER_MM and not skip_last: stitches.append(end) -def extend_line(line, minx,maxx,miny,maxy): + +def extend_line(line, minx, maxx, miny, maxy): line = line.simplify(0.01, False) upper_left = InkstitchPoint(minx, miny) @@ -103,26 +108,30 @@ def extend_line(line, minx,maxx,miny,maxy): point4 = InkstitchPoint(*line.coords[-1]) new_ending_point = point4+(point4-point3).unit()*length - line = LineString([new_starting_point.as_tuple()]+line.coords[1:-1]+[new_ending_point.as_tuple()]) + line = LineString([new_starting_point.as_tuple()] + + line.coords[1:-1]+[new_ending_point.as_tuple()]) def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing=None, flip=False): - + row_spacing = abs(row_spacing) (minx, miny, maxx, maxy) = shape.bounds upper_left = InkstitchPoint(minx, miny) rows = [] - extend_line(line, minx,maxx,miny,maxy) #extend the line towards the ends to increase probability that all offsetted curves cross the shape + # extend the line towards the ends to increase probability that all offsetted curves cross the shape + extend_line(line, minx, maxx, miny, maxy) line_offsetted = line res = line_offsetted.intersection(shape) while isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)) or (not res.is_empty and len(res.coords) > 1): if isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)): - runs = [line_string.coords for line_string in res.geoms if (not line_string.is_empty and len(line_string.coords) > 1)] + runs = [line_string.coords for line_string in res.geoms if ( + not line_string.is_empty and len(line_string.coords) > 1)] else: runs = [res.coords] - runs.sort(key=lambda seg: (InkstitchPoint(*seg[0]) - upper_left).length()) + runs.sort(key=lambda seg: ( + InkstitchPoint(*seg[0]) - upper_left).length()) if flip: runs.reverse() runs = [tuple(reversed(run)) for run in runs] @@ -130,8 +139,8 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing if row_spacing > 0: rows.append(runs) else: - rows.insert(0,runs) - line_offsetted = line_offsetted.parallel_offset(row_spacing,'left',5) + rows.insert(0, runs) + line_offsetted = line_offsetted.parallel_offset(row_spacing, 'left', 5) if row_spacing < 0: line_offsetted.coords = line_offsetted.coords[::-1] line_offsetted = line_offsetted.simplify(0.01, False) @@ -139,12 +148,13 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing if row_spacing > 0 and not isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)): if (res.is_empty or len(res.coords) == 1): row_spacing = -row_spacing - #print("Set to right") - line_offsetted = line.parallel_offset(row_spacing,'left',5) - line_offsetted.coords = line_offsetted.coords[::-1] #using negative row spacing leads as a side effect to reversed offsetted lines - here we undo this + # print("Set to right") + line_offsetted = line.parallel_offset(row_spacing, 'left', 5) + # using negative row spacing leads as a side effect to reversed offsetted lines - here we undo this + line_offsetted.coords = line_offsetted.coords[::-1] line_offsetted = line_offsetted.simplify(0.01, False) res = line_offsetted.intersection(shape) - + return rows @@ -174,7 +184,8 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non # angle degrees clockwise and ask for the new bounding box. The max # and min y tell me how far to go. - _, start, _, end = shapely.affinity.rotate(shape, angle, origin='center', use_radians=True).bounds + _, start, _, end = shapely.affinity.rotate( + shape, angle, origin='center', use_radians=True).bounds # convert start and end to be relative to center (simplifies things later) start -= center.y @@ -211,7 +222,8 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non runs = [res.coords] if runs: - runs.sort(key=lambda seg: (InkstitchPoint(*seg[0]) - upper_left).length()) + runs.sort(key=lambda seg: ( + InkstitchPoint(*seg[0]) - upper_left).length()) if flip: runs.reverse() @@ -220,7 +232,9 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non rows.append(runs) if end_row_spacing: - current_row_y += row_spacing + (end_row_spacing - row_spacing) * ((current_row_y - start) / height) + current_row_y += row_spacing + \ + (end_row_spacing - row_spacing) * \ + ((current_row_y - start) / height) else: current_row_y += row_spacing @@ -237,7 +251,8 @@ def section_to_stitches(group_of_segments, angle, row_spacing, max_stitch_length if (swap): (beg, end) = (end, beg) - stitch_row(stitches, beg, end, angle, row_spacing, max_stitch_length, staggers, skip_last) + stitch_row(stitches, beg, end, angle, row_spacing, + max_stitch_length, staggers, skip_last) swap = not swap -- cgit v1.2.3 From 3caaae693893354ff10472044116e623e219e633 Mon Sep 17 00:00:00 2001 From: Andreas Date: Wed, 10 Nov 2021 17:23:24 +0100 Subject: bug fixing --- lib/stitches/fill.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index 9a7254e2..55ce09a4 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -7,6 +7,7 @@ import math import shapely from shapely.geometry.linestring import LineString +from shapely.ops import linemerge from ..svg import PIXELS_PER_MM from ..utils import Point as InkstitchPoint from ..utils import cache @@ -108,7 +109,7 @@ def extend_line(line, minx, maxx, miny, maxy): point4 = InkstitchPoint(*line.coords[-1]) new_ending_point = point4+(point4-point3).unit()*length - line = LineString([new_starting_point.as_tuple()] + + return LineString([new_starting_point.as_tuple()] + line.coords[1:-1]+[new_ending_point.as_tuple()]) @@ -119,7 +120,7 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing upper_left = InkstitchPoint(minx, miny) rows = [] # extend the line towards the ends to increase probability that all offsetted curves cross the shape - extend_line(line, minx, maxx, miny, maxy) + line = extend_line(line, minx, maxx, miny, maxy) line_offsetted = line res = line_offsetted.intersection(shape) @@ -141,6 +142,17 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing else: rows.insert(0, runs) line_offsetted = line_offsetted.parallel_offset(row_spacing, 'left', 5) + if line_offsetted.geom_type == 'MultiLineString': # if we got multiple lines take the longest + lines = linemerge(line_offsetted) + lines = list(line_offsetted.geoms) + max_length = -1 + max_length_idx = -1 + for idx, subline in enumerate(lines): + if subline.length > max_length: + max_length = subline.length + max_length_idx = idx + line_offsetted = lines[max_length_idx] + if row_spacing < 0: line_offsetted.coords = line_offsetted.coords[::-1] line_offsetted = line_offsetted.simplify(0.01, False) -- cgit v1.2.3 From e15bce1401af8b80a72aa528714e5667edbd9429 Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 19 Nov 2021 19:32:29 +0100 Subject: minor changes --- lib/stitches/fill.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index 55ce09a4..01bfdc20 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -113,6 +113,19 @@ def extend_line(line, minx, maxx, miny, maxy): line.coords[1:-1]+[new_ending_point.as_tuple()]) +def repair_multiple_parallel_offset_curves(multi_line): + lines = linemerge(multi_line) + lines = list(multi_line.geoms) + max_length = -1 + max_length_idx = -1 + for idx, subline in enumerate(lines): + if subline.length > max_length: + max_length = subline.length + max_length_idx = idx + # need simplify to avoid doubled points caused by linemerge + return lines[max_length_idx].simplify(0.01, False) + + def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing=None, flip=False): row_spacing = abs(row_spacing) @@ -141,17 +154,12 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing rows.append(runs) else: rows.insert(0, runs) + # if len(runs) > 1: + # print("HIERRRR!") line_offsetted = line_offsetted.parallel_offset(row_spacing, 'left', 5) if line_offsetted.geom_type == 'MultiLineString': # if we got multiple lines take the longest - lines = linemerge(line_offsetted) - lines = list(line_offsetted.geoms) - max_length = -1 - max_length_idx = -1 - for idx, subline in enumerate(lines): - if subline.length > max_length: - max_length = subline.length - max_length_idx = idx - line_offsetted = lines[max_length_idx] + line_offsetted = repair_multiple_parallel_offset_curves( + line_offsetted) if row_spacing < 0: line_offsetted.coords = line_offsetted.coords[::-1] @@ -162,10 +170,15 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing row_spacing = -row_spacing # print("Set to right") line_offsetted = line.parallel_offset(row_spacing, 'left', 5) + if line_offsetted.geom_type == 'MultiLineString': # if we got multiple lines take the longest + line_offsetted = repair_multiple_parallel_offset_curves( + line_offsetted) # using negative row spacing leads as a side effect to reversed offsetted lines - here we undo this line_offsetted.coords = line_offsetted.coords[::-1] line_offsetted = line_offsetted.simplify(0.01, False) res = line_offsetted.intersection(shape) + # if res.geom_type != 'LineString': + # print("HIER!!") return rows -- cgit v1.2.3 From d445b38629a902f6c13565a83ed81a91b6458480 Mon Sep 17 00:00:00 2001 From: Andreas Date: Sun, 21 Nov 2021 12:44:06 +0100 Subject: bug fixing+first spiral implementation --- lib/stitches/fill.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index 01bfdc20..5afcb228 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -7,7 +7,7 @@ import math import shapely from shapely.geometry.linestring import LineString -from shapely.ops import linemerge +from shapely.ops import linemerge, unary_union from ..svg import PIXELS_PER_MM from ..utils import Point as InkstitchPoint from ..utils import cache @@ -126,12 +126,34 @@ def repair_multiple_parallel_offset_curves(multi_line): return lines[max_length_idx].simplify(0.01, False) +def repair_non_simple_lines(line): + repaired = unary_union(line) + counter = 0 + # Do several iterations since we might have several concatenated selfcrossings + while repaired.geom_type != 'LineString' and counter < 4: + line_segments = [] + for line_seg in repaired.geoms: + if not line_seg.is_ring: + line_segments.append(line_seg) + + repaired = unary_union(linemerge(line_segments)) + counter += 1 + if repaired.geom_type != 'LineString': + raise ValueError( + "Guide line (or offsetted instance) is self crossing!") + else: + return repaired + + def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing=None, flip=False): row_spacing = abs(row_spacing) (minx, miny, maxx, maxy) = shape.bounds upper_left = InkstitchPoint(minx, miny) rows = [] + + if line.geom_type != 'LineString' or not line.is_simple: + line = repair_non_simple_lines(line) # extend the line towards the ends to increase probability that all offsetted curves cross the shape line = extend_line(line, minx, maxx, miny, maxy) @@ -160,6 +182,8 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing if line_offsetted.geom_type == 'MultiLineString': # if we got multiple lines take the longest line_offsetted = repair_multiple_parallel_offset_curves( line_offsetted) + if not line_offsetted.is_simple: + line_offsetted = repair_non_simple_lines(line_offsetted) if row_spacing < 0: line_offsetted.coords = line_offsetted.coords[::-1] @@ -173,6 +197,8 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing if line_offsetted.geom_type == 'MultiLineString': # if we got multiple lines take the longest line_offsetted = repair_multiple_parallel_offset_curves( line_offsetted) + if not line_offsetted.is_simple: + line_offsetted = repair_non_simple_lines(line_offsetted) # using negative row spacing leads as a side effect to reversed offsetted lines - here we undo this line_offsetted.coords = line_offsetted.coords[::-1] line_offsetted = line_offsetted.simplify(0.01, False) -- cgit v1.2.3 From 82216b184c669d6dea26672e5c0771146e62ca39 Mon Sep 17 00:00:00 2001 From: Kaalleen Date: Sat, 29 Jan 2022 09:53:50 +0100 Subject: remove some pattern and marker mixups and some style issues --- lib/stitches/fill.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index 5afcb228..ceac56d9 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -145,7 +145,7 @@ def repair_non_simple_lines(line): return repaired -def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing=None, flip=False): +def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing=None, flip=False): # noqa: C901 row_spacing = abs(row_spacing) (minx, miny, maxx, maxy) = shape.bounds -- cgit v1.2.3 From d514eac81937bb64815239dd3aa96e38d6556a32 Mon Sep 17 00:00:00 2001 From: Andreas Date: Wed, 2 Feb 2022 21:19:31 +0100 Subject: adjusting namings --- lib/stitches/fill.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index ceac56d9..b5f86641 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -176,8 +176,7 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing rows.append(runs) else: rows.insert(0, runs) - # if len(runs) > 1: - # print("HIERRRR!") + line_offsetted = line_offsetted.parallel_offset(row_spacing, 'left', 5) if line_offsetted.geom_type == 'MultiLineString': # if we got multiple lines take the longest line_offsetted = repair_multiple_parallel_offset_curves( @@ -192,7 +191,7 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing if row_spacing > 0 and not isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)): if (res.is_empty or len(res.coords) == 1): row_spacing = -row_spacing - # print("Set to right") + line_offsetted = line.parallel_offset(row_spacing, 'left', 5) if line_offsetted.geom_type == 'MultiLineString': # if we got multiple lines take the longest line_offsetted = repair_multiple_parallel_offset_curves( @@ -203,8 +202,7 @@ def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing line_offsetted.coords = line_offsetted.coords[::-1] line_offsetted = line_offsetted.simplify(0.01, False) res = line_offsetted.intersection(shape) - # if res.geom_type != 'LineString': - # print("HIER!!") + return rows -- cgit v1.2.3 From 515ed3ea2fc8357482527d6e4a170db154baa205 Mon Sep 17 00:00:00 2001 From: Kaalleen Date: Fri, 18 Feb 2022 15:36:01 +0100 Subject: separate guided fill methods --- lib/stitches/fill.py | 117 +-------------------------------------------------- 1 file changed, 2 insertions(+), 115 deletions(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index b5f86641..1fdc6fac 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -6,8 +6,8 @@ import math import shapely -from shapely.geometry.linestring import LineString -from shapely.ops import linemerge, unary_union + +from ..stitch_plan import Stitch from ..svg import PIXELS_PER_MM from ..utils import Point as InkstitchPoint from ..utils import cache @@ -94,119 +94,6 @@ def stitch_row(stitches, beg, end, angle, row_spacing, max_stitch_length, stagge stitches.append(end) -def extend_line(line, minx, maxx, miny, maxy): - line = line.simplify(0.01, False) - - upper_left = InkstitchPoint(minx, miny) - lower_right = InkstitchPoint(maxx, maxy) - length = (upper_left - lower_right).length() - - point1 = InkstitchPoint(*line.coords[0]) - point2 = InkstitchPoint(*line.coords[1]) - new_starting_point = point1-(point2-point1).unit()*length - - point3 = InkstitchPoint(*line.coords[-2]) - point4 = InkstitchPoint(*line.coords[-1]) - new_ending_point = point4+(point4-point3).unit()*length - - return LineString([new_starting_point.as_tuple()] + - line.coords[1:-1]+[new_ending_point.as_tuple()]) - - -def repair_multiple_parallel_offset_curves(multi_line): - lines = linemerge(multi_line) - lines = list(multi_line.geoms) - max_length = -1 - max_length_idx = -1 - for idx, subline in enumerate(lines): - if subline.length > max_length: - max_length = subline.length - max_length_idx = idx - # need simplify to avoid doubled points caused by linemerge - return lines[max_length_idx].simplify(0.01, False) - - -def repair_non_simple_lines(line): - repaired = unary_union(line) - counter = 0 - # Do several iterations since we might have several concatenated selfcrossings - while repaired.geom_type != 'LineString' and counter < 4: - line_segments = [] - for line_seg in repaired.geoms: - if not line_seg.is_ring: - line_segments.append(line_seg) - - repaired = unary_union(linemerge(line_segments)) - counter += 1 - if repaired.geom_type != 'LineString': - raise ValueError( - "Guide line (or offsetted instance) is self crossing!") - else: - return repaired - - -def intersect_region_with_grating_line(shape, line, row_spacing, end_row_spacing=None, flip=False): # noqa: C901 - - row_spacing = abs(row_spacing) - (minx, miny, maxx, maxy) = shape.bounds - upper_left = InkstitchPoint(minx, miny) - rows = [] - - if line.geom_type != 'LineString' or not line.is_simple: - line = repair_non_simple_lines(line) - # extend the line towards the ends to increase probability that all offsetted curves cross the shape - line = extend_line(line, minx, maxx, miny, maxy) - - line_offsetted = line - res = line_offsetted.intersection(shape) - while isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)) or (not res.is_empty and len(res.coords) > 1): - if isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)): - runs = [line_string.coords for line_string in res.geoms if ( - not line_string.is_empty and len(line_string.coords) > 1)] - else: - runs = [res.coords] - - runs.sort(key=lambda seg: ( - InkstitchPoint(*seg[0]) - upper_left).length()) - if flip: - runs.reverse() - runs = [tuple(reversed(run)) for run in runs] - - if row_spacing > 0: - rows.append(runs) - else: - rows.insert(0, runs) - - line_offsetted = line_offsetted.parallel_offset(row_spacing, 'left', 5) - if line_offsetted.geom_type == 'MultiLineString': # if we got multiple lines take the longest - line_offsetted = repair_multiple_parallel_offset_curves( - line_offsetted) - if not line_offsetted.is_simple: - line_offsetted = repair_non_simple_lines(line_offsetted) - - if row_spacing < 0: - line_offsetted.coords = line_offsetted.coords[::-1] - line_offsetted = line_offsetted.simplify(0.01, False) - res = line_offsetted.intersection(shape) - if row_spacing > 0 and not isinstance(res, (shapely.geometry.GeometryCollection, shapely.geometry.MultiLineString)): - if (res.is_empty or len(res.coords) == 1): - row_spacing = -row_spacing - - line_offsetted = line.parallel_offset(row_spacing, 'left', 5) - if line_offsetted.geom_type == 'MultiLineString': # if we got multiple lines take the longest - line_offsetted = repair_multiple_parallel_offset_curves( - line_offsetted) - if not line_offsetted.is_simple: - line_offsetted = repair_non_simple_lines(line_offsetted) - # using negative row spacing leads as a side effect to reversed offsetted lines - here we undo this - line_offsetted.coords = line_offsetted.coords[::-1] - line_offsetted = line_offsetted.simplify(0.01, False) - res = line_offsetted.intersection(shape) - - - return rows - - def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=None, flip=False): # the max line length I'll need to intersect the whole shape is the diagonal (minx, miny, maxx, maxy) = shape.bounds -- cgit v1.2.3 From bd8cb0d1ff2ce1f17ed8d3a5eaca19f8e8652ad0 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Mon, 2 May 2022 14:38:33 -0400 Subject: use running_stitch instead for guided fill --- lib/stitches/fill.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index 1fdc6fac..a09b93b1 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -136,8 +136,6 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non # fill regions at the same angle and spacing always line up nicely. start -= (start + normal * center) % row_spacing - rows = [] - current_row_y = start while current_row_y < end: @@ -165,7 +163,7 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non runs.reverse() runs = [tuple(reversed(run)) for run in runs] - rows.append(runs) + yield from runs if end_row_spacing: current_row_y += row_spacing + \ @@ -174,8 +172,6 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non else: current_row_y += row_spacing - return rows - def section_to_stitches(group_of_segments, angle, row_spacing, max_stitch_length, staggers, skip_last): stitches = [] -- cgit v1.2.3 From e65aaebbcab1ca6fbcf99d9f3665af423e02c2f5 Mon Sep 17 00:00:00 2001 From: Kaalleen Date: Wed, 4 May 2022 20:04:39 +0200 Subject: rebase corrections --- lib/stitches/fill.py | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index a09b93b1..94df3f77 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -11,7 +11,6 @@ from ..stitch_plan import Stitch from ..svg import PIXELS_PER_MM from ..utils import Point as InkstitchPoint from ..utils import cache -from ..stitch_plan import Stitch def legacy_fill(shape, angle, row_spacing, end_row_spacing, max_stitch_length, flip, staggers, skip_last): -- cgit v1.2.3 From a275d49a24dc91b734c6dbee1e29157bfd0d59d5 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Thu, 5 May 2022 22:53:31 -0400 Subject: tangential->contour, fix legacy, remove unused params --- lib/stitches/fill.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index 94df3f77..d5a983f9 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -162,7 +162,7 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non runs.reverse() runs = [tuple(reversed(run)) for run in runs] - yield from runs + yield runs if end_row_spacing: current_row_y += row_spacing + \ @@ -225,6 +225,7 @@ def pull_runs(rows, shape, row_spacing): # print >>sys.stderr, "\n".join(str(len(row)) for row in rows) + rows = list(rows) runs = [] count = 0 while (len(rows) > 0): -- cgit v1.2.3 From b30fce85dbdb4097bb9e01c3d68a77e0c50dd80a Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Sat, 7 May 2022 16:20:15 -0400 Subject: undo aggressive line wrapping --- lib/stitches/fill.py | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'lib/stitches/fill.py') diff --git a/lib/stitches/fill.py b/lib/stitches/fill.py index d5a983f9..46352d4f 100644 --- a/lib/stitches/fill.py +++ b/lib/stitches/fill.py @@ -14,8 +14,7 @@ from ..utils import cache def legacy_fill(shape, angle, row_spacing, end_row_spacing, max_stitch_length, flip, staggers, skip_last): - rows_of_segments = intersect_region_with_grating( - shape, angle, row_spacing, end_row_spacing, flip) + rows_of_segments = intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing, flip) groups_of_segments = pull_runs(rows_of_segments, shape, row_spacing) return [section_to_stitches(group, angle, row_spacing, max_stitch_length, staggers, skip_last) @@ -75,8 +74,7 @@ def stitch_row(stitches, beg, end, angle, row_spacing, max_stitch_length, stagge stitches.append(beg) - first_stitch = adjust_stagger( - beg, angle, row_spacing, max_stitch_length, staggers) + first_stitch = adjust_stagger(beg, angle, row_spacing, max_stitch_length, staggers) # we might have chosen our first stitch just outside this row, so move back in if (first_stitch - beg) * row_direction < 0: @@ -85,8 +83,7 @@ def stitch_row(stitches, beg, end, angle, row_spacing, max_stitch_length, stagge offset = (first_stitch - beg).length() while offset < segment_length: - stitches.append( - Stitch(beg + offset * row_direction, tags=('fill_row'))) + stitches.append(Stitch(beg + offset * row_direction, tags=('fill_row'))) offset += max_stitch_length if (end - stitches[-1]).length() > 0.1 * PIXELS_PER_MM and not skip_last: @@ -119,8 +116,7 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non # angle degrees clockwise and ask for the new bounding box. The max # and min y tell me how far to go. - _, start, _, end = shapely.affinity.rotate( - shape, angle, origin='center', use_radians=True).bounds + _, start, _, end = shapely.affinity.rotate(shape, angle, origin='center', use_radians=True).bounds # convert start and end to be relative to center (simplifies things later) start -= center.y @@ -155,8 +151,7 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non runs = [res.coords] if runs: - runs.sort(key=lambda seg: ( - InkstitchPoint(*seg[0]) - upper_left).length()) + runs.sort(key=lambda seg: (InkstitchPoint(*seg[0]) - upper_left).length()) if flip: runs.reverse() @@ -165,9 +160,7 @@ def intersect_region_with_grating(shape, angle, row_spacing, end_row_spacing=Non yield runs if end_row_spacing: - current_row_y += row_spacing + \ - (end_row_spacing - row_spacing) * \ - ((current_row_y - start) / height) + current_row_y += row_spacing + (end_row_spacing - row_spacing) * ((current_row_y - start) / height) else: current_row_y += row_spacing @@ -182,8 +175,7 @@ def section_to_stitches(group_of_segments, angle, row_spacing, max_stitch_length if (swap): (beg, end) = (end, beg) - stitch_row(stitches, beg, end, angle, row_spacing, - max_stitch_length, staggers, skip_last) + stitch_row(stitches, beg, end, angle, row_spacing, max_stitch_length, staggers, skip_last) swap = not swap -- cgit v1.2.3