diff options
| author | Andreas <v.andreas.1@web.de> | 2022-02-02 21:19:31 +0100 |
|---|---|---|
| committer | Kaalleen <reni@allenka.de> | 2022-05-04 19:07:04 +0200 |
| commit | d514eac81937bb64815239dd3aa96e38d6556a32 (patch) | |
| tree | cdd4e2d95a3be208f9f25cfb9a811bcd6f9ec66e /lib | |
| parent | b14e445daeafd12984cb40af289a415a0cb90e5d (diff) | |
adjusting namings
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/elements/fill_stitch.py | 32 | ||||
| -rw-r--r-- | lib/extensions/params.py | 4 | ||||
| -rw-r--r-- | lib/stitches/DebuggingMethods.py | 173 | ||||
| -rw-r--r-- | lib/stitches/auto_fill.py | 14 | ||||
| -rw-r--r-- | lib/stitches/constants.py | 10 | ||||
| -rw-r--r-- | lib/stitches/fill.py | 8 | ||||
| -rw-r--r-- | lib/stitches/point_transfer.py (renamed from lib/stitches/PointTransfer.py) | 40 | ||||
| -rw-r--r-- | lib/stitches/sample_linestring.py (renamed from lib/stitches/LineStringSampling.py) | 43 | ||||
| -rw-r--r-- | lib/stitches/tangential_fill_stitch_line_creator.py (renamed from lib/stitches/StitchPattern.py) | 100 | ||||
| -rw-r--r-- | lib/stitches/tangential_fill_stitch_pattern_creator.py (renamed from lib/stitches/ConnectAndSamplePattern.py) | 129 |
10 files changed, 87 insertions, 466 deletions
diff --git a/lib/elements/fill_stitch.py b/lib/elements/fill_stitch.py index 2e67c517..3256c1ea 100644 --- a/lib/elements/fill_stitch.py +++ b/lib/elements/fill_stitch.py @@ -15,14 +15,13 @@ from shapely.validation import explain_validity from ..i18n import _ from ..marker import get_marker_elements from ..stitch_plan import StitchGroup -from ..stitches import StitchPattern, auto_fill, legacy_fill +from ..stitches import tangential_fill_stitch_line_creator, auto_fill, legacy_fill from ..svg import PIXELS_PER_MM from ..svg.tags import INKSCAPE_LABEL from ..utils import Point as InkstitchPoint from ..utils import cache, version from .element import EmbroideryElement, param from .validation import ValidationError, ValidationWarning -from shapely.ops import nearest_points class SmallShapeWarning(ValidationWarning): @@ -46,8 +45,7 @@ class UnderlayInsetWarning(ValidationWarning): class MissingGuideLineWarning(ValidationWarning): name = _("Missing Guideline") - description = _( - 'This object is set to "Guided AutoFill", but has no guide line.') + description = _('This object is set to "Guided AutoFill", but has no guide line.') steps_to_solve = [ _('* Create a stroke object'), _('* Select this object and run Extensions > Ink/Stitch > Edit > Selection to guide line') @@ -65,8 +63,7 @@ class DisjointGuideLineWarning(ValidationWarning): class MultipleGuideLineWarning(ValidationWarning): name = _("Multiple Guide Lines") - description = _( - "This object has multiple guide lines, but only the first one will be used.") + description = _("This object has multiple guide lines, but only the first one will be used.") steps_to_solve = [ _("* Remove all guide lines, except for one.") ] @@ -84,8 +81,7 @@ class UnconnectedError(ValidationError): class InvalidShapeError(ValidationError): name = _("Border crosses itself") - description = _( - "Fill: Shape is not valid. This can happen if the border crosses over itself.") + description = _("Fill: Shape is not valid. This can happen if the border crosses over itself.") steps_to_solve = [ _('* Extensions > Ink/Stitch > Fill Tools > Break Apart Fill Objects') ] @@ -125,8 +121,7 @@ class FillStitch(EmbroideryElement): @property @param('angle', _('Angle of lines of stitches'), - tooltip=_( - 'The angle increases in a counter-clockwise direction. 0 is horizontal. Negative angles are allowed.'), + tooltip=_('The angle increases in a counter-clockwise direction. 0 is horizontal. Negative angles are allowed.'), unit='deg', type='float', sort_index=4, @@ -199,8 +194,7 @@ class FillStitch(EmbroideryElement): @property @param('staggers', _('Stagger rows this many times before repeating'), - tooltip=_( - 'Setting this dictates how many rows apart the stitches will be before they fall in the same column position.'), + tooltip=_('Setting this dictates how many rows apart the stitches will be before they fall in the same column position.'), type='int', sort_index=4, select_items=[('fill_method', 0), ('fill_method', 3)], @@ -317,8 +311,7 @@ class FillStitch(EmbroideryElement): @property @param('running_stitch_length_mm', _('Running stitch length (traversal between sections)'), - tooltip=_( - 'Length of stitches around the outline of the fill region used when moving from section to section.'), + tooltip=_('Length of stitches around the outline of the fill region used when moving from section to section.'), unit='mm', type='float', default=1.5, @@ -335,8 +328,7 @@ class FillStitch(EmbroideryElement): @property @param('fill_underlay_angle', _('Fill angle'), - tooltip=_( - 'Default: fill angle + 90 deg. Insert comma-seperated list for multiple layers.'), + tooltip=_('Default: fill angle + 90 deg. Insert comma-seperated list for multiple layers.'), unit='deg', group=_('AutoFill Underlay'), type='float') @@ -380,8 +372,7 @@ class FillStitch(EmbroideryElement): @property @param('fill_underlay_inset_mm', _('Inset'), - tooltip=_( - 'Shrink the shape before doing underlay, to prevent underlay from showing around the outside of the fill.'), + tooltip=_('Shrink the shape before doing underlay, to prevent underlay from showing around the outside of the fill.'), unit='mm', group=_('AutoFill Underlay'), type='float', @@ -404,8 +395,7 @@ class FillStitch(EmbroideryElement): @property @param('expand_mm', _('Expand'), - tooltip=_( - 'Expand the shape before fill stitching, to compensate for gaps between shapes.'), + tooltip=_('Expand the shape before fill stitching, to compensate for gaps between shapes.'), unit='mm', type='float', default=0, @@ -564,7 +554,7 @@ class FillStitch(EmbroideryElement): if not starting_point: starting_point = (0, 0) for poly in polygons: - connectedLine, connectedLineOrigin = StitchPattern.offset_poly( + connectedLine, _ = tangential_fill_stitch_line_creator.offset_poly( poly, -self.row_spacing, self.join_style+1, diff --git a/lib/extensions/params.py b/lib/extensions/params.py index 69a559ce..e50d97d0 100644 --- a/lib/extensions/params.py +++ b/lib/extensions/params.py @@ -86,7 +86,6 @@ class ParamsTab(ScrolledPanel): # end wxGlade def pair(self, tab): - # print self.name, "paired with", tab.name self.paired_tab = tab self.update_description() @@ -108,7 +107,6 @@ class ParamsTab(ScrolledPanel): def update_toggle_state(self, event=None, notify_pair=True): enable = self.enabled() - # print self.name, "update_toggle_state", enable for child in self.settings_grid.GetChildren(): widget = child.GetWindow() if widget: @@ -137,7 +135,6 @@ class ParamsTab(ScrolledPanel): event.Skip() def pair_changed(self, value): - # print self.name, "pair_changed", value new_value = not value if self.enabled() != new_value: @@ -192,7 +189,6 @@ class ParamsTab(ScrolledPanel): def apply(self): values = self.get_values() for node in self.nodes: - # print >> sys.stderr, "apply: ", self.name, node.id, values for name, value in values.items(): node.set_param(name, value) diff --git a/lib/stitches/DebuggingMethods.py b/lib/stitches/DebuggingMethods.py deleted file mode 100644 index e239edba..00000000 --- a/lib/stitches/DebuggingMethods.py +++ /dev/null @@ -1,173 +0,0 @@ -import matplotlib.pyplot as plt -from shapely.geometry import Polygon - -from anytree import PreOrderIter - -# import LineStringSampling as Sampler -import numpy as np -import matplotlib.collections as mcoll - -# def offset_polygons(polys, offset,joinstyle): -# if polys.geom_type == 'Polygon': -# inners = polys.interiors -# outer = polys.exterior -# polyinners = [] -# for inner in inners: -# inner = inner.parallel_offset(offset,'left', 5, joinstyle, 1) -# polyinners.append(Polygon(inner)) -# outer = outer.parallel_offset(offset,'left', 5, joinstyle, 1) -# return Polygon(outer).difference(MultiPolygon(polyinners)) -# else: -# polyreturns = [] -# for poly in polys: -# inners = poly.interiors -# outer = poly.exterior -# polyinners = [] -# for inner in inners: -# inner = inner.parallel_offset(offset,'left', 5, joinstyle, 1) -# polyinners.append(Polygon(inner)) -# outer = outer.parallel_offset(offset,'left', 5, joinstyle, 1) -# result = Polygon(outer).difference(MultiPolygon(polyinners)) -# polyreturns.append(result) -# return MultiPolygon(polyreturns) - -# For debugging - - -def plot_MultiPolygon(MultiPoly, plt, colorString): - if MultiPoly.is_empty: - return - if MultiPoly.geom_type == "Polygon": - x2, y2 = MultiPoly.exterior.xy - plt.plot(x2, y2, colorString) - - for inners in MultiPoly.interiors: - x2, y2 = inners.coords.xy - plt.plot(x2, y2, colorString) - else: - for poly in MultiPoly: - x2, y2 = poly.exterior.xy - plt.plot(x2, y2, colorString) - - for inners in poly.interiors: - x2, y2 = inners.coords.xy - plt.plot(x2, y2, colorString) - - -# Test whether there are areas which would currently not be stitched but should be stitched - - -def subtractResult(poly, rootPoly, offsetThresh): - poly2 = Polygon(poly) - for node in PreOrderIter(rootPoly): - poly2 = poly2.difference(node.val.buffer(offsetThresh, 5, 3, 3)) - return poly2 - - -# Used for debugging - plots all polygon exteriors within an AnyTree which is provided by the root node rootPoly. - - -def drawPoly(rootPoly, colorString): - fig, axs = plt.subplots(1, 1) - axs.axis("equal") - plt.gca().invert_yaxis() - for node in PreOrderIter(rootPoly): - # if(node.id == "hole"): - # node.val = LinearRing(node.val.coords[::-1]) - print("Bounds:") - print(node.val.bounds) - x2, y2 = node.val.coords.xy - plt.plot(x2, y2, colorString) - plt.show(block=True) - - -def drawresult(resultcoords, resultcoords_Origin, colorString): - fig, axs = plt.subplots(1, 1) - axs.axis("equal") - plt.gca().invert_yaxis() - plt.plot(*zip(*resultcoords), colorString) - - colormap = np.array(["r", "g", "b", "c", "m", "y", "k", "gray", "m"]) - labelmap = np.array( - [ - "MUST_USE", - "REGULAR_SPACING", - "INITIAL_RASTERING", - "EDGE_NEEDED", - "NOT_NEEDED", - "ALREADY_TRANSFERRED", - "ADDITIONAL_TRACKING_POINT_NOT_NEEDED", - "EDGE_RASTERING_ALLOWED", - "EDGE_PREVIOUSLY_SHIFTED", - ] - ) - - for i in range(0, 8 + 1): - # if i != Sampler.PointSource.EDGE_NEEDED and i != Sampler.PointSource.INITIAL_RASTERING: - # continue - selection = [] - for j in range(len(resultcoords)): - if i == resultcoords_Origin[j]: - selection.append(resultcoords[j]) - if len(selection) > 0: - plt.scatter(*zip(*selection), c=colormap[i], label=labelmap[i]) - - # plt.scatter(*zip(*resultcoords), - # c=colormap[resultcoords_Origin]) - axs.legend() - plt.show(block=True) - - -# Just for debugging in order to draw the connected line with color gradient - - -def colorline( - x, - y, - z=None, - cmap=plt.get_cmap("copper"), - norm=plt.Normalize(0.0, 1.0), - linewidth=3, - alpha=1.0, -): - """ - http://nbviewer.ipython.org/github/dpsanders/matplotlib-examples/blob/master/colorline.ipynb - http://matplotlib.org/examples/pylab_examples/multicolored_line.html - Plot a colored line with coordinates x and y - Optionally specify colors in the array z - Optionally specify a colormap, a norm function and a line width - """ - - # Default colors equally spaced on [0,1]: - if z is None: - z = np.linspace(0.0, 1.0, len(x)) - - # Special case if a single number: - if not hasattr(z, "__iter__"): # to check for numerical input -- this is a hack - z = np.array([z]) - - z = np.asarray(z) - - segments = make_segments(x, y) - lc = mcoll.LineCollection( - segments, array=z, cmap=cmap, norm=norm, linewidth=linewidth, alpha=alpha - ) - - ax = plt.gca() - ax.add_collection(lc) - - return lc - - -# Used by colorline - - -def make_segments(x, y): - """ - Create list of line segments from x and y coordinates, in the correct format - for LineCollection: an array of the form numlines x (points per line) x 2 (x - and y) array - """ - points = np.array([x, y]).T.reshape(-1, 1, 2) - segments = np.concatenate([points[:-1], points[1:]], axis=1) - return segments diff --git a/lib/stitches/auto_fill.py b/lib/stitches/auto_fill.py index b63f4be1..7af99560 100644 --- a/lib/stitches/auto_fill.py +++ b/lib/stitches/auto_fill.py @@ -20,8 +20,8 @@ from ..utils.geometry import Point as InkstitchPoint from ..utils.geometry import line_string_to_point_list from .fill import intersect_region_with_grating, intersect_region_with_grating_line, stitch_row from .running_stitch import running_stitch -from .PointTransfer import transfer_points_to_surrounding_graph -from .LineStringSampling import raster_line_string_with_priority_points +from .point_transfer import transfer_points_to_surrounding_graph +from .sample_linestring import raster_line_string_with_priority_points class PathEdge(object): @@ -165,10 +165,6 @@ def build_fill_stitch_graph(shape, line, angle, row_spacing, end_row_spacing, st for i in range(len(rows_of_segments)): for segment in rows_of_segments[i]: - # if abs(segment[0][0]-396.5081896849414) < 0.01: - # print("HIER") - # if segment[0][0] == segment[-1][0] and segment[0][1] == segment[-1][1]: - # print("FEHLER HIER!") # First, add the grating segments as edges. We'll use the coordinates # of the endpoints as nodes, which networkx will add automatically. @@ -666,10 +662,6 @@ def travel(travel_graph, start, end, running_stitch_length, skip_last): def stitch_line(stitches, stitching_direction, geometry, projected_points, max_stitch_length, row_spacing, skip_last, offset_by_half): - # print(start_point) - # print(geometry[0]) - # if stitching_direction == -1: - # geometry.coords = geometry.coords[::-1] if stitching_direction == 1: stitched_line, _ = raster_line_string_with_priority_points( geometry, 0.0, geometry.length, max_stitch_length, projected_points, abs(row_spacing), offset_by_half, True) @@ -688,8 +680,6 @@ def stitch_line(stitches, stitching_direction, geometry, projected_points, max_s else: stitches.append( Stitch(*geometry.coords[0], tags=('fill_row_end',))) - # if stitches[-1].x == stitches[-2].x and stitches[-1].y == stitches[-2].y: - # print("FEHLER") @debug.time diff --git a/lib/stitches/constants.py b/lib/stitches/constants.py index 162c4cfb..012fac7c 100644 --- a/lib/stitches/constants.py +++ b/lib/stitches/constants.py @@ -3,10 +3,6 @@ import math # Used in the simplify routine of shapely simplification_threshold = 0.01 -# If a transferred point is closer than this value to one of its neighbors, -# it will be checked whether it can be removed -distance_thresh_remove_transferred_point = 0.15 - # If a line segment is shorter than this threshold it is handled as a single point line_lengh_seen_as_one_point = 0.05 @@ -35,12 +31,6 @@ factor_offset_starting_points = 0.5 # if points are closer than abs_offset*factor_offset_remove_points one of it is removed factor_offset_remove_points = 0.5 -# if an unshifted relevant edge is closer than -# abs_offset*fac_offset_edge_shift -# to the line segment created by the shifted edge, -# the shift is allowed - otherwise the edge must not be shifted. -fac_offset_edge_shift = 0.25 - # decides whether the point belongs to a hard edge (must use this point during sampling) # or soft edge (do not necessarily need to use this point) limiting_angle = math.pi * 15 / 180.0 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 diff --git a/lib/stitches/PointTransfer.py b/lib/stitches/point_transfer.py index 93fe02c5..a01e69cd 100644 --- a/lib/stitches/PointTransfer.py +++ b/lib/stitches/point_transfer.py @@ -4,7 +4,10 @@ from collections import namedtuple from shapely.ops import nearest_points import math from ..stitches import constants -from ..stitches import LineStringSampling +from ..stitches import sample_linestring + +"""This file contains routines which shall project already selected points for stitching to remaining +unstitched lines in the neighborhood to create a regular pattern of points.""" projected_point_tuple = namedtuple( 'projected_point_tuple', ['point', 'point_source']) @@ -136,12 +139,9 @@ def transfer_points_to_surrounding(treenode, used_offset, offset_by_half, to_tra # length including the closing segment closed_line = LinearRing(to_transfer_points) - bisectorline_length = abs(used_offset) * \ - constants.transfer_point_distance_factor * \ - (2.0 if overnext_neighbor else 1.0) + bisectorline_length = abs(used_offset) * constants.transfer_point_distance_factor * (2.0 if overnext_neighbor else 1.0) - bisectorline_length_forbidden_points = abs(used_offset) * \ - constants.transfer_point_distance_factor + bisectorline_length_forbidden_points = abs(used_offset) * constants.transfer_point_distance_factor linesign_child = math.copysign(1, used_offset) @@ -149,9 +149,7 @@ def transfer_points_to_surrounding(treenode, used_offset, offset_by_half, to_tra currentDistance = 0 while i < len(point_list): assert(point_source_list[i] != - LineStringSampling.PointSource.ENTER_LEAVING_POINT) - # if abs(point_list[i].coords[0][0]-47) < 0.3 and abs(point_list[i].coords[0][1]-4.5) < 0.3: - # print("HIIIIIIIIIIIERRR") + sample_linestring.PointSource.ENTER_LEAVING_POINT) # We create a bisecting line through the current point normalized_vector_prev_x = ( @@ -249,15 +247,15 @@ def transfer_points_to_surrounding(treenode, used_offset, offset_by_half, to_tra if point is None: continue child.transferred_point_priority_deque.insert(projected_point_tuple( - point=point, point_source=LineStringSampling.PointSource.OVERNEXT if overnext_neighbor - else LineStringSampling.PointSource.DIRECT), priority) + point=point, point_source=sample_linestring.PointSource.OVERNEXT if overnext_neighbor + else sample_linestring.PointSource.DIRECT), priority) for child in child_list_forbidden: point, priority = calc_transferred_point( bisectorline_forbidden_point_child, child) if point is None: continue child.transferred_point_priority_deque.insert(projected_point_tuple( - point=point, point_source=LineStringSampling.PointSource.FORBIDDEN_POINT), priority) + point=point, point_source=sample_linestring.PointSource.FORBIDDEN_POINT), priority) for neighbor in neighbor_list: point, priority = calc_transferred_point( @@ -265,15 +263,15 @@ def transfer_points_to_surrounding(treenode, used_offset, offset_by_half, to_tra if point is None: continue neighbor.transferred_point_priority_deque.insert(projected_point_tuple( - point=point, point_source=LineStringSampling.PointSource.OVERNEXT if overnext_neighbor - else LineStringSampling.PointSource.DIRECT), priority) + point=point, point_source=sample_linestring.PointSource.OVERNEXT if overnext_neighbor + else sample_linestring.PointSource.DIRECT), priority) for neighbor in neighbor_list_forbidden: point, priority = calc_transferred_point( bisectorline_forbidden_point_neighbor, neighbor) if point is None: continue neighbor.transferred_point_priority_deque.insert(projected_point_tuple( - point=point, point_source=LineStringSampling.PointSource.FORBIDDEN_POINT), priority) + point=point, point_source=sample_linestring.PointSource.FORBIDDEN_POINT), priority) i += 1 currentDistance += next_spacing @@ -398,9 +396,6 @@ def transfer_points_to_surrounding_graph(fill_stitch_graph, current_edge, used_o currentDistance = 0 while i < len(point_list): - # if abs(point_list[i].coords[0][0]-47) < 0.3 and abs(point_list[i].coords[0][1]-4.5) < 0.3: - # print("HIIIIIIIIIIIERRR") - # We create a bisecting line through the current point normalized_vector_prev_x = ( point_list[i].coords[0][0]-point_list[i-1].coords[0][0]) # makes use of closed shape @@ -409,9 +404,6 @@ def transfer_points_to_surrounding_graph(fill_stitch_graph, current_edge, used_o prev_spacing = math.sqrt(normalized_vector_prev_x*normalized_vector_prev_x + normalized_vector_prev_y*normalized_vector_prev_y) - # if prev_spacing == 0: - # print("HIER FEHLER") - normalized_vector_prev_x /= prev_spacing normalized_vector_prev_y /= prev_spacing @@ -489,15 +481,15 @@ def transfer_points_to_surrounding_graph(fill_stitch_graph, current_edge, used_o if point is None: continue edge['projected_points'].insert(projected_point_tuple( - point=point, point_source=LineStringSampling.PointSource.OVERNEXT if overnext_neighbor - else LineStringSampling.PointSource.DIRECT), priority) + point=point, point_source=sample_linestring.PointSource.OVERNEXT if overnext_neighbor + else sample_linestring.PointSource.DIRECT), priority) for edge_forbidden in previous_edge_list_forbidden+next_edge_list_forbidden: point, priority = calc_transferred_point_graph( bisectorline_forbidden_point, edge_forbidden['geometry']) if point is None: continue edge_forbidden['projected_points'].insert(projected_point_tuple( - point=point, point_source=LineStringSampling.PointSource.FORBIDDEN_POINT), priority) + point=point, point_source=sample_linestring.PointSource.FORBIDDEN_POINT), priority) i += 1 currentDistance += next_spacing diff --git a/lib/stitches/LineStringSampling.py b/lib/stitches/sample_linestring.py index 71660e2d..fb4bbc52 100644 --- a/lib/stitches/LineStringSampling.py +++ b/lib/stitches/sample_linestring.py @@ -5,7 +5,7 @@ import math import numpy as np from enum import IntEnum from ..stitches import constants -from ..stitches import PointTransfer +from ..stitches import point_transfer class PointSource(IntEnum): @@ -53,19 +53,12 @@ def calculate_line_angles(line): vec2 = np.array(line.coords[i+1])-np.array(line.coords[i]) vec1length = np.linalg.norm(vec1) vec2length = np.linalg.norm(vec2) - # if vec1length <= 0: - # print("HIER FEHLER") - # if vec2length <=0: - # print("HIER FEHLEr") assert(vec1length > 0) assert(vec2length > 0) scalar_prod = np.dot(vec1, vec2)/(vec1length*vec2length) scalar_prod = min(max(scalar_prod, -1), 1) - # if scalar_prod > 1.0: - # scalar_prod = 1.0 - # elif scalar_prod < -1.0: - # scalar_prod = -1.0 + Angles[i] = math.acos(scalar_prod) return Angles @@ -145,8 +138,6 @@ def raster_line_string_with_priority_points(line, start_distance, end_distance, merged_point_list = [] dq_iter = 0 for point, angle in zip(path_coords.coords, angles): - # if abs(point[0]-7) < 0.2 and abs(point[1]-3.3) < 0.2: - # print("GEFUNDEN") current_distance += last_point.distance(Point(point)) last_point = Point(point) while dq_iter < len(deque_points) and deque_points[dq_iter][1] < current_distance+start_distance: @@ -156,7 +147,7 @@ def raster_line_string_with_priority_points(line, start_distance, end_distance, if (merged_point_list[-1][0].point_source == PointSource.SOFT_EDGE_INTERNAL and abs(merged_point_list[-1][1]-deque_points[dq_iter][1]+start_distance < abs_offset*constants.factor_offset_forbidden_point)): item = merged_point_list.pop() - merged_point_list.append((PointTransfer.projected_point_tuple( + merged_point_list.append((point_transfer.projected_point_tuple( point=item[0].point, point_source=PointSource.FORBIDDEN_POINT), item[1]-start_distance)) else: merged_point_list.append( @@ -174,7 +165,7 @@ def raster_line_string_with_priority_points(line, start_distance, end_distance, point_source = PointSource.SOFT_EDGE_INTERNAL else: point_source = PointSource.HARD_EDGE_INTERNAL - merged_point_list.append((PointTransfer.projected_point_tuple( + merged_point_list.append((point_transfer.projected_point_tuple( point=Point(point), point_source=point_source), current_distance)) result_list = [merged_point_list[0]] @@ -188,10 +179,6 @@ def raster_line_string_with_priority_points(line, start_distance, end_distance, segment_end_index = 1 forbidden_point_list = [] while segment_end_index < len(merged_point_list): - # if abs(merged_point_list[segment_end_index-1][0].point.coords[0][0]-67.9) < 0.2 and - # abs(merged_point_list[segment_end_index-1][0].point.coords[0][1]-161.0)< 0.2: - # print("GEFUNDEN") - # Collection of points for the current segment current_point_list = [merged_point_list[segment_start_index][0].point] @@ -201,16 +188,10 @@ def raster_line_string_with_priority_points(line, start_distance, end_distance, if segment_length > maxstitch_distance+constants.point_spacing_to_be_considered_equal: new_distance = merged_point_list[segment_start_index][1] + \ maxstitch_distance - merged_point_list.insert(segment_end_index, (PointTransfer.projected_point_tuple( + merged_point_list.insert(segment_end_index, (point_transfer.projected_point_tuple( point=aligned_line.interpolate(new_distance), point_source=PointSource.REGULAR_SPACING_INTERNAL), new_distance)) - # if (abs(merged_point_list[segment_end_index][0].point.coords[0][0]-12.2) < 0.2 and - # abs(merged_point_list[segment_end_index][0].point.coords[0][1]-0.9) < 0.2): - # print("GEFUNDEN") segment_end_index += 1 break - # if abs(merged_point_list[segment_end_index][0].point.coords[0][0]-93.6) < 0.2 and - # abs(merged_point_list[segment_end_index][0].point.coords[0][1]-122.7)< 0.2: - # print("GEFUNDEN") current_point_list.append( merged_point_list[segment_end_index][0].point) @@ -291,8 +272,6 @@ def raster_line_string_with_priority_points(line, start_distance, end_distance, # Finally we create the final return_point_list and return_point_source_list for i in range(len(result_list)): return_point_list.append(result_list[i][0].point.coords[0]) - # if abs(result_list[i][0].point.coords[0][0]-91.7) < 0.2 and abs(result_list[i][0].point.coords[0][1]-106.15)< 0.2: - # print("GEFUNDEN") if result_list[i][0].point_source == PointSource.HARD_EDGE_INTERNAL: point_source = PointSource.HARD_EDGE elif result_list[i][0].point_source == PointSource.SOFT_EDGE_INTERNAL: @@ -316,8 +295,6 @@ def _replace_forbidden_points(line, result_list, forbidden_point_list_indices, a # since we add and remove points in the result_list, we need to adjust the indices stored in forbidden_point_list_indices current_index_shift = 0 for index in forbidden_point_list_indices: - # if abs(result_list[index][0].point.coords[0][0]-40.7) < 0.2 and abs(result_list[index][0].point.coords[0][1]-1.3)< 0.2: - # print("GEFUNDEN") index += current_index_shift distance_left = result_list[index][0].point.distance( result_list[index-1][0].point)/2.0 @@ -336,9 +313,9 @@ def _replace_forbidden_points(line, result_list, forbidden_point_list_indices, a LineString([point_left, point_right])) if forbidden_point_distance < constants.factor_offset_remove_dense_points*abs_offset: del result_list[index] - result_list.insert(index, (PointTransfer.projected_point_tuple( + result_list.insert(index, (point_transfer.projected_point_tuple( point=point_right, point_source=PointSource.REPLACED_FORBIDDEN_POINT), new_point_right_proj)) - result_list.insert(index, (PointTransfer.projected_point_tuple( + result_list.insert(index, (point_transfer.projected_point_tuple( point=point_left, point_source=PointSource.REPLACED_FORBIDDEN_POINT), new_point_left_proj)) current_index_shift += 1 break @@ -346,9 +323,3 @@ def _replace_forbidden_points(line, result_list, forbidden_point_list_indices, a distance_left /= 2.0 distance_right /= 2.0 return result_list - - -if __name__ == "__main__": - line = LineString([(0, 0), (1, 0), (2, 1), (3, 0), (4, 0)]) - - print(calculate_line_angles(line)*180.0/math.pi) diff --git a/lib/stitches/StitchPattern.py b/lib/stitches/tangential_fill_stitch_line_creator.py index 4a38c0bc..af14ea0f 100644 --- a/lib/stitches/StitchPattern.py +++ b/lib/stitches/tangential_fill_stitch_line_creator.py @@ -1,4 +1,3 @@ -from anytree.render import RenderTree from shapely.geometry.polygon import LinearRing, LineString from shapely.geometry import Polygon, MultiLineString from shapely.ops import polygonize @@ -7,7 +6,7 @@ from anytree import AnyNode, PreOrderIter, LevelOrderGroupIter from shapely.geometry.polygon import orient from depq import DEPQ from enum import IntEnum -from ..stitches import ConnectAndSamplePattern +from ..stitches import tangential_fill_stitch_pattern_creator from ..stitches import constants @@ -311,110 +310,21 @@ def offset_poly(poly, offset, join_style, stitch_distance, offset_by_half, strat if previous_hole.parent is None: previous_hole.parent = current_poly - # DebuggingMethods.drawPoly(root, 'r-') make_tree_uniform_ccw(root) - # print(RenderTree(root)) + if strategy == StitchingStrategy.CLOSEST_POINT: - (connected_line, connected_line_origin) = ConnectAndSamplePattern.connect_raster_tree_nearest_neighbor( + (connected_line, connected_line_origin) = tangential_fill_stitch_pattern_creator.connect_raster_tree_nearest_neighbor( root, offset, stitch_distance, starting_point, offset_by_half) elif strategy == StitchingStrategy.INNER_TO_OUTER: - (connected_line, connected_line_origin) = ConnectAndSamplePattern.connect_raster_tree_from_inner_to_outer( + (connected_line, connected_line_origin) = tangential_fill_stitch_pattern_creator.connect_raster_tree_from_inner_to_outer( root, offset, stitch_distance, starting_point, offset_by_half) elif strategy == StitchingStrategy.SPIRAL: if not check_and_prepare_tree_for_valid_spiral(root): raise ValueError("Geometry cannot be filled with one spiral!") - (connected_line, connected_line_origin) = ConnectAndSamplePattern.connect_raster_tree_spiral( + (connected_line, connected_line_origin) = tangential_fill_stitch_pattern_creator.connect_raster_tree_spiral( root, offset, stitch_distance, starting_point, offset_by_half) else: raise ValueError("Invalid stitching stratety!") return connected_line, connected_line_origin - - -if __name__ == "__main__": - line1 = LineString([(0, 0), (1, 0)]) - line2 = LineString([(0, 0), (3, 0)]) - - root = AnyNode( - id="root", - val=line1) - child1 = AnyNode( - id="node", - val=line1, - parent=root) - child2 = AnyNode( - id="node", - val=line1, - parent=root) - child3 = AnyNode( - id="node", - val=line2, - parent=root) - - print(RenderTree(root)) - print(check_and_prepare_tree_for_valid_spiral(root)) - print(RenderTree(root)) - print("---------------------------") - root = AnyNode( - id="root", - val=line1) - child1 = AnyNode( - id="node", - val=line1, - parent=root) - child2 = AnyNode( - id="node", - val=line1, - parent=root) - child3 = AnyNode( - id="node", - val=line2, - parent=child1) - print(RenderTree(root)) - print(check_and_prepare_tree_for_valid_spiral(root)) - print(RenderTree(root)) - - print("---------------------------") - root = AnyNode( - id="root", - val=line1) - child1 = AnyNode( - id="node", - val=line1, - parent=root) - child2 = AnyNode( - id="node", - val=line1, - parent=child1) - child3 = AnyNode( - id="node", - val=line2, - parent=child2) - print(RenderTree(root)) - print(check_and_prepare_tree_for_valid_spiral(root)) - print(RenderTree(root)) - - print("---------------------------") - root = AnyNode( - id="root", - val=line1) - child1 = AnyNode( - id="node", - val=line1, - parent=root) - child2 = AnyNode( - id="node", - val=line1, - parent=root) - child3 = AnyNode( - id="node", - val=line2, - parent=child1) - child4 = AnyNode( - id="node", - val=line2, - parent=child2) - print(RenderTree(root)) - print(check_and_prepare_tree_for_valid_spiral(root)) - print(RenderTree(root)) diff --git a/lib/stitches/ConnectAndSamplePattern.py b/lib/stitches/tangential_fill_stitch_pattern_creator.py index 1cf2b2a1..d7afad0c 100644 --- a/lib/stitches/ConnectAndSamplePattern.py +++ b/lib/stitches/tangential_fill_stitch_pattern_creator.py @@ -8,8 +8,8 @@ import numpy as np from scipy import spatial import math from anytree import PreOrderIter -from ..stitches import LineStringSampling -from ..stitches import PointTransfer +from ..stitches import sample_linestring +from ..stitches import point_transfer from ..stitches import constants nearest_neighbor_tuple = namedtuple( @@ -110,8 +110,7 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 nearest_point_parent=point_parent, nearest_point_child=point_child, proj_distance_parent=proj_distance, - child_node=subnode, - ) + child_node=subnode) ) nearest_points_list.sort( reverse=False, key=lambda tup: tup.proj_distance_parent) @@ -128,14 +127,9 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 ) else: start_distance = abs_offset * constants.factor_offset_starting_points - end_distance = ( - current_coords.length - abs_offset * constants.factor_offset_starting_points - ) + end_distance = (current_coords.length - abs_offset * constants.factor_offset_starting_points) - ( - own_coords, - own_coords_origin, - ) = LineStringSampling.raster_line_string_with_priority_points( + (own_coords, own_coords_origin) = sample_linestring.raster_line_string_with_priority_points( current_coords, start_distance, # We add/subtract an offset to not sample # the same point again (avoid double @@ -145,11 +139,11 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 tree.transferred_point_priority_deque, abs_offset, offset_by_half, - False - ) + False) + assert len(own_coords) == len(own_coords_origin) - own_coords_origin[0] = LineStringSampling.PointSource.ENTER_LEAVING_POINT - own_coords_origin[-1] = LineStringSampling.PointSource.ENTER_LEAVING_POINT + own_coords_origin[0] = sample_linestring.PointSource.ENTER_LEAVING_POINT + own_coords_origin[-1] = sample_linestring.PointSource.ENTER_LEAVING_POINT tree.stitching_direction = stitching_direction tree.already_rastered = True @@ -160,15 +154,10 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 # Do not take the first and the last since they are ENTER_LEAVING_POINT # points for sure - if ( - not offset_by_half - and own_coords_origin[k] == LineStringSampling.PointSource.EDGE_NEEDED - ): + if (not offset_by_half and own_coords_origin[k] == sample_linestring.PointSource.EDGE_NEEDED): continue - if ( - own_coords_origin[k] == LineStringSampling.PointSource.ENTER_LEAVING_POINT - or own_coords_origin[k] == LineStringSampling.PointSource.FORBIDDEN_POINT - ): + if (own_coords_origin[k] == sample_linestring.PointSource.ENTER_LEAVING_POINT or + own_coords_origin[k] == sample_linestring.PointSource.FORBIDDEN_POINT): continue to_transfer_point_list.append(Point(own_coords[k])) point_origin = own_coords_origin[k] @@ -176,7 +165,7 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 # Since the projection is only in ccw direction towards inner we need # to use "-used_offset" for stitching_direction==-1 - PointTransfer.transfer_points_to_surrounding( + point_transfer.transfer_points_to_surrounding( tree, stitching_direction * used_offset, offset_by_half, @@ -192,7 +181,7 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 # We transfer also to the overnext child to get a more straight # arrangement of points perpendicular to the stitching lines if offset_by_half: - PointTransfer.transfer_points_to_surrounding( + point_transfer.transfer_points_to_surrounding( tree, stitching_direction * used_offset, False, @@ -224,7 +213,7 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 cur_item = 0 result_coords = [own_coords[0]] result_coords_origin = [ - LineStringSampling.PointSource.ENTER_LEAVING_POINT] + sample_linestring.PointSource.ENTER_LEAVING_POINT] for i in range(1, len(own_coords)): next_distance = math.sqrt( (own_coords[i][0] - own_coords[i - 1][0]) ** 2 @@ -237,10 +226,7 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 ): item = nearest_points_list[cur_item] - ( - child_coords, - child_coords_origin, - ) = connect_raster_tree_nearest_neighbor( + (child_coords, child_coords_origin) = connect_raster_tree_nearest_neighbor( item.child_node, used_offset, stitch_distance, @@ -253,7 +239,7 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 if d > abs_offset * constants.factor_offset_starting_points: result_coords.append(item.nearest_point_parent.coords[0]) result_coords_origin.append( - LineStringSampling.PointSource.ENTER_LEAVING_POINT + sample_linestring.PointSource.ENTER_LEAVING_POINT ) # reversing avoids crossing when entering and # leaving the child segment @@ -265,11 +251,7 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 if cur_item < len(nearest_points_list) - 1: d = min( d, - abs( - nearest_points_list[cur_item + - 1].proj_distance_parent - - item.proj_distance_parent - ), + abs(nearest_points_list[cur_item+1].proj_distance_parent-item.proj_distance_parent) ) if d > abs_offset * constants.factor_offset_starting_points: @@ -279,16 +261,11 @@ def connect_raster_tree_nearest_neighbor( # noqa: C901 + abs_offset * constants.factor_offset_starting_points ).coords[0] ) - result_coords_origin.append( - LineStringSampling.PointSource.ENTER_LEAVING_POINT - ) + result_coords_origin.append(sample_linestring.PointSource.ENTER_LEAVING_POINT) cur_item += 1 if i < len(own_coords) - 1: - if ( - Point(result_coords[-1]).distance(Point(own_coords[i])) - > abs_offset * constants.factor_offset_remove_points - ): + if (Point(result_coords[-1]).distance(Point(own_coords[i])) > abs_offset * constants.factor_offset_remove_points): result_coords.append(own_coords[i]) result_coords_origin.append(own_coords_origin[i]) @@ -445,14 +422,12 @@ def calculate_replacing_middle_point(line_segment, abs_offset, max_stitch_distan straight enough to be resampled by points max_stitch_distance apart FROM THE END OF line_segment. Returns None if the middle point is not needed. """ - angles = LineStringSampling.calculate_line_angles(line_segment) + angles = sample_linestring.calculate_line_angles(line_segment) if angles[1] < abs_offset * constants.limiting_angle_straight: if line_segment.length < max_stitch_distance: return None else: - return line_segment.interpolate( - line_segment.length - max_stitch_distance - ).coords[0] + return line_segment.interpolate(line_segment.length - max_stitch_distance).coords[0] else: return line_segment.coords[1] @@ -513,7 +488,7 @@ def connect_raster_tree_from_inner_to_outer(tree, used_offset, stitch_distance, stitching_direction, nearest_points_list = create_nearest_points_list( current_coords, tree.children, - 1.5 * abs_offset, + constants.offset_factor_for_adjacent_geometry * abs_offset, 2.05 * abs_offset, parent_stitching_direction, ) @@ -534,15 +509,10 @@ def connect_raster_tree_from_inner_to_outer(tree, used_offset, stitch_distance, ) else: start_offset = abs_offset * constants.factor_offset_starting_points - end_offset = ( - current_coords.length - abs_offset * constants.factor_offset_starting_points - ) + end_offset = (current_coords.length - abs_offset * constants.factor_offset_starting_points) if stitching_direction == 1: - ( - own_coords, - own_coords_origin, - ) = LineStringSampling.raster_line_string_with_priority_points( + (own_coords, own_coords_origin) = sample_linestring.raster_line_string_with_priority_points( current_coords, start_offset, # We add start_offset to not sample the same # point again (avoid double points for start @@ -555,10 +525,7 @@ def connect_raster_tree_from_inner_to_outer(tree, used_offset, stitch_distance, False ) else: - ( - own_coords, - own_coords_origin, - ) = LineStringSampling.raster_line_string_with_priority_points( + (own_coords, own_coords_origin) = sample_linestring.raster_line_string_with_priority_points( current_coords, current_coords.length - start_offset, # We subtract # start_offset to not @@ -587,11 +554,10 @@ def connect_raster_tree_from_inner_to_outer(tree, used_offset, stitch_distance, # since they are ENTER_LEAVING_POINT points for sure if ( not offset_by_half - and own_coords_origin[k] == LineStringSampling.PointSource.EDGE_NEEDED - or own_coords_origin[k] == LineStringSampling.PointSource.FORBIDDEN_POINT - ): + and own_coords_origin[k] == sample_linestring.PointSource.EDGE_NEEDED + or own_coords_origin[k] == sample_linestring.PointSource.FORBIDDEN_POINT): continue - if own_coords_origin[k] == LineStringSampling.PointSource.ENTER_LEAVING_POINT: + if own_coords_origin[k] == sample_linestring.PointSource.ENTER_LEAVING_POINT: continue to_transfer_point_list.append(Point(own_coords[k])) to_transfer_point_list_origin.append(own_coords_origin[k]) @@ -601,7 +567,7 @@ def connect_raster_tree_from_inner_to_outer(tree, used_offset, stitch_distance, # Next we need to transfer our rastered points to siblings and childs # Since the projection is only in ccw direction towards inner we # need to use "-used_offset" for stitching_direction==-1 - PointTransfer.transfer_points_to_surrounding( + point_transfer.transfer_points_to_surrounding( tree, stitching_direction * used_offset, offset_by_half, @@ -617,7 +583,7 @@ def connect_raster_tree_from_inner_to_outer(tree, used_offset, stitch_distance, # We transfer also to the overnext child to get a more straight # arrangement of points perpendicular to the stitching lines if offset_by_half: - PointTransfer.transfer_points_to_surrounding( + point_transfer.transfer_points_to_surrounding( tree, stitching_direction * used_offset, False, @@ -684,14 +650,10 @@ def connect_raster_tree_from_inner_to_outer(tree, used_offset, stitch_distance, # the entering of the child to have only minor deviations to # the desired shape. # Here is the point for the entering: - if ( - Point(result_coords[-1] - ).distance(item.nearest_point_parent) - > constants.factor_offset_starting_points * abs_offset - ): + if (Point(result_coords[-1]).distance(item.nearest_point_parent) > constants.factor_offset_starting_points * abs_offset): result_coords.append(item.nearest_point_parent.coords[0]) result_coords_origin.append( - LineStringSampling.PointSource.ENTER_LEAVING_POINT + sample_linestring.PointSource.ENTER_LEAVING_POINT ) # Check whether the number of points of the connecting lines @@ -736,7 +698,7 @@ def connect_raster_tree_from_inner_to_outer(tree, used_offset, stitch_distance, ).coords[0] ) result_coords_origin.append( - LineStringSampling.PointSource.ENTER_LEAVING_POINT + sample_linestring.PointSource.ENTER_LEAVING_POINT ) # Check whether this additional point makes the last point # of the child unnecessary @@ -753,10 +715,7 @@ def connect_raster_tree_from_inner_to_outer(tree, used_offset, stitch_distance, cur_item += 1 if i < len(own_coords) - 1: - if ( - Point(result_coords[-1]).distance(Point(own_coords[i])) - > abs_offset * constants.factor_offset_remove_points - ): + if (Point(result_coords[-1]).distance(Point(own_coords[i])) > abs_offset * constants.factor_offset_remove_points): result_coords.append(own_coords[i]) result_coords_origin.append(own_coords_origin[i]) @@ -855,7 +814,7 @@ def connect_raster_tree_spiral( abs_offset = abs(used_offset) if tree.is_leaf: - return LineStringSampling.raster_line_string_with_priority_points( + return sample_linestring.raster_line_string_with_priority_points( tree.val, 0, tree.val.length, @@ -878,7 +837,7 @@ def connect_raster_tree_spiral( node.val = part_spiral for node in PreOrderIter(tree, stop=lambda n: n.is_leaf): - (own_coords, own_coords_origin) = LineStringSampling.raster_line_string_with_priority_points( + (own_coords, own_coords_origin) = sample_linestring.raster_line_string_with_priority_points( node.val, 0, node.val.length, @@ -888,7 +847,7 @@ def connect_raster_tree_spiral( offset_by_half, False) - PointTransfer.transfer_points_to_surrounding( + point_transfer.transfer_points_to_surrounding( node, -used_offset, offset_by_half, @@ -903,7 +862,7 @@ def connect_raster_tree_spiral( # We transfer also to the overnext child to get a more straight # arrangement of points perpendicular to the stitching lines if offset_by_half: - PointTransfer.transfer_points_to_surrounding( + point_transfer.transfer_points_to_surrounding( node, -used_offset, False, @@ -921,13 +880,11 @@ def connect_raster_tree_spiral( result_coords_origin.extend(own_coords_origin) elif len(own_coords) > 0: if Point(result_coords[-1]).distance(Point(own_coords[0])) > constants.line_lengh_seen_as_one_point: - lineseg = LineString( - [result_coords[-2], result_coords[-1], own_coords[0], own_coords[1]]) + lineseg = LineString([result_coords[-2], result_coords[-1], own_coords[0], own_coords[1]]) else: - lineseg = LineString( - [result_coords[-2], result_coords[-1], own_coords[1]]) - (temp_coords, _) = LineStringSampling.raster_line_string_with_priority_points(lineseg, 0, lineseg.length, stitch_distance, - DEPQ(), abs_offset, offset_by_half, False) + lineseg = LineString([result_coords[-2], result_coords[-1], own_coords[1]]) + (temp_coords, _) = sample_linestring.raster_line_string_with_priority_points(lineseg, 0, lineseg.length, stitch_distance, + DEPQ(), abs_offset, offset_by_half, False) if len(temp_coords) == 2: # only start and end point of lineseg was needed result_coords.pop() result_coords_origin.pop() |
