sarahyung commited on
Commit
96d9839
·
verified ·
1 Parent(s): 4c94f09

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -63
app.py CHANGED
@@ -1,20 +1,15 @@
1
  """
2
- AI 3D Generation Pipeline Hugging Face Space (TripoSG + rembg)
3
  """
4
- from __future__ import annotations
5
  import os
6
- import re
7
  import sys
8
- import json
9
  import uuid
10
  import time
11
- import shutil
12
- import base64
13
  import logging
14
  import tempfile
15
- import zipfile
16
  from pathlib import Path
17
  from typing import List
 
18
  import gradio as gr
19
  import numpy as np
20
  import torch
@@ -22,7 +17,7 @@ from PIL import Image
22
  import trimesh
23
  from rembg import remove
24
 
25
- # HuggingFace ZeroGPU
26
  try:
27
  import spaces
28
  except ImportError:
@@ -33,31 +28,25 @@ except ImportError:
33
  return lambda f: f
34
  return fn
35
 
36
- # ---------------------------------------------------------------------------
37
- # Configuration
38
- # ---------------------------------------------------------------------------
 
39
  MODEL_ID = "VAST-AI/TripoSG"
40
  TRIPOSG_REPO_URL = "https://github.com/VAST-AI-Research/TripoSG.git"
41
- TRIPOSG_CODE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "triposg_repo")
42
- MAX_FACES = 90000
43
- DEFAULT_FACES = 50000
44
  OUTPUT_DIR = Path(tempfile.gettempdir()) / "triposg_output"
45
  OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
46
 
47
- logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
48
- logger = logging.getLogger(__name__)
49
-
50
- # Clone repo if needed
51
  if not os.path.exists(TRIPOSG_CODE_DIR):
52
- logger.info("Cloning TripoSG repository...")
53
  os.system(f"git clone {TRIPOSG_REPO_URL} {TRIPOSG_CODE_DIR}")
54
 
55
  sys.path.insert(0, TRIPOSG_CODE_DIR)
56
  sys.path.insert(0, os.path.join(TRIPOSG_CODE_DIR, "scripts"))
57
 
58
- # ---------------------------------------------------------------------------
59
- # Global models
60
- # ---------------------------------------------------------------------------
61
  triposg_pipeline = None
62
  device = "cuda" if torch.cuda.is_available() else "cpu"
63
 
@@ -65,61 +54,60 @@ def load_models():
65
  global triposg_pipeline
66
  if triposg_pipeline is not None:
67
  return
68
- logger.info("Loading TripoSG pipeline...")
69
  try:
70
  from huggingface_hub import snapshot_download
71
  from triposg.pipelines.pipeline_triposg import TripoSGPipeline
72
  model_path = snapshot_download(MODEL_ID)
73
- triposg_pipeline = TripoSGPipeline.from_pretrained(model_path).to(
74
- device, torch.float16 if device == "cuda" else torch.float32
75
- )
76
- logger.info("TripoSG loaded successfully")
77
  except Exception as e:
78
- logger.error("Failed to load TripoSG: %s", e)
79
  triposg_pipeline = None
80
 
81
- # ---------------------------------------------------------------------------
82
- # Background Removal
83
- # ---------------------------------------------------------------------------
84
  def remove_background(image: Image.Image) -> Image.Image:
85
  try:
86
- output = remove(image)
87
- logger.info("Background removed with rembg")
88
- return output
89
  except Exception as e:
90
- logger.warning("rembg failed: %s", e)
91
  return image
92
 
93
- # ---------------------------------------------------------------------------
94
- # 其他有函數 (select_best_view, create_composite_view, extract_dimensions..., repair_mesh, scale_mesh, segment_mesh_parts, export_mesh)
95
- # 請把你原本這些函數貼返入嚟(我下面留空位,你 copy 返落去)
96
- # ---------------------------------------------------------------------------
97
 
98
- # ... paste your original functions here (from select_best_view to export_mesh) ...
99
 
100
- # ---------------------------------------------------------------------------
101
- # Main Generation (keep your original logic)
102
- # ---------------------------------------------------------------------------
103
  @spaces.GPU(duration=300)
104
- def generate_3d_model(
105
- input_images: list,
106
- text_prompt: str,
107
- num_faces: int = DEFAULT_FACES,
108
- export_format: str = "glb",
109
- enable_modular: bool = False,
110
- progress=gr.Progress(track_tqdm=True),
111
- ):
112
- # ... 你原本 generate_3d_model 嘅 code(load_models, process images, remove bg, triposg inference, post-process, export)...
113
- # 只需要確保第一��� load_models() 仲喺度
114
- pass # 暫時 placeholder,請貼返你原本內容
115
-
116
- # ---------------------------------------------------------------------------
117
- # Gradio UI
118
- # ---------------------------------------------------------------------------
119
- with gr.Blocks(title="AI 3D Model Generator") as demo:
120
- # ... 你原本 UI code(HEADER_MD, inputs, outputs, button click 等)...
121
- pass # placeholder,請貼返你原本 UI 部分
122
-
123
- # Launch
 
 
 
 
 
 
 
 
 
124
  demo.queue(max_size=5)
125
  demo.launch(show_api=True)
 
1
  """
2
+ AI 3D Generator - TripoSG + rembg (Fixed for HF Space)
3
  """
 
4
  import os
 
5
  import sys
 
6
  import uuid
7
  import time
 
 
8
  import logging
9
  import tempfile
 
10
  from pathlib import Path
11
  from typing import List
12
+
13
  import gradio as gr
14
  import numpy as np
15
  import torch
 
17
  import trimesh
18
  from rembg import remove
19
 
20
+ # ZeroGPU support
21
  try:
22
  import spaces
23
  except ImportError:
 
28
  return lambda f: f
29
  return fn
30
 
31
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
32
+ logger = logging.getLogger(__name__)
33
+
34
+ # Config
35
  MODEL_ID = "VAST-AI/TripoSG"
36
  TRIPOSG_REPO_URL = "https://github.com/VAST-AI-Research/TripoSG.git"
37
+ TRIPOSG_CODE_DIR = "triposg_repo"
 
 
38
  OUTPUT_DIR = Path(tempfile.gettempdir()) / "triposg_output"
39
  OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
40
 
41
+ # Clone repo
 
 
 
42
  if not os.path.exists(TRIPOSG_CODE_DIR):
43
+ logger.info("Cloning TripoSG...")
44
  os.system(f"git clone {TRIPOSG_REPO_URL} {TRIPOSG_CODE_DIR}")
45
 
46
  sys.path.insert(0, TRIPOSG_CODE_DIR)
47
  sys.path.insert(0, os.path.join(TRIPOSG_CODE_DIR, "scripts"))
48
 
49
+ # Global
 
 
50
  triposg_pipeline = None
51
  device = "cuda" if torch.cuda.is_available() else "cpu"
52
 
 
54
  global triposg_pipeline
55
  if triposg_pipeline is not None:
56
  return
57
+ logger.info("Loading TripoSG...")
58
  try:
59
  from huggingface_hub import snapshot_download
60
  from triposg.pipelines.pipeline_triposg import TripoSGPipeline
61
  model_path = snapshot_download(MODEL_ID)
62
+ triposg_pipeline = TripoSGPipeline.from_pretrained(model_path).to(device, torch.float16 if device == "cuda" else torch.float32)
63
+ logger.info("TripoSG loaded")
 
 
64
  except Exception as e:
65
+ logger.error(f"Load failed: {e}")
66
  triposg_pipeline = None
67
 
 
 
 
68
  def remove_background(image: Image.Image) -> Image.Image:
69
  try:
70
+ return remove(image)
 
 
71
  except Exception as e:
72
+ logger.warning(f"rembg failed: {e}")
73
  return image
74
 
75
+ # ================== 下面貼返你原本其他函數 ==================
76
+ # 請你從 app.py copy 下面這些函數貼入去:
77
+ # select_best_view, create_composite_view, extract_dimensions_from_prompt, repair_mesh, scale_mesh, segment_mesh_parts, export_mesh
 
78
 
79
+ # (如果你冇,我可以提供最小版 placeholder)
80
 
81
+ # ================== Main Pipeline ==================
 
 
82
  @spaces.GPU(duration=300)
83
+ def generate_3d_model(input_images: list, text_prompt: str, num_faces: int = 50000, export_format: str = "glb", progress=gr.Progress()):
84
+ load_models()
85
+ if triposg_pipeline is None:
86
+ raise gr.Error("Model load failed. Check logs.")
87
+
88
+ # ... 你原本 generate 邏輯 ...
89
+ # 暫時用 placeholder
90
+ return None, None, "Pipeline running... (add your full logic here)"
91
+
92
+ # ================== UI ==================
93
+ with gr.Blocks(title="AI 3D Generator") as demo:
94
+ gr.Markdown("# 🚀 TripoSG 3D Generator (rembg version)")
95
+ with gr.Row():
96
+ with gr.Column():
97
+ input_images = gr.File(label="Upload Images", file_count="multiple", file_types=["image"])
98
+ text_prompt = gr.Textbox(label="Text Prompt (dimensions etc)", lines=3)
99
+ num_faces = gr.Slider(5000, 90000, value=50000, step=5000, label="Target Faces")
100
+ btn = gr.Button("Generate 3D Model", variant="primary")
101
+ with gr.Column():
102
+ preview = gr.Model3D(label="3D Preview")
103
+ download = gr.File(label="Download Model")
104
+ status = gr.Textbox(label="Status", lines=8)
105
+
106
+ btn.click(
107
+ generate_3d_model,
108
+ inputs=[input_images, text_prompt, num_faces],
109
+ outputs=[preview, download, status]
110
+ )
111
+
112
  demo.queue(max_size=5)
113
  demo.launch(show_api=True)