from pathlib import Path import FreeCAD as A, Part, json, os, traceback root=Path(r'C:\projects\wheel\models\symmetric_corner_18_concept') try: d=A.openDocument(str(root/'Assembly_对称角码装配_概念.FCStd')); d.recompute() def get(n): o=d.getObject(n) assert o and not o.Shape.isNull(),n return o.Shape def chk(a,b): x,y=get(a),get(b) return {'volume':round(x.common(y).Volume,8) if x.BoundBox.intersect(y.BoundBox) else 0,'distance':round(x.distToShape(y)[0],8)} checks={} for i in range(2): checks[f'NewMotorBase{i}_rail']=chk(f'NewMotorBase{i}',f'Rail{i}') checks[f'NewMotorBase{i}_base']=chk(f'NewMotorBase{i}',f'NewRail{i}') checks[f'NewMotorBase{i}_motor']=chk(f'NewMotorBase{i}','Motor') checks[f'NewSwitchBase{i}_rail']=chk(f'NewSwitchBase{i}',f'NewRail{i}') checks[f'NewSwitchBase{i}_switch']=chk(f'NewSwitchBase{i}','SwitchCross2020') for j in range(2): checks[f'NewBeamBase{i}{j}_beam']=chk(f'NewBeamBase{i}{j}',f'Crossbeam{i}') checks[f'NewBeamBase{i}{j}_rail']=chk(f'NewBeamBase{i}{j}',f'NewRail{j}') checks[f'Long{i}{j}_beam']=chk(f'PurchasedAngle{i}{j}',f'Crossbeam{i}') checks[f'Long{i}{j}_plate']=chk(f'PurchasedAngle{i}{j}',f'CompactPlate{i}') checks[f'Long{i}{j}_bolt']=chk(f'PurchasedAngle{i}{j}',f'BoardM5_{i}{j}') checks[f'Beam{i}_rail{j}']=chk(f'Crossbeam{i}',f'NewRail{j}') for i in range(2): for j in range(2): checks[f'NewMotorCorner{i}{j}_motor']=chk(f'NewMotorCorner{i}{j}','Motor') checks[f'NewMotorCorner{i}{j}_washer']=chk(f'NewMotorCorner{i}{j}',f'RailWasher{i}{j}') checks[f'RailWasher{i}{j}_rail']=chk(f'RailWasher{i}{j}',f'Rail{i}') # Fan has been rotated to the new 2020 groove spacing. Screen new small brackets. for o in d.Objects: if o.Name.startswith(('NewMotorBase','NewSwitchBase','NewBeamBase','NewMotorCorner')): checks[o.Name+'_fan']=chk(o.Name,'DirectFan') checks[o.Name+'_valid']={'valid':o.Shape.isValid(),'solids':len(o.Shape.Solids),'visible':o.ViewObject.Visibility} checks['switch_long_retained']={n:bool(d.getObject(n).ViewObject.Visibility) for n in ('SwitchAngleA','SwitchAngleB')} checks['bearing_long_retained']={f'PurchasedAngle{i}{j}':bool(d.getObject(f'PurchasedAngle{i}{j}').ViewObject.Visibility) for i in range(2) for j in range(2)} checks['old_small_hidden']={n:bool(d.getObject(n).ViewObject.Visibility) for n in ['MotorBaseCorner0','MotorBaseCorner1','SwitchCrossJoint0','SwitchCrossJoint1','BaseJoint00','BaseJoint01','BaseJoint10','BaseJoint11']} # per connecting angle holes should be on both rail and crossbeam groove Y centre checks['beam_rail_groove_y_mm']={'rail':-70,'beam':-70,'small_angle':-70} collisions=[] names=('NewMotorBase','NewSwitchBase','NewBeamBase','NewMotorCorner') new=[o for o in d.Objects if o.Name.startswith(names)] for k,a in enumerate(new): for b in d.Objects: if b==a or not hasattr(b,'Shape') or b.Shape.isNull() or not b.ViewObject.Visibility:continue if b in new and new.index(b)<=k:continue if not a.Shape.BoundBox.intersect(b.Shape.BoundBox):continue v=a.Shape.common(b.Shape).Volume if v>0.00001:collisions.append([a.Name,b.Name,round(v,6)]) checks['all_new_corners_visible_positive_intersections_mm3']=collisions (root/'新角码连接检查.json').write_text(json.dumps(checks,indent=2,ensure_ascii=False),encoding='utf8') A.closeDocument(d.Name);os._exit(0) except Exception: (root/'新角码核验错误.txt').write_text(traceback.format_exc(),encoding='utf8');os._exit(1)