mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-07-27 08:16:44 +00:00
181 lines
6.5 KiB
Python
181 lines
6.5 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import folder_paths
|
|
import nodes
|
|
from comfy_api.input_impl import VideoFromFile
|
|
from comfy_api.latest import io, ui
|
|
|
|
|
|
def normalize_path(path):
|
|
return path.replace("\\", "/")
|
|
|
|
|
|
class Load3D(io.ComfyNode):
|
|
@classmethod
|
|
def define_schema(cls):
|
|
input_dir = os.path.join(folder_paths.get_input_directory(), "3d")
|
|
|
|
os.makedirs(input_dir, exist_ok=True)
|
|
|
|
input_path = Path(input_dir)
|
|
base_path = Path(folder_paths.get_input_directory())
|
|
|
|
files = [
|
|
normalize_path(str(file_path.relative_to(base_path)))
|
|
for file_path in input_path.rglob("*")
|
|
if file_path.suffix.lower() in {".gltf", ".glb", ".obj", ".fbx", ".stl"}
|
|
]
|
|
|
|
return io.Schema(
|
|
node_id="Load3D_V3",
|
|
display_name="Load 3D _V3",
|
|
category="3d",
|
|
is_experimental=True,
|
|
inputs=[
|
|
io.Combo.Input("model_file", options=sorted(files), upload=io.UploadType.model),
|
|
io.Load3D.Input("image"),
|
|
io.Int.Input("width", default=1024, min=1, max=4096, step=1),
|
|
io.Int.Input("height", default=1024, min=1, max=4096, step=1),
|
|
],
|
|
outputs=[
|
|
io.Image.Output(display_name="image"),
|
|
io.Mask.Output(display_name="mask"),
|
|
io.String.Output(display_name="mesh_path"),
|
|
io.Image.Output(display_name="normal"),
|
|
io.Image.Output(display_name="lineart"),
|
|
io.Load3DCamera.Output(display_name="camera_info"),
|
|
io.Video.Output(display_name="recording_video"),
|
|
],
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, model_file, image, **kwargs):
|
|
image_path = folder_paths.get_annotated_filepath(image["image"])
|
|
mask_path = folder_paths.get_annotated_filepath(image["mask"])
|
|
normal_path = folder_paths.get_annotated_filepath(image["normal"])
|
|
lineart_path = folder_paths.get_annotated_filepath(image["lineart"])
|
|
|
|
load_image_node = nodes.LoadImage()
|
|
output_image, ignore_mask = load_image_node.load_image(image=image_path)
|
|
ignore_image, output_mask = load_image_node.load_image(image=mask_path)
|
|
normal_image, ignore_mask2 = load_image_node.load_image(image=normal_path)
|
|
lineart_image, ignore_mask3 = load_image_node.load_image(image=lineart_path)
|
|
|
|
video = None
|
|
if image["recording"] != "":
|
|
recording_video_path = folder_paths.get_annotated_filepath(image["recording"])
|
|
video = VideoFromFile(recording_video_path)
|
|
|
|
return io.NodeOutput(
|
|
output_image, output_mask, model_file, normal_image, lineart_image, image["camera_info"], video
|
|
)
|
|
|
|
|
|
class Load3DAnimation(io.ComfyNode):
|
|
@classmethod
|
|
def define_schema(cls):
|
|
input_dir = os.path.join(folder_paths.get_input_directory(), "3d")
|
|
|
|
os.makedirs(input_dir, exist_ok=True)
|
|
|
|
input_path = Path(input_dir)
|
|
base_path = Path(folder_paths.get_input_directory())
|
|
|
|
files = [
|
|
normalize_path(str(file_path.relative_to(base_path)))
|
|
for file_path in input_path.rglob("*")
|
|
if file_path.suffix.lower() in {".gltf", ".glb", ".fbx"}
|
|
]
|
|
|
|
return io.Schema(
|
|
node_id="Load3DAnimation_V3",
|
|
display_name="Load 3D - Animation _V3",
|
|
category="3d",
|
|
is_experimental=True,
|
|
inputs=[
|
|
io.Combo.Input("model_file", options=sorted(files), upload=io.UploadType.model),
|
|
io.Load3DAnimation.Input("image"),
|
|
io.Int.Input("width", default=1024, min=1, max=4096, step=1),
|
|
io.Int.Input("height", default=1024, min=1, max=4096, step=1),
|
|
],
|
|
outputs=[
|
|
io.Image.Output(display_name="image"),
|
|
io.Mask.Output(display_name="mask"),
|
|
io.String.Output(display_name="mesh_path"),
|
|
io.Image.Output(display_name="normal"),
|
|
io.Load3DCamera.Output(display_name="camera_info"),
|
|
io.Video.Output(display_name="recording_video"),
|
|
],
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, model_file, image, **kwargs):
|
|
image_path = folder_paths.get_annotated_filepath(image["image"])
|
|
mask_path = folder_paths.get_annotated_filepath(image["mask"])
|
|
normal_path = folder_paths.get_annotated_filepath(image["normal"])
|
|
|
|
load_image_node = nodes.LoadImage()
|
|
output_image, ignore_mask = load_image_node.load_image(image=image_path)
|
|
ignore_image, output_mask = load_image_node.load_image(image=mask_path)
|
|
normal_image, ignore_mask2 = load_image_node.load_image(image=normal_path)
|
|
|
|
video = None
|
|
if image['recording'] != "":
|
|
recording_video_path = folder_paths.get_annotated_filepath(image["recording"])
|
|
video = VideoFromFile(recording_video_path)
|
|
|
|
return io.NodeOutput(output_image, output_mask, model_file, normal_image, image["camera_info"], video)
|
|
|
|
|
|
class Preview3D(io.ComfyNode):
|
|
@classmethod
|
|
def define_schema(cls):
|
|
return io.Schema(
|
|
node_id="Preview3D_V3", # frontend expects "Preview3D" to work
|
|
display_name="Preview 3D _V3",
|
|
category="3d",
|
|
is_experimental=True,
|
|
is_output_node=True,
|
|
inputs=[
|
|
io.String.Input("model_file", default="", multiline=False),
|
|
io.Load3DCamera.Input("camera_info", optional=True),
|
|
],
|
|
outputs=[],
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, model_file, camera_info=None):
|
|
return io.NodeOutput(ui=ui.PreviewUI3D(model_file, camera_info, cls=cls))
|
|
|
|
|
|
class Preview3DAnimation(io.ComfyNode):
|
|
@classmethod
|
|
def define_schema(cls):
|
|
return io.Schema(
|
|
node_id="Preview3DAnimation_V3", # frontend expects "Preview3DAnimation" to work
|
|
display_name="Preview 3D - Animation _V3",
|
|
category="3d",
|
|
is_experimental=True,
|
|
is_output_node=True,
|
|
inputs=[
|
|
io.String.Input("model_file", default="", multiline=False),
|
|
io.Load3DCamera.Input("camera_info", optional=True),
|
|
],
|
|
outputs=[],
|
|
)
|
|
|
|
@classmethod
|
|
def execute(cls, model_file, camera_info=None):
|
|
return io.NodeOutput(ui=ui.PreviewUI3D(model_file, camera_info, cls=cls))
|
|
|
|
|
|
NODES_LIST: list[type[io.ComfyNode]] = [
|
|
Load3D,
|
|
Load3DAnimation,
|
|
Preview3D,
|
|
Preview3DAnimation,
|
|
]
|