adjusting namings

pull/1548/head
Andreas 2022-02-02 21:19:31 +01:00 zatwierdzone przez Kaalleen
rodzic b14e445dae
commit d514eac819
10 zmienionych plików z 87 dodań i 466 usunięć

Wyświetl plik

@ -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,

Wyświetl plik

@ -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)

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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)

Wyświetl plik

@ -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))

Wyświetl plik

@ -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()