Spaces:
Running on Zero
Running on Zero
Bobby commited on
Commit ·
b320648
1
Parent(s): e150777
Fix Gradio 4.44.1 output updates for video/model visibility
Browse files
AGENTS.md
CHANGED
|
@@ -5,12 +5,12 @@
|
|
| 5 |
- **Goal**: High-fidelity 3D asset generation from 2D images.
|
| 6 |
- **Priority**: Robust execution, VRAM efficiency, and seamless Hugging Face Space deployment.
|
| 7 |
|
| 8 |
-
## 2. Tech Stack
|
| 9 |
-
- **Core**: Python, PyTorch, CUDA.
|
| 10 |
-
- **Model Architecture**: Diffusion-based 3D generation (TRELLIS).
|
| 11 |
-
- **UI**: Gradio (`app.py`).
|
| 12 |
-
- **Deployment**: Dockerized on Hugging Face Spaces.
|
| 13 |
-
- **Models**: Loaded via Hugging Face Hub (DinoV2, RMBG2, etc.) or local cache.
|
| 14 |
|
| 15 |
## 3. Repository Structure
|
| 16 |
- `app.py`: Main Gradio web application. Handles UI, video rendering, and high-level pipeline orchestration.
|
|
|
|
| 5 |
- **Goal**: High-fidelity 3D asset generation from 2D images.
|
| 6 |
- **Priority**: Robust execution, VRAM efficiency, and seamless Hugging Face Space deployment.
|
| 7 |
|
| 8 |
+
## 2. Tech Stack
|
| 9 |
+
- **Core**: Python, PyTorch, CUDA.
|
| 10 |
+
- **Model Architecture**: Diffusion-based 3D generation (TRELLIS).
|
| 11 |
+
- **UI**: Gradio (`app.py`) pinned to **4.44.1**. Keep event/callback usage compatible with Gradio 4.44.1 APIs.
|
| 12 |
+
- **Deployment**: Dockerized on Hugging Face Spaces.
|
| 13 |
+
- **Models**: Loaded via Hugging Face Hub (DinoV2, RMBG2, etc.) or local cache.
|
| 14 |
|
| 15 |
## 3. Repository Structure
|
| 16 |
- `app.py`: Main Gradio web application. Handles UI, video rendering, and high-level pipeline orchestration.
|
app.py
CHANGED
|
@@ -147,7 +147,12 @@ def process_image_yielding(
|
|
| 147 |
for name, exr_data in envmap.items():
|
| 148 |
loaded_envmap[name] = EnvMap(torch.tensor(exr_data, dtype=torch.float32, device='cuda'))
|
| 149 |
|
| 150 |
-
yield
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 151 |
|
| 152 |
if do_preprocess:
|
| 153 |
progress(0, desc="Removing background...")
|
|
@@ -217,9 +222,15 @@ def process_image_yielding(
|
|
| 217 |
|
| 218 |
if video_path:
|
| 219 |
logger.info(f"Video rendered: {video_path}")
|
| 220 |
-
yield
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
except Exception as e:
|
| 222 |
logger.error(f"Video rendering error: {e}", exc_info=True)
|
|
|
|
| 223 |
|
| 224 |
progress(0.7, desc="Extracting GLB model...")
|
| 225 |
glb_start = time.time()
|
|
@@ -276,8 +287,14 @@ def process_image_yielding(
|
|
| 276 |
except Exception as stl_e:
|
| 277 |
logger.error(f"STL export error: {stl_e}", exc_info=True)
|
| 278 |
|
| 279 |
-
|
| 280 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 281 |
|
| 282 |
except gr.Error:
|
| 283 |
raise
|
|
@@ -334,7 +351,7 @@ with gr.Blocks(theme='Taithrah/Minimal', css=css, title="Pocket 3D AI") as demo:
|
|
| 334 |
label=" ",
|
| 335 |
height=240,
|
| 336 |
elem_classes="video-container",
|
| 337 |
-
visible=
|
| 338 |
autoplay=True,
|
| 339 |
loop=True,
|
| 340 |
show_download_button=True,
|
|
@@ -360,9 +377,9 @@ with gr.Blocks(theme='Taithrah/Minimal', css=css, title="Pocket 3D AI") as demo:
|
|
| 360 |
exposure=10.0,
|
| 361 |
height=360,
|
| 362 |
elem_classes="model-container",
|
| 363 |
-
visible=
|
| 364 |
)
|
| 365 |
-
stl_download_button = gr.DownloadButton(label="Download STL", visible=
|
| 366 |
|
| 367 |
with gr.Accordion(label="Generation Settings", open=False, visible=not prod):
|
| 368 |
seed_slider = gr.Slider(0, MAX_SEED, label="Seed", value=0, step=1)
|
|
@@ -432,26 +449,6 @@ with gr.Blocks(theme='Taithrah/Minimal', css=css, title="Pocket 3D AI") as demo:
|
|
| 432 |
scroll_to_output=True,
|
| 433 |
)
|
| 434 |
|
| 435 |
-
@gr.on(triggers=[image_prompt.change], inputs=None, outputs=[video_output, model_output, stl_download_button], show_progress="minimal")
|
| 436 |
-
def toggle_outputs_on_new_image():
|
| 437 |
-
return (
|
| 438 |
-
gr.update(visible=True, value=None),
|
| 439 |
-
gr.update(visible=False, value=None),
|
| 440 |
-
gr.update(visible=False, value=None, interactive=False)
|
| 441 |
-
)
|
| 442 |
-
|
| 443 |
-
@gr.on(triggers=[video_output.change], inputs=None, outputs=[model_output, stl_download_button])
|
| 444 |
-
def toggle_model_and_stl_visibility():
|
| 445 |
-
return (
|
| 446 |
-
gr.update(label="Interactive 3D Model", visible=True),
|
| 447 |
-
gr.update(visible=True)
|
| 448 |
-
)
|
| 449 |
-
|
| 450 |
-
@gr.on(triggers=[video_output.change], inputs=None, outputs=video_output, show_progress="hidden")
|
| 451 |
-
def toggle_label():
|
| 452 |
-
return gr.update(label="Double Tap To Play", visible=True)
|
| 453 |
-
|
| 454 |
-
|
| 455 |
if __name__ == "__main__":
|
| 456 |
if pipeline is None:
|
| 457 |
logger.critical("Pipeline failed to initialize. Exiting.")
|
|
|
|
| 147 |
for name, exr_data in envmap.items():
|
| 148 |
loaded_envmap[name] = EnvMap(torch.tensor(exr_data, dtype=torch.float32, device='cuda'))
|
| 149 |
|
| 150 |
+
yield (
|
| 151 |
+
gr.update(value=None, visible=True, label="Preview"),
|
| 152 |
+
gr.update(value=None, visible=True, label="Generating 3D Model..."),
|
| 153 |
+
gr.update(value=None, visible=True, interactive=False),
|
| 154 |
+
None,
|
| 155 |
+
)
|
| 156 |
|
| 157 |
if do_preprocess:
|
| 158 |
progress(0, desc="Removing background...")
|
|
|
|
| 222 |
|
| 223 |
if video_path:
|
| 224 |
logger.info(f"Video rendered: {video_path}")
|
| 225 |
+
yield (
|
| 226 |
+
gr.update(value=video_path, visible=True, label="Double Tap To Play"),
|
| 227 |
+
gr.update(value=None, visible=True, label="Generating 3D Model..."),
|
| 228 |
+
gr.update(value=None, visible=True, interactive=False),
|
| 229 |
+
None,
|
| 230 |
+
)
|
| 231 |
except Exception as e:
|
| 232 |
logger.error(f"Video rendering error: {e}", exc_info=True)
|
| 233 |
+
logger.warning("Preview video generation failed; continuing with GLB/STL outputs.")
|
| 234 |
|
| 235 |
progress(0.7, desc="Extracting GLB model...")
|
| 236 |
glb_start = time.time()
|
|
|
|
| 287 |
except Exception as stl_e:
|
| 288 |
logger.error(f"STL export error: {stl_e}", exc_info=True)
|
| 289 |
|
| 290 |
+
video_update = gr.update(
|
| 291 |
+
value=video_path,
|
| 292 |
+
visible=True,
|
| 293 |
+
label="Double Tap To Play" if video_path else "Preview unavailable",
|
| 294 |
+
)
|
| 295 |
+
model_update = gr.update(value=glb_path, visible=True, label="Interactive 3D Model")
|
| 296 |
+
stl_update = gr.update(value=stl_path, visible=True, interactive=bool(stl_path))
|
| 297 |
+
yield video_update, model_update, stl_update, None
|
| 298 |
|
| 299 |
except gr.Error:
|
| 300 |
raise
|
|
|
|
| 351 |
label=" ",
|
| 352 |
height=240,
|
| 353 |
elem_classes="video-container",
|
| 354 |
+
visible=True,
|
| 355 |
autoplay=True,
|
| 356 |
loop=True,
|
| 357 |
show_download_button=True,
|
|
|
|
| 377 |
exposure=10.0,
|
| 378 |
height=360,
|
| 379 |
elem_classes="model-container",
|
| 380 |
+
visible=True,
|
| 381 |
)
|
| 382 |
+
stl_download_button = gr.DownloadButton(label="Download STL", visible=True, interactive=False, size="lg", variant="primary")
|
| 383 |
|
| 384 |
with gr.Accordion(label="Generation Settings", open=False, visible=not prod):
|
| 385 |
seed_slider = gr.Slider(0, MAX_SEED, label="Seed", value=0, step=1)
|
|
|
|
| 449 |
scroll_to_output=True,
|
| 450 |
)
|
| 451 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 452 |
if __name__ == "__main__":
|
| 453 |
if pipeline is None:
|
| 454 |
logger.critical("Pipeline failed to initialize. Exiting.")
|