allow locking of all objects
This commit is contained in:
parent
09711116a7
commit
e0db621595
14 changed files with 290 additions and 36 deletions
|
|
@ -147,7 +147,9 @@ class Arc(Shape):
|
|||
rotation: float = 0,
|
||||
mirrored: Tuple[bool] = (False, False),
|
||||
layer: int = 0,
|
||||
dose: float = 1.0):
|
||||
dose: float = 1.0,
|
||||
locked: bool = False):
|
||||
self.unlock()
|
||||
self.identifier = ()
|
||||
self.radii = radii
|
||||
self.angles = angles
|
||||
|
|
@ -159,6 +161,7 @@ class Arc(Shape):
|
|||
self.dose = dose
|
||||
self.poly_num_points = poly_num_points
|
||||
self.poly_max_arclen = poly_max_arclen
|
||||
self.locked = locked
|
||||
|
||||
def __deepcopy__(self, memo: Dict = None) -> 'Arc':
|
||||
memo = {} if memo is None else memo
|
||||
|
|
|
|||
|
|
@ -44,7 +44,9 @@ class Circle(Shape):
|
|||
poly_max_arclen: float = None,
|
||||
offset: vector2 = (0.0, 0.0),
|
||||
layer: int = 0,
|
||||
dose: float = 1.0):
|
||||
dose: float = 1.0,
|
||||
locked: bool = False):
|
||||
self.unlock()
|
||||
self.identifier = ()
|
||||
self.offset = numpy.array(offset, dtype=float)
|
||||
self.layer = layer
|
||||
|
|
@ -52,6 +54,7 @@ class Circle(Shape):
|
|||
self.radius = radius
|
||||
self.poly_num_points = poly_num_points
|
||||
self.poly_max_arclen = poly_max_arclen
|
||||
self.locked = locked
|
||||
|
||||
def __deepcopy__(self, memo: Dict = None) -> 'Circle':
|
||||
memo = {} if memo is None else memo
|
||||
|
|
|
|||
|
|
@ -88,7 +88,9 @@ class Ellipse(Shape):
|
|||
rotation: float = 0,
|
||||
mirrored: Tuple[bool] = (False, False),
|
||||
layer: int = 0,
|
||||
dose: float = 1.0):
|
||||
dose: float = 1.0,
|
||||
locked: bool = False):
|
||||
self.unlock()
|
||||
self.identifier = ()
|
||||
self.radii = radii
|
||||
self.offset = offset
|
||||
|
|
@ -98,6 +100,7 @@ class Ellipse(Shape):
|
|||
self.dose = dose
|
||||
self.poly_num_points = poly_num_points
|
||||
self.poly_max_arclen = poly_max_arclen
|
||||
self.locked = locked
|
||||
|
||||
def __deepcopy__(self, memo: Dict = None) -> 'Ellipse':
|
||||
memo = {} if memo is None else memo
|
||||
|
|
|
|||
|
|
@ -151,7 +151,9 @@ class Path(Shape):
|
|||
mirrored: Tuple[bool] = (False, False),
|
||||
layer: int = 0,
|
||||
dose: float = 1.0,
|
||||
locked: bool = False,
|
||||
) -> 'Path':
|
||||
self.unlock()
|
||||
self._cap_extensions = None # Since .cap setter might access it
|
||||
|
||||
self.identifier = ()
|
||||
|
|
@ -165,6 +167,7 @@ class Path(Shape):
|
|||
self.cap_extensions = cap_extensions
|
||||
self.rotate(rotation)
|
||||
[self.mirror(a) for a, do in enumerate(mirrored) if do]
|
||||
self.locked = locked
|
||||
|
||||
def __deepcopy__(self, memo: Dict = None) -> 'Path':
|
||||
memo = {} if memo is None else memo
|
||||
|
|
|
|||
|
|
@ -77,7 +77,9 @@ class Polygon(Shape):
|
|||
mirrored: Tuple[bool] = (False, False),
|
||||
layer: int = 0,
|
||||
dose: float = 1.0,
|
||||
locked: bool = False,
|
||||
):
|
||||
self.unlock()
|
||||
self.identifier = ()
|
||||
self.layer = layer
|
||||
self.dose = dose
|
||||
|
|
@ -85,6 +87,7 @@ class Polygon(Shape):
|
|||
self.offset = offset
|
||||
self.rotate(rotation)
|
||||
[self.mirror(a) for a, do in enumerate(mirrored) if do]
|
||||
self.locked = locked
|
||||
|
||||
def __deepcopy__(self, memo: Dict = None) -> 'Polygon':
|
||||
memo = {} if memo is None else memo
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from abc import ABCMeta, abstractmethod
|
|||
import copy
|
||||
import numpy
|
||||
|
||||
from .. import PatternError
|
||||
from ..error import PatternError, PatternLockedError
|
||||
from ..utils import is_scalar, rotation_matrix_2d, vector2
|
||||
|
||||
|
||||
|
|
@ -24,13 +24,26 @@ class Shape(metaclass=ABCMeta):
|
|||
"""
|
||||
Abstract class specifying functions common to all shapes.
|
||||
"""
|
||||
__slots__ = ('_offset', '_layer', '_dose', 'identifier')
|
||||
__slots__ = ('_offset', '_layer', '_dose', 'identifier', 'locked')
|
||||
|
||||
_offset: numpy.ndarray # [x_offset, y_offset]
|
||||
_layer: int or Tuple # Layer (integer >= 0 or tuple)
|
||||
_dose: float # Dose
|
||||
identifier: Tuple # An arbitrary identifier for the shape,
|
||||
# usually empty but used by Pattern.flatten()
|
||||
locked: bool # If True, any changes to the shape will raise a PatternLockedError
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if self.locked and name != 'locked':
|
||||
raise PatternLockedError()
|
||||
object.__setattr__(self, name, value)
|
||||
|
||||
def __copy__(self) -> 'Shape':
|
||||
cls = self.__class__
|
||||
new = cls.__new__(cls)
|
||||
for name in Shape.__slots__ + self.__slots__:
|
||||
object.__setattr__(new, name, getattr(self, name))
|
||||
return new
|
||||
|
||||
# --- Abstract methods
|
||||
@abstractmethod
|
||||
|
|
@ -388,3 +401,20 @@ class Shape(metaclass=ABCMeta):
|
|||
|
||||
return manhattan_polygons
|
||||
|
||||
def lock(self) -> 'Shape':
|
||||
"""
|
||||
Lock the Shape
|
||||
|
||||
:return: self
|
||||
"""
|
||||
object.__setattr__(self, 'locked', True)
|
||||
return self
|
||||
|
||||
def unlock(self) -> 'Shape':
|
||||
"""
|
||||
Unlock the Shape
|
||||
|
||||
:return: self
|
||||
"""
|
||||
object.__setattr__(self, 'locked', False)
|
||||
return self
|
||||
|
|
|
|||
|
|
@ -77,7 +77,10 @@ class Text(Shape):
|
|||
rotation: float = 0.0,
|
||||
mirrored: Tuple[bool] = (False, False),
|
||||
layer: int = 0,
|
||||
dose: float = 1.0):
|
||||
dose: float = 1.0,
|
||||
locked: bool = False,
|
||||
):
|
||||
self.unlock()
|
||||
self.identifier = ()
|
||||
self.offset = offset
|
||||
self.layer = layer
|
||||
|
|
@ -87,6 +90,7 @@ class Text(Shape):
|
|||
self.rotation = rotation
|
||||
self.font_path = font_path
|
||||
self.mirrored = mirrored
|
||||
self.locked = locked
|
||||
|
||||
def __deepcopy__(self, memo: Dict = None) -> 'Text':
|
||||
memo = {} if memo is None else memo
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue