From 3c12ee16b9f8248ba9d5758a7d98f6fd51266eaf Mon Sep 17 00:00:00 2001 From: "Mr. For Example" <62230687+MrForExample@users.noreply.github.com> Date: Fri, 24 Jan 2025 12:31:59 -0600 Subject: [PATCH] Small update for Hunyuan3D-2 --- .../Diffusers/tencent/Hunyuan3D-2/README.md | 36 ++++++++++---- .../texgen/differentiable_renderer/setup.py | 47 +++++++++++++++++++ .../Hunyuan3D_V2/hy3dgen/texgen/pipelines.py | 35 ++++++++++++++ mesh_processer/mesh_utils.py | 27 ++++++++--- nodes.py | 30 ++++++++++++ pyproject.toml | 2 +- 6 files changed, 161 insertions(+), 16 deletions(-) create mode 100644 Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/differentiable_renderer/setup.py diff --git a/Checkpoints/Diffusers/tencent/Hunyuan3D-2/README.md b/Checkpoints/Diffusers/tencent/Hunyuan3D-2/README.md index ad18c9a..51ebc3e 100644 --- a/Checkpoints/Diffusers/tencent/Hunyuan3D-2/README.md +++ b/Checkpoints/Diffusers/tencent/Hunyuan3D-2/README.md @@ -9,14 +9,11 @@ language: tags: - image-to-3d - text-to-3d -pipeline_tag: text-to-3d +pipeline_tag: image-to-3d --- -

- -

@@ -40,6 +37,9 @@ pipeline_tag: text-to-3d “ Living out everyone’s imagination on creating and manipulating 3D assets.”

+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). +For code and more details on how to use it, refer to the [Github repository](https://github.com/Tencent/Hunyuan3D-2). + ## 🔥 News - 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 including the open-source models and closed-source models in geometry details, condition alignment, texture quality, and e.t.c. - -

@@ -104,6 +102,7 @@ Generation results of Hunyuan3D 2.0: |----------------------|------------|--------------------------------------------------------| | Hunyuan3D-DiT-v2-0 | 2025-01-21 | [Download](https://huggingface.co/tencent/Hunyuan3D-2) | | Hunyuan3D-Paint-v2-0 | 2025-01-21 | [Download](https://huggingface.co/tencent/Hunyuan3D-2) | +| Hunyuan3D-Delight-v2-0 | 2025-01-21 | [Download](https://huggingface.co/tencent/Hunyuan3D-2/tree/main/hunyuan3d-delight-v2-0) | ## 🤗 Get Started with Hunyuan3D 2.0 @@ -118,8 +117,9 @@ pip install -r requirements.txt # for texture cd hy3dgen/texgen/custom_rasterizer python3 setup.py install +cd ../../.. cd hy3dgen/texgen/differentiable_renderer -bash compile_mesh_painter.sh +bash compile_mesh_painter.sh OR python3 setup.py install (on Windows) ``` ### API Usage @@ -184,9 +184,29 @@ If you found this repository helpful, please cite our report: title={Hunyuan3D 2.0: Scaling Diffusion Models for High Resolution Textured 3D Assets Generation}, author={Tencent Hunyuan3D Team}, year={2025}, + eprint={2501.12202}, + archivePrefix={arXiv}, + primaryClass={cs.CV} +} + +@misc{yang2024tencent, + title={Tencent Hunyuan3D-1.0: A Unified Framework for Text-to-3D and Image-to-3D Generation}, + author={Tencent Hunyuan3D Team}, + year={2024}, + eprint={2411.02293}, + archivePrefix={arXiv}, + primaryClass={cs.CV} } ``` +## Community Resources + +Thanks for the contributions of community members, here we have these great extensions of Hunyuan3D 2.0: + +- [ComfyUI-Hunyuan3DWrapper](https://github.com/kijai/ComfyUI-Hunyuan3DWrapper) +- [Hunyuan3D-2-for-windows](https://github.com/sdbds/Hunyuan3D-2-for-windows) +- [📦 A bundle for running on Windows | 整合包](https://github.com/YanWenKun/Comfy3D-WinPortable/releases/tag/r8-hunyuan3d2) + ## Acknowledgements We would like to thank the contributors to @@ -201,4 +221,4 @@ and [HuggingFace](https://huggingface.co) repositories, for their open research Star History Chart - + \ No newline at end of file diff --git a/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/differentiable_renderer/setup.py b/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/differentiable_renderer/setup.py new file mode 100644 index 0000000..902d842 --- /dev/null +++ b/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/differentiable_renderer/setup.py @@ -0,0 +1,47 @@ +from setuptools import setup, Extension +import pybind11 +import sys +import platform + +# Common compile arguments +common_compile_args = [] + +if sys.platform == 'win32': + # Windows-specific compile arguments + extra_compile_args = [ + '/O2', # Optimization level + '/std:c++14', # C++ standard (using C++14 for better compatibility) + '/EHsc', # Exception handling model + '/MP', # Multi-process compilation + '/DWIN32_LEAN_AND_MEAN', # Exclude rarely-used Windows headers + ] + extra_link_args = [] +else: + # Linux/Unix compile arguments + extra_compile_args = [ + '-O3', # Optimization level + '-std=c++14', # C++ standard + '-fPIC', # Position independent code + ] + extra_link_args = ['-fPIC'] + +ext_modules = [ + Extension( + "mesh_processor", + ["mesh_processor.cpp"], + include_dirs=[ + pybind11.get_include(), + pybind11.get_include(user=True) + ], + language='c++', + extra_compile_args=common_compile_args + extra_compile_args, + extra_link_args=extra_link_args, + ), +] + +setup( + name="mesh_processor", + ext_modules=ext_modules, + install_requires=['pybind11>=2.6.0'], + python_requires='>=3.6', +) \ No newline at end of file diff --git a/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/pipelines.py b/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/pipelines.py index 7c987cd..00bd8da 100644 --- a/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/pipelines.py +++ b/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/pipelines.py @@ -140,6 +140,40 @@ class Hunyuan3DPaintPipeline: texture = torch.tensor(texture_np / 255).float().to(texture.device) return texture + + def recenter_image(self, image, border_ratio=0.2): + if image.mode == 'RGB': + return image + elif image.mode == 'L': + image = image.convert('RGB') + return image + + alpha_channel = np.array(image)[:, :, 3] + non_zero_indices = np.argwhere(alpha_channel > 0) + if non_zero_indices.size == 0: + raise ValueError("Image is fully transparent") + + min_row, min_col = non_zero_indices.min(axis=0) + max_row, max_col = non_zero_indices.max(axis=0) + + cropped_image = image.crop((min_col, min_row, max_col + 1, max_row + 1)) + + width, height = cropped_image.size + border_width = int(width * border_ratio) + border_height = int(height * border_ratio) + + new_width = width + 2 * border_width + new_height = height + 2 * border_height + + square_size = max(new_width, new_height) + + new_image = Image.new('RGBA', (square_size, square_size), (255, 255, 255, 0)) + + paste_x = (square_size - new_width) // 2 + border_width + paste_y = (square_size - new_height) // 2 + border_height + + new_image.paste(cropped_image, (paste_x, paste_y)) + return new_image @torch.no_grad() def __call__(self, mesh, image): @@ -153,6 +187,7 @@ class Hunyuan3DPaintPipeline: else: image_prompt = image + image_prompt = self.recenter_image(image_prompt) image_prompt = self.models['delight_model'](image_prompt) step_num_i += 1 diff --git a/mesh_processer/mesh_utils.py b/mesh_processer/mesh_utils.py index f631f53..a70b61b 100644 --- a/mesh_processer/mesh_utils.py +++ b/mesh_processer/mesh_utils.py @@ -211,9 +211,22 @@ def poisson_mesh_reconstruction(points, normals=None): def decimate_mesh( - verts, faces, target, backend="pymeshlab", remesh=False, optimalplacement=True + verts, faces, target=5e4, backend="pymeshlab", remesh=False, optimalplacement=True, verbose=True ): - # optimalplacement: default is True, but for flat mesh must turn False to prevent spike artifect. + """ perform mesh decimation. + + Args: + verts (np.ndarray): mesh vertices, float [N, 3] + faces (np.ndarray): mesh faces, int [M, 3] + target (int): targeted number of faces + backend (str, optional): algorithm backend, can be "pymeshlab" or "pyfqmr". Defaults to "pymeshlab". + remesh (bool, optional): whether to remesh after decimation. Defaults to False. + optimalplacement (bool, optional): For flat mesh, use False to prevent spikes. Defaults to True. + verbose (bool, optional): whether to print the decimation process. Defaults to True. + + Returns: + Tuple[np.ndarray]: vertices and faces after decimation. + """ _ori_vert_shape = verts.shape _ori_face_shape = faces.shape @@ -231,7 +244,7 @@ def decimate_mesh( ms.add_mesh(m, "mesh") # will copy! # filters - # ms.meshing_decimation_clustering(threshold=pml.Percentage(1)) + # ms.meshing_decimation_clustering(threshold=pml.PercentageValue(1)) ms.meshing_decimation_quadric_edge_collapse( targetfacenum=int(target), optimalplacement=optimalplacement ) @@ -239,17 +252,17 @@ def decimate_mesh( if remesh: # ms.apply_coord_taubin_smoothing() ms.meshing_isotropic_explicit_remeshing( - iterations=3, targetlen=pml.Percentage(1) + iterations=3, targetlen=pml.PercentageValue(1) ) # extract mesh m = ms.current_mesh() + m.compact() verts = m.vertex_matrix() faces = m.face_matrix() - print( - f"[INFO] mesh decimation: {_ori_vert_shape} --> {verts.shape}, {_ori_face_shape} --> {faces.shape}" - ) + if verbose: + print(f"[INFO] mesh decimation: {_ori_vert_shape} --> {verts.shape}, {_ori_face_shape} --> {faces.shape}") return verts, faces diff --git a/nodes.py b/nodes.py index accc238..b527f33 100644 --- a/nodes.py +++ b/nodes.py @@ -46,6 +46,7 @@ from .mesh_processer.mesh_utils import ( marching_cubes_density_to_mesh, color_func_to_albedo, interpolate_texture_map_attr, + decimate_mesh, ) from FlexiCubes.flexicubes_trainer import FlexiCubesTrainer @@ -608,6 +609,35 @@ class Fast_Clean_Mesh: mesh = Mesh(v=vertices, f=faces, device=DEVICE) return (mesh,) + +class Decimate_Mesh: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "mesh": ("MESH",), + "target": ("INT", {"default": 5e4, "min": 0, "max": 0xffffffffffffffff}), + "remesh": ("BOOLEAN", {"default": True},), + "optimalplacement": ("BOOLEAN", {"default": True},), + }, + } + + RETURN_TYPES = ( + "MESH", + ) + RETURN_NAMES = ( + "mesh", + ) + FUNCTION = "process_mesh" + CATEGORY = "Comfy3D/Preprocessor" + + def process_mesh(self, mesh, target, remesh, optimalplacement): + + vertices, faces = decimate_mesh(mesh.v, mesh.f, target, remesh, optimalplacement) + mesh.v = vertices + mesh.f = faces + + return (mesh,) class Switch_3DGS_Axis: @classmethod diff --git a/pyproject.toml b/pyproject.toml index ddcf166..195d74c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-3d-pack" description = "Make ComfyUI generates 3D assets as good & convenient as it generates image/video!" -version = "0.1.3" +version = "0.1.4" license = { file = "LICENSE" } dynamic = ["dependencies"] [tool.setuptools.dynamic]