第04章-选择器系统详解
第04章:选择器系统详解
4.1 选择器概述
4.1.1 什么是选择器
选择器(Selector)是CadQuery中用于精确选择几何元素的强大工具。在CAD建模中,我们经常需要对特定的面、边或顶点进行操作,选择器提供了一种直观且灵活的方式来定位这些元素。
import cadquery as cq
# 选择器示例:选择盒子的顶面
result = (
cq.Workplane("XY")
.box(20, 20, 10)
.faces(">Z") # 选择Z方向最高的面
.workplane()
.hole(5)
)
4.1.2 可选择的几何元素类型
CadQuery支持选择以下类型的几何元素:
| 方法 | 选择的元素类型 | 说明 |
|---|---|---|
.faces() |
面(Face) | 实体的表面 |
.edges() |
边(Edge) | 面与面的交线 |
.vertices() |
顶点(Vertex) | 边的端点 |
.wires() |
线框(Wire) | 闭合的边集合 |
.solids() |
实体(Solid) | 完整的3D实体 |
.shells() |
壳(Shell) | 封闭的面集合 |
.compounds() |
复合体(Compound) | 多个形状的组合 |
4.1.3 选择器的工作原理
选择器本质上是一个过滤器,它遍历当前对象的所有子元素,并返回符合条件的元素:
# 不带参数 - 选择所有该类型的元素
box.faces() # 选择所有6个面
box.edges() # 选择所有12条边
# 带选择器字符串 - 过滤元素
box.faces(">Z") # 只选择Z方向最高的面
box.edges("|X") # 只选择平行于X轴的边
4.2 方向选择器
4.2.1 最大/最小方向选择器
使用 > 和 < 选择在某个方向上最大或最小的元素:
# 选择各方向的面
box = cq.Workplane("XY").box(20, 30, 10)
top_face = box.faces(">Z") # 顶面(Z最大)
bottom_face = box.faces("<Z") # 底面(Z最小)
front_face = box.faces(">Y") # 前面(Y最大)
back_face = box.faces("<Y") # 后面(Y最小)
right_face = box.faces(">X") # 右面(X最大)
left_face = box.faces("<X") # 左面(X最小)
多元素选择:
# 当多个元素在同一方向上处于相同位置时,都会被选中
# 例如选择圆柱的顶面边缘
cylinder = cq.Workplane("XY").circle(10).extrude(20)
top_edges = cylinder.edges(">Z") # 选择顶面的圆形边
4.2.2 平行/垂直选择器
使用 | 选择平行于某轴的元素,使用 # 选择垂直于某轴的元素:
box = cq.Workplane("XY").box(20, 30, 10)
# 平行选择器
vertical_edges = box.edges("|Z") # 4条竖直边
horizontal_x = box.edges("|X") # 4条平行于X轴的边
horizontal_y = box.edges("|Y") # 4条平行于Y轴的边
# 垂直选择器
faces_perp_z = box.faces("#Z") # 顶面和底面(垂直于Z轴)
faces_perp_x = box.faces("#X") # 左面和右面(垂直于X轴)
4.2.3 自定义方向向量
可以使用任意方向向量进行选择:
import cadquery as cq
from cadquery import Vector
# 使用Vector指定方向
box = cq.Workplane("XY").box(20, 20, 10)
# 选择法向量指向(1, 1, 0)方向的面(如果存在)
# 对于标准盒子,这不会选中任何面
# 但对于倾斜的面会有效
4.3 位置选择器
4.3.1 中心点选择器
使用中心点选择器选择接近某一位置的元素:
box = cq.Workplane("XY").box(20, 30, 10)
# 按中心点位置选择
# 这在有多个相似元素时特别有用
4.3.2 索引选择器
当有多个相似元素时,可以使用索引选择特定元素:
# 选择特定索引的元素
box = cq.Workplane("XY").box(20, 30, 10)
# 获取所有竖直边,然后选择第一条
first_vertical_edge = box.edges("|Z").val()
4.4 几何选择器
4.4.1 圆形/圆弧选择器
使用 % 选择圆形或包含圆弧的元素:
# 选择圆形边
cylinder = cq.Workplane("XY").circle(10).extrude(20)
# %Circle 选择圆形边
circular_edges = cylinder.edges("%Circle")
# 选择圆形面
circular_faces = cylinder.faces("%Plane") # 顶面和底面(平面)
4.4.2 形状类型选择器
# 按形状类型选择
result = cq.Workplane("XY").box(20, 20, 10)
# 选择平面(Plane类型的面)
planar_faces = result.faces("%Plane")
# 对于有圆角的物体
filleted_box = cq.Workplane("XY").box(20, 20, 10).edges().fillet(2)
# 选择圆柱面(圆角产生的)
curved_faces = filleted_box.faces("%Cylinder")
4.5 组合选择器
4.5.1 逻辑AND组合
使用 and 关键字组合多个条件:
box = cq.Workplane("XY").box(20, 30, 10)
# 选择平行于Z轴且X最大的边
edges = box.edges("|Z and >X") # 右侧的2条竖直边
# 选择顶部且平行于X轴的边
edges = box.edges(">Z and |X") # 顶面的2条平行于X轴的边
4.5.2 逻辑OR组合
使用 or 关键字表示满足任一条件:
box = cq.Workplane("XY").box(20, 30, 10)
# 选择顶面或底面
faces = box.faces(">Z or <Z")
# 选择所有水平边
edges = box.edges("|X or |Y")
4.5.3 逻辑NOT组合
使用 not 关键字排除某些元素:
box = cq.Workplane("XY").box(20, 30, 10)
# 选择不是顶面的所有面
faces = box.faces("not >Z") # 5个面
# 选择不是竖直的所有边
edges = box.edges("not |Z") # 8条水平边
4.5.4 复杂组合
box = cq.Workplane("XY").box(20, 30, 10)
# 复杂组合示例
# 选择顶部或底部的、平行于X轴的边
edges = box.edges("(>Z or <Z) and |X")
# 选择不在顶面的竖直边
edges = box.edges("|Z and not >Z")
4.6 自定义选择器
4.6.1 使用过滤函数
可以使用自定义函数进行过滤:
import cadquery as cq
box = cq.Workplane("XY").box(20, 30, 10)
# 获取所有边并手动过滤
all_edges = box.edges().vals()
# 自定义过滤:选择长度大于15的边
long_edges = [e for e in all_edges if e.Length() > 15]
4.6.2 创建自定义选择器类
from cadquery import Selector, Edge
from cadquery.occ_impl.shapes import Shape
class LengthSelector(Selector):
"""选择指定长度范围的边"""
def __init__(self, min_length, max_length=float('inf')):
self.min_length = min_length
self.max_length = max_length
def filter(self, objectList):
result = []
for obj in objectList:
if isinstance(obj, Edge):
length = obj.Length()
if self.min_length <= length <= self.max_length:
result.append(obj)
return result
# 使用自定义选择器
box = cq.Workplane("XY").box(20, 30, 10)
long_edges = box.edges(LengthSelector(20, 35))
4.6.3 基于属性的选择器
class RadiusSelector(Selector):
"""选择指定半径的圆形边"""
def __init__(self, radius, tolerance=0.001):
self.radius = radius
self.tolerance = tolerance
def filter(self, objectList):
result = []
for obj in objectList:
if hasattr(obj, 'radius'):
r = obj.radius()
if abs(r - self.radius) < self.tolerance:
result.append(obj)
return result
4.7 标签系统
4.7.1 为元素添加标签
标签系统允许在建模过程中标记特定元素,以便后续选择:
import cadquery as cq
result = (
cq.Workplane("XY")
.box(30, 20, 10)
.faces(">Z")
.tag("top_face") # 为顶面添加标签
.workplane()
.circle(5)
.extrude(15)
.edges(">Z")
.tag("top_circle") # 为圆形边添加标签
)
4.7.2 使用标签选择元素
# 通过标签选择之前标记的元素
top_face = result.faces(tag="top_face")
# 在标签选中的面上继续操作
result = result.faces(tag="top_face").workplane().hole(8)
4.7.3 标签的最佳实践
# 完整的标签使用示例
result = (
cq.Workplane("XY")
# 创建基础板
.box(100, 60, 10)
.faces(">Z").tag("base_top")
.end()
# 创建凸台
.faces(tag="base_top")
.workplane()
.circle(20)
.extrude(15)
.faces(">Z").tag("boss_top")
.end()
# 在凸台顶部钻孔
.faces(tag="boss_top")
.workplane()
.hole(10)
# 在基础板上创建安装孔
.faces(tag="base_top")
.workplane()
.rect(80, 40, forConstruction=True)
.vertices()
.hole(8)
)
4.8 实际应用示例
4.8.1 选择性圆角
import cadquery as cq
# 创建L型支架,只对某些边倒圆角
result = (
cq.Workplane("XY")
.box(50, 30, 5)
.faces(">Z")
.workplane()
.center(-20, 0)
.rect(10, 30)
.extrude(40)
# 只对竖直边进行大圆角
.edges("|Z")
.fillet(3)
# 对顶部边进行小圆角
.edges(">Z")
.fillet(1)
)
4.8.2 多面孔加工
# 在多个面上创建相同的特征
result = (
cq.Workplane("XY")
.box(40, 40, 40)
# 在每个面中心创建凹槽
.faces(">X")
.workplane()
.rect(20, 20)
.cutBlind(-5)
.faces("<X")
.workplane()
.rect(20, 20)
.cutBlind(-5)
.faces(">Y")
.workplane()
.rect(20, 20)
.cutBlind(-5)
)
4.8.3 复杂零件的边处理
# 创建复杂零件并选择性处理边
result = (
cq.Workplane("XY")
.box(60, 40, 20)
# 顶面凸台
.faces(">Z")
.workplane()
.circle(15)
.extrude(10)
# 对基础板的竖直边大圆角
.faces("<Z")
.edges("|Z")
.fillet(5)
# 对凸台的顶部边小圆角
.faces(">Z")
.edges()
.fillet(2)
# 对基础板的底部边倒角
.faces("<Z")
.edges()
.chamfer(1)
)
4.8.4 装配孔定位
# 使用选择器精确定位装配孔
result = (
cq.Workplane("XY")
.box(80, 60, 10)
# 在四个角落钻孔
.faces(">Z")
.workplane()
.rect(60, 40, forConstruction=True)
.vertices()
.cboreHole(6, 12, 4)
# 在中心钻大孔
.faces(">Z")
.workplane()
.hole(20)
# 只对四个角落的孔边缘倒角
.faces(">Z")
.edges("%Circle and >X and >Y") # 右上角的圆形边
# 注意:实际使用中可能需要更复杂的选择逻辑
)
4.9 选择器性能优化
4.9.1 选择器链优化
# 低效:多次遍历
result = box.faces(">Z").edges().edges("|X")
# 高效:直接组合条件
result = box.edges(">Z and |X")
4.9.2 缓存选择结果
# 如果需要多次使用同一选择结果
top_face = box.faces(">Z")
# 复用选择结果
feature1 = top_face.workplane().circle(5).extrude(10)
feature2 = top_face.workplane().rect(3, 3).cutBlind(-3)
4.9.3 使用标签减少重复选择
# 使用标签避免重复选择
result = (
cq.Workplane("XY")
.box(50, 50, 10)
.faces(">Z").tag("top")
.end()
# 后续多次引用
.faces(tag="top").workplane().circle(10).extrude(5)
.faces(tag="top").workplane().rarray(15, 15, 2, 2).hole(3)
)
4.10 常见问题与解决方案
4.10.1 选择器没有选中任何元素
# 问题:选择器字符串拼写错误或条件不匹配
box = cq.Workplane("XY").box(20, 20, 10)
# 错误:大小写敏感
# box.edges("|z") # 应该是 "|Z"
# 解决:使用正确的语法
edges = box.edges("|Z")
# 调试:检查有多少元素被选中
print(f"选中的边数: {len(box.edges('|Z').vals())}")
4.10.2 选择了过多的元素
# 问题:条件太宽泛
box = cq.Workplane("XY").box(20, 20, 10)
# 选择了所有12条边
all_edges = box.edges()
# 解决:添加更多条件
top_edges = box.edges(">Z") # 只选择顶部的4条边
specific_edges = box.edges(">Z and |X") # 只选择顶部平行于X的2条边
4.10.3 组合选择器语法错误
# 错误的语法
# box.edges(">Z && |X") # 不支持 &&
# 正确的语法
box.edges(">Z and |X") # 使用 and
# 括号用于复杂条件
box.edges("(>Z or <Z) and |X")
4.11 本章小结
本章详细介绍了CadQuery的选择器系统:
-
基本选择器
- 方向选择器:
>、<、|、# - 几何选择器:
%Circle、%Plane等
- 方向选择器:
-
组合选择器
- 逻辑运算:
and、or、not - 括号分组
- 逻辑运算:
-
自定义选择器
- 过滤函数
- 自定义选择器类
-
标签系统
- 添加和使用标签
- 标签最佳实践
-
实际应用
- 选择性圆角/倒角
- 精确定位特征
通过本章的学习,您应该能够:
- 使用各种选择器精确选择几何元素
- 组合多个选择条件
- 创建自定义选择器
- 使用标签系统管理复杂模型
下一章我们将学习装配体(Assembly)功能,这是创建复杂多零件模型的关键。

浙公网安备 33010602011771号