ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CAD转Revit自动翻模:图层识别算法与ObjectARX开发实践

CAD转Revit自动翻模:图层识别算法与ObjectARX开发实践 搞BIM翻模的人应该都有同感CAD图纸一大摞Revit里面一栋楼要重新建模手工一根梁一堵墙地描费时费力又容易漏。我参与的几个项目都卡在“CAD转Revit”这个环节上后来做了一个基于图层自动识别算法的转换工具配合VS2022和AutoCAD2024的ObjectARX开发环境把大量重复工作交给了程序。这篇文章就把整个开发环境和核心算法梳理一遍给准备做同类事情的同行一个参考。这个内容的适用人群很明确BIM工程师、CAD/Revit二次开发人员以及被“翻模”折磨的机电和土建建模团队。文章不会绕弯子直接讲清楚图层自动识别到底怎么设计、VS2022和AutoCAD2024的开发环境怎么从零配置、转换主流程怎么落地以及实测中遇到的问题和对应解法。我自己是从零起步踩了不少坑写出来的东西基本是按照“如果再让我做一遍我会怎么做”的思路来的。1. 为什么CAD到BIM卡在了图层这个环节1.1 传统翻模方式的效率瓶颈先说个场景。一个三层办公楼CAD图纸大概有几十张分建筑、结构、给排水、暖通、电气五个专业。传统做法是打开Revit链接CAD图纸然后人肉描图。风管一根一根画管道一根一根连设备一个一个放置。一个熟练的BIM工程师纯手动建一栋三层办公楼的机电模型保守估计要一周到两周。这还只是建模不考虑图纸变更。一旦设计院出了V2版图纸前面做的很多工作就得推翻重来。半自动翻模工具是另一条路。市面上有些插件可以自动识别图块和图层比如风管翻模、给排水翻模它们的底层逻辑就是把“图块图层文字标注”绑定到指定族然后在Revit里自动放置族实例。这类工具的本质其实就是针对特定图层的识别。之所以能自动翻模是因为设计师作图时用了统一的图层标准比如暖通专业的风管通常放在“W-风管-送风”“W-风管-回风”这样的图层里。所以问题很清楚了CAD图纸里最有价值的语义信息除了图块名称和文字标注之外就是图层。图层是DWG文件里现成的分组依据也是连接CAD和Revit之间语义鸿沟的最短路径。谁能在图层信息上做好文章谁就能把转换效率提上去。1.2 为什么不能直接把DWG链接进Revit有人可能会说Revit不是支持链接CAD吗链接进来还能捕捉、还能描图不是挺方便吗没错链接CAD确实能作为底图但底图永远只是底图。Revit里的墙、风管、桥架是参数化构件有系统、有类型、有连接关系而DWG里的线就是线没有任何语义。链接CAD后你得自己根据线框去“翻译”成Revit构件这个翻译动作才是耗时的根源。反过来说如果能把CAD的图层、图块、文字、坐标等信息提取出来经过一套规则映射到Revit的类别、族、类型和标高上然后让Revit批量生成构件这个过程就有机会完全自动化。这也是图层自动识别算法的价值所在。1.3 开发环境选择的核心考量确定了要做图层自动识别和自动转换之后紧接着要回答一个问题在哪个软件端开发我的选择是在AutoCAD端用ObjectARX C做图层提取和识别在Revit端用Revit APIC#做构件生成。中间用一份JSON文件交换数据。这么设计有四个原因图层信息、图块定义、实体属性颜色/线型/文字内容都存在DWG数据库里ObjectARX是读取DWG最直接最稳定的方式。AutoCAD2024使用x64架构底层API对图层、实体、块表的访问非常完整遍历图纸的效率和稳定性都远高于其他间接方式。Revit API更适合做“生成构件”这种正向操作反向去读取DWG哪怕用Document.Import反而会把问题复杂化。用中间JSON解耦AutoCAD端和Revit端可以独立测试哪边出了bug就单独修不用两边联动调试省了很多时间。这个方案确定了之后接下来的核心工作就是两件第一把图层自动识别算法做扎实第二把VS2022和AutoCAD2024的开发环境跑通。我先说算法再说环境因为算法决定了工具的天花板环境只是基础条件。2. 图层自动识别算法的核心设计与容错机制2.1 不要把问题想复杂规则优先模型兜底一提到“算法”有些人的第一反应就是要不要上机器学习、深度学习。我在实际项目中得到的结论是多数情况下不需要。设计院的图层命名是有迹可循的虽然各个设计院的标准不一样但基本都会遵循国家标准或者院内标准比如《建筑CAD制图标准》之类。常见的命名方式有“专业-系统-用途”结构比如W-风管-送风W-风管-回风W-水管-冷水供水E-桥架-强电A-墙-周(这是一个常见示例实际可变)也就是说图层名本身已经包含了一部分语义。对于这种情况最合理的技术方案是建立一套“规则引擎”把已知的图层命名规则写进配置库然后对图层名做精确匹配、通配符匹配、正则匹配。只有在规则命中不了的时候才需要模糊匹配和人工复核。这样做的好处很明显规则可解释、可调试、可让设计院的人自己维护不用训练模型也不用攒数据集。我的规则库用JSON文件维护结构大致如下{ layerRules: [ { pattern: ^W-风管-(送风|回风|排风|新风)$, revitCategory: Duct, systemType: 送风, defaultFamily: 风管-圆形, priority: 100 }, { pattern: ^E-桥架-(强电|弱电|消防)$, revitCategory: CableTray, systemType: 强电桥架, priority: 90 } ] }priority字段用来处理图层命名重叠的情况。比如有的图纸把“W-风管-送风”写成“W-送风管”如果两条规则都命中了就取优先级最高的。这个机制在实际处理多个设计院的图纸时特别有用每家单位的标准不一样但规则库是同一个只需要调整优先级和正则表达式。2.2 模糊匹配和实体双通道校验规则匹配是主力但不能只靠它。实际图纸里经常出现“图层名不规范”“图块重命名”“多图框混排”的情况。比如一个图层叫“送风管-1F”正则表达式^W-风管-送风$就匹配不上这时候需要模糊匹配。模糊匹配我采用的是“关键词权重评分”的方案不搞复杂的向量相似度。具体做法是把一个图层名拆成关键词比如“送风管-1F”拆成“送风管”和“1F”然后跟规则库里的模板做权重比对。每个专业关键词都有权重例如“风管”权重4“送风”权重4“回风”权重4“1F”这种楼层后缀权重很低不计入匹配得分。当累计得分超过阈值我通常设为0.7时就判定为疑似命中进入下一轮校验。只靠图层名打分还不够稳妥因为有些图纸会把风管画在“0图层”或者“DEFPOINTS”图层上。这种时候必须加“实体双通道校验”除了图层名之外还要看实体类型和块名。具体来说如果实体是INSERT图块引用就看块名比如“风机盘管-卧式暗装”“喷头-下垂型”块名本身有很强的类别指向性。如果实体是LINE、LWPOLYLINE且所在图层匹配了“风管”关键词再结合线宽风管通常用宽线和文字标注附近有“630x400”这类尺寸标注来综合判断。如果实体是TEXT/MTEXT就看文字内容里是否包含“风管”“桥架”“管道”等关键词来辅助修正。实体层面的校验相当于第二道防线。当一个图层同时包含多种类型实体时算法会把图元按实体类型拆分分别映射到不同的Revit类别。举例来说“W-设备”图层里既有风机盘管的块又有风机盘管的供水管线和回水管线如果没有实体维度参与判断只凭图层名根本分不清哪个是设备、哪个是管道。加了实体类型和块名校验之后就可以准确地区分“设备族实例”和“管线实例”。2.3 未识别图层的兜底流程与增量自学习再完善的规则库碰到一个新设计院的图纸也一定会出现识别不了的图层。最怕的是算法给个“猜”的结果但猜错了转换完才发现风管变成了桥架那真是灾难。我的处理方式是识别不了的图层全部进“未分类缓冲区”。这一步非常关键宁可慢一点也不能错着转。具体流程是程序先把所有图层扫描一遍能识别的自动标记不能识别的统一列到一个界面上由BIM工程师人工确认。界面上会显示图层名、图层上的实体数量、实体类型样本和一张缩略图方便快速判断。工程师把“送风管-1F”拖到“送风管”的归类下这个映射关系就写回规则库的“自定义别名”区。下次再跑同一套图纸或者同一家设计院的其他图纸这个图层就能直接命中。这个机制用起来有点像输入法的自学习词库——越用越准而且规则库可以随项目积累。一个项目下来规则库基本能覆盖该设计院90%以上的图层标准。这也让我意识到图层自动识别算法的核心竞争力不在模型多先进而在工程经验的沉淀和容错机制是否灵活。2.4 同义词典与图层合并预处理还有一个细节容易被忽略同一家设计院内部的图层命名也可能不统一。比如给排水专业的“W-给水”和“W-生活给水”其实是同一个系统电气的“E-照明-应急”和“E-应急照明”指的是同一类图元。如果不做归一化处理规则库会越来越臃肿。所以我加了一个同义词替换层在匹配之前先对图层名做一次清洗全角半角统一中文状态下输入的全角符号转半角去掉冗余空格和首尾非法字符专业简写归一化“给水/生活给水/JS水”统一转成“给水”楼层后缀剥离“_1F”“-1F”“(一层)”统一去掉图层合并这个操作也建议在进入识别之前先做一遍。很多CAD图纸里有大量重复图层和近似图层比如“W-风管”和“W-风管1”并存。这种图层最好在AutoCAD端先用脚本合并再进入识别流程。有一个热词叫“cad图纸合并”说的就是类似场景合并图层和图纸清理是提高识别精度的前置条件这个步骤不能省。3. VS2022与AutoCAD2024开发环境的完整配置与踩坑记录3.1 版本对应关系很多人第一次配ObjectARX环境就翻车很大程度上是因为“版本匹配”没搞清楚。AutoCAD每个版本的ObjectARX SDK对Visual Studio版本和.NET Framework版本是有硬性要求的。AutoCAD2024对应的是ObjectARX 2024 SDK官方支持的VS版本是Visual Studio 2022v143工具集编译器是MSVC v143平台工具集也是v143。如果拿VS2019去编译生成的ARX在AutoCAD2024里加载会直接报错提示“无法加载ARX文件”或者模块未找到。操作系统方面建议Windows 10或Windows 11AutoCAD2024只支持64位系统项目的平台目标也必须是x64。这一点是初学者最容易踩的坑——新建工程的时候如果选了默认的Win32编译出来是多少位都搞不清楚加载到64位的AutoCAD里就是“无法加载”。3.2 安装清单开发机需要装的东西包括这些Visual Studio 2022我建议装Community版本装的时候勾选“使用C的桌面开发”工作负载这一步很关键不勾的话后面没有C编译器Windows 11 SDKVS安装器里自带建议选最新稳定版至少Windows 10 SDK以上.NET Framework 4.8 Developer PackAutoCAD2024和Revit 2024都基于.NET 4.8运行ObjectARX的.NET封装也需要ObjectARX 2024 SDK从Autodesk官方开发者中心获取需要注册账号下载后解压到一个没有中文和空格的路径比如D:\ObjectARXAutoCAD 2024用于调试和运行ARX插件正式环境建议使用正版授权Revit 2024 Revit SDK用于Revit端的族实例生成插件有两个细节说一下。第一SDK解压路径别带空格。我见过有人解压到D:\Program Files\ObjectARX 2024结果编译时一堆包含路径和库路径因为空格问题报错。第二VS2022安装完第一次启动的时候会提示登录这个不影响命令行的编译但我个人建议登录一下方便后续安装扩展组件。3.3 从零创建ObjectARX项目的步骤ObjectARX项目的创建有两种方式一种是使用SDK自带的向导插件把向导安装在VS2022里通过向导自动生成工程另一种是手动创建一个C DLL项目然后配置属性。手动方式更稳因为自动向导有时会在新版VS上失效这里我说一下手动方式。打开VS2022新建项目选择“空项目”或“动态链接库(DLL)”。项目名称例如CadLayerExporter存放路径建议和SDK放在同一个盘符下。创建完成后打开“项目属性”重点配置几项平台x64配置Release调试时可以用Debug但最终交付建议ReleaseC/C - 常规 - 附加包含目录加上$(ObjectARX)\inc。这里为了省事我建议在系统环境变量里新建一个ObjectARX变量指向SDK根目录然后在属性里写$(ObjectARX)\inc这样以后升级SDK版本不用改项目。链接器 - 常规 - 附加库目录$(ObjectARX)\lib-x64注意是lib-x64不是lib很多人在这里栽跟头链接器 - 输入 - 附加依赖项acad.lib、rxapi.lib、acdb*.lib、acutil.lib等。一般SDK里提供了样例照着样例工程抄一份即可。C/C - 代码生成 - 运行库多线程(/MT)交付时用/MT避免依赖VCRuntime的DLL调试也可以用/MDd链接器 - 常规 - 启用增量链接否ARX插件的增量链接经常出问题平台工具集Visual Studio 2022 (v143)关于字符集建议使用“使用Unicode字符集”。CAD2024本身是Unicode的如果你的代码里处理中文图层名用Unicode字符集可以省掉很多编码转换的麻烦。另外源码文件如果包含中文字符串保存时一定要用“UTF-8 with BOM”编码否则编译器可能按GBK解析导致中文乱码。VS2022里可以在“文件-高级保存选项”里选择编码也可以在项目属性里加/utf-8编译选项两个都做最保险。3.4 注册命令与调试ObjectARX插件的入口点是acrxEntryPoint但在实际编码中推荐使用SDK提供的AcRxArxApp类来写代码量少且不容易出错。基本骨架看下面这段#include StdAfx.h #include acad.h class CadLayerExporterApp : public AcRxArxApp { public: CadLayerExporterApp() : AcRxArxApp() {} // 注册CAD命令: 例如 EXPORTLAYERS static void CADExportLayers() { // 在这里写图层提取逻辑 } }; IMPLEMENT_ARX_ENTRYPOINT(CadLayerExporterApp) ACED_ARXCOMMAND_ENTRY_AUTO(CadLayerExporterApp, MyGroup, ExportLayers, ExportLayers, ACRX_CMD_MODAL, NULL)编译成功后会生成一个.arx文件。在AutoCAD2024里在命令行输入APPLOAD加载这个ARX文件再输入ExportLayers命令就能调用插件了。调试配置也算一个坑。要在VS2022里按F5直接启动AutoCAD进行调试需要做两件事第一在项目的“调试”属性里设置“命令”为AutoCAD2024的acad.exe路径比如C:\Program Files\Autodesk\AutoCAD 2024\acad.exe第二调试器类型选择“仅本机”。F5启动后VS会拉起AutoCAD2024插件已经自动注入了入口此时可以用VS的断点来调试C代码。这里有一条经验AutoCAD2024启动时会创建主进程acad.exe和工作进程acad.accore.dll所在的进程调试器有时会弹窗问你要附加到哪个进程。选择包含acad主窗体的那个进程一般是第一个。如果断点不命中可以手动在AutoCAD里执行NETLOAD或ARX命令把插件加载一次断点就会生效。还有一个很常见的坑ARX插件加载时会报“尝试阅读或写入受保护的内存”或“拒绝访问”。这类问题多半是版本不匹配或者引用了release版的SDK库却在debug模式下编译。所以我的建议是debug和release各配一套环境但最终调试验证只在Release下做省去很多和MFC/CRT版本相关的麻烦。3.5 关于VS2022编译C的通用经验现在VS2022下载安装教程一搜一大把但很多人装了VS2022之后连C项目都创建不了原因是安装VS的时候没有勾选“使用C的桌面开发”工作负载。这个负载包含MSVC编译器、Windows SDK、CMake工具等。如果后期发现没装可以在“Visual Studio Installer”里点击“修改”勾选对应工作负载再点“修改”按钮。安装过程可能需要重启建议装完立刻重启避免后续环境变量不生效。VS2022的C新工程编译报错另外一个高发点是找不到Windows SDK版本。解决办法是在项目属性 - 常规 - Windows SDK版本里选择一个已安装的版本或者直接选“最新已安装的版本”。如果已经装过多个版本的Windows SDK建议统一选一个长期稳定的版本比如10.0.19041.0或更高不要选老旧的8.1版本。4. 转换主流程的实现从DWG图层提取到Revit族实例落地4.1 第一步AutoCAD端遍历图层和实体打开AutoCAD绘制好的DWG文件用ObjectARX遍历当前数据库。核心思路是获取当前数据库的块表BlockTable找到模型空间块表记录BlockTableRecord遍历记录里的每个实体AcDbEntity读取实体的图层、实体类型、几何数据、文字内容等伪代码大概是这样AcDbDatabase* pDb acdbHostApplicationServices()-workingDatabase(); AcDbBlockTable* pBlockTable nullptr; pDb-getBlockTable(pBlockTable, AcDb::kForRead); AcDbBlockTableRecord* pModelSpace nullptr; pBlockTable-getAt(ACDB_MODEL_SPACE, pModelSpace, AcDb::kForRead); AcDbBlockTableRecordIterator* pIter nullptr; pModelSpace-newIterator(pIter); for (; !pIter-done(); pIter-step()) { AcDbEntity* pEnt nullptr; pIter-getEntity(pEnt, AcDb::kForRead); // 读取图层名 const TCHAR* layerName nullptr; pEnt-layer(layerName); // 根据 entity-isKindOf(AcDbLine::desc()) 等做类型分发 pEnt-close(); }遍历过程中要注意匿名块。CAD图纸里很多设备图块是匿名块块名以“*U”开头或动态块直接读块名读到的是*U123这种随机名称跟规则库完全对不上。解决办法是当遇到INSERT实体时先尝试用AcDbBlockReference获取块名如果块名以*开头就需要用explode方法炸开获取里面的实体再从内部实体的图层和块属性里找线索。这一步无法完全避免递归炸开带来的性能损耗但通常一层炸开就足够了。4.2 第二步输出标准化JSON交换文件图层识别完成后把所有信息汇总到一个中间结构。这里不推荐直接在AutoCAD端去调Revit的API跨进程调用非常脆弱而且两边只要有一方版本升级就可能崩。中间文件是最稳定的解耦方式。我输出JSON的格式大致长这样{ version: 1.0, source: AutoCAD2024, drawingUnits: mm, exportTime: 2025-01-12 10:20:00, entities: [ { id: 1, layer: W-风管-送风, matchedRule: ^W-风管-(送风|回风|排风|新风)$, revitCategory: Duct, entityType: LWPOLYLINE, points: [[0, 0, 0], [5000, 0, 0], [5000, 800, 0]], elevation: 3200 }, { id: 2, layer: W-设备-风机盘管, matchedRule: ^W-设备-(风机盘管|新风机组)$, revitCategory: FamilyInstance, entityType: INSERT, blockName: 风机盘管-卧式暗装, insertionPoint: [12000, 4500, 0], rotation: 0 } ] }这份JSON里最关键的是matchedRule和revitCategory字段它们记录了“图层是如何被识别的”以及“识别成哪个Revit类别”。如果以后发现某条规则识别错了可以直接回到AutoCAD端调整规则库重新导出JSON不用改Revit端的代码。坐标单位的问题在这里要统一处理。AutoCAD图纸可能是毫米也可能是英寸而Revit项目里也是要事先约定好单位的。我的做法是在JSON头部队写明drawingUnitsRevit端读取的时候根据项目单位做一次缩放避免出现1:1的图纸错位1000倍这种事故。4.3 第三步Revit端读取JSON并生成构件Revit端的插件用C#写通过AddIn文件注册为外部命令。读取JSON后用Revit API批量创建构件。主要逻辑如下用FilteredElementCollector查找项目里的族类型比如要找“风管-圆形”就遍历FamilyInstance或者内置族对于设备类图元风机盘管、喷头、桥架配件用FamilyInstance.Create()在指定标高放置对于管线类图元风管、水管、桥架用Duct.Create()或Pipe.Create()创建并设置系统类型根据elevation字段计算标高偏移放置到正确的楼层这里有一个很实用的经验Revit的族匹配不能光靠族名称字符串最好在族结构里加一个“关键字”共享参数比如“DN100闸阀”“风机盘管-1200风量”然后用这个共享参数做精确匹配。原因很简单一个项目里的族可能来自不同族库名字千奇百怪但共享参数往往保持了原始标准定义匹配成功率更高。坐标对齐也要在Revit端处理。如果CAD原点和Revit项目基点不一致会在读入JSON之后做一个平移变换把CAD坐标统一偏移到Revit项目基点附近。如果CAD图纸本身有旋转比如正北方向不一致还要加一个旋转变换矩阵。这块建议在Revit端写一个“坐标校准”界面选两个已知点对位比在代码里硬编码偏移量稳健得多。4.4 关于MEP曲线的简化处理管线类图元是转换里最麻烦的部分。Revit里创建风管和管道需要管件、连接件、系统类型最少要指定一个“起点”和一个“终点”并且要求曲线必须处于同一个平面或者有正确的坡度。CAD图纸里的管线通常是一组LINE或LWPOLYLINE转弯处没有管件这种情况直接转成Revit曲线很容易报“曲线未连接”的错误。我的处理方式是分两步第一步只创建直管段。把每段LINE/LWPOLYLINE作为一条独立的管道曲线先确保模型里有几何形体同时不要求在管件处连接。第二步吊顶/机房管线连接问题由人工在Revit里补管件或者通过“管线自动连接”功能统一处理。这样做虽然会增加一部分人工调整但比一口气把所有管线都转出来然后报一堆错要靠谱很多。要记住自动转换的目标不是100%消灭人工操作而是把重复度最高的80%工作自动化剩下20%的复杂连接关系留给专业工程师去处理。一上来就追求全自动往往最后全自动变成全手动擦屁股。4.5 性能优化与批量处理处理一个几万实体的CAD图纸ObjectARX遍历本身很快真正影响性能的是往JSON里写坐标点和在Revit端逐条创建构件。前者的优化办法是合并共线线段、移除重复点、过滤掉被冻结图层上的无效实体。后者的优化办法是用事务批量提交不要每个元素开一个Transaction一个事务里放几十上百个创建操作提交一次速度能提升不少。另外一个提升转换速度的细节是在AutoCAD端先执行一次图形清理PURGE和图层合并把无用的0图层实体、重复图层、空图层清理掉导出JSON的体量能缩小30%到50%Revit端创建构件的数量也会相应减少。这个操作看似跟算法无关但对整体转换效率影响很大。5. 实测数据与高频问题排查5.1 一次三层办公楼项目的实测对比我用自己这套工具做了一个三层办公楼机电项目的转换测试。CAD图纸为原始设计院图纸包含给排水、暖通、电气三专业的平面图和大样图总实体数约6万多图层86个。转换前的预处理阶段用脚本清理了重复图层和0图层实体耗时3分钟。接着运行ObjectARX插件导出JSON耗时26秒。Revit端创建构件识别成功并完成创建的实体约5.4万个耗时4分多钟。整体转换速度大概在200多个实体每秒。识别准确率方面首次运行时86个图层里命中规则库的有78个7个图层进入模糊匹配1个完全未识别进入人工复核。未识别的那个图层叫“W-保温层”规则库里没有定义人工归类到风管保温后规则库就多了一条新规则。全流程跑下来实体级识别准确率大约在94%左右剩余的6%主要是图块嵌套过深和错误标注导致的漏检。对比人工翻模的一到两周这个效率提升已经非常明显了。下面这张表是我自己整理的典型数据不同图纸会有浮动但经验性结论是一致的。指标人工翻模图层自动识别转换说明三层办公楼机电建模1~2周2~3小时时间含前期规则库配置和后期人工修正识别准确率实体级100%人工判断92%~97%取决于图层标准规范程度主要耗时作图、对图、描线规则库配置、未识别复核人工处理集中在“语义理解”环节5.2 高频问题1图层被锁定冻结导致漏读图纸里经常有锁定或冻结图层ObjectARX在遍历时可以读到这些图层上的实体但提取坐标信息时有可能受到外部参照XREF的影响。比如某个风管图元是外部参照进来的实体本身还在DWG文件里但图层名可能带有“XREF”前缀导致规则无法命中。解决办法是遍历实体前先检查AcDbLayerTableRecord的isOff()和isFrozen()状态并在导出时给外部参照实体打上标记。识别阶段如果碰到带“XREF”的图层名先尝试剥离前缀再进行匹配。对于外部参照图层不能简单忽略因为很多项目把风管分成两个文件绘制一个本专业的一个提资的漏了外部参照等于漏了一部分工程量。5.3 高频问题2图块嵌套导致设备漏转设备类的INSERT实体嵌套层级一般不多但有的图块会把风管末端、送风口、静压箱嵌套在风管块里。遍历的时候如果只读最外层图块名很可能把“送风口”读成“风管组合”导致转换后设备数量少了一大截。处理方式就是递归炸开。每炸开一层把子实体的类型、图层、块名、插入点记录下来然后重新进入识别流程。为了避免死循环我设置了一个最大递归深度默认是4层。动态块的炸开需要先转换为普通块否则拿不到正确的块内容。这里还有一个细节炸开会改变原图形不会。AcDbEntity::explode()只生成临时实体副本不修改原图所以可以放心调用。但要注意炸开后的临时实体必须用完后释放否则内存一直在涨处理几万实体时OOM也是有可能的。5.4 高频问题3中文乱码和文字错位CAD图纸里的文字和标注用的是中文导出JSON时如果编码不对会出现“鍙侀”这种乱码。解决方法是源码文件统一UTF-8 with BOMJSON写入时明确指定UTF-8编码AutoCAD端读取字符串时不做额外的代码页转换。如果遇到老的GB2312编码的DWGObjectARX读取到的字符串通常是宽字符形态直接转成UTF-8再写JSON就行。文字错位是另一个让人头疼的问题。DWG里单行文字用AcDbText它的对齐点有两个插入点position和对齐点alignment point。很多图纸只设置了插入点没设置对齐点或者两者正好反着来。如果只读position转换后文字跟原来的位置差一大截。解决方法是同时读取position()和alignmentPoint()如果对齐点不为零就用对齐点作为放置点否则退回插入点。这个规则也适用于多行文字AcDbMText。5.5 高频问题4坐标基准不一致AutoCAD的世界坐标系和Revit的项目基点通常不一致这是转换后模型错位的头号原因。我的做法是在AutoCAD端导出一对“定位点”——通常取平面图的西南角和东北角同时记录它们在WCS下的真实坐标。在Revit端读取JSON后先不着急创建构件而是让用户指定这两个定位点在Revit项目中的对应位置程序计算变换矩阵平移旋转缩放再把所有几何坐标依次变换。这个“双点对位”的思路非常实用比单纯用原点偏移可靠得多。尤其是多个平面图合成一个项目时每个CAD文件的对位点不同统一经过变换后再放置才不会出现楼层错位和构件穿越楼板的问题。6. 后续可以扩展的方向工具跑通之后可以做的事情还有很多这里分享几个我自己觉得有价值的方向。第一把规则库做成云端共享。目前规则库是本地JSON团队几个人一起用就得不停地同步文件。改成云端配置后识别规则可以跨项目沉淀不同设计院的命名规则积累得越多识别准确率越高。第二支持批量图纸转换。现在一次处理一张图后续可以做一个“图纸队列”把一整个项目的多张CAD图纸批量导出JSON再批量导入Revit。前提是每张图纸的定位点信息要做好配置否则批量导入会乱。第三把图层识别结果做成一个“图层映射报告”。报告里列出每个被识别图层的名称、命中的规则、映射到的Revit类别和族方便BIM负责人审核也方便建设单位和设计院确认转换结果。这比直接扔一个rvt文件出去更有说服力项目验收时也好交代。第四如果有人想做纯Revit端的转换也可以用DWG格式转换的思路但建议配合Revit的“导入DWG”功能然后在此基础上做二次识别。不过这个方案受Revit导入性能的限制处理超大图纸会比较吃力。至少我自己测试下来用ObjectARX在AutoCAD端做识别性能是最稳的。最后再分享一个小技巧也是我踩过坑之后养成的习惯每次处理新的设计院图纸之前先只导出1%的实体做一次快速预览转换确认图层规则和坐标对位没问题再跑全量。这样能避免花了半小时跑完转换之后发现所有构件都跑到地平线下面去了。批量操作里面“先验证再全跑”这个原则能帮你省下的时间比你想的要多得多。
返回列表