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