Files
cxntibor-ComfyUI-CXN/tests/test_pose_solve_render.py
Tibor Fulop fba6fea68d fix(shoe_pose): render silhouette untextured + depth-only
The silhouette renderer reused trimesh_to_pyrender, which uploads the model's
baseColor texture to the GL context; glGenTextures fails with a ctypes
ArgumentError on the container's PyOpenGL/EGL stack. A silhouette needs only
geometry, so build the pyrender scene with a plain MetallicRoughnessMaterial and
render with RenderFlags.DEPTH_ONLY. Fixes the CXN_ShoePose crash and avoids
per-render texture uploads in the optimizer loop (faster). Regression test added.
2026-06-23 12:30:30 +02:00

56 lines
1.9 KiB
Python

import os
os.environ.setdefault("PYOPENGL_PLATFORM", "egl")
import numpy as np
import pytest
import trimesh
pyrender = pytest.importorskip("pyrender")
from cxn.pose_solve import render_silhouette
def _egl_ok():
try:
r = pyrender.OffscreenRenderer(8, 8)
r.delete()
return True
except Exception:
return False
pytestmark = pytest.mark.skipif(not _egl_ok(), reason="EGL/pyrender offscreen unavailable")
def test_render_silhouette_box_is_nonempty_and_centered():
scene = trimesh.Scene(trimesh.creation.box(extents=(0.4, 0.4, 0.4)))
# Camera 2m in front (looking -Z), model at origin, no rotation.
sil = render_silhouette(scene, 0.0, 0.0, 0.0, (0.0, 0.0, 2.0), 45.0, 128, 128)
assert sil.dtype == bool
assert sil.shape == (128, 128)
frac = sil.mean()
assert 0.01 < frac < 0.9 # box visible but not filling the frame
ys, xs = np.nonzero(sil)
assert abs(xs.mean() - 64) < 12 and abs(ys.mean() - 64) < 12 # roughly centered
def test_render_silhouette_further_camera_is_smaller():
scene = trimesh.Scene(trimesh.creation.box(extents=(0.4, 0.4, 0.4)))
near = render_silhouette(scene, 0, 0, 0, (0, 0, 1.5), 45.0, 128, 128).sum()
far = render_silhouette(scene, 0, 0, 0, (0, 0, 4.0), 45.0, 128, 128).sum()
assert far < near
def test_render_silhouette_ignores_textures():
# Regression: a GLB-style mesh carrying a baseColor texture must not trigger
# a GL texture upload during silhouette rendering (silhouette = geometry only).
from PIL import Image
mesh = trimesh.creation.box(extents=(0.4, 0.2, 0.3))
uv = np.zeros((len(mesh.vertices), 2), dtype=float)
mesh.visual = trimesh.visual.TextureVisuals(uv=uv, image=Image.new("RGB", (8, 8), (200, 40, 40)))
sil = render_silhouette(trimesh.Scene(mesh), 0, 0, 0, (0, 0, 2.0), 45.0, 96, 96)
assert sil.dtype == bool
assert 0.01 < sil.mean() < 0.9