Remove pyclipper dependency; remove shape.cut()
This commit is contained in:
parent
8dfd856e18
commit
ab483fc9d4
@ -11,7 +11,6 @@ E-beam doses, and the ability to output to multiple formats.
|
|||||||
Requirements:
|
Requirements:
|
||||||
* python >= 3.5 (written and tested with 3.6)
|
* python >= 3.5 (written and tested with 3.6)
|
||||||
* numpy
|
* numpy
|
||||||
* pyclipper
|
|
||||||
* matplotlib (optional, used for visualization functions and text)
|
* matplotlib (optional, used for visualization functions and text)
|
||||||
* python-gdsii (optional, used for gdsii i/o)
|
* python-gdsii (optional, used for gdsii i/o)
|
||||||
* svgwrite (optional, used for svg output)
|
* svgwrite (optional, used for svg output)
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
Dependencies:
|
Dependencies:
|
||||||
- numpy
|
- numpy
|
||||||
- pyclipper
|
|
||||||
- matplotlib [Pattern.visualize(...)]
|
- matplotlib [Pattern.visualize(...)]
|
||||||
- python-gdsii [masque.file.gdsii]
|
- python-gdsii [masque.file.gdsii]
|
||||||
- svgwrite [masque.file.svgwrite]
|
- svgwrite [masque.file.svgwrite]
|
||||||
|
@ -2,8 +2,6 @@ from typing import List
|
|||||||
import copy
|
import copy
|
||||||
import numpy
|
import numpy
|
||||||
from numpy import pi
|
from numpy import pi
|
||||||
import pyclipper
|
|
||||||
from pyclipper import scale_to_clipper, scale_from_clipper
|
|
||||||
|
|
||||||
from . import Shape, normalized_shape_tuple
|
from . import Shape, normalized_shape_tuple
|
||||||
from .. import PatternError
|
from .. import PatternError
|
||||||
@ -185,11 +183,38 @@ class Polygon(Shape):
|
|||||||
|
|
||||||
:returns: self
|
:returns: self
|
||||||
"""
|
"""
|
||||||
self.vertices = scale_from_clipper(
|
self.remove_colinear_vertices()
|
||||||
pyclipper.CleanPolygon(
|
|
||||||
scale_to_clipper(
|
|
||||||
self.vertices
|
|
||||||
)))
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def remove_duplicate_vertices(self) -> 'Polygon'
|
||||||
|
'''
|
||||||
|
Removes all consecutive duplicate (repeated) vertices.
|
||||||
|
|
||||||
|
:returns: self
|
||||||
|
'''
|
||||||
|
duplicates = (self.vertices == numpy.roll(self.vertices, 1, axis=0)).all(axis=1)
|
||||||
|
self.vertices = self.vertices[~duplicates]
|
||||||
|
return self
|
||||||
|
|
||||||
|
def remove_colinear_vertices(self) -> 'Polygon'
|
||||||
|
'''
|
||||||
|
Removes consecutive co-linear vertices.
|
||||||
|
|
||||||
|
:returns: self
|
||||||
|
'''
|
||||||
|
dv0 = numpy.roll(self.vertices, 1, axis=0) - self.vertices
|
||||||
|
dv1 = numpy.roll(dv0, -1, axis=0)
|
||||||
|
|
||||||
|
# find cases where at least one coordinate is 0 in successive dv's
|
||||||
|
eq = dv1 == dv0
|
||||||
|
aa_colinear = numpy.logical_and(eq, dv0 == 0).any(axis=1)
|
||||||
|
|
||||||
|
# find cases where slope is equal
|
||||||
|
with numpy.errstate(divide='ignore', invalid='ignore'): # don't care about zeroes
|
||||||
|
slope_quotient = (dv0[:, 0] * dv1[:, 1]) / (dv1[:, 0] * dv0[:, 1])
|
||||||
|
slopes_equal = numpy.abs(slope_quotient - 1) < 1e-14
|
||||||
|
|
||||||
|
colinear = numpy.logical_or(aa_colinear, slopes_equal)
|
||||||
|
self.vertices = self.vertices[~colinear]
|
||||||
|
return self
|
||||||
|
|
||||||
|
@ -3,9 +3,6 @@ from abc import ABCMeta, abstractmethod
|
|||||||
import copy
|
import copy
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
import pyclipper
|
|
||||||
from pyclipper import scale_to_clipper, scale_from_clipper
|
|
||||||
|
|
||||||
from .. import PatternError
|
from .. import PatternError
|
||||||
from ..utils import is_scalar, rotation_matrix_2d, vector2
|
from ..utils import is_scalar, rotation_matrix_2d, vector2
|
||||||
|
|
||||||
@ -369,49 +366,3 @@ class Shape(metaclass=ABCMeta):
|
|||||||
|
|
||||||
return manhattan_polygons
|
return manhattan_polygons
|
||||||
|
|
||||||
def cut(self,
|
|
||||||
cut_xs: numpy.ndarray = None,
|
|
||||||
cut_ys: numpy.ndarray = None
|
|
||||||
) -> List['Polygon']:
|
|
||||||
"""
|
|
||||||
Decomposes the shape into a list of constituent polygons by polygonizing and
|
|
||||||
then cutting along the specified x and/or y coordinates.
|
|
||||||
|
|
||||||
:param cut_xs: list of x-coordinates to cut along (e.g., [1, 1.4, 6])
|
|
||||||
:param cut_ys: list of y-coordinates to cut along (e.g., [1, 3, 5.4])
|
|
||||||
:return: List of Polygon objects
|
|
||||||
"""
|
|
||||||
from . import Polygon
|
|
||||||
|
|
||||||
clipped_shapes = []
|
|
||||||
for polygon in self.to_polygons():
|
|
||||||
min_x, min_y = numpy.min(polygon.vertices, axis=0)
|
|
||||||
max_x, max_y = numpy.max(polygon.vertices, axis=0)
|
|
||||||
range_x = max_x - min_x
|
|
||||||
range_y = max_y - min_y
|
|
||||||
|
|
||||||
edge_xs = (min_x - range_x - 1,) + tuple(cut_xs) + (max_x + range_x + 1,)
|
|
||||||
edge_ys = (min_y - range_y - 1,) + tuple(cut_ys) + (max_y + range_y + 1,)
|
|
||||||
|
|
||||||
for i in range(2):
|
|
||||||
for j in range(2):
|
|
||||||
clipper = pyclipper.Pyclipper()
|
|
||||||
clipper.AddPath(scale_to_clipper(polygon.vertices), pyclipper.PT_SUBJECT, True)
|
|
||||||
|
|
||||||
for start_x, stop_x in zip(edge_xs[i::2], edge_xs[(i+1)::2]):
|
|
||||||
for start_y, stop_y in zip(edge_ys[j::2], edge_ys[(j+1)::2]):
|
|
||||||
clipper.AddPath(scale_to_clipper((
|
|
||||||
(start_x, start_y),
|
|
||||||
(start_x, stop_y),
|
|
||||||
(stop_x, stop_y),
|
|
||||||
(stop_x, start_y),
|
|
||||||
)), pyclipper.PT_CLIP, True)
|
|
||||||
|
|
||||||
clipped_parts = scale_from_clipper(clipper.Execute(pyclipper.CT_INTERSECTION,
|
|
||||||
pyclipper.PFT_EVENODD,
|
|
||||||
pyclipper.PFT_EVENODD))
|
|
||||||
for part in clipped_parts:
|
|
||||||
poly = polygon.copy()
|
|
||||||
poly.vertices = part
|
|
||||||
clipped_shapes.append(poly)
|
|
||||||
return clipped_shapes
|
|
||||||
|
Loading…
Reference in New Issue
Block a user