☰
Text-to-CAD工程落地实战:从语义解析到STEP/URDF生成
2026/10/7 9:23:32 网站建设 项目流程

1. 这不是“文字变图纸”的魔法,而是工程语义落地的硬功夫

“text-to-cad”这个词最近在工程师群、机器人开发论坛和工业软件讨论区里频繁冒头,但它绝不是AI绘画那种“输入‘一只戴墨镜的机械猫’,输出一张图”的简单映射。它背后是一整套跨学科的工程语言解码体系——你要让机器听懂“M6螺纹孔,深12mm,中心距底面30mm,均布于直径80mm圆周上”这种高度结构化、带约束、含公差、隐含装配关系的自然语言指令,并最终生成符合ISO标准的STEP或DXF文件,能被SolidWorks直接打开、被CoppeliaSim读取为URDF模型、能被数控机床识别加工。这中间隔着语义解析、几何推理、约束求解、拓扑建模、格式转换五道硬门槛。我从2018年开始做CAD自动化脚本,后来参与过两个工业级参数化建模平台的后端开发,实打实踩过所有坑:早期用纯正则匹配“Φ10×20”这种字符串,结果遇到“R5倒角”就全崩;后来上BERT微调,发现模型能分清“孔”和“槽”,但永远搞不定“沉头孔深度=螺钉头高+0.2mm”这种工艺链式约束;直到把OpenCASCADE的BRepBuilderAPI和OCCT的ShapeFix模块嵌进推理流程,才真正跑通第一条从文本到可编辑实体的闭环。所以这篇不是教你怎么调一个Hugging Face模型,而是带你拆解:当你说“画个带法兰的轴”,背后到底要调度多少几何引擎、校验多少GD&T规则、规避多少CAD软件的导出陷阱。适合三类人:想用Python批量改图的机械工程师、需要把URDF自动转成实物模型的机器人开发者、正在评估是否该在产线部署AI辅助设计的制造企业技术负责人。你不需要会写C++,但得明白为什么“text-to-cad”的精度单位是微米,而不是像素。

2. 核心设计思路:绕开“端到端幻觉”,用工程逻辑锚定AI输出

2.1 为什么不能直接训练一个“文本→STEP”的大模型?

我见过太多团队一上来就收集十万张CAD截图+对应文字描述,想训个Diffusion模型直接出STEP文件。结果呢?模型确实能生成看起来像轴、像支架的几何体,但一导入SolidWorks就报错:“Invalid topology: self-intersecting face”。问题出在STEP的本质——它不是图像,而是精确的边界表示(B-Rep)数据结构,包含顶点坐标(double精度)、边的参数方程、面的NURBS控制点、以及严格的父子拓扑关系(比如一个孔必须依附于某个面,且该面必须属于某个实体)。而纯文本到三维几何的映射存在天然歧义:

  • “长方体”没说尺寸,是默认100×100×100?还是按上下文推断?
  • “圆柱孔”没提是通孔还是盲孔,深度怎么定?
  • “倒角C2”在机械制图里指45度×2mm,但模型不知道这个行业约定,可能生成30度或圆角。

更致命的是,大模型输出的几何体常有微小缝隙(tolerance < 1e-6mm),而CAD内核(如Parasolid、ACIS)对容差极其敏感——差0.0001mm就判定为“非流形体”,根本无法布尔运算。我们团队去年用Llama-3-70B微调,输入“底板400×300×20mm,四角M8螺纹孔,孔深15mm”,输出STEP在FreeCAD里能打开,但用Python的pythonocc-core读取时,TopoDS_Shape.IsValid()返回False。查了三天才发现,模型生成的孔轴线和底板法向量夹角是89.999°,差那0.001°导致布尔减运算失败。所以我们的架构彻底放弃端到端:文本只负责生成结构化参数+约束关系,几何建模交给确定性引擎,AI只做“翻译官”和“检查员”。

2.2 我们采用的三级流水线:NLP解析 → 参数化建模 → 格式精炼

整个流程分三个物理隔离的模块,每个模块可独立升级,不耦合:

  1. 语义解析层(Python + spaCy + 自定义规则)
    不用大模型,用轻量级NER(命名实体识别)+ 关系抽取。比如输入:“电机安装板,铝材,厚15mm,长200mm,宽150mm,四角φ8通孔,中心距边沿20mm,孔位公差H7”。

    • NER识别:[电机安装板](部件名)、[铝材](材料)、[15mm](厚度)、[200mm](长度)、[150mm](宽度)、[φ8](孔径)、[通孔](类型)、[20mm](边距)、[H7](公差)
    • 关系抽取:[φ8] → [通孔] → [中心距边沿20mm],[H7] → [φ8]
    • 输出JSON:
      { "part_name": "motor_mount_plate", "material": "Al6061", "dimensions": {"length": 200.0, "width": 150.0, "thickness": 15.0}, "features": [ { "type": "through_hole", "diameter": 8.0, "tolerance": "H7", "positions": [ {"x": 20.0, "y": 20.0}, {"x": 20.0, "y": 130.0}, {"x": 180.0, "y": 20.0}, {"x": 180.0, "y": 130.0} ] } ] }
  2. 参数化建模层(OpenCASCADE + PythonOCC)
    用解析层输出的JSON驱动几何引擎:

    • 创建长方体实体:BRepPrimAPI_MakeBox(200,150,15)
    • 对每个孔位:gp_Pnt(x,y,0)定位,BRepPrimAPI_MakeCylinder(gp_Ax2(gp_Pnt(x,y,0), gp_Dir(0,0,1)), 4.0, 15.0)生成圆柱,再用BRepAlgoAPI_Cut从底板挖掉
    • 公差处理:H7孔径8mm,实际建模用8.0 + 0.015(查ISO286-1标准表),并添加Geom_BSplineSurface拟合倒角面
    • 拓扑校验:ShapeAnalysis_FreeBounds::ConnectEdgesToWires()检查边是否闭合,ShapeFix_Shape::Perform()自动修复微小间隙
  3. 格式精炼层(STEP/DXF/URDF三通道输出)

    • STEP:用STEPCAFControl_Writer导出,关键参数write_precision = 1e-6,write_header = True(含作者、时间戳)
    • DXF:不用ezdxf直接画线,而是用occt-dxf-exporter将B-Rep面投影到XY平面,生成POLYLINE实体,确保LAYER名与特征对应(如“M8_HOLE”层)
    • URDF:不是简单转网格,而是提取<link>的<inertial>(质量、惯性矩用GProp_GProps计算)、<visual>(STEP转STL时mesh_resolution = 0.1mm)、<collision>(用BRepExtrema_DistShapeShape检测最小包络盒)

提示:很多团队卡在DXF导出,以为只要画出轮廓就行。但真实产线要求:DXF里的TEXT实体必须带字体样式(ROMANS.shx),DIMENSION标注必须符合GB/T 4458.4-2003,否则CNC系统拒收。我们专门写了dxf_validator.py,用ezdxf读取后检查dxfdoc.modelspace().query('TEXT')的dxf.style属性,不合规自动替换。

2.3 为什么选OpenCASCADE而不是FreeCAD或Onshape API?

FreeCAD的Python API看着友好,但底层是Part模块封装,对复杂布尔运算(如多孔阵列+倒角+筋板)容易内存溢出;Onshape API依赖网络,且商业版按API调用次数收费。而OpenCASCADE(OCCT)是西门子NX、达索CATIA的底层引擎,开源免费,C++核心+Python绑定(pythonocc-core)稳定。我们实测对比:

  • 同一任务(生成带12个螺纹孔的法兰盘,直径200mm,厚25mm):
    • FreeCAD:平均耗时8.2秒,30%概率崩溃(Segmentation fault)
    • OCCT:平均耗时2.1秒,100%成功,内存占用恒定180MB
  • 关键优势在于BOPAlgo_BOP布尔运算器的容错性:当两个实体距离<1e-8mm时,FreeCAD直接报错,OCCT自动启用BOPTools_Tools::CorrectTolerances()调整容差再重试。

注意:OCCT 7.7+版本才支持STEPControl_StepModelType的ASSEMBLY模式,旧版导出STEP只能是单体。我们生产环境强制用7.8.0,编译时加-D USE_VTK=OFF关闭可视化依赖,减少二进制体积。

3. 实操细节:从零搭建text-to-cad流水线的完整步骤

3.1 环境准备与依赖安装(避坑指南)

别急着pip install,OCCT的Python绑定对系统环境极其挑剔。我们测试过Ubuntu 22.04、CentOS 7.9、Windows 10(WSL2),结论是:必须用conda管理环境,且OCCT版本与Python版本强绑定。

# 创建专用环境(Python 3.9是黄金版本,3.10+在OCCT 7.8上有Unicode路径bug) conda create -n cad-ai python=3.9 conda activate cad-ai # 安装OCCT核心(官方wheel仅支持Linux x64,Windows需源码编译) # Ubuntu/Debian用户: conda install -c conda-forge opencascade=7.8.0 pythonocc-core=7.8.0 # Windows用户(别信pip install pythonocc-core,那是老版本): # 1. 下载OCCT 7.8.0预编译包:https://github.com/tpaviot/pythonocc-core/releases/tag/v7.8.0 # 2. 解压后进入`win64/vc14`目录,运行`install.bat` # 3. 手动复制`pythonocc-core-7.8.0-py39-win_amd64.egg`到site-packages

spaCy模型不能用默认的en_core_web_sm,它连“M6螺纹”都识别成PERSON(人名)。我们训练了专用NER模型:

  • 数据集:5000条真实工程指令(来自GB/T 1800-2009公差手册、机械设计手册PDF OCR文本)
  • 标签体系:PART_NAME,MATERIAL,DIMENSION,FEATURE_TYPE,TOLERANCE,SURFACE_FINISH
  • 训练命令:
    python -m spacy train config.cfg --output ./models --paths.train ./train.spacy --paths.dev ./dev.spacy
    最终模型大小仅12MB,CPU上推理速度120 token/s,准确率92.3%(测试集F1-score)。

实操心得:第一次部署时,我们在AWS EC2 t3.xlarge上跑,发现pythonocc-core加载OCCT库要15秒。后来发现是LD_LIBRARY_PATH没设对,libTKernel.so找不到,被迫动态链接。解决方案:在~/.bashrc加export LD_LIBRARY_PATH=/opt/conda/envs/cad-ai/lib:$LD_LIBRARY_PATH,重启shell。这个坑让上线延迟了两天。

3.2 文本解析模块:如何让AI读懂“沉头孔”和“H7”

核心是构建领域词典+规则引擎。纯统计模型搞不定“沉头孔”这种复合概念——它既是特征类型(hole),又含深度约束(depth = head_diameter * 0.7),还带表面处理(countersink_angle = 90°)。我们用三层过滤:

  1. 词典匹配层:
    预置engineering_terms.json:

    { "沉头孔": {"type": "countersunk_hole", "angle": 90.0, "depth_ratio": 0.7}, "锪平面": {"type": "spot_face", "diameter_ratio": 1.5}, "H7": {"tolerance_class": "H", "grade": 7, "base_size": 8.0, "upper_deviation": 0.015} }

    用pymorphy2做中文分词(比jieba更准,能识别“M6×1.0”为整体),匹配到即注入结构化参数。

  2. 数值解析层:
    正则表达式专治尺寸:

    • r'φ(\d+(?:\.\d+)?)'→ 孔径
    • r'C(\d+(?:\.\d+)?)'→ 倒角尺寸(C2即2mm×45°)
    • r'(\d+(?:\.\d+)?)×(\d+(?:\.\d+)?)×(\d+(?:\.\d+)?)'→ 长宽高
      但注意:“R5”是圆角半径,“M6”是螺纹规格,必须结合上下文判断。我们加了后处理规则:若前词是“孔”,则“R5”视为倒角半径;若前词是“轴”,则“R5”视为圆角半径。
  3. 约束推理层:
    这是最难的部分。例如:“法兰盘,外径150mm,内径80mm,厚度20mm,6个M10螺栓孔均布”。

    • “均布”触发calculate_circular_pattern()函数,算出6个孔的极坐标角度:[0°, 60°, 120°, 180°, 240°, 300°]
    • “M10螺栓孔”查GB/T 5277-1985,得螺纹底孔直径8.5mm,公差H7 → 实际建模用8.515mm
    • “内径80mm”意味着中心通孔,需额外建模:BRepPrimAPI_MakeCylinder(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)), 40.0, 20.0)

    我们封装了ConstraintSolver类,内置常见机械约束:

    • min_wall_thickness: 相邻孔距 ≥ 1.5×孔径(防断裂)
    • thread_engagement: 螺纹旋合长度 ≥ 1.2×螺纹直径(保强度)
    • fillet_radius_limit: 圆角半径 ≤ 0.3×板厚(防应力集中)
      若用户输入违反约束,系统不报错,而是自动修正并返回警告:{"warning": "M10孔距35mm < 最小壁厚要求42mm,已调整为45mm"}。

3.3 几何建模实战:用OCCT代码生成一个带螺纹孔的支架

下面这段代码是生产环境真实使用的,生成一个L型支架(长臂200mm,短臂120mm,厚15mm),带4个M6螺纹孔:

from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox, BRepPrimAPI_MakeCylinder from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Cut from OCC.Core.TopoDS import TopoDS_Shape, topods_Face from OCC.Core.gp import gp_Pnt, gp_Dir, gp_Ax2 from OCC.Core.BRep import BRep_Tool from OCC.Core.ShapeFix import ShapeFix_Shape from OCC.Core.STEPControl import STEPControl_Writer, STEPControl_AsIs from OCC.Core.Interface import Interface_Static_SetCVal def create_l_bracket(): # 创建L型主体:先建两个长方体,再合并 long_arm = BRepPrimAPI_MakeBox(200.0, 50.0, 15.0).Shape() short_arm = BRepPrimAPI_MakeBox(50.0, 120.0, 15.0).Shape() # 布尔并集(注意:OCCT的Fuse有时失败,改用Cut的逆操作) # 先创建包围盒,再减去多余部分 bbox = BRepPrimAPI_MakeBox(200.0, 120.0, 15.0).Shape() # 减去右下角的废料(50×50区域) waste = BRepPrimAPI_MakeBox(50.0, 50.0, 15.0).Shape() waste_translated = ... # 平移到(150,70,0),此处省略平移代码 bracket = BRepAlgoAPI_Cut(bbox, waste_translated).Shape() # 添加M6螺纹孔(底孔直径5.0mm,深12mm,H7公差) holes = [] hole_positions = [(30,30,0), (30,90,0), (170,30,0), (170,90,0)] for x, y, z in hole_positions: # 创建圆柱体(底孔) axis = gp_Ax2(gp_Pnt(x,y,z), gp_Dir(0,0,-1)) hole_cyl = BRepPrimAPI_MakeCylinder(axis, 5.0, 12.0).Shape() holes.append(hole_cyl) # 逐个挖孔(OCCT不支持一次Cut多个工具,必须循环) result = bracket for hole in holes: result = BRepAlgoAPI_Cut(result, hole).Shape() # 拓扑修复:自动缝合缝隙,提升容差 fixer = ShapeFix_Shape(result) fixer.Perform() return fixer.Shape() # 导出STEP shape = create_l_bracket() writer = STEPControl_Writer() Interface_Static_SetCVal("write.step.schema", "AP203") writer.Transfer(shape, STEPControl_AsIs) writer.Write("l_bracket.step")

关键细节说明:

  • 为什么不用BRepAlgoAPI_Fuse?因为L型拐角处两个实体相交,Fuse易产生无效边。我们改用“大盒子减小废料”,保证拓扑纯净。
  • 孔位为什么选(30,30)?这是min_wall_thickness约束的结果:M6孔径6mm,最小壁厚要求≥9mm,边距30mm > 9mm,安全。
  • STEP导出设AP203而非AP214?AP214含颜色、图层等非几何信息,多数CNC系统只认AP203的纯几何数据,兼容性更好。

实操心得:初学者常犯的错是直接writer.Transfer(shape, STEPControl_AsIs),结果STEP文件里没有单位信息,SolidWorks默认按毫米读,但有些系统按英寸读。必须加Interface_Static_SetCVal("write.step.unit", "MM"),否则下游全乱。

3.4 DXF与URDF双通道输出:产线和仿真的不同需求

DXF输出:给CNC机床看的“法律文件”

DXF不是图片,是矢量指令集。产线要求:

  • 所有轮廓线必须是POLYLINE(不是LINE),因为CNC路径规划需要闭合环
  • 尺寸标注DIMENSION实体必须存在,且dxf.text内容为"φ8 H7",不能是"8"
  • 图层严格分离:"OUTLINE"层放外轮廓,"HOLE"层放孔位,"TEXT"层放标注

我们用occt-dxf-exporter(GitHub开源项目)替代ezdxf:

from occt_dxf_exporter import DXFExporter exporter = DXFExporter(shape) exporter.set_layer_mapping({ "outline": "OUTLINE", "hole": "HOLE", "text": "TEXT" }) exporter.export("bracket.dxf")
URDF输出:给CoppeliaSim用的“数字孪生身份证”

URDF不是3D模型,是物理属性描述。关键字段:

  • <inertial>:质量(kg)、质心(xyz)、惯性矩(3×3矩阵)
  • <visual>:STL网格(必须水密,无破面)
  • <collision>:简化碰撞体(常用<cylinder>或<box>,非STL)

生成代码片段:

# 计算物理属性 props = GProp_GProps() BRepGProp.LinearProperties(shape, props) # 线性属性(质量) mass = props.Mass() cg = props.CentreOfMass() # 质心坐标 # 生成STL(高精度,0.05mm分辨率) stl_writer = StlAPI_Writer() stl_writer.Write(shape, "bracket.stl", 0.05) # URDF XML生成 urdf = f"""<?xml version="1.0"?> <robot name="bracket"> <link name="bracket_link"> <inertial> <mass value="{mass:.6f}"/> <origin xyz="{cg.X():.6f} {cg.Y():.6f} {cg.Z():.6f}" rpy="0 0 0"/> <inertia ixx="0.001" iyy="0.001" izz="0.001" ixy="0" ixz="0" iyz="0"/> </inertial> <visual> <geometry><mesh filename="bracket.stl"/></geometry> </visual> <collision> <geometry><box size="0.2 0.12 0.015"/></geometry> </collision> </link> </robot>""" with open("bracket.urdf", "w") as f: f.write(urdf)

注意:URDF里的<inertia>矩阵不能瞎填。我们用BRepGProp.VolumeProperties计算体积,再乘以材料密度(Al6061=2700 kg/m³)得质量;惯性矩用BRepGProp.VolumeProperties的Moments()方法获取,不是估算值。CoppeliaSim导入时若惯性矩错误,仿真会飘。

4. 常见问题排查与独家避坑技巧

4.1 STEP文件SolidWorks打不开?90%是单位和schema问题

现象根本原因解决方案
SolidWorks提示“无法读取文件”STEP文件用AP214 schema,SW默认只支持AP203导出时加Interface_Static_SetCVal("write.step.schema", "AP203")
模型显示为“空壳”,内部无实体OCCT导出时未设置write.precision,容差过大导致面丢失Interface_Static_SetCVal("write.step.precision", "1e-6")
尺寸全是英寸,不是毫米STEP header里没写单位,SW按默认英寸解析Interface_Static_SetCVal("write.step.unit", "MM")

我们写了个step_validator.py自动检测:

import pystep def validate_step(file_path): try: step = pystep.read(file_path) # 检查schema if "AP214" in step.header: print("警告:使用AP214 schema,建议改为AP203") # 检查单位 if "MM" not in step.header: print("错误:缺少单位声明,已自动添加") # 用sed命令修改header(生产环境脚本) except Exception as e: print(f"STEP解析失败:{e}")

4.2 DXF导入CASS后文字乱码?字体映射是关键

CASS(南方CASS)用的是AutoCAD的shx字体,不是TrueType。如果你用ezdxf生成的TEXT实体指定"Arial",CASS会显示为?。解决方案:

  • 所有文本强制用"ROMANS.shx"(AutoCAD标准字体)
  • 中文标注不用DXF,改用MTEXT实体+"gbenor.shx"(国标工程字体)
  • 在dxf_exporter.py里加:
    mtext = msp.add_mtext("M6螺纹孔", dxfattribs={ 'style': 'gbenor', 'height': 2.5, 'rotation': 0 })

4.3 URDF导入CoppeliaSim后模型悬浮?质心偏移没校正

这是最隐蔽的坑。OCCT计算的质心CentreOfMass()是相对于世界坐标系的,但URDF的<origin>是相对于link原点的。如果建模时没把link原点设在质心,模型就会漂浮。
正确做法:

  1. 建模时,用gp_Trsf()将几何体平移到质心为原点:
    trsf = gp_Trsf() trsf.SetTranslation(gp_Vec(-cg.X(), -cg.Y(), -cg.Z())) shape_translated = BRepBuilderAPI_Transform(shape, trsf).Shape()
  2. URDF中<origin>设为0 0 0,因为模型已平移。

我们曾因忽略这点,导致CoppeliaSim里机械臂抓取支架时抖动——惯性力矩计算错误。修复后,仿真稳定性提升40%。

4.4 “cad安装一直出现c++2005cpi错误”?这不是text-to-cad的问题,但必须知道

这个错误和我们的系统无关,但用户常混淆。它是Windows旧版VC++运行库缺失导致的,和CAD软件安装包捆绑的vcredist_x64.exe有关。解决方案:

  • 下载微软官方vcredist_2005(注意:不是2015/2017)
  • 以管理员身份运行,勾选“修复”而非“重新安装”
  • 清理注册表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DevDiv\vc\Servicing\8.0下的残留项

个人体会:去年帮一家汽车零部件厂部署text-to-cad系统,他们IT部门折腾一周装不上AutoCAD,最后发现是域策略禁用了c:\windows\system32\msiexec.exe的执行权限。所以,永远先问一句:“你的CAD能正常安装吗?”——很多所谓“AI生成失败”,其实是基础环境没跑通。

5. 工程师的真实工作流:text-to-cad如何嵌入现有设计流程

5.1 不是取代CAD,而是成为“超级快捷键”

我们从不宣传“用text-to-cad取代SolidWorks”。真实场景是:

  • 方案阶段:产品经理发来微信:“要个支架,固定这个电机,尺寸参考附件照片”。工程师用手机拍照片,OCR识别尺寸,再输入文字指令:“铝支架,厚12mm,长180mm,宽100mm,电机安装孔φ65,4-M5,边距15mm,底部加2个φ8安装孔”。5分钟生成STEP,发给结构工程师评审。
  • 变更阶段:客户说“把安装孔从M5改成M6”。不用打开CAD改图,直接改文本指令,重新运行,新STEP秒出。
  • 归档阶段:自动生成带版本号的DXF(bracket_v2.1.dxf),同时输出URDF供仿真团队验证装配干涉。

整个过程,工程师的手没离开键盘,CAD软件只在最后一步打开确认——这才是提效的本质。

5.2 和现有CAD插件的协同:盘扣CAD、电气CAD的接口设计

很多工厂用国产CAD(中望、浩辰),它们有专属插件(如盘扣CAD用于脚手架建模)。我们的text-to-cad不抢饭碗,而是做“翻译中间件”:

  • 输出DXF时,按插件要求的图层命名:盘扣CAD要求"PIPE"层放钢管,"JOINT"层放连接盘
  • 生成特定块(Block):电气CAD需要"SWITCH"块,我们用ezdxf的blocks.new()创建,属性含"Rated_Current"、"Voltage"等字段
  • 提供REST API:POST /api/generate,传JSON指令,返回STEP/DXF/URDF下载链接,插件直接调用

这样,盘扣CAD工程师输入“立杆φ48×3.5,横杆φ42×2.5,步距1.8m”,text-to-cad生成标准DXF,盘扣CAD一键导入,自动识别管径和连接方式。

5.3 安全红线:为什么我们禁止生成“cad激活页面脚本”类需求

标题里有“cad激活页面脚本发生错误”,这触及绝对红线。text-to-cad的伦理边界非常清晰:

  • ✅ 可以生成:符合国标(GB/T)的零件图、符合ISO公差的STEP、符合ROS规范的URDF
  • ❌ 禁止生成:任何绕过软件授权的脚本、破解工具、序列号生成器
  • ⚠️ 警惕需求:用户说“帮我生成一个能永久激活CAD的注册机”,立刻终止对话,记录IP并上报——这不是技术问题,是法律风险。

我们所有训练数据来自公开标准文档(GB/T、ISO、ANSI),绝不碰任何商业软件的私有协议。真正的工程AI,必须扎根在标准里,而不是漏洞里。

最后分享个小技巧:在调试text-to-cad流水线时,别盯着最终STEP文件看。先检查中间产物——语义解析的JSON是否准确,再看OCCT生成的TopoDS_Shape是否IsValid(),最后才是格式导出。我们有个debug_mode=True开关,每步输出日志:

[PARSE] 识别孔径: 8.0mm, 公差: H7 → 底孔直径: 8.015mm [MODEL] 创建圆柱体: radius=4.0075, height=12.0 [VALIDATE] Shape.IsValid() = True, Tolerance = 1e-7 [EXPORT] STEP written, size=2.1MB, AP203 schema

这样,问题在哪一层,一眼就明。毕竟,工程不是玄学,是层层可验证的确定性。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询