FreeCAD Python API实战:10个提升建模效率的脚本案例
你是否还在为重复的建模操作浪费时间?本文将通过10个实用的Python脚本案例,展示如何利用FreeCAD Python API(应用程序编程接口)自动化建模流程,显著提升设计效率。读完本文,你将能够编写简单的脚本完成复杂模型的创建、修改和管理,从重复劳动中解放出来,专注于创意设计。
1. 快速创建基础几何体
FreeCAD的Draft模块提供了丰富的基础几何体创建函数。以下脚本演示如何快速创建立方体、圆柱体和球体,并设置它们的位置和颜色。
import FreeCAD as App
import Draft
# 创建新文档
doc = App.newDocument("基础几何体示例")
# 创建立方体
cube = Draft.make_cube(length=10, width=10, height=10)
cube.Placement.Base = App.Vector(0, 0, 0) # 设置位置
cube.Label = "立方体" # 设置名称
# 创建圆柱体
cylinder = Draft.make_cylinder(radius=5, height=20)
cylinder.Placement.Base = App.Vector(20, 0, 0)
cylinder.Label = "圆柱体"
cylinder.ViewObject.ShapeColor = (0.5, 0.5, 1.0) # 设置颜色为浅蓝色
# 创建球体
sphere = Draft.make_sphere(radius=8)
sphere.Placement.Base = App.Vector(40, 0, 0)
sphere.Label = "球体"
sphere.ViewObject.ShapeColor = (1.0, 0.5, 0.5) # 设置颜色为浅红色
doc.recompute() # 重新计算文档
这段脚本使用了Draft.make_cube、Draft.make_cylinder和Draft.make_sphere函数创建基础几何体。通过设置Placement.Base属性可以精确定位模型,ViewObject.ShapeColor则用于改变模型的显示颜色。相关函数定义可参考src/Mod/Draft/draftmake/make_cube.py、src/Mod/Draft/draftmake/make_cylinder.py和src/Mod/Draft/draftmake/make_sphere.py。
2. 批量创建阵列特征
当需要创建多个相同或相似的特征时,阵列功能非常有用。以下脚本使用Draft模块的极坐标阵列功能,围绕中心点创建多个均匀分布的圆柱体。
import FreeCAD as App
import Draft
doc = App.newDocument("极坐标阵列示例")
# 创建原始圆柱体
cylinder = Draft.make_cylinder(radius=2, height=15)
cylinder.Placement.Base = App.Vector(10, 0, 0)
cylinder.Label = "原始圆柱"
# 创建极坐标阵列
polar_array = Draft.make_polar_array(
base_object=cylinder,
number=8, # 阵列数量
angle=360, # 阵列总角度(度)
center=App.Vector(0, 0, 0) # 阵列中心
)
polar_array.Label = "极坐标阵列"
doc.recompute()
Draft.make_polar_array函数根据指定的数量、角度和中心点创建极坐标阵列。你还可以使用Draft.make_ortho_array创建矩形阵列,或Draft.make_path_array沿路径创建阵列。相关实现可查看src/Mod/Draft/draftmake/make_polararray.py。
3. 自动生成参数化模型
参数化设计是FreeCAD的核心功能之一。以下脚本创建一个参数化的螺栓模型,通过修改参数可以轻松调整螺栓的尺寸。
import FreeCAD as App
import Part
import PartDesign
doc = App.newDocument("参数化螺栓")
# 创建草图
body = PartDesign.Body(doc)
doc.addObject(body)
sketch = body.newObject('Sketcher::SketchObject', '螺栓头部草图')
sketch.Support = (doc.getObject('XY_Plane'), [''])
sketch.MapMode = 'FlatFace'
# 在草图中绘制六边形(螺栓头部)
geoList = []
geoList.append(Part.LineSegment(App.Vector(0, 5, 0), App.Vector(4.33, 2.5, 0)))
geoList.append(Part.LineSegment(App.Vector(4.33, 2.5, 0), App.Vector(4.33, -2.5, 0)))
geoList.append(Part.LineSegment(App.Vector(4.33, -2.5, 0), App.Vector(0, -5, 0)))
geoList.append(Part.LineSegment(App.Vector(0, -5, 0), App.Vector(-4.33, -2.5, 0)))
geoList.append(Part.LineSegment(App.Vector(-4.33, -2.5, 0), App.Vector(-4.33, 2.5, 0)))
geoList.append(Part.LineSegment(App.Vector(-4.33, 2.5, 0), App.Vector(0, 5, 0)))
sketch.addGeometry(geoList, False)
# 添加约束
conList = []
conList.append(Sketcher.Constraint('Equal', 0, 1))
conList.append(Sketcher.Constraint('Equal', 1, 2))
conList.append(Sketcher.Constraint('Equal', 2, 3))
conList.append(Sketcher.Constraint('Equal', 3, 4))
conList.append(Sketcher.Constraint('Equal', 4, 5))
conList.append(Sketcher.Constraint('Equal', 5, 0))
conList.append(Sketcher.Constraint('Radius', 0, 5)) # 六边形外接圆半径
sketch.addConstraint(conList)
# 拉伸草图创建螺栓头部
pad = body.newObject("PartDesign::Pad", "螺栓头部")
pad.Profile = sketch
pad.Length = 6 # 拉伸长度
# 创建螺栓杆
sketch2 = body.newObject('Sketcher::SketchObject', '螺栓杆草图')
sketch2.Support = (pad, ['Face6'])
sketch2.MapMode = 'FlatFace'
sketch2.addGeometry(Part.Circle(App.Vector(0, 0, 0), App.Vector(0, 0, 1), 3), False)
sketch2.addConstraint(Sketcher.Constraint('Radius', 0, 3))
pad2 = body.newObject("PartDesign::Pad", "螺栓杆")
pad2.Profile = sketch2
pad2.Length = 30
doc.recompute()
这个例子展示了如何使用PartDesign工作台创建参数化模型。通过修改草图的尺寸约束(如六边形半径、拉伸长度等),可以轻松调整螺栓的大小。更多参数化设计的示例可参考src/Mod/PartDesign目录下的相关代码。
4. 模型自动标注尺寸
为模型添加尺寸标注是设计文档的重要部分。以下脚本使用TechDraw模块自动为模型添加线性尺寸标注。
import FreeCAD as App
import TechDraw
from TechDraw import TechDrawGui
doc = App.newDocument("自动标注示例")
# 创建一个立方体
cube = doc.addObject("Part::Box", "立方体")
cube.Length = 20
cube.Width = 15
cube.Height = 10
# 创建工程图页面
page = TechDraw.newPage("Page", "A4_Landscape")
# 创建视图
view = TechDraw.newView("View", cube)
page.addView(view)
view.X = 100
view.Y = 100
view.Scale = 1.0
# 自动标注长度尺寸
dim_length = TechDraw.makeDimension(page, view, 'Edge1', 'Edge7')
dim_length.Label = "长度标注"
# 自动标注宽度尺寸
dim_width = TechDraw.makeDimension(page, view, 'Edge2', 'Edge4')
dim_width.Label = "宽度标注"
doc.recompute()
TechDrawGui.fitPage(page) # 调整页面以适应视图
TechDraw.makeDimension函数用于创建尺寸标注,需要指定页面、视图以及要标注的边。TechDraw模块还提供了多种其他标注工具,如角度标注、半径标注等。相关实现可查看src/Mod/TechDraw/App/Dimension.cpp和src/Mod/TechDraw/Gui/DimensionGui.cpp。
5. 自动生成BOM表
物料清单(BOM)是制造过程中不可或缺的文档。以下脚本遍历模型中的所有零件,提取相关信息并生成简单的BOM表。
import FreeCAD as App
import csv
def generate_bom(doc, filename):
"""生成物料清单并保存到CSV文件"""
bom_data = []
# 遍历文档中的所有对象
for obj in doc.Objects:
# 只考虑实体对象
if hasattr(obj, "Shape") and obj.Shape.Solids:
# 获取对象基本信息
item = {
"名称": obj.Label,
"类型": obj.TypeId.split("::")[-1],
"体积": round(obj.Shape.Volume, 4), # 体积(立方毫米)
"质量": round(obj.Shape.Volume * 7.85 / 1000, 4) # 估算质量(克,假设密度7.85g/cm³)
}
bom_data.append(item)
# 保存到CSV文件
if bom_data:
with open(filename, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=bom_data[0].keys())
writer.writeheader()
writer.writerows(bom_data)
App.Console.PrintMessage(f"BOM表已保存到 {filename}\n")
else:
App.Console.PrintWarning("未找到实体对象,无法生成BOM表\n")
# 示例用法
doc = App.ActiveDocument or App.newDocument("BOM示例")
# 假设文档中已有模型对象...
generate_bom(doc, "物料清单.csv")
这个函数遍历文档中的所有对象,筛选出具有实体形状的对象,然后提取名称、类型、体积等信息,最后保存到CSV文件中。你可以根据需要扩展这个函数,添加更多属性或自定义格式。FreeCAD的TechDraw模块也提供了更专业的BOM表生成工具,相关代码可参考src/Mod/TechDraw/App/DrawViewBill.cpp。
6. 模型批量导出
在协作或制造过程中,经常需要将模型导出为不同格式。以下脚本演示如何批量将选中的对象导出为STL格式文件。
import FreeCAD as App
import Mesh
def batch_export_stl(objects, directory, prefix="part_"):
"""批量导出对象为STL格式"""
if not objects:
App.Console.PrintWarning("未选择对象\n")
return
for i, obj in enumerate(objects):
if not hasattr(obj, "Shape"):
App.Console.PrintWarning(f"对象 {obj.Label} 没有形状,跳过\n")
continue
# 创建导出文件名
filename = f"{directory}/{prefix}{i+1}_{obj.Label}.stl"
# 导出为STL
Mesh.export([obj], filename)
App.Console.PrintMessage(f"已导出: {filename}\n")
# 示例用法
selected_objects = App.Gui.Selection.getSelection() # 获取当前选中的对象
if selected_objects:
batch_export_stl(selected_objects, "/path/to/export/directory")
else:
App.Console.PrintWarning("请先选择要导出的对象\n")
Mesh.export函数可以将一个或多个对象导出为STL格式。FreeCAD还支持导出为STEP、IGES、OBJ等多种格式,相关功能可在src/Mod/Import/App和src/Mod/Export/App目录中找到。
7. 自动检查模型几何错误
复杂模型可能存在几何错误,如非流形边、重复面等。以下脚本使用Part模块的检查功能,自动检测模型中的常见几何问题。
import FreeCAD as App
import Part
def check_geometry(obj):
"""检查对象几何错误并返回结果"""
if not hasattr(obj, "Shape"):
return {"status": "错误", "消息": "对象没有形状"}
shape = obj.Shape
errors = []
# 检查非流形边
non_manifold_edges = shape.checkNonManifoldEdges()
if non_manifold_edges:
errors.append(f"非流形边: {len(non_manifold_edges)} 个")
# 检查自由边
free_edges = shape.checkFreeEdges()
if free_edges:
errors.append(f"自由边: {len(free_edges)} 个")
# 检查重复面
duplicate_faces = shape.checkDuplicateFaces()
if duplicate_faces:
errors.append(f"重复面: {len(duplicate_faces)} 个")
if errors:
return {"status": "警告", "消息": "; ".join(errors)}
else:
return {"status": "正常", "消息": "未发现明显几何错误"}
# 示例用法
doc = App.ActiveDocument
if doc:
for obj in doc.Objects:
result = check_geometry(obj)
App.Console.PrintMessage(f"{obj.Label}: {result['status']} - {result['message']}\n")
else:
App.Console.PrintWarning("没有活动文档\n")
这个函数使用了Part模块提供的checkNonManifoldEdges、checkFreeEdges和checkDuplicateFaces等方法来检测常见的几何问题。更详细的几何检查功能可参考src/Mod/Part/App/TopoShape.cpp中的相关实现。
8. 从CSV文件导入数据创建模型
当需要根据外部数据创建模型时,可以从CSV文件导入数据。以下脚本读取包含多个圆柱体参数的CSV文件,并批量创建相应的圆柱体。
import FreeCAD as App
import Draft
import csv
def import_cylinders_from_csv(filename):
"""从CSV文件导入数据并创建圆柱体"""
doc = App.ActiveDocument or App.newDocument("从CSV导入")
with open(filename, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
try:
# 解析CSV数据
name = row.get('名称', f"圆柱_{len(doc.Objects)+1}")
radius = float(row['半径'])
height = float(row['高度'])
x = float(row.get('X', 0))
y = float(row.get('Y', 0))
z = float(row.get('Z', 0))
# 创建圆柱体
cylinder = Draft.make_cylinder(radius=radius, height=height)
cylinder.Placement.Base = App.Vector(x, y, z)
cylinder.Label = name
App.Console.PrintMessage(f"已创建: {name} (半径: {radius}, 高度: {height})\n")
except Exception as e:
App.Console.PrintError(f"处理行时出错: {row},错误: {str(e)}\n")
doc.recompute()
# 示例用法
import_cylinders_from_csv("cylinders_data.csv")
CSV文件应包含列:名称,半径,高度,X,Y,Z。这个脚本展示了如何将外部数据集成到FreeCAD建模流程中,适用于从其他系统导入设计参数的场景。
9. 使用Python脚本创建自定义工作流程
结合多个API功能,可以创建复杂的自定义工作流程。以下脚本创建一个包含多个步骤的工作流程:创建基础形状、添加特征、生成工程图和导出BOM表。
import FreeCAD as App
import Draft
import TechDraw
import PartDesign
def custom_workflow():
"""自定义工作流程示例"""
# 1. 创建新文档
doc = App.newDocument("自定义工作流程示例")
# 2. 创建基础模型
body = PartDesign.Body(doc)
doc.addObject(body)
sketch = body.newObject('Sketcher::SketchObject', '底座草图')
sketch.Support = (doc.getObject('XY_Plane'), [''])
sketch.MapMode = 'FlatFace'
sketch.addGeometry(Part.Rectangle(App.Vector(-15, -10, 0), App.Vector(15, 10, 0)), False)
pad = body.newObject("PartDesign::Pad", "底座")
pad.Profile = sketch
pad.Length = 5
# 3. 添加孔特征
sketch2 = body.newObject('Sketcher::SketchObject', '孔草图')
sketch2.Support = (pad, ['Face6'])
sketch2.MapMode = 'FlatFace'
sketch2.addGeometry(Part.Circle(App.Vector(-10, -5, 0), App.Vector(0, 0, 1), 2), False)
sketch2.addGeometry(Part.Circle(App.Vector(10, -5, 0), App.Vector(0, 0, 1), 2), False)
sketch2.addGeometry(Part.Circle(App.Vector(0, 5, 0), App.Vector(0, 0, 1), 2), False)
hole = body.newObject("PartDesign::Hole", "孔")
hole.Profile = sketch2
hole.Diameter = 4
hole.Depth = 10
hole.Type = 'ThroughAll'
# 4. 生成工程图
page = TechDraw.newPage("Page", "A4_Landscape")
view = TechDraw.newView("View", body)
page.addView(view)
view.X = 100
view.Y = 100
view.Scale = 1.0
# 5. 标注尺寸
TechDraw.makeDimension(page, view, 'Edge1', 'Edge7') # 长度
TechDraw.makeDimension(page, view, 'Edge2', 'Edge4') # 宽度
# 6. 导出BOM表
generate_bom(doc, "custom_workflow_bom.csv")
doc.recompute()
App.Console.PrintMessage("自定义工作流程完成\n")
# 调用工作流程
custom_workflow()
这个综合示例展示了如何将多个FreeCAD功能组合成一个完整的工作流程。通过编写类似的脚本,你可以自动化特定领域的设计流程,大幅提高工作效率。
10. 使用外部库扩展FreeCAD功能
FreeCAD可以利用Python丰富的第三方库扩展功能。以下脚本使用NumPy库生成复杂的数学曲面,并在FreeCAD中创建对应的3D模型。
import FreeCAD as App
import Draft
import numpy as np
def create_math_surface():
"""使用NumPy创建数学曲面"""
doc = App.newDocument("数学曲面示例")
# 生成网格数据
x = np.linspace(-10, 10, 50)
y = np.linspace(-10, 10, 50)
X, Y = np.meshgrid(x, y)
# 计算Z值(使用正弦函数创建波浪面)
Z = 3 * np.sin(np.sqrt(X**2 + Y**2)) / (0.5 * np.sqrt(X**2 + Y**2 + 1))
# 创建点列表
points = []
for i in range(len(x)):
for j in range(len(y)):
points.append(App.Vector(X[i,j], Y[i,j], Z[i,j]))
# 创建网格面
faces = []
for i in range(len(x)-1):
for j in range(len(y)-1):
p1 = i * len(y) + j
p2 = p1 + 1
p3 = (i+1) * len(y) + j + 1
p4 = (i+1) * len(y) + j
faces.append([p4, p3, p2, p1]) # 四边形面
# 创建形状
mesh = App.ActiveDocument.addObject("Mesh::Feature", "数学曲面")
mesh.Mesh = Mesh.Mesh(points, faces)
mesh.ViewObject.ShapeColor = (0.2, 0.8, 0.2) # 绿色
doc.recompute()
# 确保已安装NumPy
try:
import numpy as np
create_math_surface()
except ImportError:
App.Console.PrintError("需要安装NumPy库,请使用命令: pip install numpy\n")
这个例子展示了如何将科学计算库NumPy与FreeCAD结合,创建复杂的数学驱动形状。通过集成外部Python库,你可以为FreeCAD添加几乎无限的功能扩展。
总结与展望
本文介绍的10个Python脚本案例展示了FreeCAD API的强大功能,从简单的几何体创建到复杂的工作流程自动化。通过编写自定义脚本,你可以:
- 自动化重复的建模任务
- 创建参数化设计,轻松修改模型尺寸
- 生成工程图和BOM表,加速文档编制
- 导入/导出数据,与其他软件集成
- 实现自定义设计规则和检查
随着对FreeCAD API的深入了解,你可以开发更复杂的脚本和插件,完全定制FreeCAD以满足特定的设计需求。FreeCAD的开源性质意味着你还可以查看和学习其源代码,甚至为项目贡献自己的改进。
FreeCAD的Python API为用户提供了无限可能,鼓励你探索更多高级功能,如创建自定义工具栏、开发完整的插件,或与外部CAD/CAE系统集成。通过不断实践和探索,你将能够充分利用FreeCAD的潜力,成为更高效的设计工程师。
要获取更多FreeCAD Python API的信息和示例,可以参考以下资源:
- FreeCAD官方文档:src/Doc/sphinx
- FreeCAD Python教程:README.md
- API参考:src/App/DocumentPy.cpp
- 社区贡献的脚本和插件:src/Mod
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



