Spaces:
Paused
Paused
Commit History
-
Remove remaining @spaces.GPU decorators from bake_albedo and bake_ao
68a4e06 -
Fix ZeroGPU proxy token expiry: single GPU allocation for full pipeline
Individual @spaces.GPU decorators on each baking stage caused the proxy token (tied to the original Gradio request) to expire by the time material and AO baking ran. Fix: remove per-stage decorators and put a single @spaces.GPU(duration=600) on run_post_process so all baking happens within one uninterrupted GPU allocation.5dad3a0 -
Fix nvdiffrast SM mismatch: add +PTX arch + GL context fallback
cudaErrorNoKernelImageForDevice (209) means the compiled kernels don't match the actual GPU (likely Blackwell SM 10.0 on ZeroGPU's CUDA 13.0 upgrade). Fix: - TORCH_CUDA_ARCH_LIST="8.0;8.9;9.0+PTX": +PTX lets CUDA 13.0 runtime JIT-compile for any newer arch (SM 10.0) at first use - Marker file (/tmp/nvdiffrast_arch.txt) avoids redundant rebuilds on warm container restarts; force-reinstalls when arch string changes - All four bake stages fall back to RasterizeGLContext if CUDA context creation fails851bece -
Fix nvdiffrast ABI mismatch + pymeshfix TrackedArray crash
- Replace Jeff Xiang's prebuilt nvdiffrast wheel (built against PyTorch ~2.5.x) with a source build from git so it compiles against torch 2.8.0 - Add packages.txt with ninja-build and OpenGL headers needed for compilation - Fix pymeshfix load_array crash: cast trimesh TrackedArray to plain np.ndarray with correct dtypes (float64 vertices, int32 faces)09e4a10
-
Fix pymeshlab pipeline crash + add post-process progress streaming
- Re-add pymeshlab to requirements.txt: hy3dshape/postprocessors.py imports it at module level, so removing it broke _get_hy_pipeline(). The import itself works fine; only the OpenGL-dependent filter plugins print warnings (which we no longer call from our own code). - Replace inline pymeshlab decimation in generate_hunyuan with fast_simplification to match stage2_decimate.py - run_post_process() is now a streaming generator: yields cumulative status markdown at each step so the UI updates live (⏳ before, ✅/⚠️ after each stage completes)f9271f9 -
Fix all post-processing errors on ZeroGPU/headless environment
Repair (stage2_repair.py): - Remove verbose=False from PyTMesh() — kwarg dropped in pymeshfix ≥0.17 Cleanup (stage2_cleanup.py): - Remove remove_duplicate_faces() call — removed from trimesh 4.x - Replace entire PyMeshLab filter chain with trimesh process=True + trimesh.repair.fix_winding/fix_normals (no OpenGL dependency) Decimation (stage2_decimate.py): - Replace PyMeshLab quadric decimation with fast_simplification (VTK-based, no libOpenGL.so.0 needed); both preview and final pass now use the same fast_simplification.simplify() call LODs (stage2_finalize.py): - Same: replace PyMeshLab+PLY intermediate with fast_simplification directly on trimesh vertices/faces requirements.txt: - Remove pymeshlab (its filter plugins need libOpenGL.so.0 which is absent on headless ZeroGPU Spaces — causes "Unknown format for load: ply") nvdiffrast ABI mismatch (_ZN3c107WarningC1E... symbol) is a known issue with the torch 2.6.0-compiled wheel on torch 2.8.0; baking stages already degrad…c6d0961 -
Fix state persistence across ZeroGPU subprocess boundary
ZeroGPU runs @spaces.GPU functions in a forked subprocess. Any writes to module-level variables (_state) are invisible to the parent Gradio process, causing Tab 2 to report "no asset" and the viewer to clear on refresh even after a successful generation. Fix: - workspace.py: get_state() now calls _build_state_from_disk() which scans CURRENT/ for known filenames and reads .meta.json for metadata. This makes all state reads cross-process-safe. - workspace.py: flush_meta(state) writes face_count, vertex_count, model_used, asset_name to CURRENT/.meta.json from the subprocess. - stage1_generate.py: both generate_hunyuan and generate_trellis call workspace.flush_meta(ws) before yielding the final result. - ui_helpers.py: get_viewer_model_path() now scans CURRENT/ directly (no longer reads _state) — correct from any process. - The viewer glb path returned directly from handle_generate bypasses all state lookups for the initial display.299ba9b -
Fix viewer not updating: direct GLB output + allowed_paths
- Moved gen_btn.click() wiring to after gr.Model3D viewer is defined so outputs=[gen_status, viewer] is valid (viewer was not in scope when the click was wired inside Tab 1) - generate_hunyuan() now yields (status_str, glb_path|None) tuples; the final yield carries str(raw_gen_path) so Gradio receives the GLB path as a direct function output and serves it automatically — no separate state lookup needed - Added allowed_paths=[workspace.WORKSPACE] to launch() so Gradio 5 can serve files from the workspace directory (without this, local paths returned to gr.Model3D are silently rejected) - _gen_event.then() now only refreshes [summary, status_bar] since the viewer is already updated by the direct output above - pp/rig/ex still use _global_refresh for all three (viewer, summary, status_bar) via .then()1fe7d3d -
Add streaming progress to generate_hunyuan + fix omegaconf dep
- generate_hunyuan() is now a generator: yields status at each of 5 stages (load images → rembg → load pipeline → diffusion → save) so the UI updates live instead of showing a blank status bar - handle_generate() updated to yield-from for Hunyuan3D and yield for TRELLIS.2 — both stream into the gen_status Markdown component - Added omegaconf to requirements.txt (required by hy3dshape config loading, was causing ModuleNotFoundError at generation time)bb34c64 -
Implement Hunyuan3D-2.1 generation with background removal
- generate_hunyuan() is now fully implemented using the vendored hy3dshape package (tencent/Hunyuan3D-2.1, diffusers-based, no custom CUDA wheels, works on torch 2.8.0 + ZeroGPU H200) - @spaces.GPU(duration=240) wraps the local inference call - Pipeline is loaded lazily on first GPU request and cached globally - Background removal via rembg (IS-Net) with fallback to hy3dshape's BackgroundRemover; toggled by do_rembg parameter - Multi-view support: >1 image routed as {front/left/back/right} dict - Working mesh is decimated via PyMeshLab to preset face target; full mesh saved as high_poly.glb for Stage 2 baking - Added gen_rembg checkbox to the Generate tab (default: on) - Hunyuan3D-2.1 is now the default model (moved to top of radio) - Preset save/load includes rembg flag (n=27 components) - requirements.txt: added diffusers>=0.30.0, accelerate, einops, rembg0062a30 -
Fix: preprocess image on remote TRELLIS.2 Space before calling image_to_3d
image_to_3d uses preprocess_image=False — it expects the image to already have background removed and be cropped to the object bounding box. In the UI flow this is done by the image_prompt.upload() event handler before generation runs. When calling via gradio_client we bypass that handler, sending a raw RGB image that causes the model to raise RuntimeError. Fix: add a Step 0 that calls /preprocess_image on the remote Space first. This runs background removal (BRIA-RMBG via the Space's own rmbg_client) and crops to bbox, producing the RGBA image image_to_3d expects. Falls back to raw image if preprocessing endpoint is unavailable.8138769 -
Polish: preset loading, quota recording, coacd fallback
- app.py: add ui_load_preset() — loads a saved preset and applies gr.update() to all 26 UI components across Stage 1-4 tabs. Add 'Load selected' button to Presets tab wired to all target components. Preset load/save/delete now fully symmetric. - stage1_generate.py: record elapsed wall-clock time to quota tracker after each generate call so the status bar stays accurate. - stage2_finalize.py: broaden coacd except clause from ImportError to Exception so any runtime failure (e.g. version mismatch) falls back to convex_hull gracefully.85a0e9b -
Fix: replace PyPI nvdiffrast (doesn't exist) with Jeff Xiang's prebuilt wheel
nvdiffrast is not published on PyPI — pip found zero matching distributions. Use the prebuilt cp310 wheel from JeffreyXiang/Storages instead. Also add try/except guards at the top of every @spaces.GPU baking function so that if the wheel fails to load at runtime (e.g. ABI mismatch with torch 2.8+) the Space still boots and the baking steps return a clear error message rather than crashing the process.eb018ed -
Milestones 9-12: UniRig, UE5 Export, Presets, Polish
Milestone 9 — Stage 3 Auto-Rigging (stage3_rig.py): - gradio_client → MohamedRashad/UniRig: sends GLB, downloads rigged.glb - Same client pattern as TRELLIS.2 generation (no local GPU/weights needed) - Handles rig_type + seed inputs; outputs saved to workspace/current/ Milestone 10 — Stage 4 UE5 Export (stage4_export.py): - Bundles all workspace outputs into a UE5-ready zip: SM_/SK_ mesh, LOD1/2, UCX_ collision, T_*_D/N/ORM textures + manifest.json - Game-ready checklist warns before export (missing UVs, LODs, collision, etc.) - engine != UE5 returns informative stub (Unity/Godot/Blender planned) Milestone 11 — Presets (workspace/presets/*.json + app.py): - ui_save_preset() now reads ALL tab UI values and writes real JSON - 5 default presets committed to workspace/presets/ - Presets tab description updated Milestone 12 — Polish: - Game-ready checklist before export (already in handle_export) - Presets tab fully wired; Save captures all Stage 1-4 settings app.py: rig_btn → handle_…75e8e33 -
Milestones 6+8: albedo/material/AO baking + ORM pack, LODs, collision, pivot, scale
Milestone 6 — Stage 2G-2I (stage2_bake_albedo.py, stage2_bake_ao.py): - bake_albedo(): vertex-colour albedo to UV atlas via nvdiffrast + trimesh proximity - bake_material(): metallic/roughness maps; reads mesh metadata attrs from TRELLIS.2 GLB, falls back to dielectric defaults (met=0, rough=0.5) - bake_ao(): hemisphere ray casting via trimesh RayMesh; 16/64/256 rays per quality preset; uses nvdiffrast only for UV rasterization, CPU for actual ray tests Milestone 8 — Stage 2K-2O (stage2_finalize.py): - pack_orm(): AO→R, Roughness→G, Metallic→B for UE5 - generate_lods(): LOD0/1/2 via PyMeshLab quadric at 100%/50%/25% - generate_collision(): CoACD convex decomposition (convex_hull fallback) - set_pivot(): bottom_center / geometric_center pivot correction - validate_scale(): rescale to real-world height in cm (UE5 units) app.py: wire all stages into run_post_process; only SDXL inpaint (M7) is a stub requirements.txt: add coacd==1.0.44537d39 -
Milestone 4+5: UV unwrap (xatlas), symmetry, and normal map baking (nvdiffrast)
Milestone 4 — Stage 2D-2E: - stage2_symmetry.py: bilateral-X/Y symmetry via half-mesh mirror + merge - stage2_uv.py: xatlas atlas generation with configurable texels_per_unit and padding; exports unwrapped.glb with TEXCOORD_0 Milestone 5 — Stage 2F: - stage2_bake_normal.py: full tangent-space normal map baker - Rasterizes low-poly in UV space via nvdiffrast - Interpolates per-pixel world position + TBN frame - Queries high-poly nearest-surface normals via trimesh.proximity - Transforms to tangent space, packs RGB, dilates past UV islands - Saves both GL (Y-up) and DX/UE5 (Y-down) variants - @spaces.GPU(duration=120) app.py: wire M4/M5 steps in run_post_process (removed from stubs) requirements.txt: add xatlas, scipy, nvdiffrast (PyPI version)4fab588 -
Milestone 3: Stage 2A-2C Mesh Cleanup (repair, cleanup, decimation)
- src/stages/stage2_repair.py: pymeshfix hole-filling + manifold repair - src/stages/stage2_cleanup.py: trimesh pre-pass + PyMeshLab filter chain (null faces, duplicate verts/faces, non-manifold edges/verts) - src/stages/stage2_decimate.py: fast-simplification preview + PyMeshLab quadric edge collapse final pass; preserves normals and topology - app.py: wire Post-Process tab to run_post_process dispatcher; add live decimation preview on slider change; later steps remain stubs - requirements.txt: activate trimesh[easy], pymeshfix, pymeshlab, fast-simplification5c6c726 -
Switch Stage 1 to gradio_client: all TRELLIS.2 custom wheels ABI-broken on torch 2.8+
TRELLIS.2's o_voxel, cumesh, flex_gemm wheels were compiled against torch 2.6.0. ZeroGPU no longer supports torch < 2.8.0, and no torch 2.8+ wheels exist yet. Solution: call microsoft/TRELLIS.2 via gradio_client (same approach as gradio_client docs). Stage 1 no longer needs local GPU — the remote Space handles generation and returns two GLB files (high_poly + working mesh) which we copy to workspace. Changes: - stage1_generate.py: complete rewrite using gradio_client.Client - app.py: remove entire trellis2 bootstrap block (no longer needed) - requirements.txt: remove ABI-broken custom wheels; add gradio_client0b410ef -
Fix circular import: bootstrap trellis2 at app.py top-level before src.stages import
Importing trellis2 from inside a Python subpackage (src.stages.stage1_generate) caused a false-positive circular import on trellis2/__init__.py line 1. Fix: set env vars, sys.path, and 'import trellis2' at the very top of app.py so trellis2 is fully in sys.modules before stage1_generate is imported. stage1_generate now reuses the cached module with no re-init.85d4c34 -
Milestone 2: Wire TRELLIS.2 generation + vendor both model packages
- src/stages/stage1_generate.py: real TRELLIS.2 image-to-3D generation - Module-level pipeline init (ZeroGPU requirement) - Exports high_poly.glb (no decimation, for Stage 2 baking) + raw_gen.glb - Quality presets: Fast (512/8-step), Balanced (1024-cascade/12), Hero (1536-cascade/16) - Uses pipeline's built-in BiRefNet rembg (preprocess_image=True) - Hunyuan3D-2.1 stub — wired in Milestone 2b - app.py: replace stub_generate with handle_generate dispatcher - requirements.txt: activate TRELLIS.2 deps (torch 2.6, custom wheels) - TRELLIS.2/: vendored trellis2 package + autotune_cache.json + assets - Hunyuan3D-2.1/: vendored hy3dshape + hy3dpaint packages (M2b ready) - .gitignore: exclude Hunyuan training data dirs + model weights1ae114b -
Upload __init__.py
Verified signature0fe520f -
Delete src/__init__.py
Verified signature3e62563 -
Upload 4 files
Verified signaturea54a5ca -
Create src/__init__.py
Verified signaturec8ed469