Files
wheel/scripts/build_integer_profiles.FCMacro

56 lines
3.2 KiB
Plaintext

from pathlib import Path
import os, time, json, traceback
import FreeCAD as A, FreeCADGui as G, Part, Import
R=Path(r'C:\projects\wheel')
O=R/'models'/'integer_profiles';O.mkdir(parents=True,exist_ok=True)
try:
d=A.openDocument(str(R/'models'/'switch_2020_crossbar132'/'Assembly.FCStd'))
d.Label='Wheel assembly - integer profile lengths'
check={}; baselines={}
for i in range(2):
o=d.getObject('Crossbeam%d'%i);b=o.Shape.BoundBox
old=o.Shape.copy()
cutbox=Part.makeBox(71, b.YLength, b.ZLength,A.Vector(-35.5,b.YMin,b.ZMin))
new=old.common(cutbox)
assert new.isValid() and len(new.Solids)==1 and abs(new.BoundBox.XLength-71)<1e-6
assert new.cut(old).Volume <1e-5
o.Shape=new;o.Label='3030 crossbeam %d - 71 mm'%i
baselines[o.Name]={'removed_mm3':old.cut(new).Volume,'added_mm3':new.cut(old).Volume}
d.recompute()
for n,dimensions in [('NewRail0',(30,30,255)),('NewRail1',(30,30,255)),('Crossbeam0',(71,30,30)),('Crossbeam1',(71,30,30)),('Rail0',(20,110,20)),('Rail1',(20,110,20)),('SwitchCross2020',(132,20,20))]:
o=d.getObject(n);b=o.Shape.BoundBox
dims=(b.XLength,b.YLength,b.ZLength)
assert all(abs(a-b)<1e-6 for a,b in zip(dims,dimensions)),(n,dims)
check[n]={'dimensions_xyz_mm':dims}
for i in range(2):
for j in range(2):
cross=d.getObject('Crossbeam%d'%i).Shape
rail=d.getObject('NewRail%d'%j).Shape
angle=d.getObject('BaseJoint%d%d'%(i,j)).Shape
pd=d.getObject('PurchasedAngle%d%d'%(i,j)).Shape
check['beam%d_rail%d'%(i,j)]={'distance_mm':cross.distToShape(rail)[0],'intersection_mm3':cross.common(rail).Volume}
check['beam%d_angle%d'%(i,j)]={'distance_mm':cross.distToShape(angle)[0],'intersection_mm3':cross.common(angle).Volume}
check['rail%d_angle%d%d'%(j,i,j)]={'distance_mm':rail.distToShape(angle)[0],'intersection_mm3':rail.common(angle).Volume}
check['beam%d_longangle%d'%(i,j)]={'distance_mm':cross.distToShape(pd)[0],'intersection_mm3':cross.common(pd).Volume}
assert cross.distToShape(angle)[0]<1e-6 and cross.common(angle).Volume<1e-6
assert rail.distToShape(angle)[0]<1e-6 and rail.common(angle).Volume<1e-6
assert cross.distToShape(pd)[0]<1e-6 and cross.common(pd).Volume<1e-6
assert abs(cross.distToShape(rail)[0]-.1200577)<1e-5
assert cross.common(rail).Volume<1e-6
d.recompute()
d.saveAs(str(O/'Assembly.FCStd'))
visible=[o for o in d.Objects if hasattr(o,'Shape') and not o.Shape.isNull() and o.ViewObject.Visibility]
Import.export(visible,str(O/'Assembly.step'))
v=G.activeDocument().activeView();v.viewAxonometric();G.updateGui();v.fitAll();time.sleep(.5);G.updateGui();v.saveImage(str(O/'assembly.png'),1800,1250,'White')
source=O/'Assembly.FCStd';A.closeDocument(d.Name)
dd=A.openDocument(str(source));dd.recompute()
for i in range(2): assert abs(dd.getObject('Crossbeam%d'%i).Shape.BoundBox.XLength-71)<1e-6
s=Part.read(str(O/'Assembly.step'));assert s.isValid() and len(s.Solids)>0
check['baselines']=baselines;check['fcstd_reopened']=True;check['step_valid']=True;check['step_solid_count']=len(s.Solids)
(O/'validation.json').write_text(json.dumps(check,indent=2),encoding='utf8')
A.closeDocument(dd.Name)
(O/'DONE.txt').write_text('OK',encoding='utf8')
os._exit(0)
except Exception:
(O/'ERROR.txt').write_text(traceback.format_exc(),encoding='utf8');os._exit(1)