Compare commits

..

No commits in common. "3a73fb1d60502a20e00f4558f9f7a89e223c8685" and "f78ba3655e6fd6cf50a93e252d0d69608e750943" have entirely different histories.

3 changed files with 20 additions and 49 deletions

View File

@ -40,7 +40,7 @@ from pyarrow.cffi import ffi
from .utils import is_gzipped, tmpfile from .utils import is_gzipped, tmpfile
from .. import Pattern, Ref, PatternError, LibraryError, Label, Shape from .. import Pattern, Ref, PatternError, LibraryError, Label, Shape
from ..shapes import Polygon, Path, PolyCollection from ..shapes import Polygon, Path
from ..repetition import Grid from ..repetition import Grid
from ..utils import layer_t, annotations_t from ..utils import layer_t, annotations_t
from ..library import LazyLibrary, Library, ILibrary, ILibraryView from ..library import LazyLibrary, Library, ILibrary, ILibraryView
@ -267,10 +267,10 @@ def _grefs_to_mrefs(
a_count, b_count = elem_rep_counts[ee] a_count, b_count = elem_rep_counts[ee]
rep = Grid(a_vector=a_vector, b_vector=b_vector, a_count=a_count, b_count=b_count) rep = Grid(a_vector=a_vector, b_vector=b_vector, a_count=a_count, b_count=b_count)
annotations: None | dict[str, list[int | float | str]] = None annotations: None | dict[int, str] = None
prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1] prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1]
if prop_ii < prop_ff: if prop_ii < prop_ff:
annotations = {str(prop_key[off]): [prop_val[off]] for off in range(prop_ii, prop_ff)} annotations = {prop_key[off]: prop_val[off] for off in range(prop_ii, prop_ff)}
ref = Ref(offset=offset, mirrored=mirr, rotation=rot, scale=mag, repetition=rep, annotations=annotations) ref = Ref(offset=offset, mirrored=mirr, rotation=rot, scale=mag, repetition=rep, annotations=annotations)
pat.refs[target].append(ref) pat.refs[target].append(ref)
@ -300,10 +300,10 @@ def _texts_to_labels(
offset = xy[ee] offset = xy[ee]
string = elem_strings[ee] string = elem_strings[ee]
annotations: None | dict[str, list[int | float | str]] = None annotations: None | dict[int, str] = None
prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1] prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1]
if prop_ii < prop_ff: if prop_ii < prop_ff:
annotations = {str(prop_key[off]): [prop_val[off]] for off in range(prop_ii, prop_ff)} annotations = {prop_key[off]: prop_val[off] for off in range(prop_ii, prop_ff)}
mlabel = Label(string=string, offset=offset, annotations=annotations) mlabel = Label(string=string, offset=offset, annotations=annotations)
pat.labels[layer].append(mlabel) pat.labels[layer].append(mlabel)
@ -344,10 +344,10 @@ def _gpaths_to_mpaths(
else: else:
cap_extensions = None cap_extensions = None
annotations: None | dict[str, list[int | float | str]] = None annotations: None | dict[int, str] = None
prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1] prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1]
if prop_ii < prop_ff: if prop_ii < prop_ff:
annotations = {str(prop_key[off]): [prop_val[off]] for off in range(prop_ii, prop_ff)} annotations = {prop_key[off]: prop_val[off] for off in range(prop_ii, prop_ff)}
path = Path(vertices=vertices, offset=zeros[ee], annotations=annotations, raw=raw_mode, path = Path(vertices=vertices, offset=zeros[ee], annotations=annotations, raw=raw_mode,
width=width, cap=cap,cap_extensions=cap_extensions) width=width, cap=cap,cap_extensions=cap_extensions)
@ -370,43 +370,19 @@ def _boundaries_to_polygons(
elem_count = elem_off[cc + 1] - elem_off[cc] elem_count = elem_off[cc + 1] - elem_off[cc]
elem_slc = slice(elem_off[cc], elem_off[cc] + elem_count + 1) # +1 to capture ending location for last elem elem_slc = slice(elem_off[cc], elem_off[cc] + elem_count + 1) # +1 to capture ending location for last elem
xy_offs = elem['xy_off'][elem_slc] # which xy coords belong to each element xy_offs = elem['xy_off'][elem_slc] # which xy coords belong to each element
xy_counts = xy_offs[1:] - xy_offs[:-1]
prop_offs = elem['prop_off'][elem_slc] # which props belong to each element prop_offs = elem['prop_off'][elem_slc] # which props belong to each element
prop_counts = prop_offs[1:] - prop_offs[:-1]
elem_layer_inds = layer_inds[elem_slc] elem_layer_inds = layer_inds[elem_slc]
order = numpy.argsort(elem_layer_inds, stable=True)
unilayer_inds, unilayer_first, unilayer_count = numpy.unique(elem_layer_inds, return_indices=True, return_counts=True)
zeros = numpy.zeros((elem_count, 2)) zeros = numpy.zeros((elem_count, 2))
raw_mode = global_args['raw_mode'] raw_mode = global_args['raw_mode']
for layer_ind, ff, cc in zip(unilayer_inds, unilayer_first, unilayer_count, strict=True): for ee in range(elem_count):
ee_inds = order[ff:ff + cc]
layer = layer_tups[layer_ind]
propless_mask = prop_counts[ee_inds] == 0
if propless_mask.sum() == 1:
propless_mask[:] = 0 # Never make a 1-element collection
propless_vert_counts = xy_counts[ee_inds[propless_mask]] - 1 # -1 to drop closing point
vertex_lists = numpy.empty((propless_vert_counts.sum(), 2), dtype=numpy.float64)
vertex_offsets = numpy.cumsum(propless_vert_counts) - propless_vert_counts[0]
for ii, ee in enumerate(ee_inds[propless_mask]):
vo = vertex_offsets[ii]
vertex_lists[vo:vo + propless_vert_counts[ii]] = xy_val[xy_offs[ee]:xy_offs[ee + 1] - 1]
polys = PolyCollection(vertex_lists=vertex_lists, vertex_offsets=vertex_offsets, offset=zeros[ee])
pat.shapes[layer].append(polys)
# Handle single polygons
for ee in ee_inds[~propless_mask]:
layer = layer_tups[elem_layer_inds[ee]] layer = layer_tups[elem_layer_inds[ee]]
vertices = xy_val[xy_offs[ee]:xy_offs[ee + 1] - 1] # -1 to drop closing point vertices = xy_val[xy_offs[ee]:xy_offs[ee + 1] - 1] # -1 to drop closing point
annotations: None | dict[str, list[int | float | str]] = None annotations: None | dict[int, str] = None
prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1] prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1]
if prop_ii < prop_ff: if prop_ii < prop_ff:
annotations = {str(prop_key[off]): prop_val[off] for off in range(prop_ii, prop_ff)} annotations = {prop_key[off]: prop_val[off] for off in range(prop_ii, prop_ff)}
poly = Polygon(vertices=vertices, offset=zeros[ee], annotations=annotations, raw=raw_mode) poly = Polygon(vertices=vertices, offset=zeros[ee], annotations=annotations, raw=raw_mode)
pat.shapes[layer].append(poly) pat.shapes[layer].append(poly)

View File

@ -10,7 +10,6 @@ from .shape import (
) )
from .polygon import Polygon as Polygon from .polygon import Polygon as Polygon
from .poly_collection import PolyCollection as PolyCollection
from .circle import Circle as Circle from .circle import Circle as Circle
from .ellipse import Ellipse as Ellipse from .ellipse import Ellipse as Ellipse
from .arc import Arc as Arc from .arc import Arc as Arc

View File

@ -55,11 +55,7 @@ class PolyCollection(Shape):
""" """
Iterator which provides slices which index vertex_lists Iterator which provides slices which index vertex_lists
""" """
for ii, ff in zip( for ii, ff in chain(self._vertex_offsets, (self._vertex_lists.shape[0],)):
self._vertex_offsets,
chain(self._vertex_offsets, (self._vertex_lists.shape[0],)),
strict=True,
):
yield slice(ii, ff) yield slice(ii, ff)
@property @property
@ -148,7 +144,7 @@ class PolyCollection(Shape):
return [Polygon( return [Polygon(
vertices = vv, vertices = vv,
offset = self.offset, offset = self.offset,
repetition = copy.deepcopy(self.repetition), repetition = self.repetition.copy(),
annotations = copy.deepcopy(self.annotations), annotations = copy.deepcopy(self.annotations),
) for vv in self.polygon_vertices] ) for vv in self.polygon_vertices]
@ -159,7 +155,7 @@ class PolyCollection(Shape):
def rotate(self, theta: float) -> Self: def rotate(self, theta: float) -> Self:
if theta != 0: if theta != 0:
rot = rotation_matrix_2d(theta) rot = rotation_matrix_2d(theta)
self._vertex_lists = numpy.einsum('ij,kj->ki', rot, self._vertex_lists) self._vertex_lists = numpy.einsum('ij,kj->ki', rot, self._vertex_lists_)
return self return self
def mirror(self, axis: int = 0) -> Self: def mirror(self, axis: int = 0) -> Self:
@ -167,7 +163,7 @@ class PolyCollection(Shape):
return self return self
def scale_by(self, c: float) -> Self: def scale_by(self, c: float) -> Self:
self._vertex_lists *= c self.vertex_lists *= c
return self return self
def normalized_form(self, norm_value: float) -> normalized_shape_tuple: def normalized_form(self, norm_value: float) -> normalized_shape_tuple: