HexaGrid / spec.mdx
Surn's picture
Add project spec, update README metadata, and .gitignore
4fc5901
Raw
History Blame Contribute Delete
11.9 kB
---
title: HexaGrid Creator Project Spec / Context
version: 0.1
source_repo:
github: https://github.com/Oncorporation/HexaGrid
huggingface_space: https://huggingface.co/spaces/Surn/HexaGrid
last_updated: 2026-02-12
---
# HexaGrid Creator (Beeuty-MapMaker)
## 1) What this project is
HexaGrid Creator is a Gradio (Hugging Face Spaces) application that:
- Takes an **input image** and generates a **tiled grid overlay** (hexagon / square / triangle) suitable for tabletop maps.
- Optionally generates a new image via **FLUX** (Diffusers) with **LoRA** styles, and then applies the grid.
- Supports interactive **image filtering** via **LUT (.cube)** files, plus compositing/blur utilities.
- Can generate a **depth map** (DPT) and a **3D asset** (TRELLIS pipeline), then export **GLB** and **Gaussian PLY**.
- Can produce a shareable **permalink** to an external 3D viewer by uploading assets to a Hugging Face **dataset repo**.
Primary entrypoint: `app.py`.
## 2) Deployment target and runtime
### Hugging Face Spaces metadata (from `README.md` frontmatter)
- SDK: `gradio`
- `python_version`: **3.10.13**
- `sdk_version`: **5.44.1**
- `app_file`: `app.py`
- OAuth: `hf_oauth: true`
### GPUs and ZeroGPU note
The UI warns that **ZeroGPU** may be unavailable or crash intermittently. This is treated as an infrastructure limitation rather than a code defect.
## 3) Repository layout (high-level)
- `app.py`: Main Gradio Blocks UI + orchestration.
- `utils/`: Application modules used by `app.py`.
- `trellis/`: TRELLIS 3D pipeline package (imported as `trellis.*`).
- `assets/`, `images/`, `LUT/`, `fonts/`: Static resources used by the UI.
- `style_20250314.css`: UI CSS.
- `requirements.txt`, `pre-requirements.txt`: Python dependencies.
- `wheels/`: platform-specific wheel artifacts referenced by `requirements.txt`.
## 4) Key dependencies and version-sensitive components
### Python package stack (from `requirements.txt`)
This project relies on:
- Gradio UI + Spaces GPU decorator: `gradio`, `spaces`
- Diffusers & model tooling: `diffusers` (git), `transformers`, `accelerate`, `safetensors`, `peft`
- Torch stack (CUDA index used): `torch`, `torchvision`, `xformers==0.0.29.post3`
- Image processing: `Pillow`, `opencv-python`, `opencv-python-headless`, `imageio`, `imageio-ffmpeg`, `numpy==1.26.4`, `scipy`
- Palette extraction: `Haishoku`
- 3D processing: `open3d`, `trimesh`, `xatlas`, `pyvista`, `pymeshfix`, `igraph`, `utils3d` (git)
- Background removal: `rembg`, `onnxruntime`
- Cairo/Pango for text rendering: `pycairo`, `cairocffi`, `pangocffi`, `pangocairocffi`, `cairosvg`
- CUDA/3D special wheels referenced (Linux-specific links present):
- `flash_attn` wheel
- `diff_gaussian_rasterization` wheel
- `nvdiffrast` wheel
### Environment and tokens
- `utils/constants.py` requires `HF_TOKEN` to be present; it raises at import time if missing.
- Several Hugging Face operations implicitly depend on write permissions to a dataset used for uploads/shortlinks.
## 5) Session model and temp storage
### Session directories
- `start_session(req)` creates a per-session directory at `utils.constants.TMPDIR/<session_hash>`.
- `end_session(req)` deletes that directory on unload.
Notes:
- Many image outputs are written under `TMPDIR/<session_hash>`.
- Some functions still use the module-level `user_dir = constants.TMPDIR`; watch for places where session scoping is expected but not passed through.
## 6) Feature map & UI structure (Gradio)
The app is defined using `gr.Blocks(...) as hexaGrid` in `app.py` with major sections:
### Left panel
- `Input Image` (uploaded file path)
- `Sketch Pad` (`gr.Sketchpad`) for drawing/overlaying; can replace the input image.
- `Generate HURA Background` (procedural pattern generator from `utils/hex_hura.py`).
### Right panel
- `Image Filters (LUT)`: upload/select `.cube` file and apply to input/sketch/HURA.
- `Color Composite` and `Blur` tools.
### Tabs
1. `HexaGrid Generation`
- Core grid parameters (hex size, border, fill, rotation, background/border colors).
- Excluded color list management.
- Grid shape selection: triangle / square / hexagon.
- Optional text labeling inside tiles.
- Output images: grid render + overlay.
- Post transforms: tilt/rotate, alpha composite, multiply blend, interpolate (lerp).
2. `Image Generation (AI)`
- Generates an image using FLUX pipelines and LoRA “style gallery”.
- Supports img2img and “Fill” model flows.
- Template (pre-rendered) image gallery.
3. `Add Margins`
- Adds printable margins (DPI-aware) to input/overlay image.
4. `3D and Depth (fun)`
- Loads DPT depth estimation + TRELLIS 3D pipeline on accordion expand.
- Creates depth map, then generates 3D asset, video preview.
- Exports GLB and Gaussian PLY.
- Builds permalink for external viewer.
## 7) Core pipelines (end-to-end flows)
### 7.1 Grid generation pipeline
Entry: `hex_button.click(...)` `hex_create(...)`
- Loads input image, coerces to RGBA; if conversion fails, it pads onto a minimum canvas.
- Builds an input palette via `Haishoku.loadHaishoku(...)`.
- Converts UI colors + opacity to RGBA tuples via `utils.color_utils.update_color_opacity`.
- Calls `utils.hex_grid.generate_hexagon_grid_interface(...)` (wrapper around grid generation + overlay creation).
- Writes output files with `utils.image_utils.save_image_to_temp_png(...)` under the session directory.
Outputs:
- `output_image`: rendered tiled grid result
- `overlay_image`: overlay-only layer
### 7.2 Excluded color workflow
Module: `utils/excluded_colors.py`
- Stores excluded colors as a `gr.State` list of RGBA tuples.
- UI allows adding via `add_color`, deleting rows via `delete_color`, and manual edits via `on_input`.
- Grid sampling can filter out excluded colors (`filter_color` checkbox).
### 7.3 LUT filter pipeline
Module: `utils.image_utils.py`
- UI selects a LUT filename (from `constants.lut_files`) and previews it (`show_lut`).
- Apply operations call `apply_lut_to_image_path(lut_filename, image_path, intensity)`.
Important behavior:
- Images are opened through `open_image(...)` which supports local paths, URLs, and DataURL strings.
- Some file types (SVG/ICO) are converted to PNG.
### 7.4 AI image generation (FLUX + LoRA)
Primary functions:
- `get_model_and_lora(model_textbox)`
- `set_pipeline(model_name, lora_weights, pipeline_name)`
- `generate_image_lowmem(...)` (decorated with `@spaces.GPU(duration=230)`)
- `generate_ai_image_local(...)`
- `generate_input_image_click(...)` (UI handler)
Key concepts:
- Pipeline classes are selected from `PIPELINE_CLASSES`:
- `FluxPipeline`
- `FluxImg2ImgPipeline`
- `FluxControlPipeline`
- `FluxFillPipeline`
- LoRA configuration is driven by `utils.constants.LORA_DETAILS` and helper methods in `utils/lora_details.py`.
- For long prompts, `split_prompt_precisely(...)` is used when token count exceeds a threshold.
Performance/memory approach:
- Pipeline is moved to `device` for execution then returned to CPU with CUDA cache cleared.
- `enable_model_cpu_offload()` is used in some paths.
### 7.5 Depth + 3D generation (DPT + TRELLIS)
Load/unload model flow:
- `load_3d_models(is_open=True)` loads:
- `DPTImageProcessor.from_pretrained("Intel/dpt-large")`
- `DPTForDepthEstimation.from_pretrained("Intel/dpt-large", ignore_mismatched_sizes=True)`
- TRELLIS pipeline via `load_trellis_model()` when not in shared space.
- `unload_3d_models(is_open=False)` deletes models and runs GC.
Depth map creation:
- `depth_process_image(image_path, resized_width, z_scale)` produces an 8-bit depth image.
3D asset creation:
- `generate_3d_asset_part1(...)` chooses source image, creates depth map file.
- `generate_3d_asset_part2(...)` runs TRELLIS:
- preprocesses images
- optionally uses multi-image algorithms (`singleimage`, `stochastic`, `multidiffusion`)
- renders a preview mp4 via `render_utils.render_video`
- packs results into a serializable “state” dict (`pack_state` / `unpack_state`).
Exports:
- `extract_glb(state, mesh_simplify, texture_size)` writes `<name>.glb`.
- `extract_gaussian(state)` writes `<name>.ply`.
### 7.6 Permalink creation + upload storage
The 3D tab can create a shareable viewer link.
Implementation components:
- `app.py:create_permalink(...)` calls `utils.storage.upload_files_to_repo(...)` with:
- smallest of (GLB, Gaussian)
- depth image
- source image used for depth
- `utils/storage.py` handles:
- extension filtering
- `upload_folder(...)` batching
- link building under `https://huggingface.co/datasets/<repo_id>/resolve/main/<folder_name>/...`
- optional permalink building and URL shortening via JSON mapping
`utils/storage.py` version:
- `__version__ = "0.1.1"`
Shortener behavior:
- `gen_full_url(full_url=...)` stores mapping in a JSON file in a dataset repo.
- `version_info.versions_html()` links to the shortener JSON file for debugging.
## 8) `utils/` modules (responsibilities)
This list focuses on modules imported directly by `app.py`.
- `utils/constants.py`
- Environment loading (`.env`) and required `HF_TOKEN` enforcement
- UI prompt presets and negative prompts (`PROMPTS`, `NEGATIVE_PROMPTS`)
- Pre-rendered template image registry (`PRE_RENDERED_MAPS_JSON_LEVELS`)
- Model registry (`MODELS`, `LORA_WEIGHTS`, `LORA_TO_MODEL`, `LORA_DETAILS`)
- Temp directory root (`TMPDIR`) used for session subfolders
- `utils/image_utils.py`
- `open_image(...)` + helpers (`get_image_from_dict`, SVG/ICO conversion)
- LUT preview/apply helpers
- Compositing/blending functions (`alpha_composite_with_control`, lerp, multiply)
- Temp PNG writer `save_image_to_temp_png(...)`
- Pre-rendered gallery builder `build_prerendered_images_by_quality(...)`
- `utils/hex_grid.py`
- Core grid rendering algorithms (hex/square/triangle tiling)
- Shape selection mapping via `map_sides(...)`
- Text-in-tile rendering utilities (Pango/Cairo + emoji font)
- `utils/excluded_colors.py`
- Gradio state + DataFrame helpers for excluded RGBA colors
- `utils/file_utils.py`
- File path parsing and safe extension normalization
- Temp file cleanup tracking via `constants.temp_files`
- `utils/storage.py`
- Upload assets to HF dataset repo and create permalink
- URL shortener JSON file management
- `utils/version_info.py`
- Visible runtime diagnostics in UI footer
## 9) Operational notes / gotchas
- `utils/constants.py` raises if `HF_TOKEN` is not set this affects local dev and any import-time tooling.
- Some dependencies are platform-specific (Linux wheels referenced directly). Windows dev may require different wheels.
- Some paths in `hexaGrid.launch(allowed_paths=...)` include absolute drive paths (e.g., `e:/TMP`), which may not exist locally.
- `atexit.register(end_session)` registers `end_session(req)` without a `req`; this is likely a no-op or error path in some environments. Session cleanup is mostly handled by Gradio `load`/`unload` events.
## 10) How to extend safely (agent/human guidance)
- Prefer adding new UI actions as pure functions in `utils/` with minimal coupling to Gradio components.
- Keep session scoping by writing outputs to `TMPDIR/<session_hash>`.
- When adding new upload/permalink types, update `utils/constants.py` extension lists and ensure `utils/storage.py` filters accept them.
- When adding LoRAs, use `constants.LORA_DETAILS` and `utils/lora_details.py` conventions rather than hardcoding behavior in `app.py`.
## 11) Quick pointers for reading the code
- Start with `app.py` to understand UI event wiring and high-level orchestration.
- Then read:
- `utils/hex_grid.py` for the tiling algorithm
- `utils/image_utils.py` for I/O and image transforms
- `utils/storage.py` for permalink/upload semantics
- `utils/constants.py` for the “registry” of models, LoRAs, templates, and environment variables