diff --git a/comfy_api_sealed_worker/__init__.py b/comfy_api_sealed_worker/__init__.py index 269aa2644..e7e88539f 100644 --- a/comfy_api_sealed_worker/__init__.py +++ b/comfy_api_sealed_worker/__init__.py @@ -2,7 +2,7 @@ Drop-in replacement for comfy_api.latest._util type imports in sealed workers that do not have torch installed. Contains only data type definitions (TrimeshData, -PLY, NPZ, etc.) with numpy-only dependencies. +etc.) with numpy-only dependencies. Usage in serializers: if _IMPORT_TORCH: @@ -12,7 +12,5 @@ Usage in serializers: """ from .trimesh_types import TrimeshData -from .ply_types import PLY -from .npz_types import NPZ -__all__ = ["TrimeshData", "PLY", "NPZ"] +__all__ = ["TrimeshData"] diff --git a/comfy_api_sealed_worker/npz_types.py b/comfy_api_sealed_worker/npz_types.py deleted file mode 100644 index a93eed68c..000000000 --- a/comfy_api_sealed_worker/npz_types.py +++ /dev/null @@ -1,27 +0,0 @@ -from __future__ import annotations - -import os - - -class NPZ: - """Ordered collection of NPZ file payloads. - - Each entry in ``frames`` is a complete compressed ``.npz`` file stored - as raw bytes (produced by ``numpy.savez_compressed`` into a BytesIO). - ``save_to`` writes numbered files into a directory. - """ - - def __init__(self, frames: list[bytes]) -> None: - self.frames = frames - - @property - def num_frames(self) -> int: - return len(self.frames) - - def save_to(self, directory: str, prefix: str = "frame") -> str: - os.makedirs(directory, exist_ok=True) - for i, frame_bytes in enumerate(self.frames): - path = os.path.join(directory, f"{prefix}_{i:06d}.npz") - with open(path, "wb") as f: - f.write(frame_bytes) - return directory diff --git a/comfy_api_sealed_worker/ply_types.py b/comfy_api_sealed_worker/ply_types.py deleted file mode 100644 index 8beb566bc..000000000 --- a/comfy_api_sealed_worker/ply_types.py +++ /dev/null @@ -1,97 +0,0 @@ -from __future__ import annotations - -import numpy as np - - -class PLY: - """Point cloud payload for PLY file output. - - Supports two schemas: - - Pointcloud: xyz positions with optional colors, confidence, view_id (ASCII format) - - Gaussian: raw binary PLY data built by producer nodes using plyfile (binary format) - - When ``raw_data`` is provided, the object acts as an opaque binary PLY - carrier and ``save_to`` writes the bytes directly. - """ - - def __init__( - self, - points: np.ndarray | None = None, - colors: np.ndarray | None = None, - confidence: np.ndarray | None = None, - view_id: np.ndarray | None = None, - raw_data: bytes | None = None, - ) -> None: - self.raw_data = raw_data - if raw_data is not None: - self.points = None - self.colors = None - self.confidence = None - self.view_id = None - return - if points is None: - raise ValueError("Either points or raw_data must be provided") - if points.ndim != 2 or points.shape[1] != 3: - raise ValueError(f"points must be (N, 3), got {points.shape}") - self.points = np.ascontiguousarray(points, dtype=np.float32) - self.colors = np.ascontiguousarray(colors, dtype=np.float32) if colors is not None else None - self.confidence = np.ascontiguousarray(confidence, dtype=np.float32) if confidence is not None else None - self.view_id = np.ascontiguousarray(view_id, dtype=np.int32) if view_id is not None else None - - @property - def is_gaussian(self) -> bool: - return self.raw_data is not None - - @property - def num_points(self) -> int: - if self.points is not None: - return self.points.shape[0] - return 0 - - @staticmethod - def _to_numpy(arr, dtype): - if arr is None: - return None - if hasattr(arr, "numpy"): - arr = arr.cpu().numpy() if hasattr(arr, "cpu") else arr.numpy() - return np.ascontiguousarray(arr, dtype=dtype) - - def save_to(self, path: str) -> str: - if self.raw_data is not None: - with open(path, "wb") as f: - f.write(self.raw_data) - return path - self.points = self._to_numpy(self.points, np.float32) - self.colors = self._to_numpy(self.colors, np.float32) - self.confidence = self._to_numpy(self.confidence, np.float32) - self.view_id = self._to_numpy(self.view_id, np.int32) - N = self.num_points - header_lines = [ - "ply", - "format ascii 1.0", - f"element vertex {N}", - "property float x", - "property float y", - "property float z", - ] - if self.colors is not None: - header_lines += ["property uchar red", "property uchar green", "property uchar blue"] - if self.confidence is not None: - header_lines.append("property float confidence") - if self.view_id is not None: - header_lines.append("property int view_id") - header_lines.append("end_header") - - with open(path, "w") as f: - f.write("\n".join(header_lines) + "\n") - for i in range(N): - parts = [f"{self.points[i, 0]} {self.points[i, 1]} {self.points[i, 2]}"] - if self.colors is not None: - r, g, b = (self.colors[i] * 255).clip(0, 255).astype(np.uint8) - parts.append(f"{r} {g} {b}") - if self.confidence is not None: - parts.append(f"{self.confidence[i]}") - if self.view_id is not None: - parts.append(f"{int(self.view_id[i])}") - f.write(" ".join(parts) + "\n") - return path diff --git a/comfy_extras/nodes_save_npz.py b/comfy_extras/nodes_save_npz.py deleted file mode 100644 index fb9e4c877..000000000 --- a/comfy_extras/nodes_save_npz.py +++ /dev/null @@ -1,40 +0,0 @@ -import os - -import folder_paths -from comfy_api.latest import io -from comfy_api_sealed_worker.npz_types import NPZ - - -class SaveNPZ(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="SaveNPZ", - display_name="Save NPZ", - category="3d", - is_output_node=True, - inputs=[ - io.Npz.Input("npz"), - io.String.Input("filename_prefix", default="da3_streaming/ComfyUI"), - ], - ) - - @classmethod - def execute(cls, npz: NPZ, filename_prefix: str) -> io.NodeOutput: - full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path( - filename_prefix, folder_paths.get_output_directory() - ) - batch_dir = os.path.join(full_output_folder, f"{filename}_{counter:05}") - os.makedirs(batch_dir, exist_ok=True) - filenames = [] - for i, frame_bytes in enumerate(npz.frames): - f = f"frame_{i:06d}.npz" - with open(os.path.join(batch_dir, f), "wb") as fh: - fh.write(frame_bytes) - filenames.append(f) - return io.NodeOutput(ui={"npz_files": [{"folder": os.path.join(subfolder, f"{filename}_{counter:05}"), "count": len(filenames), "type": "output"}]}) - - -NODE_CLASS_MAPPINGS = { - "SaveNPZ": SaveNPZ, -} diff --git a/comfy_extras/nodes_save_ply.py b/comfy_extras/nodes_save_ply.py deleted file mode 100644 index 64c32e4de..000000000 --- a/comfy_extras/nodes_save_ply.py +++ /dev/null @@ -1,34 +0,0 @@ -import os - -import folder_paths -from comfy_api.latest import io -from comfy_api_sealed_worker.ply_types import PLY - - -class SavePLY(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="SavePLY", - display_name="Save PLY", - category="3d", - is_output_node=True, - inputs=[ - io.Ply.Input("ply"), - io.String.Input("filename_prefix", default="pointcloud/ComfyUI"), - ], - ) - - @classmethod - def execute(cls, ply: PLY, filename_prefix: str) -> io.NodeOutput: - full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path( - filename_prefix, folder_paths.get_output_directory() - ) - f = f"{filename}_{counter:05}_.ply" - ply.save_to(os.path.join(full_output_folder, f)) - return io.NodeOutput(ui={"pointclouds": [{"filename": f, "subfolder": subfolder, "type": "output"}]}) - - -NODE_CLASS_MAPPINGS = { - "SavePLY": SavePLY, -} diff --git a/nodes.py b/nodes.py index f05d15793..4a5adc5a4 100644 --- a/nodes.py +++ b/nodes.py @@ -2459,8 +2459,6 @@ async def init_builtin_extra_nodes(): "nodes_wan.py", "nodes_lotus.py", "nodes_hunyuan3d.py", - "nodes_save_ply.py", - "nodes_save_npz.py", "nodes_primitive.py", "nodes_cfg.py", "nodes_optimalsteps.py",