Skip to content

Commit 58c6ed5

Browse files
authored
Merge 3d animation node (#10025)
1 parent 234c3dc commit 58c6ed5

File tree

1 file changed

+19
-83
lines changed

1 file changed

+19
-83
lines changed

comfy_extras/nodes_load_3d.py

Lines changed: 19 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
from pathlib import Path
99

10+
from PIL import Image
11+
import numpy as np
12+
13+
import uuid
1014

1115
def normalize_path(path):
1216
return path.replace('\\', '/')
@@ -34,58 +38,6 @@ def INPUT_TYPES(s):
3438
"height": ("INT", {"default": 1024, "min": 1, "max": 4096, "step": 1}),
3539
}}
3640

37-
RETURN_TYPES = ("IMAGE", "MASK", "STRING", "IMAGE", "IMAGE", "LOAD3D_CAMERA", IO.VIDEO)
38-
RETURN_NAMES = ("image", "mask", "mesh_path", "normal", "lineart", "camera_info", "recording_video")
39-
40-
FUNCTION = "process"
41-
EXPERIMENTAL = True
42-
43-
CATEGORY = "3d"
44-
45-
def process(self, model_file, image, **kwargs):
46-
image_path = folder_paths.get_annotated_filepath(image['image'])
47-
mask_path = folder_paths.get_annotated_filepath(image['mask'])
48-
normal_path = folder_paths.get_annotated_filepath(image['normal'])
49-
lineart_path = folder_paths.get_annotated_filepath(image['lineart'])
50-
51-
load_image_node = nodes.LoadImage()
52-
output_image, ignore_mask = load_image_node.load_image(image=image_path)
53-
ignore_image, output_mask = load_image_node.load_image(image=mask_path)
54-
normal_image, ignore_mask2 = load_image_node.load_image(image=normal_path)
55-
lineart_image, ignore_mask3 = load_image_node.load_image(image=lineart_path)
56-
57-
video = None
58-
59-
if image['recording'] != "":
60-
recording_video_path = folder_paths.get_annotated_filepath(image['recording'])
61-
62-
video = VideoFromFile(recording_video_path)
63-
64-
return output_image, output_mask, model_file, normal_image, lineart_image, image['camera_info'], video
65-
66-
class Load3DAnimation():
67-
@classmethod
68-
def INPUT_TYPES(s):
69-
input_dir = os.path.join(folder_paths.get_input_directory(), "3d")
70-
71-
os.makedirs(input_dir, exist_ok=True)
72-
73-
input_path = Path(input_dir)
74-
base_path = Path(folder_paths.get_input_directory())
75-
76-
files = [
77-
normalize_path(str(file_path.relative_to(base_path)))
78-
for file_path in input_path.rglob("*")
79-
if file_path.suffix.lower() in {'.gltf', '.glb', '.fbx'}
80-
]
81-
82-
return {"required": {
83-
"model_file": (sorted(files), {"file_upload": True}),
84-
"image": ("LOAD_3D_ANIMATION", {}),
85-
"width": ("INT", {"default": 1024, "min": 1, "max": 4096, "step": 1}),
86-
"height": ("INT", {"default": 1024, "min": 1, "max": 4096, "step": 1}),
87-
}}
88-
8941
RETURN_TYPES = ("IMAGE", "MASK", "STRING", "IMAGE", "LOAD3D_CAMERA", IO.VIDEO)
9042
RETURN_NAMES = ("image", "mask", "mesh_path", "normal", "camera_info", "recording_video")
9143

@@ -120,7 +72,8 @@ def INPUT_TYPES(s):
12072
"model_file": ("STRING", {"default": "", "multiline": False}),
12173
},
12274
"optional": {
123-
"camera_info": ("LOAD3D_CAMERA", {})
75+
"camera_info": ("LOAD3D_CAMERA", {}),
76+
"bg_image": ("IMAGE", {})
12477
}}
12578

12679
OUTPUT_NODE = True
@@ -133,50 +86,33 @@ def INPUT_TYPES(s):
13386

13487
def process(self, model_file, **kwargs):
13588
camera_info = kwargs.get("camera_info", None)
89+
bg_image = kwargs.get("bg_image", None)
13690

137-
return {
138-
"ui": {
139-
"result": [model_file, camera_info]
140-
}
141-
}
142-
143-
class Preview3DAnimation():
144-
@classmethod
145-
def INPUT_TYPES(s):
146-
return {"required": {
147-
"model_file": ("STRING", {"default": "", "multiline": False}),
148-
},
149-
"optional": {
150-
"camera_info": ("LOAD3D_CAMERA", {})
151-
}}
152-
153-
OUTPUT_NODE = True
154-
RETURN_TYPES = ()
91+
bg_image_path = None
92+
if bg_image is not None:
15593

156-
CATEGORY = "3d"
94+
img_array = (bg_image[0].cpu().numpy() * 255).astype(np.uint8)
95+
img = Image.fromarray(img_array)
15796

158-
FUNCTION = "process"
159-
EXPERIMENTAL = True
97+
temp_dir = folder_paths.get_temp_directory()
98+
filename = f"bg_{uuid.uuid4().hex}.png"
99+
bg_image_path = os.path.join(temp_dir, filename)
100+
img.save(bg_image_path, compress_level=1)
160101

161-
def process(self, model_file, **kwargs):
162-
camera_info = kwargs.get("camera_info", None)
102+
bg_image_path = f"temp/{filename}"
163103

164104
return {
165105
"ui": {
166-
"result": [model_file, camera_info]
106+
"result": [model_file, camera_info, bg_image_path]
167107
}
168108
}
169109

170110
NODE_CLASS_MAPPINGS = {
171111
"Load3D": Load3D,
172-
"Load3DAnimation": Load3DAnimation,
173112
"Preview3D": Preview3D,
174-
"Preview3DAnimation": Preview3DAnimation
175113
}
176114

177115
NODE_DISPLAY_NAME_MAPPINGS = {
178-
"Load3D": "Load 3D",
179-
"Load3DAnimation": "Load 3D - Animation",
180-
"Preview3D": "Preview 3D",
181-
"Preview3DAnimation": "Preview 3D - Animation"
116+
"Load3D": "Load 3D & Animation",
117+
"Preview3D": "Preview 3D & Animation",
182118
}

0 commit comments

Comments
 (0)