Files

90 lines
3.2 KiB
Python

import sys
import types
import numpy as np
import trimesh
from PIL import Image
def _export_textured_glb(path):
mesh = trimesh.creation.box()
img = Image.new("RGB", (8, 8), (10, 20, 30))
uv = np.zeros((len(mesh.vertices), 2), dtype=np.float64)
mesh.visual = trimesh.visual.TextureVisuals(uv=uv, image=img)
trimesh.Scene(mesh).export(str(path), file_type="glb")
def test_loadglb_node_end_to_end(tmp_path, monkeypatch):
input_dir = tmp_path / "input"
(input_dir / "3d").mkdir(parents=True)
glb = input_dir / "3d" / "shoe.glb"
_export_textured_glb(glb)
fake = types.ModuleType("folder_paths")
fake.get_input_directory = lambda: str(input_dir)
fake.get_annotated_filepath = lambda rel: str(input_dir / rel)
monkeypatch.setitem(sys.modules, "folder_paths", fake)
# Evict any previously cached import so the stub is picked up at import time.
monkeypatch.delitem(sys.modules, "cxn.load_glb", raising=False)
from cxn.load_glb import LoadGLB
from cxn.types import Model3D
(model,) = LoadGLB().load(model_file="3d/shoe.glb", toe_axis="+X", up_axis="+Z")
assert isinstance(model, Model3D)
assert len(model.scene.geometry) >= 1
assert model.source_path.endswith("shoe.glb")
assert len(model.textures) >= 1
assert all(isinstance(t, Image.Image) for t in model.textures)
def test_loadglb_node_sentinel_raises(tmp_path, monkeypatch):
import pytest
input_dir = tmp_path / "input"
(input_dir / "3d").mkdir(parents=True)
fake = types.ModuleType("folder_paths")
fake.get_input_directory = lambda: str(input_dir)
fake.get_annotated_filepath = lambda rel: str(input_dir / rel)
monkeypatch.setitem(sys.modules, "folder_paths", fake)
# Evict any previously cached import so the stub is picked up at import time.
monkeypatch.delitem(sys.modules, "cxn.load_glb", raising=False)
from cxn.load_glb import LoadGLB, _NO_FILES_SENTINEL
with pytest.raises(RuntimeError, match="No .glb"):
LoadGLB().load(model_file=_NO_FILES_SENTINEL)
def test_loadglb_node_applies_axis_remap(tmp_path, monkeypatch):
input_dir = tmp_path / "input"
(input_dir / "3d").mkdir(parents=True)
glb = input_dir / "3d" / "shoe.glb"
_export_textured_glb(glb)
fake = types.ModuleType("folder_paths")
fake.get_input_directory = lambda: str(input_dir)
fake.get_annotated_filepath = lambda rel: str(input_dir / rel)
monkeypatch.setitem(sys.modules, "folder_paths", fake)
monkeypatch.delitem(sys.modules, "cxn.load_glb", raising=False)
from cxn.glb_loader import load_glb_as_scene
from cxn.load_glb import LoadGLB
from cxn.loader_common import apply_axis_remap, build_axis_remap
# Vertices as the node will load them (pre-remap), for the same file.
raw_scene = load_glb_as_scene(str(glb))
raw_geom = list(raw_scene.geometry.values())[0]
expected = (
np.asarray(raw_geom.vertices, dtype=np.float64)
@ build_axis_remap("+Y", "+Z").T
)
(model,) = LoadGLB().load(model_file="3d/shoe.glb", toe_axis="+Y", up_axis="+Z")
out_geom = list(model.scene.geometry.values())[0]
assert np.allclose(np.asarray(out_geom.vertices, dtype=np.float64), expected)