99 FaceReducer , FloaterRemover , DegenerateFaceRemover ,
1010 Hunyuan3DDiTFlowMatchingPipeline
1111)
12+ from hy3dgen .rembg import BackgroundRemover
1213from hy3dgen .texgen import Hunyuan3DPaintPipeline
1314
14- MODEL_PATH = "checkpoints "
15+ MODEL_REPO = "tencent/Hunyuan3D-2 "
1516MODEL_URL = "https://weights.replicate.delivery/default/tencent/Hunyuan3D-2/hunyuan3d-dit-v2-0/model.tar"
16- # DELIGHT_URL = "https://weights.replicate.delivery/default/tencent/Hunyuan3D-2/hunyuan3d-dit-v2-0/delight.tar"
17- # PAINT_URL = "https://weights.replicate.delivery/default/tencent/Hunyuan3D-2/hunyuan3d-dit-v2-0/paint.tar"
17+ DELIGHT_URL = "https://weights.replicate.delivery/default/tencent/Hunyuan3D-2/hunyuan3d-dit-v2-0/delight.tar"
18+ PAINT_URL = "https://weights.replicate.delivery/default/tencent/Hunyuan3D-2/hunyuan3d-dit-v2-0/paint.tar"
1819
1920def download_weights (url , dest ):
2021 start = time .time ()
@@ -28,26 +29,24 @@ class Output(BaseModel):
2829
2930class Predictor (BasePredictor ):
3031 def setup (self ) -> None :
31- """Load the model into memory to make running multiple predictions efficient"""
32- #make directory model_path
33- os .makedirs (MODEL_PATH , exist_ok = True )
34-
35- # Download weights
36- if not os .path .exists (MODEL_PATH + "/hunyuan3d-dit-v2-0" ):
37- download_weights (MODEL_URL , MODEL_PATH + "/hunyuan3d-dit-v2-0" )
38- # if not os.path.exists(MODEL_PATH + "/hunyuan3d-delight-v2-0"):
39- # download_weights(DELIGHT_URL, MODEL_PATH + "/hunyuan3d-delight-v2-0")
40- # if not os.path.exists(MODEL_PATH + "/hunyuan3d-paint-v2-0"):
41- # download_weights(PAINT_URL, MODEL_PATH + "/hunyuan3d-paint-v2-0")
42-
43- # Load shape generation model
44- self .pipeline = Hunyuan3DDiTFlowMatchingPipeline .from_pretrained (MODEL_PATH + "/hunyuan3d-dit-v2-0" )
32+ model_base_path = os .path .expanduser (os .path .join ("~/.cache/hy3dgen" , MODEL_REPO ))
33+ os .makedirs (model_base_path , exist_ok = True )
34+
35+ model_path = os .path .join (model_base_path , "hunyuan3d-dit-v2-0" )
36+ delight_path = os .path .join (model_base_path , "hunyuan3d-delight-v2-0" )
37+ paint_path = os .path .join (model_base_path , "hunyuan3d-paint-v2-0" )
38+ if not os .path .exists (model_path ):
39+ download_weights (MODEL_URL , model_path )
40+ if not os .path .exists (delight_path ):
41+ download_weights (DELIGHT_URL , delight_path )
42+ if not os .path .exists (paint_path ):
43+ download_weights (PAINT_URL , paint_path )
44+
45+ self .i23d_worker = Hunyuan3DDiTFlowMatchingPipeline .from_pretrained (MODEL_REPO )
46+ self .texgen_worker = Hunyuan3DPaintPipeline .from_pretrained (MODEL_REPO )
4547 self .floater_remove_worker = FloaterRemover ()
4648 self .degenerate_face_remove_worker = DegenerateFaceRemover ()
4749 self .face_reduce_worker = FaceReducer ()
48-
49- # Load background remover
50- from hy3dgen .rembg import BackgroundRemover
5150 self .rmbg_worker = BackgroundRemover ()
5251
5352 def predict (
@@ -82,51 +81,39 @@ def predict(
8281 default = True
8382 ),
8483 ) -> Output :
85- """Run a single prediction on the model"""
86- # Clean up past runs, delete output directory
8784 if os .path .exists ("output" ):
8885 shutil .rmtree ("output" )
8986
90- # Create output directory
9187 os .makedirs ("output" , exist_ok = True )
92-
93- # Set random seed
88+
9489 generator = torch .Generator ()
9590 generator = generator .manual_seed (seed )
9691
97- # Process input image
9892 if image is not None :
9993 input_image = Image .open (str (image ))
10094 if remove_background or input_image .mode == "RGB" :
10195 input_image = self .rmbg_worker (input_image .convert ('RGB' ))
10296 else :
10397 raise ValueError ("Image must be provided" )
10498
105- # Save processed input image
10699 input_image .save ("output/input.png" )
107100
108- # Generate 3D mesh
109- mesh = self .pipeline (
101+ mesh = self .i23d_worker (
110102 image = input_image ,
111103 num_inference_steps = steps ,
112104 guidance_scale = guidance_scale ,
113105 generator = generator ,
114106 octree_resolution = octree_resolution
115107 )[0 ]
116108
117- # Post-process mesh
118109 mesh = self .floater_remove_worker (mesh )
119110 mesh = self .degenerate_face_remove_worker (mesh )
120111 mesh = self .face_reduce_worker (mesh )
112+ textured_mesh = self .texgen_worker (mesh , input_image )
121113
122- # Set mesh color to dark gray
123- mesh .visual .face_colors = [64 , 64 , 64 , 255 ] # RGB + Alpha for dark gray
124-
125- # Export mesh
126- output_path = Path ("output/gray_mesh.glb" )
127- mesh .export (str (output_path ), include_normals = False )
114+ output_path = Path ("output/mesh.glb" )
115+ textured_mesh .export (str (output_path ), include_normals = True )
128116
129- # Verify file exists and is readable
130117 if not Path (output_path ).exists ():
131118 raise RuntimeError (f"Failed to generate mesh file at { output_path } " )
132119
0 commit comments