第07章-高级建模技巧
第07章:高级建模技巧
7.1 参数化设计
7.1.1 参数化设计概述
参数化设计是CadQuery的核心优势之一。通过将尺寸和几何关系定义为参数,可以轻松生成不同规格的模型。
参数化设计的优点:
- 快速生成变体模型
- 易于修改和维护
- 支持批量生产
- 便于设计优化
7.1.2 基本参数化
import cadquery as cq
# 定义参数
length = 80.0
width = 60.0
height = 20.0
hole_diameter = 15.0
fillet_radius = 3.0
wall_thickness = 3.0
# 使用参数创建模型
result = (
cq.Workplane("XY")
.box(length, width, height)
.faces(">Z")
.shell(-wall_thickness)
.faces(">Z")
.workplane()
.hole(hole_diameter)
.edges("|Z")
.fillet(fillet_radius)
)
cq.exporters.export(result, "parametric_box.step")
7.1.3 参数化函数
import cadquery as cq
def make_enclosure(length, width, height, wall=2.0, corner_radius=3.0):
"""
创建参数化外壳
Args:
length: 长度
width: 宽度
height: 高度
wall: 壁厚
corner_radius: 圆角半径
"""
result = (
cq.Workplane("XY")
.box(length, width, height)
.edges("|Z")
.fillet(corner_radius)
.faces(">Z")
.shell(-wall)
)
return result
# 生成不同尺寸的外壳
small = make_enclosure(50, 30, 20)
medium = make_enclosure(80, 50, 30, wall=3.0)
large = make_enclosure(120, 80, 40, wall=4.0, corner_radius=5.0)
cq.exporters.export(small, "enclosure_small.step")
cq.exporters.export(medium, "enclosure_medium.step")
cq.exporters.export(large, "enclosure_large.step")
7.1.4 参数关联
import cadquery as cq
# 参数定义
bolt_diameter = 8
bolt_spacing = 30
num_bolts_x = 4
num_bolts_y = 3
# 派生参数(自动计算)
plate_length = bolt_spacing * (num_bolts_x - 1) + bolt_diameter * 4
plate_width = bolt_spacing * (num_bolts_y - 1) + bolt_diameter * 4
plate_thickness = bolt_diameter * 0.5
edge_distance = bolt_diameter * 2
# 创建带关联参数的安装板
result = (
cq.Workplane("XY")
.box(plate_length, plate_width, plate_thickness)
.faces(">Z")
.workplane()
.rarray(bolt_spacing, bolt_spacing, num_bolts_x, num_bolts_y)
.cboreHole(bolt_diameter, bolt_diameter * 1.8, plate_thickness * 0.3)
.edges()
.fillet(plate_thickness * 0.2)
)
cq.exporters.export(result, "mounting_plate.step")
7.1.5 配置驱动设计
import cadquery as cq
# 配置字典
configs = {
"M6": {
"thread_diameter": 6,
"head_diameter": 10,
"head_height": 4,
"length": 20
},
"M8": {
"thread_diameter": 8,
"head_diameter": 13,
"head_height": 5,
"length": 25
},
"M10": {
"thread_diameter": 10,
"head_diameter": 16,
"head_height": 6.4,
"length": 30
}
}
def make_hex_bolt(config):
"""根据配置创建六角螺栓"""
td = config["thread_diameter"]
hd = config["head_diameter"]
hh = config["head_height"]
length = config["length"]
return (
cq.Workplane("XY")
.polygon(6, hd)
.extrude(hh)
.faces("<Z")
.workplane()
.circle(td / 2)
.extrude(-length)
.edges(">Z")
.chamfer(hh * 0.1)
)
# 生成不同规格的螺栓
for name, config in configs.items():
bolt = make_hex_bolt(config)
cq.exporters.export(bolt, f"bolt_{name}.step")
7.2 复杂曲面建模
7.2.1 样条曲面
import cadquery as cq
import math
# 创建样条曲线并放样
points1 = [(0, 0), (20, 10), (40, 5), (60, 15), (80, 0)]
points2 = [(0, 0), (20, -10), (40, -5), (60, -15), (80, 0)]
result = (
cq.Workplane("XZ")
.spline(points1)
.close()
.workplane(offset=30)
.spline(points2)
.close()
.loft()
)
cq.exporters.export(result, "spline_surface.step")
7.2.2 旋转曲面
import cadquery as cq
import math
def vase_profile(height, base_radius, neck_radius, belly_radius):
"""创建花瓶轮廓"""
points = []
segments = 50
for i in range(segments + 1):
t = i / segments
h = t * height
# 使用正弦函数创建曲线轮廓
if t < 0.3:
r = base_radius + (belly_radius - base_radius) * math.sin(t / 0.3 * math.pi / 2)
elif t < 0.7:
r = belly_radius * (1 + 0.1 * math.sin((t - 0.3) / 0.4 * 2 * math.pi))
else:
r = belly_radius + (neck_radius - belly_radius) * math.sin((t - 0.7) / 0.3 * math.pi / 2)
points.append((r, h))
return points
# 创建花瓶
profile = vase_profile(100, 15, 10, 30)
vase = (
cq.Workplane("XZ")
.moveTo(0, 0)
.spline(profile)
.lineTo(0, 100)
.close()
.revolve(360, (0, 0, 0), (0, 1, 0))
.shell(-2) # 创建空心
)
cq.exporters.export(vase, "vase.step")
7.2.3 扫略曲面
import cadquery as cq
import math
# 创建螺旋路径
def helix_path(radius, pitch, turns):
points = []
segments = int(turns * 36)
for i in range(segments + 1):
angle = 2 * math.pi * i / 36
x = radius * math.cos(angle)
y = radius * math.sin(angle)
z = pitch * i / 36
points.append((x, y, z))
return points
# 使用内置的螺旋线
helix = cq.Wire.makeHelix(pitch=10, height=80, radius=25)
# 创建截面
# 异形截面
profile = (
cq.Workplane("XY")
.ellipse(5, 3)
)
# 沿螺旋线扫略
result = profile.sweep(helix, isFrenet=True)
cq.exporters.export(result, "helix_sweep.step")
7.2.4 放样曲面进阶
import cadquery as cq
from cadquery import Sketch
# 多截面放样
s1 = Sketch().rect(40, 40).vertices().fillet(5)
s2 = Sketch().circle(15)
s3 = Sketch().polygon(8, 20).vertices().fillet(2)
s4 = Sketch().rect(30, 30).vertices().fillet(8)
result = (
cq.Workplane("XY")
.placeSketch(s1)
.workplane(offset=20)
.placeSketch(s2)
.workplane(offset=20)
.placeSketch(s3)
.workplane(offset=20)
.placeSketch(s4)
.loft()
)
cq.exporters.export(result, "multi_loft.step")
7.3 图案和阵列
7.3.1 矩形阵列
import cadquery as cq
# 使用rarray创建矩形阵列
result = (
cq.Workplane("XY")
.box(100, 80, 10)
.faces(">Z")
.workplane()
.rarray(15, 15, 5, 4) # x间距, y间距, x数量, y数量
.hole(5)
)
cq.exporters.export(result, "rect_array.step")
7.3.2 极坐标阵列
import cadquery as cq
# 圆周阵列
result = (
cq.Workplane("XY")
.circle(50)
.extrude(10)
.faces(">Z")
.workplane()
.polarArray(35, 0, 360, 8) # 半径, 起始角, 结束角, 数量
.hole(8)
.faces(">Z")
.workplane()
.hole(20) # 中心孔
)
cq.exporters.export(result, "polar_array.step")
7.3.3 自定义点阵列
import cadquery as cq
import math
# 自定义点位置
custom_points = [
(0, 0),
(30, 0),
(15, 26), # 三角形布局
(-30, 15),
(30, 30),
]
result = (
cq.Workplane("XY")
.box(100, 80, 10)
.faces(">Z")
.workplane()
.pushPoints(custom_points)
.hole(8)
)
cq.exporters.export(result, "custom_array.step")
7.3.4 沿路径阵列
import cadquery as cq
import math
# 沿曲线分布
def points_along_curve(num_points):
points = []
for i in range(num_points):
t = i / (num_points - 1)
x = 80 * t - 40
y = 20 * math.sin(t * 2 * math.pi)
points.append((x, y))
return points
# 创建基板
base = cq.Workplane("XY").box(100, 60, 5)
# 沿曲线放置凸台
curve_points = points_along_curve(10)
result = (
base
.faces(">Z")
.workplane()
.pushPoints(curve_points)
.circle(3)
.extrude(8)
)
cq.exporters.export(result, "curve_array.step")
7.4 镜像与对称
7.4.1 平面镜像
import cadquery as cq
# 创建半边模型
half = (
cq.Workplane("XY")
.moveTo(0, 0)
.lineTo(30, 0)
.lineTo(30, 20)
.lineTo(20, 20)
.lineTo(20, 10)
.lineTo(0, 10)
.close()
.extrude(10)
)
# 镜像得到完整模型
result = half.mirror("XZ")
# 或者使用union合并原始和镜像
full = half.union(half.mirror("XZ"))
cq.exporters.export(full, "mirrored.step")
7.4.2 多轴对称
import cadquery as cq
# 创建四分之一模型
quarter = (
cq.Workplane("XY")
.moveTo(0, 0)
.lineTo(20, 0)
.threePointArc((28, 8), (20, 20))
.lineTo(0, 20)
.close()
.extrude(10)
)
# X和Y方向都镜像
half = quarter.union(quarter.mirror("YZ"))
full = half.union(half.mirror("XZ"))
cq.exporters.export(full, "quad_symmetric.step")
7.4.3 旋转对称
import cadquery as cq
import math
# 创建一个扇区
sector = (
cq.Workplane("XY")
.moveTo(0, 0)
.lineTo(30, 0)
.threePointArc((30 * math.cos(math.pi/3), 30 * math.sin(math.pi/3)),
(30 * math.cos(math.pi/6), 30 * math.sin(math.pi/6)))
.lineTo(0, 0)
.close()
.extrude(5)
)
# 旋转复制
result = sector
for i in range(1, 6):
angle = i * 60
rotated = sector.rotate((0, 0, 0), (0, 0, 1), angle)
result = result.union(rotated)
cq.exporters.export(result, "rotational_symmetric.step")
7.5 布尔运算进阶
7.5.1 复杂布尔组合
import cadquery as cq
# 创建基础形状
box = cq.Workplane("XY").box(50, 50, 30)
cylinder = cq.Workplane("XY").cylinder(40, 15)
sphere = cq.Workplane("XY").sphere(20)
# 复杂布尔运算
# box和cylinder的并集,减去sphere
result = box.union(cylinder).cut(sphere)
cq.exporters.export(result, "complex_boolean.step")
7.5.2 交集应用
import cadquery as cq
# 使用交集创建特殊形状
# 两个圆柱的交集(双曲抛物面)
cyl1 = cq.Workplane("XY").cylinder(60, 25)
cyl2 = cq.Workplane("XZ").cylinder(60, 25)
result = cyl1.intersect(cyl2)
cq.exporters.export(result, "cylinder_intersect.step")
7.5.3 条件布尔运算
import cadquery as cq
def make_part_with_holes(add_holes=True, num_holes=4):
"""根据条件添加特征"""
result = (
cq.Workplane("XY")
.box(80, 60, 10)
.edges("|Z")
.fillet(5)
)
if add_holes and num_holes > 0:
result = (
result
.faces(">Z")
.workplane()
.rarray(60 / (num_holes - 1), 40, num_holes, 2)
.hole(5)
)
return result
# 生成不同版本
part_no_holes = make_part_with_holes(add_holes=False)
part_4_holes = make_part_with_holes(num_holes=4)
part_6_holes = make_part_with_holes(num_holes=6)
7.6 特征识别与操作
7.6.1 面积筛选
import cadquery as cq
# 创建模型
model = (
cq.Workplane("XY")
.box(50, 30, 20)
.faces(">Z")
.workplane()
.circle(10)
.extrude(10)
)
# 获取所有面并按面积排序
faces = model.faces().vals()
face_areas = [(f, f.Area()) for f in faces]
face_areas.sort(key=lambda x: x[1], reverse=True)
print("面积从大到小:")
for f, area in face_areas[:5]:
print(f" {area:.2f} mm²")
7.6.2 边长筛选
import cadquery as cq
# 创建模型
model = cq.Workplane("XY").box(50, 30, 20)
# 获取所有边
edges = model.edges().vals()
# 按长度筛选
long_edges = [e for e in edges if e.Length() > 25]
print(f"长度>25mm的边数: {len(long_edges)}")
7.6.3 几何中心定位
import cadquery as cq
# 创建模型
model = (
cq.Workplane("XY")
.box(50, 30, 20)
.faces(">Z")
.workplane()
.rect(30, 15)
.cutBlind(-10)
)
# 获取边界框信息
bb = model.val().BoundingBox()
center = ((bb.xmin + bb.xmax) / 2,
(bb.ymin + bb.ymax) / 2,
(bb.zmin + bb.zmax) / 2)
print(f"模型中心: {center}")
print(f"尺寸: {bb.xmax - bb.xmin} x {bb.ymax - bb.ymin} x {bb.zmax - bb.zmin}")
7.7 性能优化
7.7.1 减少布尔运算
import cadquery as cq
# 低效:多次布尔运算
# def inefficient():
# result = cq.Workplane("XY").box(100, 100, 10)
# for i in range(10):
# for j in range(10):
# hole = cq.Workplane("XY").center(i*10, j*10).circle(3).extrude(15)
# result = result.cut(hole)
# return result
# 高效:使用阵列一次性操作
def efficient():
result = (
cq.Workplane("XY")
.box(100, 100, 10)
.faces(">Z")
.workplane()
.rarray(10, 10, 10, 10)
.hole(6)
)
return result
model = efficient()
cq.exporters.export(model, "optimized_holes.step")
7.7.2 简化几何
import cadquery as cq
# 使用合理的精度
# 对于大型模型,可以降低某些特征的精度
def make_model(fillet_segments=20):
"""控制圆角分段数"""
result = (
cq.Workplane("XY")
.box(50, 50, 20)
.edges()
.fillet(3)
)
return result
model = make_model()
7.7.3 延迟求值
import cadquery as cq
# 构建操作链而不立即求值
operations = [
lambda wp: wp.box(50, 50, 20),
lambda wp: wp.faces(">Z").workplane().hole(10),
lambda wp: wp.edges("|Z").fillet(2),
]
# 按需执行
def build_model(ops):
result = cq.Workplane("XY")
for op in ops:
result = op(result)
return result
model = build_model(operations)
7.8 调试技巧
7.8.1 中间结果可视化
import cadquery as cq
# 在CQ-editor中分步显示
# step1 = cq.Workplane("XY").box(50, 50, 20)
# show_object(step1, name="step1_box", options={"color": "blue"})
# step2 = step1.faces(">Z").workplane().hole(10)
# show_object(step2, name="step2_hole", options={"color": "green"})
# step3 = step2.edges("|Z").fillet(3)
# show_object(step3, name="step3_fillet", options={"color": "red"})
7.8.2 几何信息打印
import cadquery as cq
def debug_model(model, name="model"):
"""打印模型的详细信息"""
print(f"\n=== {name} 信息 ===")
# 边界框
bb = model.val().BoundingBox()
print(f"边界框: ({bb.xmin:.2f}, {bb.ymin:.2f}, {bb.zmin:.2f}) - "
f"({bb.xmax:.2f}, {bb.ymax:.2f}, {bb.zmax:.2f})")
# 体积
vol = model.val().Volume()
print(f"体积: {vol:.2f} mm³")
# 面数和边数
num_faces = len(model.faces().vals())
num_edges = len(model.edges().vals())
print(f"面数: {num_faces}")
print(f"边数: {num_edges}")
# 使用
model = cq.Workplane("XY").box(30, 20, 10)
debug_model(model, "测试盒子")
7.8.3 选择器验证
import cadquery as cq
model = cq.Workplane("XY").box(30, 20, 10)
# 验证选择器
def test_selector(model, selector_str, element_type="faces"):
"""测试选择器是否正确选择元素"""
try:
if element_type == "faces":
selected = model.faces(selector_str)
elif element_type == "edges":
selected = model.edges(selector_str)
elif element_type == "vertices":
selected = model.vertices(selector_str)
count = len(selected.vals())
print(f"选择器 '{selector_str}' ({element_type}): 选中 {count} 个元素")
return True
except Exception as e:
print(f"选择器 '{selector_str}' 错误: {e}")
return False
# 测试各种选择器
test_selector(model, ">Z")
test_selector(model, "<Z")
test_selector(model, "|Z", "edges")
test_selector(model, "#Z", "edges")
7.9 本章小结
本章介绍了CadQuery的高级建模技巧:
-
参数化设计
- 参数定义和关联
- 参数化函数
- 配置驱动设计
-
复杂曲面
- 样条曲面
- 旋转曲面
- 扫略和放样
-
图案和阵列
- 矩形阵列
- 极坐标阵列
- 自定义阵列
-
镜像与对称
- 平面镜像
- 多轴对称
- 旋转对称
-
布尔运算进阶
- 复杂组合
- 条件布尔
-
性能优化
- 减少布尔运算
- 简化几何
-
调试技巧
- 中间结果可视化
- 几何信息打印
通过本章学习,您应该能够:
- 创建参数化的复杂模型
- 使用高级曲面建模技术
- 高效地创建图案和阵列
- 优化模型性能
- 有效调试CadQuery脚本
下一章我们将进入二次开发部分,学习如何扩展CadQuery功能。

浙公网安备 33010602011771号