建立方向盘项目初始版本

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,65 @@
from pathlib import Path
import os, time, traceback, math
import FreeCAD as A, FreeCADGui as G, Part, Import
from pivy import coin
R=Path(r'C:\projects\wheel'); O=R/'models'/'switch_2020_direct_profiles';O.mkdir(parents=True,exist_ok=True)
try:
d=A.openDocument(str(R/'models'/'switch_2020_raise10_concept'/'Assembly.FCStd'))
for n in ('Rail0','Rail1','MotorBaseCorner0','MotorBaseCorner1'):
o=d.getObject(n);p=o.Placement;p.Base.y-=10;o.Placement=p
for n in ('MotorShim0','MotorShim1'):
if d.getObject(n):d.removeObject(n)
d.Label='Switch crossbeam - raised shaft, direct profile contact'
d.recompute()
checks=[]
def compare(a,b):
aa=d.getObject(a).Shape;bb=d.getObject(b).Shape
volume=aa.common(bb).Volume if aa.BoundBox.intersect(bb.BoundBox) else 0
distance=aa.distToShape(bb)[0]
checks.append('%s / %s: overlap=%.9f distance=%.6f'%(a,b,volume,distance))
return volume,distance
for i in range(2):
compare('Rail%d'%i,'NewRail%d'%i)
compare('Rail%d'%i,'MotorBaseCorner%d'%i)
compare('NewRail%d'%i,'MotorBaseCorner%d'%i)
for i in range(4):
q=d.getObject('Corner%d'%i); rail=d.getObject('Rail%d'%(i//2));bb=q.Shape.BoundBox
compare(q.Name,rail.Name); compare(q.Name,'Motor')
centers=[]
for face in q.Shape.Faces:
s=face.Surface
if hasattr(s,'Radius') and abs(s.Radius-2.75)<1e-5 and hasattr(s,'Axis') and abs(abs(s.Axis.x)-1)<1e-5:
centers.append((s.Center.y,s.Center.z))
checks.append('%s side-hole cylinders %s bbox=%s rail_y=%s..%s'%(q.Name,str(centers),str(bb),rail.Shape.BoundBox.YMin,rail.Shape.BoundBox.YMax))
if not centers:raise Exception('Missing profile side hole in '+q.Name)
for y,z in centers:
if not (rail.Shape.BoundBox.YMin < y < rail.Shape.BoundBox.YMax and abs(z-10)<1e-5):raise Exception('Profile side hole outside rail slot: '+q.Name)
checks.append('%s hole y=%.5f z=%.5f near_end=%.5f'%(q.Name,y,z,min(y-rail.Shape.BoundBox.YMin,rail.Shape.BoundBox.YMax-y)))
for name in ('Rail0','Rail1','MotorBaseCorner0','MotorBaseCorner1'):
x=d.getObject(name)
for o in d.Objects:
if o==x or not hasattr(o,'Shape') or o.Shape.isNull() or not o.ViewObject.Visibility:continue
if o.Name in ('Rail0','Rail1','MotorBaseCorner0','MotorBaseCorner1'):continue
if x.Shape.BoundBox.intersect(o.Shape.BoundBox):
vol=x.Shape.common(o.Shape).Volume
if vol>.001:checks.append('POSITIVE %s / %s volume=%.8f'%(name,o.Name,vol))
(O/'检查.txt').write_text('\n'.join(checks)+'\n',encoding='utf8')
d.saveAs(str(O/'Assembly.FCStd'))
Import.export([o for o in d.Objects if hasattr(o,'Shape') and not o.Shape.isNull() and o.ViewObject.Visibility],str(O/'Assembly.step'))
G.activateWorkbench('PartWorkbench');view=G.activeDocument().activeView()
def snap(name,mode):
if mode=='top':view.viewTop()
else: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/name),1800,1250,'White')
snap('assembly.png','axon')
vis={o.Name:o.ViewObject.Visibility for o in d.Objects if hasattr(o,'Shape')}
show=set(['Motor','Rail0','Rail1','NewRail0','NewRail1','MotorBaseCorner0','MotorBaseCorner1','Corner0','Corner1','Corner2','Corner3','OpenPillarBracket','PCB','Holder','Magnet'])
for o in d.Objects:
if hasattr(o,'Shape'):o.ViewObject.Visibility=o.Name in show
snap('motor_detail.png','axon');snap('motor_top.png','top')
for o in d.Objects:
if hasattr(o,'Shape'):o.ViewObject.Visibility=vis.get(o.Name,True)
d.recompute();d.saveAs(str(O/'Assembly.FCStd'));A.closeDocument(d.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)