move to dicty layers and targets
This commit is contained in:
parent
6b240de268
commit
9a077ea2df
23 changed files with 694 additions and 638 deletions
|
|
@ -9,7 +9,7 @@ from numpy.typing import NDArray, ArrayLike
|
|||
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_VERTICES
|
||||
from ..error import PatternError
|
||||
from ..repetition import Repetition
|
||||
from ..utils import is_scalar, layer_t, annotations_t
|
||||
from ..utils import is_scalar, annotations_t
|
||||
|
||||
|
||||
class Arc(Shape):
|
||||
|
|
@ -24,7 +24,7 @@ class Arc(Shape):
|
|||
__slots__ = (
|
||||
'_radii', '_angles', '_width', '_rotation',
|
||||
# Inherited
|
||||
'_offset', '_layer', '_repetition', '_annotations',
|
||||
'_offset', '_repetition', '_annotations',
|
||||
)
|
||||
|
||||
_radii: NDArray[numpy.float64]
|
||||
|
|
@ -156,7 +156,6 @@ class Arc(Shape):
|
|||
offset: ArrayLike = (0.0, 0.0),
|
||||
rotation: float = 0,
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
annotations: annotations_t | None = None,
|
||||
raw: bool = False,
|
||||
|
|
@ -172,7 +171,6 @@ class Arc(Shape):
|
|||
self._rotation = rotation
|
||||
self._repetition = repetition
|
||||
self._annotations = annotations if annotations is not None else {}
|
||||
self._layer = layer
|
||||
else:
|
||||
self.radii = radii
|
||||
self.angles = angles
|
||||
|
|
@ -181,7 +179,6 @@ class Arc(Shape):
|
|||
self.rotation = rotation
|
||||
self.repetition = repetition
|
||||
self.annotations = annotations if annotations is not None else {}
|
||||
self.layer = layer
|
||||
[self.mirror(a) for a, do in enumerate(mirrored) if do]
|
||||
|
||||
def __deepcopy__(self, memo: dict | None = None) -> 'Arc':
|
||||
|
|
@ -241,7 +238,7 @@ class Arc(Shape):
|
|||
ys = numpy.hstack((ys1, ys2))
|
||||
xys = numpy.vstack((xs, ys)).T
|
||||
|
||||
poly = Polygon(xys, layer=self.layer, offset=self.offset, rotation=self.rotation)
|
||||
poly = Polygon(xys, offset=self.offset, rotation=self.rotation)
|
||||
return [poly]
|
||||
|
||||
def get_bounds(self) -> NDArray[numpy.float64]:
|
||||
|
|
@ -352,13 +349,12 @@ class Arc(Shape):
|
|||
rotation %= 2 * pi
|
||||
width = self.width
|
||||
|
||||
return ((type(self), radii, angles, width / norm_value, self.layer),
|
||||
return ((type(self), radii, angles, width / norm_value),
|
||||
(self.offset, scale / norm_value, rotation, False),
|
||||
lambda: Arc(
|
||||
radii=radii * norm_value,
|
||||
angles=angles,
|
||||
width=width * norm_value,
|
||||
layer=self.layer,
|
||||
))
|
||||
|
||||
def get_cap_edges(self) -> NDArray[numpy.float64]:
|
||||
|
|
@ -415,4 +411,4 @@ class Arc(Shape):
|
|||
def __repr__(self) -> str:
|
||||
angles = f' a°{numpy.rad2deg(self.angles)}'
|
||||
rotation = f' r°{numpy.rad2deg(self.rotation):g}' if self.rotation != 0 else ''
|
||||
return f'<Arc l{self.layer} o{self.offset} r{self.radii}{angles} w{self.width:g}{rotation}>'
|
||||
return f'<Arc o{self.offset} r{self.radii}{angles} w{self.width:g}{rotation}>'
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from numpy.typing import NDArray, ArrayLike
|
|||
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_VERTICES
|
||||
from ..error import PatternError
|
||||
from ..repetition import Repetition
|
||||
from ..utils import is_scalar, layer_t, annotations_t
|
||||
from ..utils import is_scalar, annotations_t
|
||||
|
||||
|
||||
class Circle(Shape):
|
||||
|
|
@ -17,7 +17,7 @@ class Circle(Shape):
|
|||
__slots__ = (
|
||||
'_radius',
|
||||
# Inherited
|
||||
'_offset', '_layer', '_repetition', '_annotations',
|
||||
'_offset', '_repetition', '_annotations',
|
||||
)
|
||||
|
||||
_radius: float
|
||||
|
|
@ -44,7 +44,6 @@ class Circle(Shape):
|
|||
radius: float,
|
||||
*,
|
||||
offset: ArrayLike = (0.0, 0.0),
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
annotations: annotations_t | None = None,
|
||||
raw: bool = False,
|
||||
|
|
@ -55,13 +54,11 @@ class Circle(Shape):
|
|||
self._offset = offset
|
||||
self._repetition = repetition
|
||||
self._annotations = annotations if annotations is not None else {}
|
||||
self._layer = layer
|
||||
else:
|
||||
self.radius = radius
|
||||
self.offset = offset
|
||||
self.repetition = repetition
|
||||
self.annotations = annotations if annotations is not None else {}
|
||||
self.layer = layer
|
||||
|
||||
def __deepcopy__(self, memo: dict | None = None) -> 'Circle':
|
||||
memo = {} if memo is None else memo
|
||||
|
|
@ -90,7 +87,7 @@ class Circle(Shape):
|
|||
ys = numpy.sin(thetas) * self.radius
|
||||
xys = numpy.vstack((xs, ys)).T
|
||||
|
||||
return [Polygon(xys, offset=self.offset, layer=self.layer)]
|
||||
return [Polygon(xys, offset=self.offset)]
|
||||
|
||||
def get_bounds(self) -> NDArray[numpy.float64]:
|
||||
return numpy.vstack((self.offset - self.radius,
|
||||
|
|
@ -110,9 +107,9 @@ class Circle(Shape):
|
|||
def normalized_form(self, norm_value) -> normalized_shape_tuple:
|
||||
rotation = 0.0
|
||||
magnitude = self.radius / norm_value
|
||||
return ((type(self), self.layer),
|
||||
return ((type(self),),
|
||||
(self.offset, magnitude, rotation, False),
|
||||
lambda: Circle(radius=norm_value, layer=self.layer))
|
||||
lambda: Circle(radius=norm_value))
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'<Circle l{self.layer} o{self.offset} r{self.radius:g}>'
|
||||
return f'<Circle o{self.offset} r{self.radius:g}>'
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from numpy.typing import ArrayLike, NDArray
|
|||
from . import Shape, Polygon, normalized_shape_tuple, DEFAULT_POLY_NUM_VERTICES
|
||||
from ..error import PatternError
|
||||
from ..repetition import Repetition
|
||||
from ..utils import is_scalar, rotation_matrix_2d, layer_t, annotations_t
|
||||
from ..utils import is_scalar, rotation_matrix_2d, annotations_t
|
||||
|
||||
|
||||
class Ellipse(Shape):
|
||||
|
|
@ -20,7 +20,7 @@ class Ellipse(Shape):
|
|||
__slots__ = (
|
||||
'_radii', '_rotation',
|
||||
# Inherited
|
||||
'_offset', '_layer', '_repetition', '_annotations',
|
||||
'_offset', '_repetition', '_annotations',
|
||||
)
|
||||
|
||||
_radii: NDArray[numpy.float64]
|
||||
|
|
@ -91,7 +91,6 @@ class Ellipse(Shape):
|
|||
offset: ArrayLike = (0.0, 0.0),
|
||||
rotation: float = 0,
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
annotations: annotations_t | None = None,
|
||||
raw: bool = False,
|
||||
|
|
@ -104,14 +103,12 @@ class Ellipse(Shape):
|
|||
self._rotation = rotation
|
||||
self._repetition = repetition
|
||||
self._annotations = annotations if annotations is not None else {}
|
||||
self._layer = layer
|
||||
else:
|
||||
self.radii = radii
|
||||
self.offset = offset
|
||||
self.rotation = rotation
|
||||
self.repetition = repetition
|
||||
self.annotations = annotations if annotations is not None else {}
|
||||
self.layer = layer
|
||||
[self.mirror(a) for a, do in enumerate(mirrored) if do]
|
||||
|
||||
def __deepcopy__(self, memo: dict | None = None) -> 'Ellipse':
|
||||
|
|
@ -152,7 +149,7 @@ class Ellipse(Shape):
|
|||
ys = r1 * sin_th
|
||||
xys = numpy.vstack((xs, ys)).T
|
||||
|
||||
poly = Polygon(xys, layer=self.layer, offset=self.offset, rotation=self.rotation)
|
||||
poly = Polygon(xys, offset=self.offset, rotation=self.rotation)
|
||||
return [poly]
|
||||
|
||||
def get_bounds(self) -> NDArray[numpy.float64]:
|
||||
|
|
@ -183,10 +180,10 @@ class Ellipse(Shape):
|
|||
radii = self.radii[::-1] / self.radius_y
|
||||
scale = self.radius_y
|
||||
angle = (self.rotation + pi / 2) % pi
|
||||
return ((type(self), radii, self.layer),
|
||||
return ((type(self), radii),
|
||||
(self.offset, scale / norm_value, angle, False),
|
||||
lambda: Ellipse(radii=radii * norm_value, layer=self.layer))
|
||||
lambda: Ellipse(radii=radii * norm_value))
|
||||
|
||||
def __repr__(self) -> str:
|
||||
rotation = f' r{self.rotation*180/pi:g}' if self.rotation != 0 else ''
|
||||
return f'<Ellipse l{self.layer} o{self.offset} r{self.radii}{rotation}>'
|
||||
rotation = f' r{numpy.rad2deg(self.rotation):g}' if self.rotation != 0 else ''
|
||||
return f'<Ellipse o{self.offset} r{self.radii}{rotation}>'
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from numpy.typing import NDArray, ArrayLike
|
|||
from . import Shape, normalized_shape_tuple, Polygon, Circle
|
||||
from ..error import PatternError
|
||||
from ..repetition import Repetition
|
||||
from ..utils import is_scalar, rotation_matrix_2d, layer_t
|
||||
from ..utils import is_scalar, rotation_matrix_2d
|
||||
from ..utils import remove_colinear_vertices, remove_duplicate_vertices, annotations_t
|
||||
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ class Path(Shape):
|
|||
__slots__ = (
|
||||
'_vertices', '_width', '_cap', '_cap_extensions',
|
||||
# Inherited
|
||||
'_offset', '_layer', '_repetition', '_annotations',
|
||||
'_offset', '_repetition', '_annotations',
|
||||
)
|
||||
_vertices: NDArray[numpy.float64]
|
||||
_width: float
|
||||
|
|
@ -154,7 +154,6 @@ class Path(Shape):
|
|||
offset: ArrayLike = (0.0, 0.0),
|
||||
rotation: float = 0,
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
annotations: annotations_t | None = None,
|
||||
raw: bool = False,
|
||||
|
|
@ -169,7 +168,6 @@ class Path(Shape):
|
|||
self._offset = offset
|
||||
self._repetition = repetition
|
||||
self._annotations = annotations if annotations is not None else {}
|
||||
self._layer = layer
|
||||
self._width = width
|
||||
self._cap = cap
|
||||
self._cap_extensions = cap_extensions
|
||||
|
|
@ -178,7 +176,6 @@ class Path(Shape):
|
|||
self.offset = offset
|
||||
self.repetition = repetition
|
||||
self.annotations = annotations if annotations is not None else {}
|
||||
self.layer = layer
|
||||
self.width = width
|
||||
self.cap = cap
|
||||
self.cap_extensions = cap_extensions
|
||||
|
|
@ -204,7 +201,6 @@ class Path(Shape):
|
|||
offset: ArrayLike = (0.0, 0.0),
|
||||
rotation: float = 0,
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
) -> 'Path':
|
||||
"""
|
||||
Build a path by specifying the turn angles and travel distances
|
||||
|
|
@ -224,7 +220,6 @@ class Path(Shape):
|
|||
mirrored: Whether to mirror across the x or y axes. For example,
|
||||
`mirrored=(True, False)` results in a reflection across the x-axis,
|
||||
multiplying the path's y-coordinates by -1. Default `(False, False)`
|
||||
layer: Layer, default `0`
|
||||
|
||||
Returns:
|
||||
The resulting Path object
|
||||
|
|
@ -238,8 +233,7 @@ class Path(Shape):
|
|||
verts.append(verts[-1] + direction * distance)
|
||||
|
||||
return Path(vertices=verts, width=width, cap=cap, cap_extensions=cap_extensions,
|
||||
offset=offset, rotation=rotation, mirrored=mirrored,
|
||||
layer=layer)
|
||||
offset=offset, rotation=rotation, mirrored=mirrored)
|
||||
|
||||
def to_polygons(
|
||||
self,
|
||||
|
|
@ -254,7 +248,7 @@ class Path(Shape):
|
|||
|
||||
if self.width == 0:
|
||||
verts = numpy.vstack((v, v[::-1]))
|
||||
return [Polygon(offset=self.offset, vertices=verts, layer=self.layer)]
|
||||
return [Polygon(offset=self.offset, vertices=verts)]
|
||||
|
||||
perp = dvdir[:, ::-1] * [[1, -1]] * self.width / 2
|
||||
|
||||
|
|
@ -305,12 +299,12 @@ class Path(Shape):
|
|||
o1.append(v[-1] - perp[-1])
|
||||
verts = numpy.vstack((o0, o1[::-1]))
|
||||
|
||||
polys = [Polygon(offset=self.offset, vertices=verts, layer=self.layer)]
|
||||
polys = [Polygon(offset=self.offset, vertices=verts)]
|
||||
|
||||
if self.cap == PathCap.Circle:
|
||||
#for vert in v: # not sure if every vertex, or just ends?
|
||||
for vert in [v[0], v[-1]]:
|
||||
circ = Circle(offset=vert, radius=self.width / 2, layer=self.layer)
|
||||
circ = Circle(offset=vert, radius=self.width / 2)
|
||||
polys += circ.to_polygons(num_vertices=num_vertices, max_arclen=max_arclen)
|
||||
|
||||
return polys
|
||||
|
|
@ -370,13 +364,12 @@ class Path(Shape):
|
|||
|
||||
width0 = self.width / norm_value
|
||||
|
||||
return ((type(self), reordered_vertices.data.tobytes(), width0, self.cap, self.layer),
|
||||
return ((type(self), reordered_vertices.data.tobytes(), width0, self.cap),
|
||||
(offset, scale / norm_value, rotation, False),
|
||||
lambda: Path(
|
||||
reordered_vertices * norm_value,
|
||||
width=self.width * norm_value,
|
||||
cap=self.cap,
|
||||
layer=self.layer,
|
||||
))
|
||||
|
||||
def clean_vertices(self) -> 'Path':
|
||||
|
|
@ -422,4 +415,4 @@ class Path(Shape):
|
|||
|
||||
def __repr__(self) -> str:
|
||||
centroid = self.offset + self.vertices.mean(axis=0)
|
||||
return f'<Path l{self.layer} centroid {centroid} v{len(self.vertices)} w{self.width} c{self.cap}>'
|
||||
return f'<Path centroid {centroid} v{len(self.vertices)} w{self.width} c{self.cap}>'
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from numpy.typing import NDArray, ArrayLike
|
|||
from . import Shape, normalized_shape_tuple
|
||||
from ..error import PatternError
|
||||
from ..repetition import Repetition
|
||||
from ..utils import is_scalar, rotation_matrix_2d, layer_t
|
||||
from ..utils import is_scalar, rotation_matrix_2d
|
||||
from ..utils import remove_colinear_vertices, remove_duplicate_vertices, annotations_t
|
||||
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ class Polygon(Shape):
|
|||
__slots__ = (
|
||||
'_vertices',
|
||||
# Inherited
|
||||
'_offset', '_layer', '_repetition', '_annotations',
|
||||
'_offset', '_repetition', '_annotations',
|
||||
)
|
||||
|
||||
_vertices: NDArray[numpy.float64]
|
||||
|
|
@ -82,7 +82,6 @@ class Polygon(Shape):
|
|||
offset: ArrayLike = (0.0, 0.0),
|
||||
rotation: float = 0.0,
|
||||
mirrored: Sequence[bool] = (False, False),
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
annotations: annotations_t | None = None,
|
||||
raw: bool = False,
|
||||
|
|
@ -94,13 +93,11 @@ class Polygon(Shape):
|
|||
self._offset = offset
|
||||
self._repetition = repetition
|
||||
self._annotations = annotations if annotations is not None else {}
|
||||
self._layer = layer
|
||||
else:
|
||||
self.vertices = vertices
|
||||
self.offset = offset
|
||||
self.repetition = repetition
|
||||
self.annotations = annotations if annotations is not None else {}
|
||||
self.layer = layer
|
||||
self.rotate(rotation)
|
||||
[self.mirror(a) for a, do in enumerate(mirrored) if do]
|
||||
|
||||
|
|
@ -118,7 +115,6 @@ class Polygon(Shape):
|
|||
*,
|
||||
rotation: float = 0.0,
|
||||
offset: ArrayLike = (0.0, 0.0),
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
) -> 'Polygon':
|
||||
"""
|
||||
|
|
@ -128,7 +124,6 @@ class Polygon(Shape):
|
|||
side_length: Length of one side
|
||||
rotation: Rotation counterclockwise, in radians
|
||||
offset: Offset, default `(0, 0)`
|
||||
layer: Layer, default `0`
|
||||
repetition: `Repetition` object, default `None`
|
||||
|
||||
Returns:
|
||||
|
|
@ -139,7 +134,7 @@ class Polygon(Shape):
|
|||
[+1, +1],
|
||||
[+1, -1]], dtype=float)
|
||||
vertices = 0.5 * side_length * norm_square
|
||||
poly = Polygon(vertices, offset=offset, layer=layer, repetition=repetition)
|
||||
poly = Polygon(vertices, offset=offset, repetition=repetition)
|
||||
poly.rotate(rotation)
|
||||
return poly
|
||||
|
||||
|
|
@ -150,7 +145,6 @@ class Polygon(Shape):
|
|||
*,
|
||||
rotation: float = 0,
|
||||
offset: ArrayLike = (0.0, 0.0),
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
) -> 'Polygon':
|
||||
"""
|
||||
|
|
@ -161,7 +155,6 @@ class Polygon(Shape):
|
|||
ly: Length along y (before rotation)
|
||||
rotation: Rotation counterclockwise, in radians
|
||||
offset: Offset, default `(0, 0)`
|
||||
layer: Layer, default `0`
|
||||
repetition: `Repetition` object, default `None`
|
||||
|
||||
Returns:
|
||||
|
|
@ -171,7 +164,7 @@ class Polygon(Shape):
|
|||
[-lx, +ly],
|
||||
[+lx, +ly],
|
||||
[+lx, -ly]], dtype=float)
|
||||
poly = Polygon(vertices, offset=offset, layer=layer, repetition=repetition)
|
||||
poly = Polygon(vertices, offset=offset, repetition=repetition)
|
||||
poly.rotate(rotation)
|
||||
return poly
|
||||
|
||||
|
|
@ -186,7 +179,6 @@ class Polygon(Shape):
|
|||
yctr: float | None = None,
|
||||
ymax: float | None = None,
|
||||
ly: float | None = None,
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
) -> 'Polygon':
|
||||
"""
|
||||
|
|
@ -204,7 +196,6 @@ class Polygon(Shape):
|
|||
yctr: Center y coordinate
|
||||
ymax: Maximum y coordinate
|
||||
ly: Length along y direction
|
||||
layer: Layer, default `0`
|
||||
repetition: `Repetition` object, default `None`
|
||||
|
||||
Returns:
|
||||
|
|
@ -270,7 +261,7 @@ class Polygon(Shape):
|
|||
else:
|
||||
raise PatternError('Two of ymin, yctr, ymax, ly must be None!')
|
||||
|
||||
poly = Polygon.rectangle(lx, ly, offset=(xctr, yctr), layer=layer, repetition=repetition)
|
||||
poly = Polygon.rectangle(lx, ly, offset=(xctr, yctr), repetition=repetition)
|
||||
return poly
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -281,7 +272,6 @@ class Polygon(Shape):
|
|||
regular: bool = True,
|
||||
center: ArrayLike = (0.0, 0.0),
|
||||
rotation: float = 0.0,
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
) -> 'Polygon':
|
||||
"""
|
||||
|
|
@ -300,7 +290,6 @@ class Polygon(Shape):
|
|||
rotation: Rotation counterclockwise, in radians.
|
||||
`0` results in four axis-aligned sides (the long sides of the
|
||||
irregular octagon).
|
||||
layer: Layer, default `0`
|
||||
repetition: `Repetition` object, default `None`
|
||||
|
||||
Returns:
|
||||
|
|
@ -327,7 +316,7 @@ class Polygon(Shape):
|
|||
side_length = 2 * inner_radius / s
|
||||
|
||||
vertices = 0.5 * side_length * norm_oct
|
||||
poly = Polygon(vertices, offset=center, layer=layer, repetition=repetition)
|
||||
poly = Polygon(vertices, offset=center, repetition=repetition)
|
||||
poly.rotate(rotation)
|
||||
return poly
|
||||
|
||||
|
|
@ -378,9 +367,9 @@ class Polygon(Shape):
|
|||
|
||||
# TODO: normalize mirroring?
|
||||
|
||||
return ((type(self), reordered_vertices.data.tobytes(), self.layer),
|
||||
return ((type(self), reordered_vertices.data.tobytes()),
|
||||
(offset, scale / norm_value, rotation, False),
|
||||
lambda: Polygon(reordered_vertices * norm_value, layer=self.layer))
|
||||
lambda: Polygon(reordered_vertices * norm_value))
|
||||
|
||||
def clean_vertices(self) -> 'Polygon':
|
||||
"""
|
||||
|
|
@ -414,4 +403,4 @@ class Polygon(Shape):
|
|||
|
||||
def __repr__(self) -> str:
|
||||
centroid = self.offset + self.vertices.mean(axis=0)
|
||||
return f'<Polygon l{self.layer} centroid {centroid} v{len(self.vertices)}>'
|
||||
return f'<Polygon centroid {centroid} v{len(self.vertices)}>'
|
||||
|
|
|
|||
|
|
@ -5,9 +5,8 @@ import numpy
|
|||
from numpy.typing import NDArray, ArrayLike
|
||||
|
||||
from ..traits import (
|
||||
Rotatable, Mirrorable, Copyable, Scalable,
|
||||
PositionableImpl, LayerableImpl,
|
||||
PivotableImpl, RepeatableImpl, AnnotatableImpl,
|
||||
Rotatable, Mirrorable, Copyable, Scalable, Bounded,
|
||||
PositionableImpl, PivotableImpl, RepeatableImpl, AnnotatableImpl,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -26,7 +25,7 @@ normalized_shape_tuple = tuple[
|
|||
DEFAULT_POLY_NUM_VERTICES = 24
|
||||
|
||||
|
||||
class Shape(PositionableImpl, LayerableImpl, Rotatable, Mirrorable, Copyable, Scalable,
|
||||
class Shape(PositionableImpl, Rotatable, Mirrorable, Copyable, Scalable, Bounded,
|
||||
PivotableImpl, RepeatableImpl, AnnotatableImpl, metaclass=ABCMeta):
|
||||
"""
|
||||
Class specifying functions common to all shapes.
|
||||
|
|
@ -194,10 +193,7 @@ class Shape(PositionableImpl, LayerableImpl, Rotatable, Mirrorable, Copyable, Sc
|
|||
vertex_lists.append(vlist)
|
||||
polygon_contours.append(numpy.vstack(vertex_lists))
|
||||
|
||||
manhattan_polygons = [
|
||||
Polygon(vertices=contour, layer=self.layer)
|
||||
for contour in polygon_contours
|
||||
]
|
||||
manhattan_polygons = [Polygon(vertices=contour) for contour in polygon_contours]
|
||||
|
||||
return manhattan_polygons
|
||||
|
||||
|
|
@ -292,9 +288,6 @@ class Shape(PositionableImpl, LayerableImpl, Rotatable, Mirrorable, Copyable, Sc
|
|||
vertices = numpy.hstack((grx[snapped_contour[:, None, 0] + offset_i[0]],
|
||||
gry[snapped_contour[:, None, 1] + offset_i[1]]))
|
||||
|
||||
manhattan_polygons.append(Polygon(
|
||||
vertices=vertices,
|
||||
layer=self.layer,
|
||||
))
|
||||
manhattan_polygons.append(Polygon(vertices=vertices))
|
||||
|
||||
return manhattan_polygons
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from . import Shape, Polygon, normalized_shape_tuple
|
|||
from ..error import PatternError
|
||||
from ..repetition import Repetition
|
||||
from ..traits import RotatableImpl
|
||||
from ..utils import is_scalar, get_bit, normalize_mirror, layer_t
|
||||
from ..utils import is_scalar, get_bit, normalize_mirror
|
||||
from ..utils import annotations_t
|
||||
|
||||
# Loaded on use:
|
||||
|
|
@ -25,7 +25,7 @@ class Text(RotatableImpl, Shape):
|
|||
__slots__ = (
|
||||
'_string', '_height', '_mirrored', 'font_path',
|
||||
# Inherited
|
||||
'_offset', '_layer', '_repetition', '_annotations', '_rotation',
|
||||
'_offset', '_repetition', '_annotations', '_rotation',
|
||||
)
|
||||
|
||||
_string: str
|
||||
|
|
@ -73,7 +73,6 @@ class Text(RotatableImpl, Shape):
|
|||
offset: ArrayLike = (0.0, 0.0),
|
||||
rotation: float = 0.0,
|
||||
mirrored: ArrayLike = (False, False),
|
||||
layer: layer_t = 0,
|
||||
repetition: Repetition | None = None,
|
||||
annotations: annotations_t | None = None,
|
||||
raw: bool = False,
|
||||
|
|
@ -82,7 +81,6 @@ class Text(RotatableImpl, Shape):
|
|||
assert isinstance(offset, numpy.ndarray)
|
||||
assert isinstance(mirrored, numpy.ndarray)
|
||||
self._offset = offset
|
||||
self._layer = layer
|
||||
self._string = string
|
||||
self._height = height
|
||||
self._rotation = rotation
|
||||
|
|
@ -91,7 +89,6 @@ class Text(RotatableImpl, Shape):
|
|||
self._annotations = annotations if annotations is not None else {}
|
||||
else:
|
||||
self.offset = offset
|
||||
self.layer = layer
|
||||
self.string = string
|
||||
self.height = height
|
||||
self.rotation = rotation
|
||||
|
|
@ -120,7 +117,7 @@ class Text(RotatableImpl, Shape):
|
|||
|
||||
# Move these polygons to the right of the previous letter
|
||||
for xys in raw_polys:
|
||||
poly = Polygon(xys, layer=self.layer)
|
||||
poly = Polygon(xys)
|
||||
poly.mirror2d(self.mirrored)
|
||||
poly.scale_by(self.height)
|
||||
poly.offset = self.offset + [total_advance, 0]
|
||||
|
|
@ -144,7 +141,7 @@ class Text(RotatableImpl, Shape):
|
|||
mirror_x, rotation = normalize_mirror(self.mirrored)
|
||||
rotation += self.rotation
|
||||
rotation %= 2 * pi
|
||||
return ((type(self), self.string, self.font_path, self.layer),
|
||||
return ((type(self), self.string, self.font_path),
|
||||
(self.offset, self.height / norm_value, rotation, mirror_x),
|
||||
lambda: Text(
|
||||
string=self.string,
|
||||
|
|
@ -152,7 +149,6 @@ class Text(RotatableImpl, Shape):
|
|||
font_path=self.font_path,
|
||||
rotation=rotation,
|
||||
mirrored=(mirror_x, False),
|
||||
layer=self.layer,
|
||||
))
|
||||
|
||||
def get_bounds(self) -> NDArray[numpy.float64]:
|
||||
|
|
@ -256,6 +252,6 @@ def get_char_as_polygons(
|
|||
return polygons, advance
|
||||
|
||||
def __repr__(self) -> str:
|
||||
rotation = f' r°{self.rotation*180/pi:g}' if self.rotation != 0 else ''
|
||||
rotation = f' r°{numpy.rad2deg(self.rotation):g}' if self.rotation != 0 else ''
|
||||
mirrored = ' m{:d}{:d}'.format(*self.mirrored) if self.mirrored.any() else ''
|
||||
return f'<TextShape "{self.string}" l{self.layer} o{self.offset} h{self.height:g}{rotation}{mirrored}>'
|
||||
return f'<TextShape "{self.string}" o{self.offset} h{self.height:g}{rotation}{mirrored}>'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue