Files
prep-step/scripts/psb/norms.py
T
davideandClaude 2d7ace07e2 Documenta il formato PSB dei file Creo e aggiungi il parser di riferimento
Reverse engineering di 9253000117a.prt.35: contenitore (offset dall'ultimo
campo dell'intestazione, indice a catena), grammatica completa delle sezioni
(id progressivi dei campi, tabella "dopo X viene Y", marcatori di chiusura),
tabella dei double verificata sulla norma delle matrici, sezioni compresse e
catalogo del contenuto. Parser Python in scripts/psb/. docs/history.md
raccoglie stato, metodo e punti aperti per riprendere il lavoro.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-11-10 14:34:29 +01:00

31 lines
1.2 KiB
Python

import sys,os,math,collections
sys.path.insert(0,os.path.dirname(os.path.abspath(__file__)))
import prt,psb
d,secs,order=prt.load(sys.argv[1])
bad=collections.Counter(); good=0; unk=collections.Counter()
def walk(v,name=''):
global good
if isinstance(v,psb.Node):
for n,x in v: walk(x,n)
elif isinstance(v,psb.Arr):
for x in v: walk(x,name)
elif isinstance(v,list) and v and isinstance(v[0],list) and len(v) in (3,4) and len(v[0])==3 and name in ('local_sys','orient','matrix'):
for r in v[:3]:
if any(isinstance(c,psb.Unk) for c in r):
u=[c for c in r if isinstance(c,psb.Unk)]
if len(u)==1:
rest=sum(c*c for c in r if not isinstance(c,psb.Unk))
unk[(u[0].code, round(math.sqrt(max(0,1-rest)),6))]+=1
continue
n=math.sqrt(sum(c*c for c in r))
if abs(n-1)<1e-6: good+=1
else: bad[(name,tuple(round(c,4) for c in r))]+=1
for nme in order:
o,l,f=secs[nme]
if f[2]!='9': continue
p,root,e=psb.parse(d[o:o+l])
if root: walk(root[1])
print('good rows',good,'bad',sum(bad.values()))
for k,v in bad.most_common(15): print(v,k)
print('unknown consts solved by norm:',unk.most_common(20))