1、引言

    BIM(Building information modeling)是将建筑的所有信息包括几何信息、功能要求及构件性能集中到一个模型中,该模型涵盖了从建设项目最初的概念设计直至建筑物退役期间的所有信息,采用 BIM 技术将大大提高建筑信息的利用率。但是,设计、施工、运营维护人员和业主开发商等在同一个 BIM 模型上工作的 “单一模型” 模式在实践中是不切实际的。在项目建造的不同阶段,基于不同目的、不同的参与者等因素,BIM 模型所要包含和表达的信息以及详细程度也是不同的。目前绝大多数 BIM 软件都是对设计人员开发的,对电脑的配置要求较高,一般的笔记本电脑或者平板电脑根本无法安装或者流畅的运行,这大大提高了非设计人员应用 BIM 的成本,也将 BIM 技术的应用范围局限于办公室中。

    随着移动互联网的快速发展,能随时随地查看 BIM 模型成为了一种有价值的需求。目前几乎所有的浏览器都已经支持 3D 绘图标准 WebGL,我们可以直接利用网页技术来渲染三维图形。根据工程需求提取 BIM 模型中的几何信息并把模型渲染到网页上,让用户随时能通过浏览器进行查看,这将极大的提升协同效率,扩大 BIM 的应用范围。本文将从基础的 Three.js 案例开始,逐步讲解 Philippe Leefsma 和 Jeremy Tammik 所开发的轻量 3D 模型查看器的核心构造,希望能对大家了解 BIM 轻量化提供一些参考。

    2、一个 Three.js 简单的例子

    直接利用 WebGL 编程需要知道 WebGL 底层细节,并且学习复杂的着色语言来利用 WebGL 的大部分功能。Three.js 是使用 JavaScript 编写的 WebGL 第三方库,用户不需要学习 WebGL 就能创作出好看的三维图形。Three.js 使用面向对象的方式来构建程序,包含 3 个基本的对象:场景(scene)、摄像机(camera)和渲染器(renderer)。场景是一个容器,主要用于保存、跟踪所要渲染的物体(如苹果、葡萄)和使用的光源。摄像机的作用就是面对场景,在场景中取一个合适的景,把它拍下来,它决定了能在场景中看到什么。渲染器对象会基于摄像机的角度来计算场景对象在浏览器中会渲染成什么样子。他们三者的关系如下图所示:

    一个基于Three.js的BIM轻量化引擎释读 - 图1

    一个基于Three.js的BIM轻量化引擎释读 - 图2

    代码 1,一个简单的 Three.js 示例代码

    1. My first Three.js app

    代码 1 中给出了简单的 Three.js 的案例,将其用浏览器打开,将会看到一个旋转的绿色立方体。Three.js 中最常见的物体就是网格,网格模型由顶点、面三角形面组成。在这个简单的三维模型中,我们利用 new THREE.BoxGeometry(1, 1, 1) 命令生成一个边长为 1 的立方体。材料是用 new THREE.MeshBasicMaterial({color: 0x00ff00}) 命令来生成的,而 new THREE.Mesh(geometry, material) 则生成了相应的网格。

    3、利用 Three.js 进行 BIM 轻量化的核心

    上一节我们已经基本了解了如何利用 Three.js 来显示三维模型。如果将代码 1 中的立方体替换为轻量化的建筑物模型,则就可以在浏览器中展示 BIM 模型了。接下来,将要着重介绍 Three.js 中模型的构建和解析方法。

    Three.js 有 2 种导入三维模型的方法。一种是导入 WebGL 支持的几何模型格式文件,另外一种是通过内部的构造函数手动从基础数据来创建三维场景。Three.js 原生支持很多种 3D 模型文件格式,例如 ply, stl, obj, vtk 等等。但是如果我们理解和掌握了 three.js 解析和加载模型文件的方法,我们可以自己写一种 3D 文件解析器,从这一角度来说,第二种方法应该是更为基础的方法。

    Three.js 中一般用 THREE.Mesh(geometry, material)来生成相应的网格模型,其中 geometry 是一个 THREE.Geometry 对象,它是一个包含顶点和顶点之间连接关系的对象;而 material 主要是定义材质,材质会影响光照、纹理对 mesh 的作用效果。THREE.Geometry 对象最重要的三个属性为顶点 (vertices),面(faces),法向量(normal)。顶点(vertex) 组成三角形面 (face),三角形组成一个个网格,而网格就组成了 3D 物体。法向量是垂直于平面的向量。一般一个三角面会有一个法向量,一个顶点由于属于不同的三角面,同一个顶点会有多个法向量。光照和法向量的夹角决定了平面反射出的光照强度,将法向量和入射光线向量做点积就能得到物体的反射光照强度。法向量(normal) 决定了每个顶点在光照下所呈现出的颜色,对于利用 webgl rendering 来更加真实的计算光线非常重要。所以构建三维模型主要就是确定模型的顶点,面和法向量信息,在这里我们主要关注几何信息,对于材质以后可以专门讨论。

    2013 年 6 月,Philippe Leefsma 实现了一个基于 Three.js 的 3D 模型查看器,能利用浏览器将包含建筑模型的指定格式的 JSON 文件渲染到网页上。随后,Jeremy Tammik 基于这个文件格式定义了 ADN Mesh Data(Autodesk Developer Network Mesh Data)。JSON 文件包含如下几个字段,FacetCount(面片数量)、VertexCount(顶点数量)、VertexCoords(顶点坐标)、VertexIndices(顶点索引,每三个点表示一个面)、Normals(法向量)、NormalIndices(法向量索引)、Center(中心点坐标)、Color(颜色)、Id(标识码)。其中 FacetCount 和 VertexCount 是可选的,Normals(法线)是顶点处的法线,几何模型仅支持三角形面片。为了更好的解释数据的形式,一个顶点为(0,0,0)(10,0,0) (0,10,0)和 (0,0,10) 的四面体根据上述的文件格式实现了一个 JSON 文件

    代码 2 四面体的文件表示

    一个基于Three.js的BIM轻量化引擎释读 - 图3

    由此可以看出,VertexCoords 数组中以三个为一组存储了四个顶点坐标。VertexIndices 中存储了各个面片的顶点编号。[0,2,1, 0,1,3, 0,3,2, 1,2,3]中以三个为一组,分别表示一个面(face)的三个顶点,比如[0,2,1]中表示的是点 1、3 和 2 创建而成的三角形面(注意从 0 开始计数,注意这三个点的顺序决定了面是面向还是背向摄像机的)。综合 Normals 和 NormalIndices,可以看出以三个为一组定义了四个向量,这是每个顶点的法向量。

    代码 3

    1. //Generate Faces

    2. for (var i = 0; i < vertexArray.length; i += 3) {

    3.

    1. geometry.vertices.push(vertexArray[i]);

    2. geometry.vertices.push(vertexArray[i + 1]);

    3. geometry.vertices.push(vertexArray[i + 2]);

    7.

    1. var face = new THREE.Face3(i, i + 1, i + 2)

    9.

    1. geometry.faces.push(face);

    1. face.vertexNormals.push(normalArray[i]);

    2. face.vertexNormals.push(normalArray[i + 1]);

    3. face.vertexNormals.push(normalArray[i + 2]);

    }

    上面的代码中,4、5、6 行代码在 vertices 数组中保存了构成几何体的顶点,第 8 行代码 new THREE.Faces3(i, i+1, i+2) 即为在 faces 数组中保存了由这些顶点连接起来创建的三角形(就是使用 vertices 数组中的点 i, 点 i+1, 点 i+2 创建而成的三角形)。有了这些点和面,第 10 行就依此建立了一个 THREE.Geometry 的实例对象。第 12、13、14 即为定义法线信息。通过这个过程,我们就给出一个几何模型的完整定义。如上的这些工作其实就相当于代码 1 中的第 24 行代码。

    4、Philippe Leefsma 的 3D 模型查看器介绍

    当生成 THREE.mesh 对象后,将其加入到场景中,就能显示出轻量化的建筑模型了。我们接下来赖解析 Philippe Leefsma 的 3D 模型查看器程序。程序主要由三个函数组成,initUI,initGL 和 animate。从字面意思可以看到,InitUI 主要进行界面初始化相关的工作,负责文件拖拽区和模型显示区的初始化,主要调用 onFileDragOVer, onFileDrop 和 handleDragOver 这三个函数,与我们三维显示模型不直接相关。Animate 则负责渲染相关的工作。整个程序最核心的程序就是 initGL,其所调用的 createScene 就包含了一个 3D 文件解析器,能解析 ADN Mesh Data 并生成相应的几何模型。

    一个基于Three.js的BIM轻量化引擎释读 - 图4

    5、结语

    轻量化平台的发展确实扩宽了 BIM 的应用范围,很重要的一点就是不依靠建模软件我们就可以随时随地的查看相应的模型信息。在二维绘图的 CAD 时代,在设计图完成后我们都会将图纸打印成不需要 autoCAD 就能查看的 PDF 版本,在实际施工等应用中我们则会将其打印成纸质版本。在 BIM 时代,三维模型无法在二维的纸质平面上显示,而且随着移动互联网的发展,电子屏幕投影设备基本上已经随处可见,建设单位、施工企业也大多开始配备平板电脑来查看模型。从这个角度来看,BIM 时代的电子屏幕和网络浏览器就相当于 CAD 时代的纸张(不同的屏幕大小相当于不同幅面的纸张)。类比于 PDF 格式,BIM 模型目前还没有出现一个比较统一的得到大范围支持的格式,在这方面还有很多工作可以做。

    (文中相关的代码可以后台找小编索取)

    参考文献

    [1] 袁亦周. 基于 Revit 的轻量级可视化转换引擎的研究. 湖北工业大学. 2018

    [2] https://blog.csdn.net/qq_31971935/article/details/50933513

    [3] http://hewebgl.com/article/getarticle/50

    [4] https://zhuanlan.zhihu.com/p/29474729

    [5] https://adndevblog.typepad.com/cloud_and_mobile/2013/06/3d-webgl-viewer-with-javascript-and-threejs.html

    [6] https://thebuildingcoder.typepad.com/blog/2013/07/adn-mesh-data-custom-exporter-to-json.html

    为了方便大家交流技术和互通行业资讯,

    请添加我们 “大菲儿” 微信,

    加入相关讨论交流群。

    一个基于Three.js的BIM轻量化引擎释读 - 图5

    一个基于Three.js的BIM轻量化引擎释读 - 图6

    往期回顾

    SAP2000 API 入门之写道虚功题

    Revit 做总体设计的初体验

    当轨交地铁盾构线穿越场地

    穹顶发展历史及经典案例赏析

    NSTurbo 开发回顾与展望

    一个基于Three.js的BIM轻量化引擎释读 - 图7
    https://mp.weixin.qq.com/s?src=11×tamp=1623594593&ver=3128&signature=1HqYAvLvFxdbt4xBbvz0wdEzvrXMgr41za61RIOQ6VcHbjaNP2YC7ryGvSJU9V6xLjyl0BIhg0AcpQljdm5W*buFvrKkOau5rijW74DPkesLB9X2DEbUjzsUgLKZIQ9c&new=1