v60
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Verify the complete SOFT FACET V2 PDF/SVG/JSON output matrix."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import math
|
||||
import xml.etree.ElementTree as ET
|
||||
from pathlib import Path
|
||||
|
||||
from pypdf import PdfReader
|
||||
|
||||
from generate_a3_templates import SURFACE_STYLES
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--preset", default="v60_02")
|
||||
parser.add_argument("--output-root", type=Path, default=Path(__file__).resolve().parents[1] / "output")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def require(condition: bool, message: str) -> None:
|
||||
if not condition:
|
||||
raise AssertionError(message)
|
||||
|
||||
|
||||
def verify_style(root: Path, preset: str, style: str) -> None:
|
||||
pdf_path = root / "pdf" / f"{preset}_{style}_clay_templates_a3.pdf"
|
||||
data_path = root / "data" / f"{preset}_{style}_clay_templates.json"
|
||||
svg_dir = root / "svg" / style
|
||||
require(pdf_path.is_file(), f"missing PDF: {pdf_path}")
|
||||
require(data_path.is_file(), f"missing JSON: {data_path}")
|
||||
|
||||
reader = PdfReader(str(pdf_path))
|
||||
require(len(reader.pages) == 3, f"{style}: expected 3 PDF pages")
|
||||
for page_number, page in enumerate(reader.pages, start=1):
|
||||
width_mm = float(page.mediabox.width) * 25.4 / 72.0
|
||||
height_mm = float(page.mediabox.height) * 25.4 / 72.0
|
||||
require(math.isclose(width_mm, 420.0, abs_tol=0.01), f"{style}: page {page_number} width")
|
||||
require(math.isclose(height_mm, 297.0, abs_tol=0.01), f"{style}: page {page_number} height")
|
||||
text = page.extract_text() or ""
|
||||
require(style in text, f"{style}: style label missing on page {page_number}")
|
||||
require("50 x 50" in text, f"{style}: calibration square label missing on page {page_number}")
|
||||
|
||||
data = json.loads(data_path.read_text(encoding="utf-8"))
|
||||
require(data["model_version"] == "2.0", f"{style}: wrong model version")
|
||||
require(data["surface_style"] == style, f"{style}: JSON style mismatch")
|
||||
require(0 < data["release_scale"] <= 1, f"{style}: invalid release scale")
|
||||
require(data["minimum_release_draft_angle_deg"] >= 5, f"{style}: release angle below production minimum")
|
||||
for field in (
|
||||
"master_top_radius_mm",
|
||||
"master_bottom_radius_mm",
|
||||
"master_height_mm",
|
||||
"average_meridian_length_mm",
|
||||
"single_piece_outer_radius_mm",
|
||||
"single_piece_inner_radius_mm",
|
||||
"support_max_span_mm",
|
||||
"support_hole_diameter_mm",
|
||||
):
|
||||
require(data[field] > 0, f"{style}: non-positive {field}")
|
||||
for field in ("gore_top_widths_mm", "gore_bottom_widths_mm", "gore_heights_mm"):
|
||||
require(len(data[field]) == 4, f"{style}: {field} must contain four values")
|
||||
require(all(value > 0 for value in data[field]), f"{style}: invalid {field}")
|
||||
|
||||
svg_paths = sorted(svg_dir.glob(f"{preset}_{style}_*.svg"))
|
||||
require(len(svg_paths) == 6, f"{style}: expected 6 SVG files, found {len(svg_paths)}")
|
||||
for svg_path in svg_paths:
|
||||
ET.parse(svg_path)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
for style in SURFACE_STYLES:
|
||||
verify_style(args.output_root, args.preset, style)
|
||||
print(f"ok: {style}")
|
||||
print(f"verified {len(SURFACE_STYLES)} styles")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user