from typing import Iterable, Union, Callable, Optional, Tuple, List
from fibomat.shapes import HollowArcSpline, ArcSplineCompatible, Rect
from fibomat.linalg import Transformable, Vector, VectorLike
from fibomat.layout.lattices.lattice_base import LatticeBaseMixin
from fibomat.layout.groups.group import Group
from fibomat.units import U_
[docs]class Lattice(Group, LatticeBaseMixin):
[docs] def __init__(self, elements: List[Transformable], description: Optional[str] = None):
super().__init__(elements, description)
[docs] @classmethod
def generate_rect(
cls,
nu: int, nv: int,
du: float, dv: float,
element: Union[Transformable, Callable],
center: Optional[VectorLike] = None,
predicate: Optional[Union[Callable, List[Callable]]] = None,
explode: bool = False,
remove_outliers: bool = False,
):
nu = int(nu)
nv = int(nv)
if nu < 1 or nv < 1:
raise ValueError('nu and nv must be at least 1.')
du = float(du)
dv = float(dv)
seed_u = du / 2 if nu % 2 == 0 else 0
seed_v = dv / 2 if nv % 2 == 0 else 0
seed = Vector(seed_u, seed_v)
return cls.generate(
Rect(width=du*nu, height=dv*nv), (du, 0), (0, -dv), element, center, predicate, explode, remove_outliers, seed
)
[docs] @classmethod
def generate(
cls,
boundary: Union[HollowArcSpline, ArcSplineCompatible],
u: VectorLike, v: VectorLike,
element: Union[Transformable, Callable[[Tuple[float, float], Tuple[int, int]], Optional[Transformable]]],
center: Optional[VectorLike] = None,
predicate: Optional[Union[Callable, List[Callable]]] = None,
explode: bool = False,
remove_outliers: bool = False,
seed: Optional[VectorLike] = None
# break_layouts: bool = False
):
u = Vector(u)
v = Vector(v)
center = Vector(center)
if callable(element):
element_gen = element
else:
def element_gen(*args):
return element
if seed is None:
seed = center
else:
seed = Vector(seed)
elements = cls._generate_impl(
boundary, u, v, center, element_gen, predicate, explode, remove_outliers, lambda x: x, lambda x: x, seed
)
return cls(elements)
def __mul__(self, other):
if isinstance(other, U_):
from fibomat.layout.lattices.dim_lattice import DimLattice
return DimLattice([elem * other for elem in self.elements], description=self.description)
raise NotImplementedError