Source code for fibomat.layout.groups.group_base

from __future__ import annotations
from typing import Optional, List, Iterator, Any, TypeVar, Generic
import abc

from frozenlist import FrozenList

from fibomat.layout.layoutbase import LayoutBase
from fibomat.linalg import Transformable, DimTransformable, VectorLike, DimVectorLike, BoundingBox, DimBoundingBox
from fibomat.layout.utils import _have_same_type


ElementT = TypeVar('ElementT', Transformable, DimTransformable)
VectorT = TypeVar('VectorT', VectorLike, DimVectorLike)
BBoxT = TypeVar('BBoxT', BoundingBox, DimBoundingBox)


[docs]class GroupBase(LayoutBase[ElementT, VectorT, BBoxT], abc.ABC):
[docs] def __init__( self, elements: List[ElementT], description: Optional[str] = None ): if not elements: raise ValueError('Length if elements must not be zero.') if not _have_same_type(elements): raise TypeError('Elements in a layout must have same (base) type.') self._elements: FrozenList[ElementT] = FrozenList(elements) self._elements.freeze() # we evaluate this only if needed self._center = None self._bounding_box = None super().__init__(description=description)
@property def elements(self): return self._elements def _layout_elements(self) -> Iterator[ElementT]: for element in self._elements: yield element @property def center(self) -> VectorT: if self._center: return self._center else: center = self._elements[0].center for element in self._elements[1:]: center += element.center center /= len(self._elements) self._center = center return center @property def bounding_box(self) -> BBoxT: if self._bounding_box: return self._bounding_box else: bbox = self._elements[0].bounding_box for element in self._elements[1:]: bbox = bbox.extended(element.bounding_box) self._bounding_box = bbox return bbox def _impl_translate(self, trans_vec: VectorT) -> None: for element in self._elements: element._impl_translate(trans_vec) def _impl_rotate(self, theta: float) -> None: for element in self._elements: element._impl_rotate(theta) def _impl_scale(self, fac: float) -> None: for element in self._elements: element._impl_scale(fac) def _impl_mirror(self, mirror_axis: VectorT) -> None: for element in self._elements: element._impl_mirror(mirror_axis)