diff --git a/masque/file/gdsii.py b/masque/file/gdsii.py index 1b9c1d0..18fc9ff 100644 --- a/masque/file/gdsii.py +++ b/masque/file/gdsii.py @@ -28,7 +28,7 @@ import gdsii.library import gdsii.structure import gdsii.elements -from .utils import mangle_name, make_dose_table, dose2dtype, dtype2dose +from .utils import mangle_name, make_dose_table, dose2dtype, dtype2dose, clean_pattern_vertices from .. import Pattern, SubPattern, PatternError, Label, Shape from ..shapes import Polygon, Path from ..repetition import Grid @@ -250,20 +250,10 @@ def read(stream: io.BufferedIOBase, # Switch based on element type: if isinstance(element, gdsii.elements.Boundary): poly = _boundary_to_polygon(element, raw_mode) - if clean_vertices: - try: - poly.clean_vertices() - except PatternError: - continue pat.shapes.append(poly) if isinstance(element, gdsii.elements.Path): path = _gpath_to_mpath(element, raw_mode) - if clean_vertices: - try: - path.clean_vertices() - except PatternError as err: - continue pat.shapes.append(path) elif isinstance(element, gdsii.elements.Text): @@ -276,6 +266,8 @@ def read(stream: io.BufferedIOBase, isinstance(element, gdsii.elements.ARef)): pat.subpatterns.append(_ref_to_subpat(element)) + if clean_vertices: + clean_pattern_vertices(pat) patterns.append(pat) # Create a dict of {pattern.name: pattern, ...}, then fix up all subpattern.pattern entries diff --git a/masque/file/oasis.py b/masque/file/oasis.py index 6e0284d..142b4a1 100644 --- a/masque/file/oasis.py +++ b/masque/file/oasis.py @@ -27,7 +27,7 @@ import fatamorgana import fatamorgana.records as fatrec from fatamorgana.basic import PathExtensionScheme, AString, NString, PropStringReference -from .utils import mangle_name, make_dose_table +from .utils import mangle_name, make_dose_table, clean_pattern_vertices from .. import Pattern, SubPattern, PatternError, Label, Shape from ..shapes import Polygon, Path, Circle from ..repetition import Grid, Arbitrary, Repetition @@ -289,12 +289,6 @@ def read(stream: io.BufferedIOBase, annotations=annotations, repetition=repetition) - if clean_vertices: - try: - poly.clean_vertices() - except PatternError: - continue - pat.shapes.append(poly) elif isinstance(element, fatrec.Path): @@ -321,12 +315,6 @@ def read(stream: io.BufferedIOBase, cap=cap, **path_args) - if clean_vertices: - try: - path.clean_vertices() - except PatternError as err: - continue - pat.shapes.append(path) elif isinstance(element, fatrec.Rectangle): @@ -455,6 +443,8 @@ def read(stream: io.BufferedIOBase, for placement in cell.placements: pat.subpatterns.append(_placement_to_subpat(placement, lib)) + if clean_vertices: + clean_pattern_vertices(pat) patterns.append(pat) # Create a dict of {pattern.name: pattern, ...}, then fix up all subpattern.pattern entries diff --git a/masque/file/utils.py b/masque/file/utils.py index e36765e..30b2808 100644 --- a/masque/file/utils.py +++ b/masque/file/utils.py @@ -6,6 +6,7 @@ import re import copy from .. import Pattern, PatternError +from ..shapes import Polygon, Path def mangle_name(pattern: Pattern, dose_multiplier: float=1.0) -> str: @@ -25,6 +26,30 @@ def mangle_name(pattern: Pattern, dose_multiplier: float=1.0) -> str: return sanitized_name +def clean_pattern_vertices(pat: Pattern) -> Pattern: + """ + Given a pattern, remove any redundant vertices in its polygons and paths. + The cleaning process completely removes any polygons with zero area or <3 vertices. + + Args: + pat: Pattern to clean + + Returns: + pat + """ + remove_inds = [] + for ii, shape in enumerate(pat.shapes): + if not isinstance(shape, (Polygon, Path)): + continue + try: + shape.clean_vertices() + except PatternError: + remove_inds.append(ii) + for ii in sorted(remove_inds, reverse=True): + del pat.shapes[ii] + return pat + + def make_dose_table(patterns: List[Pattern], dose_multiplier: float=1.0) -> Set[Tuple[int, float]]: """ Create a set containing `(id(pat), written_dose)` for each pattern (including subpatterns)