diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/1.glb b/Gen_3D_Modules/Hunyuan3D_V2/assets/1.glb
deleted file mode 100644
index 0d33b00..0000000
Binary files a/Gen_3D_Modules/Hunyuan3D_V2/assets/1.glb and /dev/null differ
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/demo.png b/Gen_3D_Modules/Hunyuan3D_V2/assets/demo.png
deleted file mode 100755
index 00fda1d..0000000
Binary files a/Gen_3D_Modules/Hunyuan3D_V2/assets/demo.png and /dev/null differ
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/env_maps/gradient.jpg b/Gen_3D_Modules/Hunyuan3D_V2/assets/env_maps/gradient.jpg
deleted file mode 100644
index 55546c1..0000000
Binary files a/Gen_3D_Modules/Hunyuan3D_V2/assets/env_maps/gradient.jpg and /dev/null differ
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/env_maps/white.jpg b/Gen_3D_Modules/Hunyuan3D_V2/assets/env_maps/white.jpg
deleted file mode 100644
index f7af123..0000000
Binary files a/Gen_3D_Modules/Hunyuan3D_V2/assets/env_maps/white.jpg and /dev/null differ
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/example_prompts.txt b/Gen_3D_Modules/Hunyuan3D_V2/assets/example_prompts.txt
deleted file mode 100644
index 5155022..0000000
--- a/Gen_3D_Modules/Hunyuan3D_V2/assets/example_prompts.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-一片绿色的树叶在白色背景上居中展现,清晰的纹理
-一只棕白相间的仓鼠,站在白色背景前。照片采用居中构图方式,卡通风格
-一盆绿色植物生长在红色花盆中,居中,写实
-a pot of green plants grows in a red flower pot.
-a lovely rabbit eating carrots
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/modelviewer-template.html b/Gen_3D_Modules/Hunyuan3D_V2/assets/modelviewer-template.html
deleted file mode 100644
index 3406cb1..0000000
--- a/Gen_3D_Modules/Hunyuan3D_V2/assets/modelviewer-template.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/modelviewer-textured-template.html b/Gen_3D_Modules/Hunyuan3D_V2/assets/modelviewer-textured-template.html
deleted file mode 100644
index 5f84cae..0000000
--- a/Gen_3D_Modules/Hunyuan3D_V2/assets/modelviewer-textured-template.html
+++ /dev/null
@@ -1,136 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/discord.png b/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/discord.png
deleted file mode 100644
index a9c326d..0000000
Binary files a/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/discord.png and /dev/null differ
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/wechat.png b/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/wechat.png
deleted file mode 100755
index 4f25092..0000000
Binary files a/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/wechat.png and /dev/null differ
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/x.png b/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/x.png
deleted file mode 100644
index e9f9044..0000000
Binary files a/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/x.png and /dev/null differ
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/xiaohongshu.png b/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/xiaohongshu.png
deleted file mode 100644
index 7ace644..0000000
Binary files a/Gen_3D_Modules/Hunyuan3D_V2/assets/qrcode/xiaohongshu.png and /dev/null differ
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/shapegen/preprocessors.py b/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/shapegen/preprocessors.py
old mode 100644
new mode 100755
index 2bdaff2..8a9cb9e
--- a/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/shapegen/preprocessors.py
+++ b/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/shapegen/preprocessors.py
@@ -1,12 +1,3 @@
-# Open Source Model Licensed under the Apache License Version 2.0
-# and Other Licenses of the Third-Party Components therein:
-# The below Model in this distribution may have been modified by THL A29 Limited
-# ("Tencent Modifications"). All Tencent Modifications are Copyright (C) 2024 THL A29 Limited.
-# Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved.
-# The below software and/or models in this distribution may have been
-# modified by THL A29 Limited ("Tencent Modifications").
-# All Tencent Modifications are Copyright (C) THL A29 Limited.
-
# Hunyuan 3D is licensed under the TENCENT HUNYUAN NON-COMMERCIAL LICENSE AGREEMENT
# except for the third-party components listed below.
# Hunyuan 3D does not impose any additional limitations beyond what is outlined
@@ -87,7 +78,7 @@ class ImageProcessorV2:
interpolation=cv2.INTER_AREA)
bg = np.ones((result.shape[0], result.shape[1], 3), dtype=np.uint8) * 255
- # bg = np.zeros((result.shape[0], result.shape[1], 3), dtype=np.uint8) * 255
+
mask = result[..., 3:].astype(np.float32) / 255
result = result[..., :3] * mask + bg * (1 - mask)
@@ -96,15 +87,13 @@ class ImageProcessorV2:
mask = mask.clip(0, 255).astype(np.uint8)
return result, mask
- def __call__(self, image, border_ratio=0.15, to_tensor=True, return_mask=False, **kwargs):
- if self.border_ratio is not None:
- border_ratio = self.border_ratio
- print(f"Using border_ratio from init: {border_ratio}")
+ def load_image(self, image, border_ratio=0.15, to_tensor=True):
if isinstance(image, str):
image = cv2.imread(image, cv2.IMREAD_UNCHANGED)
image, mask = self.recenter(image, border_ratio=border_ratio)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
elif isinstance(image, Image.Image):
+ image = image.convert("RGBA")
image = np.asarray(image)
image, mask = self.recenter(image, border_ratio=border_ratio)
@@ -115,13 +104,64 @@ class ImageProcessorV2:
if to_tensor:
image = array_to_tensor(image)
mask = array_to_tensor(mask)
- if return_mask:
- return image, mask
- return image
+ return image, mask
+
+ def __call__(self, image, border_ratio=0.15, to_tensor=True, **kwargs):
+ if self.border_ratio is not None:
+ border_ratio = self.border_ratio
+ image, mask = self.load_image(image, border_ratio=border_ratio, to_tensor=to_tensor)
+ outputs = {
+ 'image': image,
+ 'mask': mask
+ }
+ return outputs
+
+
+class MVImageProcessorV2(ImageProcessorV2):
+ """
+ view order: front, front clockwise 90, back, front clockwise 270
+ """
+ return_view_idx = True
+
+ def __init__(self, size=512, border_ratio=None):
+ super().__init__(size, border_ratio)
+ self.view2idx = {
+ 'front': 0,
+ 'left': 1,
+ 'back': 2,
+ 'right': 3
+ }
+
+ def __call__(self, image_dict, border_ratio=0.15, to_tensor=True, **kwargs):
+ if self.border_ratio is not None:
+ border_ratio = self.border_ratio
+
+ images = []
+ masks = []
+ view_idxs = []
+ for idx, (view_tag, image) in enumerate(image_dict.items()):
+ view_idxs.append(self.view2idx[view_tag])
+ image, mask = self.load_image(image, border_ratio=border_ratio, to_tensor=to_tensor)
+ images.append(image)
+ masks.append(mask)
+
+ zipped_lists = zip(view_idxs, images, masks)
+ sorted_zipped_lists = sorted(zipped_lists)
+ view_idxs, images, masks = zip(*sorted_zipped_lists)
+
+ image = torch.cat(images, 0).unsqueeze(0)
+ mask = torch.cat(masks, 0).unsqueeze(0)
+ outputs = {
+ 'image': image,
+ 'mask': mask,
+ 'view_idxs': view_idxs
+ }
+ return outputs
IMAGE_PROCESSORS = {
"v2": ImageProcessorV2,
+ 'mv_v2': MVImageProcessorV2,
}
DEFAULT_IMAGEPROCESSOR = 'v2'
diff --git a/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/pipelines.py b/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/pipelines.py
index 2110588..33cbebc 100644
--- a/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/pipelines.py
+++ b/Gen_3D_Modules/Hunyuan3D_V2/hy3dgen/texgen/pipelines.py
@@ -53,38 +53,19 @@ class Hunyuan3DTexGenConfig:
class Hunyuan3DPaintPipeline:
@classmethod
def from_pretrained(cls, model_path, subfolder='hunyuan3d-paint-v2-0-turbo'):
- original_model_path = model_path
- if not os.path.exists(model_path):
- # try local path
- base_dir = os.environ.get('HY3DGEN_MODELS', '~/.cache/hy3dgen')
- model_path = os.path.expanduser(os.path.join(base_dir, model_path))
+ delight_model_path = os.path.join(model_path, 'hunyuan3d-delight-v2-0')
+ multiview_model_path = os.path.join(model_path, subfolder)
- delight_model_path = os.path.join(model_path, 'hunyuan3d-delight-v2-0')
- multiview_model_path = os.path.join(model_path, subfolder)
-
- if not os.path.exists(delight_model_path) or not os.path.exists(multiview_model_path):
- try:
- import huggingface_hub
- # download from huggingface
- model_path = huggingface_hub.snapshot_download(
- repo_id=original_model_path, allow_patterns=["hunyuan3d-delight-v2-0/*"]
- )
- model_path = huggingface_hub.snapshot_download(
- repo_id=original_model_path, allow_patterns=[f'{subfolder}/*']
- )
- delight_model_path = os.path.join(model_path, 'hunyuan3d-delight-v2-0')
- multiview_model_path = os.path.join(model_path, subfolder)
- return cls(Hunyuan3DTexGenConfig(delight_model_path, multiview_model_path, subfolder))
- except ImportError:
- logger.warning(
- "You need to install HuggingFace Hub to load models from the hub."
- )
- raise RuntimeError(f"Model path {model_path} not found")
- else:
- return cls(Hunyuan3DTexGenConfig(delight_model_path, multiview_model_path, subfolder))
-
- raise FileNotFoundError(f"Model path {original_model_path} not found and we could not find it at huggingface")
+ if os.path.exists(delight_model_path) and os.path.exists(multiview_model_path):
+ return cls(Hunyuan3DTexGenConfig(
+ delight_model_path,
+ multiview_model_path,
+ subfolder
+ ))
+ raise FileNotFoundError(
+ f"Required models not found in local paths: {delight_model_path} or {multiview_model_path}"
+ )
def __init__(self, config):
self.config = config
self.models = {}
diff --git a/nodes.py b/nodes.py
index 7036f71..794296d 100644
--- a/nodes.py
+++ b/nodes.py
@@ -4330,10 +4330,10 @@ class Load_Hunyuan3D_V2_ShapeGen_Pipeline:
repo, subfolder, def_steps = self._MODES[generation_mode]
use_safe = (weights_format == "safetensors")
pipe = self._build_pipe(repo, subfolder, use_safe, flash_vdm)
- pipe.default_steps = def_steps
+ pipe.num_inference_steps = def_steps
return (pipe,)
-class Load_Hunyuan3D_V2_TexGen_Pipeline:
+class Load_Hunyuan3D_V2_TexGen_Pipeline:
CATEGORY = "Comfy3D/Algorithm"
RETURN_TYPES = ("DIFFUSERS_PIPE",)
RETURN_NAMES = ("texgen_pipe",)
@@ -4348,32 +4348,35 @@ class Load_Hunyuan3D_V2_TexGen_Pipeline:
def INPUT_TYPES(cls):
return {"required": {
"generation_mode": (list(cls.MODEL2REPO.keys()),),
- "weights_format": (["safetensors","ckpt"],),
}}
- @staticmethod
- def _ensure_weights(repo_id: str, subfolder: str, use_safetensors: bool):
- base_dir = os.path.join(CKPT_DIFFUSERS_PATH, repo_id)
- os.makedirs(base_dir, exist_ok=True)
- target_dir = os.path.join(base_dir, subfolder)
- if not os.path.exists(target_dir):
+ def _download_required_weights(self, repo_id, subfolder):
+ ckpt_download_dir = os.path.join(CKPT_DIFFUSERS_PATH, repo_id)
+ os.makedirs(ckpt_download_dir, exist_ok=True)
+
+ # Only download the "delight" and target submodel directories
+ for folder in ["hunyuan3d-delight-v2-0", subfolder]:
snapshot_download(
repo_id=repo_id,
+ local_dir=ckpt_download_dir,
repo_type="model",
- local_dir=base_dir,
- resume_download=True,
- ignore_patterns = HF_DOWNLOAD_IGNORE
+ force_download=False,
+ ignore_patterns=HF_DOWNLOAD_IGNORE
)
- def load(self, generation_mode, weights_format):
- repo_id,subfolder=self.MODEL2REPO[generation_mode]
- Load_Hunyuan3D_V2_TexGen_Pipeline._ensure_weights(repo_id,subfolder,
- weights_format=="safetensors")
- pipe=Hunyuan3DPaintPipeline.from_pretrained(
- model_path=repo_id,
- subfolder=subfolder,
+ def load(self, generation_mode):
+ repo_id, subfolder = self.MODEL2REPO[generation_mode]
+
+ self._download_required_weights(repo_id, subfolder)
+
+ local_repo_dir = os.path.join(CKPT_DIFFUSERS_PATH, repo_id)
+
+ pipe = Hunyuan3DPaintPipeline.from_pretrained(
+ model_path=local_repo_dir,
+ subfolder=subfolder
)
- return (pipe.to("cuda",torch.float16),)
+
+ return (pipe.to("cuda", torch.float16),)
class Hunyuan3D_V2_Paint_Model_Turbo_MV:
"""
@@ -4443,7 +4446,8 @@ class Multi_Background_Remover:
self,
image_front,
image_back=None,
- image_left=None
+ image_left=None,
+ image_right=None
):
rmbg = BackgroundRemover()
@@ -4451,7 +4455,8 @@ class Multi_Background_Remover:
k: v for k, v in {
"front": image_front,
"back": image_back,
- "left": image_left
+ "left": image_left,
+ "right": image_right
}.items() if v is not None
}
@@ -4504,7 +4509,7 @@ class Hunyuan3D_V2_ShapeGen_MV:
if len(images) == 1:
image = images[0]
else:
- directions = ["front", "back", "left"]
+ directions = ["front", "back", "left", "right"]
image = {k: v for k, v in zip(directions, images)}
steps = shapegen_pipe.default_steps if num_inference_steps == 0 else num_inference_steps