Skip to content

Commit bdf8a02

Browse files
authored
Merge pull request #440 from MrForExample/dev
Small Update for Hunyuan3D-2, Merge 2 pull requests, and add Decimate Mesh node
2 parents a3c515f + 979d770 commit bdf8a02

File tree

6 files changed

+161
-16
lines changed

6 files changed

+161
-16
lines changed

Checkpoints/Diffusers/tencent/Hunyuan3D-2/README.md

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@ language:
99
tags:
1010
- image-to-3d
1111
- text-to-3d
12-
pipeline_tag: text-to-3d
12+
pipeline_tag: image-to-3d
1313
---
1414

15-
1615
<p align="center">
1716
<img src="./assets/images/teaser.jpg">
18-
19-
2017
</p>
2118

2219
<div align="center">
@@ -40,6 +37,9 @@ pipeline_tag: text-to-3d
4037
“ Living out everyone’s imagination on creating and manipulating 3D assets.”
4138
</p>
4239

40+
This repository contains the models of the paper [Hunyuan3D 2.0: Scaling Diffusion Models for High Resolution Textured 3D Assets Generation](https://huggingface.co/papers/2501.12202).
41+
For code and more details on how to use it, refer to the [Github repository](https://github.com/Tencent/Hunyuan3D-2).
42+
4343
## 🔥 News
4444

4545
- Jan 21, 2025: 💬 Release [Hunyuan3D 2.0](https://huggingface.co/spaces/tencent/Hunyuan3D-2). Please give it a try!
@@ -60,8 +60,6 @@ We systematically evaluate our models, showing that Hunyuan3D 2.0 outperforms pr
6060
including the open-source models and closed-source models in geometry details, condition alignment, texture quality, and
6161
e.t.c.
6262

63-
64-
6563
<p align="center">
6664
<img src="assets/images/system.jpg">
6765
</p>
@@ -104,6 +102,7 @@ Generation results of Hunyuan3D 2.0:
104102
|----------------------|------------|--------------------------------------------------------|
105103
| Hunyuan3D-DiT-v2-0 | 2025-01-21 | [Download](https://huggingface.co/tencent/Hunyuan3D-2) |
106104
| Hunyuan3D-Paint-v2-0 | 2025-01-21 | [Download](https://huggingface.co/tencent/Hunyuan3D-2) |
105+
| Hunyuan3D-Delight-v2-0 | 2025-01-21 | [Download](https://huggingface.co/tencent/Hunyuan3D-2/tree/main/hunyuan3d-delight-v2-0) |
107106

108107
## 🤗 Get Started with Hunyuan3D 2.0
109108

@@ -118,8 +117,9 @@ pip install -r requirements.txt
118117
# for texture
119118
cd hy3dgen/texgen/custom_rasterizer
120119
python3 setup.py install
120+
cd ../../..
121121
cd hy3dgen/texgen/differentiable_renderer
122-
bash compile_mesh_painter.sh
122+
bash compile_mesh_painter.sh OR python3 setup.py install (on Windows)
123123
```
124124

125125
### API Usage
@@ -184,9 +184,29 @@ If you found this repository helpful, please cite our report:
184184
title={Hunyuan3D 2.0: Scaling Diffusion Models for High Resolution Textured 3D Assets Generation},
185185
author={Tencent Hunyuan3D Team},
186186
year={2025},
187+
eprint={2501.12202},
188+
archivePrefix={arXiv},
189+
primaryClass={cs.CV}
190+
}
191+
192+
@misc{yang2024tencent,
193+
title={Tencent Hunyuan3D-1.0: A Unified Framework for Text-to-3D and Image-to-3D Generation},
194+
author={Tencent Hunyuan3D Team},
195+
year={2024},
196+
eprint={2411.02293},
197+
archivePrefix={arXiv},
198+
primaryClass={cs.CV}
187199
}
188200
```
189201

202+
## Community Resources
203+
204+
Thanks for the contributions of community members, here we have these great extensions of Hunyuan3D 2.0:
205+
206+
- [ComfyUI-Hunyuan3DWrapper](https://github.com/kijai/ComfyUI-Hunyuan3DWrapper)
207+
- [Hunyuan3D-2-for-windows](https://github.com/sdbds/Hunyuan3D-2-for-windows)
208+
- [📦 A bundle for running on Windows | 整合包](https://github.com/YanWenKun/Comfy3D-WinPortable/releases/tag/r8-hunyuan3d2)
209+
190210
## Acknowledgements
191211

192212
We would like to thank the contributors to
@@ -201,4 +221,4 @@ and [HuggingFace](https://huggingface.co) repositories, for their open research
201221
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Tencent/Hunyuan3D-2&type=Date" />
202222
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Tencent/Hunyuan3D-2&type=Date" />
203223
</picture>
204-
</a>
224+
</a>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from setuptools import setup, Extension
2+
import pybind11
3+
import sys
4+
import platform
5+
6+
# Common compile arguments
7+
common_compile_args = []
8+
9+
if sys.platform == 'win32':
10+
# Windows-specific compile arguments
11+
extra_compile_args = [
12+
'/O2', # Optimization level
13+
'/std:c++14', # C++ standard (using C++14 for better compatibility)
14+
'/EHsc', # Exception handling model
15+
'/MP', # Multi-process compilation
16+
'/DWIN32_LEAN_AND_MEAN', # Exclude rarely-used Windows headers
17+
]
18+
extra_link_args = []
19+
else:
20+
# Linux/Unix compile arguments
21+
extra_compile_args = [
22+
'-O3', # Optimization level
23+
'-std=c++14', # C++ standard
24+
'-fPIC', # Position independent code
25+
]
26+
extra_link_args = ['-fPIC']
27+
28+
ext_modules = [
29+
Extension(
30+
"mesh_processor",
31+
["mesh_processor.cpp"],
32+
include_dirs=[
33+
pybind11.get_include(),
34+
pybind11.get_include(user=True)
35+
],
36+
language='c++',
37+
extra_compile_args=common_compile_args + extra_compile_args,
38+
extra_link_args=extra_link_args,
39+
),
40+
]
41+
42+
setup(
43+
name="mesh_processor",
44+
ext_modules=ext_modules,
45+
install_requires=['pybind11>=2.6.0'],
46+
python_requires='>=3.6',
47+
)

Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/pipelines.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,40 @@ def texture_inpaint(self, texture, mask):
140140
texture = torch.tensor(texture_np / 255).float().to(texture.device)
141141

142142
return texture
143+
144+
def recenter_image(self, image, border_ratio=0.2):
145+
if image.mode == 'RGB':
146+
return image
147+
elif image.mode == 'L':
148+
image = image.convert('RGB')
149+
return image
150+
151+
alpha_channel = np.array(image)[:, :, 3]
152+
non_zero_indices = np.argwhere(alpha_channel > 0)
153+
if non_zero_indices.size == 0:
154+
raise ValueError("Image is fully transparent")
155+
156+
min_row, min_col = non_zero_indices.min(axis=0)
157+
max_row, max_col = non_zero_indices.max(axis=0)
158+
159+
cropped_image = image.crop((min_col, min_row, max_col + 1, max_row + 1))
160+
161+
width, height = cropped_image.size
162+
border_width = int(width * border_ratio)
163+
border_height = int(height * border_ratio)
164+
165+
new_width = width + 2 * border_width
166+
new_height = height + 2 * border_height
167+
168+
square_size = max(new_width, new_height)
169+
170+
new_image = Image.new('RGBA', (square_size, square_size), (255, 255, 255, 0))
171+
172+
paste_x = (square_size - new_width) // 2 + border_width
173+
paste_y = (square_size - new_height) // 2 + border_height
174+
175+
new_image.paste(cropped_image, (paste_x, paste_y))
176+
return new_image
143177

144178
@torch.no_grad()
145179
def __call__(self, mesh, image):
@@ -153,6 +187,7 @@ def __call__(self, mesh, image):
153187
else:
154188
image_prompt = image
155189

190+
image_prompt = self.recenter_image(image_prompt)
156191
image_prompt = self.models['delight_model'](image_prompt)
157192

158193
step_num_i += 1

mesh_processer/mesh_utils.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,22 @@ def poisson_mesh_reconstruction(points, normals=None):
211211

212212

213213
def decimate_mesh(
214-
verts, faces, target, backend="pymeshlab", remesh=False, optimalplacement=True
214+
verts, faces, target=5e4, backend="pymeshlab", remesh=False, optimalplacement=True, verbose=True
215215
):
216-
# optimalplacement: default is True, but for flat mesh must turn False to prevent spike artifect.
216+
""" perform mesh decimation.
217+
218+
Args:
219+
verts (np.ndarray): mesh vertices, float [N, 3]
220+
faces (np.ndarray): mesh faces, int [M, 3]
221+
target (int): targeted number of faces
222+
backend (str, optional): algorithm backend, can be "pymeshlab" or "pyfqmr". Defaults to "pymeshlab".
223+
remesh (bool, optional): whether to remesh after decimation. Defaults to False.
224+
optimalplacement (bool, optional): For flat mesh, use False to prevent spikes. Defaults to True.
225+
verbose (bool, optional): whether to print the decimation process. Defaults to True.
226+
227+
Returns:
228+
Tuple[np.ndarray]: vertices and faces after decimation.
229+
"""
217230

218231
_ori_vert_shape = verts.shape
219232
_ori_face_shape = faces.shape
@@ -231,25 +244,25 @@ def decimate_mesh(
231244
ms.add_mesh(m, "mesh") # will copy!
232245

233246
# filters
234-
# ms.meshing_decimation_clustering(threshold=pml.Percentage(1))
247+
# ms.meshing_decimation_clustering(threshold=pml.PercentageValue(1))
235248
ms.meshing_decimation_quadric_edge_collapse(
236249
targetfacenum=int(target), optimalplacement=optimalplacement
237250
)
238251

239252
if remesh:
240253
# ms.apply_coord_taubin_smoothing()
241254
ms.meshing_isotropic_explicit_remeshing(
242-
iterations=3, targetlen=pml.Percentage(1)
255+
iterations=3, targetlen=pml.PercentageValue(1)
243256
)
244257

245258
# extract mesh
246259
m = ms.current_mesh()
260+
m.compact()
247261
verts = m.vertex_matrix()
248262
faces = m.face_matrix()
249263

250-
print(
251-
f"[INFO] mesh decimation: {_ori_vert_shape} --> {verts.shape}, {_ori_face_shape} --> {faces.shape}"
252-
)
264+
if verbose:
265+
print(f"[INFO] mesh decimation: {_ori_vert_shape} --> {verts.shape}, {_ori_face_shape} --> {faces.shape}")
253266

254267
return verts, faces
255268

nodes.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
marching_cubes_density_to_mesh,
4747
color_func_to_albedo,
4848
interpolate_texture_map_attr,
49+
decimate_mesh,
4950
)
5051

5152
from FlexiCubes.flexicubes_trainer import FlexiCubesTrainer
@@ -608,6 +609,35 @@ def clean_mesh(self, mesh, apply_smooth, smooth_step, apply_sub_divide, sub_divi
608609
mesh = Mesh(v=vertices, f=faces, device=DEVICE)
609610

610611
return (mesh,)
612+
613+
class Decimate_Mesh:
614+
@classmethod
615+
def INPUT_TYPES(cls):
616+
return {
617+
"required": {
618+
"mesh": ("MESH",),
619+
"target": ("INT", {"default": 5e4, "min": 0, "max": 0xffffffffffffffff}),
620+
"remesh": ("BOOLEAN", {"default": True},),
621+
"optimalplacement": ("BOOLEAN", {"default": True},),
622+
},
623+
}
624+
625+
RETURN_TYPES = (
626+
"MESH",
627+
)
628+
RETURN_NAMES = (
629+
"mesh",
630+
)
631+
FUNCTION = "process_mesh"
632+
CATEGORY = "Comfy3D/Preprocessor"
633+
634+
def process_mesh(self, mesh, target, remesh, optimalplacement):
635+
636+
vertices, faces = decimate_mesh(mesh.v, mesh.f, target, remesh, optimalplacement)
637+
mesh.v = vertices
638+
mesh.f = faces
639+
640+
return (mesh,)
611641

612642
class Switch_3DGS_Axis:
613643
@classmethod

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "comfyui-3d-pack"
33
description = "Make ComfyUI generates 3D assets as good & convenient as it generates image/video!"
4-
version = "0.1.3"
4+
version = "0.1.4"
55
license = { file = "LICENSE" }
66
dynamic = ["dependencies"]
77
[tool.setuptools.dynamic]

0 commit comments

Comments
 (0)