diff --git a/comfy_extras/nodes_save_3d.py b/comfy_extras/nodes_save_3d.py index d7afd1713..4441c7684 100644 --- a/comfy_extras/nodes_save_3d.py +++ b/comfy_extras/nodes_save_3d.py @@ -197,7 +197,7 @@ def _compute_vertex_normals(vertices_np, faces_np, crease_angle=None): return (vertices_np[remap], out_faces.astype(np.uint32), normals.astype(np.float32), remap) -def save_glb(vertices, faces, filepath, metadata=None, +def save_glb(vertices, faces, filepath=None, metadata=None, uvs=None, vertex_colors=None, texture_image=None, metallic_roughness_image=None, unlit=False, normals=None, normal_map_image=None, tangents=None, occlusion_in_mr=False, @@ -208,7 +208,7 @@ def save_glb(vertices, faces, filepath, metadata=None, Parameters: vertices: torch.Tensor of shape (N, 3) - The vertex coordinates faces: torch.Tensor of shape (M, 3) - The face indices (triangle faces) - filepath: str - Output filepath (should end with .glb) + filepath: str - Output filepath (should end with .glb). None returns the GLB bytes instead of writing. metadata: dict - Optional asset.extras metadata uvs: torch.Tensor of shape (N, 2) - Optional per-vertex texture coordinates vertex_colors: torch.Tensor of shape (N, 3) or (N, 4) - Optional per-vertex colors in [0, 1] @@ -572,17 +572,48 @@ def save_glb(vertices, faces, filepath, metadata=None, # Create BIN chunk header (chunk type 1) bin_chunk_header = struct.pack(' IO.NodeOutput: + if mesh.vertices.shape[0] > 1: + logging.warning("MeshToFile3D supports one item per batch only. Got %d; using first.", + mesh.vertices.shape[0]) + glb = mesh_item_to_glb_bytes(mesh, 0) + if glb is None: + raise ValueError("MeshToFile3D: mesh is empty (no vertices/faces).") + return IO.NodeOutput(Types.File3D(BytesIO(glb), file_format="glb")) + + class RotateMesh(IO.ComfyNode): class ModeValues(TypedDict, total=False): mode: str @@ -889,7 +897,7 @@ class MeshSmoothNormals(IO.ComfyNode): class Save3DExtension(ComfyExtension): @override async def get_node_list(self) -> list[type[IO.ComfyNode]]: - return [SaveGLB, RotateMesh, MeshSmoothNormals] + return [SaveGLB, MeshToFile3D, RotateMesh, MeshSmoothNormals] async def comfy_entrypoint() -> Save3DExtension: