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)。场景是一个容器,主要用于保存、跟踪所要渲染的物体(如苹果、葡萄)和使用的光源。摄像机的作用就是面对场景,在场景中取一个合适的景,把它拍下来,它决定了能在场景中看到什么。渲染器对象会基于摄像机的角度来计算场景对象在浏览器中会渲染成什么样子。他们三者的关系如下图所示:
代码1,一个简单的Three.js示例代码
1. <!DOCTYPEhtml>
2. <scripttype=”text/javascript”src=”./js/three73.js”></script>
3. <html>
4. <head>
5. <title>MyfirstThree.jsapp</title>
6. <style>
7. body{margin:0;}
8. canvas{width:100%;height:100%}
9. </style>
10. </head>
11. <body>
12. <script>
13. varscene=newTHREE.Scene();//场景
14.
15. varcamera=newTHREE.PerspectiveCamera(75,
16. window.innerWidth/window.innerHeight,0.1,1000);//摄像机
17. camera.position.z=5;
18.
19. varrenderer=newTHREE.WebGLRenderer();//渲染器
20. renderer.setSize(window.innerWidth,window.innerHeight);
21. document.body.appendChild(renderer.domElement);
22.
23. //建立几何模型
24. vargeometry=newTHREE.BoxGeometry(1,1,1);
25. varmaterial=newTHREE.MeshBasicMaterial({color:0x00ff00});
26. varcube=newTHREE.Mesh(geometry,material);
27. scene.add(cube);
28.
29. //渲染
30. varrender=function(){
31. requestAnimationFrame(render);
32.
33. cube.rotation.x+=0.1;
34. cube.rotation.y+=0.1;
35.
36. renderer.render(scene,camera);
37. };
38. render();
39. </script>
40. </body>
41. </html>
代码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 四面体的文件表示
由此可以看出,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. //GenerateFaces
2. for(vari=0;i<vertexArray.length;i+=3){
3.
4. geometry.vertices.push(vertexArray[i]);
5. geometry.vertices.push(vertexArray[i+1]);
6. geometry.vertices.push(vertexArray[i+2]);
7.
8. varface=newTHREE.Face3(i,i+1,i+2)
9.
10. geometry.faces.push(face);
11.
12. face.vertexNormals.push(normalArray[i]);
13. face.vertexNormals.push(normalArray[i+1]);
14. 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并生成相应的几何模型。
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
为了方便大家交流技术和互通行业资讯,
请添加我们“转自:非解构-公众号”微信,
加入相关讨论交流群。