address PR review feedback:

- Rename File3D parameter 'path' to 'source'
- Convert File3D.data property to get_data()
- Make .glb extension check case-insensitive in nodes_rodin.py
- Restrict SaveGLB node to only accept File3DGLB
This commit is contained in:
bigcat88 2026-02-03 15:06:46 +02:00
parent c18aed33d6
commit c51b30de9c
4 changed files with 34 additions and 36 deletions

View File

@ -23,13 +23,13 @@ class File3D:
Supports both disk-backed (file path) and memory-backed (BytesIO) storage. Supports both disk-backed (file path) and memory-backed (BytesIO) storage.
""" """
def __init__(self, path: str | IO[bytes], file_format: str = ""): def __init__(self, source: str | IO[bytes], file_format: str = ""):
self._path = path self._source = source
self._format = file_format or self._infer_format() self._format = file_format or self._infer_format()
def _infer_format(self) -> str: def _infer_format(self) -> str:
if isinstance(self._path, str): if isinstance(self._source, str):
return Path(self._path).suffix.lstrip(".").lower() return Path(self._source).suffix.lstrip(".").lower()
return "" return ""
@property @property
@ -42,49 +42,48 @@ class File3D:
@property @property
def is_disk_backed(self) -> bool: def is_disk_backed(self) -> bool:
return isinstance(self._path, str) return isinstance(self._source, str)
def get_source(self) -> str | IO[bytes]: def get_source(self) -> str | IO[bytes]:
if isinstance(self._path, str): if isinstance(self._source, str):
return self._path return self._source
if hasattr(self._path, "seek"): if hasattr(self._source, "seek"):
self._path.seek(0) self._source.seek(0)
return self._path return self._source
@property def get_data(self) -> BytesIO:
def data(self) -> BytesIO: if isinstance(self._source, str):
if isinstance(self._path, str): with open(self._source, "rb") as f:
with open(self._path, "rb") as f:
result = BytesIO(f.read()) result = BytesIO(f.read())
return result return result
if hasattr(self._path, "seek"): if hasattr(self._source, "seek"):
self._path.seek(0) self._source.seek(0)
if isinstance(self._path, BytesIO): if isinstance(self._source, BytesIO):
return self._path return self._source
return BytesIO(self._path.read()) return BytesIO(self._source.read())
def save_to(self, path: str) -> str: def save_to(self, path: str) -> str:
dest = Path(path) dest = Path(path)
dest.parent.mkdir(parents=True, exist_ok=True) dest.parent.mkdir(parents=True, exist_ok=True)
if isinstance(self._path, str): if isinstance(self._source, str):
if Path(self._path).resolve() != dest.resolve(): if Path(self._source).resolve() != dest.resolve():
shutil.copy2(self._path, dest) shutil.copy2(self._source, dest)
else: else:
if hasattr(self._path, "seek"): if hasattr(self._source, "seek"):
self._path.seek(0) self._source.seek(0)
with open(dest, "wb") as f: with open(dest, "wb") as f:
f.write(self._path.read()) f.write(self._source.read())
return str(dest) return str(dest)
def get_bytes(self) -> bytes: def get_bytes(self) -> bytes:
if isinstance(self._path, str): if isinstance(self._source, str):
return Path(self._path).read_bytes() return Path(self._source).read_bytes()
if hasattr(self._path, "seek"): if hasattr(self._source, "seek"):
self._path.seek(0) self._source.seek(0)
return self._path.read() return self._source.read()
def __repr__(self) -> str: def __repr__(self) -> str:
if isinstance(self._path, str): if isinstance(self._source, str):
return f"File3D(path={self._path!r}, format={self._format!r})" return f"File3D(source={self._source!r}, format={self._format!r})"
return f"File3D(<stream>, format={self._format!r})" return f"File3D(<stream>, format={self._format!r})"

View File

@ -216,7 +216,7 @@ async def download_files(url_list, task_uuid: str) -> tuple[str | None, Types.Fi
for i in url_list.list: for i in url_list.list:
file_path = os.path.join(save_path, i.name) file_path = os.path.join(save_path, i.name)
if i.name.endswith(".glb"): if i.name.lower().endswith(".glb"):
model_file_path = os.path.join(result_folder_name, i.name) model_file_path = os.path.join(result_folder_name, i.name)
file_3d = await download_url_to_file_3d(i.url, "glb") file_3d = await download_url_to_file_3d(i.url, "glb")
# Save to disk for backward compatibility # Save to disk for backward compatibility

View File

@ -296,4 +296,4 @@ async def download_url_to_file_3d(
output_path.write_bytes(data.getvalue()) output_path.write_bytes(data.getvalue())
data.seek(0) data.seek(0)
return Types.File3D(path=data, file_format=file_format) return Types.File3D(source=data, file_format=file_format)

View File

@ -626,9 +626,8 @@ class SaveGLB(IO.ComfyNode):
IO.Mesh.Input("mesh"), IO.Mesh.Input("mesh"),
types=[ types=[
IO.File3DGLB, IO.File3DGLB,
IO.File3DAny,
], ],
tooltip="Mesh or 3D file to save as GLB", tooltip="Mesh or GLB file to save",
), ),
IO.String.Input("filename_prefix", default="mesh/ComfyUI"), IO.String.Input("filename_prefix", default="mesh/ComfyUI"),
], ],