models.py

7.0 kB · python · 223 lines

1import numpy as np2from copy import deepcopy3from PIL import Image4from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING5from mrlypy.core.enums import Mode6from mrlypy.core.errors import MrlyError78if TYPE_CHECKING:9    from mrlypy.core.colors import Color10    from mrlypy.three.models import Cell3d1112class Cell2d:1314    def __init__(15        self,16        width: Optional[int] = None,17        height: Optional[int] = None,18        types: Optional[np.ndarray] = None,19        colors: Optional[np.ndarray] = None,20        tags: Optional[np.ndarray] = None,21    ):22        self._width = width23        self._height = height24        self._types = types25        self._colors = colors26        self._tags = tags2728    @property29    def width(self) -> int:30        if self._types is not None:31            return self._types.shape[1]32        if self._colors is not None:33            return self._colors.shape[1]34        if self._tags is not None:35            return self._tags.shape[1]36        if self._width is not None:37            return self._width38        raise MrlyError("Cell2d has no data and no dimensions")3940    @property41    def height(self) -> int:42        if self._types is not None:43            return self._types.shape[0]44        if self._colors is not None:45            return self._colors.shape[0]46        if self._tags is not None:47            return self._tags.shape[0]48        if self._height is not None:49            return self._height50        raise MrlyError("Cell2d has no data and no dimensions")5152    @property53    def types(self) -> np.ndarray:54        if self._types is None:55            self._types = np.zeros((self.height, self.width), dtype=np.uint8)56        return self._types5758    @types.setter59    def types(self, value: np.ndarray):60        self._types = value6162    @property63    def colors(self) -> np.ndarray:64        if self._colors is None:65            self._colors = np.zeros((self.height, self.width, 4), dtype=np.uint8)66        return self._colors6768    @colors.setter69    def colors(self, value: Optional[np.ndarray]):70        self._colors = value7172    @property73    def tags(self) -> np.ndarray:74        if self._tags is None:75            self._tags = np.zeros((self.height, self.width), dtype=np.uint8)76        return self._tags7778    @tags.setter79    def tags(self, value: Optional[np.ndarray]):80        self._tags = value8182    # MAIN8384    def shape(self) -> Tuple[int, int]:85        return (self.height, self.width)8687    def __repr__(self) -> str:88        return f"Cell2d(width={self.width}, height={self.height})"8990    def copy(self) -> "Cell2d":91        return deepcopy(self)9293    def to_3d(self) -> "Cell3d":94        from mrlypy.three.models import Cell3d95        return Cell3d(types=self.types[:, :, np.newaxis])9697    @classmethod98    def from_3d(cls, cell: "Cell3d") -> "Cell2d":99        types = cell.types[:, :, 0]100        return cls(types=types)101102    # SERIALIZER103104    def to_dict(self) -> Dict[str, Any]:105        from . import serializer106        return serializer.to_dict_2d(self)107108    @classmethod109    def from_dict(cls, data: Dict[str, Any]) -> "Cell2d":110        from . import serializer111        return serializer.from_dict_2d(data)112113    def to_array(self) -> np.ndarray:114        from . import serializer115        return serializer.to_array_2d(self)116117    @classmethod118    def from_array(cls, array: np.ndarray) -> "Cell2d":119        from . import serializer120        return serializer.from_array_2d(array)121122    def to_list(self) -> List[List[int]]:123        from . import serializer124        return serializer.to_list_2d(self)125126    @classmethod127    def from_list(cls, list: List[List[int]]) -> "Cell2d":128        from . import serializer129        return serializer.from_list_2d(list)130131    def to_strings(self) -> List[str]:132        from . import serializer133        return serializer.to_strings_2d(self)134135    @classmethod136    def from_strings(cls, data: List[str]) -> "Cell2d":137        from . import serializer138        return serializer.from_strings_2d(data)139140    # GEOMETRY141142    def invert(self) -> "Cell2d":143        from . import geometry144        return geometry.invert_2d(self)145146    def anti(self) -> "Cell2d":147        from . import geometry148        return geometry.invert_2d(self)149150    def pad(self, count: int = 1, value: int = 0) -> "Cell2d":151        from . import geometry152        return geometry.pad_2d(self, count, value)153154    def rotate(self, k: int = 1) -> "Cell2d":155        from . import geometry156        return geometry.rotate_2d(self, k)157158    def fractal(self, level: int = 1) -> "Cell2d":159        from . import geometry160        return geometry.fractal_2d(self, level)161162    def tile(self, width: int, height: int) -> "Cell2d":163        from . import geometry164        return geometry.tile_2d(self, width, height)165166    def layers(self, dtype: np.dtype = np.dtype(np.uint8)) -> "Cell2d":167        from . import geometry168        return geometry.layers_2d(self, dtype)169170    def neighbors(self, types: np.ndarray, target: int = 1, mode: str = "constant", dtype: np.dtype = np.dtype(np.uint8)) -> "Cell2d":171        from . import geometry172        return geometry.neighbors_2d(self, types, target, mode, dtype)173174    # CENSUS175176    def census(self) -> Dict[str, int]:177        from mrlypy.core import census178        return census.census_2d(self.types)179180    # PAINTER181182    def paint(self, palette: Optional[Dict[int, List["Color"]]] = None, mode: Optional[Mode] = None) -> "Cell2d":183        from . import painter184        return painter.paint_2d(self, palette, mode)185186    # RENDERER187188    def text(self, mapping: Optional[Dict[int, str]] = None) -> List[str]:189        from . import renderer190        return renderer.text_2d(self.types, mapping)191192    def to_image(self, scale: int = 1) -> Image.Image:193        from . import renderer194        return renderer.to_image(self, scale)195196    @classmethod197    def from_image(cls, image: Image.Image) -> "Cell2d":198        from . import renderer199        return renderer.from_image(image)200201    def draw_square(self, scale: int = 1, outline: Optional["Color"] = None, width: int = 1) -> Image.Image:202        from . import renderer203        return renderer.draw_square(self, scale, outline, width)204205    def draw_circle(self, scale: int = 1, outline: Optional["Color"] = None, width: int = 1) -> Image.Image:206        from . import renderer207        return renderer.draw_circle(self, scale, outline, width)208209    def draw_diamond(self, scale: int = 1, outline: Optional["Color"] = None, width: int = 1) -> Image.Image:210        from . import renderer211        return renderer.draw_diamond(self, scale, outline, width)212213    def svg_square(self, scale: int = 1, outline: Optional["Color"] = None, width: int = 1) -> str:214        from . import renderer215        return renderer.svg_square(self, scale, outline, width)216217    def svg_circle(self, scale: int = 1, outline: Optional["Color"] = None, width: int = 1) -> str:218        from . import renderer219        return renderer.svg_circle(self, scale, outline, width)220221    def svg_diamond(self, scale: int = 1, outline: Optional["Color"] = None, width: int = 1) -> str:222        from . import renderer223        return renderer.svg_diamond(self, scale, outline, width)