建立方向盘项目初始版本
This commit is contained in:
70
scripts/build_conversion_disk_m4_drill.FCMacro
Normal file
70
scripts/build_conversion_disk_m4_drill.FCMacro
Normal file
@@ -0,0 +1,70 @@
|
||||
"""Build a separate Ø3.3 drill-hole quoting test copy, not a threaded model."""
|
||||
from pathlib import Path
|
||||
import FreeCAD as App, FreeCADGui as Gui, Part, Import
|
||||
import math, traceback
|
||||
root=Path(r'C:\projects\wheel')
|
||||
out=root/'models'/'conversion_disk_m4_drill'
|
||||
out.mkdir(parents=True,exist_ok=True)
|
||||
logs=[]
|
||||
try:
|
||||
source=root/'scripts'/'build_conversion_disk.py'
|
||||
src=source.read_text(encoding='utf-8')
|
||||
src=src.replace("target = ROOT / 'models' / 'conversion_disk_parametric.FCStd'", "target = ROOT / 'models' / 'conversion_disk_m4_drill' / '转换盘_M4底孔.FCStd'")
|
||||
src=src.replace("('OuterHole','4.234 mm','Outer 6-hole diameter'),", "('OuterHole','3.3 mm','Outer 6-hole M4 tap-drill, no modeled thread'),")
|
||||
assert "conversion_disk_m4_drill' / '转换盘_M4底孔.FCStd'" in src and "('OuterHole','3.3 mm'" in src
|
||||
ctx={'__name__':'__main__','__file__':str(source)}
|
||||
exec(compile(src,str(source),'exec'),ctx)
|
||||
d=ctx['doc'];body=d.getObject('Body');f=d.getObject('InnerHoleThrough');d.recompute()
|
||||
assert f.Shape.isValid() and len(f.Shape.Solids)==1
|
||||
def inspect(shape):
|
||||
found=[]
|
||||
for face in shape.Faces:
|
||||
surf=face.Surface
|
||||
if isinstance(surf,Part.Cylinder) and abs(surf.Radius-1.65)<1e-5:
|
||||
c=surf.Center
|
||||
if abs(math.hypot(c.x,c.y)-24)<1e-4 and face.BoundBox.ZLength>7.99: found.append((c.x,c.y))
|
||||
assert len(found)==6, 'found %d intended Ø3.3 through bores' % len(found)
|
||||
for i in range(6):
|
||||
a=math.radians(30+i*60);x=24*math.cos(a);y=24*math.sin(a)
|
||||
assert any(math.hypot(x-u,y-v)<1e-4 for u,v in found), 'Missing bore %d' % i
|
||||
return found
|
||||
pos=inspect(f.Shape);logs.append('FCStd: six Ø3.3 full-depth PCD48 holes, phase 30°, coordinates='+str(pos))
|
||||
original=App.openDocument(str(root/'models'/'conversion_disk_parametric.FCStd'))
|
||||
orig=original.getObject('InnerHoleThrough').Shape
|
||||
masks=[Part.makeCylinder(3,8.2,App.Vector(24*math.cos(math.radians(30+i*60)),24*math.sin(math.radians(30+i*60)),-.1)) for i in range(6)]
|
||||
mask=masks[0].multiFuse(masks[1:])
|
||||
def outside(a,b):
|
||||
t=a.cut(b)
|
||||
if t.isNull():return 0.0
|
||||
try:r=t.cut(mask)
|
||||
except ValueError as e:
|
||||
if str(e)=='Null shape':return 0.0
|
||||
raise
|
||||
return 0.0 if r.isNull() else r.Volume
|
||||
old_new=outside(orig,f.Shape);new_old=outside(f.Shape,orig)
|
||||
assert old_new<1e-5 and new_old<1e-5
|
||||
logs.append('Outside hole masks differences: old-new=%.9f new-old=%.9f mm³' % (old_new,new_old))
|
||||
App.closeDocument(original.Name);App.setActiveDocument(d.Name)
|
||||
for o in d.Objects:
|
||||
if o.ViewObject:o.ViewObject.Visibility=False
|
||||
body.ViewObject.Visibility=True;f.ViewObject.Visibility=True
|
||||
Gui.activeDocument().activeView().viewAxonometric();Gui.activeDocument().activeView().fitAll();Gui.updateGui()
|
||||
Gui.activeDocument().activeView().saveImage(str(out/'转换盘_M4底孔预览.png'),1500,1100,'White')
|
||||
d.saveAs(str(out/'转换盘_M4底孔.FCStd'));volume=f.Shape.Volume
|
||||
Import.export([f],str(out/'转换盘_M4底孔.step'))
|
||||
App.closeDocument(d.Name)
|
||||
d=App.openDocument(str(out/'转换盘_M4底孔.FCStd'));d.recompute();f=d.getObject('InnerHoleThrough')
|
||||
assert f.Shape.isValid();inspect(f.Shape);logs.append('FCStd reopened and recomputed: valid')
|
||||
App.closeDocument(d.Name)
|
||||
d=App.newDocument('STEPCheck');Import.insert(str(out/'转换盘_M4底孔.step'),d.Name);d.recompute()
|
||||
shapes=[o.Shape for o in d.Objects if hasattr(o,'Shape') and not o.Shape.isNull()]
|
||||
assert len(shapes)==1 and shapes[0].isValid(); inspect(shapes[0]);assert abs(shapes[0].Volume-volume)<0.001
|
||||
logs.append('STEP reopened: valid, six Ø3.3 through bores, volume=%.8f, error=%.9f' % (shapes[0].Volume,abs(shapes[0].Volume-volume)))
|
||||
App.closeDocument(d.Name)
|
||||
(out/'validation.txt').write_text('\n'.join(logs)+'\n',encoding='utf-8')
|
||||
(out/'DONE.txt').write_text('ok',encoding='utf-8')
|
||||
except Exception:
|
||||
(out/'ERROR.txt').write_text(traceback.format_exc()+'\n'+'\n'.join(logs),encoding='utf-8')
|
||||
finally:
|
||||
for d in list(App.listDocuments().values()):App.closeDocument(d.Name)
|
||||
Gui.getMainWindow().close()
|
||||
Reference in New Issue
Block a user