# AI ATLAS: independently import exported files and measure world-space dimensions.
# Tested with Blender4.3.2. Save your work: this clears the active scene.
# Run in a separate background process. Input GLBs are never rewritten.
# Example: blender --background --python-exit-code 1 --python verify_glb_in_blender.py -- reading-corner.glb --expect-reading-corner --report blender-recheck.json
import argparse
import bpy
import json
import math
from pathlib import Path
import sys
from mathutils import Vector
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('inputs',nargs='+',type=Path)
parser.add_argument('--expect-reading-corner',action='store_true')
parser.add_argument('--report',type=Path)
args=parser.parse_args(sys.argv[sys.argv.index('--')+1:] if '--' in sys.argv else [])
if args.report and args.report.exists():raise ValueError('Choose a new report filename; existing files are not overwritten.')
if args.expect_reading_corner and len(args.inputs)!=1:raise ValueError('Fixed reading-corner assertions apply to one input only.')
for path in args.inputs:
    if not path.is_file():raise ValueError('Missing input: '+str(path))
results=[]
for path in args.inputs:
    bpy.ops.wm.read_factory_settings(use_empty=True)
    bpy.ops.import_scene.gltf(filepath=str(path.resolve()))
    objects=[o for o in bpy.context.scene.objects if o.type=='MESH']
    measured=[]
    for obj in objects:
        obj.data.calc_loop_triangles()
        points=[obj.matrix_world @ vertex.co for vertex in obj.data.vertices]
        if not points or not all(math.isfinite(v) for p in points for v in p):raise ValueError('Empty or non-finite geometry')
        lo=[min(p[k] for p in points) for k in range(3)];hi=[max(p[k] for p in points) for k in range(3)]
        degenerate=0
        for tri in obj.data.loop_triangles:
            a,b,c=[points[i] for i in tri.vertices]
            if (b-a).cross(c-a).length_squared<=1e-20:degenerate+=1
        measured.append({'name':obj.name,'worldDimensionsBlenderXYZM':[hi[k]-lo[k] for k in range(3)],
                         'triangles':len(obj.data.loop_triangles),'degenerateTriangles':degenerate,
                         'materialSlots':len(obj.material_slots)})
    row={'file':path.name,'meshObjects':len(objects),'triangles':sum(x['triangles'] for x in measured),
         'degenerateTriangles':sum(x['degenerateTriangles'] for x in measured),
         'imageDatablocks':len(bpy.data.images),'objects':measured}
    if args.expect_reading_corner:
        assert row['meshObjects']==46 and row['triangles']==792
        assert row['degenerateTriangles']==0 and row['imageDatablocks']==0
        floor=next(o for o in measured if o['name']=='Floor_3m_x_2m')
        assert all(abs(a-b)<1e-5 for a,b in zip(floor['worldDimensionsBlenderXYZM'],(3,2,.12)))
        row['readingCornerChecksPassed']=True
    results.append(row)
report={'blenderVersion':bpy.app.version_string,'files':results,
        'scope':'Actual Blender re-import and world-axis-aligned bounds. Not a visual material test, glTF conformance certification, watertightness/intersection test, game frame-rate benchmark, AR compatibility or construction-safety check.'}
if args.report:
    with args.report.open('x',encoding='utf-8') as f:json.dump(report,f,ensure_ascii=False,indent=2);f.write('\n')
print('ATLAS_IMPORT_CHECK',json.dumps(report,ensure_ascii=False))
