-
Notifications
You must be signed in to change notification settings - Fork 0
Implementing Materials detected from the Vacuums #41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
2b5bd0e
adding const.py and update types.py to separate const and types
sca075 c6ab4ee
last files for 12 isort / ruff and lint
sca075 e6b006c
remove duplicate import of const
sca075 a5ca571
const was not properly imported
sca075 0d4f63c
minor changes in rand256_handler.py, shared.py removed snapshot at in…
sca075 c412fd7
updated __init__.py
sca075 11c09e2
updated __init__.py all
sca075 cb056f4
updated __init__.py all
sca075 4e21656
update shared.py to load floor data from the config if present else u…
sca075 0505a8c
update TrimsCropData to use the floors when init, else default values.
sca075 9426afb
Merge branch 'main' into dev_main
sca075 3b9d5b2
feat: Add carpet zone detection and rendering support
sca075 3bea98e
feat: Add carpet zone detection and rendering support
sca075 de0effa
fix: Add missing CARPET to element_color_mapping
sca075 644b81e
Dead code removed. The _draw_carpets method was leftover from the ini…
sca075 f3af432
Merge branch 'main' into dev_main
sca075 a67cd56
Materials implementation and configuration
sca075 317511d
removed test and unused code _update_material_colors()
sca075 dbe642f
improved material.py drawings with mcvrender
sca075 9ac664b
isort and ruffed code and added configurable colours for material.py
sca075 a7ce494
Merge branch 'main' into dev_main
sca075 64c4743
updated types.py isort and ruff
sca075 7536d8f
updated drawable_elements.py with correct colors name for material
sca075 b009533
double import correction in colors.py and indexing
sca075 f30bafd
use MaterialColor instead of direct access.
sca075 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,223 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from dataclasses import dataclass | ||
| from functools import lru_cache | ||
| from typing import Final, Optional | ||
|
|
||
| import numpy as np | ||
| from mvcrender.draw import line_u8 | ||
|
|
||
| from .colors import color_material_tile, color_material_wood | ||
| from .types import Color, NumpyArray | ||
|
|
||
|
|
||
| @dataclass(frozen=True, slots=True) | ||
| class _MaterialSpec: | ||
| cells: int | ||
| kind: str # "wood_h", "wood_v", "tile" | ||
|
|
||
|
|
||
| @dataclass(frozen=True, slots=True) | ||
| class MaterialColors: | ||
| """Material colors for rendering.""" | ||
|
|
||
| wood_rgba: Color = color_material_wood | ||
| tile_rgba: Color = color_material_tile | ||
|
|
||
|
|
||
| # Create a singleton instance for easy access | ||
| _material_colors = MaterialColors() | ||
|
|
||
|
|
||
| class MaterialTileRenderer: | ||
| """ | ||
| Material patterns rendered as small RGBA tiles. | ||
|
|
||
| Wood is drawn as staggered rectangular planks (brick-like) with ONLY thin seams | ||
| (no extra inner grain line). | ||
| """ | ||
|
|
||
| _SPECS: Final[dict[str, _MaterialSpec]] = { | ||
| "wood_horizontal": _MaterialSpec(cells=36, kind="wood_h"), | ||
| "wood_vertical": _MaterialSpec(cells=36, kind="wood_v"), | ||
| "tile": _MaterialSpec(cells=4, kind="tile"), | ||
| } | ||
|
|
||
| @staticmethod | ||
| def _empty_rgba(h: int, w: int) -> NumpyArray: | ||
| return np.zeros((h, w, 4), dtype=np.uint8) | ||
|
|
||
| @staticmethod | ||
| def _thin_px(pixel_size: int) -> int: | ||
| """Thin seam thickness in pixels (for pixel_size 5/7 -> 1 px).""" | ||
| return 1 if pixel_size <= 7 else 2 | ||
|
|
||
| @staticmethod | ||
| def _draw_rect_outline( | ||
| tile: NumpyArray, | ||
| x0: int, | ||
| y0: int, | ||
| x1: int, | ||
| y1: int, | ||
| thickness: int, | ||
| rgba: Color, | ||
| ) -> None: | ||
| """Draw rectangle outline using mvcrender.line_u8.""" | ||
| if x1 <= x0 or y1 <= y0: | ||
| return | ||
|
|
||
| # Draw four lines to form rectangle outline | ||
| # Top line | ||
| line_u8(tile, x0, y0, x1 - 1, y0, rgba, thickness) | ||
| # Bottom line | ||
| line_u8(tile, x0, y1 - 1, x1 - 1, y1 - 1, rgba, thickness) | ||
| # Left line | ||
| line_u8(tile, x0, y0, x0, y1 - 1, rgba, thickness) | ||
| # Right line | ||
| line_u8(tile, x1 - 1, y0, x1 - 1, y1 - 1, rgba, thickness) | ||
|
|
||
| @staticmethod | ||
| def _wood_planks_horizontal( | ||
| tile_px: int, pixel_size: int, color: Color | ||
| ) -> NumpyArray: | ||
| """ | ||
| Horizontal wood planks as staggered rectangles. | ||
| ONLY thin seams (no inner lines). | ||
| """ | ||
| t = MaterialTileRenderer._empty_rgba(tile_px, tile_px) | ||
| seam = MaterialTileRenderer._thin_px(pixel_size) | ||
|
|
||
| # Plank size in CELLS (tweak here) | ||
| plank_h_cells = 3 | ||
| plank_w_cells = 24 # longer planks -> looks less like tiles | ||
|
|
||
| plank_h = plank_h_cells * pixel_size | ||
| plank_w = plank_w_cells * pixel_size | ||
|
|
||
| rows = max(1, tile_px // plank_h) | ||
| cols = max(1, (tile_px + plank_w - 1) // plank_w) | ||
|
|
||
| for r in range(rows + 1): | ||
| y0 = r * plank_h | ||
| y1 = y0 + plank_h | ||
| offset = (plank_w // 2) if (r % 2 == 1) else 0 | ||
|
|
||
| for c in range(cols + 1): | ||
| x0 = c * plank_w - offset | ||
| x1 = x0 + plank_w | ||
|
|
||
| cx0 = max(0, x0) | ||
| cy0 = max(0, y0) | ||
| cx1 = min(tile_px, x1) | ||
| cy1 = min(tile_px, y1) | ||
|
|
||
| MaterialTileRenderer._draw_rect_outline( | ||
| t, cx0, cy0, cx1, cy1, seam, color | ||
| ) | ||
|
|
||
| return t | ||
|
|
||
| @staticmethod | ||
| def _wood_planks_vertical( | ||
| tile_px: int, pixel_size: int, color: Color | ||
| ) -> NumpyArray: | ||
| """Vertical wood planks as staggered rectangles, ONLY thin seams.""" | ||
| t = MaterialTileRenderer._empty_rgba(tile_px, tile_px) | ||
| seam = MaterialTileRenderer._thin_px(pixel_size) | ||
|
|
||
| plank_w_cells = 3 | ||
| plank_h_cells = 24 | ||
|
|
||
| plank_w = plank_w_cells * pixel_size | ||
| plank_h = plank_h_cells * pixel_size | ||
|
|
||
| cols = max(1, tile_px // plank_w) | ||
| rows = max(1, (tile_px + plank_h - 1) // plank_h) | ||
|
|
||
| for c in range(cols + 1): | ||
| x0 = c * plank_w | ||
| x1 = x0 + plank_w | ||
| offset = (plank_h // 2) if (c % 2 == 1) else 0 | ||
|
|
||
| for r in range(rows + 1): | ||
| y0 = r * plank_h - offset | ||
| y1 = y0 + plank_h | ||
|
|
||
| cx0 = max(0, x0) | ||
| cy0 = max(0, y0) | ||
| cx1 = min(tile_px, x1) | ||
| cy1 = min(tile_px, y1) | ||
|
|
||
| MaterialTileRenderer._draw_rect_outline( | ||
| t, cx0, cy0, cx1, cy1, seam, color | ||
| ) | ||
|
|
||
| return t | ||
|
|
||
| @staticmethod | ||
| def _tile_pixels(cells: int, pixel_size: int, tile_rgba: Color) -> NumpyArray: | ||
| """Draw tile grid using mvcrender.line_u8.""" | ||
| size = cells * pixel_size | ||
| t = MaterialTileRenderer._empty_rgba(size, size) | ||
| th = MaterialTileRenderer._thin_px(pixel_size) | ||
| rgba = tile_rgba | ||
|
|
||
| # Draw horizontal line at top | ||
| line_u8(t, 0, 0, size - 1, 0, rgba, th) | ||
| # Draw vertical line at left | ||
| line_u8(t, 0, 0, 0, size - 1, rgba, th) | ||
|
|
||
| return t | ||
|
|
||
| @staticmethod | ||
| @lru_cache(maxsize=64) | ||
| def get_tile( | ||
| material: str, pixel_size: int, colors: MaterialColors = None | ||
| ) -> Optional[NumpyArray]: | ||
| spec = MaterialTileRenderer._SPECS.get(material) | ||
| if spec is None or pixel_size <= 0: | ||
| return None | ||
|
|
||
| # Use provided colors or fall back to defaults | ||
| if colors is None: | ||
| colors = _material_colors | ||
|
|
||
| wood_color = colors.wood_rgba | ||
| tile_color = colors.tile_rgba | ||
|
|
||
| if spec.kind == "tile": | ||
| return MaterialTileRenderer._tile_pixels(spec.cells, pixel_size, tile_color) | ||
|
|
||
| tile_px = spec.cells * pixel_size | ||
| if spec.kind == "wood_h": | ||
| return MaterialTileRenderer._wood_planks_horizontal( | ||
| tile_px, pixel_size, wood_color | ||
| ) | ||
| if spec.kind == "wood_v": | ||
| return MaterialTileRenderer._wood_planks_vertical( | ||
| tile_px, pixel_size, wood_color | ||
| ) | ||
|
|
||
| return None | ||
|
|
||
| @staticmethod | ||
| def tile_block(tile: NumpyArray, r0: int, r1: int, c0: int, c1: int) -> NumpyArray: | ||
| th, tw, _ = tile.shape | ||
| rows = (np.arange(r0, r1) % th).astype(np.intp, copy=False) | ||
| cols = (np.arange(c0, c1) % tw).astype(np.intp, copy=False) | ||
| return tile[rows[:, None], cols[None, :], :] | ||
|
|
||
| @staticmethod | ||
| def apply_overlay_on_region( | ||
| image: NumpyArray, | ||
| tile: NumpyArray, | ||
| r0: int, | ||
| r1: int, | ||
| c0: int, | ||
| c1: int, | ||
| ) -> None: | ||
| region = image[r0:r1, c0:c1] | ||
| overlay = MaterialTileRenderer.tile_block(tile, r0, r1, c0, c1) | ||
| mask = overlay[..., 3] > 0 | ||
| if np.any(mask): | ||
| region[mask] = overlay[mask] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.