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
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"]

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_lotus.py",
"nodes_hunyuan3d.py",
"nodes_save_ply.py",
"nodes_save_npz.py",
"nodes_primitive.py",
"nodes_cfg.py",
"nodes_optimalsteps.py",