CadQuery
CadQuery 是一个基于 Python 的参数化 3D CAD 库,底层使用 OpenCascade(OCCT)内核。支持输出STL、STEP、AMF和3MF的CAD格式。
简介
时间轴
安装
最简单方式使用CQ-Editor(官方的 GUI 编辑器),或者使用常用的编辑器+插件,如VS Code编辑器和OCP CAD Viewer插件。
CQ-Editor
安装CQ-editor编辑器,会自动安装cadquery,通过pip安装:
pip install CQ-editor
安装后,通过命令行启动:
CQ-editor
https://github.com/CadQuery/CQ-editor/wiki/Installation
VS Code
VS Code中,先安装cadquery,在安装OCP CAD Viewer插件。
pip install cadquery
安装cadquery后,在VS Code插件中查找OCP CAD Viewer安装,方便在VS Code查看模型,安装后在VS Code运行查看下。
import cadquery as cq
from ocp_vscode import show, show_object
result = cq.Workplane("XY").box(2,2,2).shell(0.2)
show_object(result)
如果出现错误,不显示模型,在VS Code左侧栏点击OCP图标,在点击ocp_vscode行右侧的Open viewer按钮,就会显示RUNNING并运行,再次运行代码即可。
https://cadquery.readthedocs.io/en/latest/installation.html https://github.com/bernhard-42/vscode-ocp-cad-viewer
快速入门
核心概念
CadQuery 是一个基于 Python 的 3D CAD 建模库,其底层是 OpenCascade 几何内核。
BREP 拓扑
CadQuery 使用边界表示法(BREP)来定义 3D 物体,即物体由其表面来定义。基本的拓扑元素从简单到复杂依次为:
- 顶点 (Vertex):空间中的一个点
- 边 (Edge):连接两个或多个顶点的曲线段
- 线框 (Wire):一组相互连接的边
- 面 (Face):由线框围成的平面或曲面
- 实体 (Solid):由面围成的封闭三维体
- 复合体 (Compound):多个实体的集合
API 层次结构
CadQuery 提供了三个层次的 API,从上到下越来越灵活,但也越来越复杂。
流畅 API
流畅 API是通过链式调用进行建模的接口,入门首选,简单易用。主要分为2类
- Workplane类,传统 3D 建模,最常用。 示例:
part = Workplane("XY").box(1,2,3).faces(">Z").circle(0.5).cutThruAll() - Sketch类,二维草图专用,更符合传统 CAD 绘图习惯,CadQuery 2.x版本引入。
两者可以协同工作,如从二维草图开始创建三维模型Sketch → Workplane.placeSketch() → .extrude(),在现有模型上添加特征Workplane → 选面 → .sketch() → 修改 → .cutBlind()。典型工作流示例:
# 创建一个带孔和圆角的平板
sketch_base = Sketch().rect(20, 15).constrain().solve() # 底板轮廓
base = Workplane().placeSketch(sketch_base).extrude(3) # 拉伸底板
# 在底板上表面画圆孔
hole_sketch = base.faces(">Z").sketch().circle(2).constrain().solve()
result = base.faces(">Z").placeSketch(hole_sketch).cutBlind(2)
Sketch 和 Workplane 的 2D 操作区别:
- Workplane 的 2D 操作:过程式建模,按顺序执行命令:画圆 → 移动 → 画矩形,尺寸硬编码数值,适用简单、固定的轮廓场景。
- Sketch :约束驱动建模,定义几何约束如圆与矩形同心、相切等,尺寸约束 + 变量控制,适用复杂、参数化、需要设计意图的轮廓。
传统 CAD 中,设计意图(如"这个孔始终与板的中心对齐")是通过约束实现的。Workplane 的过程式方式需要手动计算位置,参数变化时容易出错。Sketch约束后自动计算。当轮廓包含多个相互关联的图形时(如齿轮轮廓、法兰盘),约束系统能保证所有元素的关系正确。
直接 API
- 当流畅 API 不够用时使用,直接操作拓扑元素(顶点、边、面等)。
- 可以“自底向上”构建几何体,控制更精细。
- 示例:`wire = Wire.makeCircle(10); face = Face.makeFromWires(wire, [])`
OCCT API
- 最底层,直接调用 OpenCascade 的 C++ 函数(通过 Python 绑定 `OCP`)。
- 极其强大但也极其繁琐,适合需要完全控制的场景。
- 示例:`from OCP.BRepPrimAPI import BRepPrimAPI_MakeBox`
在 API 之间切换
你可以根据需要混合使用不同层次的 API:
- 从流畅 API 获取直接 API 对象:使用 `.val()` 或 `.findSolid()` 方法。
- 从直接 API 对象回到流畅 API:将直接 API 对象作为参数传入新的 `Workplane`。
- 获取底层的 OCCT 对象:直接 API 对象通过 `.wrapped` 属性即可获得。
选择器
选择器用于在已有模型上快速定位特征,相当于传统 CAD 中的鼠标选取。你可以通过字符串表达式选择面、边、顶点等。
- 例如:`faces(">Z")` 选择最上方的面,`edges(">X")` 选择 X 轴正方向的边。
API 参考
草图初始化
| 内容 | 描述 | 示例 |
|---|---|---|
Sketch(parent, locs, obj) |
2D 草图,用于构建二维几何形状 | s = Sketch()创建一个空的 2D 草图对象 |
Sketch.importDXF(filename[, tol, exclude, ...]) |
导入 DXF 文件并构建面 | sketch = Sketch.importDXF("profile.dxf")从 DXF 文件导入几何图形并创建草图 |
Workplane.sketch() |
初始化并返回一个草图 | s = Workplane().sketch()初始化一个新草图,通常在创建后自动调用 |
Sketch.finalize() |
完成草图构造并返回父对象 | result = sketch.finalize()完成草图编辑,返回父对象(通常用于链式调用) |
Sketch.copy() |
创建草图的局部副本 | s2 = s.copy()创建草图 s 的一个独立副本,用于后续修改而不影响原草图。 |
Sketch.located(loc) |
创建带有新位置的草图局部副本 | sketch.located(Location(Vector(10, 0, 0)))创建草图副本并平移到新位置 |
Sketch.moved(....) |
创建移动后的面的草图局部副本 | sketch.moved(Vector(5, 5))将草图中的面移动后创建新副本 |
草图选择
| 内容 | 描述 | 示例 |
|---|---|---|
Sketch.tag(name) |
为当前选择添加标签 | sketch.rect(10, 10).tag("outer")创建一个 10x10 矩形并为其添加标签 "outer",便于后续选择 |
Sketch.select(tag) |
根据标签选择元素 | sketch.select("outer")选择之前标记为 "outer" 的几何元素 |
Sketch.reset() |
重置当前选择状态 | sketch.reset()清除所有当前选中的元素,恢复到初始未选择状态 |
Sketch.delete([mode]) |
删除选中的对象 | sketch.circle(5).tag("hole").delete()创建一个圆形后标记并删除它 |
Sketch.faces([selector]) |
选择面元素 | sketch.rect(10, 10).faces().fillet(1)选择矩形面并添加圆角 |
Sketch.edges([selector]) |
选择边元素 | sketch.rect(10, 10).edges().chamfer(0.5)选择矩形所有边并添加倒角 |
Sketch.vertices([selector]) |
选择顶点元素 | sketch.rect(10, 10).vertices().fillet(2)选择矩形所有顶点并添加圆角 |
基于面的草图绘制
- Sketch Mode 类型说明
'a'- Add (添加) - 添加区域到草图 - 默认模式,创建实体区域's'- Subtract (减去) - 从现有区域中减去 - 创建孔洞或凹陷'i'- Intersect (相交) - 保留与现有区域的交集 - 创建重叠部分'c'- Construction (构造) - 创建辅助几何 - 辅助线/圆,不参与实体'g'- Guide (引导) - 引导线 - 用于扫掠等操作
| 内容 | 描述 | 示例 |
|---|---|---|
Sketch.face(b[, angle, mode, tag, ...]) |
从线框或边构建一个面 | s = Sketch().face(wire, mode='a')从闭合线框创建一个面,使用 ADD 模式添加到现有图形 |
Sketch.rect(w, h[, angle, mode, tag]) |
构建一个矩形面 | cq.Sketch().rect(10, 20).rect(5, 10, mode='s')创建一个 10x20 矩形,然后在其中减去一个 5x10 矩形 |
Sketch.circle(r[, mode, tag]) |
构建一个圆形面 | s = cq.Sketch().circle(5).circle(3,mode='s')创建一个半径 5 的圆,然后在中心减去一个半径 3 的圆(形成环形) |
Sketch.ellipse(a1, a2[, angle, mode, tag]) |
构建一个椭圆面 | s = Sketch().ellipse(10, 5)创建一个长半轴 10、短半轴 5 的椭圆面 |
Sketch.trapezoid(w, h, a1[, a2, angle, ...]) |
构建一个梯形面 | s = Sketch().trapezoid(10, 5, 2)创建一个顶宽 10、高 5、顶部偏移 2 的梯形 |
Sketch.slot(w, h[, angle, mode, tag]) |
构建一个槽形面 | s = Sketch().slot(20, 5)绘制一个长度20、宽度5的槽形面(带圆角) |
Sketch.regularPolygon(r, n[, angle, mode, tag]) |
构建一个正多边形面 | s = Sketch().regularPolygon(5, 6)创建一个外接圆半径 5、6 条边的正六边形面 |
Sketch.polygon(pts[, angle, mode, tag]) |
构建一个多边形面 | s = Sketch().polygon([(0,0), (10,0), (5,8)])创建一个由三个点构成的三角形面 |
Sketch.rarray(xs, ys, nx, ny) |
生成一个矩形位置阵列 | s = cq.Sketch().rect(50, 40).rarray(4, 3, 12, 10).circle(2, mode='s')创建一个 3x3 矩形,然后在创建12x10的孔阵列。 |
Sketch.parray(r, a1, da, n[, rotate]) |
生成极坐标阵列位置 | sketch.parray(20, 0, 360, 8)创建围绕中心、半径 20、从 0 度到 360 度均匀分布的 8 个极坐标阵列位置 |
Sketch.distribute(n[, start, stop, rotate]) |
沿选中的边或线框分布位置 | sketch.rect(20, 10).edges().distribute(5)沿矩形选中边均匀分布 5 个位置点 |
Sketch.each(callback[, mode, tag, ...]) |
对所有适用实体应用回调函数 | sketch.rarray(5, 5, 3, 2).each(lambda loc: Sketch().circle(2).moved(loc))在每个阵列位置点执行回调,绘制半径为 2 的圆 |
Sketch.push(locs[, tag]) |
将当前选择设置为给定位置或点 | sketch.push([Vector(0,0), Vector(10,10), Vector(20,0)])将三个位置点推入当前选择栈,作为后续操作的基准点 |
Sketch.hull([mode, tag]) |
从当前选择或所有对象生成凸包 | s = Sketch().circle(3).circle(5, (10,0)).hull()创建两个圆,然后生成包含它们的最小凸包面 |
Sketch.offset(d[, mode, tag]) |
偏移选定的线框或边 | s = Sketch().rect(10, 10).offset(1)创建一个 10x10 矩形,然后向外偏移 1 单位(形成更大的矩形) |
Sketch.fillet(r) |
基于当前选择添加圆角 | s = Sketch().rect(10, 10).vertices().fillet(1)创建一个 10x10 矩形,然后对所有顶点添加半径 1 的圆角 |
Sketch.chamfer(d) |
基于当前选择添加倒角 | s = Sketch().rect(10, 10).vertices().chamfer(1)创建一个 10x10 矩形,然后对所有顶点添加距离 1 的倒角 |
Sketch.clean() |
移除内部线。 | sketch.clean()清理草图中内部的非边界线段。 |
基于边和约束的草图绘制
| 内容 | 描述 | 示例 |
|---|---|---|
Sketch.edge(val[, tag, forConstruction]) |
向草图中添加一条边 | s = Sketch().edge("|")添加一条水平线作为构造线(用于约束) |
Sketch.segment(p1, p2) |
构建一条线段 | s = Sketch().segment((0,0), (10,0))从 (0,0) 到 (10,0) 添加一条线段 |
Sketch.arc(p1, p2, p3) |
构建一条弧线 | s = Sketch().arc((0,0), (5,5), (10,0))通过三点添加一条圆弧 |
Sketch.spline(pts) |
构造样条曲线边 | sketch.spline([(0,0), (5,10), (10,0)])绘制通过给定点的样条曲线边 |
Sketch.close() |
将最后一条边连接到第一条边 | s = Sketch().segment((0,0), (10,0)).segment((10,0), (10,10)).close()添加两条垂直边后闭合,形成 L 形线框 |
Sketch.assemble([mode, tag]) |
将边组合成面 | s = Sketch().rect(10, 10, mode=Mode.PRIVATE).assemble()创建私有矩形边,然后组合成一个面 |
Sketch.constrain(constraint) |
添加一个约束 | s = Sketch().circle(5).constrain(("distance", "origin", 2))创建一个圆,然后添加约束使其圆心距离原点 2 单位 |
Sketch.solve() |
求解当前约束并更新边位置 | s = Sketch().rect(10, 10).constrain(("coincident", "vertex0", "vertex1")).solve()添加重合约束后求解,更新几何位置 |
Workplane 初始化
| 内容 | 描述 | 示例 |
|---|---|---|
Workplane(, obj) |
在空间中定义一个坐标系,可用于2D坐标操作。 | Workplane()创建一个新的Workplane对象,默认在XY平面原点。 |
2D 操作
| 内容 | 描述 | 示例 |
|---|---|---|
Workplane.center(x, y) |
将局部坐标移动到指定位置 | result = cq.Workplane().center(5, 5).rect(10, 10)将工作平面中心移动到 (5,5) 后创建 10x10 矩形 |
Workplane.lineTo(x, y[, forConstruction]) |
从当前点到指定点绘制一条线 | result = cq.Workplane().moveTo(0,0).lineTo(10, 10)从原点画线到 (10,10) |
Workplane.line(xDist, yDist[, forConstruction]) |
从当前点绘制相对直线 | cq.Workplane().moveTo(0,0).line(5, 5)从当前点相对移动 (5,5) 并绘制直线 |
Workplane.vLine(distance[, forConstruction]) |
从当前点绘制垂直直线 | cq.Workplane().moveTo(0,0).vLine(10)从当前点垂直向上绘制长度 10 的直线 |
Workplane.vLineTo(yCoord[, forConstruction]) |
从当前点绘制垂直直线到指定 Y 坐标 | cq.Workplane().moveTo(0,0).vLineTo(15)垂直绘制到 Y=15 的直线 |
Workplane.hLine(distance[, forConstruction]) |
从当前点绘制水平直线 | cq.Workplane().moveTo(0,0).hLine(10)水平绘制长度 10 的直线 |
Workplane.hLineTo(xCoord[, forConstruction]) |
从当前点绘制水平直线到指定 X 坐标 | cq.Workplane().moveTo(0,0).hLineTo(15)水平绘制到 X=15 的直线 |
Workplane.polarLine(distance, angle[, ...]) |
从当前点按角度和长度绘制直线 | cq.Workplane().moveTo(0,0).polarLine(10, 45)以 45 度角绘制长度 10 的直线 |
Workplane.polarLineTo(distance, angle[, ...]) |
从当前点绘制极坐标直线到指定位置 | cq.Workplane().moveTo(0,0).polarLineTo(10, 90)绘制到极坐标 (10, 90°) 的直线 |
Workplane.moveTo(x, y) |
移动到指定点(不绘制) | cq.Workplane().moveTo(5, 5).lineTo(10, 10)将当前点移动到 (5,5)(不绘制),然后从该点画线到 (10,10) |
Workplane.move([xDist, yDist]) |
相对移动指定距离(不绘制) | cq.Workplane().move(3, 4).line(5, 0)相对移动 (3,4)(不绘制),然后水平绘制长度 5 的直线 |
Workplane.spline(listOfXYTuple[, tangents, ...]) |
创建通过给定点的样条曲线(2D或3D) | cq.Workplane().spline([(0,0), (5,10), (10,0)])绘制通过三个点的平滑样条曲线 |
Workplane.parametricCurve(func[, N, start, ...]) |
创建逼近给定函数的样条曲线 | cq.Workplane().parametricCurve(lambda t: (t, t**2), N=50)绘制参数曲线 y=x² 的逼近样条,使用 50 个采样点 |
Workplane.parametricSurface(func[, N, start, ...]) |
创建逼近给定函数的样条曲面 | cq.Workplane().parametricSurface(lambda u,v: (u, v, u*v))绘制参数曲面 z=xy 的逼近曲面 |
Workplane.threePointArc(point1, point2[, ...]) |
通过三个点绘制圆弧 | cq.Workplane().moveTo(0,0).threePointArc((5,0), (10,0))从当前点通过 (5,0) 到 (10,0) 绘制圆弧(形成半圆) |
Workplane.sagittaArc(endPoint, sag[, ...]) |
使用矢高(sagitta)定义的圆弧 | cq.Workplane().moveTo(0,0).sagittaArc((10,0), 2)绘制到 (10,0)、矢高 2 的圆弧(拱形) |
Workplane.radiusArc(endPoint, radius[, ...]) |
使用半径定义的圆弧 | cq.Workplane().moveTo(0,0).radiusArc((10,0), 5)绘制到 (10,0)、半径 5 的圆弧 |
Workplane.tangentArcPoint(endPoint) |
从当前边末端绘制切线圆弧到指定点 | cq.Workplane().moveTo(0,0).lineTo(5,0).tangentArcPoint((10,5))先绘制水平线,然后绘制与前一条边相切的圆弧到 (10,5) |
Workplane.mirrorY() |
沿 Y 轴镜像实体 | cq.Workplane().rect(5, 10).mirrorY()将矩形沿 Y 轴镜像,生成对称图形 |
Workplane.mirrorX() |
沿 X 轴镜像实体 | cq.Workplane().rect(5, 10).mirrorX()将矩形沿 X 轴镜像,生成对称图形 |
Workplane.wire([forConstruction]) |
将所有待定边连接成线框 | cq.Workplane().moveTo(0,0).lineTo(10,0).lineTo(10,10).wire()将两条边连接成 L 形线框对象 |
Workplane.rect(xLen, yLen[, centered, ...]) |
为栈上每个项构造矩形 | cq.Workplane().rect(10, 20)在工作平面原点绘制 10x20 的矩形(默认 centered=True) |
Workplane.circle(radius[, forConstruction]) |
为栈上每个项构造圆 | cq.Workplane().circle(5)在工作平面原点绘制半径 5 的圆 |
Workplane.ellipse(x_radius, y_radius[, ...]) |
为栈上每个项构造椭圆 | cq.Workplane().ellipse(10, 5)在工作平面原点绘制长轴 10、短轴 5 的椭圆 |
Workplane.ellipseArc(x_radius, y_radius[, ...]) |
绘制椭圆弧 | cq.Workplane().ellipseArc(10, 5, 0, 90)在工作平面原点绘制从 0° 到 90° 的椭圆弧 |
Workplane.polyline(listOfXYTuple[, ...]) |
从点列表创建折线 | cq.Workplane().polyline([(0,0), (10,0), (10,10)])绘制连接三个点的折线(L 形) |
Workplane.close() |
结束构建并尝试创建封闭线框 | cq.Workplane().moveTo(0,0).lineTo(10,0).lineTo(10,10).close()闭合当前绘制的轮廓,形成封闭矩形线框 |
Workplane.rarray(xSpacing, ySpacing, xCount, ...) |
创建矩形阵列点并推入栈 | cq.Workplane().rarray(10, 10, 3, 2).circle(2)创建 3 列 2 行、间距 10 的矩形阵列点,并在每个点绘制半径 2 的圆 |
Workplane.polarArray(radius, startAngle, ...) |
创建极坐标阵列点并推入栈 | cq.Workplane().polarArray(20, 0, 360, 8).circle(2)创建 8 个点的 360° 极坐标阵列,并在每个点绘制半径 2 的圆 |
Workplane.slot2D(length, diameter[, angle]) |
创建带圆角的槽形 | cq.Workplane().slot2D(20, 5)在工作平面原点创建长度 20、宽度 5 的跑道形槽 |
Workplane.offset2D(d[, kind, forConstruction]) |
创建 2D 偏移线框 | cq.Workplane().rect(10, 10).offset2D(2)将 10x10 矩形线框向外偏移 2 个单位,生成更大的矩形 |
Workplane.placeSketch(sketch) |
根据栈上项放置草图 | cq.Workplane().placeSketch(mySketch).extrude(5)将 Sketch 对象放置到当前 Workplane 位置,然后拉伸 5 个单位 |
3D 操作(需要活动工作平面)
| 内容 | 描述 | 示例 |
|---|---|---|
Workplane.cboreHole(diameter, cboreDiameter, cboreDepth[, depth, clean]) |
创建沉头孔 | cq.Workplane().box(50, 50, 10).faces(">Z").workplane().cboreHole(5, 10, 3, depth=8)在盒子顶面上创建直径 5、沉头直径 10、沉头深度 3、总深 8 的沉头孔 |
Workplane.cskHole(diameter, cskDiameter, cskAngle[, depth, clean]) |
创建锥形沉头孔 | cq.Workplane().box(50, 50, 10).faces(">Z").workplane().cskHole(5, 10, 90, depth=8)在盒子顶面上创建直径 5、锥头直径 10、锥角 90° 的锥形沉头孔 |
Workplane.hole(diameter[, depth, clean]) |
创建通孔或盲孔 | cq.Workplane().box(50, 50, 10).faces(">Z").workplane().hole(5, depth=8)在盒子顶面上创建直径 5、深度 8 的盲孔 |
Workplane.extrude(until[, combine, clean, both, taper]) |
将线框挤出为棱柱体,可以给定数值,或'next','last ',或输入一个对象的Face。 | result = cq.Workplane().rect(10, 20).extrude(30)将 10x20 矩形沿法线方向挤出高度 30 的实体 result = cq.Workplane(origin=(20, 0, 0)).circle(2).revolve(180, (-20, 0, 0), (-20, -1, 0)).center(-20, 0).workplane().rect(10, 4).extrude("last") |
Workplane.cut(toCut[, clean, tol]) |
从当前实体切除另一个实体 | result = cq.Workplane().box(50, 50, 10).cut(cq.Workplane().sphere(8))从盒子中减去半径为 8 的球体(布尔差集运算) |
Workplane.cutBlind(until[, clean, both, taper]) |
盲切(有限深度挤出切除) | result = cq.Workplane().rect(10, 20).cutBlind(15)将当前轮廓沿法线方向挤出切除深度 15 的槽 |
Workplane.cutThruAll([clean, taper]) |
贯穿切除 | result = cq.Workplane().rect(10, 20).cutThruAll()将当前轮廓贯穿整个实体进行切除 |
Workplane.box(length, width, height[, centered, combine]) |
创建立方体 | result = cq.Workplane().box(10, 20, 30)创建长 10、宽 20、高 30 的长方体(默认 centered=True,中心位于原点) |
Workplane.sphere(radius[, direct, angle1, angle2, combine]) |
创建球体 | result = cq.Workplane().sphere(10)在当前工作平面位置创建半径 10 的球体 |
Workplane.wedge(dx, dy, dz, xmin, zmin, xmax, zmax[, combine]) |
创建楔形体 | result = cq.Workplane().wedge(10, 20, 30, 0, 0, 10, 20)创建指定尺寸的楔形实体(类似三棱柱形状) |
Workplane.cylinder(height, radius[, direct, angle, combine]) |
创建圆柱体 | result = cq.Workplane().cylinder(30, 10)创建高度 30、半径 10 的圆柱体 |
Workplane.union([toUnion, clean, glue, tol]) |
合并实体 | result = cq.Workplane().box(10, 10, 10).union(cq.Workplane().sphere(5))将球体与当前实体合并(布尔并集运算) |
Workplane.combine([clean, glue, tol]) |
合并栈上所有实体 | result = cq.Workplane().box(10, 10, 10).add(cq.Workplane().sphere(5)).combine()将当前栈中的多个实体合并为一个实体 |
Workplane.intersect(toIntersect[, clean, tol]) |
与当前实体进行布尔交集运算 | result = cq.Workplane().box(10, 10, 10).intersect(cq.Workplane().sphere(8))创建一个 10x10x10 的立方体,然后与半径 8 的球体进行布尔交集,保留两者重叠的部分 |
Workplane.loft([ruled, combine, clean]) |
放样多个截面 | result = cq.Workplane().rect(10, 10).workplane(offset=5).rect(5, 5).loft()将两个不同尺寸的矩形截面放样成 3D 实体 |
Workplane.sweep(path[, multisection, transition, combine, clean]) |
沿路径扫掠截面 | path = cq.Workplane().spline([(0,0,0), (0,0,10)])沿样条曲线路径扫掠圆形截面,生成弯曲管道 |
Workplane.twistExtrude(distance, angleDegrees) |
在拉伸的同时扭转指定角度 | result = cq.Workplane().rect(5, 5).twistExtrude(20, 90)将 5x5 矩形沿法线方向拉伸 20 个单位,同时从底部到顶部扭转 90° |
Workplane.revolve([angleDegrees, axisStart, axisEnd, combine, clean]) |
绕轴旋转生成实体 | result = cq.Workplane().rect(5, 10).revolve(360, (0,0), (0,1))将矩形轮廓绕 Y 轴旋转 360° 生成回转体(类似圆环体或圆柱) |
Workplane.text(txt, fontsize, distance[, ...]) |
返回 3D 文本实体 | result = cq.Workplane().text("CadQuery", 5, 2)创建内容为 "CadQuery"、字体高度 5、拉伸深度 2 的 3D 文本实体 |
3D 操作(无需活动工作平面)
| 内容 | 描述 | 示例 |
|---|---|---|
Workplane.shell(thickness[, kind]) |
移除选定的面以创建指定厚度的壳体 | result = cq.Workplane().box(10, 10, 5).faces(">Z").shell(0.5)创建一个盒子,移除顶面后形成壁厚 0.5 的壳体 |
Workplane.fillet(radius) |
在选定的边上添加圆角 | Z").fillet(2) 在立方体所有垂直边上添加半径 2 的圆角 |
Workplane.chamfer(length[, length2]) |
在选定的边上添加倒角 | Z").chamfer(2) 在立方体所有垂直边上添加距离 2 的倒角 |
Workplane.rotate(axisStartPoint, axisEndPoint, angleDegrees) |
返回旋转后的所有项的副本 | result = cq.Workplane().box(10, 10, 10).rotate((0,0,0), (1,0,0), 45)绕 X 轴旋转立方体 45 度 |
Workplane.rotateAboutCenter(axisEndPoint, ...) |
绕指定轴旋转栈中所有项 | result = cq.Workplane().box(10, 10, 10).rotateAboutCenter((0,0,0), (1,0,0), 45)创建 10x10x10 立方体,然后绕 X 轴(通过原点沿 X 方向)旋转 45 度 |
Workplane.translate(vec) |
返回平移后的所有项的副本 | result = cq.Workplane().box(10, 10, 10).translate((5, 0, 0))将立方体沿 X 轴平移 5 个单位 |
Workplane.mirror([mirrorPlane, ...]) |
镜像单个 CQ 对象 | result = cq.Workplane().box(10, 10, 10).mirror("YZ")创建立方体后,以 YZ 平面为镜像平面进行镜像 |
迭代方法
| 内容 | 描述 | 示例 |
|---|---|---|
Workplane.each(callback[, useLocalCoordinates, ...]) |
对栈中的每个值运行提供的函数,并将返回值收集到新的 CQ 对象中 | result = cq.Workplane().rarray(10, 10, 3, 2).each(lambda loc: cq.Workplane().circle(2).moved(loc))在矩形阵列的每个位置点执行回调函数,在每个点处创建半径为 2 的圆,并收集所有结果 |
Workplane.eachpoint(callback[, useLocalCoordinates, ...]) |
与 each() 类似,但回调函数的参数会根据栈中位置进行平移 | result = cq.Workplane().rarray(10, 10, 3, 2).eachpoint(lambda pos: cq.Workplane().circle(2).translate(pos))在每个位置点处创建圆,回调函数接收位置向量作为参数,便于创建相对于每个点的几何体 |
栈与选择器方法
| 内容 | 描述 | 示例 |
|---|---|---|
Workplane.all() |
返回栈中所有 CQ 对象的列表 | objects = cq.Workplane().box(10, 10, 10).faces().all()获取立方体所有面的列表,返回包含每个面对象的列表 |
Workplane.size() |
返回栈中当前对象的数量 | count = cq.Workplane().box(10, 10, 10).faces().size()获取立方体面的数量(返回 6) |
Workplane.vals() |
获取当前列表中的值 | values = cq.Workplane().box(10, 10, 10).faces().vals()获取所有面对象的原始值(TopoDS_Shape 列表) |
Workplane.add(obj) |
向栈中添加一个对象或对象列表 | result = cq.Workplane().box(10, 10, 10).add(cq.Workplane().sphere(5))创建立方体后添加球体到栈中,栈中现在包含两个实体 |
Workplane.val() |
返回栈中的第一个值 | first = cq.Workplane().box(10, 10, 10).faces().val()获取立方体的第一个面对象 |
Workplane.first() |
返回栈中的第一个项 | first_item = cq.Workplane().box(10, 10, 10).faces().first()获取立方体的第一个面(与 val() 类似) |
Workplane.item(i) |
返回栈中的第 i 个项 | third_face = cq.Workplane().box(10, 10, 10).faces().item(2)获取立方体的第三个面(索引从 0 开始) |
Workplane.last() |
返回栈中的最后一个项 | last_face = cq.Workplane().box(10, 10, 10).faces().last()获取立方体的最后一个面 |
Workplane.end([n]) |
返回此 CQ 元素的第 n 级父对象 | parent = cq.Workplane().box(10, 10, 10).faces().vertices().end(2)从顶点选择返回两级父对象(返回到实体层级) |
Workplane.vertices([selector, tag]) |
选择栈中对象的顶点,可选择过滤 | vertices = cq.Workplane().box(10, 10, 10).vertices()选择立方体的所有 8 个顶点 |
Workplane.faces([selector, tag]) |
选择栈中对象的面,可选择过滤 | top_face = cq.Workplane().box(10, 10, 10).faces(">Z")选择立方体上表面(法线方向为正 Z 的面) |
Workplane.edges([selector, tag]) |
选择栈中对象的边,可选择过滤 | vertical_edges = cq.Workplane().box(10, 10, 10).edges("|Z")选择立方体所有垂直边(平行于 Z 轴) |
Workplane.wires([selector, tag]) |
选择栈中对象的线框,可选择过滤 | wires = cq.Workplane().box(10, 10, 10).faces(">Z").wires()选择立方体顶面的外轮廓线框 |
Workplane.solids([selector, tag]) |
选择栈中对象的实体,可选择过滤 | solids = cq.Workplane().box(10, 10, 10).solids()选择立方体实体(通常只有一个) |
Workplane.shells([selector, tag]) |
选择栈中对象的壳体,可选择过滤 | shells = cq.Workplane().box(10, 10, 10).shell(0.5).shells()创建壳体后选择壳体对象 |
Workplane.compounds([selector, tag]) |
选择栈中的复合体,可选择过滤 | compounds = cq.Workplane().box(10, 10, 10).union(cq.Workplane().sphere(5)).compounds()合并立方体和球体后,选择复合体对象 |
选择器
| 内容 | 描述 | 示例 |
|---|---|---|
NearestToPointSelector(pnt) |
选择离指定点最近的对象 | nearest = cq.Workplane().box(10, 10, 10).faces(NearestToPointSelector((0,0,5)))选择距离点 (0,0,5) 最近的面(通常为上表面) |
BoxSelector(point0, point1[, boundingbox]) |
选择由两点定义的 3D 框内的对象 | faces = cq.Workplane().box(10, 10, 10).faces(BoxSelector((-5,-5,-5), (5,5,5)))选择位于立方体边界框内的所有面 |
BaseDirSelector(vector[, tolerance]) |
基于单个方向向量进行选择的基础选择器 | edges = cq.Workplane().box(10, 10, 10).edges(BaseDirSelector((0,0,1), 0.01))选择方向与 Z 轴对齐的边 |
ParallelDirSelector(vector[, tolerance]) |
选择与指定方向平行的对象 | edges = cq.Workplane().box(10, 10, 10).edges(ParallelDirSelector((0,0,1)))选择平行于 Z 轴的边(即所有垂直边) |
DirectionSelector(vector[, tolerance]) |
选择与指定方向对齐的对象 | faces = cq.Workplane().box(10, 10, 10).faces(DirectionSelector((0,0,1)))选择法线方向为 Z 轴方向的面(上表面和下表面) |
DirectionNthSelector(vector, n[, ...]) |
过滤与指定方向平行(或垂直)的对象,返回第 N 个 | edge = cq.Workplane().box(10, 10, 10).edges(DirectionNthSelector((0,0,1), 2))选择平行于 Z 轴的第 3 条边(索引从 0 开始) |
LengthNthSelector(n[, directionMax, tolerance]) |
选择第 N 个长度的对象 | edge = cq.Workplane().box(10, 10, 10).edges(LengthNthSelector(0))选择长度最短的边 |
AreaNthSelector(n[, directionMax, tolerance]) |
选择第 N 个面积的对象 | face = cq.Workplane().box(10, 10, 10).faces(AreaNthSelector(0))选择面积最小的面(10x10 的面中最小为 100) |
RadiusNthSelector(n[, directionMax, tolerance]) |
选择第 N 个半径的对象 | edge = cq.Workplane().cylinder(10, 5).edges(RadiusNthSelector(0))选择半径最小的边(圆柱体上下圆边半径 5) |
PerpendicularDirSelector(vector[, tolerance]) |
选择与指定方向垂直的对象 | faces = cq.Workplane().box(10, 10, 10).faces(PerpendicularDirSelector((0,0,1)))选择法线方向与 Z 轴垂直的面(四个侧面) |
TypeSelector(typeString) |
选择具有指定几何类型的对象 | faces = cq.Workplane().box(10, 10, 10).faces(TypeSelector("PLANE"))选择所有平面类型的面(立方体所有面都是平面) |
DirectionMinMaxSelector(vector, minOrMax) |
选择在指定方向上最近或最远的对象 | face = cq.Workplane().box(10, 10, 10).faces(DirectionMinMaxSelector((0,0,1), "MAX"))选择在 Z 轴方向上最远的面(即上表面) |
CenterNthSelector(vector, n[, directionMax, ...]) |
按中心在指定方向上投影的距离排序,选择第 N 个对象 | face = cq.Workplane().box(10, 10, 10).faces(CenterNthSelector((0,0,1), 1))按面中心在 Z 轴投影距离排序,选择第 2 个面 |
AndSelector(left, right) |
交集选择器(同时满足两个选择器) | faces = cq.Workplane().box(10, 10, 10).faces(AndSelector(DirectionSelector((0,0,1)), TypeSelector("PLANE")))选择法线为 Z 轴方向的平面(即上表面和下表面) |
SumSelector(left, right) |
并集选择器(满足任一选择器) | faces = cq.Workplane().box(10, 10, 10).faces(SumSelector(DirectionSelector((0,0,1)), DirectionSelector((1,0,0))))选择法线为 Z 轴或 X 轴方向的面 |
SubtractSelector(left, right) |
差集选择器(满足 left 但不满足 right) | faces = cq.Workplane().box(10, 10, 10).faces(SubtractSelector(DirectionSelector((0,0,1)), TypeSelector("PLANE")))选择法线为 Z 轴方向但非平面的面(立方体中无结果) |
InverseSelector(selector) |
反转给定选择器的选择结果 | faces = cq.Workplane().box(10, 10, 10).faces(InverseSelector(DirectionSelector((0,0,1))))选择所有法线方向不是 Z 轴的面(即四个侧面) |
StringSyntaxSelector(selectorString) |
使用简单字符串语法过滤对象列表 | faces = cq.Workplane().box(10, 10, 10).faces(StringSyntaxSelector(">Z"))使用字符串语法选择法线方向为正 Z 的面(等价于 ">Z") |
装配体
| 内容 | 描述 | 示例 |
|---|---|---|
Assembly([obj, loc, name, color, material, ...]) |
嵌套的 Workplane 和 Shape 对象装配体,定义它们的相对位置 | assy = cq.Assembly()创建一个空的装配体对象,用于组织和定位多个零件 |
Assembly.add(obj[, loc, name, color, ...]) |
向当前装配体添加子装配体或零件 | assy.add(cq.Workplane().box(10, 10, 5), name="base")向装配体添加底座(立方体)和顶部球体,并指定位置和名称 |
Assembly.save(path[, exportType, mode, ...]) |
将装配体保存到文件 | assy.save("assembly.step")将装配体保存为 STEP 文件,支持 STEP、STL、VRML 等格式 |
Assembly.constrain(constraint) |
定义一个新的约束 | assy.constrain("base", "top", "Axis", (0,0,1), (0,0,1))约束底座和顶部的 Z 轴对齐,使球体位于底座正上方 |
Assembly.solve([verbosity]) |
求解所有已定义的约束 | assy.solve()求解所有约束,自动调整零件位置以满足约束条件,verbosity=1 可输出求解详情 |
Color(r, g, b[, a]) |
OCCT 颜色对象 Quantity_ColorRGBA 的包装器 | red = cq.Color(1, 0, 0)创建红色颜色对象,并将其应用于装配体中的零件 |
导出与导入
| 内容 | 描述 | 示例 |
|---|---|---|
Workplane.toSvg([opts]) |
返回表示栈中第一个项的 SVG 文本 | svg_text = cq.Workplane().rect(10, 10).toSvg()创建矩形并将其转换为 SVG 文本字符串,可用于网页显示或保存 |
Workplane.exportSvg(fileName) |
将栈中第一个项导出为 SVG 文件 | cq.Workplane().rect(10, 10).exportSvg("rectangle.svg")创建矩形并导出为 "rectangle.svg" 文件 |
importers.importStep(fileName) |
加载 STEP 文件到 CadQuery Workplane | part = cq.importers.importStep("model.step")从 "model.step" 文件导入 3D 模型,返回 Workplane 对象 |
importers.importDXF(filename[, tol, exclude, ...]) |
加载 DXF 文件到 Workplane | sketch = cq.importers.importDXF("profile.dxf", tol=0.01)从 DXF 文件导入 2D 轮廓,容差设为 0.01 |
exporters.export(w, fname[, exportType, ...]) |
将 Workplane 或 Shape 导出到文件 | cq.exporters.export(part, "output.step")将 Workplane 对象导出为 STEP 文件,支持 STL、STEP、SVG 等格式 |
occ_impl.exporters.dxf.DxfDocument([...]) |
从 CadQuery 对象创建 DXF 文档 | doc = cq.occ_impl.exporters.dxf.DxfDocument()创建 DXF 文档对象,添加几何形状后保存为 DXF 文件 |