whitespace
This commit is contained in:
parent
4d58516049
commit
599723e470
@ -267,10 +267,12 @@ def _read_block(block, clean_vertices: bool) -> Pattern:
|
||||
}
|
||||
|
||||
if 'column_count' in attr:
|
||||
args['repetition'] = Grid(a_vector=(attr['column_spacing'], 0),
|
||||
args['repetition'] = Grid(
|
||||
a_vector=(attr['column_spacing'], 0),
|
||||
b_vector=(0, attr['row_spacing']),
|
||||
a_count=attr['column_count'],
|
||||
b_count=attr['row_count'])
|
||||
b_count=attr['row_count'],
|
||||
)
|
||||
pat.subpatterns.append(SubPattern(**args))
|
||||
else:
|
||||
logger.warning(f'Ignoring DXF element {element.dxftype()} (not implemented).')
|
||||
|
@ -114,9 +114,11 @@ def write(
|
||||
patterns = [p.wrap_repeated_shapes() for p in patterns]
|
||||
|
||||
# Create library
|
||||
header = klamath.library.FileHeader(name=library_name.encode('ASCII'),
|
||||
header = klamath.library.FileHeader(
|
||||
name=library_name.encode('ASCII'),
|
||||
user_units_per_db_unit=logical_units_per_unit,
|
||||
meters_per_db_unit=meters_per_unit)
|
||||
meters_per_db_unit=meters_per_unit,
|
||||
)
|
||||
header.write(stream)
|
||||
|
||||
# Get a dict of id(pattern) -> pattern
|
||||
@ -241,7 +243,8 @@ def _read_header(stream: BinaryIO) -> Dict[str, Any]:
|
||||
"""
|
||||
header = klamath.library.FileHeader.read(stream)
|
||||
|
||||
library_info = {'name': header.name.decode('ASCII'),
|
||||
library_info = {
|
||||
'name': header.name.decode('ASCII'),
|
||||
'meters_per_unit': header.meters_per_db_unit,
|
||||
'logical_units_per_unit': header.user_units_per_db_unit,
|
||||
}
|
||||
@ -276,10 +279,12 @@ def read_elements(
|
||||
path = _gpath_to_mpath(element, raw_mode)
|
||||
pat.shapes.append(path)
|
||||
elif isinstance(element, klamath.elements.Text):
|
||||
label = Label(offset=element.xy.astype(float),
|
||||
label = Label(
|
||||
offset=element.xy.astype(float),
|
||||
layer=element.layer,
|
||||
string=element.string.decode('ASCII'),
|
||||
annotations=_properties_to_annotations(element.properties))
|
||||
annotations=_properties_to_annotations(element.properties),
|
||||
)
|
||||
pat.labels.append(label)
|
||||
elif isinstance(element, klamath.elements.Reference):
|
||||
pat.subpatterns.append(_ref_to_subpat(element))
|
||||
@ -314,16 +319,22 @@ def _ref_to_subpat(ref: klamath.library.Reference) -> SubPattern:
|
||||
a_count, b_count = ref.colrow
|
||||
a_vector = (xy[1] - offset) / a_count
|
||||
b_vector = (xy[2] - offset) / b_count
|
||||
repetition = Grid(a_vector=a_vector, b_vector=b_vector,
|
||||
a_count=a_count, b_count=b_count)
|
||||
repetition = Grid(
|
||||
a_vector=a_vector,
|
||||
b_vector=b_vector,
|
||||
a_count=a_count,
|
||||
b_count=b_count,
|
||||
)
|
||||
|
||||
subpat = SubPattern(pattern=None,
|
||||
subpat = SubPattern(
|
||||
pattern=None,
|
||||
offset=offset,
|
||||
rotation=numpy.deg2rad(ref.angle_deg),
|
||||
scale=ref.mag,
|
||||
mirrored=(ref.invert_y, False),
|
||||
annotations=_properties_to_annotations(ref.properties),
|
||||
repetition=repetition)
|
||||
repetition=repetition,
|
||||
)
|
||||
subpat.identifier = (ref.struct_name.decode('ASCII'),)
|
||||
return subpat
|
||||
|
||||
@ -334,7 +345,8 @@ def _gpath_to_mpath(gpath: klamath.library.Path, raw_mode: bool) -> Path:
|
||||
else:
|
||||
raise PatternError(f'Unrecognized path type: {gpath.path_type}')
|
||||
|
||||
mpath = Path(vertices=gpath.xy.astype(float),
|
||||
mpath = Path(
|
||||
vertices=gpath.xy.astype(float),
|
||||
layer=gpath.layer,
|
||||
width=gpath.width,
|
||||
cap=cap,
|
||||
@ -348,7 +360,8 @@ def _gpath_to_mpath(gpath: klamath.library.Path, raw_mode: bool) -> Path:
|
||||
|
||||
|
||||
def _boundary_to_polygon(boundary: klamath.library.Boundary, raw_mode: bool) -> Polygon:
|
||||
return Polygon(vertices=boundary.xy[:-1].astype(float),
|
||||
return Polygon(
|
||||
vertices=boundary.xy[:-1].astype(float),
|
||||
layer=boundary.layer,
|
||||
offset=numpy.zeros(2),
|
||||
annotations=_properties_to_annotations(boundary.properties),
|
||||
@ -377,31 +390,37 @@ def _subpatterns_to_refs(subpatterns: List[SubPattern]) -> List[klamath.library.
|
||||
rep.a_vector * rep.a_count,
|
||||
b_vector * b_count,
|
||||
]
|
||||
aref = klamath.library.Reference(struct_name=encoded_name,
|
||||
aref = klamath.library.Reference(
|
||||
struct_name=encoded_name,
|
||||
xy=numpy.round(xy).astype(int),
|
||||
colrow=(numpy.round(rep.a_count), numpy.round(rep.b_count)),
|
||||
angle_deg=angle_deg,
|
||||
invert_y=mirror_across_x,
|
||||
mag=subpat.scale,
|
||||
properties=properties)
|
||||
properties=properties,
|
||||
)
|
||||
refs.append(aref)
|
||||
elif rep is None:
|
||||
ref = klamath.library.Reference(struct_name=encoded_name,
|
||||
ref = klamath.library.Reference(
|
||||
struct_name=encoded_name,
|
||||
xy=numpy.round([subpat.offset]).astype(int),
|
||||
colrow=None,
|
||||
angle_deg=angle_deg,
|
||||
invert_y=mirror_across_x,
|
||||
mag=subpat.scale,
|
||||
properties=properties)
|
||||
properties=properties,
|
||||
)
|
||||
refs.append(ref)
|
||||
else:
|
||||
new_srefs = [klamath.library.Reference(struct_name=encoded_name,
|
||||
new_srefs = [klamath.library.Reference(
|
||||
struct_name=encoded_name,
|
||||
xy=numpy.round([subpat.offset + dd]).astype(int),
|
||||
colrow=None,
|
||||
angle_deg=angle_deg,
|
||||
invert_y=mirror_across_x,
|
||||
mag=subpat.scale,
|
||||
properties=properties)
|
||||
properties=properties,
|
||||
)
|
||||
for dd in rep.displacements]
|
||||
refs += new_srefs
|
||||
return refs
|
||||
@ -453,30 +472,36 @@ def _shapes_to_elements(
|
||||
else:
|
||||
extension = (0, 0)
|
||||
|
||||
path = klamath.elements.Path(layer=(layer, data_type),
|
||||
path = klamath.elements.Path(
|
||||
layer=(layer, data_type),
|
||||
xy=xy,
|
||||
path_type=path_type,
|
||||
width=width,
|
||||
extension=extension,
|
||||
properties=properties)
|
||||
properties=properties,
|
||||
)
|
||||
elements.append(path)
|
||||
elif isinstance(shape, Polygon):
|
||||
polygon = shape
|
||||
xy_closed = numpy.empty((polygon.vertices.shape[0] + 1, 2), dtype=numpy.int32)
|
||||
numpy.rint(polygon.vertices + polygon.offset, out=xy_closed[:-1], casting='unsafe')
|
||||
xy_closed[-1] = xy_closed[0]
|
||||
boundary = klamath.elements.Boundary(layer=(layer, data_type),
|
||||
boundary = klamath.elements.Boundary(
|
||||
layer=(layer, data_type),
|
||||
xy=xy_closed,
|
||||
properties=properties)
|
||||
properties=properties,
|
||||
)
|
||||
elements.append(boundary)
|
||||
else:
|
||||
for polygon in shape.to_polygons():
|
||||
xy_closed = numpy.empty((polygon.vertices.shape[0] + 1, 2), dtype=numpy.int32)
|
||||
numpy.rint(polygon.vertices + polygon.offset, out=xy_closed[:-1], casting='unsafe')
|
||||
xy_closed[-1] = xy_closed[0]
|
||||
boundary = klamath.elements.Boundary(layer=(layer, data_type),
|
||||
boundary = klamath.elements.Boundary(
|
||||
layer=(layer, data_type),
|
||||
xy=xy_closed,
|
||||
properties=properties)
|
||||
properties=properties,
|
||||
)
|
||||
elements.append(boundary)
|
||||
return elements
|
||||
|
||||
@ -487,7 +512,8 @@ def _labels_to_texts(labels: List[Label]) -> List[klamath.elements.Text]:
|
||||
properties = _annotations_to_properties(label.annotations, 128)
|
||||
layer, text_type = _mlayer2gds(label.layer)
|
||||
xy = numpy.round([label.offset]).astype(int)
|
||||
text = klamath.elements.Text(layer=(layer, text_type),
|
||||
text = klamath.elements.Text(
|
||||
layer=(layer, text_type),
|
||||
xy=xy,
|
||||
string=label.string.encode('ASCII'),
|
||||
properties=properties,
|
||||
@ -496,7 +522,8 @@ def _labels_to_texts(labels: List[Label]) -> List[klamath.elements.Text]:
|
||||
invert_y=False,
|
||||
width=0,
|
||||
path_type=0,
|
||||
mag=1)
|
||||
mag=1,
|
||||
)
|
||||
texts.append(text)
|
||||
return texts
|
||||
|
||||
|
@ -285,11 +285,13 @@ def read(
|
||||
if isinstance(element, fatrec.Polygon):
|
||||
vertices = numpy.cumsum(numpy.vstack(((0, 0), element.get_point_list())), axis=0)
|
||||
annotations = properties_to_annotations(element.properties, lib.propnames, lib.propstrings)
|
||||
poly = Polygon(vertices=vertices,
|
||||
poly = Polygon(
|
||||
vertices=vertices,
|
||||
layer=element.get_layer_tuple(),
|
||||
offset=element.get_xy(),
|
||||
annotations=annotations,
|
||||
repetition=repetition)
|
||||
repetition=repetition,
|
||||
)
|
||||
|
||||
pat.shapes.append(poly)
|
||||
|
||||
@ -308,14 +310,16 @@ def read(
|
||||
element.get_extension_end()[1]))
|
||||
|
||||
annotations = properties_to_annotations(element.properties, lib.propnames, lib.propstrings)
|
||||
path = Path(vertices=vertices,
|
||||
path = Path(
|
||||
vertices=vertices,
|
||||
layer=element.get_layer_tuple(),
|
||||
offset=element.get_xy(),
|
||||
repetition=repetition,
|
||||
annotations=annotations,
|
||||
width=element.get_half_width() * 2,
|
||||
cap=cap,
|
||||
**path_args)
|
||||
**path_args,
|
||||
)
|
||||
|
||||
pat.shapes.append(path)
|
||||
|
||||
@ -323,7 +327,8 @@ def read(
|
||||
width = element.get_width()
|
||||
height = element.get_height()
|
||||
annotations = properties_to_annotations(element.properties, lib.propnames, lib.propstrings)
|
||||
rect = Polygon(layer=element.get_layer_tuple(),
|
||||
rect = Polygon(
|
||||
layer=element.get_layer_tuple(),
|
||||
offset=element.get_xy(),
|
||||
repetition=repetition,
|
||||
vertices=numpy.array(((0, 0), (1, 0), (1, 1), (0, 1))) * (width, height),
|
||||
@ -357,7 +362,8 @@ def read(
|
||||
vertices[2, 0] -= b
|
||||
|
||||
annotations = properties_to_annotations(element.properties, lib.propnames, lib.propstrings)
|
||||
trapz = Polygon(layer=element.get_layer_tuple(),
|
||||
trapz = Polygon(
|
||||
layer=element.get_layer_tuple(),
|
||||
offset=element.get_xy(),
|
||||
repetition=repetition,
|
||||
vertices=vertices,
|
||||
@ -412,7 +418,8 @@ def read(
|
||||
vertices[0, 1] += width
|
||||
|
||||
annotations = properties_to_annotations(element.properties, lib.propnames, lib.propstrings)
|
||||
ctrapz = Polygon(layer=element.get_layer_tuple(),
|
||||
ctrapz = Polygon(
|
||||
layer=element.get_layer_tuple(),
|
||||
offset=element.get_xy(),
|
||||
repetition=repetition,
|
||||
vertices=vertices,
|
||||
@ -422,11 +429,13 @@ def read(
|
||||
|
||||
elif isinstance(element, fatrec.Circle):
|
||||
annotations = properties_to_annotations(element.properties, lib.propnames, lib.propstrings)
|
||||
circle = Circle(layer=element.get_layer_tuple(),
|
||||
circle = Circle(
|
||||
layer=element.get_layer_tuple(),
|
||||
offset=element.get_xy(),
|
||||
repetition=repetition,
|
||||
annotations=annotations,
|
||||
radius=float(element.get_radius()))
|
||||
radius=float(element.get_radius()),
|
||||
)
|
||||
pat.shapes.append(circle)
|
||||
|
||||
elif isinstance(element, fatrec.Text):
|
||||
@ -436,11 +445,13 @@ def read(
|
||||
string = lib.textstrings[str_or_ref].string
|
||||
else:
|
||||
string = str_or_ref.string
|
||||
label = Label(layer=element.get_layer_tuple(),
|
||||
label = Label(
|
||||
layer=element.get_layer_tuple(),
|
||||
offset=element.get_xy(),
|
||||
repetition=repetition,
|
||||
annotations=annotations,
|
||||
string=string)
|
||||
string=string,
|
||||
)
|
||||
pat.labels.append(label)
|
||||
|
||||
else:
|
||||
@ -499,14 +510,16 @@ def _placement_to_subpat(placement: fatrec.Placement, lib: fatamorgana.OasisLayo
|
||||
rotation = 0
|
||||
else:
|
||||
rotation = numpy.deg2rad(float(placement.angle))
|
||||
subpat = SubPattern(offset=xy,
|
||||
subpat = SubPattern(
|
||||
offset=xy,
|
||||
pattern=None,
|
||||
mirrored=(placement.flip, False),
|
||||
rotation=rotation,
|
||||
scale=float(mag),
|
||||
identifier=(name,),
|
||||
repetition=repetition_fata2masq(placement.repetition),
|
||||
annotations=annotations)
|
||||
annotations=annotations,
|
||||
)
|
||||
return subpat
|
||||
|
||||
|
||||
@ -532,7 +545,8 @@ def _subpatterns_to_placements(
|
||||
properties=annotations_to_properties(subpat.annotations),
|
||||
x=offset[0],
|
||||
y=offset[1],
|
||||
repetition=frep)
|
||||
repetition=frep,
|
||||
)
|
||||
|
||||
refs.append(ref)
|
||||
return refs
|
||||
@ -551,13 +565,15 @@ def _shapes_to_elements(
|
||||
if isinstance(shape, Circle):
|
||||
offset = numpy.round(shape.offset + rep_offset).astype(int)
|
||||
radius = numpy.round(shape.radius).astype(int)
|
||||
circle = fatrec.Circle(layer=layer,
|
||||
circle = fatrec.Circle(
|
||||
layer=layer,
|
||||
datatype=datatype,
|
||||
radius=radius,
|
||||
x=offset[0],
|
||||
y=offset[1],
|
||||
properties=properties,
|
||||
repetition=repetition)
|
||||
repetition=repetition,
|
||||
)
|
||||
elements.append(circle)
|
||||
elif isinstance(shape, Path):
|
||||
xy = numpy.round(shape.offset + shape.vertices[0] + rep_offset).astype(int)
|
||||
@ -566,7 +582,8 @@ def _shapes_to_elements(
|
||||
path_type = next(k for k, v in path_cap_map.items() if v == shape.cap) # reverse lookup
|
||||
extension_start = (path_type, shape.cap_extensions[0] if shape.cap_extensions is not None else None)
|
||||
extension_end = (path_type, shape.cap_extensions[1] if shape.cap_extensions is not None else None)
|
||||
path = fatrec.Path(layer=layer,
|
||||
path = fatrec.Path(
|
||||
layer=layer,
|
||||
datatype=datatype,
|
||||
point_list=deltas,
|
||||
half_width=half_width,
|
||||
@ -582,13 +599,15 @@ def _shapes_to_elements(
|
||||
for polygon in shape.to_polygons():
|
||||
xy = numpy.round(polygon.offset + polygon.vertices[0] + rep_offset).astype(int)
|
||||
points = numpy.round(numpy.diff(polygon.vertices, axis=0)).astype(int)
|
||||
elements.append(fatrec.Polygon(layer=layer,
|
||||
elements.append(fatrec.Polygon(
|
||||
layer=layer,
|
||||
datatype=datatype,
|
||||
x=xy[0],
|
||||
y=xy[1],
|
||||
point_list=points,
|
||||
properties=properties,
|
||||
repetition=repetition))
|
||||
repetition=repetition,
|
||||
))
|
||||
return elements
|
||||
|
||||
|
||||
@ -602,13 +621,15 @@ def _labels_to_texts(
|
||||
repetition, rep_offset = repetition_masq2fata(label.repetition)
|
||||
xy = numpy.round(label.offset + rep_offset).astype(int)
|
||||
properties = annotations_to_properties(label.annotations)
|
||||
texts.append(fatrec.Text(layer=layer,
|
||||
texts.append(fatrec.Text(
|
||||
layer=layer,
|
||||
datatype=datatype,
|
||||
x=xy[0],
|
||||
y=xy[1],
|
||||
string=label.string,
|
||||
properties=properties,
|
||||
repetition=repetition))
|
||||
repetition=repetition,
|
||||
))
|
||||
return texts
|
||||
|
||||
|
||||
@ -648,10 +669,12 @@ def repetition_fata2masq(
|
||||
) -> Optional[Repetition]:
|
||||
mrep: Optional[Repetition]
|
||||
if isinstance(rep, fatamorgana.GridRepetition):
|
||||
mrep = Grid(a_vector=rep.a_vector,
|
||||
mrep = Grid(
|
||||
a_vector=rep.a_vector,
|
||||
b_vector=rep.b_vector,
|
||||
a_count=rep.a_count,
|
||||
b_count=rep.b_count)
|
||||
b_count=rep.b_count,
|
||||
)
|
||||
elif isinstance(rep, fatamorgana.ArbitraryRepetition):
|
||||
displacements = numpy.cumsum(numpy.column_stack((rep.x_displacements,
|
||||
rep.y_displacements)), axis=0)
|
||||
|
@ -118,10 +118,12 @@ def build(
|
||||
patterns = [p.wrap_repeated_shapes() for p in patterns]
|
||||
|
||||
# Create library
|
||||
lib = gdsii.library.Library(version=600,
|
||||
lib = gdsii.library.Library(
|
||||
version=600,
|
||||
name=library_name.encode('ASCII'),
|
||||
logical_unit=logical_units_per_unit,
|
||||
physical_unit=meters_per_unit)
|
||||
physical_unit=meters_per_unit,
|
||||
)
|
||||
|
||||
# Get a dict of id(pattern) -> pattern
|
||||
patterns_by_id = {id(pattern): pattern for pattern in patterns}
|
||||
@ -244,7 +246,8 @@ def read(
|
||||
|
||||
lib = gdsii.library.Library.load(stream)
|
||||
|
||||
library_info = {'name': lib.name.decode('ASCII'),
|
||||
library_info = {
|
||||
'name': lib.name.decode('ASCII'),
|
||||
'meters_per_unit': lib.physical_unit,
|
||||
'logical_units_per_unit': lib.logical_unit,
|
||||
}
|
||||
@ -265,9 +268,11 @@ def read(
|
||||
pat.shapes.append(path)
|
||||
|
||||
elif isinstance(element, gdsii.elements.Text):
|
||||
label = Label(offset=element.xy.astype(float),
|
||||
label = Label(
|
||||
offset=element.xy.astype(float),
|
||||
layer=(element.layer, element.text_type),
|
||||
string=element.string.decode('ASCII'))
|
||||
string=element.string.decode('ASCII'),
|
||||
)
|
||||
pat.labels.append(label)
|
||||
|
||||
elif isinstance(element, (gdsii.elements.SRef, gdsii.elements.ARef)):
|
||||
@ -341,16 +346,22 @@ def _ref_to_subpat(
|
||||
b_count = element.rows
|
||||
a_vector = (element.xy[1] - offset) / a_count
|
||||
b_vector = (element.xy[2] - offset) / b_count
|
||||
repetition = Grid(a_vector=a_vector, b_vector=b_vector,
|
||||
a_count=a_count, b_count=b_count)
|
||||
repetition = Grid(
|
||||
a_vector=a_vector,
|
||||
b_vector=b_vector,
|
||||
a_count=a_count,
|
||||
b_count=b_count,
|
||||
)
|
||||
|
||||
subpat = SubPattern(pattern=None,
|
||||
subpat = SubPattern(
|
||||
pattern=None,
|
||||
offset=offset,
|
||||
rotation=rotation,
|
||||
scale=scale,
|
||||
mirrored=(mirror_across_x, False),
|
||||
annotations=_properties_to_annotations(element.properties),
|
||||
repetition=repetition)
|
||||
repetition=repetition,
|
||||
)
|
||||
subpat.identifier = (element.struct_name,)
|
||||
return subpat
|
||||
|
||||
@ -361,7 +372,8 @@ def _gpath_to_mpath(element: gdsii.elements.Path, raw_mode: bool) -> Path:
|
||||
else:
|
||||
raise PatternError(f'Unrecognized path type: {element.path_type}')
|
||||
|
||||
args = {'vertices': element.xy.astype(float),
|
||||
args = {
|
||||
'vertices': element.xy.astype(float),
|
||||
'layer': (element.layer, element.data_type),
|
||||
'width': element.width if element.width is not None else 0.0,
|
||||
'cap': cap,
|
||||
@ -381,7 +393,8 @@ def _gpath_to_mpath(element: gdsii.elements.Path, raw_mode: bool) -> Path:
|
||||
|
||||
|
||||
def _boundary_to_polygon(element: gdsii.elements.Boundary, raw_mode: bool) -> Polygon:
|
||||
args = {'vertices': element.xy[:-1].astype(float),
|
||||
args = {
|
||||
'vertices': element.xy[:-1].astype(float),
|
||||
'layer': (element.layer, element.data_type),
|
||||
'offset': numpy.zeros(2),
|
||||
'annotations': _properties_to_annotations(element.properties),
|
||||
@ -483,9 +496,11 @@ def _shapes_to_elements(
|
||||
xy = rint_cast(shape.vertices + shape.offset)
|
||||
width = rint_cast(shape.width)
|
||||
path_type = next(k for k, v in path_cap_map.items() if v == shape.cap) # reverse lookup
|
||||
path = gdsii.elements.Path(layer=layer,
|
||||
path = gdsii.elements.Path(
|
||||
layer=layer,
|
||||
data_type=data_type,
|
||||
xy=xy)
|
||||
xy=xy,
|
||||
)
|
||||
path.path_type = path_type
|
||||
path.width = width
|
||||
path.properties = properties
|
||||
|
@ -34,7 +34,8 @@ class SubPattern(PositionableImpl, DoseableImpl, RotatableImpl, ScalableImpl, Mi
|
||||
SubPattern provides basic support for nesting Pattern objects within each other, by adding
|
||||
offset, rotation, scaling, and associated methods.
|
||||
"""
|
||||
__slots__ = ('_pattern',
|
||||
__slots__ = (
|
||||
'_pattern',
|
||||
'_mirrored',
|
||||
'identifier',
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user