Compare commits
3 Commits
f78ba3655e
...
3a73fb1d60
Author | SHA1 | Date | |
---|---|---|---|
3a73fb1d60 | |||
25cde0abb5 | |||
2ef7a6e9e3 |
@ -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
|
from ..shapes import Polygon, Path, PolyCollection
|
||||||
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[int, str] = None
|
annotations: None | dict[str, list[int | float | 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 = {prop_key[off]: prop_val[off] for off in range(prop_ii, prop_ff)}
|
annotations = {str(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[int, str] = None
|
annotations: None | dict[str, list[int | float | 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 = {prop_key[off]: prop_val[off] for off in range(prop_ii, prop_ff)}
|
annotations = {str(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[int, str] = None
|
annotations: None | dict[str, list[int | float | 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 = {prop_key[off]: prop_val[off] for off in range(prop_ii, prop_ff)}
|
annotations = {str(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,22 +370,46 @@ 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 ee in range(elem_count):
|
for layer_ind, ff, cc in zip(unilayer_inds, unilayer_first, unilayer_count, strict=True):
|
||||||
layer = layer_tups[elem_layer_inds[ee]]
|
ee_inds = order[ff:ff + cc]
|
||||||
vertices = xy_val[xy_offs[ee]:xy_offs[ee + 1] - 1] # -1 to drop closing point
|
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
|
||||||
|
|
||||||
annotations: None | dict[int, str] = None
|
propless_vert_counts = xy_counts[ee_inds[propless_mask]] - 1 # -1 to drop closing point
|
||||||
prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1]
|
vertex_lists = numpy.empty((propless_vert_counts.sum(), 2), dtype=numpy.float64)
|
||||||
if prop_ii < prop_ff:
|
vertex_offsets = numpy.cumsum(propless_vert_counts) - propless_vert_counts[0]
|
||||||
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)
|
for ii, ee in enumerate(ee_inds[propless_mask]):
|
||||||
pat.shapes[layer].append(poly)
|
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]]
|
||||||
|
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
|
||||||
|
prop_ii, prop_ff = prop_offs[ee], prop_offs[ee + 1]
|
||||||
|
if prop_ii < prop_ff:
|
||||||
|
annotations = {str(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)
|
||||||
|
pat.shapes[layer].append(poly)
|
||||||
|
|
||||||
|
|
||||||
#def _properties_to_annotations(properties: pyarrow.Array) -> annotations_t:
|
#def _properties_to_annotations(properties: pyarrow.Array) -> annotations_t:
|
||||||
|
@ -10,6 +10,7 @@ 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
|
||||||
|
@ -55,7 +55,11 @@ class PolyCollection(Shape):
|
|||||||
"""
|
"""
|
||||||
Iterator which provides slices which index vertex_lists
|
Iterator which provides slices which index vertex_lists
|
||||||
"""
|
"""
|
||||||
for ii, ff in chain(self._vertex_offsets, (self._vertex_lists.shape[0],)):
|
for ii, ff in zip(
|
||||||
|
self._vertex_offsets,
|
||||||
|
chain(self._vertex_offsets, (self._vertex_lists.shape[0],)),
|
||||||
|
strict=True,
|
||||||
|
):
|
||||||
yield slice(ii, ff)
|
yield slice(ii, ff)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -144,7 +148,7 @@ class PolyCollection(Shape):
|
|||||||
return [Polygon(
|
return [Polygon(
|
||||||
vertices = vv,
|
vertices = vv,
|
||||||
offset = self.offset,
|
offset = self.offset,
|
||||||
repetition = self.repetition.copy(),
|
repetition = copy.deepcopy(self.repetition),
|
||||||
annotations = copy.deepcopy(self.annotations),
|
annotations = copy.deepcopy(self.annotations),
|
||||||
) for vv in self.polygon_vertices]
|
) for vv in self.polygon_vertices]
|
||||||
|
|
||||||
@ -155,7 +159,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:
|
||||||
@ -163,7 +167,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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user