CadQuery Assembly 入门:从单零件到多零件装配体¶
本页是 V7 系列(单零件代码化建模)的**第一篇装配体入门**。V7A/V7B/V7C 演示了**单零件**的代码化建模(带孔板 / 圆角倒角 / 支架 Capstone),但真实产品几乎都是**多零件装配体**:底板 + 立板 + 螺栓 + 定位销等。
本页用 CadQuery 的 Assembly 概念,演示如何把多个零件组织为一个**完整装配体**,理解:
单零件模型与多零件装配体的区别
Assembly、Component、Location、Color、Name的基本概念如何用代码表达"在哪个位置放置哪个零件"
装配体与 CAM 加工、作品集展示的关系
教学定位:本页是**教学示例**,不追求工业级装配设计: - 不包含完整工程约束(配合公差、过盈/间隙计算等) - 不替代商业 CAD 装配设计工具 - 重点是让读者理解"装配体不是简单合并"
A. 本页解决什么问题¶
V7 系列已经讲完单零件代码化建模
阶段 |
内容 |
对应版本 |
单/多零件 |
|---|---|---|---|
入门 |
带孔矩形板 |
V7A |
单零件 |
进阶 |
圆角/倒角/孔阵列 + 简化支架 |
V7B |
单零件 |
综合 |
完整 L 型支架 Capstone |
V7C |
单零件(合并实体) |
收口 |
V7 系列三步走 |
V7D |
收口页 |
V8A 进一步解释多零件装配体¶
V7C 里的 L 型支架虽然是组合结构(底板 + 立板),但 CadQuery 代码里**合并**成了一个实体(base.union(vertical))。这种方式称为"单实体焊接"——所有特征都属于同一个 Workplane。
真实产品的设计是**多零件**:
底板、立板、螺栓、螺母、定位销是**独立零件**
每个零件可以单独加工、检测、运输
最后通过螺栓、销钉、焊接等方式**装配**成完整产品
CadQuery 用 Assembly 表达这种**多零件关系**,本节演示其基本用法。
B. 单零件 vs 装配体¶
下方对比两种建模方式的核心差异:
维度 |
单零件模型 |
装配体模型 |
评分 |
|---|---|---|---|
几何表达 |
一个 |
多个 |
互补 |
文件组织 |
一个 .py 文件 / 一个 .step |
多个 .py 文件或一个 .py / 多个零件 .step 或一个总 .step |
装配体更多 |
修改方式 |
改参数 → 重新生成单个 .step |
改参数 → 重新生成各零件 .step → 重新装配 |
装配体更复杂 |
导出用途 |
直接进 CAM / 3D 打印 |
展示用,加工要拆分为单零件 |
装配体更适合展示 |
作品集展示 |
提交 .step + 截图 |
提交装配体截图 + 零件分解 |
装配体更丰富 |
工程意义 |
焊接件 / 一体化零件 |
装配产品 / 可拆解维护 |
互补 |
CadQuery 表达 |
|
|
完全不同 |
关键区别:单零件 = 一个实体;装配体 = 多个独立零件 + 空间位置关系。
C. Assembly 基本概念¶
CadQuery 的 Assembly 用以下几个核心概念表达多零件关系:
概念 |
说明 |
CadQuery 表达 |
|---|---|---|
|
一个独立的零件(用 |
|
|
多个 Component 的容器 |
|
|
零件在装配体中的空间位置(平移 + 旋转) |
|
|
零件的名字(用于展示和检索) |
|
|
零件的颜色(用于可视化) |
|
|
通过 Location 显式放置(这是 CadQuery 的主要方式) |
|
|
把整个装配体导出为单个 STEP |
|
BOM |
物料清单(概念性理解,本教学例不实现) |
手工记录或外部生成 |
关键认识 :CadQuery 的 Assembly 主要是"展示"和"导出"工具,不 包含完整的"约束求解"功能(如"两个圆柱面必须同轴")。所有位置关系通过显式的 Location 数学表达。
D. 教学装配体设定¶
本节用一个**简化"支架装配体"** 演示 Assembly 用法。
组件清单¶
组件 |
数量 |
作用 |
对应 V6A / V7C |
|---|---|---|---|
base_plate |
1 |
底板(与 V6A/V7C 几何一致) |
V7C 底板 |
vertical_plate |
1 |
立板(与 V6A/V7C 几何一致) |
V7C 立板 |
mounting_bolt |
2 |
底板安装螺栓(教学示意) |
新增 |
side_pin |
1 |
立板定位销(教学示意) |
新增 |
教学声明¶
这**不是**完整工业装配(工业装配涉及公差、配合、过盈/间隙、拧紧力矩等)
螺栓和销钉的尺寸是教学示意值,不可直接用于实际设计
重点是理解组件、位置、装配关系
E. CadQuery Assembly 示例代码¶
下方代码展示如何用 Assembly 构造一个"底板 + 立板 + 2 个螺栓 + 1 个销钉"的简化支架装配体。
完整代码¶
"""
简化支架装配体 — CadQuery Assembly 教学示例 (V8A)
============================================
本文件是 CAD-CAM-Technology-docs 项目的 V8A 教学示例,
配合 examples/cadquery-assembly-intro.rst 使用。
教学目的
--------
演示如何用 CadQuery 的 Assembly 表达"底板 + 立板 + 螺栓 + 销钉"的多零件关系。
注意
----
本文件是教学示例(teaching example),不作为工业生产模型(not for industrial production):
- 螺栓和销钉的尺寸是教学示意值,不可直接用于实际设计
- 不包含工程约束(公差、配合、过盈/间隙等)
- 不替代商业 CAD 装配设计工具
- 真实工程中应根据需求选择合适的工具
与 V7C 区别
----------
- V7C bracket_capstone.py:底板 + 立板 union 成一个实体
- V8A bracket_assembly.py:底板、立板、螺栓、销钉作为独立零件 + Assembly 容器
依赖
----
- cadquery >= 2.0
- 安装:pip install cadquery
- 运行:python bracket_assembly.py
"""
import cadquery as cq
# ============================================================
# 参数集中区
# ============================================================
# 底板参数(与 V6A / V7C 一致)
base_length = 200.0
base_width = 60.0
base_thickness = 10.0
base_hole_diameter = 8.0
base_hole_spacing = 100.0
# 立板参数
vertical_length = 40.0
vertical_height = 100.0
vertical_thickness = 10.0
vertical_hole_diameter = 6.0
vertical_hole_spacing = 50.0
# 螺栓参数(教学示意)
bolt_diameter = 8.0 # 螺栓直径(与底板孔匹配)
bolt_head_diameter = 13.0 # 螺栓头直径
bolt_head_height = 5.0 # 螺栓头高度
bolt_length = 25.0 # 螺栓总长
bolt_count = 2 # 螺栓数量
# 销钉参数(教学示意)
pin_diameter = 6.0 # 销钉直径(与立板孔匹配)
pin_length = 15.0 # 销钉长度
# 圆角
fillet_radius = 3.0
# 输出文件名
output_step = "bracket_assembly.step"
# ============================================================
# 组件构造函数
# ============================================================
def make_base_plate():
"""构造底板(与 V7C 底板几何一致)。
坐标系:以原点为底板底面中心,底板向 +Z 方向延伸。
"""
plate = cq.Workplane("XY").box(
base_length, base_thickness, base_width
)
# 2 个底板安装孔
plate = (
plate
.faces(">Z")
.workplane()
.rect(base_hole_spacing, 0, forConstruction=True)
.vertices()
.hole(base_hole_diameter)
)
return plate
def make_vertical_plate():
"""构造立板(与 V7C 立板几何一致)。
坐标系:与底板相对定位。
"""
vertical = (
cq.Workplane("XY")
.transformed(offset=(vertical_length / 2.0, 0, base_thickness + vertical_height / 2.0))
.box(vertical_length, vertical_thickness, vertical_height)
)
# 1 个立板大孔(简化:销钉孔)
vertical = (
vertical
.faces(">Z")
.workplane()
.hole(vertical_hole_diameter)
)
return vertical
def make_bolt(head_diameter, head_height, shaft_diameter, shaft_length):
"""构造一个简化螺栓(教学示意)。
螺栓结构:圆柱头 + 圆柱杆。
注:实际工程中需要螺纹、退刀槽、扳手孔等细节。
"""
# 头(圆柱体 + 顶部倒角简化)
head = cq.Workplane("XY").circle(head_diameter / 2.0).extrude(head_height)
# 杆(圆柱体)
shaft = (
cq.Workplane("XY")
.workplane(offset=head_height)
.circle(shaft_diameter / 2.0)
.extrude(shaft_length - head_height)
)
# 合并
bolt = head.union(shaft)
return bolt
def make_pin(diameter, length):
"""构造一个简化销钉(教学示意)。"""
return cq.Workplane("XY").circle(diameter / 2.0).extrude(length)
# ============================================================
# 装配体构建
# ============================================================
def build_assembly():
"""构建完整的支架装配体。"""
# 创建装配体容器
assembly = cq.Assembly(name="bracket_assembly")
# 1. 添加底板(位于装配体原点)
base = make_base_plate()
assembly.add(
base,
name="base_plate",
color=cq.Color(0.7, 0.7, 0.8, 1.0), # 浅蓝色
)
# 2. 添加立板(位于底板左端上方)
vertical = make_vertical_plate()
assembly.add(
vertical,
name="vertical_plate",
loc=cq.Location(cq.Vector(0, 0, 0)), # 立板坐标已通过 make_vertical_plate 定位
color=cq.Color(0.7, 0.8, 0.7, 1.0), # 浅绿色
)
# 3. 添加螺栓(2 个,位于底板安装孔位)
# 螺栓头部朝上(+Y 方向),从底板上方插入
bolt = make_bolt(
head_diameter=bolt_head_diameter,
head_height=bolt_head_height,
shaft_diameter=bolt_diameter,
shaft_length=bolt_length,
)
# 螺栓 1:左侧孔位
assembly.add(
bolt,
name="bolt_left",
loc=cq.Location(
cq.Vector(
-base_hole_spacing / 2.0, # X 位置
base_thickness / 2.0, # Y 位置:板厚中心
base_thickness - bolt_length, # Z 位置:从板底穿出
)
),
color=cq.Color(0.8, 0.7, 0.5, 1.0), # 棕色
)
# 螺栓 2:右侧孔位
assembly.add(
bolt,
name="bolt_right",
loc=cq.Location(
cq.Vector(
base_hole_spacing / 2.0,
base_thickness / 2.0,
base_thickness - bolt_length,
)
),
color=cq.Color(0.8, 0.7, 0.5, 1.0),
)
# 4. 添加销钉(位于立板中心孔)
pin = make_pin(pin_diameter, pin_length)
assembly.add(
pin,
name="side_pin",
loc=cq.Location(
cq.Vector(
vertical_length / 2.0, # X:立板中心
vertical_thickness / 2.0, # Y:立板中心
base_thickness + vertical_height / 2.0 - pin_length / 2.0, # Z:立板中心
)
),
color=cq.Color(0.6, 0.6, 0.6, 1.0), # 灰色
)
return assembly
# ============================================================
# 主流程
# ============================================================
def main():
print(f"=== CadQuery 支架装配体 (V8A) ===")
print(f"组件清单:")
print(f" - 1 × base_plate ({base_length} x {base_thickness} x {base_width} mm)")
print(f" - 1 × vertical_plate ({vertical_length} x {vertical_thickness} x {vertical_height} mm)")
print(f" - {bolt_count} × mounting_bolt (M{bolt_diameter} 示意)")
print(f" - 1 × side_pin (Φ{pin_diameter} 示意)")
# 构建装配体
assembly = build_assembly()
# 导出整个装配体为单个 STEP
assembly.save(output_step)
print(f"[OK] 装配体已导出: {output_step}")
if __name__ == "__main__":
main()
代码逐段解读¶
组件独立性:
make_base_plate()、make_vertical_plate()、make_bolt()、make_pin() 各自返回独立的 Workplane,不 合并。
装配体容器:
cq.Assembly(name="...") 创建一个装配体容器,所有零件都加到这里。
位置表达:
cq.Location(cq.Vector(x, y, z)) 表达"在 (x, y, z) 位置放置这个零件"。本例里螺栓和销钉的坐标都通过数学计算确定。
颜色区分:
color=cq.Color(r, g, b, alpha) 给每个零件不同颜色,便于可视化(不影响几何)。
导出:
assembly.save("xxx.step") 把整个装配体导出为单个 STEP 文件(包含所有零件)。
F. 组件与参数对照表¶
下方汇总本节涉及的所有组件和参数:
组件 |
关键参数 |
在装配体中的作用 |
与支架 Capstone 的关系 |
常见风险 |
|---|---|---|---|---|
base_plate |
length/width/thickness |
装配体的"地面" |
V7C 底板 |
孔位错误 |
vertical_plate |
length/height/thickness |
装配体的"立面" |
V7C 立板 |
定位错位 |
mounting_bolt |
head_dia/shaft_dia/length |
连接底板到其他设备 |
新增(V8A 教学) |
尺寸不匹配 |
side_pin |
diameter/length |
立板定位 |
新增(V8A 教学) |
销钉过短 |
assembly_origin |
(0, 0, 0) |
装配体全局原点 |
新概念 |
原点混乱 |
component_location |
Location(Vector(...)) |
零件相对原点的位置 |
新概念 |
坐标系翻转 |
G. 装配体与 CAM 的关系¶
关键认识:CAM 通常**不直接加工装配体**,而是**先拆分到单零件**。
CAM 加工流程¶
装配体 (.step, 多零件)
↓ 拆分(手动或半自动)
单零件 (.step, 单实体)
↓ 工艺规划
CAM 加工任务单 (worksheet)
↓ 刀具路径计算
G-code
关键点¶
CAM 处理单零件:Mastercam、Fusion 360 CAM、FreeCAD Path Workbench 等都是针对**单零件**进行刀具路径计算
装配体的作用:用于理解零件关系、安装方向、干涉检查
加工前必须拆分:把装配体 STEP 导入 CAM 软件后,选中**单个零件**生成 G-code
坐标系是重点:单零件的"工件原点"决定 G-code 怎么写
相关页面¶
FreeCAD 到 CAM 加工任务单 — FreeCAD 到 CAM 加工任务单
FreeCAD Path Workbench 入门:从 Job 到 G-code — FreeCAD Path Workbench 入门
G-code 路径可视化:从指令到动作 — G-code 逐行解释
H. 与作品集的关系¶
V8A 装配体代码可以作为**作品集补充材料**提交。
推荐提交清单¶
V8A 装配体作品集提交物(建议):
├── bracket_assembly.py # CadQuery 装配体代码
├── bracket_assembly.step # 完整装配体 STEP
├── components/ # (可选)拆分后的单零件 STEP
│ ├── base_plate.step
│ ├── vertical_plate.step
│ ├── bolt.step
│ └── side_pin.step
├── README.md # 装配体说明(组件、位置、导出)
└── images/
└── assembly_overview.png # 装配体总览图
与已有作品集的关系¶
Bracket Capstone 项目档案 — V6B 作品集模板(V8A 装配体可作为补充)
Capstone 项目线:从支架零件到作品集提交 — V6D Capstone 项目线总入口
CadQuery 学习路径:从入门到 Capstone 收口 — V7D CadQuery 学习路径(V8A 是 V7D 的延伸)
I. 常见误区¶
# |
误区 |
正确做法 |
影响等级 |
|---|---|---|---|
1 |
以为装配体就是把实体 union 到一起 |
装配体保留每个零件的独立性 |
⭐⭐⭐ |
2 |
忽略组件坐标系 |
显式计算每个零件的 Location |
⭐⭐⭐ |
3 |
参数命名混乱 |
用语义化命名(bolt_length 而非 L) |
⭐⭐ |
4 |
螺钉/定位件尺寸不合理 |
螺栓直径 ≤ 孔径、销钉直径 ≤ 孔径 |
⭐⭐ |
5 |
不区分展示装配和加工模型 |
展示用装配体、加工用单零件 |
⭐⭐ |
6 |
以为装配体 STEP 可直接变成 CNC 程序 |
装配体 STEP 需要先拆分到单零件 |
⭐⭐⭐ |
7 |
忽略导出后检查 |
用 FreeCAD 打开 STEP,目视检查每个零件位置 |
⭐⭐ |
8 |
螺栓/销钉缺少"过孔"考虑 |
教学示例可不实现,但实际工程需要 |
⭐ |
前 3 个是 V8A 特有误区,必须避免。后 5 个是 V7/V8 通用问题。
J. 教学声明¶
本页面是 CAD/CAM 学习路径的辅助材料:
教学示例不考虑工业级鲁棒性
螺栓、销钉的尺寸是教学示意值,不可直接用于实际设计
不替代商业 CAD 装配设计工具(SolidWorks、Fusion 360、Inventor)
重点是让读者理解"装配体不是简单合并"
K. 相关页面¶
Python + CadQuery:用代码生成参数化零件 — V7A 入门
CadQuery 进阶:圆角、倒角、阵列与支架变体 — V7B 进阶
CadQuery 支架 Capstone:用代码生成完整支架 — V7C 综合(单实体焊接版支架)
CadQuery 学习路径:从入门到 Capstone 收口 — V7D V7 系列收口
支架零件 Capstone 综合项目 — V6A 图形化版支架 Capstone
Bracket Capstone 项目档案 — V6B 作品集模板
Capstone 项目线:从支架零件到作品集提交 — V6D 项目线总入口
FreeCAD 到 CAM 加工任务单 — V5C FreeCAD 到 CAM
FreeCAD Path Workbench 入门:从 Job 到 G-code — V6C FreeCAD Path Workbench