Spaces:
Running on Zero
Running on Zero
| 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 | |