资讯详情

text-to-cad 实战:从自然语言到三维模型的程序化建模方案

📅 2026/10/8 17:00:19 | 华诺云谱 👁 阅读
text-to-cad 实战:从自然语言到三维模型的程序化建模方案
1. 从一段文字到三维模型text-to-cad 到底在解决什么问题第一次听到 “text-to-cad” 这个词很多做机械设计、建筑建模或者工业制造的朋友可能会觉得有点玄乎——输入一段文字直接吐出 CAD 模型这玩意儿靠谱吗我一开始也是这个反应。但实际折腾了一段时间之后我发现它背后的逻辑并不复杂而且已经在一些特定场景里跑得挺通了。简单来说text-to-cad 是一类将自然语言描述转化为三维 CAD 模型文件的技术方案统称它的输出格式通常包括 STEP、GLB、STL 这几种主流三维数据格式。你给它一句“一个长宽高分别为 100mm、50mm、30mm 的长方体中心开一个直径 20mm 的通孔”它就能生成对应的三维几何体并且导出成你可以直接拿去用 CAD 软件打开、或者丢进 3D 打印机切片软件里的文件。这件事的意义在哪儿传统 CAD 建模的流程是打开 SolidWorks、Fusion 360、中望 CAD 或者类似工具画草图、拉伸、打孔、倒角一步步手动操作。一个简单的零件可能几分钟搞定但如果是批量化的、参数化的、需要反复调整的模型手动操作的时间成本就非常可观了。而 text-to-cad 的思路是把“描述需求”和“生成几何”之间的鸿沟用程序填平——你用文字或者结构化参数描述你要什么程序帮你生成对应的几何体直接输出 STEP 或 STL。这对于需要快速验证设计想法、批量生成变体模型、或者非专业建模人员想要快速得到一个可用的三维文件来说价值非常直接。这篇文章适合谁看如果你是做产品设计、机械加工、3D 打印、建筑建模的从业者或者你是一个会写点 Python 但不太会 CAD 建模的程序员再或者你只是对“文字生成三维模型”这件事好奇想自己动手跑一遍看看效果那接下来的内容应该都能给你一些可以直接抄作业的东西。我会从整体设计思路、核心技术细节、完整实操流程、常见问题排查这几个维度把 text-to-cad 这件事拆开讲清楚。涉及到的工具选型、参数计算、代码实现我都会给出具体的方案和解释尽量让你看完就能自己跑起来。2. 整体设计思路与方案选型拆解2.1 为什么选择程序化建模而不是直接训练一个端到端模型提到 text-to-cad很多人第一反应是“是不是要用深度学习训练一个从文本到三维模型的网络”。这个方向确实有研究者在做比如基于扩散模型或者 Transformer 架构直接生成三维表示。但如果你是一个从业者想要在实际工作中用起来我建议你先别碰端到端训练这条路。原因很实际训练数据的获取和标注成本极高三维模型的数据集远没有图像和文本那么丰富而且生成结果的几何精度和可编辑性往往达不到工程要求。你生成一个“看起来像”的模型容易但你要生成一个尺寸精确、拓扑合理、能直接导入 CAD 软件继续编辑的 STEP 文件端到端模型目前还很难稳定做到。所以我采用的方案是程序化建模加自然语言解析的组合路线。具体来说分三步走第一步用自然语言处理或者规则解析的方式从输入文本中提取出建模所需的结构化参数比如几何类型、尺寸、位置、布尔运算关系等第二步用程序化的方式调用几何建模内核根据这些参数生成三维几何体第三步将生成的几何体导出为 STEP、GLB 或 STL 格式。这个方案的核心优势在于几何精度完全可控因为底层用的是成熟的几何内核输出格式标准STEP 是工业界通用的交换格式STL 是 3D 打印的标配GLB 适合做可视化展示整个流程可调试、可复现出了问题你能定位到具体是哪一步的参数解析错了还是几何运算失败了。2.2 几何内核的选择为什么我最终用了 CadQuery 加 OpenCASCADE程序化建模的核心是几何内核。市面上能用的方案有不少我试过几种最后稳定在CadQuery这个 Python 库上它底层调用的是OpenCASCADE这个工业级的几何建模内核。OpenCASCADE 是很多商业 CAD 软件的底层依赖稳定性和精度都经过了几十年的验证。CadQuery 在它上面封装了一套比较友好的 Python API你可以用链式调用的方式描述建模操作代码写起来很直观。举个例子你要生成一个带孔的长方体用 CadQuery 写出来大概是这样import cadquery as cq result ( cq.Workplane(XY) .box(100, 50, 30) .faces(Z) .workplane() .hole(20) ) cq.exporters.export(result, output.step)这段代码的意思是在 XY 平面上创建一个 100x50x30 的长方体然后选择朝向 Z 轴正方向的那个面在这个面上创建一个直径 20 的孔。最后导出为 STEP 文件。整个过程非常清晰而且你可以随时修改参数重新生成。为什么不用 FreeCAD 的 Python 脚本FreeCAD 确实也能做程序化建模但它的 API 比较冗长而且文档质量参差不齐踩坑的概率更高。为什么不用 Blender 的 Python APIBlender 更偏向于网格建模和渲染它的布尔运算和精确尺寸控制不如 OpenCASCADE 来得可靠导出 STEP 格式也需要额外的插件支持。所以综合来看CadQuery 加 OpenCASCADE 是目前 Python 生态里做程序化 CAD 建模最稳的组合。2.3 输出格式的选择逻辑STEP、GLB、STL 各自适合什么场景text-to-cad 的输出格式选择不是随便定的每种格式背后对应的是不同的使用场景。我把它们的关键区别整理成了一张表方便你快速判断该用哪种格式全称数据表示方式典型用途是否支持颜色/材质是否可编辑STEPStandard for the Exchange of Product DataB-Rep边界表示工业设计、CAD 软件交换、CNC 加工有限支持是参数化可编辑STLStereolithography三角网格3D 打印、快速原型不支持否仅网格GLBGL Transmission Format Binary三角网格 材质网页展示、AR/VR、游戏引擎支持否仅网格如果你生成的模型要拿去给机械工程师继续用 SolidWorks 或者中望 CAD 编辑那必须导出 STEP。如果你是要丢进 3D 打印机切片STL 就够了。如果你是要在网页上展示或者做交互式预览GLB 是最合适的。CadQuery 对这三种格式都支持导出所以你在代码里可以根据需求灵活切换。注意STL 和 GLB 都是网格格式它们会把几何体离散成大量三角形。这意味着一旦导出成 STL你就很难再精确地修改尺寸了。所以如果你后续还需要调整模型建议保留 STEP 文件作为母版。3. 核心细节解析与实操要点3.1 自然语言解析从一句话到结构化参数的映射逻辑text-to-cad 的第一个难点在于怎么把一段自然语言变成程序能理解的参数。比如用户输入“一个直径 50mm、高 80mm 的圆柱体顶部倒角 2mm”你需要提取出几何类型是圆柱体直径 50高度 80倒角位置在顶部倒角尺寸 2mm。这个过程我采用的是规则匹配加关键词提取的方式而不是直接上大语言模型。原因很简单对于尺寸、位置这类精确参数规则匹配的可靠性远高于模型生成而且速度更快、成本更低。具体实现上我会先定义一个参数模板库每种几何体对应一组关键词和参数槽位。比如圆柱体的模板大概是这样的CYLINDER_TEMPLATE { keywords: [圆柱, 圆柱体, cylinder], params: { diameter: {patterns: [r直径\s*(\d\.?\d*)\s*mm, r直径\s*(\d\.?\d*)], type: float}, height: {patterns: [r高\s*(\d\.?\d*)\s*mm, r高度\s*(\d\.?\d*)], type: float}, fillet: {patterns: [r倒角\s*(\d\.?\d*)\s*mm], type: float, optional: True} } }然后用正则表达式去匹配输入文本提取出对应的数值。如果某个必填参数没有匹配到就返回错误提示让用户补充。这种方式的优点是可控性强你能清楚地知道每个参数是从哪里来的出了问题也容易排查。当然它的局限性是只能处理预定义好的几何类型和表达方式对于非常复杂的自由曲面描述就无能为力了。但对于大多数工程场景下的标准几何体这套方案已经够用了。3.2 几何建模的关键参数计算与单位处理参数提取出来之后下一步是把它转换成几何建模的实际操作。这里有一个很容易被忽略的坑单位统一。CAD 建模里常用的单位有毫米、厘米、米、英寸而不同软件和格式的默认单位可能不一样。OpenCASCADE 内部使用的是毫米作为基本单位所以你在建模之前一定要把所有参数统一转换成毫米。我见过有人输入“直径 5cm”程序直接当成 5mm 处理结果生成的模型小了十倍。除了单位还有一个关键点是坐标系和定位。当你生成多个几何体并需要进行布尔运算时每个几何体的位置和朝向必须明确。比如“在长方体顶部中心打一个孔”你需要先确定长方体的顶面在哪个 Z 高度然后计算出孔的中心坐标。这些计算在 CadQuery 里可以通过选择器selector来自动完成比如.faces(Z)就是选择 Z 方向最高的那个面。但如果你要做的操作比较复杂建议还是手动计算坐标这样更可控。# 手动计算孔位坐标的示例 box_length 100 box_width 50 box_height 30 hole_diameter 20 # 孔的中心在长方体顶面中心 hole_x box_length / 2 hole_y box_width / 2 hole_z box_height result ( cq.Workplane(XY) .box(box_length, box_width, box_height) .faces(Z) .workplane() .center(0, 0) .hole(hole_diameter) )3.3 布尔运算的稳定性技巧与常见陷阱布尔运算是程序化建模里最容易出问题的环节。两个几何体做并集、差集、交集的时候如果面与面之间刚好重合或者间隙极小内核可能会报错或者生成非预期的结果。我在实际使用中总结了几个技巧第一尽量避免让两个几何体的面完全重合可以稍微偏移一点点比如 0.01mm这样内核更容易判断内外关系第二做差集运算之前先确认被减的几何体完全包含在减去的几何体内部不要出现部分相交的情况第三如果布尔运算失败可以尝试用.clean()方法清理几何体的冗余面或者调整几何体的生成顺序。实操心得CadQuery 的布尔运算在大多数情况下是稳定的但如果你生成的模型特别复杂比如几十个特征叠加建议分步进行布尔运算每步之后检查一下几何体是否有效。可以用.isValid()方法来验证。4. 完整实操流程从零搭建一个 text-to-cad 管道4.1 环境准备与依赖安装先把环境搭起来。我假设你用的是 Python 3.9 以上的版本操作系统不限Windows、macOS、Linux 都可以。CadQuery 的安装方式有两种一种是用 conda一种是用 pip。我推荐用 conda因为 CadQuery 依赖的 OpenCASCADE 库在 conda 里有预编译好的包安装起来省事很多。# 用 conda 创建环境并安装 CadQuery conda create -n text-to-cad python3.10 conda activate text-to-cad conda install -c conda-forge cadquery # 验证安装是否成功 python -c import cadquery; print(cadquery.__version__)如果你不想用 conda也可以用 pip 安装但可能需要手动解决 OpenCASCADE 的依赖问题在 Windows 上尤其容易踩坑。安装完成之后你还需要一个用来做自然语言解析的库我用的主要是re标准库不需要额外安装。如果你想要更灵活的自然语言处理能力可以加上spacy或者transformers但这会增加安装体积和运行时间初期建议先用正则表达式跑通流程。4.2 文本解析模块的实现解析模块的核心任务是输入一段文本输出一个结构化的建模指令字典。我把它设计成一个parse_text_to_spec函数接收文本字符串返回一个包含几何类型和参数的字典。import re def parse_text_to_spec(text): text text.strip().lower() # 检测几何类型 if any(kw in text for kw in [圆柱, cylinder]): geom_type cylinder elif any(kw in text for kw in [长方体, 方块, box]): geom_type box elif any(kw in text for kw in [球, sphere]): geom_type sphere else: raise ValueError(无法识别的几何类型请检查输入文本) # 提取数值参数 spec {type: geom_type, params: {}} # 提取直径 diameter_match re.search(r直径\s*(\d\.?\d*)\s*(mm|cm|m)?, text) if diameter_match: value float(diameter_match.group(1)) unit diameter_match.group(2) or mm spec[params][diameter] convert_to_mm(value, unit) # 提取高度 height_match re.search(r高\s*(\d\.?\d*)\s*(mm|cm|m)?, text) if height_match: value float(height_match.group(1)) unit height_match.group(2) or mm spec[params][height] convert_to_mm(value, unit) # 提取长宽 length_match re.search(r长\s*(\d\.?\d*)\s*(mm|cm|m)?, text) width_match re.search(r宽\s*(\d\.?\d*)\s*(mm|cm|m)?, text) if length_match: spec[params][length] convert_to_mm(float(length_match.group(1)), length_match.group(2) or mm) if width_match: spec[params][width] convert_to_mm(float(width_match.group(1)), width_match.group(2) or mm) return spec def convert_to_mm(value, unit): unit_map {mm: 1, cm: 10, m: 1000} return value * unit_map.get(unit, 1)这个解析函数能处理基本的几何类型和尺寸参数。你可以根据实际需求扩展它比如增加倒角、圆角、孔位等特征的识别。4.3 几何生成与导出模块的实现拿到结构化的 spec 之后下一步就是调用 CadQuery 生成几何体并导出。我写了一个generate_model函数根据 spec 中的类型分发到不同的建模逻辑。import cadquery as cq def generate_model(spec, output_formatstep, output_pathoutput): geom_type spec[type] params spec[params] if geom_type box: length params.get(length, 100) width params.get(width, 50) height params.get(height, 30) result cq.Workplane(XY).box(length, width, height) elif geom_type cylinder: diameter params.get(diameter, 50) height params.get(height, 80) result cq.Workplane(XY).circle(diameter / 2).extrude(height) elif geom_type sphere: diameter params.get(diameter, 50) result cq.Workplane(XY).sphere(diameter / 2) else: raise ValueError(f不支持的几何类型: {geom_type}) # 导出文件 if output_format step: cq.exporters.export(result, f{output_path}.step) elif output_format stl: cq.exporters.export(result, f{output_path}.stl) elif output_format glb: cq.exporters.export(result, f{output_path}.glb) return result把这两个模块串起来一个最简版的 text-to-cad 管道就完成了text 一个长100mm、宽50mm、高30mm的长方体 spec parse_text_to_spec(text) model generate_model(spec, output_formatstep, output_pathmy_model) print(模型已生成并导出)4.4 参数计算实例一个带孔法兰盘的完整生成过程为了让你更清楚地看到整个流程我拿一个实际例子走一遍。假设输入文本是“一个外径 120mm、内径 80mm、厚度 10mm 的圆环在圆环上均匀分布 6 个直径 8mm 的通孔孔的中心圆直径为 100mm。”这个描述比之前的例子复杂一些涉及到圆环体和环形阵列孔。解析模块需要提取的参数包括外径 120、内径 80、厚度 10、孔数 6、孔径 8、孔中心圆直径 100。然后建模逻辑是这样的import cadquery as cq import math outer_d 120 inner_d 80 thickness 10 hole_count 6 hole_d 8 pcd 100 # 孔中心圆直径 # 创建圆环体 result ( cq.Workplane(XY) .circle(outer_d / 2) .circle(inner_d / 2) .extrude(thickness) ) # 创建环形阵列孔 for i in range(hole_count): angle 2 * math.pi * i / hole_count x (pcd / 2) * math.cos(angle) y (pcd / 2) * math.sin(angle) result ( result.faces(Z) .workplane() .center(x, y) .hole(hole_d) ) cq.exporters.export(result, flange.step)这段代码里圆环体的创建用了两个圆然后拉伸环形阵列孔用了一个循环来计算每个孔的中心坐标。math.cos和math.sin用来把角度转换成 XY 坐标。最终导出的 STEP 文件可以直接在 SolidWorks 或者中望 CAD 里打开尺寸和位置都是精确的。注意事项在循环里做布尔运算的时候每次都要重新选择面.faces(Z)因为前一次布尔运算之后几何体的面可能会变化。如果你发现孔的位置不对大概率是因为没有重新选择工作面。5. 常见问题与排查技巧实录5.1 解析失败文本描述模糊或参数缺失怎么办实际使用中用户输入的文本往往不会像示例那么规范。比如有人说“给我搞个圆柱大概这么高”没有具体数值。这种情况下解析模块应该给出明确的错误提示而不是随便猜一个值。我的做法是维护一个必填参数列表如果某个必填参数没有提取到就返回一个包含缺失参数名称的错误信息让用户补充。另一种情况是文本里有多个几何体比如“一个长方体上面放一个圆柱”。这种需要做组合建模的场景解析逻辑会更复杂需要识别出“上面放”这种空间关系。我目前的方案是先把每个几何体单独解析出来然后根据关系词如“上面”“旁边”“内部”来确定它们的相对位置最后做布尔并集。这个逻辑还在不断完善中但对于常见的堆叠和嵌入关系已经能处理了。5.2 几何生成报错布尔运算失败与无效几何体布尔运算失败是最高频的问题。常见的报错信息包括“BRep_API: command not done”或者“Boolean operation failed”。遇到这种情况我一般按以下顺序排查排查步骤检查内容解决方法1几何体是否有效调用.isValid()检查无效则重新生成2面是否重合将其中一个几何体偏移 0.01-0.1mm3布尔运算顺序尝试交换被减体和减体的顺序4几何体是否为空检查尺寸参数是否为零或负数5内核版本兼容性升级 CadQuery 和 OpenCASCADE 到最新版还有一个容易被忽略的点是当你从 STL 文件导入几何体再做布尔运算时由于 STL 是网格格式导入后变成的是网格面而不是精确的 B-Rep 面布尔运算的稳定性会大幅下降。所以如果你的流程里涉及 STL 导入建议先用工具把 STL 转换成 STEP再做后续操作。5.3 导出文件异常STEP 打开后显示空白或 STL 文件过大STEP 文件导出后在 CAD 软件里打开显示空白通常是因为几何体的坐标系不对模型可能被生成在了很远的地方。你可以在导出之前检查一下几何体的包围盒bounding box确认它的坐标范围是合理的。CadQuery 里可以用.val().BoundingBox()来获取包围盒信息。STL 文件过大的问题则是因为网格精度设置得太高。CadQuery 导出 STL 时可以指定公差参数cq.exporters.export(result, output.stl, tolerance0.1, angularTolerance0.1)tolerance控制线性公差angularTolerance控制角度公差。默认值可能比较小导致生成的三角形数量很多文件体积大。对于一般的 3D 打印用途把这两个值设在 0.05 到 0.2 之间就足够了。如果你需要更精细的表面可以适当减小但文件会变大。5.4 性能优化批量生成大量模型时的提速技巧如果你需要批量生成几百上千个模型性能就成了一个需要考虑的问题。我实测下来单个简单模型的生成时间在 0.5 到 2 秒之间主要耗时在几何内核的初始化和布尔运算上。几个提速技巧第一尽量复用同一个 CadQuery Workplane 对象减少重复初始化第二如果多个模型之间只有尺寸参数不同可以把建模逻辑封装成一个函数用多进程并行生成第三导出格式优先选 STEP因为 STL 的网格离散化比较耗时。from multiprocessing import Pool def generate_one(params): spec {type: box, params: params} return generate_model(spec, output_formatstep, output_pathfmodel_{params[id]}) if __name__ __main__: param_list [{id: i, length: 100i, width: 50, height: 30} for i in range(100)] with Pool(4) as p: p.map(generate_one, param_list)这段代码用多进程池并行生成 100 个不同尺寸的长方体模型实测比串行快了大约 3 倍。6. 工具链扩展与进阶方向6.1 结合大语言模型做更灵活的文本理解前面我用的正则表达式方案对于标准化的描述已经够用了但如果你想要处理更自由、更口语化的输入可以考虑引入大语言模型来做意图识别和参数抽取。具体做法是把用户输入和一组预定义的建模指令模板一起发给模型让模型输出结构化的 JSON 参数。比如你可以这样设计提示词“你是一个 CAD 建模助手请从以下文本中提取几何类型和尺寸参数以 JSON 格式输出。”然后把模型返回的 JSON 直接喂给几何生成模块。这个方案的好处是能处理更复杂的描述比如“一个像椅子腿一样的圆柱稍微有点锥度”。但缺点是模型可能会产生幻觉生成不存在的参数或者错误的数值。所以我的建议是用大语言模型做初步解析然后用规则做校验和修正。两者结合既灵活又可靠。6.2 与现有 CAD 工作流的集成方式text-to-cad 生成的模型最终要融入到实际的设计流程中。常见的集成方式有几种第一种是直接导出 STEP 文件然后手动导入到 SolidWorks、中望 CAD 或者 Fusion 360 里继续编辑第二种是通过 API 把生成逻辑嵌入到现有的设计自动化脚本里比如用 Python 脚本批量生成变体模型第三种是把 text-to-cad 做成一个 Web 服务前端接收文本输入后端生成模型并返回下载链接。第三种方式适合团队协作场景非技术同事也能用。如果你用的是中望 CAD 或者 AutoCAD它们都支持脚本化操作你可以把生成的 STEP 文件用脚本批量导入并做后续处理。Python 生态里有pyautocad这样的库可以操作 AutoCAD中望 CAD 也有类似的 COM 接口。不过这些接口的稳定性参差不齐建议先小规模测试再上生产。6.3 精度控制与工程标准符合性检查工业场景下生成的模型需要符合一定的工程标准比如尺寸公差、表面粗糙度、材料标注等。text-to-cad 目前主要解决的是几何形状的生成对于这些工程属性的支持还比较有限。一个可行的做法是在生成几何体之后用额外的元数据来标注这些信息导出时一并写入 STEP 文件的属性字段。STEP 格式本身是支持自定义属性的你可以在 CadQuery 里给几何体附加属性然后在导出时保留。另外如果你生成的模型要用于 CNC 加工建议在导出之前做一次几何有效性检查确认没有自相交、没有零厚度面、没有重复顶点。这些检查可以用 OpenCASCADE 提供的工具函数来做CadQuery 也封装了一部分。我一般会在导出前跑一遍.isValid()和.clean()确保几何体是干净的。7. 我在实际使用中踩过的坑和总结的经验先说一个最让我头疼的问题单位不一致导致的尺寸错误。有一次我批量生成了一批模型输入文本里有的用厘米有的用毫米解析模块没有做单位转换结果生成出来的模型尺寸差了十倍。后来我在解析模块里强制加了单位转换逻辑所有参数统一转成毫米再传给建模模块。这个坑让我意识到在 text-to-cad 的管道里单位处理必须在最前面做而且要做成强制性的不能依赖用户输入的一致性。另一个经验是不要试图一次性生成过于复杂的模型。我试过用一段描述生成一个包含几十个特征的复杂零件结果布尔运算频繁失败调试了整整一个下午。后来我把复杂模型拆成多个简单几何体分别生成之后再在 CAD 软件里手动组装效率反而高了很多。程序化建模的优势在于批量化和参数化而不是替代所有手动建模操作。找到合适的粒度才能发挥它的最大价值。还有一个关于 STL 导出的细节如果你生成的模型要用于 3D 打印导出 STL 之前一定要检查模型的法线方向是否正确。CadQuery 生成的几何体法线通常是正确的但如果你做了复杂的布尔运算有时候会出现法线翻转的情况。导入切片软件后如果发现模型有破面或者内部空洞大概率就是法线问题。解决方法是在导出前调用.val().fix()来修复几何体。最后分享一个提高开发效率的小技巧把常用的建模操作封装成函数库。比如“生成带孔长方体”“生成环形阵列孔”“生成倒角圆柱”这些操作我在多个项目里反复用到后来干脆写了一个cad_helpers.py模块每个函数接收几个关键参数返回 CadQuery 的 Workplane 对象。这样每次新建项目的时候直接导入这个模块几行代码就能搭出一个可用的建模管道。这个习惯帮我省了大量的重复劳动时间。这个方向后续还可以往几个方向扩展一是支持更多的几何特征类型比如螺纹、齿轮、弹簧这些标准件二是增加从二维图纸自动生成三维模型的能力三是把整个管道容器化做成一个可以随时调用的微服务。如果你也在做类似的事情欢迎交流踩坑经验。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑