一、痛点引入
图纸下发了,质检员拿到一张总图,上面密密麻麻 80 多个尺寸标注——长度、角度、半径、直径混在一起。主管的要求是:把每个尺寸的类型、标称值、公差逐个抄到 Excel 检验清单里,后面好对照实测。
两个人对着屏幕数尺寸,一个念一个敲,抄到第 30 个发现漏了一个,从头对……一天下来眼花手酸,还不敢保证没抄错。
这不是质检员效率低,是工具没跟上。今天用一段 Python 脚本,把整张图纸的尺寸标注自动提取成结构化检验清单,10 秒搞定。
二、核心思路
整条数据链路是:打开工程图 遍历图幅 遍历视图 取尺寸集合 逐个读取类型/值/公差 导出 CSV。
Python 脚本
pywin32 COM
CATIA.Application ActiveDocument (DrawingDocument)
Sheets Sheet Views View
View.Dimensions (DrawingDimensions 集合)
Dimension.GetValue() DrawingDimValue.Value (实际数值)
Dimension.DimType (尺寸类型枚举)
Dimension.GetTolerances() (公差信息)
CSV 检验清单你需要准备:
- pywin32(
pip install pywin32) - 一张已标注尺寸的 CATIA 工程图(.CATDrawing)
三、环境搭建(1分钟)
pip install pywin32验证 CATIA COM 连接是否正常:
import win32com.client
catia = win32com.client.Dispatch("CATIA.Application")
doc = catia.ActiveDocument
print(f"文档名: {doc.Name}")
print(f"类型: {'DrawingDocument' if doc.Sheets.Count > 0 else '非工程图'}")输出 文档名: xxx.CATDrawing 且 类型: DrawingDocument 即环境就绪。
四、核心代码
import win32com.client
import csv
# ========== 第1步:连接 CATIA,获取当前工程图 ==========
catia = win32com.client.Dispatch("CATIA.Application")
doc = catia.ActiveDocument
if not hasattr(doc, "Sheets"):
raise RuntimeError("请先打开一张工程图(.CATDrawing)")
sheets = doc.Sheets
# 尺寸类型枚举映射表(CatDimType 中文标签)
DIM_TYPE_MAP = {
0: "距离", 1: "偏距", 2: "长度", 3: "曲线长度",
4: "角度", 5: "半径", 6: "切向半径", 7: "柱面半径",
8: "边线半径", 9: "直径", 10: "切向直径", 11: "柱面直径",
12: "边线直径", 13: "锥径", 14: "倒角", 15: "斜度",
16: "圆周长", 17: "圆角半径", 18: "环径", 19: "环半径",
20: "最小距离"
}
# ========== 第2步:遍历所有图幅 视图 尺寸 ==========
results = []
for i in range(1, sheets.Count + 1):
sheet = sheets.Item(i)
views = sheet.Views
for j in range(1, views.Count + 1):
view = views.Item(j)
dims = view.Dimensions # DrawingDimensions 集合
for k in range(1, dims.Count + 1):
dim = dims.Item(k)
# --- 尺寸类型 ---
dim_type_id = dim.DimType # 返回 CatDimType 枚举值(int)
dim_type_name = DIM_TYPE_MAP.get(dim_type_id, f"未知({dim_type_id})")
# --- 尺寸值 ---
# 注意:GetValue 是方法,必须加括号调用!
# 写成 dim.GetValue(不带括号)会返回 method 对象而非 DrawingDimValue
dim_value_obj = dim.GetValue()
dim_value = dim_value_obj.Value # 实际数值(float)
# --- 公差信息 ---
# GetTolerances 返回 SafeArray:[上偏差, 下偏差, 公差类型]
try:
tol = dim.GetTolerances()
tol_upper = tol[0] if len(tol) > 0 else ""
tol_lower = tol[1] if len(tol) > 1 else ""
except Exception:
tol_upper, tol_lower = "", ""
# --- 前缀/后缀文本(如 "4-M", "H7") ---
try:
ps = dim_value_obj.GetBaultText(1) # 1=主值
# 返回 (before, after, upper, lower)
prefix = ps[0] if ps[0] else ""
suffix = ps[1] if ps[1] else ""
except Exception:
prefix, suffix = "", ""
results.append({
"序号": len(results) + 1,
"图幅": sheet.Name,
"视图": view.Name,
"尺寸名": dim.Name,
"类型": dim_type_name,
"标称值": round(dim_value, 3),
"上偏差": tol_upper,
"下偏差": tol_lower,
"前缀": prefix,
"后缀": suffix,
})
# ========== 第3步:导出 CSV 检验清单 ==========
output_path = r"D:\尺寸检验清单.csv"
fieldnames = ["序号", "图幅", "视图", "尺寸名", "类型",
"标称值", "上偏差", "下偏差", "前缀", "后缀"]
with open(output_path, "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(results)
print(f"完成!共提取 {len(results)} 个尺寸标注")
print(f"检验清单已保存至: {output_path}")代码解析:
View.Dimensions:返回当前视图的DrawingDimensions集合,包含该视图下所有尺寸标注。dim.GetValue():返回DrawingDimValue对象——必须加括号调用,这是 pywin32 的经典坑(不带括号返回的是 method 对象,不是尺寸值对象)。dim_value_obj.Value:在DrawingDimValue上取.Value,得到float类型的实际数值。dim.DimType:返回CatDimType枚举(int),用映射表转成中文标签,方便质检员阅读。dim.GetTolerances():返回 SafeArray,索引 [0] 为上偏差、[1] 为下偏差;无公差时可能抛异常,用 try/except 兜底。dim_value_obj.GetBaultText(1):获取主值的附加文本(前缀/后缀/上文本/下文本),参数 1 代表主值、2 代表双值。
五、效果对比
| 对比项 | 人工逐个抄写 | 自动化脚本 |
|---|---|---|
| 80 个尺寸耗时 | 4-6 小时 | 约 10 秒 |
| 出错率 | 高(看漏/敲错/串行) | 极低(直接读 API) |
| 公差信息 | 容易漏抄 | 自动提取上下偏差 |
| 可重复性 | 每张图重来 | 一键运行 |
| 格式统一性 | 因人而异 | CSV 标准格式,可直接导入 Excel |
六、进阶用法
技巧 1:用 Selection.Search 全局搜索所有尺寸
上面的代码按"图幅视图尺寸"三层遍历,逻辑清晰但对超大图纸偏慢。用 Selection.Search 一步搜全图尺寸:
sel = doc.Selection
sel.Search("CATDrwSearch.DrwDimension,all") # 搜索全部尺寸
for i in range(1, sel.Count + 1):
dim = sel.Item(i).Value # 直接拿到 DrawingDimension
val = dim.GetValue().Value
print(f"[{i}] {dim.Name} = {val:.3f}")
sel.Clear()CATDrwSearch.DrwDimension 是 CATIA 内置的搜索类型,all 表示全文档范围。这种写法跳过了图幅/视图层级,适合"我只要所有尺寸值"的快速场景。
技巧 2:按尺寸类型分组统计
检验清单导出后,质检员往往需要按类型统计——多少个长度、多少个角度、多少个直径:
from collections import Counter
type_counter = Counter(r["类型"] for r in results)
print("=== 尺寸类型分布 ===")
for t, cnt in type_counter.most_common():
print(f" {t}: {cnt} 个")
# 示例输出:
# 长度: 32 个
# 直径: 18 个
# 角度: 15 个
# 半径: 10 个
# ...按类型分组后,可以把不同类型的尺寸分给不同工位的质检员,分配更均衡。
关注回复「尺寸检验」获取完整源码
下一篇:回到 CAA C++ 第5篇——单步撤销与命令持久化,把工具改得能 Undo / Redo
_栏目:开发实战 | 发布日期:2026-08-24 | 字数:约 1100 字_