建立方向盘项目初始版本

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,52 @@
from pathlib import Path
import os,time,traceback,json
import FreeCAD as A, FreeCADGui as G, Part, Mesh, Import
V=A.Vector
R=Path(r'C:\projects\wheel'); O=R/'models'/'fan120_integer_v2'; O.mkdir(parents=True,exist_ok=True)
def cy(r,h,x,y,z): return Part.makeCylinder(r,h,V(x,y,z))
def slot(x,y,z,r,travel,h): return Part.makeBox(travel,2*r,h,V(x-travel/2,y-r,z)).fuse(cy(r,h,x-travel/2,y,z)).fuse(cy(r,h,x+travel/2,y,z))
def feature(d,name,shape,color):
o=d.addObject('PartDesign::Feature',name);o.Shape=shape;o.Label=name;o.ViewObject.ShapeColor=color;return o
try:
d=A.openDocument(str(R/'models'/'integer_profiles'/'Assembly.FCStd'));d.recompute()
source=[o for o in d.Objects if hasattr(o,'Shape') and not o.Shape.isNull() and o.ViewObject.Visibility]
centers=[(d.getObject('Rail%d'%i).Shape.BoundBox.XMin+d.getObject('Rail%d'%i).Shape.BoundBox.XMax)/2 for i in range(2)]
zrail=20.; zframe=42.
frame=Part.makeBox(120,120,4,V(-60,-60,zframe)).cut(Part.makeBox(96,96,4.04,V(-48,-48,zframe-.02)))
for x in centers:
for y in (-25,25):frame=frame.fuse(Part.makeBox(24,18,zframe+4-zrail,V(x-12,y-9,zrail)))
frame=frame.removeSplitter()
for x in (-52.5,52.5):
for y in (-52.5,52.5):frame=frame.cut(cy(2.25,4.04,x,y,zframe-.02))
for x in centers:
for y in (-25,25):
frame=frame.cut(slot(x,y,zrail-.02,2.75,10,zframe+4-zrail+.04))
frame=frame.cut(slot(x,y,zframe-1.5,4.9,10,5.52))
frame=frame.removeSplitter()
assert frame.isValid() and len(frame.Solids)==1
fan=Part.makeBox(120,120,25,V(-60,-60,zframe+4)).cut(cy(56,25.04,0,0,zframe+3.98))
for x in (-52.5,52.5):
for y in (-52.5,52.5):fan=fan.cut(cy(2.2,25.04,x,y,zframe+3.98))
fan=fan.removeSplitter()
result=[]
for o in source:
for name,sh in [('frame',frame),('fan',fan)]:
if sh.BoundBox.intersect(o.Shape.BoundBox):
v=sh.common(o.Shape).Volume
if v>1e-4:result.append([name,o.Name,v])
(O/'hits.json').write_text(json.dumps(result,indent=2),encoding='utf8')
if result:raise RuntimeError('Intersecting assemblies '+str(result))
for i in range(2):
rail=d.getObject('Rail%d'%i).Shape
assert frame.distToShape(rail)[0]<1e-6 and frame.common(rail).Volume<1e-5
mount=feature(d,'FanSupportV2',frame,(0.95,.55,.08)); ff=feature(d,'FanEnvelopeV2',fan,(.2,.2,.2));ff.ViewObject.Transparency=55
d.recompute();d.saveAs(str(O/'Assembly.FCStd'))
G.activeDocument().activeView().viewAxonometric();G.updateGui();G.activeDocument().activeView().fitAll();time.sleep(.5);G.updateGui();G.activeDocument().activeView().saveImage(str(O/'assembly.png'),1600,1200,'White')
p=frame.copy();p.translate(V(0,0,-(zframe+4)));p.rotate(V(),V(1,0,0),180)
pd=A.newDocument('Fan120Print');po=feature(pd,'FanMount',Part.makeCompound([p]),(.15,.5,.86));pd.recompute();Mesh.export([po],str(O/'Fan120Mount.stl'));Import.export([po],str(O/'Fan120Mount.step'));pd.saveAs(str(O/'Fan120Mount.FCStd'))
mesh=Mesh.Mesh(str(O/'Fan120Mount.stl'));assert mesh.isSolid() and abs(mesh.BoundBox.ZMin)<1e-3
data={'rail_centres_x':centers,'leg_y':[ -25,25],'rail_top_z':zrail,'ring_bottom_z':zframe,'fan_bottom_z':zframe+4,'leg_height':zframe+4-zrail,'frame_volume':frame.Volume,'mesh_solid':mesh.isSolid(),'stl_z_min':mesh.BoundBox.ZMin,'static_hits':result,'fan_envelope_mm':[120,120,25],'not_modeled':'slot hardware, fan hub, cable, user physical components'}
(O/'validation.json').write_text(json.dumps(data,indent=2),encoding='utf8');(O/'DONE.txt').write_text('ok',encoding='utf8')
A.closeDocument(pd.Name);A.closeDocument(d.Name);os._exit(0)
except Exception:
(O/'ERROR.txt').write_text(traceback.format_exc(),encoding='utf8');os._exit(1)