近年来, 建筑信息模型(Building Information Modeling, BIM)技术已广泛应用于建筑行业, Revit是BIM技术常用的建模软件之一[1]. 目前, 钢筋BIM模型三维视图中钢筋型号、直径等信息能够采用引线方式标注[2,3], CAD图中的房间名称等信息可以自动转换到Revit楼层平面图中[4,5], 但是, Revit三维视图无法显示房间名称及ID信息, 在仿真漫游或观察剖面视图时, 需要由三维视图切换到二维楼层平面图查阅标注的房间名称及ID, 降低了工作效率.
本文旨在设计一种在Revit三维视图中自动标注房间名称及ID信息的中间件, 减少仿真漫游或观察剖面视图时Revit二维与三维视图之间的多次切换, 并自动准确定位房间位置, 解决标注信息位置与模型重叠问题.
1 基于Revit的中间件二次开发技术中间件, 作为Revit楼层平面图与Revit三维视图之间的数据中转站, 在提取、存储二维楼层平面数息标注到三维视图模型房间方面做到了起承转合的作用.
Visual Studio是微软基于.NET Framework框架的一个集成开发环境. 在本文中, Visual Studio软件作为Revit二次开发的平台. Revit的应用程序接口(API)能够访问Revit模型的图形数据、参数数据.
基于Revit API接口设计中间件有两种方式: 外部应用函数(IExternalApplication ( ))和外部命令函数(IExternalCommand ( )). Revit开发平台通过两者后缀为“.addin”的文件识别和加载外部插件, 其中IExternalApplication ( )需要调用两个接口命令函数(OnStartup ( )和OnShutdown ( ))创建应用程序. 该工作方式在运行的Revit开发平台上即可进行编程和调试工作, 调试完毕重新加载运行调试的程序实现功能扩展, 节省编程调试时间. 而IExternalCommand ( )函数在程序调试时, 需要关闭Revit软件平台, 返回到外部命令函数调用Execute ( )函数调试程序, 由于反复关闭和启动Revit软件平台, 会需要更多的调试时间.
本文选用IExternalApplication ( )函数创建功能面板, 通过加载Addin Manager来识别外部工具. 该方式利用Visual Studio集成开发环境、C#编程语言, 添加引用Revit API.dll和Revit API UI.dll接口, 搭建Revit软件应用平台, 通过IExternalApplication ( )函数来读取应用插件. 基于Revit的中间件二次开发技术的外部应用操作流程如图1所示.
2 中间件设计方案在Revit软件平台上, 链接CAD图纸, 由二次开发的“CAD文字转化”插件自动识别链接图纸的房间名称及ID文字信息, 并标注于Revit楼层平面房间[6]. 自动标注Revit三维视图房间信息的中间件在此基础上进行设计. 具体设计可以分为三部分: 中间件楼层房间信息获取方法、中间件数据存储及中间件模型房间信息标注方法.
2.1 中间件获取楼层房间信息方法在以标准建筑规范为准的Revit二维楼层平面中, 各房间通过Revit软件“标记房间”功能标识房间, 并且它也是由建筑墙体、门窗等构件无缝连接组成的封闭轮廓. 其中不同房间名称可能相同但是其ID信息和坐标定位不同. 通过Revit API获取楼层房间信息需对建筑房间内的构件进行访问、类别过滤以及坐标定位.
2.1.1 建筑构件的访问在建筑设计建模时, 类别(Category)是一组图元, 类名是该组图元的名称[6]. 根据构件标识特征, Revit API对不同构件进行辨别和访问. 该方法访问系统族实例仅需要判断构件的类名属性即可, 访问可载入族实例需要共同判断构件的类名及类别.
由于门、窗、柱等构件没有专用的系统类来表示, 都是FamilyInsurance的载入族实例, 无法通过类名辨别, 故Revit二次开发的中间件需要采用类别和类名判断载入族实例的构件.
2.1.2 建筑构件的类别过滤
Revit开发平台中所有的对象构件遍历都要使用过滤收集器(FilteredElementCollector)收集被过滤的对象, 在过滤操作时结合多个过滤器共同使用, 过滤后, 过滤收集器获得满足条件的对象构件集合[7,8].
Revit API创建过滤收集器后, 选择其中的构件过滤条件, 过滤当前楼层平面图中的构件, 指定视图中的可见对象或集合, 例如房间(Room)、墙体(Wall)、门(Door)等. 以Room类为例:
FilteredElementCollector roomFilter=new Filtered ElementCollector(doc);//创建过滤集合
ElementCategoryFilter orCategory=new Element CategoryFilter(BuiltInCategory.OST_rooms);//创建类别过滤条件
roomFilter.WherePasses(roomCategory);//这个返回的是房间类别下的所有Element, 包括了文件中的房间实例(对应type为FamilyInstance), 和用来创建房间实例的类型(type对应FamilySymbol)
ElementClassFilter roomType=new Element Class Filter(typeof(FamilyInstance));//创建一个type过滤器
roomFilter.WherePasses(doorType);
2.1.3 楼层房间信息获取由于建筑模型内部是由多个房间和公共区域组成, 所以判断房间是获取信息的主要依据, 而楼层房间内的建筑构件应该由统一坐标系进行定位. Revit楼层平面图中, 房间名称及ID信息标注于封闭房间墙体轮廓内部.
(1)坐标转化
在Revit楼层平面图内, 不同图元构件间的坐标基准值不同, 图元构件通过图元间的相对位置进行定位. 因此, 图元构件首要进行坐标转换, 转化为统一的模型坐标系.
Revit软件提供了Transform类来进行坐标转换, 开发人员可以给Transform对象进行赋值构造转换矩阵, 使用该转换矩阵将给定的坐标点坐标转成模型坐标系. 首先, 初始化Transform, 然后设置其目标坐标系的三个方向向量BasisX, BasisY, BasisZ的值, 使用Of Point进行点坐标转换, 用Of Vector进行向量坐标转换, 把目标点或向量坐标转换到模型坐标系的坐标.
Revit开发平台内的GeometryInstance.Tr ansform函数访问族定义到模型中的位置矩阵, 使用Transform转换矩阵计算出楼层平面图中的图元构件门、窗等族实例中的所有点在模型坐标系的位置(从族实例中获取其点、线、面的坐标也可以通过GeometryInstance对象的GeometryInstance.GetIns tanceGeomery( )函数直接返回在模型坐标系下的坐标).
(2)坐标定位
Revit图元构件的定位信息通过两种方式来获取:
1)使用Revit.Location函数来获取定位简单族实例位置. 包含两类对象:
①基于点的族实例: 例如柱子、门窗和家具等. 基于点的族实例的Location属性返回Location Point IP对象, 通过IP Point获得插入点的位置坐标以及IP Rotation获得该点的旋转角度, 其值为弧度值, 逆时针旋转为正.
②基于线的族实例: 例如梁、墙等. 基于线的族实例的Location属性返回Location Curve Ic对象, 通过Ic Curve可返回基线, 从而获得路径的起始点和终止点的位置信息.
2)使用Element Geometry函数来获取复杂图元的点、面、线空间定位. 例如: 楼梯、屋顶、斜墙.
(3)确定房间边界
在Revit楼层平面中, 通过Revit API获取标识房间的参数及封闭房间边界坐标. 房间边界可以为几种图元构件: 墙体、门、窗、柱等.
图元构件元素为房间边界的条件:
1)对于模型曲线的元素, 它的类别是BuiltInCategory. OST_AreaSeparationLines.
2)对于其他元素, 比如墙、柱, 它们的房间边界(BuihInParameter.WALL_ATTR_ROOM_B OUNDING)参数必须设为True.
Revit API获取所有房间边界信息可以用Room里的
public IList<IList<BoundarySegment>> GetBo undarySegments
(
SpatialElementBoundaryOptions options
)
BoundarySegment函数集合IList<IList<Boun darySegment>>包含了每一个房间边界的信息. 房间边界类图如图2所示.
(4)获取房间信息
楼层房间经建筑构件的访问和过滤收集器过滤后, 将指定的集合房间存入创建好的收集器中, 接着, 使用Transform类转化为统一的模型坐标系, 使用Revit.Location获取建筑楼层房间边界的坐标定位信息; 再通过Revit API的内置参数BuiltInParameter.ELEM_ROOM_NAME直接识别和提取房间名称、ID字符串, 为下一步数据存储做好准备.
利用各楼层房间边界的区域坐标数据范围来表示中间件获取的楼层房间名称及ID信息. 在Revit楼层平面图中, 定义图纸楼层房间的左下角为坐标系原点
以某幼儿园施工图的一层楼层平面为例(如图4所示), 取施工图中某一特征点A
2.2 中间件的数据存储
数据库作为Revit楼层平面图与Revit三维视图之间的数据中转站, 在数据储存、数据调用方面起到重要作用.
工程技术人员在进行模型房间标注时, 需要鼠标移动选择待标注的模型房间位置发送到中间件, 而中间件需要获取该位置的空间坐标系数据信息, 才可以进行下一步的运算. 所以, 数据表存放着Revit楼层平面图中的各楼层房间直角坐标系、楼层信息以及房间名称及ID信息.
本方案中BIM数据库(Epplus库)的构件主要包含2张数据表, 分别为: 1)房间名称及ID的数据表, 保存了BIM模型中房间名称及ID信息; 2)房间边界的数据表, 保存了BIM模型中房间轮廓的坐标数据信息.
为清楚每条记录都能够被唯一识别, 便于和其相关的语句相映射, 需要定义房间名称及ID来使数据库中每条记录可以被唯一识别, 以便于在各个表之间建立主键和外键关系. 表1所示为一个房间存储信息数据表, 以房间的名称及ID作为主键, 其他的字段包括文件名名称、围成房间边界的墙体ID及门窗等, 清晰地反映房间的坐标数据信息.
以上述幼儿园为例, 其中一层活动室101, 教室103, 二层办公室201等楼层分布, 如图4所示. 提取直线X、Y坐标数据信息, 经过Epplus库输出到Excel表格, 其中, 表格抬头分为“楼层信息”、“房间边界坐标数据”、“房间名称”、“房间ID”, 按组将坐标信息写入表2某幼儿园生成中间件的Excel文件.
2.3 中间件房间信息标注在Revit三维视图下, 结合Revit API判断待标注的模型房间空间坐标系的位置, 匹配中间件内存储坐标数据, 并提取模型待标注信息, 将需要标注的房间名称及ID信息加载到模型房间中, 完成标注.
2.3.1 Revit坐标数据匹配算法
在Revit三维视图中, 获取模型标注信息, 匹配中间件内坐标数据信息算法思路: 确定需要标注的模型房间, 取其模型房间内任意一点A, 获取该点空间坐标系
根据
具体的判断方法: 在空间坐标系中, 令Z轴代表楼层的高度, X、Y轴代表楼层房间内水平位置. 以图5的A点为例, 根据
访问中间件存储数据, 需要C#语言在VS中进行添加引用.dll文件, 以下为连接中间件的程序主要代码:
string strConnect = "Provider=Microsoft.Ace. OleDb.12.0;" + "data source=" + excelFilePath + ";Extended Properties='Excel 12.0; HDR=Yes; IMEX=1'";
2.3.2 Revit三维视图中模型信息提取标注在Revit三维视图中, 对中间件内存储的楼层平面内坐标数据的访问、提取, 利用遍历特征, 获取房间名称和ID的属性信息. 提取数据信息的具体流程如图7所示.
在仿真漫游或是剖面视图下, 采取鼠标触发事件技术, 显示房间的名称和ID信息, 利用提示节点(Tooltip)函数功能, 提取中间件信息实现标注. 当鼠标移动其模型房间区域内任意一点时, 模型房间信息将会通过提示节点出现在鼠标旁, 适时显示模型房间的信息; 当鼠标移开之后, 信息消失. 具体实现显示信息流程如图8所示.
2.4 小结
经过上述中间件房间数据信息的描述, 自动标注Revit三维房间信息中间件框架设计流程图, 如图9所示.
具体总结为几个步骤:
Step 1. 在Revit楼层平面图中, 通过Revit API接口对建筑构件访问, 创建过滤收集器、过滤条件, 将房间Room存入到收集器中.
Step 2. 各楼层房间图元构件利用Transform函数坐标转化为统一的模型坐标系, RevitLocation函数坐标定位获取房间区域边界轮廓的坐标数据, 利用Revit API内置参数BuiltInParameter. ELEM_ROOM_NAME获取房间名称及ID字符串信息.
Step 3. 结合SQL server, 建立基于BIM数据库(Epplus库), 并定义ID使得数据库中每条记录可以被唯一识别, 确立各个表之间主键和外键关系, 接着, 将Step 2中提取的房间信息存储到数据库, 并将数据库存储信息写入Excel文件.
Step 4. 在Revit三维视图中, 判断待标注的模型房间空间坐标系的位置, 再次借助Revit API接口, 提取空间位置坐标数据.
Step 5. 采用坐标数据匹配算法, 将空间定位的位置坐标数据组与中间件存储的直角坐标数据信息进行匹配, 提取待标注数据信息.
Step 6. 利用鼠标触发事件, 显示三维视图中模型房间名称及ID信息, 完成标注.
3 实例验证
根据分析以上所提出的三维视图房间标注方法, 采用面向对象技术的C#语言, 使用Visual Studio 2013进行代码编写, 在Autodesk Revit 2016中进行测试. 其中在Revit中, 利用外部命令Addin Manager来加载运行编译完成的中间件名称“fangjian.dll”—点击“fangjian.Command”—“Run”运行加载模型房间的标注. 图10为Revit附加模块生成的中间件.
本测试是以某幼儿园实际工程为案例, 一楼三维剖面视图上进行标注, 其标注内容为房间名称及ID, 完成效果如图11所示.
Revit三维模型的标注, 将房间的名称及ID添加到三维模型中, 能够让工程技术人员清晰的看到房间的名称和ID, 相比较于之前需要查阅Revit楼层平面上的标注来确定房间名称及ID, 节省了部分时间, 提高了阅图效率.
4 结束语本文主要结合Revit二次开发技术, 重点研究模型房间在三维视图中自动标注房间名称和ID信息的方法, 具体得到以下结论:
1)本文借助Revit API接口, 研究了Revit三维模型视图中自动标注楼层平面房间信息的方法, 该方法能够将楼层平面房间坐标信息提取并存储到中间件中, 而且调用中间件存储信息自动匹配坐标数据对模型房间标注名称和ID信息.
2)以某幼儿园工程为例验证程序的可行性及稳定性. 通过工程图纸房间测试, 能够看到三维视图中的房间名称及ID信息. 给设计人员和审图人员节省了部分时间, 提高了工作效率.
3) 本文研究的三维标注模型房间自动标注方法有待更多的工程实例测试, 此外, 由于BIM模型本身的复杂性, 更多的丰富信息标注待进一步研究, 这也为Revit在三维模型标注方面或其他程序开发提供一些经验.
[1] |
李正农, 朱爱民, 吴红华, 等. 基于Revit的二次开发在脚手架设计中的应用研究. 湖南大学学报(自然科学版), 2018, 45(9): 65-73. |
[2] |
徐鹏, 吝江峰, 左威龙, 等. 水利工程三维BIM钢筋标注二次开发技术研究. 小水电, 2016(4): 15-19. DOI:10.3969/j.issn.1007-7642.2016.04.006 |
[3] |
Zhao Q, Ma ZX, Hei XH, et al. A 3-D structural components automatic modeling method based on BIM. Proceedings of 2017 13th International Conference on Computational Intelligence and Security. Hong Kong, China. 2017. 59–63.
|
[4] |
Pärn EA, Edwards DJ. Conceptualising the FinDD API plug-in: A study of BIM-FM integration. Automation in Construction, 2017, 80: 11-21. DOI:10.1016/j.autcon.2017.03.015 |
[5] |
邓朗妮, 黄晓霞, 彭来, 等. 基于Revit二次开发的施工危险源安全管理平台研究与应用. 广西科技大学学报, 2018, 29(1): 106-112. |
[6] |
Venne F, Rivest L, Desrochers A. Assessment of 3D annotation tools as a substitute for 2D traditional engineering drawings in aerospace product development. Computer-Aided Design & Applications, 2010, 7(4): 547-563. |
[7] |
李昌华, 田思敏, 周方晓. 自适应分块的BIM墙体轮廓提取及三维重建研究. 计算机科学与探索, 2018, 12(3): 452-461. DOI:10.3778/j.issn.1673-9418.1612080 |
[8] |
钟辉, 李驰, 孙红, 等. 面向BIM模型二次开发数据提取与应用技术. 沈阳建筑大学学报(自然科学版), 2019, 35(3): 560-566. |