--- 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/`. - `end_session(req)` deletes that directory on unload. Notes: - Many image outputs are written under `TMPDIR/`. - 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 `.glb`. - `extract_gaussian(state)` writes `.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//resolve/main//...` - 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/`. - 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