建立方向盘项目初始版本

This commit is contained in:
2026-10-29 22:04:55 +08:00
commit 9962cbfbce
834 changed files with 1519203 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
from pathlib import Path
import os, time, json, traceback
import FreeCAD as A, FreeCADGui as G, Part, Import
from pivy import coin
R=Path(r'C:\projects\wheel'); O=R/'models'/'switch_2020_crossbar132'; O.mkdir(parents=True,exist_ok=True)
try:
d=A.openDocument(str(R/'models'/'switch_2020_direct_profiles'/'Assembly.FCStd'))
beam=d.getObject('SwitchCross2020'); old=beam.Shape.copy()
assert abs(old.BoundBox.XLength-160)<1e-5
beam.Shape=Part.makeBox(132,20,20,A.Vector(-66,-55,-142))
beam.Label='Switch crossbeam 2020 x 132 mm'; d.recompute()
new=beam.Shape
assert new.isValid() and abs(new.BoundBox.XLength-132)<1e-6
added=new.cut(old).Volume; removed=old.cut(new).Volume
assert added<1e-7 and abs(removed-11200)<1e-5
result={'crossbar_length_mm':132,'profile_mm':[20,20],'crossbar_x_min_mm':-66,'crossbar_x_max_mm':66,'added_volume_mm3':added,'removed_volume_mm3':removed,'components':{}}
# Replace the two old square bearing plates by the latest V3 machining model.
# V3 coordinates have the same X origin, Y=0 at the plate bottom, and Z=0 at its front face.
v3=Part.read(str(R/'models'/'kfl001_plate_v3_alt'/'KFL001_plate_V3.step'))
result['bearing_plates_v3']={}
for i,z in ((0,-84),(1,-187)):
obj=d.getObject('CompactPlate%d'%i);before=obj.Shape.copy()
revised=v3.copy();revised.translate(A.Vector(0,-41,z))
addedplate=revised.cut(before).Volume
assert addedplate<1e-4,(i,addedplate)
obj.Placement=A.Placement();obj.Shape=revised
obj.Label='Bearing plate V3 %d (76 x 75 x 8)'%(i+1)
result['bearing_plates_v3'][obj.Name]={'added_volume_mm3':addedplate,'removed_volume_mm3':before.cut(revised).Volume,'z_mm':z}
d.recompute()
for n in ['NewRail0','NewRail1','SwitchAngleA','SwitchAngleB','SwitchCrossJoint0','SwitchCrossJoint1','SwitchEnvelope']:
obj=d.getObject(n);bb=obj.Shape.BoundBox
overlap=new.common(obj.Shape).Volume if new.BoundBox.intersect(bb) else 0
distance=new.distToShape(obj.Shape)[0]
result['components'][n]={'x_min_mm':bb.XMin,'x_max_mm':bb.XMax,'distance_mm':distance,'overlap_mm3':overlap}
if n!='SwitchEnvelope':
assert bb.XMin>=-66 and bb.XMax<=66,(n,bb.XMin,bb.XMax)
assert overlap<0.001,(n,overlap)
else: assert distance>4.99
for n in ['SwitchAngleA','SwitchAngleB','SwitchCrossJoint0','SwitchCrossJoint1']:
assert result['components'][n]['distance_mm']<0.0001, n
d.Label='Switch crossbar 2020 x 132 mm - layout'
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'))
G.activateWorkbench('PartWorkbench');view=G.activeDocument().activeView()
view.viewAxonometric();G.updateGui();view.getCameraNode().orientation.setValue(coin.SbRotation(.880476,.115917,-.279848,-.364705));G.updateGui();time.sleep(.3);view.fitAll();G.updateGui();time.sleep(.4);view.saveImage(str(O/'assembly.png'),1800,1250,'White')
visibility={o.Name:o.ViewObject.Visibility for o in d.Objects if hasattr(o,'Shape')}
show=set(['SwitchCross2020','SwitchAngleA','SwitchAngleB','SwitchHeadA','SwitchHeadB','SwitchRailHeadA','SwitchRailHeadB','SwitchCrossJoint0','SwitchCrossJoint1','SwitchEnvelope','AssumedEarA','AssumedEarB','NewRail0','NewRail1'])
for o in d.Objects:
if hasattr(o,'Shape'):o.ViewObject.Visibility=o.Name in show
view.viewAxonometric();G.updateGui();time.sleep(.2);view.fitAll();G.updateGui();time.sleep(.4);view.saveImage(str(O/'crossbar_focus.png'),1800,1250,'White')
view.viewTop();G.updateGui();time.sleep(.2);view.fitAll();G.updateGui();time.sleep(.4);view.saveImage(str(O/'crossbar_front.png'),1800,1250,'White')
for o in d.Objects:
if hasattr(o,'Shape'):o.ViewObject.Visibility=visibility.get(o.Name,True)
d.recompute();d.saveAs(str(O/'Assembly.FCStd'));A.closeDocument(d.Name)
dd=A.openDocument(str(O/'Assembly.FCStd'));dd.recompute();v=dd.getObject('SwitchCross2020').Shape
assert v.isValid() and abs(v.BoundBox.XLength-132)<1e-6
step=Part.read(str(O/'Assembly.step'));assert step.isValid() and len(step.Solids)>0
result['fcstd_reopened']=True;result['step_valid']=True;result['step_solid_count']=len(step.Solids)
(O/'validation.json').write_text(json.dumps(result,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)