first commit
Verify / test (push) Failing after 2m54s

This commit is contained in:
2026-11-05 17:31:17 +03:30
کامیت 56c5ee23d3
63فایلهای تغییر یافته به همراه2749 افزوده شده و 0 حذف شده
+61
مشاهده پرونده
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
"""Render actual SchDoc and compare to a trusted Altium page PNG, without alignment.
Images must represent the same sheet viewport. No registration, recoloring or
cropping hides coordinate differences. Altium PDF exports can be rasterized to
PNG with pdftoppm first. This tool does not manufacture reference images.
"""
import argparse
import hashlib
import json
import sys
from pathlib import Path
sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'backend'))
import cairosvg
import numpy as np
from PIL import Image
from app.parser.schdoc_parser import parse_schdoc
from app.render import svg_document
def main():
p=argparse.ArgumentParser(description=__doc__)
p.add_argument('schematic',type=Path)
p.add_argument('--reference',type=Path)
p.add_argument('--output',type=Path,default=Path('validation-output'))
p.add_argument('--width',type=int,default=2000)
p.add_argument('--max-mae',type=float,default=2.0,help='Mean absolute RGB error threshold, 0..255')
p.add_argument('--max-changed-fraction',type=float,default=.01)
p.add_argument('--pixel-tolerance',type=int,default=12)
args=p.parse_args(); args.output.mkdir(parents=True,exist_ok=True)
raw=args.schematic.read_bytes(); doc=parse_schdoc(raw,args.schematic.name,'validation')
svg=svg_document(doc); (args.output/'drawing.svg').write_bytes(svg)
width=args.width; height=max(1,round(width*doc.sheet.bounds.height/doc.sheet.bounds.width))
if args.reference:
with Image.open(args.reference) as ref: width,height=ref.size
expected_ratio=doc.sheet.bounds.width/doc.sheet.bounds.height
if abs(width/height/expected_ratio-1)>.005:
p.error('Reference aspect ratio differs from original sheet; export the same viewport')
png=cairosvg.svg2png(bytestring=svg,output_width=width,output_height=height)
(args.output/'rendered.png').write_bytes(png)
report={'source_sha256':hashlib.sha256(raw).hexdigest(),'record_count':doc.metadata['record_count'],
'component_count':len(doc.components),'primitive_count':len(doc.primitives),
'diagnostics':[d.model_dump() for d in doc.diagnostics],
'reference_compared':bool(args.reference),'fidelity_verified':False}
passed=True
if args.reference:
reference=Image.open(args.reference).convert('RGB'); actual=Image.open(args.output/'rendered.png').convert('RGB')
a=np.array(actual,dtype=np.int16); b=np.array(reference,dtype=np.int16); delta=np.abs(a-b)
mae=float(delta.mean()); changed=float((delta.max(axis=2)>args.pixel_tolerance).mean())
heat=np.zeros_like(a,dtype=np.uint8); heat[:,:,0]=np.clip(delta.max(axis=2)*4,0,255).astype(np.uint8)
Image.fromarray(heat).save(args.output/'difference.png')
Image.blend(reference,actual,.5).save(args.output/'overlay.png')
passed=mae<=args.max_mae and changed<=args.max_changed_fraction
report.update(reference_sha256=hashlib.sha256(args.reference.read_bytes()).hexdigest(),mae=mae,
changed_pixel_fraction=changed,thresholds={'max_mae':args.max_mae,'max_changed_fraction':args.max_changed_fraction,'pixel_tolerance':args.pixel_tolerance},
regression_passed=passed)
(args.output/'report.json').write_text(json.dumps(report,indent=2))
print(json.dumps({k:v for k,v in report.items() if k!='diagnostics'},indent=2))
return 0 if passed else 1
if __name__=='__main__': sys.exit(main())