1. 什么是text-to-CAD:从文字描述直接生成可编辑的三维工程模型
“text-to-CAD”这个词最近在工程师、产品设计师和制造从业者的朋友圈里频繁刷屏,但它绝不是又一个AI绘画式的概念玩具。我第一次在客户现场听到这个词,是在帮一家做定制化医疗支架的公司做产线数字化升级时——他们的结构工程师指着屏幕上一段自然语言描述说:“如果这段话能直接变成SolidWorks里可参数修改的STEP文件,我们每天能省下6小时重复建模时间。”那一刻我就意识到,text-to-CAD不是“把文字变图片”,而是要把“人类对物理世界的语义理解”,精准映射为“CAD系统能识别、能约束、能驱动、能制造的几何拓扑与工程语义”。
它解决的核心问题非常具体:传统CAD建模严重依赖人工操作路径(拉伸、旋转、倒角、阵列……),而大量初级结构件、标准件、工装夹具、原型验证件的设计意图,其实早就在需求文档、邮件、会议纪要甚至微信聊天记录里用文字写清楚了。比如“一个直径80mm、高35mm的圆柱体,顶部中心开一个M6内螺纹通孔,底部沿圆周均匀分布4个Φ12沉头孔,沉孔深度6mm,锪平直径20mm”,这种描述在机械设计中再常见不过。过去,工程师得花12分钟手动建模;现在,text-to-CAD的目标是让这个过程压缩到8秒内完成,并且输出的是真正的、带特征树、可回溯编辑、符合ASME Y14.41标准的原生CAD模型,而不是一张渲染图或一个哑巴网格。
这和常见的text-to-3D(如生成GLB/STL)有本质区别。GLB是Web端可视化用的轻量格式,STL是3D打印切片用的三角面片集合,它们都是“结果导向”的静态几何,没有尺寸驱动、没有装配关系、没有公差标注、不能反向修改——你无法在STL上双击一个孔,然后把M6改成M8。而text-to-CAD输出的必须是STEP(AP242)或原生CAD格式(如SldPart、Ipt),它承载的是“设计意图”本身:参数、约束、特征顺序、父子关系、材料定义、甚至初步的GD&T标注框架。这也是为什么搜索热词里反复出现“sw中stl转stp”“cad切地形”“qopengl加载stl”——这些恰恰暴露了当前工业流程中的断层:大家手上有大量文本需求,却只能靠STL/GLB这类中间态格式来“凑合用”,再费力地逆向重建CAD语义。text-to-CAD要做的,就是把这个“凑合”环节彻底砍掉。
适合谁来关注?不是AI研究员,而是每天打开CAD软件、被重复建模折磨的机械工程师;不是CG艺术家,而是需要快速验证结构可行性的硬件产品经理;不是IT运维,而是负责PLM系统集成、想把设计需求自动同步到Windchill或Teamcenter里的数字化负责人。它不取代高级曲面建模或复杂机构仿真,但能吃掉制造业中60%以上的标准件、连接件、外壳、散热器、测试治具等“确定性高、变化规则明确”的建模工作量。我试过用早期原型工具处理客户发来的27份《非标工装技术要求》文档,平均建模耗时从43分钟/件降到92秒/件,且所有模型都通过了下游CNC编程软件的特征识别校验——这才是text-to-CAD落地的真实水位线。
2. text-to-CAD的技术实现路径:为什么不能直接套用text-to-image的模型
很多人第一反应是:“不就是换个模型?把Stable Diffusion的UNet换成别的就行。”我去年也这么想,还专门搭了个LoRA微调环境,拿5000张SolidWorks截图+对应特征树文本去训,结果跑出来的“模型”生成的所谓“STEP文件”,解压后全是乱码,用FreeCAD打开直接报错“Invalid STEP header”。后来和西门子PLM团队的一位老架构师喝咖啡,他一句话点醒我:“Diffusion模型学的是像素分布概率,而CAD引擎认的是B-rep拓扑关系。你让一个猜‘这张图像像不像猫’的模型,去生成‘这个体素集合是否满足欧拉公式V−E+F=2’,就像让厨师凭菜名炒一盘符合米其林分子料理标准的菜——菜名只是输入,但火候、乳化、相变、晶格结构,全在锅里发生。”
所以真正可行的text-to-CAD路径,从来就不是端到端黑箱生成。它是一个分层解耦的工程系统,核心由三块硬骨头组成:
第一层:语义解析引擎(NLP for Engineering)
这不是通用BERT或ChatGLM,而是专为工程语言训练的领域模型。它要能准确识别“M6内螺纹”不是“M6号内裤”,“沉头孔”不是“沉到头的孔”,“沿圆周均匀分布”隐含的是360°/n的旋转对称约束。我们团队用20万条真实机械设计手册、GB/T标准文档、SolidWorks帮助文件微调了一个小型LLM,关键不是参数量,而是对“工程实体-关系-约束”三元组的抽取精度。比如输入“底板厚12mm,四角各有一个Φ8通孔,孔中心距边缘15mm”,它必须输出结构化三元组:[底板, has_thickness, 12mm]、[Φ8通孔, is_located_at, [corner]]、[Φ8通孔, has_distance_to_edge, 15mm]、[Φ8通孔, has_count, 4]。这个环节出错,后面全崩。
第二层:几何求解器(Constraint-Based Geometry Solver)
拿到结构化三元组后,不能直接画图。它要调用类似OpenCASCADE的几何内核,把“Φ8通孔”解析为“半径4mm的圆柱体减去底板实体”,把“距边缘15mm”转化为“圆心在距离底板四边均为15mm的平行线上”,再启动约束求解器(如OCCT的TKGeomBase)迭代计算满足所有距离、同心、共面约束的精确坐标。这里有个致命细节:CAD里“孔中心距边缘15mm”在不同投影方向含义不同——是正交距离?还是沿某斜面的距离?解析引擎必须结合上下文判断,否则生成的孔会偏到零件外面。我们踩过的最大坑,就是没处理好“距边缘”在斜面投影下的歧义,导致第一批生成的法兰盘模型,螺栓孔全在密封面上方悬空。
第三层:格式编译器(CAD Format Compiler)
最后一步最反直觉:它不直接写STEP文件,而是先生成一个中间表示(IR),类似CAD领域的“汇编语言”。这个IR包含完整的特征树指令序列:CREATE_SKETCH(Plane:XY, Entities:[Circle(center=[0,0], r=4)]) → EXTRUDE(Cut=True, Depth=12) → THREAD(M6, Type:Internal, Depth:Full)。再由专用编译器将IR翻译成符合AP242规范的STEP实体数据(ENTITY #123 = ADVANCED_BREP_SHAPE_REPRESENTATION(...))。为什么绕这么大弯?因为STEP是纯声明式格式,没有执行逻辑。直接生成STEP容易违反ISO 10303-21的语法树嵌套规则,导致主流CAD软件拒绝导入。而IR+编译器模式,既能保证语义正确性,又能灵活适配SolidWorks、Inventor、Creo等不同内核的导出接口。
这三层缺一不可。少一层,你就得到一个“看起来像CAD”的假货。我见过太多项目卡在第二层——能解析文字,也能画出草图,但一拉伸就报“几何不连续”,因为求解器没处理好倒角与圆角的拓扑优先级。也见过卡在第三层的:生成的STEP文件能在FreeCAD里打开,但在NX里提示“缺少required shape_representation_relationship”。text-to-CAD不是算法竞赛,它是把NLP、计算几何、CAD内核、标准协议全打通的系统工程,每层都要用工程思维去死磕。
3. 核心实操环节拆解:从一行文字到可编辑STEP文件的完整链路
现在我们把上面说的三层架构,落到一个真实可复现的操作链路上。以最典型的入门案例为例:“生成一个长120mm、宽80mm、高25mm的矩形基座,顶部中心铣一个40×30mm的矩形凹槽,深5mm,四角倒R3圆角”。下面是我用自研工具链(已开源核心模块)跑通的全流程,每一步都附上关键参数、避坑点和验证方法。
3.1 第一步:工程语义清洗与结构化标注
原始文本直接喂给NLP模型会出大问题。比如“顶部中心”这个短语,在机械制图中默认指Z轴正向的最大面中心,但模型可能误判为“任意面的中心”。所以必须加一层规则清洗。我们用Python写的预处理器(eng_cleaner.py)会做三件事:
标准化术语映射:把“铣”统一为
MILLING_OPERATION,“倒R3圆角”转为FILLET(radius=3),“深5mm”转为DEPTH=5.0。这步用的是基于正则+词典的硬规则,不用LLM,因为工程术语容错率极低——把“M6”错成“M8”是灾难,但把“漂亮”错成“美观”在图像生成里无伤大雅。空间关系消歧:识别“顶部”对应的基准面。工具会扫描文本中所有尺寸描述,发现“高25mm”是Z向尺寸,于是锁定Z+面为top face。如果文本写“高25mm,厚度12mm”,就会触发冲突检测,要求人工确认哪个是主高度方向。
约束显式化:把隐含约束补全。例如“四角倒R3圆角”实际意味着:① 圆角半径3mm;② 应用于所有顶点;③ 圆角类型为“面间相切”(tangent);④ 优先级高于其他特征(避免倒角被后续拉伸覆盖)。这步生成的JSON结构如下:
{ "base_part": { "type": "BOX", "dimensions": {"length": 120.0, "width": 80.0, "height": 25.0}, "features": [ { "type": "POCKET", "profile": {"shape": "RECTANGLE", "size": [40.0, 30.0]}, "depth": 5.0, "location": {"relative_to": "top_face_center", "offset": [0, 0, 0]} }, { "type": "FILLET", "radius": 3.0, "edges": "all_vertices", "continuity": "tangent" } ] } }提示:这一步的JSON必须严格遵循我们定义的
EngSchema v1.2,字段名、单位、嵌套层级都不能错。我们曾因把"length"写成"len",导致下游几何求解器直接跳过该尺寸,生成了一个1x1x1mm的迷你基座——客户收到样品时差点报警。
3.2 第二步:B-rep拓扑构建与约束求解
拿到JSON后,进入OpenCASCADE内核的战场。核心是BRepBuilderAPI_MakeSolid和BRepFilletAPI_MakeFillet两个类的组合调用。关键不在代码多,而在调用顺序和参数陷阱:
基座创建:用
BRepPrimAPI_MakeBox(gp_Pnt(0,0,0), 120, 80, 25)生成长方体。注意起点设为(0,0,0),这是为了后续特征定位统一基准。凹槽定位:难点在“顶部中心”。不能简单取
gp_Pnt(60,40,25),因为OCC中box的Z向范围是[0,25],顶部面Z=25,但“中心”需在面内坐标系下计算。正确做法是先用TopExp_Explorer遍历所有面,找到ZMax面(即gp_Pln(gp_Pnt(0,0,25), gp_Dir(0,0,1))),再用BRep_Tool::Surface()获取面参数,调用ElSLib::Parameters()算出面中心在UV空间的坐标,最终映射回世界坐标(60,40,25)。凹槽布尔运算:用
BRepAlgoAPI_Cut做差集。但必须设置BOPAlgo_GlueEnum::GLUE_FULL,否则OCC在布尔运算后可能产生微小缝隙(tolerance issue),导致STEP导出失败。这个参数在官方文档里藏得很深,是我们在调试200多个失败STEP文件后才挖出来的。圆角施加:
BRepFilletAPI_MakeFillet必须在布尔运算之后调用!如果先倒角再挖槽,圆角会被凹槽边界截断。而且要指定AddEdge()时传入TopoDS_Edge对象,不能传TopoDS_Vertex——OCC里圆角是施加在边上,不是顶点上。我们最初传错类型,生成的模型四角是尖锐的,客户说“这不像我们图纸上的R3”。
所有操作完成后,用BRepCheck_Analyzer做拓扑健康检查:
BRepCheck_Analyzer analyzer(shape); if (!analyzer.IsValid()) { // 输出具体错误:e.g. "Self-intersection detected in face #45" // 这时要回溯到上一步,调整圆角半径或凹槽深度 }只有IsValid()返回true,才进入下一步。这步不能跳,否则生成的STEP在NX里打开会提示“invalid topology”。
3.3 第三步:STEP AP242编译与合规性验证
OCC生成的TopoDS_Shape只是内存对象,要变成STEP,必须走标准编译流程。我们不用OCC自带的STEPControl_Writer(它只支持AP203,不支持带PMI的AP242),而是用自研的StepCompiler,核心逻辑是:
实体映射:把OCC的
TopoDS_Solid映射为STEP的manifold_solid_brep,TopoDS_Face映射为advanced_face,并确保每个advanced_face都关联正确的surface(plane, cylinder等)和outer_bound。几何精度控制:STEP文件对浮点精度极其敏感。OCC默认用
Precision::Confusion()(1e-7),但AP242要求所有坐标值小数位≤6位。编译器会强制Round(x, 6),并检查四舍五入后是否破坏拓扑(如两个本应重合的顶点被round成不同值)。我们加了ToleranceValidator模块,对每个顶点计算Distance(vertex1, vertex2),若>1e-6则报错。AP242扩展写入:为支持下游PLM系统读取,必须写入
product_definition_shape和shape_representation。关键是要生成唯一的#123 = PRODUCT_DEFINITION(...),并让所有几何实体通过#456 = SHAPE_REPRESENTATION_RELATIONSHIP(...)关联到它。漏写这个,Siemens Teamcenter导入时会丢失BOM关联。
生成STEP后,用stepcheck命令行工具(来自STEP Tools Inc.)做三级验证:
stepcheck -level 3 -schema ap242 your_model.step # Level 3 = full semantic validation against ISO 10303-242只有输出PASSED (100%)才算成功。我们曾因漏写geometric_representation_context实体,导致Level 3验证卡在Entity #789 missing required attribute,debug了17小时。
最后,用SolidWorks 2023 SP5打开验证:
- ✅ 特征树显示“拉伸1”、“切除-拉伸1”、“圆角1”三个可编辑特征
- ✅ 双击“圆角1”,参数栏显示“半径:3.00 mm”,可实时修改
- ✅ 导出为STP再导入Inventor,所有尺寸、倒角、位置关系100%一致
- ❌ 如果用MeshLab打开,看到的是三角面片——说明编译失败,你得到的是STL伪装的STEP
这整套链路,从文本输入到验证通过,实测平均耗时4.2秒(i7-11800H + 32GB RAM)。比老师傅手动建模快6倍,且零人为误差。关键是,它生成的不是“能看的模型”,而是“能改、能算、能造”的真CAD。
4. 工具链选型与本地化部署:避开云服务陷阱,打造离线可用的生产环境
市面上突然冒出一堆“text-to-CAD SaaS平台”,首页写着“秒级生成STEP”,点进去却要求上传图纸到云端、绑定企业邮箱、开通API额度。我劝所有制造业同仁立刻关掉——你的产品结构、公差要求、材料规格,全是核心商业机密。去年有家汽车零部件厂试用某国外工具,生成的转向节模型里,连内部油道的R0.8过渡圆角都被上传到对方服务器,审计时被罚了七位数。text-to-CAD的生产环境,必须满足三个铁律:离线运行、数据不出域、格式全可控。下面是我团队实测半年后沉淀的工具链方案,全部开源或商用许可清晰。
4.1 NLP语义解析层:轻量化领域模型替代大语言模型
别碰7B以上的大模型。我们对比过Llama3-8B、Qwen2-7B和自研的EngBERT-Tiny(12M参数),在机械术语NER任务上,EngBERT-Tiny的F1值92.3%,比Qwen2高1.7%,推理速度却快23倍(RTX4090上单次解析<80ms)。原因很简单:大模型在学“如何写诗”,小模型在学“如何读图纸”。EngBERT-Tiny的训练数据全部来自GB/T国家标准库、《机械设计手册》PDF OCR文本、SolidWorks官方帮助文档HTML,连词向量都用word2vec在工程语料上重训过。
部署方式:用ONNX Runtime量化后,封装成Python API:
from eng_nlp import EngParser parser = EngParser(model_path="engbert_tiny.onnx") result = parser.parse("Φ20H7通孔,表面粗糙度Ra1.6") # 返回: {'diameter': 20.0, 'tolerance': 'H7', 'type': 'through_hole', 'roughness': 1.6}注意:必须禁用所有网络请求。我们删掉了所有
requests、urllib相关代码,连模型下载逻辑都注释掉——安装包里直接打包.onnx文件。某次客户现场断网,用大模型的竞品直接瘫痪,我们的工具照常运行。
4.2 几何内核层:OpenCASCADE是唯一务实选择
有人问为什么不用ACIS或Parasolid?答案很现实:授权费。ACIS单机授权起步2.5万美元/年,Parasolid更贵。而OpenCASCADE是LGPLv2.1开源协议,商用免费,且对STEP AP242支持最成熟(2023版已原生支持geometric_tolerance实体)。我们用的是OCC 7.7.0,关键补丁包括:
src/BRepOffset/BRepOffset_MakeOffset.cxx:修复了OFFSET_MODE_2D在薄壁件上的自交bugsrc/STEPControl/STEPControl_Writer.cxx:增加AP242product_definition_with_associated_documents写入
编译OCC时,必须开启BUILD_MODULE_STEP和BUILD_MODULE_VISUALIZATION,但关闭BUILD_MODULE_DRAW(它依赖X11,在Linux服务器上会报错)。我们做了Docker镜像(occt-builder:7.7.0-cuda12.2),docker build一次,全公司开发机docker pull即可,版本零差异。
4.3 CAD格式层:放弃通用转换器,直写STEP实体
别用FreeCAD或pythonocc的exportStep()——它们调用的是OCC的旧版STEP写入器,只支持AP203。必须手写AP242实体。我们维护了一个step_writer.py模块,核心是实体模板:
def write_manifold_solid_brep(entity_id, solid_id): return f"""#{entity_id} = MANIFOLD_SOLID_BREP('{entity_id}',#{solid_id});""" def write_product_definition_shape(entity_id, product_id): return f"""#{entity_id} = PRODUCT_DEFINITION_SHAPE('', '', #{product_id});"""所有实体按AP242 Part242 Annex A的顺序生成:先product,再product_definition,再product_definition_shape,最后才是manifold_solid_brep。顺序错一个,stepcheck就报错。这个模块我们已封装成PyPI包py-step-ap242,pip install py-step-ap242即可用。
4.4 部署架构:单机离线工作站方案
最终交付给客户的,是一台戴尔Precision 3660(i7-12700K + 64GB RAM + RTX4070),预装Ubuntu 22.04 LTS。整个工具链打包成text2cad-cli命令行工具:
# 安装(离线) sudo dpkg -i text2cad-cli_1.2.0_amd64.deb # 使用(完全离线) echo "直径50mm,高30mm圆柱,顶部中心M8螺纹孔" | text2cad-cli --format step --output base.stp所有依赖(OCC、ONNX Runtime、STEP writer)都打包进deb包,ldd text2cad-cli显示无外部.so依赖。客户IT部门审计时,只看到一个二进制文件和一份LICENSE,没有任何可疑的域名连接。这才是制造业敢用的text-to-CAD。
我们拒绝所有“云协同”“在线渲染”“AI模型持续学习”等华而不实的功能。工程师要的,就是一个命令敲下去,3秒后硬盘里多一个能直接发给CNC车间的STEP文件。多一个功能,就多一分风险;少一个依赖,就多一分可靠。
5. 真实场景问题排查与避坑指南:那些文档里不会写的血泪教训
理论再完美,一到客户现场就露馅。过去一年,我带着这套工具跑了12家制造企业,从医疗器械到航天电子,踩过的坑比生成的模型还多。下面这些,全是文档里绝对找不到、但能让你少熬30个通宵的实战经验。我按问题严重程度排序,最致命的放前面。
5.1 问题:生成的STEP文件在SolidWorks里能打开,但特征树为空,显示为“输入的实体”
现象:模型看起来完全正确,尺寸、倒角、孔位都对,但右键“编辑特征”是灰色的,属性里显示“Type: Imported Body”。客户急得拍桌子:“这跟STL有什么区别?!”
根因分析:不是模型错了,是STEP文件里缺失了shape_representation_relationship实体。OCC的STEPControl_Writer默认不写这个,它认为“只要几何对就行”。但SolidWorks的导入器需要这个实体来建立“产品定义→几何表示”的映射关系,否则就当哑巴实体处理。
解决方案:在step_writer.py里强制插入:
# 在写完manifold_solid_brep后,立即写: sr_id = next_id() srr_id = next_id() output += f"#{sr_id} = SHAPE_REPRESENTATION('',(#123),#124);\n" output += f"#{srr_id} = SHAPE_REPRESENTATION_RELATIONSHIP('','',#{product_def_id},#{sr_id});\n"其中#123是manifold_solid_brep的ID,#124是geometric_representation_context的ID(必须提前写好)。这个补丁让我们通过SolidWorks 2022+所有SP版本的特征树识别测试。
实操心得:每次生成STEP后,用VS Code打开文本,搜索
SHAPE_REPRESENTATION_RELATIONSHIP,必须存在且ID引用正确。这是上线前必做的“三查”之一(另两个是查manifold_solid_brep、查product_definition_shape)。
5.2 问题:同一段文字,有时生成正确模型,有时布尔运算失败报“Self-intersection”
现象:输入“长100mm宽60mm高20mm基座,顶部铣40×25mm凹槽深4mm”,上午生成成功,下午就报错。重启工具也无效。
根因分析:OCC的BRepAlgoAPI_Cut对输入实体的拓扑状态极度敏感。如果基座实体在创建时,某个面的法向量是反的(比如Z-面被误认为Z+面),布尔运算就会在内部计算中产生自交。而OCC的面法向量方向,取决于创建时点的输入顺序(右手定则),而BRepPrimAPI_MakeBox的点序在不同OCC版本、不同编译器优化级别下会有微小差异。
解决方案:在创建基座后,强制统一所有面的法向:
TopExp_Explorer face_exp(shape, TopAbs_FACE); for (; face_exp.More(); face_exp.Next()) { TopoDS_Face face = TopoDS::Face(face_exp.Current()); // 获取面的表面 Handle(Geom_Surface) surf = BRep_Tool::Surface(face); // 强制法向朝Z+(假设Z是高度方向) if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane)) { Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(surf); gp_Dir norm = plane->Position().Direction(); if (norm.Z() < 0) { // 法向朝下,翻转 BRepTools::Reverse(face); } } }这个BRepTools::Reverse()调用,是我们在OCC源码里挖了三天才找到的隐藏API。加上后,布尔运算失败率从37%降到0.2%。
5.3 问题:客户要求“表面粗糙度Ra3.2”,但生成的STEP里没有PMI信息
现象:模型几何完美,但下游CNC程序无法读取粗糙度要求,工艺员还得手动在图纸上标注。
根因分析:AP242标准里,表面粗糙度属于geometric_tolerance,但OCC 7.7.0的STEP写入器根本不支持。它只写几何,不写制造语义。
解决方案:手写AP242的geometric_tolerance实体。我们扩展了step_writer.py,新增write_surface_roughness()函数:
def write_surface_roughness(entity_id, face_id, roughness_value): return f"""#{entity_id} = GEOMETRIC_TOLERANCE('surface_roughness','{roughness_value} Ra',#{face_id}); #{entity_id+1} = SURFACE_PROFILE_TOLERANCE('','',#{entity_id},#{face_id});"""关键是要把roughness_value(如3.2)和具体的face_id(即凹槽底面的ID)关联起来。这需要在几何构建阶段,就用TopExp_Explorer遍历所有面,用BRepAdaptor_Surface判断哪个面是“凹槽底面”(平面、Z坐标最小、面积=40*25),然后记下它的ID。这样生成的STEP,用Siemens NX打开,PMI面板里就能看到Ra3.2标注。
注意事项:粗糙度值必须带单位字符串(如
'3.2 Ra'),不能只写数字。AP242标准要求geometric_tolerance的name属性是字符串,写数字会导致stepcheckLevel 3失败。
5.4 问题:中文字符导致STEP文件损坏,用记事本打开全是乱码
现象:输入含中文的描述,如“带铭牌安装孔”,生成的STEP文件在SolidWorks里提示“文件损坏”。
根因分析:STEP文件是ASCII文本格式,但AP242标准允许UTF-8编码的字符串。OCC的STEP写入器默认用std::string,遇到中文会截断字节流,导致后续实体ID错乱。
解决方案:所有字符串字段(如name、description)必须UTF-8编码,并在STEP文件头部声明编码:
# STEP文件开头必须加: header = "ISO-10303-21;\n" \ "HEADER;\n" \ "FILE_DESCRIPTION(('AP242'), '2');\n" \ "FILE_NAME('model.stp', '2024-06-15T10:30:00', ('Author'), ('Company'), 'OpenCASCADE STEP Processor', 'OpenCASCADE', '');\n" \ "FILE_SCHEMA(('CONFIG_CONTROL_DESIGN'));\n" \ "ENDSEC;\n" # 注意:FILE_NAME里的字符串必须是UTF-8 bytes,不是str在Python中,用bytes(header, 'utf-8')写入,而非header.encode('utf-8')——后者在某些环境下会加BOM头,导致STEP解析器崩溃。
5.5 常见问题速查表
| 问题现象 | 可能原因 | 快速验证方法 | 解决方案 |
|---|---|---|---|
| STEP在FreeCAD能开,在NX里报“Invalid entity #123” | STEP实体ID引用错误或缺失 | 用VS Code打开STEP,搜索#123=,看该实体是否存在且格式正确 | 检查step_writer.py中实体生成顺序,确保所有#xxx都被正确定义 |
| 模型尺寸正确,但倒角位置偏移2mm | “距边缘”距离解析为正交距离,实际应为沿斜面距离 | 在OCC中用BRepExtrema_DistShapeShape测量倒角圆心到边缘的实际距离 | 在语义解析层增加“距离类型”判断逻辑,结合上下文识别斜面 |
| 生成的模型在CNC软件里无法识别螺纹特征 | STEP中未写入thread_feature实体 | 用stepcheck -level 2检查,看是否有thread_feature实体 | 手写AP242thread_feature,关联到对应圆柱面 |
| 同一输入,不同机器生成结果不一致 | OCC随机种子或浮点精度差异 | 在两台机器上运行occt_version,对比OCC版本和编译选项 | 统一使用我们提供的Docker镜像,禁用所有随机化选项 |
最后分享一个血泪换来的技巧:永远用“最小可行输入”做回归测试。我们维护一个test_cases/目录,里面全是超短文本,如"Φ10孔"、"R5圆角"、"120x80x25基座"。每次代码变更,先跑这20个case,全过才提交。因为text-to-CAD的脆弱点,永远在最简单的case里——复杂描述有冗余信息兜底,简单描述一错就全崩。这比写1000行单元测试管用得多。
6. 从text-to-CAD到设计自动化:它真正改变的是工程师的工作重心
上周在苏州一家精密模具厂,我看着老师傅用我们的工具,把一份《滑块定位销技术要求》(全文83字)生成STEP后,直接拖进PowerMill做五轴加工编程。他没碰一次鼠标建模,却在22分钟内完成了从需求到刀路的全过程。他跟我说:“以前我花70%时间建模,30%时间思考怎么加工;现在建模3分钟,我有67分钟专心琢磨刀具路径和冷却液角度——这才是工程师该干的活。”
这让我想起十年前刚入行时,CAD软件商总宣传“缩短建模时间”,结果大家只是更快地重复画线、拉伸、倒角。text-to-CAD的价值,从来不在“快”,而在于把工程师从几何构造的体力劳动中解放出来,逼他们回归设计的本质:定义约束、权衡性能、预测失效、优化制造。当“画一个M6螺纹孔”变成一句命令,工程师终于能抬头看全局——这个孔的轴向载荷是多少?配合的轴类零件热膨胀系数是否匹配?在模具开合过程中会不会干涉?这些才是真正决定产品成败的问题。
所以别再纠结“text-to-CAD能不能替代高级曲面建模”。它替代不了,也不该替代。它替代的是那些本不该由人来做的、确定性高、规则明确、重复性强的建模劳动。就像数控机床没让钳工消失,而是让钳工从划线锉削转向夹具设计和工艺优化。text-to-CAD正在做的,是把CAD工程师从“几何绘图员”升级为“设计规则架构师”。
我现在的日常工作,已经从教客户“怎么用工具”,变成和他们一起梳理《企业标准件语义词典》:把“国标GB/T 5783 M6×20六角头螺栓”映射为结构化JSON,把“模具导柱H7/g6配合”转化为公差约束表达式。这个过程,比写代码难十倍,但价值高百倍——因为当语义词典建成,text-to-CAD就不再是工具,而是企业设计知识的自动执行引擎。
最后说个真实的后续:那家医疗支架公司,用我们工具跑通200个标准件后,把节省的时间