Spaces:
Running
on
Zero
Running
on
Zero
import argparse | |
import base64 | |
import os | |
from datetime import datetime | |
import traceback | |
import trimesh | |
import torch | |
from craftsman import CraftsManPipeline | |
CURRENT_DIR = f'/tmp/native3d_server/{os.getpid()}' | |
os.makedirs(CURRENT_DIR, exist_ok=True) | |
def parse_parameters(): | |
parser = argparse.ArgumentParser("native3d") | |
parser.add_argument('--host', default="0.0.0.0", type=str) | |
parser.add_argument('--port', default=12345, type=int) | |
return parser.parse_args() | |
# -------------------- fastapi -------------------- | |
from typing import Optional | |
from pydantic import BaseModel, Field | |
class Native3DRequestV1(BaseModel): | |
image_path: str # input image path | |
mesh_path: str # output mesh path, support glb or obj in clean dir | |
class Native3DResponseV1(BaseModel): | |
pass | |
class Native3DRequestV2(BaseModel): | |
image_bytes: str # input image bytes(base64) | |
mesh_type: str # output mesh type, support glb or obj | |
class Native3DResponseV2(BaseModel): | |
mesh_bytes: str # output mesh bytes(base64) | |
if __name__=="__main__": | |
parse_args = parse_parameters() | |
# prepare models | |
pipeline = CraftsManPipeline.from_pretrained("/home/super/Desktop/8TDisk/weiyu/CraftsMan_gradio/ckpts/craftsman-v1-5", device="cuda:0", torch_dtype=torch.float32) | |
# -------------------- fastapi -------------------- | |
from fastapi import FastAPI, Request | |
import requests | |
app = FastAPI() | |
async def native3d(request: Request, image_to_mesh_request: Native3DRequestV1): | |
try: | |
print(f"image_to_mesh_request = {image_to_mesh_request}") | |
mesh = pipeline(image_to_mesh_request.image_path).meshes[0] | |
os.makedirs(os.path.dirname(os.path.abspath(image_to_mesh_request.mesh_path)), exist_ok=True) | |
mesh.export(image_to_mesh_request.mesh_path) | |
except Exception as e: | |
traceback.print_exc() | |
print(f"generate_model error: {e}") | |
return Native3DResponseV1() | |
async def native3d(request: Request, image_to_mesh_request: Native3DRequestV2): | |
try: | |
# print(f"image_to_mesh_request = {image_to_mesh_request}") | |
mesh_type = image_to_mesh_request.mesh_type | |
assert mesh_type in ['obj', 'glb'] | |
task_id = datetime.now().strftime('%Y-%m-%d-%H-%M-%S-%f') + '-' + 'native3d' | |
current_dir = os.path.join(CURRENT_DIR, task_id) | |
os.makedirs(current_dir, exist_ok=True) | |
image_path = os.path.join(current_dir, 'input_image.png') | |
with open(image_path, 'wb') as f: | |
f.write(base64.b64decode(image_to_mesh_request.image_bytes)) | |
mesh_path = os.path.join(current_dir, f'output_mesh.{mesh_type}') | |
import time | |
start = time.time() | |
# mesh = pipeline(image_path).meshes[0] | |
# mesh = pipeline(image_path, mc_depth=7, num_inference_steps=50).meshes[0] | |
mesh = pipeline(image_path).meshes[0] | |
print(f"Time: {time.time() - start}s") | |
os.makedirs(os.path.dirname(os.path.abspath(mesh_path)), exist_ok=True) | |
mesh.visual = trimesh.visual.TextureVisuals( | |
material=trimesh.visual.material.PBRMaterial( | |
baseColorFactor=(255, 255, 255), main_color=(255, 255, 255), metallicFactor=0.05, roughnessFactor=1.0 | |
) | |
) | |
mesh.export(mesh_path) | |
with open(mesh_path, 'rb') as f: | |
mesh_bytes = f.read() | |
except Exception as e: | |
traceback.print_exc() | |
print(f"generate_model error: {e}") | |
return Native3DResponseV2(mesh_bytes=base64.b64encode(mesh_bytes).decode('utf-8')) | |
async def health(): | |
return {"status": "OK"} | |
import uvicorn | |
uvicorn.run(app, host=parse_args.host, port=parse_args.port) | |