remove(isolation): drop internal ply and npz support

This commit is contained in:
John Pollock 2026-04-12 21:08:47 -05:00
parent b1bcaaf8fe
commit 3b0fc0ab87
6 changed files with 2 additions and 204 deletions

View File

@ -2,7 +2,7 @@
Drop-in replacement for comfy_api.latest._util type imports in sealed workers 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, 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: Usage in serializers:
if _IMPORT_TORCH: if _IMPORT_TORCH:
@ -12,7 +12,5 @@ Usage in serializers:
""" """
from .trimesh_types import TrimeshData from .trimesh_types import TrimeshData
from .ply_types import PLY
from .npz_types import NPZ
__all__ = ["TrimeshData", "PLY", "NPZ"] __all__ = ["TrimeshData"]

View File

@ -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

View File

@ -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

View File

@ -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,
}

View File

@ -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,
}

View File

@ -2459,8 +2459,6 @@ async def init_builtin_extra_nodes():
"nodes_wan.py", "nodes_wan.py",
"nodes_lotus.py", "nodes_lotus.py",
"nodes_hunyuan3d.py", "nodes_hunyuan3d.py",
"nodes_save_ply.py",
"nodes_save_npz.py",
"nodes_primitive.py", "nodes_primitive.py",
"nodes_cfg.py", "nodes_cfg.py",
"nodes_optimalsteps.py", "nodes_optimalsteps.py",