yonnel commited on
Commit
31cb973
·
1 Parent(s): 50be971

Real manifest-driven gallery + API temp-dir bugfix (#2)

Browse files

- Real manifest-driven gallery + API temp-dir bugfix (ff51da1dbb77510ce6ffd9c1a975d3275276f5c7)

.gitattributes CHANGED
@@ -1,99 +1,102 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
36
- assets/example_image/T.png filter=lfs diff=lfs merge=lfs -text
37
- assets/example_image/typical_building_building.png filter=lfs diff=lfs merge=lfs -text
38
- assets/example_image/typical_building_castle.png filter=lfs diff=lfs merge=lfs -text
39
- assets/example_image/typical_building_colorful_cottage.png filter=lfs diff=lfs merge=lfs -text
40
- assets/example_image/typical_building_maya_pyramid.png filter=lfs diff=lfs merge=lfs -text
41
- assets/example_image/typical_building_mushroom.png filter=lfs diff=lfs merge=lfs -text
42
- assets/example_image/typical_building_space_station.png filter=lfs diff=lfs merge=lfs -text
43
- assets/example_image/typical_creature_dragon.png filter=lfs diff=lfs merge=lfs -text
44
- assets/example_image/typical_creature_elephant.png filter=lfs diff=lfs merge=lfs -text
45
- assets/example_image/typical_creature_furry.png filter=lfs diff=lfs merge=lfs -text
46
- assets/example_image/typical_creature_quadruped.png filter=lfs diff=lfs merge=lfs -text
47
- assets/example_image/typical_creature_robot_crab.png filter=lfs diff=lfs merge=lfs -text
48
- assets/example_image/typical_creature_robot_dinosour.png filter=lfs diff=lfs merge=lfs -text
49
- assets/example_image/typical_creature_rock_monster.png filter=lfs diff=lfs merge=lfs -text
50
- assets/example_image/typical_humanoid_block_robot.png filter=lfs diff=lfs merge=lfs -text
51
- assets/example_image/typical_humanoid_dragonborn.png filter=lfs diff=lfs merge=lfs -text
52
- assets/example_image/typical_humanoid_dwarf.png filter=lfs diff=lfs merge=lfs -text
53
- assets/example_image/typical_humanoid_goblin.png filter=lfs diff=lfs merge=lfs -text
54
- assets/example_image/typical_humanoid_mech.png filter=lfs diff=lfs merge=lfs -text
55
- assets/example_image/typical_misc_crate.png filter=lfs diff=lfs merge=lfs -text
56
- assets/example_image/typical_misc_fireplace.png filter=lfs diff=lfs merge=lfs -text
57
- assets/example_image/typical_misc_gate.png filter=lfs diff=lfs merge=lfs -text
58
- assets/example_image/typical_misc_lantern.png filter=lfs diff=lfs merge=lfs -text
59
- assets/example_image/typical_misc_magicbook.png filter=lfs diff=lfs merge=lfs -text
60
- assets/example_image/typical_misc_mailbox.png filter=lfs diff=lfs merge=lfs -text
61
- assets/example_image/typical_misc_monster_chest.png filter=lfs diff=lfs merge=lfs -text
62
- assets/example_image/typical_misc_paper_machine.png filter=lfs diff=lfs merge=lfs -text
63
- assets/example_image/typical_misc_phonograph.png filter=lfs diff=lfs merge=lfs -text
64
- assets/example_image/typical_misc_portal2.png filter=lfs diff=lfs merge=lfs -text
65
- assets/example_image/typical_misc_storage_chest.png filter=lfs diff=lfs merge=lfs -text
66
- assets/example_image/typical_misc_telephone.png filter=lfs diff=lfs merge=lfs -text
67
- assets/example_image/typical_misc_television.png filter=lfs diff=lfs merge=lfs -text
68
- assets/example_image/typical_misc_workbench.png filter=lfs diff=lfs merge=lfs -text
69
- assets/example_image/typical_vehicle_biplane.png filter=lfs diff=lfs merge=lfs -text
70
- assets/example_image/typical_vehicle_bulldozer.png filter=lfs diff=lfs merge=lfs -text
71
- assets/example_image/typical_vehicle_cart.png filter=lfs diff=lfs merge=lfs -text
72
- assets/example_image/typical_vehicle_excavator.png filter=lfs diff=lfs merge=lfs -text
73
- assets/example_image/typical_vehicle_helicopter.png filter=lfs diff=lfs merge=lfs -text
74
- assets/example_image/typical_vehicle_locomotive.png filter=lfs diff=lfs merge=lfs -text
75
- assets/example_image/typical_vehicle_pirate_ship.png filter=lfs diff=lfs merge=lfs -text
76
- assets/example_image/weatherworn_misc_paper_machine3.png filter=lfs diff=lfs merge=lfs -text
77
- assets/example_multi_image/character_1.png filter=lfs diff=lfs merge=lfs -text
78
- assets/example_multi_image/character_2.png filter=lfs diff=lfs merge=lfs -text
79
- assets/example_multi_image/character_3.png filter=lfs diff=lfs merge=lfs -text
80
- assets/example_multi_image/mushroom_1.png filter=lfs diff=lfs merge=lfs -text
81
- assets/example_multi_image/mushroom_2.png filter=lfs diff=lfs merge=lfs -text
82
- assets/example_multi_image/mushroom_3.png filter=lfs diff=lfs merge=lfs -text
83
- assets/example_multi_image/orangeguy_1.png filter=lfs diff=lfs merge=lfs -text
84
- assets/example_multi_image/orangeguy_2.png filter=lfs diff=lfs merge=lfs -text
85
- assets/example_multi_image/orangeguy_3.png filter=lfs diff=lfs merge=lfs -text
86
- assets/example_multi_image/popmart_1.png filter=lfs diff=lfs merge=lfs -text
87
- assets/example_multi_image/popmart_2.png filter=lfs diff=lfs merge=lfs -text
88
- assets/example_multi_image/popmart_3.png filter=lfs diff=lfs merge=lfs -text
89
- assets/example_multi_image/rabbit_1.png filter=lfs diff=lfs merge=lfs -text
90
- assets/example_multi_image/rabbit_2.png filter=lfs diff=lfs merge=lfs -text
91
- assets/example_multi_image/rabbit_3.png filter=lfs diff=lfs merge=lfs -text
92
- assets/example_multi_image/tiger_1.png filter=lfs diff=lfs merge=lfs -text
93
- assets/example_multi_image/tiger_2.png filter=lfs diff=lfs merge=lfs -text
94
- assets/example_multi_image/tiger_3.png filter=lfs diff=lfs merge=lfs -text
95
- assets/example_multi_image/yoimiya_1.png filter=lfs diff=lfs merge=lfs -text
96
- assets/example_multi_image/yoimiya_2.png filter=lfs diff=lfs merge=lfs -text
97
- assets/example_multi_image/yoimiya_3.png filter=lfs diff=lfs merge=lfs -text
98
- wheels/diff_gaussian_rasterization-0.0.0-cp310-cp310-linux_x86_64.whl filter=lfs diff=lfs merge=lfs -text
99
- wheels/nvdiffrast-0.3.3-cp310-cp310-linux_x86_64.whl filter=lfs diff=lfs merge=lfs -text
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ assets/example_image/T.png filter=lfs diff=lfs merge=lfs -text
37
+ assets/example_image/typical_building_building.png filter=lfs diff=lfs merge=lfs -text
38
+ assets/example_image/typical_building_castle.png filter=lfs diff=lfs merge=lfs -text
39
+ assets/example_image/typical_building_colorful_cottage.png filter=lfs diff=lfs merge=lfs -text
40
+ assets/example_image/typical_building_maya_pyramid.png filter=lfs diff=lfs merge=lfs -text
41
+ assets/example_image/typical_building_mushroom.png filter=lfs diff=lfs merge=lfs -text
42
+ assets/example_image/typical_building_space_station.png filter=lfs diff=lfs merge=lfs -text
43
+ assets/example_image/typical_creature_dragon.png filter=lfs diff=lfs merge=lfs -text
44
+ assets/example_image/typical_creature_elephant.png filter=lfs diff=lfs merge=lfs -text
45
+ assets/example_image/typical_creature_furry.png filter=lfs diff=lfs merge=lfs -text
46
+ assets/example_image/typical_creature_quadruped.png filter=lfs diff=lfs merge=lfs -text
47
+ assets/example_image/typical_creature_robot_crab.png filter=lfs diff=lfs merge=lfs -text
48
+ assets/example_image/typical_creature_robot_dinosour.png filter=lfs diff=lfs merge=lfs -text
49
+ assets/example_image/typical_creature_rock_monster.png filter=lfs diff=lfs merge=lfs -text
50
+ assets/example_image/typical_humanoid_block_robot.png filter=lfs diff=lfs merge=lfs -text
51
+ assets/example_image/typical_humanoid_dragonborn.png filter=lfs diff=lfs merge=lfs -text
52
+ assets/example_image/typical_humanoid_dwarf.png filter=lfs diff=lfs merge=lfs -text
53
+ assets/example_image/typical_humanoid_goblin.png filter=lfs diff=lfs merge=lfs -text
54
+ assets/example_image/typical_humanoid_mech.png filter=lfs diff=lfs merge=lfs -text
55
+ assets/example_image/typical_misc_crate.png filter=lfs diff=lfs merge=lfs -text
56
+ assets/example_image/typical_misc_fireplace.png filter=lfs diff=lfs merge=lfs -text
57
+ assets/example_image/typical_misc_gate.png filter=lfs diff=lfs merge=lfs -text
58
+ assets/example_image/typical_misc_lantern.png filter=lfs diff=lfs merge=lfs -text
59
+ assets/example_image/typical_misc_magicbook.png filter=lfs diff=lfs merge=lfs -text
60
+ assets/example_image/typical_misc_mailbox.png filter=lfs diff=lfs merge=lfs -text
61
+ assets/example_image/typical_misc_monster_chest.png filter=lfs diff=lfs merge=lfs -text
62
+ assets/example_image/typical_misc_paper_machine.png filter=lfs diff=lfs merge=lfs -text
63
+ assets/example_image/typical_misc_phonograph.png filter=lfs diff=lfs merge=lfs -text
64
+ assets/example_image/typical_misc_portal2.png filter=lfs diff=lfs merge=lfs -text
65
+ assets/example_image/typical_misc_storage_chest.png filter=lfs diff=lfs merge=lfs -text
66
+ assets/example_image/typical_misc_telephone.png filter=lfs diff=lfs merge=lfs -text
67
+ assets/example_image/typical_misc_television.png filter=lfs diff=lfs merge=lfs -text
68
+ assets/example_image/typical_misc_workbench.png filter=lfs diff=lfs merge=lfs -text
69
+ assets/example_image/typical_vehicle_biplane.png filter=lfs diff=lfs merge=lfs -text
70
+ assets/example_image/typical_vehicle_bulldozer.png filter=lfs diff=lfs merge=lfs -text
71
+ assets/example_image/typical_vehicle_cart.png filter=lfs diff=lfs merge=lfs -text
72
+ assets/example_image/typical_vehicle_excavator.png filter=lfs diff=lfs merge=lfs -text
73
+ assets/example_image/typical_vehicle_helicopter.png filter=lfs diff=lfs merge=lfs -text
74
+ assets/example_image/typical_vehicle_locomotive.png filter=lfs diff=lfs merge=lfs -text
75
+ assets/example_image/typical_vehicle_pirate_ship.png filter=lfs diff=lfs merge=lfs -text
76
+ assets/example_image/weatherworn_misc_paper_machine3.png filter=lfs diff=lfs merge=lfs -text
77
+ assets/example_multi_image/character_1.png filter=lfs diff=lfs merge=lfs -text
78
+ assets/example_multi_image/character_2.png filter=lfs diff=lfs merge=lfs -text
79
+ assets/example_multi_image/character_3.png filter=lfs diff=lfs merge=lfs -text
80
+ assets/example_multi_image/mushroom_1.png filter=lfs diff=lfs merge=lfs -text
81
+ assets/example_multi_image/mushroom_2.png filter=lfs diff=lfs merge=lfs -text
82
+ assets/example_multi_image/mushroom_3.png filter=lfs diff=lfs merge=lfs -text
83
+ assets/example_multi_image/orangeguy_1.png filter=lfs diff=lfs merge=lfs -text
84
+ assets/example_multi_image/orangeguy_2.png filter=lfs diff=lfs merge=lfs -text
85
+ assets/example_multi_image/orangeguy_3.png filter=lfs diff=lfs merge=lfs -text
86
+ assets/example_multi_image/popmart_1.png filter=lfs diff=lfs merge=lfs -text
87
+ assets/example_multi_image/popmart_2.png filter=lfs diff=lfs merge=lfs -text
88
+ assets/example_multi_image/popmart_3.png filter=lfs diff=lfs merge=lfs -text
89
+ assets/example_multi_image/rabbit_1.png filter=lfs diff=lfs merge=lfs -text
90
+ assets/example_multi_image/rabbit_2.png filter=lfs diff=lfs merge=lfs -text
91
+ assets/example_multi_image/rabbit_3.png filter=lfs diff=lfs merge=lfs -text
92
+ assets/example_multi_image/tiger_1.png filter=lfs diff=lfs merge=lfs -text
93
+ assets/example_multi_image/tiger_2.png filter=lfs diff=lfs merge=lfs -text
94
+ assets/example_multi_image/tiger_3.png filter=lfs diff=lfs merge=lfs -text
95
+ assets/example_multi_image/yoimiya_1.png filter=lfs diff=lfs merge=lfs -text
96
+ assets/example_multi_image/yoimiya_2.png filter=lfs diff=lfs merge=lfs -text
97
+ assets/example_multi_image/yoimiya_3.png filter=lfs diff=lfs merge=lfs -text
98
+ wheels/diff_gaussian_rasterization-0.0.0-cp310-cp310-linux_x86_64.whl filter=lfs diff=lfs merge=lfs -text
99
+ wheels/nvdiffrast-0.3.3-cp310-cp310-linux_x86_64.whl filter=lfs diff=lfs merge=lfs -text
100
+ assets/gallery/**/*.png filter=lfs diff=lfs merge=lfs -text
101
+ assets/gallery/**/*.mp4 filter=lfs diff=lfs merge=lfs -text
102
+ assets/gallery/**/*.glb filter=lfs diff=lfs merge=lfs -text
app.py CHANGED
@@ -230,10 +230,18 @@ def split_reasoning(text: str) -> Tuple[str, str]:
230
  # Strip any stray opener (e.g. the model omitted the closing tag).
231
  prompt = prompt.replace("<think>", "").strip()
232
 
233
- # Strip a leading header line such as "**Prompt for FLUX.1-dev:**".
234
- lines = prompt.split("\n")
235
- if lines and lines[0].lstrip().startswith("**") and lines[0].rstrip().endswith("**"):
236
- prompt = "\n".join(lines[1:]).strip()
 
 
 
 
 
 
 
 
237
 
238
  # Remove wrapping quotation marks.
239
  if len(prompt) >= 2 and prompt[0] in "\"'" and prompt[-1] == prompt[0]:
@@ -358,28 +366,34 @@ css="""
358
  }
359
  """
360
 
361
- # Curated subset of the bundled TRELLIS example renders, used as an instant
362
- # gallery so visitors see results even while the ZeroGPU Space is cold.
363
- GALLERY_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'assets', 'example_image')
364
- GALLERY_ITEMS = [
365
- ("typical_misc_lantern.png", "Lantern"),
366
- ("typical_misc_telephone.png", "Telephone"),
367
- ("typical_vehicle_biplane.png", "Biplane"),
368
- ("typical_creature_dragon.png", "Dragon"),
369
- ("typical_building_castle.png", "Castle"),
370
- ("typical_misc_phonograph.png", "Phonograph"),
371
- ("typical_misc_magicbook.png", "Magic book"),
372
- ("typical_vehicle_pirate_ship.png", "Pirate ship"),
373
- ]
374
 
375
 
376
  def load_gallery():
377
- items = []
378
- for filename, caption in GALLERY_ITEMS:
379
- path = os.path.join(GALLERY_DIR, filename)
380
- if os.path.exists(path):
381
- items.append((path, caption))
382
- return items
 
 
 
 
 
 
 
 
 
 
 
 
383
 
384
  def pack_state(gs: Gaussian, mesh: MeshExtractResult) -> dict:
385
  return {
@@ -458,6 +472,9 @@ def image_to_3d(
458
  )
459
  # temp_dir = os.path.join(TMP_DIR, "temp_output")
460
  temp_dir = os.path.join(TMP_DIR, str(req.session_hash))
 
 
 
461
 
462
  video = render_utils.render_video(outputs['gaussian'][0], num_frames=120)['color']
463
  video_geo = render_utils.render_video(outputs['mesh'][0], num_frames=120)['normal']
@@ -672,16 +689,39 @@ def create_interface():
672
  # ------------------------------------------------------- Gallery
673
  with gr.Tab("Galerie"):
674
  gr.Markdown(
675
- "Quelques objets déjà passés par le pipeline. Résultats "
676
- "instantanés, même quand le GPU est endormi."
677
- )
678
- gr.Gallery(
679
- value=load_gallery(),
680
- label="Exemples",
681
- columns=4,
682
- height="auto",
683
- object_fit="contain",
684
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
685
 
686
  # --------------------------------------------------- How it works
687
  with gr.Tab("Comment ça marche"):
 
230
  # Strip any stray opener (e.g. the model omitted the closing tag).
231
  prompt = prompt.replace("<think>", "").strip()
232
 
233
+ # Strip a leading bold header, whether on its own line ("**Prompt for
234
+ # FLUX:**\n...") or inline ("**Prompt:** actual text"). Only strip when the
235
+ # bold segment looks like a header (mentions "prompt") to avoid removing a
236
+ # legitimate bold opening word.
237
+ stripped = prompt.lstrip()
238
+ if stripped.startswith("**"):
239
+ end = stripped.find("**", 2)
240
+ if end != -1 and "prompt" in stripped[2:end].lower():
241
+ rest = stripped[end + 2:].lstrip()
242
+ if rest.startswith(":"):
243
+ rest = rest[1:]
244
+ prompt = rest.strip()
245
 
246
  # Remove wrapping quotation marks.
247
  if len(prompt) >= 2 and prompt[0] in "\"'" and prompt[-1] == prompt[0]:
 
366
  }
367
  """
368
 
369
+ # Real gallery results produced by running the pipeline on the Space, captured
370
+ # by scripts/generate_gallery.py into assets/gallery/ + manifest.json. Each
371
+ # manifest entry is {prompt, refined_prompt, image, video, glb} with repo-relative
372
+ # asset paths.
373
+ APP_DIR = os.path.dirname(os.path.abspath(__file__))
374
+ GALLERY_DIR = os.path.join(APP_DIR, 'assets', 'gallery')
375
+ GALLERY_MANIFEST = os.path.join(GALLERY_DIR, 'manifest.json')
 
 
 
 
 
 
376
 
377
 
378
  def load_gallery():
379
+ if not os.path.exists(GALLERY_MANIFEST):
380
+ return []
381
+ import json
382
+ try:
383
+ with open(GALLERY_MANIFEST, encoding='utf-8') as f:
384
+ items = json.load(f)
385
+ except Exception as e:
386
+ print(f"Error loading gallery manifest: {e}")
387
+ return []
388
+ resolved = []
389
+ for it in items:
390
+ entry = dict(it)
391
+ for key in ('image', 'video', 'glb'):
392
+ if it.get(key):
393
+ abs_path = os.path.join(APP_DIR, it[key])
394
+ entry[key] = abs_path if os.path.exists(abs_path) else None
395
+ resolved.append(entry)
396
+ return resolved
397
 
398
  def pack_state(gs: Gaussian, mesh: MeshExtractResult) -> dict:
399
  return {
 
472
  )
473
  # temp_dir = os.path.join(TMP_DIR, "temp_output")
474
  temp_dir = os.path.join(TMP_DIR, str(req.session_hash))
475
+ # The browser `load` event normally creates this via start_session, but
476
+ # API callers (e.g. gradio_client) never trigger it, so ensure it exists.
477
+ os.makedirs(temp_dir, exist_ok=True)
478
 
479
  video = render_utils.render_video(outputs['gaussian'][0], num_frames=120)['color']
480
  video_geo = render_utils.render_video(outputs['mesh'][0], num_frames=120)['normal']
 
689
  # ------------------------------------------------------- Gallery
690
  with gr.Tab("Galerie"):
691
  gr.Markdown(
692
+ "De **vrais résultats** produits par le pipeline complet "
693
+ "(prompt → image → 3D). Affichage instantané, même quand le "
694
+ "GPU est endormi."
 
 
 
 
 
 
695
  )
696
+ gallery_items = load_gallery()
697
+ if not gallery_items:
698
+ gr.Markdown(
699
+ "_Galerie en cours de génération — lancez "
700
+ "`python scripts/generate_gallery.py` puis committez "
701
+ "`assets/gallery/`._"
702
+ )
703
+ for item in gallery_items:
704
+ with gr.Group(elem_classes="step-card"):
705
+ gr.Markdown(f"**Prompt :** {item.get('prompt', '')}")
706
+ with gr.Row():
707
+ if item.get("image"):
708
+ gr.Image(
709
+ value=item["image"], label="Image (FLUX)",
710
+ height=260, interactive=False,
711
+ )
712
+ if item.get("video"):
713
+ gr.Video(
714
+ value=item["video"], label="Aperçu (TRELLIS)",
715
+ autoplay=True, loop=True, height=260,
716
+ )
717
+ if item.get("glb"):
718
+ gr.Model3D(
719
+ value=item["glb"],
720
+ label="Modèle 3D interactif", height=260,
721
+ )
722
+ if item.get("refined_prompt"):
723
+ with gr.Accordion("Prompt détaillé (DeepSeek-R1)", open=False):
724
+ gr.Markdown(item["refined_prompt"])
725
 
726
  # --------------------------------------------------- How it works
727
  with gr.Tab("Comment ça marche"):
assets/gallery/a_backpack_for_kids_flower_style/glb.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aeaf154b7758697debd18c8b08b0a1925e96ca51d014cc870981950a0129d3b9
3
+ size 1734604
assets/gallery/a_backpack_for_kids_flower_style/image.png ADDED

Git LFS Details

  • SHA256: 3962eae937c64a86ceaaef5af20efca6b282c77fb6e8f871efef580011aee63f
  • Pointer size: 131 Bytes
  • Size of remote file: 248 kB
assets/gallery/a_backpack_for_kids_flower_style/video.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2b5931fbbad8f0adb7825a825a4d1a29b9d1476c6229c5ca86370a5af21c1f93
3
+ size 466901
assets/gallery/cat_shaped_cake_mold/glb.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f474d877306124acc49fd1fb8600021a052440df6dd57b3b33c4178277330220
3
+ size 1187612
assets/gallery/cat_shaped_cake_mold/image.png ADDED

Git LFS Details

  • SHA256: 2e5d906f09b07c5f08efef554a0d802a4b01d3b5a83041806fc60546cc46fe17
  • Pointer size: 131 Bytes
  • Size of remote file: 182 kB
assets/gallery/cat_shaped_cake_mold/video.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6e2635aa5449891f2d44d0e9a3661b528b417904b4ca767da91c45d9a6f35d92
3
+ size 189857
assets/gallery/manifest.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "prompt": "a backpack for kids, flower style",
4
+ "refined_prompt": "A futuristic, flower-themed kids' backpack designed for school. The backpack features a vibrant, photorealistic floral pattern with detailed petal and blooming flower motifs. It has a sleek, kid-friendly design with a front zipper compartment and a small side pocket. The backpack is made from durable, water-resistant material with padded straps for comfort. The color scheme is bright and inviting, with a mix of pink, purple, and yellow flowers. A small flower emblem is placed on the front as the logo. The image is rendered in high quality with a white background, ensuring the backpack is the main focus. The composition is clean and focused, showcasing the backpack's playful and functional design.",
5
+ "image": "assets/gallery/a_backpack_for_kids_flower_style/image.png",
6
+ "video": "assets/gallery/a_backpack_for_kids_flower_style/video.mp4",
7
+ "glb": "assets/gallery/a_backpack_for_kids_flower_style/glb.glb"
8
+ },
9
+ {
10
+ "prompt": "medieval flip flops",
11
+ "refined_prompt": "Design a photorealistic image of a pair of medieval-style flip flops, featuring intricate medieval designs. The flip flops have a strap adorned with knotwork and heraldic motifs, including a crown and a sword. The buckle is an elaborate clasp resembling medieval armor. The soles are made of a durable, slightly textured material resembling leather, with etched patterns matching the strap. The flip flops are rendered in rich colors—deep reds, greens, and golds—with sharp focus and medium focal length. The background is entirely white to highlight the design.",
12
+ "image": "assets/gallery/medieval_flip_flops/image.png",
13
+ "video": "assets/gallery/medieval_flip_flops/video.mp4",
14
+ "glb": "assets/gallery/medieval_flip_flops/glb.glb"
15
+ },
16
+ {
17
+ "prompt": "cat shaped cake mold",
18
+ "refined_prompt": "Design a cat-shaped cake mold that seamlessly integrates functionality with an appealing aesthetic. The mold should feature a realistically shaped cat form, with visible details like ears, a head, and a body that smoothly transitions for easy cake pouring. The mold should be made from high-quality, food-safe materials with a non-stick coating to ensure easy removal of baked goods. The design should be rendered in a photorealistic style with a clean, white background, showcasing the cat's form in sharp detail. The texture of the mold should be subtly realistic, with a slightly glossy finish. The focal length should be wide to capture the entire cat shape clearly, and the grain should be fine to ensure high-quality imaging.",
19
+ "image": "assets/gallery/cat_shaped_cake_mold/image.png",
20
+ "video": "assets/gallery/cat_shaped_cake_mold/video.mp4",
21
+ "glb": "assets/gallery/cat_shaped_cake_mold/glb.glb"
22
+ }
23
+ ]
assets/gallery/medieval_flip_flops/glb.glb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c12e085b85b04a80f9f5aa3c0f85bf720be10314192f995a668640a17be44059
3
+ size 1554828
assets/gallery/medieval_flip_flops/image.png ADDED

Git LFS Details

  • SHA256: fbc1ec16f7f6355456b4e685336d2de9466c28ce429df1ea4bed58213ba3f067
  • Pointer size: 131 Bytes
  • Size of remote file: 324 kB
assets/gallery/medieval_flip_flops/video.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4dd4aadc0c36a6ce3dec9d9ee889f61b8fb52487320e5c8442c56151e920ace0
3
+ size 293568
scripts/generate_gallery.py ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Generate real gallery assets by driving the live Hugging Face Space.
2
+
3
+ The whole pipeline (DeepSeek-R1 -> FLUX -> TRELLIS) runs on the Space's ZeroGPU;
4
+ this script just orchestrates the calls over the gradio_client API and saves the
5
+ produced image / video / GLB locally, then writes a manifest the app reads.
6
+
7
+ Usage:
8
+ python scripts/generate_gallery.py --smoke # one prompt, prints shapes
9
+ python scripts/generate_gallery.py # full list
10
+
11
+ Auth: uses the locally cached HF token (huggingface-cli login).
12
+ """
13
+ import argparse
14
+ import json
15
+ import os
16
+ import re
17
+ import shutil
18
+
19
+ from gradio_client import Client, handle_file
20
+ from huggingface_hub import get_token
21
+
22
+ SPACE_ID = "yonnel/text-to-3d_flux_trellis"
23
+ ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
24
+ GALLERY_DIR = os.path.join(ROOT, "assets", "gallery")
25
+
26
+ PROMPTS = [
27
+ "a backpack for kids, flower style",
28
+ "medieval flip flops",
29
+ "cat shaped cake mold",
30
+ ]
31
+
32
+
33
+ def slugify(text: str) -> str:
34
+ return re.sub(r"[^a-z0-9]+", "_", text.lower()).strip("_")[:40]
35
+
36
+
37
+ def as_path(x):
38
+ """Extract a local filepath from a gradio_client result item."""
39
+ if x is None:
40
+ return None
41
+ if isinstance(x, str):
42
+ return x
43
+ if isinstance(x, dict):
44
+ if "video" in x:
45
+ v = x["video"]
46
+ return v if isinstance(v, str) else (v.get("path") or v.get("url"))
47
+ return x.get("path") or x.get("url")
48
+ if isinstance(x, (list, tuple)) and x:
49
+ return as_path(x[0])
50
+ return None
51
+
52
+
53
+ def generate_one(client: Client, prompt: str, verbose: bool = True) -> dict:
54
+ # Step 1 - DeepSeek-R1: prompt refinement
55
+ r1 = client.predict(prompt, api_name="/refine_prompt")
56
+ reasoning, clean_prompt, status1 = r1
57
+ if verbose:
58
+ print(f" [1] status: {status1!r}")
59
+ print(f" [1] clean_prompt: {clean_prompt[:160]!r}")
60
+ if not clean_prompt:
61
+ raise RuntimeError(f"empty refined prompt (status: {status1})")
62
+
63
+ # Step 2 - FLUX: image (fixed seed so the gallery is reproducible)
64
+ r2 = client.predict(
65
+ clean_prompt, 42, False, 512, 512, 6, api_name="/generate_image"
66
+ )
67
+ image_path = as_path(r2[0])
68
+ if verbose:
69
+ print(f" [2] image: {image_path}")
70
+ if not image_path or not os.path.exists(image_path):
71
+ raise RuntimeError(f"no image produced (status: {r2[-1]})")
72
+
73
+ # Step 3 - TRELLIS: video + GLB
74
+ r3 = client.predict(
75
+ handle_file(image_path), 0, 7.5, 12, 3.0, 12, api_name="/image_to_3d"
76
+ )
77
+ video_path = as_path(r3[0])
78
+ glb_path = as_path(r3[1]) or as_path(r3[3])
79
+ if verbose:
80
+ print(f" [3] video: {video_path}")
81
+ print(f" [3] glb: {glb_path}")
82
+
83
+ return {
84
+ "prompt": prompt,
85
+ "refined_prompt": clean_prompt,
86
+ "reasoning": reasoning,
87
+ "_image": image_path,
88
+ "_video": video_path,
89
+ "_glb": glb_path,
90
+ }
91
+
92
+
93
+ def main():
94
+ ap = argparse.ArgumentParser()
95
+ ap.add_argument("--smoke", action="store_true", help="only the first prompt")
96
+ args = ap.parse_args()
97
+
98
+ prompts = PROMPTS[:1] if args.smoke else PROMPTS
99
+ os.makedirs(GALLERY_DIR, exist_ok=True)
100
+
101
+ print(f"Connecting to {SPACE_ID} ...")
102
+ client = Client(SPACE_ID, token=get_token(), verbose=False)
103
+ # The per-session temp dir is created by the Space's `load` handler, which
104
+ # never fires over the API -> call it explicitly so image_to_3d can write.
105
+ client.predict(api_name="/start_session")
106
+
107
+ manifest = []
108
+ for i, prompt in enumerate(prompts, 1):
109
+ print(f"[{i}/{len(prompts)}] {prompt}")
110
+ try:
111
+ res = generate_one(client, prompt)
112
+ except Exception as e:
113
+ print(f" !! failed: {e}")
114
+ continue
115
+
116
+ slug = slugify(prompt)
117
+ item_dir = os.path.join(GALLERY_DIR, slug)
118
+ os.makedirs(item_dir, exist_ok=True)
119
+ entry = {"prompt": prompt, "refined_prompt": res["refined_prompt"]}
120
+ for kind, key, ext in [
121
+ ("image", "_image", ".png"),
122
+ ("video", "_video", ".mp4"),
123
+ ("glb", "_glb", ".glb"),
124
+ ]:
125
+ src = res[key]
126
+ if src and os.path.exists(src):
127
+ dst = os.path.join(item_dir, kind + ext)
128
+ shutil.copyfile(src, dst)
129
+ entry[kind] = os.path.relpath(dst, ROOT).replace("\\", "/")
130
+ manifest.append(entry)
131
+ print(f" -> saved to {item_dir}")
132
+
133
+ if args.smoke:
134
+ print("\nSMOKE RESULT:\n" + json.dumps(manifest, indent=2, ensure_ascii=False))
135
+ return
136
+
137
+ manifest_path = os.path.join(GALLERY_DIR, "manifest.json")
138
+ with open(manifest_path, "w", encoding="utf-8") as f:
139
+ json.dump(manifest, f, indent=2, ensure_ascii=False)
140
+ print(f"\nWrote {manifest_path} ({len(manifest)} items)")
141
+
142
+
143
+ if __name__ == "__main__":
144
+ main()