FreeCAD Python API 实战指南:6 类自动化脚本让建模效率翻倍
【免费下载链接】FreeCADOfficial source code of FreeCAD, a free and opensource multiplatform 3D parametric modeler.项目地址: https://gitcode.com/GitHub_Trending/fr/FreeCAD
你有没有这样的经历:同一个法兰盘,换了 8 个规格就要重复画 8 遍;装配前 200 个零件要挨个点"另存为"导出;图纸标注全靠鼠标一条一条拉。这些活儿都不难,但就是费时间。
FreeCAD 的 Python API 就是为这类重复劳动准备的:几乎所有工作台的按钮,背后都有一个脚本能调用的函数。本文按"能力进阶"的思路,带你用 6 类自动化脚本(基础几何、参数化建模、工程标注与 BOM、数据集成、组合工作流)把 FreeCAD 变成一个自动化建模流水线,全程只用能直接跑通的最小代码。
从重复操作解放:一段脚本画出整个零件
⚡️ 第一层自动化,就是把"点击"换成"代码"。
新建文档、放几何体、定位置、上色,这些操作在 Draft 工作台里每个都有对应函数。下面这段脚本 20 行,产出一个带布局的零件集合:
import FreeCAD as App import Draft doc = App.newDocument("bracket") # 新建文档,名字随意 cyl = Draft.make_cylinder(radius=6, height=24) cyl.Placement.Base = App.Vector(0, 0, 0) # 定位到原点 cyl.ViewObject.ShapeColor = (0.35, 0.55, 0.85) for i in range(4): # 顶部一圈小圆柱(定位销孔位示意) pin = Draft.make_cylinder(radius=1.5, height=8) pin.Placement.Base = App.Vector((i - 1.5) * 12, 10, 0) sph = Draft.make_sphere(radius=5) sph.Placement.Base = App.Vector(0, 0, 30) doc.recompute() # 触发重算,让 3D 视图刷新两个值得记住的要点:
Placement.Base决定位置,改一个数就能整体平移,比手动拖拽精确得多。ViewObject.ShapeColor改颜色,批量区分不同零件时非常好用。
想看懂这些函数内部怎么实现的,可以去 Draft 模块 目录翻源码,draftmake文件夹里一个文件对应一个创建函数。
参数化建模:改一行数字,整个零件跟着变
🔧 会建模型,更会"变"模型,才是脚本的价值所在。
PartDesign 的草图约束可以完全用代码写,约束一旦写好,尺寸就是参数。下面是个六角螺栓的最小版本——把head_w改成别的值,头部六边形会跟着变:
import FreeCAD as App import Part, PartDesign, Sketcher doc = App.newDocument("bolt") body = doc.addObject("PartDesign::Body", "Body") # 草图:六边形轮廓 sk = body.newObject("Sketcher::SketchObject", "HeadProfile") sk.AttachmentSupport = (doc.Origin.OriginFeatures[3], [""]) # 附着到 XY 基准面 sk.MapMode = "FlatFace" head_w = 10.0 # 参数:头部对角宽度 pts = [App.Vector(head_w/2, 0, 0)] for k in range(1, 6): a = 3.14159265 * k / 3 pts.append(App.Vector(head_w/2 * __import__('math').cos(a), head_w/2 * __import__('math').sin(a), 0)) for i in range(6): # 6 条边围成六边形 sk.addGeometry(Part.LineSegment(pts[i], pts[(i+1) % 6]), False) pad = body.newObject("PartDesign::Pad", "Head") pad.Profile = sk pad.Length = 6.0 doc.recompute()再进一步,把参数放到电子表格里。这是 FreeCAD 参数化的隐藏大招——约束、特征长度都能绑定到单元格,建模师再也不用进代码:
sheet = doc.addObject("Spreadsheet::Sheet", "Params") sheet.set("A1", "dia"); sheet.set("B1", "5") # 杆径 5mm sk2 = body.newObject("Sketcher::SketchObject", "ShankProfile") sk2.AttachmentSupport = (doc.getObject("Pad"), ["Face1"]) sk2.MapMode = "FlatFace" sk2.addGeometry(Part.Circle(App.Vector(0, 0, 0), App.Vector(0, 0, 1), 2.5), False) sk2.setExpression("Constraints[0]", "Params.dia / 2") # 半径跟着表格走 shank = body.newObject("PartDesign::Pad", "Shank") shank.Profile = sk2 shank.Length = 24.0 doc.recompute() # 改 sheet B1 的值,整个螺栓杆径自动联动特征数组也一样能脚本化。比如给法兰盘均匀布孔,一行搞定:
hole = Draft.make_cylinder(radius=2, height=30) Draft.make_polar_array(hole, number=8, angle=360, center=App.Vector(0, 0, 0)) # 8 孔均布矩形阵列(make_ortho_array)、沿路径阵列(make_path_array)都遵循同样的调用模式,源码在 Draft 的 draftmake 目录。
工程文档自动化:标注和 BOM 不再手搓
📦 模型做完,图纸和物料清单才是交付的最后一公里。
自动生成工程标注
TechDraw 的页面、视图、尺寸标注全部可以脚本创建。这段代码产出一张带长度标注的零件图:
import FreeCAD as App import TechDraw doc = App.ActiveDocument box = doc.getObject("Box") or doc.addObject("Part::Box", "Box") box.Length, box.Width, box.Height = 40, 24, 16 page = doc.addObject("TechDraw::DrawPage", "Page") tpl = doc.addObject("TechDraw::DrawSVGTemplate", "Tpl") tpl.Template = App.getResourceDir() + "Mod/TechDraw/Templates/A4_Landscape_blank.svg" page.Template = tpl view = doc.addObject("TechDraw::DrawViewPart", "Front") page.addView(view) view.Source = [box] view.Direction = (0, -1, 0) view.Scale = 2.0 dim = doc.addObject("TechDraw::DrawViewDimension", "LenDim") dim.Type = "DistanceX" dim.References2D = [(view, "Edge0"), (view, "Edge1")] page.addView(dim) doc.recompute()References2D里写的是视图上的边编号(Edge0、Edge1……),先用脚本建视图,重算后就能从视图属性里读出编号,再把标注"钉"上去。角度、半径、直径标注同理,只是Type换成别的值。
一键生成 BOM
物料清单本质是遍历对象、导出属性。这个函数可以直接贴进你的宏里:
import FreeCAD as App import csv def make_bom(doc, out): rows = [] for obj in doc.Objects: shape = getattr(obj, "Shape", None) if shape is not None and shape.Solids: rows.append([obj.Label, obj.TypeId, round(shape.Volume / 1000, 3)]) # 体积换算成 cm³ with open(out, "w", newline="", encoding="utf-8-sig") as f: w = csv.writer(f) w.writerow(["名称", "类型", "体积(cm³)"]) w.writerows(rows) print(f"BOM 已写入 {out},共 {len(rows)} 项")想更专业的表格形式,TechDraw 里也有现成的 BOM 视图对象,实现可以参考 TechDraw 模块 源码。
数据进出与体检:把 FreeCAD 接进你的流程
🚀 自动化建模的完整闭环,还包括"数据从哪来、结果到哪去、对不对"。
一键批量导出 STL
3D 打前要批量导 STL?选中的对象循环导出即可:
import FreeCAD as App import Mesh import os def export_stl(objs, out_dir): os.makedirs(out_dir, exist_ok=True) for i, o in enumerate(objs, 1): if not hasattr(o, "Shape") or not o.Shape.Solids: print(f"跳过 {o.Label}:没有实体"); continue Mesh.export([o], os.path.join(out_dir, f"{i:03d}_{o.Label}.stl")) export_stl(App.Gui.Selection.getSelection(), "./stl_out")STEP、IGES 等格式的导出函数也都在src/Mod/Import与src/Mod/Export里,调用方式几乎一样。
几何体检:交付前查一遍
复杂模型常见问题是非流形边、自由边。一行代码就能体检:
def check_model(obj): r = obj.Shape.checkGeometry() # 返回 (是否通过, 详细信息) status = "正常" if r[0] else f"有问题:{r[1]}" print(f"{obj.Label}: {status}") return r[0]对每个零件跑一遍,有问题的单独拎出来修,比等 CAM 软件报错再倒查快得多。
用外部库扩展能力
FreeCAD 的 Python 环境就是标准 Python,第三方库随便用。用 NumPy 生成数学曲面,再转成 Mesh 塞进文档,二十来行就能做出波浪面、地形面这类手工很难画的形状——思路是:NumPy 算点云,Mesh.Mesh拼面片,addObject("Mesh::Feature")挂到文档。外部库让 FreeCAD 的边界从 CAD 延伸到数据处理。
组合层:一条流水线跑完建模到交付
把前面的能力串起来,就是一段可复用的工作流脚本。下面这条流水线:建参数化零件 → 布孔 → 生成 BOM → 批量导出 → 几何体检,一次全干完:
import FreeCAD as App import Part, PartDesign, Draft, csv, os doc = App.newDocument("flange") body = doc.addObject("PartDesign::Body", "Body") sk = body.newObject("Sketcher::SketchObject", "Outer") sk.AttachmentSupport = (doc.Origin.OriginFeatures[3], [""]) sk.MapMode = "FlatFace" sk.addGeometry(Part.Circle(App.Vector(0, 0, 0), App.Vector(0, 0, 1), 30), False) pad = body.newObject("PartDesign::Pad", "Disk") pad.Profile = sk pad.Length = 8 hole = Draft.make_cylinder(radius=2, height=8) Draft.make_polar_array(hole, number=8, angle=360, center=App.Vector(0, 0, 0)) doc.recompute() # 交付三件套 with open("flange_bom.csv", "w", newline="", encoding="utf-8-sig") as f: csv.writer(f).writerow(["Flange", "PartDesign::Body", round(body.Shape.Volume / 1000, 2)]) os.makedirs("stl_out", exist_ok=True) import Mesh Mesh.export([body], "stl_out/flange.stl") print("体检:", "通过" if body.Shape.checkGeometry()[0] else "有问题") print("流水线完成 ✅")参数化建模、自动标注、批量导出、BOM 生成,这些脚本单拎出来都有用,串起来就是整条自动化工作流。
下一步可以做什么
- 把脚本存成模板:常用的孔位、法兰、卡扣做成函数,参数一传就能出件,存进宏里随叫随到。
- 给团队定标准件:把公司常用件做成参数表驱动的脚本,新人也能按规范出图。
- 接入 CI:脚本不依赖界面,配合
App.Console打印日志,可以放进批处理里定时跑。 - 往工程标注和 BOM 深挖:TechDraw 的尺寸类型、装配模块的 BOM 导出,都能脚本化。
进一步学习
- 官方 Sphinx 文档目录:src/Doc/sphinx
- 核心 Python API 类型存根:src/App、src/Base(
.pyi文件就是 API 速查表) - Draft 建模函数源码:src/Mod/Draft/draftmake
- PartDesign 特征实现:src/Mod/PartDesign
- TechDraw 图纸与标注实现:src/Mod/TechDraw
想搞清楚某个功能怎么脚本化,最快的办法就是去对应的 Mod 目录翻它的 C++ 与 Python 实现——按钮背后一定藏着你需要的函数。
【免费下载链接】FreeCADOfficial source code of FreeCAD, a free and opensource multiplatform 3D parametric modeler.项目地址: https://gitcode.com/GitHub_Trending/fr/FreeCAD
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考