Files
Pier_v1/pierzainer_ground/inspect_sample_terrain.py
T

51 lines
3.1 KiB
Python

"""Read-only drawing diagnostics; writes evidence below the sample output only."""
import argparse
from collections import Counter
import json
from pathlib import Path
import numpy as np
from ezdxf import recover
from build_sample_grounds import OUTPUT, save
from pierzainer_ground.project_coordinates import workbook_piers
def inspect(job):
out=Path(job['output'])
paths=list((out/'cache').glob('*.dxf'))
if not paths:return
doc,_=recover.readfile(str(paths[0]))
controls=workbook_piers(job['workbook'])
centers=np.array([np.mean(p['axis'],axis=0) for p in controls])
blocks=[]
for block in doc.blocks:
types=Counter();points=[];elevations=[];texts=[];inserts=[]
for entity in block:
kind=entity.dxftype();types[kind]+=1
if kind=='POINT':points.append(tuple(entity.dxf.location))
elif kind=='LWPOLYLINE':elevations.append(float(entity.dxf.elevation))
elif kind=='POLYLINE':
elevations.extend(float(v.dxf.location.z) for v in entity.vertices)
elif kind in ('TEXT','MTEXT') and len(texts)<12:
text=entity.plain_text() if kind=='MTEXT' else entity.dxf.text
texts.append({'text':text,'position':tuple(entity.dxf.insert),'layer':entity.dxf.layer})
elif kind=='INSERT' and len(inserts)<25:
inserts.append({'name':entity.dxf.name,'position':tuple(entity.dxf.insert),'rotation':entity.dxf.rotation,
'scales':[entity.dxf.get(k,1) for k in ('xscale','yscale','zscale')]})
if sum(types.values())<10:continue
a=np.array(points)
blocks.append({'name':block.name,'types':dict(types),'xref_path':block.block.dxf.get('xref_path',''),
'point_bounds': [a.min(0).tolist(),a.max(0).tolist()] if len(a) else None,
'nonzero_points':int(np.count_nonzero(np.abs(a[:,2])>1e-6)) if len(a) else 0,
'polyline_z_range':[min(elevations),max(elevations)] if elevations else None,
'nonzero_polyline_vertices':sum(abs(z)>1e-6 for z in elevations),
'text_examples':texts,'inserts':inserts})
result={'sample':job['sample'],'bridge':job['bridge'],'pier_bounds_NE':[centers.min(0).tolist(),centers.max(0).tolist()],
'blocks':sorted(blocks,key=lambda b:sum(b['types'].values()),reverse=True),
'empty_xrefs':[{'name':b.name,'path':b.block.dxf.get('xref_path','')} for b in doc.blocks if b.block.dxf.get('xref_path','') and len(b)==0]}
save(out/'terrain_diagnostics.json',result)
print(json.dumps({'sample':job['sample'],'pier_bounds_NE':result['pier_bounds_NE'],'blocks':[{k:b[k] for k in ('name','types','point_bounds','nonzero_points','polyline_z_range')} for b in result['blocks'][:8]],'empty_xrefs':result['empty_xrefs']},ensure_ascii=False),flush=True)
if __name__=='__main__':
p=argparse.ArgumentParser();p.add_argument('samples',nargs='*',type=int);args=p.parse_args()
for job in json.loads((OUTPUT/'inputs.json').read_text(encoding='utf-8')):
if job['sample'] in args.samples:inspect(job)