"""The stroke CLI uses the texture geometry job and verifies its outputs.""" from __future__ import annotations import argparse import json from pathlib import Path from orisys_sensor_design import cli from orisys_sensor_design.manifest import RevisionPaths, sha256_file REVISION = Path(__file__).resolve().parents[1] / "sensors" / "finger-xynova" / "r01" def _args(job: Path, output_dir: Path, views=False) -> argparse.Namespace: return argparse.Namespace( views=views, source_job=job, output_dir=output_dir, width_ratio=0.4, length_ratio=0.8, orientation_mode=None, proposals=None, seed=13, ) def _job(tmp_path: Path) -> Path: paths = RevisionPaths.from_revision_dir(REVISION) job = tmp_path / "_texture_job.json" job.write_text(json.dumps({ "schema": "orisys-sensor-design/texture-job-v3", "revision_dir": str(paths.root), "source_blend": str(paths.source_blend), "settings": {"nx": 80, "ny": 80}, "objects": {"mesh": "sensing_surface", "camera": "cam_sensor"}, "outputs": [{"uv_map": "compute"}], }), encoding="utf-8") return job def test_exports_from_geometry_job(tmp_path, monkeypatch): job = _job(tmp_path) output_dir = tmp_path / "strokes" calls = [] def run_blender(script, blend, args): calls.append((script, blend, args)) for fmt in ("png", "svg", "pdf"): (output_dir / f"stroke_texture_compute.{fmt}").write_bytes(fmt.encode()) return 0 monkeypatch.setattr(cli, "_run_blender_script", run_blender) assert cli.cmd_stroke_texture(REVISION, _args(job, output_dir)) == 0 assert calls[0][0] == "camera_grid_stroke.py" params_path = Path(calls[0][2][calls[0][2].index("--params") + 1]) params = json.loads(params_path.read_text(encoding="utf-8")) assert params["seed"] == 13 assert params["width_ratio"] == 0.4 manifest = json.loads((output_dir / "stroke_texture_manifest.json").read_text()) assert manifest["schema"] == "orisys-sensor-design/stroke-texture-manifest-v2" assert manifest["source_job"]["sha256"] == sha256_file(job) assert set(manifest["outputs"][0]["artifacts"]) == {"png", "svg", "pdf"} assert cli.cmd_stroke_texture(REVISION, _args(job, output_dir)) == 2 assert len(calls) == 1 def test_multiview_exports_owned_pairs_without_colour_artwork(tmp_path, monkeypatch): paths = RevisionPaths.from_revision_dir(REVISION) job = tmp_path / "_texture_views_job.json" job.write_text(json.dumps({ "schema": "orisys-sensor-design/texture-job-multiview-v1", "revision_dir": str(paths.root), "source_blend": str(paths.source_blend), "settings": {"nx": 80, "ny": 80}, "objects": {"mesh": "sensing_surface"}, "pairs": [{"id": "uv_1"}, {"id": "uv_2"}], }), encoding="utf-8") output_dir = tmp_path / "strokes" calls = [] def run_blender(script, blend, args): calls.append((script, blend, args)) for pair in ("uv_1", "uv_2"): for fmt in ("png", "svg", "pdf"): (output_dir / f"stroke_texture_{pair}.{fmt}").write_bytes(pair.encode()) for name in ("_multiview_ground_truth.json", "_print_views.json"): (output_dir / name).write_text("{}", encoding="utf-8") return 0 monkeypatch.setattr(cli, "_run_blender_script", run_blender) assert cli.cmd_stroke_texture(REVISION, _args(job, output_dir, views=True)) == 0 assert calls[0][0] == "random_patch_multiview.py" assert "--stroke-params" in calls[0][2] manifest = json.loads((output_dir / "stroke_texture_manifest.json").read_text()) assert manifest["views"] is True assert [entry["id"] for entry in manifest["outputs"]] == ["uv_1", "uv_2"] assert set(manifest["auxiliary"]) == {"_multiview_ground_truth.json", "_print_views.json"} assert len(calls) == 1