mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-06-01 20:07:37 +08:00
feat: add PreviewGaussianSplat + PreviewPointCloud nodes
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
Python Linting / Run Pylint (push) Waiting to run
Build package / Build Test (3.10) (push) Waiting to run
Build package / Build Test (3.11) (push) Waiting to run
Build package / Build Test (3.12) (push) Waiting to run
Build package / Build Test (3.13) (push) Waiting to run
Build package / Build Test (3.14) (push) Waiting to run
Some checks are pending
Python Linting / Run Ruff (push) Waiting to run
Python Linting / Run Pylint (push) Waiting to run
Build package / Build Test (3.10) (push) Waiting to run
Build package / Build Test (3.11) (push) Waiting to run
Build package / Build Test (3.12) (push) Waiting to run
Build package / Build Test (3.13) (push) Waiting to run
Build package / Build Test (3.14) (push) Waiting to run
This commit is contained in:
parent
c37d2a0dac
commit
f1c41bf4cf
@ -755,6 +755,18 @@ class File3DKSPLAT(ComfyTypeIO):
|
|||||||
Type = File3D
|
Type = File3D
|
||||||
|
|
||||||
|
|
||||||
|
@comfytype(io_type="FILE_3D_SPLAT_ANY")
|
||||||
|
class File3DSplatAny(ComfyTypeIO):
|
||||||
|
"""General 3D Gaussian splat file type - accepts any supported splat container (.ply / .spz / .splat / .ksplat)."""
|
||||||
|
Type = File3D
|
||||||
|
|
||||||
|
|
||||||
|
@comfytype(io_type="FILE_3D_POINT_CLOUD_ANY")
|
||||||
|
class File3DPointCloudAny(ComfyTypeIO):
|
||||||
|
"""General point cloud file type - accepts any supported point cloud container (currently .ply)."""
|
||||||
|
Type = File3D
|
||||||
|
|
||||||
|
|
||||||
@comfytype(io_type="HOOKS")
|
@comfytype(io_type="HOOKS")
|
||||||
class Hooks(ComfyTypeIO):
|
class Hooks(ComfyTypeIO):
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -2336,6 +2348,8 @@ __all__ = [
|
|||||||
"File3DSPLAT",
|
"File3DSPLAT",
|
||||||
"File3DSPZ",
|
"File3DSPZ",
|
||||||
"File3DKSPLAT",
|
"File3DKSPLAT",
|
||||||
|
"File3DSplatAny",
|
||||||
|
"File3DPointCloudAny",
|
||||||
"Hooks",
|
"Hooks",
|
||||||
"HookKeyframes",
|
"HookKeyframes",
|
||||||
"TimestepsRange",
|
"TimestepsRange",
|
||||||
|
|||||||
@ -488,7 +488,7 @@ class SplatToFile3D(IO.ComfyNode):
|
|||||||
"spz: Niantic gzip-compressed (~10x smaller), base color only "
|
"spz: Niantic gzip-compressed (~10x smaller), base color only "
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
outputs=[IO.File3DAny.Output(display_name="model_3d")],
|
outputs=[IO.File3DSplatAny.Output(display_name="model_3d")],
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -516,7 +516,7 @@ class File3DToSplat(IO.ComfyNode):
|
|||||||
inputs=[
|
inputs=[
|
||||||
IO.MultiType.Input(
|
IO.MultiType.Input(
|
||||||
IO.File3DAny.Input("model_3d"),
|
IO.File3DAny.Input("model_3d"),
|
||||||
types=[IO.File3DPLY, IO.File3DSPLAT, IO.File3DKSPLAT, IO.File3DSPZ],
|
types=[IO.File3DSplatAny, IO.File3DPLY, IO.File3DSPLAT, IO.File3DKSPLAT, IO.File3DSPZ],
|
||||||
tooltip="A gaussian splat 3D file",
|
tooltip="A gaussian splat 3D file",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -182,6 +182,133 @@ class Preview3DAdvanced(IO.ComfyNode):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PreviewGaussianSplat(IO.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return IO.Schema(
|
||||||
|
node_id="PreviewGaussianSplat",
|
||||||
|
display_name="Preview Gaussian Splat",
|
||||||
|
category="3d",
|
||||||
|
is_experimental=True,
|
||||||
|
is_output_node=True,
|
||||||
|
search_aliases=[
|
||||||
|
"view splat",
|
||||||
|
"view gaussian",
|
||||||
|
"view gaussian splat",
|
||||||
|
"preview gaussian",
|
||||||
|
"preview gaussian splat",
|
||||||
|
"view 3dgs",
|
||||||
|
"preview 3dgs",
|
||||||
|
"preview ply",
|
||||||
|
"preview spz",
|
||||||
|
"preview splat",
|
||||||
|
"preview ksplat",
|
||||||
|
],
|
||||||
|
inputs=[
|
||||||
|
IO.MultiType.Input(
|
||||||
|
"model_file",
|
||||||
|
types=[
|
||||||
|
IO.File3DSplatAny,
|
||||||
|
IO.File3DPLY,
|
||||||
|
IO.File3DSPLAT,
|
||||||
|
IO.File3DSPZ,
|
||||||
|
IO.File3DKSPLAT,
|
||||||
|
],
|
||||||
|
tooltip="3D Gaussian splat file (.ply / .spz / .splat / .ksplat)",
|
||||||
|
),
|
||||||
|
IO.Load3D.Input("image"),
|
||||||
|
IO.Load3DCamera.Input("camera_info", optional=True, advanced=True),
|
||||||
|
IO.Load3DModelInfo.Input("model_3d_info", optional=True, advanced=True),
|
||||||
|
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.File3DSplatAny.Output(display_name="model_file"),
|
||||||
|
IO.Load3DCamera.Output(display_name="camera_info"),
|
||||||
|
IO.Load3DModelInfo.Output(display_name="model_3d_info"),
|
||||||
|
IO.Int.Output(display_name="width"),
|
||||||
|
IO.Int.Output(display_name="height"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, model_file: Types.File3D, image, width: int, height: int, **kwargs) -> IO.NodeOutput:
|
||||||
|
filename = f"preview_splat_{uuid.uuid4().hex}.{model_file.format}"
|
||||||
|
model_file.save_to(os.path.join(folder_paths.get_output_directory(), filename))
|
||||||
|
|
||||||
|
camera_info_input = kwargs.get("camera_info", None)
|
||||||
|
camera_info = camera_info_input if camera_info_input is not None else image['camera_info']
|
||||||
|
model_3d_info_input = kwargs.get("model_3d_info", None)
|
||||||
|
model_3d_info = model_3d_info_input if model_3d_info_input is not None else image.get('model_3d_info', [])
|
||||||
|
return IO.NodeOutput(
|
||||||
|
model_file,
|
||||||
|
camera_info,
|
||||||
|
model_3d_info,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
ui=UI.PreviewUI3DAdvanced(filename, camera_info, model_3d_info),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PreviewPointCloud(IO.ComfyNode):
|
||||||
|
@classmethod
|
||||||
|
def define_schema(cls):
|
||||||
|
return IO.Schema(
|
||||||
|
node_id="PreviewPointCloud",
|
||||||
|
display_name="Preview Point Cloud",
|
||||||
|
category="3d",
|
||||||
|
is_experimental=True,
|
||||||
|
is_output_node=True,
|
||||||
|
search_aliases=[
|
||||||
|
"view point cloud",
|
||||||
|
"view pointcloud",
|
||||||
|
"preview point cloud",
|
||||||
|
"preview pointcloud",
|
||||||
|
"preview ply",
|
||||||
|
],
|
||||||
|
inputs=[
|
||||||
|
IO.MultiType.Input(
|
||||||
|
"model_file",
|
||||||
|
types=[
|
||||||
|
IO.File3DPointCloudAny,
|
||||||
|
IO.File3DPLY,
|
||||||
|
],
|
||||||
|
tooltip="Point cloud file (.ply)",
|
||||||
|
),
|
||||||
|
IO.Load3D.Input("image"),
|
||||||
|
IO.Load3DCamera.Input("camera_info", optional=True, advanced=True),
|
||||||
|
IO.Load3DModelInfo.Input("model_3d_info", optional=True, advanced=True),
|
||||||
|
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.File3DPointCloudAny.Output(display_name="model_file"),
|
||||||
|
IO.Load3DCamera.Output(display_name="camera_info"),
|
||||||
|
IO.Load3DModelInfo.Output(display_name="model_3d_info"),
|
||||||
|
IO.Int.Output(display_name="width"),
|
||||||
|
IO.Int.Output(display_name="height"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, model_file: Types.File3D, image, width: int, height: int, **kwargs) -> IO.NodeOutput:
|
||||||
|
filename = f"preview_pointcloud_{uuid.uuid4().hex}.{model_file.format}"
|
||||||
|
model_file.save_to(os.path.join(folder_paths.get_output_directory(), filename))
|
||||||
|
|
||||||
|
camera_info_input = kwargs.get("camera_info", None)
|
||||||
|
camera_info = camera_info_input if camera_info_input is not None else image['camera_info']
|
||||||
|
model_3d_info_input = kwargs.get("model_3d_info", None)
|
||||||
|
model_3d_info = model_3d_info_input if model_3d_info_input is not None else image.get('model_3d_info', [])
|
||||||
|
return IO.NodeOutput(
|
||||||
|
model_file,
|
||||||
|
camera_info,
|
||||||
|
model_3d_info,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
ui=UI.PreviewUI3DAdvanced(filename, camera_info, model_3d_info),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Load3DExtension(ComfyExtension):
|
class Load3DExtension(ComfyExtension):
|
||||||
@override
|
@override
|
||||||
async def get_node_list(self) -> list[type[IO.ComfyNode]]:
|
async def get_node_list(self) -> list[type[IO.ComfyNode]]:
|
||||||
@ -189,6 +316,8 @@ class Load3DExtension(ComfyExtension):
|
|||||||
Load3D,
|
Load3D,
|
||||||
Preview3D,
|
Preview3D,
|
||||||
Preview3DAdvanced,
|
Preview3DAdvanced,
|
||||||
|
PreviewGaussianSplat,
|
||||||
|
PreviewPointCloud,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user