Create an ordering for everything
In order to make layouts more reproducible Also add pattern.sort() and file.utils.preflight_check() optionally don't sort elements elements aren't re-ordered that often, sorting them is slow, and the sort criteria are arbitrary, so we might want to only sort stuff by name
This commit is contained in:
parent
94aa853a49
commit
6db4bb96db
16 changed files with 653 additions and 24 deletions
|
|
@ -2,8 +2,9 @@
|
|||
Repetitions provide support for efficiently representing multiple identical
|
||||
instances of an object .
|
||||
"""
|
||||
from typing import Any, Type, Self, TypeVar
|
||||
from typing import Any, Type, Self, TypeVar, cast
|
||||
import copy
|
||||
import functools
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
import numpy
|
||||
|
|
@ -17,6 +18,7 @@ from .utils import rotation_matrix_2d
|
|||
GG = TypeVar('GG', bound='Grid')
|
||||
|
||||
|
||||
@functools.total_ordering
|
||||
class Repetition(Copyable, Rotatable, Mirrorable, Scalable, Bounded, metaclass=ABCMeta):
|
||||
"""
|
||||
Interface common to all objects which specify repetitions
|
||||
|
|
@ -31,6 +33,14 @@ class Repetition(Copyable, Rotatable, Mirrorable, Scalable, Bounded, metaclass=A
|
|||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def __le__(self, other: 'Repetition') -> bool:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
pass
|
||||
|
||||
|
||||
class Grid(Repetition):
|
||||
"""
|
||||
|
|
@ -270,7 +280,7 @@ class Grid(Repetition):
|
|||
return (f'<Grid {self.a_count}x{self.b_count} ({self.a_vector}{bv})>')
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, type(self)):
|
||||
if type(other) is not type(self):
|
||||
return False
|
||||
if self.a_count != other.a_count or self.b_count != other.b_count:
|
||||
return False
|
||||
|
|
@ -284,6 +294,24 @@ class Grid(Repetition):
|
|||
return False
|
||||
return True
|
||||
|
||||
def __le__(self, other: Repetition) -> bool:
|
||||
if type(self) is not type(other):
|
||||
return repr(type(self)) < repr(type(other))
|
||||
other = cast(Grid, other)
|
||||
if self.a_count != other.a_count:
|
||||
return self.a_count < other.a_count
|
||||
if self.b_count != other.b_count:
|
||||
return self.b_count < other.b_count
|
||||
if not numpy.array_equal(self.a_vector, other.a_vector):
|
||||
return tuple(self.a_vector) < tuple(other.a_vector)
|
||||
if self.b_vector is None:
|
||||
return other.b_vector is not None
|
||||
if other.b_vector is None:
|
||||
return False
|
||||
if not numpy.array_equal(self.b_vector, other.b_vector):
|
||||
return tuple(self.a_vector) < tuple(other.a_vector)
|
||||
return False
|
||||
|
||||
|
||||
class Arbitrary(Repetition):
|
||||
"""
|
||||
|
|
@ -325,10 +353,23 @@ class Arbitrary(Repetition):
|
|||
return (f'<Arbitrary {len(self.displacements)}pts >')
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, type(self)):
|
||||
if not type(other) is not type(self):
|
||||
return False
|
||||
return numpy.array_equal(self.displacements, other.displacements)
|
||||
|
||||
def __le__(self, other: Repetition) -> bool:
|
||||
if type(self) is not type(other):
|
||||
return repr(type(self)) < repr(type(other))
|
||||
other = cast(Arbitrary, other)
|
||||
if self.displacements.size != other.displacements.size:
|
||||
return self.displacements.size < other.displacements.size
|
||||
|
||||
neq = (self.displacements != other.displacements)
|
||||
if neq.any():
|
||||
return self.displacements[neq][0] < other.displacements[neq][0]
|
||||
|
||||
return False
|
||||
|
||||
def rotate(self, rotation: float) -> Self:
|
||||
"""
|
||||
Rotate dispacements (around (0, 0))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue