Add DB9 CAD reference data
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
"""Read pinned STEP B-rep; write reproducible solid/face measurements beside it."""
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
from OCP.STEPControl import STEPControl_Reader
|
||||
from OCP.IFSelect import IFSelect_RetDone
|
||||
from OCP.TopExp import TopExp_Explorer
|
||||
from OCP.TopAbs import TopAbs_SOLID, TopAbs_FACE
|
||||
from OCP.TopoDS import TopoDS
|
||||
from OCP.Bnd import Bnd_Box
|
||||
from OCP.BRepBndLib import BRepBndLib
|
||||
from OCP.BRepAdaptor import BRepAdaptor_Surface
|
||||
from OCP.GeomAbs import GeomAbs_Cylinder, GeomAbs_Plane
|
||||
from OCP.BRepCheck import BRepCheck_Analyzer
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
|
||||
def bounds(s):
|
||||
b = Bnd_Box()
|
||||
BRepBndLib.AddOptimal_s(s, b, False, False)
|
||||
return list(b.Get())
|
||||
|
||||
def xyz(p):
|
||||
return [p.X(), p.Y(), p.Z()]
|
||||
|
||||
r = STEPControl_Reader()
|
||||
assert r.ReadFile(str(HERE / '5988 RS-232 Level Shifter.step')) == IFSelect_RetDone
|
||||
r.TransferRoots()
|
||||
entities = dict(re.findall(r'#(\d+)\s*=\s*(.*?);', (HERE / '5988 RS-232 Level Shifter.step').read_text(), re.S))
|
||||
styles = {}
|
||||
for text in entities.values():
|
||||
if text.startswith('STYLED_ITEM('):
|
||||
refs = re.findall(r'#(\d+)', text)
|
||||
styles[refs[-1]] = refs[:-1]
|
||||
|
||||
def colors(refs, seen=None):
|
||||
seen = set() if seen is None else seen
|
||||
result = []
|
||||
for ref in refs:
|
||||
if ref in seen:
|
||||
continue
|
||||
seen.add(ref)
|
||||
text = entities[ref]
|
||||
if text.startswith('COLOUR_RGB('):
|
||||
result.append(text.replace('\n', ''))
|
||||
else:
|
||||
result.extend(colors(re.findall(r'#(\d+)', text), seen))
|
||||
return result
|
||||
|
||||
e = TopExp_Explorer(r.OneShape(), TopAbs_SOLID)
|
||||
out = []
|
||||
while e.More():
|
||||
s = TopoDS.Solid_s(e.Current())
|
||||
item = dict(id=len(out)+1, bounds=bounds(s), valid=BRepCheck_Analyzer(s).IsValid(), faces=[])
|
||||
f = TopExp_Explorer(s, TopAbs_FACE)
|
||||
while f.More():
|
||||
face = TopoDS.Face_s(f.Current())
|
||||
a = BRepAdaptor_Surface(face)
|
||||
# These unique bodies retain CLOSED_SHELL face order on this pinned import.
|
||||
shell_id = {1: '14428', 12: '14431', 13: '14432', 14: '14433'}.get(item['id'])
|
||||
refs = re.findall(r'#(\d+)', entities[shell_id]) if shell_id else []
|
||||
step_id = refs[len(item['faces'])] if refs else '0'
|
||||
if refs:
|
||||
surface_id = re.findall(r'#(\d+)', entities[step_id])[-1]
|
||||
surface = entities[surface_id]
|
||||
expected = str(a.GetType()).split('_')[-1].upper()
|
||||
assert surface.startswith({'PLANE': 'PLANE(', 'CYLINDER': 'CYLINDRICAL_SURFACE(', 'CONE': 'CONICAL_SURFACE(', 'TORUS': 'TOROIDAL_SURFACE('}[expected])
|
||||
if a.GetType() == GeomAbs_Cylinder:
|
||||
assert abs(float(surface.rsplit(',', 1)[1].rstrip(')')) - a.Cylinder().Radius()) < 1e-8
|
||||
row = dict(id=len(item['faces'])+1, bounds=bounds(face), type=str(a.GetType()), orientation=str(face.Orientation()))
|
||||
row.update(step_id=step_id, colors=colors(styles.get(step_id, [])))
|
||||
if a.GetType() == GeomAbs_Cylinder:
|
||||
c = a.Cylinder()
|
||||
row.update(radius=c.Radius(), location=xyz(c.Location()), axis=xyz(c.Axis().Direction()))
|
||||
elif a.GetType() == GeomAbs_Plane:
|
||||
p = a.Plane()
|
||||
row.update(location=xyz(p.Location()), normal=xyz(p.Axis().Direction()))
|
||||
item['faces'].append(row)
|
||||
f.Next()
|
||||
if shell_id:
|
||||
assert len(item['faces']) == len(refs)
|
||||
out.append(item)
|
||||
e.Next()
|
||||
(HERE / 'geometry.json').write_text(json.dumps(out, indent=2)+'\n')
|
||||
for s in out:
|
||||
print(s['id'], 'valid', s['valid'], 'bounds', [round(v,6) for v in s['bounds']], 'faces', len(s['faces']))
|
||||
Reference in New Issue
Block a user