第05章-装配体与约束系统
第05章:装配体与约束系统
5.1 装配体概述
5.1.1 什么是装配体
装配体(Assembly)是CadQuery中用于组合多个零件的功能模块。在实际产品设计中,产品往往由多个零件组成,装配体功能允许你:
- 将多个零件组合在一起
- 定义零件之间的相对位置关系
- 使用约束自动定位零件
- 支持层次化组装
import cadquery as cq
# 创建两个简单零件
base = cq.Workplane("XY").box(50, 50, 10)
pillar = cq.Workplane("XY").cylinder(30, 10)
# 创建装配体
assembly = cq.Assembly()
assembly.add(base, name="base", color=cq.Color("blue"))
assembly.add(pillar, name="pillar", color=cq.Color("red"),
loc=cq.Location(cq.Vector(0, 0, 10)))
# 导出装配体
assembly.save("assembly.step")
5.1.2 装配体的组成
一个CadQuery装配体包含以下元素:
| 元素 | 说明 |
|---|---|
| 零件(Parts) | 单独的3D模型 |
| 名称(Names) | 零件的唯一标识 |
| 位置(Locations) | 零件的空间位置和方向 |
| 颜色(Colors) | 零件的显示颜色 |
| 约束(Constraints) | 零件间的几何关系 |
| 子装配体 | 嵌套的装配体 |
5.1.3 装配体的应用场景
- 机械设计:齿轮箱、发动机组件
- 电子产品:外壳与内部组件
- 家具设计:桌子、椅子的组装
- 建筑模型:房屋结构件组合
- 3D打印准备:多部件打印预览
5.2 创建装配体
5.2.1 基本创建方法
import cadquery as cq
# 方法1:使用空构造函数
assy = cq.Assembly()
# 方法2:使用根对象构造
root_part = cq.Workplane("XY").box(50, 50, 10)
assy = cq.Assembly(root_part, name="root")
5.2.2 添加零件
import cadquery as cq
# 创建零件
plate = cq.Workplane("XY").box(100, 60, 5)
cylinder = cq.Workplane("XY").cylinder(20, 15)
screw = cq.Workplane("XY").cylinder(3, 8).faces(">Z").workplane().circle(5).extrude(2)
# 创建装配体
assy = cq.Assembly()
# 添加零件(无位置偏移)
assy.add(plate, name="base_plate", color=cq.Color("gray"))
# 添加零件(指定位置)
assy.add(
cylinder,
name="cylinder",
color=cq.Color("red"),
loc=cq.Location(cq.Vector(0, 0, 5)) # Z方向偏移5mm
)
# 添加多个相同零件
for i, pos in enumerate([(-30, -20), (-30, 20), (30, -20), (30, 20)]):
assy.add(
screw,
name=f"screw_{i}",
color=cq.Color("silver"),
loc=cq.Location(cq.Vector(pos[0], pos[1], 5))
)
assy.save("multi_parts.step")
5.2.3 层次化装配体
import cadquery as cq
# 创建子装配体1:电机组件
motor_body = cq.Workplane("XY").cylinder(30, 50)
motor_shaft = cq.Workplane("XY").cylinder(60, 5)
motor_assy = cq.Assembly()
motor_assy.add(motor_body, name="body", color=cq.Color("blue"))
motor_assy.add(motor_shaft, name="shaft", color=cq.Color("silver"),
loc=cq.Location(cq.Vector(0, 0, 5)))
# 创建子装配体2:齿轮组件
gear1 = cq.Workplane("XY").circle(20).extrude(10).faces(">Z").workplane().hole(5)
gear2 = cq.Workplane("XY").circle(30).extrude(10).faces(">Z").workplane().hole(5)
gear_assy = cq.Assembly()
gear_assy.add(gear1, name="pinion", color=cq.Color("orange"))
gear_assy.add(gear2, name="gear", color=cq.Color("yellow"),
loc=cq.Location(cq.Vector(50, 0, 0)))
# 主装配体
main_assy = cq.Assembly()
main_assy.add(motor_assy, name="motor")
main_assy.add(gear_assy, name="gears",
loc=cq.Location(cq.Vector(0, 0, 70)))
main_assy.save("hierarchical_assembly.step")
5.3 位置与方向
5.3.1 Location对象
Location对象定义了零件的位置和方向:
import cadquery as cq
from cadquery import Location, Vector
# 仅平移
loc1 = Location(Vector(10, 20, 30))
# 仅旋转(绕Z轴旋转45度)
loc2 = Location(Vector(0, 0, 0), Vector(0, 0, 1), 45)
# 平移+旋转
loc3 = Location(Vector(10, 20, 30), Vector(0, 0, 1), 45)
# 使用元组指定旋转角度(rx, ry, rz)
# 需要使用transformed方法
5.3.2 复合变换
import cadquery as cq
from cadquery import Location, Vector
import math
# 创建一个零件
part = cq.Workplane("XY").box(20, 10, 5)
# 创建装配体
assy = cq.Assembly()
# 添加原始位置
assy.add(part, name="original", color=cq.Color("red"))
# 添加平移后的
loc_translate = Location(Vector(30, 0, 0))
assy.add(part, name="translated", color=cq.Color("green"),
loc=loc_translate)
# 添加旋转后的
loc_rotate = Location(Vector(60, 0, 0), Vector(0, 0, 1), 45)
assy.add(part, name="rotated", color=cq.Color("blue"),
loc=loc_rotate)
# 添加平移+旋转
loc_complex = Location(Vector(90, 0, 0), Vector(0, 1, 0), 30)
assy.add(part, name="complex", color=cq.Color("yellow"),
loc=loc_complex)
assy.save("transformations.step")
5.3.3 动态定位
import cadquery as cq
from cadquery import Location, Vector
import math
# 创建一个螺栓零件
bolt = cq.Workplane("XY").cylinder(10, 3).faces(">Z").workplane().polygon(6, 8).extrude(5)
# 创建底板
plate = cq.Workplane("XY").box(100, 100, 10)
# 创建装配体
assy = cq.Assembly()
assy.add(plate, name="plate", color=cq.Color("gray"))
# 动态添加圆周分布的螺栓
num_bolts = 8
radius = 35
for i in range(num_bolts):
angle = 2 * math.pi * i / num_bolts
x = radius * math.cos(angle)
y = radius * math.sin(angle)
assy.add(
bolt,
name=f"bolt_{i}",
color=cq.Color("silver"),
loc=Location(Vector(x, y, 10))
)
assy.save("circular_pattern.step")
5.4 约束系统
5.4.1 约束概述
约束(Constraints)定义了零件之间的几何关系,CadQuery会自动求解这些约束来确定零件位置。
支持的约束类型:
| 约束类型 | 说明 | 参数 |
|---|---|---|
| Fixed | 固定零件位置 | 无 |
| Plane | 平面共面/平行 | 可选:间距 |
| Axis | 轴线对齐 | 可选:角度 |
| Point | 点重合 | 无 |
| PointInPlane | 点在平面上 | 可选:偏移 |
5.4.2 使用约束定位零件
import cadquery as cq
# 创建基座(带凸台)
base = (
cq.Workplane("XY")
.box(50, 50, 10)
.faces(">Z")
.workplane()
.circle(10)
.extrude(5)
)
# 创建配合件(带孔)
mating_part = (
cq.Workplane("XY")
.box(30, 30, 15)
.faces("<Z")
.workplane()
.hole(10.1, 6) # 稍大的配合孔
)
# 创建装配体
assy = cq.Assembly()
# 添加基座(固定)
assy.add(base, name="base", color=cq.Color("blue"))
# 添加配合件
assy.add(mating_part, name="mating", color=cq.Color("red"))
# 添加约束
# 基座是固定的
assy.constrain("base", "Fixed")
# 配合件的底面与基座的顶面平面约束
assy.constrain("base@faces@>Z", "mating@faces@<Z", "Plane")
# 配合件的孔轴线与基座的凸台轴线对齐
assy.constrain("base@faces@>Z", "mating@faces@<Z", "Axis")
# 求解约束
assy.solve()
assy.save("constrained_assembly.step")
5.4.3 约束路径语法
约束需要指定几何元素的路径,语法如下:
<零件名>@<元素类型>@<选择器>
示例:
"base@faces@>Z"- base零件的Z方向最高的面"shaft@edges@%Circle"- shaft零件的圆形边"plate@vertices@<X and <Y"- plate零件的X和Y最小的顶点
# 更多约束路径示例
assy.constrain(
"part1@faces@>Z", # part1的顶面
"part2@faces@<Z", # part2的底面
"Plane" # 平面约束
)
assy.constrain(
"shaft@edges@|Z", # shaft的平行于Z轴的边
"hole@faces@%Cylinder", # hole的圆柱面
"Axis" # 轴线约束
)
5.4.4 带参数的约束
import cadquery as cq
# 两个盒子
box1 = cq.Workplane("XY").box(30, 30, 10)
box2 = cq.Workplane("XY").box(20, 20, 15)
assy = cq.Assembly()
assy.add(box1, name="box1", color=cq.Color("blue"))
assy.add(box2, name="box2", color=cq.Color("red"))
# 固定box1
assy.constrain("box1", "Fixed")
# 带间距的平面约束(box2放在box1上方5mm处)
assy.constrain("box1@faces@>Z", "box2@faces@<Z", "Plane", param=5)
assy.solve()
assy.save("offset_constraint.step")
5.4.5 复杂约束示例
import cadquery as cq
# 创建铰链两个部分
# 固定部分
fixed_part = (
cq.Workplane("XY")
.box(30, 50, 5)
.faces(">Z")
.workplane()
.center(10, 0)
.cylinder(15, 5, centered=(True, True, False))
)
# 活动部分
moving_part = (
cq.Workplane("XY")
.box(30, 50, 5)
.faces(">Z")
.workplane()
.center(10, 0)
.circle(5.2)
.cutThruAll()
)
# 销钉
pin = cq.Workplane("XY").cylinder(25, 4.9)
# 装配
assy = cq.Assembly()
assy.add(fixed_part, name="fixed", color=cq.Color("blue"))
assy.add(moving_part, name="moving", color=cq.Color("red"))
assy.add(pin, name="pin", color=cq.Color("silver"))
# 约束
assy.constrain("fixed", "Fixed")
# 销钉与固定部分的孔对齐
assy.constrain("fixed@faces@>Z", "pin@faces@<Z", "Axis")
# 活动部分可以绕销钉旋转
assy.constrain("pin@faces@%Cylinder", "moving@faces@%Cylinder", "Axis")
assy.solve()
assy.save("hinge.step")
5.5 标签在装配中的应用
5.5.1 标记约束面
import cadquery as cq
# 创建带标签的零件
base = (
cq.Workplane("XY")
.box(50, 50, 10)
.faces(">Z").tag("mount_face")
.end()
.faces(">Z")
.workplane()
.circle(10)
.extrude(5)
.faces(">Z").tag("boss_face")
)
cover = (
cq.Workplane("XY")
.box(50, 50, 5)
.faces("<Z").tag("bottom")
.end()
.faces("<Z")
.workplane()
.hole(10.1)
)
# 装配时使用标签
assy = cq.Assembly()
assy.add(base, name="base", color=cq.Color("blue"))
assy.add(cover, name="cover", color=cq.Color("red"))
# 使用标签进行约束引用更清晰
# 注意:CadQuery的约束系统主要使用选择器语法
assy.constrain("base", "Fixed")
assy.constrain("base@faces@>Z", "cover@faces@<Z", "Plane")
assy.solve()
5.5.2 组织复杂装配
import cadquery as cq
def make_bracket():
"""创建带标签的支架"""
return (
cq.Workplane("XY")
.box(40, 20, 5)
.faces(">Z").tag("top")
.faces("<Z").tag("bottom")
.faces(">X").tag("front")
.faces("<X").tag("back")
)
def make_shaft():
"""创建带标签的轴"""
return (
cq.Workplane("XY")
.cylinder(50, 8)
.faces(">Z").tag("end1")
.faces("<Z").tag("end2")
.edges("%Circle and >Z").tag("chamfer_edge")
)
# 使用工厂函数创建零件
bracket = make_bracket()
shaft = make_shaft()
# 组装
assy = cq.Assembly()
assy.add(bracket, name="bracket")
assy.add(shaft, name="shaft")
5.6 导出与可视化
5.6.1 导出装配体
import cadquery as cq
# 创建简单装配体
base = cq.Workplane("XY").box(50, 50, 10)
top = cq.Workplane("XY").box(30, 30, 20)
assy = cq.Assembly()
assy.add(base, name="base", color=cq.Color("blue"))
assy.add(top, name="top", color=cq.Color("red"),
loc=cq.Location(cq.Vector(0, 0, 10)))
# 导出为STEP格式(保持装配结构)
assy.save("assembly.step")
# 导出为其他格式
assy.save("assembly.stl") # STL(会合并所有零件)
assy.save("assembly.gltf") # glTF(支持Web显示)
5.6.2 导出选项
# 导出时的选项
assy.save(
"assembly.step",
exportType="STEP"
)
# 分别导出每个零件
for name, part in assy.traverse():
if part.obj is not None:
cq.exporters.export(part.obj, f"{name}.step")
5.6.3 在CQ-editor中可视化
# CQ-editor中显示装配体
import cadquery as cq
base = cq.Workplane("XY").box(50, 50, 10)
top = cq.Workplane("XY").sphere(15)
assy = cq.Assembly()
assy.add(base, name="base", color=cq.Color("blue"))
assy.add(top, name="top", color=cq.Color("red"),
loc=cq.Location(cq.Vector(0, 0, 25)))
# 在CQ-editor中使用show_object显示
show_object(assy)
5.7 实战案例
5.7.1 简单机械装配
import cadquery as cq
from cadquery import Location, Vector
import math
# 创建底板
base_plate = (
cq.Workplane("XY")
.box(100, 80, 10)
.faces(">Z")
.workplane()
.rarray(80, 60, 2, 2)
.hole(6)
)
# 创建立柱
pillar = cq.Workplane("XY").cylinder(40, 10)
# 创建顶板
top_plate = (
cq.Workplane("XY")
.box(80, 60, 8)
.faces(">Z or <Z")
.shell(-3)
)
# 创建螺栓
bolt = (
cq.Workplane("XY")
.cylinder(15, 3)
.faces(">Z")
.workplane()
.polygon(6, 8)
.extrude(5)
)
# 组装
assy = cq.Assembly(name="machine_assembly")
# 添加底板
assy.add(base_plate, name="base", color=cq.Color("silver"))
# 添加四个立柱
positions = [(-30, -20), (-30, 20), (30, -20), (30, 20)]
for i, (x, y) in enumerate(positions):
assy.add(
pillar,
name=f"pillar_{i}",
color=cq.Color("blue"),
loc=Location(Vector(x, y, 10))
)
# 添加顶板
assy.add(
top_plate,
name="top",
color=cq.Color("green"),
loc=Location(Vector(0, 0, 50))
)
# 添加螺栓
bolt_positions = [(-40, -30), (-40, 30), (40, -30), (40, 30)]
for i, (x, y) in enumerate(bolt_positions):
assy.add(
bolt,
name=f"bolt_{i}",
color=cq.Color("darkgray"),
loc=Location(Vector(x, y, -5))
)
assy.save("machine_assembly.step")
5.7.2 齿轮传动装配
import cadquery as cq
from cadquery import Location, Vector
import math
def make_gear(teeth, module=2, thickness=10, bore=8):
"""创建简化齿轮"""
pitch_radius = module * teeth / 2
outer_radius = pitch_radius + module
return (
cq.Workplane("XY")
.circle(outer_radius)
.extrude(thickness)
.faces(">Z")
.workplane()
.hole(bore)
.edges("|Z")
.fillet(1)
)
# 创建不同大小的齿轮
gear1 = make_gear(20)
gear2 = make_gear(40)
gear3 = make_gear(15)
# 创建轴
shaft = cq.Workplane("XY").cylinder(80, 4)
# 创建轴承座
bearing_block = (
cq.Workplane("XY")
.box(30, 30, 20)
.faces(">Z or <Z")
.hole(8.2)
)
# 组装齿轮系统
assy = cq.Assembly(name="gear_train")
# 输入轴和齿轮
assy.add(shaft, name="input_shaft", color=cq.Color("silver"))
assy.add(gear1, name="input_gear", color=cq.Color("orange"),
loc=Location(Vector(0, 0, 20)))
# 中间轴和齿轮
m = 2 # 模数
center_distance = m * (20 + 40) / 2 # 齿轮1和齿轮2的中心距
assy.add(shaft, name="inter_shaft", color=cq.Color("silver"),
loc=Location(Vector(center_distance, 0, 0)))
assy.add(gear2, name="inter_gear", color=cq.Color("yellow"),
loc=Location(Vector(center_distance, 0, 20)))
# 轴承座
assy.add(bearing_block, name="bearing1", color=cq.Color("gray"),
loc=Location(Vector(0, 0, 0)))
assy.add(bearing_block, name="bearing2", color=cq.Color("gray"),
loc=Location(Vector(0, 0, 60)))
assy.add(bearing_block, name="bearing3", color=cq.Color("gray"),
loc=Location(Vector(center_distance, 0, 0)))
assy.add(bearing_block, name="bearing4", color=cq.Color("gray"),
loc=Location(Vector(center_distance, 0, 60)))
assy.save("gear_train.step")
5.8 最佳实践
5.8.1 装配体设计原则
-
模块化设计
# 将重复使用的零件定义为函数 def make_mounting_plate(length, width, thickness, hole_pattern): # ... pass -
合理的命名约定
# 使用描述性名称 assy.add(part, name="left_side_bracket_01") # 而不是 assy.add(part, name="part1") -
层次化组织
# 将相关零件组织到子装配体 wheel_assy = cq.Assembly(name="front_left_wheel") wheel_assy.add(tire, name="tire") wheel_assy.add(rim, name="rim") wheel_assy.add(hub, name="hub") car_assy.add(wheel_assy, name="FL_wheel")
5.8.2 性能优化
-
复用零件对象
# 创建一次,多次使用 bolt = make_bolt() for i in range(100): assy.add(bolt, name=f"bolt_{i}", loc=...) -
简化约束
# 尽可能使用简单约束 # 避免过度约束
5.8.3 调试技巧
# 分步构建装配体
assy = cq.Assembly()
assy.add(base, name="base")
assy.save("debug_step1.step") # 检查中间结果
assy.add(part2, name="part2")
assy.save("debug_step2.step") # 继续检查
5.9 本章小结
本章详细介绍了CadQuery的装配体与约束系统:
-
装配体基础
- Assembly对象创建
- 添加零件和位置
- 层次化组织
-
位置与方向
- Location对象使用
- 复合变换
- 动态定位
-
约束系统
- 约束类型:Fixed、Plane、Axis、Point
- 约束路径语法
- 约束求解
-
导出与可视化
- 多种格式导出
- CQ-editor显示
-
实战案例
- 机械装配
- 齿轮传动系统
通过本章学习,您应该能够:
- 创建和管理复杂装配体
- 使用约束自动定位零件
- 导出装配体供其他软件使用
- 应用最佳实践组织装配结构
下一章我们将学习数据导入导出功能,包括STEP、STL等格式的处理。

浙公网安备 33010602011771号