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)