|
|
|
|
|
import os |
|
import subprocess |
|
|
|
|
|
os.environ.pop("PYENV_VERSION", None) |
|
|
|
|
|
subprocess.run(["pip", "install", "torch", "wheel"], check=True) |
|
subprocess.run([ |
|
"pip", "install", "--no-build-isolation", |
|
"diso@git+https://github.com/SarahWeiii/diso.git" |
|
], check=True) |
|
|
|
|
|
import gradio as gr |
|
import uuid |
|
import torch |
|
import zipfile |
|
import requests |
|
import traceback |
|
import trimesh |
|
from trimesh.exchange.gltf import export_glb |
|
|
|
print("Trimesh version:", trimesh.__version__) |
|
|
|
|
|
from inference_triposg import run_triposg |
|
from triposg.pipelines.pipeline_triposg import TripoSGPipeline |
|
from briarmbg import BriaRMBG |
|
|
|
|
|
device = "cuda" if torch.cuda.is_available() else "cpu" |
|
dtype = torch.float16 if device == "cuda" else torch.float32 |
|
|
|
|
|
weights_dir = "pretrained_weights" |
|
triposg_path = os.path.join(weights_dir, "TripoSG") |
|
rmbg_path = os.path.join(weights_dir, "RMBG-1.4") |
|
|
|
if not (os.path.exists(triposg_path) and os.path.exists(rmbg_path)): |
|
print("📦 Downloading pretrained weights...") |
|
url = "https://huggingface.co/datasets/endlesstools/pretrained-assets/resolve/main/pretrained_models.zip" |
|
zip_path = "pretrained_models.zip" |
|
|
|
with requests.get(url, stream=True) as r: |
|
r.raise_for_status() |
|
with open(zip_path, "wb") as f: |
|
for chunk in r.iter_content(chunk_size=8192): |
|
f.write(chunk) |
|
|
|
print("📦 Extracting weights...") |
|
with zipfile.ZipFile(zip_path, "r") as zip_ref: |
|
zip_ref.extractall(weights_dir) |
|
|
|
os.remove(zip_path) |
|
print("✅ Weights ready.") |
|
|
|
|
|
pipe = TripoSGPipeline.from_pretrained(triposg_path).to(device, dtype) |
|
rmbg_net = BriaRMBG.from_pretrained(rmbg_path).to(device) |
|
rmbg_net.eval() |
|
|
|
|
|
|
|
def generate(image_path, face_number=50000, guidance_scale=5.0, num_steps=25): |
|
print("[API CALL] image_path received:", image_path) |
|
print("[API CALL] File exists:", os.path.exists(image_path)) |
|
|
|
temp_id = str(uuid.uuid4()) |
|
output_path = f"/tmp/{temp_id}.glb" |
|
|
|
print("[DEBUG] Generating mesh from:", image_path) |
|
|
|
try: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mesh = run_triposg( |
|
pipe=pipe, |
|
image_input=image_path, |
|
rmbg_net=rmbg_net, |
|
seed=42, |
|
num_inference_steps=int(num_steps), |
|
guidance_scale=float(guidance_scale), |
|
faces=int(face_number), |
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if mesh is None: |
|
raise ValueError("Mesh generation returned None") |
|
|
|
|
|
mesh.visual = None |
|
mesh.metadata.clear() |
|
mesh.name = "geometry_0" |
|
|
|
|
|
glb_data = export_glb(mesh) |
|
with open(output_path, "wb") as f: |
|
f.write(glb_data) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(f"[DEBUG] Mesh saved to {output_path}") |
|
return output_path if os.path.exists(output_path) else None |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
print("[ERROR]", e) |
|
traceback.print_exc() |
|
return f"Error: {e}" |
|
|
|
|
|
demo = gr.Interface( |
|
fn=generate, |
|
inputs=gr.Image(type="filepath", label="Upload image"), |
|
outputs=gr.File(label="Download .glb"), |
|
title="TripoSG Image to 3D", |
|
description="Upload an image to generate a 3D model (.glb)", |
|
) |
|
|
|
|
|
demo.launch() |
|
|
|
|
|
|
|
|
|
|