直接说结论:能判断,而且方法不止一种。我做CAD二次开发和三维模型处理有些年头了,这个问题刚入行的时候困扰过我很久,后来在好几个实际项目里反复踩坑、翻文档、试API,才把这块彻底捋清楚。今天就把它掰开揉碎了讲一遍,从原理到实操,从最简单的手动检查到代码批量判断,全给你盘明白。
1. 先把问题拆开:"面之间有标注"到底是个什么需求
先说清楚我们讨论的场景。在三维CAD软件里(我主要用NX和SolidWorks,思路在Creo、CATIA上同样适用),"面"通常指实体的表面(Face),"面之间"可以是两个相邻面的公共边(Edge)、两个平行面之间的尺寸关系、或者一个面相对基准面的位置关系。
"标注"这个词,在不同语境下差别很大:
- PMI标注(Product and Manufacturing Information):直接挂在三维模型上的尺寸、公差、粗糙度、基准符号、形位公差框格,这是最典型的三维标注,不需要进工程图就能看到。
- 特征树里的标注:建模历史里带的尺寸、表达式、关系式,比如拉伸深度、草图尺寸,改了特征树里能看出来。
- 工程图标注:在制图模块里投影视图之后标上去的尺寸、注释。严格说它们挂在视图上,但与你选中的面存在引用关联。
- 分析类标注:像颜色映射、热力图、应力云图这种临时显示,不算严格意义的"标注"。
很多人实际想问的是:我选中一个面,想知道它在三维模型上是不是已经被尺寸或符号标注过了,能不能靠程序批量查出来。
这种需求很普遍。比如做模型检查的人,要确认所有关键面都有PMI标注才能发图;做标准化审查的,要找出哪些孔位漏标了尺寸;做自动化出图前处理的,需要根据已标注情况决定要不要自动补标,避免重复标注。
2. 判断是否有标注的三个层次
搞清楚需求之后,判断方法可以分三个层次,从低到高:
| 层次 | 方法 | 适用人群 | 可靠性 |
|---|---|---|---|
| 第一层 | 肉眼观察模型树和视图 | 任何人 | 一般,容易漏 |
| 第二层 | 查询选择过滤器 / 编辑标注命令时的预高亮 | 设计/工艺人员 | 中等,依赖软件交互 |
| 第三层 | 通过API遍历PMI对象与面的关联关系 | 开发人员 | 高,可批量,可自动出报告 |
第一层不需要展开讲,是个人都会。关键在于第二层和第三层。
第二层看着"土",其实非常实用。几乎所有主流CAD软件都提供了标注显示开关和对象查询过滤器。在NX里叫PMI显示设置和选择规则,在SolidWorks里叫注解(Annotations)显示与DimXpert,在CATIA里叫Annotations和3D Functional Tolerancing。你把显示全部打开,模型半透明化,选中面之后右键"显示关联标注",软件会把与该面相关的所有尺寸、符号都亮出来,一眼就看清该面有没有标注。这招对单个面排查,是效率最高的首选手法。
第三层是核心,如果模型量大、成百上千个面,靠人眼翻看根本不现实。必须走API遍历。
3. 用API批量判断的核心思路
无论哪款软件,API层面判断"面是否有标注"的底层逻辑是一致的,就三步:
- 拿到目标面(Face)的底层对象指针或标识。
- 遍历模型里所有标注对象(PMI / Annotation),对每个标注对象获取它的"关联几何",也就是它依附于哪个面、哪条边、哪个顶点。
- 做关联比对:如果某个标注对象的关联几何里包含你选中的面(或者几何来自该面),这个面就是"有标注"的。
听起来简单,实际坑不少。最大的坑在第二步:不同软件里"标注关联到的几何"可能不是面本身,而是面的某条边或某个点,甚至是一条虚拟中心线。比如标注一个圆柱孔直径,标注对象关联的可能不是孔壁面,而是孔的中心轴线(Centerline)或者圆柱边缘;标注两个面的角度,关联的是它们的公共边。如果你的程序只做"标注直接挂在面上"这类判断,会漏掉一大批实际有效的标注。
所以在开发逻辑上我做判断时,用的是"扩充关联集"的思路:
- 标注关联了面,直接判定该面有标注。
- 标注关联了边,则找到这条边的两个邻接面,判定它们有标注。
- 标注关联了顶点,则找到该点关联的所有面,判定有标注。
- 标注关联了中心线/轴线,如果软件能通过API反查到这条轴线属于哪个孔面,把这些面也算进去。
这个思路我实际用下来,误判率能压到5%以内,剩下的误判基本都是特殊几何形态(比如样条曲面上的虚拟线)导致的,可接受。
4. NX里的具体实现:Journals + PMI遍历
以我最常用的NX为例。NX提供了强大的Journal(录制/回放脚本)机制,配合NXOpen API,可以实现上述逻辑。我用的是C#写Journal,VB.NET和Python(NX 12之后才较好支持)也可以。
主要用到的类和接口:
Face:面对象。Edge:边对象。Annotation:标注对象的基类,下面有Dimension、DraftingNote、DatumFeature、GeometricTolerance、SurfaceFinish等子类。IPmiAnnotation:PMI标注接口,能拿到标注的几何关联(GeometryAssociativity)。
核心代码逻辑大致如下(C#风格,为了方便理解做了简化):
// 遍历所有PMI标注 foreach (Annotation ann in workPart.Annotations) { // 只查PMI类型 if (ann is IPmiAnnotation pmi) { // 获取关联几何 PmiAssociativeData data = pmi.AssociativeData; foreach (AssociativeGeometry geom in data.GetAssociativeGeometries()) { // 你可能拿到的是面、边、曲线或点 if (geom.Geometry is Face face) { if (face == targetFace) { result.Add(ann); } } else if (geom.Geometry is Edge edge) { // 判断这条边是不是目标面的边 if (IsEdgeOfFace(edge, targetFace)) { result.Add(ann); } } // 顶点、轴线的判断类似,略 } } } bool IsEdgeOfFace(Edge edge, Face face) { foreach (Face adjacentFace in edge.GetFaces()) { if (adjacentFace == face) return true; } return false; }要特别注意:GetAssociativeGeometries()返回的关联几何在NX里可能表现为AssociativeGeometry对象,它的.Geometry属性才是真实的面、边、曲线或点。如果你拿到的是Curve而不是Face,别急着跳过——可以通过Curve.IsAssociated()或利用边的类似方法回溯到实体边,再回溯到面。我在NX 10和NX 12上实测过,PMI尺寸多数情况下关联的是面或边,形位公差框格往往关联基准面或特征控制框引线指到的边,都得按扩充关联集处理。
对于老版本的NX,也有另一种思路:读取Dimension对象的AssociatedGeometry属性,老API返回的是View和几何对象对,处理起来会更绕。能升版本建议直接上高版本,省时间。
5. SolidWorks里的实现:Annotations + GetAnnotation
SolidWorks API的架构和NX思路一致,但写法差异很大。SolidWorks 中,标注分为模型内注解(Model Annotation)和DimXpert标注。判断面是否有标注,通常有两种做法:
做法A:遍历SolidWorks注解
通过ModelDocExtension.GetAnnotations()拿到所有注解对象Annotation,然后对每个注解调用GetAnnotation获取其关联实体(IGetAttachedEntities)。如果关联到的实体包含目标面(Face2对象),就说明这个面被标注了。
Annotation[] anns = ext.GetAnnotations((int)swAnnotationType_e.swAnnotationAllItems); foreach (Annotation ann in anns) { object[] entities = ann.GetAttachedEntities(); foreach (object ent in entities) { if (ent is Face2 face && face == targetFace) { // 命中 } } }做法B:直接查询所选面的关联注解
SolidWorks有个比较隐蔽但好用的接口:IFace2::GetAnnotation,它可以返回挂在面上的注解。配合GetAnnotationsInSelection(通过IModelDocExtension::GetAnnotationsInSelection)等扩展接口,能直接查询"选中了这些实体"之后显示出来的标注。这在视觉上等价于点选面、系统亮出关联标注,但可以在代码里批量执行。
做法B的效率比做法A高得多,尤其面对大模型几百个面时。做法A要遍历全模型所有注解,做法B直接按面索引查,时间差一个数量级。我的建议是优先用B,拿不到再退回A。
object[] annsOnFace = targetFace.GetAnnotations(); foreach (object annObj in annsOnFace) { if (annObj is Annotation ann) { result.Add(ann); } }另外SolidWorks的DimXpert(对于PMI)需要在安装选项里勾选TolAnalyst和Design Checker,有的老环境默认不装,代码跑一半报没找到接口,先确认一下装没装。
6. 判断结果出来后怎么生成可用报告
程序判断完不能只是返回true/false,要给使用者拿得出手的产出。我每次做这类工具,都会同时输出三类东西:
清单列表:把所有"未标注的面"列出来,带面的ID、面积、类型(平面、圆柱面、B样条面)和它在模型树上的特征名,方便设计师点名称就能锁定目标。
示意图标注:通过高亮显示或截图,把"未标注面"在模型上用醒目的颜色自动标出来。NX里可以用DisplayableObject设置高亮颜色,SolidWorks里用SelectByID2之后设置SetFaceVisibility(类似操作)。这样拿到报告的人不用来回翻列表,一眼就能看到漏标区域。
统计摘要:统计标注覆盖率、按面类型统计漏标率。这些数据在评审会上特别有用,能说服工艺和质检部门按流程补标注,而不是拍脑袋说"应该没问题"。
报告格式我一般用CSV或Excel,加一列"建议操作"(补尺寸/补基准/忽略),生成之后直接发邮件或写回数据管理库。
7. 常见问题与排查技巧实录
问:为什么用API查出来某个面没有任何标注,但模型上肉眼明明能看到一个尺寸指向它?
答:大概率是尺寸没真正关联到这个面。在三维CAD里,你可以画一条尺寸线但它不和几何关联("自由尺寸"或"非关联尺寸"),指向只是视觉上的。这是三维标注文化差异带来的常见误会。排查办法:点选这个尺寸,看软件状态栏或属性框里有没有显示"已关联到面/边",没有就是没关联,按"无标注"处理不仅合理,反而能暴露制图流程漏洞。
问:中心线和轴线怎么办?我对直径标注处理得不好。
答:拿DimXpert举例,它的孔标注通常关联的是孔径特征(尺寸特征)、中心轴或孔面。我的经验是:加一步"特征识别",先把孔、槽、凸台这些特征识别出来,建立特征和面的包含关系,再去匹配标注。比如一个通孔由两个半圆柱面和一个圆柱面构成,标注关联到特征时,就把特征包含的所有面都标记为"有标注"。这个逻辑在NX里用Feature遍历实现,在SolidWorks里用FeatureManager.GetFeature配合GetFaces实现。
问:模型里有阵列特征,面太多,程序运行慢得像蜗牛,有优化办法吗?
答:有,先做过滤。面面积小于某阈值(比如1平方毫米)的跳过,这些小王面在实际标注中极少被单独标注;规律的阵列件可以先测一个代表面,再用阵列关系扩展,不用逐个面全查。实测500个面的零件,优化后耗时可从180秒降到15秒,而且准确率几乎不变。
问:标注对象里有"注释文本"(Text Note)而不是尺寸/符号,它会被MyQuery抓到吗?
答:看你写的过滤器。如果判定条件只在Dimension和GeometricTolerance里找,普通注释不会命中。如果你的需求是"文字注释也算标注"(有些企业就是这么要求的),需要把Note或DraftingNote类型纳入遍历范围。我建议默认放进去,别因为"注释不算尺寸"就排除,很多审图规则的底线是"关键面上必须有沟通信息",注释也能满足这个要求。
问:多实体零件(Multi-body)怎么处理?
答:别忘了遍历所有实体,不要只查当前一个Body的Face。SolidWorks的PartDoc.GetBodies2返回所有Body,NX通过Part.Bodies拿BodyCollection。每个Body分别判断,输出报告里加一列"所属Body名"。这个点我吃过亏,只对主实体查完就下结论,结果漏掉了焊接件里的副体,后来CTO审报告的时候当场抓包。
8. 我的一点总结式心得
这个问题我在很多项目里反复用过,说几个真实经验:
第一,判断"面是否有标注"从来不是技术难点,难的是把"标注"的业务定义搞清楚。是只算尺寸,还是算PMI全部类型?算不算普通注释?算不算跨工程图视图的标注?这些必须在开发第一周就和业务方对齐,否则后面返工成本极高。我见过一个项目,前两周都在纠结"这算标注吗",确认完规则之后,代码一天就写完了。
第二,批量判断最大的价值不是替代人,而是帮你找到"你没时间去查的面"。复杂装配体里几千个面,正常情况下设计师只会手动检查自己关心的面;批量脚本能在几分钟内扫完全部面,把"漏标面"清单给到设计师——这个清单本身就是指导工艺动作的高价值交付物。
第三,尽量做到"判断-定位-高亮-出报告"闭环。光告诉设计师"编号145号面没标注"没有意义,他还要去一个一个找。我通常会直接把未标注面按颜色区分、一键高亮、一键截图、自动生成Excel报告,凑成完整流程,让设计师拿到报告就能直接上手补标注,而不是再问我"145号面是哪一块"。
如果你只是偶尔查一个面,先用软件自带的显示关联标注功能就不亏;如果是重复性工作、模型量大、或者要做质量记录,非常建议把这套API方案搭起来。核心思路换汤不换药,换软件只是换接口而已。