Files
wheel/scripts/validate_70_m4_drill_plain.FCMacro

58 lines
3.0 KiB
Plaintext

from pathlib import Path
import json, math, traceback
import FreeCAD as App
import Part
base=Path(r'C:\projects\wheel')
out=base/'models'/'70_m4_drill_plain'
try:
doc=App.openDocument(str(out/'70_M4_drill_plain.FCStd'))
doc.recompute()
final=doc.getObject('Cut70')
assert final and final.Shape.isValid() and len(final.Shape.Solids)==1
assert all(not str(obj.Name).startswith('Countersink') for obj in doc.Objects)
assert abs(doc.getObject('Parameters').get('B4').Value-3.3)<1e-8
step=Part.read(str(out/'70_M4_drill_plain.step'))
assert step.isValid() and len(step.Solids)==1
bores=[]
for f in step.Faces:
s=f.Surface
if isinstance(s,Part.Cylinder) and abs(s.Radius-1.65)<1e-6:
c=s.Center
bores.append({'x':round(c.x,6),'y':round(c.y,6),'z_span':round(f.BoundBox.ZLength,6),'radius':round(s.Radius,6)})
assert len(bores)==24, f'expected 24, got {len(bores)}'
assert all(abs(x['z_span']-8)<1e-6 for x in bores), bores
expected=[]
for pcd, ang in [(42,45),(48,0),(50.8,30),(70,30)]:
for i in range(6):
a=math.radians(ang+60*i)
expected.append((pcd/2*math.cos(a),pcd/2*math.sin(a)))
for x,y in expected:
assert min(math.hypot(b['x']-x,b['y']-y) for b in bores)<1e-5, (x,y)
src=Part.read(str(base/'models'/'70转接板.step'))
outline=doc.getObject('OuterChamfer').Shape
sections=[]
for z in (0.2,1,2,4,6,7,7.8):
sw=max(src.slice(App.Vector(0,0,1),z),key=lambda w:w.Length)
ow=max(outline.slice(App.Vector(0,0,1),z),key=lambda w:w.Length)
sf,of=Part.Face(sw),Part.Face(ow)
a=sf.cut(of).Area; b=of.cut(sf).Area
sections.append({'z':z,'source_minus_new_area':a,'new_minus_source_area':b})
assert a<1e-4 and b<1e-4, (z,a,b)
refs=[obj for obj in doc.Objects if obj.Label=='Original STEP - reference (hidden)']
assert len(refs)==1 and not refs[0].ViewObject.Visibility
sheet=doc.getObject('Parameters')
oldcenter=doc.getObject('Hole42_0').Placement.Base
sheet.set('B6','46 deg');doc.recompute()
newcenter=doc.getObject('Hole42_0').Placement.Base
movement=(newcenter-oldcenter).Length
assert movement>0.36 and final.Shape.isValid()
# No save: the production file remains at the original 45-degree phase.
result={'fcstd_valid':True,'step_valid':True,'fcstd_solids':1,'step_solids':len(step.Solids),'step_volume':step.Volume,'bore_count':len(bores),'bore_diameter_mm':3.3,'bore_full_depth_mm':8,'expected_locations_matched':True,'counterbores_removed':True,'source_outline_sections':sections,'source_reference_hidden':True,'parameter_angle_test_movement_mm':movement,'parameter_angle_test_saved':False}
(out/'validation.json').write_text(json.dumps(result,indent=2),encoding='utf-8')
(out/'validation_status.txt').write_text('OK',encoding='utf-8')
except:
(out/'validation_status.txt').write_text(traceback.format_exc(),encoding='utf-8')
for n in list(App.listDocuments()): App.closeDocument(n)
Gui.getMainWindow().close()