afe1ce39cb
沿用彩色纹理的视图归属、接缝留白和自动页面尺寸。 已验证双视图与单视图 Blender 导出、相关测试及文档门禁。
92 lines
3.8 KiB
Python
92 lines
3.8 KiB
Python
"""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
|