from pathlib import Path import FreeCAD as A, Part, math, json, traceback try: folder=Path(r'C:\projects\wheel\models\70_m4_threaded') d=A.openDocument(str(folder/'70_M4_threaded.FCStd'));d.recompute() h=d.getObject('ThreadHoles');s=d.getObject('ThreadProfiles');f=d.getObject('FinishedPlate');p=d.getObject('Parameters') step=Part.read(str(folder/'70_M4_threaded.step')) radii=[round((g.Center.x**2+g.Center.y**2)**0.5,5) for g in s.Geometry if hasattr(g,'Radius')] types={} for face in step.Faces: key=type(face.Surface).__name__;types[key]=types.get(key,0)+1 out={'fcstd_valid':f.Shape.isValid(),'fcstd_solids':len(f.Shape.Solids),'fcstd_volume':f.Shape.Volume,'fcstd_faces':len(f.Shape.Faces),'step_valid':step.isValid(),'step_solids':len(step.Solids),'step_volume':step.Volume,'step_faces':len(step.Faces),'step_surface_types':types,'thread_feature':{'size':h.ThreadSize,'thread_type':h.ThreadType,'threaded':h.Threaded,'model_thread':h.ModelThread,'depth_type':h.DepthType,'minor_diameter':h.Diameter.Value,'thread_diameter':h.ThreadDiameter.Value},'circles':len(radii),'circle_radii':sorted(radii),'countersink_diameter':p.get('B14'),'countersink_depth':p.get('B16'),'plate_thickness':p.get('B2'),'pcd_values':[p.get('B5'),p.get('B7'),p.get('B9'),p.get('B11')],'holes_profile_state':s.State,'final_state':f.State} (folder/'validation.json').write_text(json.dumps(out,ensure_ascii=False,indent=2,default=str),encoding='utf-8') except: Path(r'C:\projects\wheel\models\70_m4_threaded\validation_error.txt').write_text(traceback.format_exc(),encoding='utf-8') for name in list(A.listDocuments()): A.closeDocument(name) Gui.getMainWindow().close()