47 lines
3.5 KiB
Plaintext
47 lines
3.5 KiB
Plaintext
from pathlib import Path
|
|
import os, json, math, traceback
|
|
import FreeCAD as App
|
|
import FreeCADGui as Gui
|
|
import Import, Part
|
|
|
|
root = Path(r'C:\projects\wheel')
|
|
out = root / 'models' / '70_m4_drill_quote'
|
|
out.mkdir(parents=True, exist_ok=True)
|
|
try:
|
|
os.chdir(str(root))
|
|
base = (root / 'scripts' / 'build_70.py').read_text(encoding='utf-8')
|
|
base = base.replace("target = os.path.join(root, 'models', '\\u0037\\u0030\\u8f6c\\u63a5\\u677f_\\u53c2\\u6570\\u5316.FCStd')", "target = str(out / '70_M4_drill.FCStd')")
|
|
base = base.replace("('HoleDiameter', '4.234 mm', 'Through hole diameter (all 24 holes)')", "('HoleDiameter', '3.3 mm', 'M4 tapping pilot diameter for all 24 holes')")
|
|
base = base.replace("print('OUTPUT', target)", "Import.export([final], str(out / '70_M4_drill.step'))\nGui.activeDocument().activeView().saveImage(str(out / '70_M4_drill.png'), 1600, 1200, 'White')\nprint('OUTPUT', target)")
|
|
if "target = str(out / '70_M4_drill.FCStd')" not in base or "'3.3 mm'" not in base:
|
|
raise RuntimeError('Failed to patch baseline; original file not modified')
|
|
exec(compile(base, str(root/'scripts'/'build_70.py'), 'exec'), {'out':out, '__name__':'__main__'})
|
|
for name in list(App.listDocuments()): App.closeDocument(name)
|
|
f=App.openDocument(str(out/'70_M4_drill.FCStd')); f.recompute()
|
|
plate=f.getObject('FinishedPlate'); shape=plate.Shape
|
|
assert shape.isValid() and len(shape.Solids)==1
|
|
assert abs(f.getObject('Hole42_0').Radius.Value-1.65)<1e-8
|
|
assert abs(f.getObject('Countersink0').Height.Value-1.75)<1e-8
|
|
step=App.newDocument('VerifyExport'); Import.insert(str(out/'70_M4_drill.step'), step.Name); step.recompute()
|
|
stepShapes=[o.Shape for o in step.Objects if hasattr(o,'Shape') and not o.Shape.isNull()]
|
|
assert len(stepShapes)==1 and stepShapes[0].isValid() and len(stepShapes[0].Solids)==1
|
|
cylinder_faces=[]
|
|
for face in stepShapes[0].Faces:
|
|
surf=face.Surface
|
|
if isinstance(surf,Part.Cylinder) and abs(surf.Radius-1.65)<1e-6 and abs(abs(surf.Axis.z)-1)<1e-7:
|
|
center=surf.Center
|
|
cylinder_faces.append({'x':round(center.x,6),'y':round(center.y,6),'z_min':round(face.BoundBox.ZMin,6),'z_max':round(face.BoundBox.ZMax,6),'r':surf.Radius})
|
|
assert len(cylinder_faces)==24, 'Expected 24 pilot cylinders, found '+str(len(cylinder_faces))
|
|
radii=sorted(round(math.hypot(c['x'],c['y']),4) for c in cylinder_faces)
|
|
assert radii == [21.0]*6+[24.0]*6+[25.4]*6+[35.0]*6, str(radii)
|
|
pcd42=[c for c in cylinder_faces if abs(math.hypot(c['x'],c['y'])-21)<0.001]
|
|
assert all(abs(c['z_min']-1.75)<1e-6 and abs(c['z_max']-8)<1e-6 for c in pcd42)
|
|
assert all(abs(c['z_min'])<1e-6 and abs(c['z_max']-8)<1e-6 for c in cylinder_faces if c not in pcd42)
|
|
result={'fcstd_valid':True,'fcstd_solids':1,'step_valid':True,'step_solids':1,'step_volume':stepShapes[0].Volume,'pilot_diameter_mm':3.3,'number_pilot_cylinders':len(cylinder_faces),'positions_and_extents':cylinder_faces,'countersink_diameter_mm':6.8,'countersink_angle_deg':90,'countersink_depth_mm':1.75,'pcd42_straight_segment_mm':6.25,'other_straight_segment_mm':8.0,'interpretation':'These are smooth pilot holes, not semantic or geometric threads. Automatic quotation recognition untested.'}
|
|
(out/'validation.json').write_text(json.dumps(result,ensure_ascii=False,indent=2),encoding='utf-8')
|
|
(out/'status.txt').write_text('OK',encoding='utf-8')
|
|
except:
|
|
(out/'status.txt').write_text(traceback.format_exc(),encoding='utf-8')
|
|
for name in list(App.listDocuments()): App.closeDocument(name)
|
|
Gui.getMainWindow().close()
|