Daankular commited on
Commit
57a7d49
Β·
1 Parent(s): 85d2e0f

Fix diso undefined symbol (clone with --recurse-submodules); remove RMBG preview/controls from UI

Browse files
Files changed (1) hide show
  1. app.py +55 -25
app.py CHANGED
@@ -45,9 +45,10 @@ _NO_DEPS_PACKAGES = [
45
  ]
46
 
47
  # 3. Packages requiring nvcc (CUDA compiler only in runtime GPU containers)
 
 
48
  _CUDA_PACKAGES = [
49
  "nvdiffrast @ git+https://github.com/NVlabs/nvdiffrast.git@253ac4fcea7de5f396371124af597e6cc957bfae",
50
- "diso @ git+https://github.com/SarahWeiii/diso.git@9792ad928ccb09bdec938779651ee03e395758a6",
51
  "detectron2 @ git+https://github.com/facebookresearch/detectron2.git@8a9d885b3d4dcf1bef015f0593b872ed8d32b4ab",
52
  ]
53
 
@@ -83,6 +84,20 @@ def _install_runtime_packages():
83
  [sys.executable, "-m", "pip", "install", "--quiet", "--no-build-isolation"]
84
  + _CUDA_PACKAGES, env=_cuda_env, check=True,
85
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  _RUNTIME_PKG_MARKER.touch()
87
  print("[startup] Runtime packages installed.")
88
 
@@ -174,6 +189,35 @@ def load_triposg():
174
  if str(triposg_src) not in sys.path:
175
  sys.path.insert(0, str(triposg_src))
176
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  weights_path = snapshot_download("VAST-AI/TripoSG")
178
 
179
  from triposg.pipelines.pipeline_triposg import TripoSGPipeline
@@ -593,17 +637,16 @@ def render_views(glb_file):
593
 
594
  # ── Full pipeline ─────────────────────────────────────────────────────────────
595
 
596
- def run_full_pipeline(input_image, remove_background, num_steps, guidance, seed, face_count,
597
- variant, tex_seed, enhance_face, rembg_threshold, rembg_erode,
598
  export_fbx, mdm_prompt, mdm_n_frames, progress=gr.Progress()):
599
  progress(0.0, desc="Stage 1/3: Generating shape...")
600
- glb, status = generate_shape(input_image, remove_background, num_steps, guidance, seed, face_count)
601
  if not glb:
602
  return None, None, None, None, None, None, status
603
 
604
  progress(0.33, desc="Stage 2/3: Applying texture...")
605
- glb, mv_img, status = apply_texture(glb, input_image, remove_background, variant, tex_seed,
606
- enhance_face, rembg_threshold, rembg_erode)
607
  if not glb:
608
  return None, None, None, None, None, None, status
609
 
@@ -626,12 +669,6 @@ with gr.Blocks(title="Image2Model") as demo:
626
  with gr.Row():
627
  with gr.Column(scale=1):
628
  input_image = gr.Image(label="Input Image", type="numpy")
629
- remove_bg_check = gr.Checkbox(label="Remove Background", value=True)
630
- with gr.Row():
631
- rembg_threshold = gr.Slider(0.1, 0.95, value=0.5, step=0.05,
632
- label="BG Threshold")
633
- rembg_erode = gr.Slider(0, 8, value=2, step=1,
634
- label="Edge Erode (px)")
635
 
636
  with gr.Accordion("Shape Settings", open=True):
637
  num_steps = gr.Slider(20, 100, value=50, step=5, label="Inference Steps")
@@ -653,7 +690,6 @@ with gr.Blocks(title="Image2Model") as demo:
653
  run_all_btn = gr.Button("β–Ά Run Full Pipeline", variant="primary", interactive=False)
654
 
655
  with gr.Column(scale=1):
656
- rembg_preview = gr.Image(label="BG Removed Preview", type="numpy", interactive=False)
657
  status = gr.Textbox(label="Status", lines=3, interactive=False)
658
  model_3d = gr.Model3D(label="3D Preview", clear_color=[0.9, 0.9, 0.9, 1.0])
659
  download_file = gr.File(label="Download GLB")
@@ -661,7 +697,6 @@ with gr.Blocks(title="Image2Model") as demo:
661
 
662
  render_gallery = gr.Gallery(label="Rendered Views", columns=5, height=300)
663
 
664
- _rembg_inputs = [input_image, remove_bg_check, rembg_threshold, rembg_erode]
665
  _pipeline_btns = [shape_btn, run_all_btn]
666
 
667
  input_image.upload(
@@ -672,14 +707,10 @@ with gr.Blocks(title="Image2Model") as demo:
672
  fn=lambda: (gr.update(interactive=False), gr.update(interactive=False)),
673
  inputs=[], outputs=_pipeline_btns,
674
  )
675
- input_image.upload(fn=preview_rembg, inputs=_rembg_inputs, outputs=[rembg_preview])
676
- remove_bg_check.change(fn=preview_rembg, inputs=_rembg_inputs, outputs=[rembg_preview])
677
- rembg_threshold.release(fn=preview_rembg, inputs=_rembg_inputs, outputs=[rembg_preview])
678
- rembg_erode.release(fn=preview_rembg, inputs=_rembg_inputs, outputs=[rembg_preview])
679
 
680
  shape_btn.click(
681
- fn=generate_shape,
682
- inputs=[input_image, remove_bg_check, num_steps, guidance, seed, face_count],
683
  outputs=[glb_state, status],
684
  ).then(
685
  fn=lambda p: (p, p) if p else (None, None),
@@ -687,9 +718,8 @@ with gr.Blocks(title="Image2Model") as demo:
687
  )
688
 
689
  texture_btn.click(
690
- fn=apply_texture,
691
- inputs=[glb_state, input_image, remove_bg_check, variant, tex_seed,
692
- enhance_face_check, rembg_threshold, rembg_erode],
693
  outputs=[glb_state, multiview_img, status],
694
  ).then(
695
  fn=lambda p: (p, p) if p else (None, None),
@@ -791,8 +821,8 @@ with gr.Blocks(title="Image2Model") as demo:
791
  run_all_btn.click(
792
  fn=run_full_pipeline,
793
  inputs=[
794
- input_image, remove_bg_check, num_steps, guidance, seed, face_count,
795
- variant, tex_seed, enhance_face_check, rembg_threshold, rembg_erode,
796
  export_fbx_check, mdm_prompt_box, mdm_frames_slider,
797
  ],
798
  outputs=[glb_state, download_file, multiview_img,
 
45
  ]
46
 
47
  # 3. Packages requiring nvcc (CUDA compiler only in runtime GPU containers)
48
+ # NOTE: diso is NOT listed here β€” it's cloned with --recurse-submodules below
49
+ # because pip install git+... doesn't fetch submodules, causing undefined symbols.
50
  _CUDA_PACKAGES = [
51
  "nvdiffrast @ git+https://github.com/NVlabs/nvdiffrast.git@253ac4fcea7de5f396371124af597e6cc957bfae",
 
52
  "detectron2 @ git+https://github.com/facebookresearch/detectron2.git@8a9d885b3d4dcf1bef015f0593b872ed8d32b4ab",
53
  ]
54
 
 
84
  [sys.executable, "-m", "pip", "install", "--quiet", "--no-build-isolation"]
85
  + _CUDA_PACKAGES, env=_cuda_env, check=True,
86
  )
87
+ # diso: pip install git+... does not fetch git submodules, causing undefined
88
+ # CUDA symbols at import time. Clone with --recurse-submodules first.
89
+ _diso_src = Path("/tmp/diso-build")
90
+ if not _diso_src.exists():
91
+ subprocess.run(
92
+ ["git", "clone", "--recurse-submodules", "--depth=1",
93
+ "https://github.com/SarahWeiii/diso.git", str(_diso_src)],
94
+ env=_cuda_env, check=True,
95
+ )
96
+ subprocess.run(
97
+ [sys.executable, "-m", "pip", "install", "--quiet", "--no-build-isolation",
98
+ str(_diso_src)],
99
+ env=_cuda_env, check=True,
100
+ )
101
  _RUNTIME_PKG_MARKER.touch()
102
  print("[startup] Runtime packages installed.")
103
 
 
189
  if str(triposg_src) not in sys.path:
190
  sys.path.insert(0, str(triposg_src))
191
 
192
+ # Safety net: patch inference_utils.py to make diso import optional.
193
+ # Even if diso compiled with submodules, guard against any residual link errors.
194
+ _iu_path = triposg_src / "triposg" / "inference_utils.py"
195
+ if _iu_path.exists():
196
+ _iu_text = _iu_path.read_text()
197
+ if "DiffDMC = None" not in _iu_text and "from diso import DiffDMC" in _iu_text:
198
+ _iu_text = _iu_text.replace(
199
+ "from diso import DiffDMC",
200
+ "try:\n from diso import DiffDMC\n"
201
+ "except Exception as _diso_err:\n"
202
+ " print(f'[TripoSG] diso unavailable ({_diso_err}), using flash fallback')\n"
203
+ " DiffDMC = None",
204
+ )
205
+ if ("def hierarchical_extract_geometry(" in _iu_text
206
+ and "flash_extract_geometry" in _iu_text):
207
+ _iu_text = _iu_text.replace(
208
+ "def hierarchical_extract_geometry(",
209
+ "def _hierarchical_extract_geometry_impl(",
210
+ )
211
+ _iu_text += (
212
+ "\n\n"
213
+ "def hierarchical_extract_geometry(*args, **kwargs):\n"
214
+ " if DiffDMC is None:\n"
215
+ " return flash_extract_geometry(*args, **kwargs)\n"
216
+ " return _hierarchical_extract_geometry_impl(*args, **kwargs)\n"
217
+ )
218
+ _iu_path.write_text(_iu_text)
219
+ print("[load_triposg] Patched inference_utils.py: diso optional")
220
+
221
  weights_path = snapshot_download("VAST-AI/TripoSG")
222
 
223
  from triposg.pipelines.pipeline_triposg import TripoSGPipeline
 
637
 
638
  # ── Full pipeline ─────────────────────────────────────────────────────────────
639
 
640
+ def run_full_pipeline(input_image, num_steps, guidance, seed, face_count,
641
+ variant, tex_seed, enhance_face,
642
  export_fbx, mdm_prompt, mdm_n_frames, progress=gr.Progress()):
643
  progress(0.0, desc="Stage 1/3: Generating shape...")
644
+ glb, status = generate_shape(input_image, True, num_steps, guidance, seed, face_count)
645
  if not glb:
646
  return None, None, None, None, None, None, status
647
 
648
  progress(0.33, desc="Stage 2/3: Applying texture...")
649
+ glb, mv_img, status = apply_texture(glb, input_image, True, variant, tex_seed, enhance_face)
 
650
  if not glb:
651
  return None, None, None, None, None, None, status
652
 
 
669
  with gr.Row():
670
  with gr.Column(scale=1):
671
  input_image = gr.Image(label="Input Image", type="numpy")
 
 
 
 
 
 
672
 
673
  with gr.Accordion("Shape Settings", open=True):
674
  num_steps = gr.Slider(20, 100, value=50, step=5, label="Inference Steps")
 
690
  run_all_btn = gr.Button("β–Ά Run Full Pipeline", variant="primary", interactive=False)
691
 
692
  with gr.Column(scale=1):
 
693
  status = gr.Textbox(label="Status", lines=3, interactive=False)
694
  model_3d = gr.Model3D(label="3D Preview", clear_color=[0.9, 0.9, 0.9, 1.0])
695
  download_file = gr.File(label="Download GLB")
 
697
 
698
  render_gallery = gr.Gallery(label="Rendered Views", columns=5, height=300)
699
 
 
700
  _pipeline_btns = [shape_btn, run_all_btn]
701
 
702
  input_image.upload(
 
707
  fn=lambda: (gr.update(interactive=False), gr.update(interactive=False)),
708
  inputs=[], outputs=_pipeline_btns,
709
  )
 
 
 
 
710
 
711
  shape_btn.click(
712
+ fn=lambda img, ns, gs, sd, fc: generate_shape(img, True, ns, gs, sd, fc),
713
+ inputs=[input_image, num_steps, guidance, seed, face_count],
714
  outputs=[glb_state, status],
715
  ).then(
716
  fn=lambda p: (p, p) if p else (None, None),
 
718
  )
719
 
720
  texture_btn.click(
721
+ fn=lambda glb, img, v, ts, ef: apply_texture(glb, img, True, v, ts, ef),
722
+ inputs=[glb_state, input_image, variant, tex_seed, enhance_face_check],
 
723
  outputs=[glb_state, multiview_img, status],
724
  ).then(
725
  fn=lambda p: (p, p) if p else (None, None),
 
821
  run_all_btn.click(
822
  fn=run_full_pipeline,
823
  inputs=[
824
+ input_image, num_steps, guidance, seed, face_count,
825
+ variant, tex_seed, enhance_face_check,
826
  export_fbx_check, mdm_prompt_box, mdm_frames_slider,
827
  ],
828
  outputs=[glb_state, download_file, multiview_img,