前言
前两年BIM模型在建筑领域如火如荼的展开,前端不可避免的遇见了一些挑战,具体为可视化和3D展示,还有一些多到爆炸的数据展示,最近项目做了一些BIM模型,有一些心得体会
前端使用的框架
Vue3+pinia+ts
前端基础概念
-
在建筑模型领域,免不了需要和Revit打交道,很多都是对Revit的二次开发,我使用的是xbim/viewer插件,桌面端有插件转换成xbim插件可以识别的模型文件,由桌面端上传文件经由插件转换后上传服务端可由前端进行展示
-
构件 比如一根柱子,一个地板,每个房间元素,包括管道,都可以成为一个构件 xbim
竞品插件浅析
-
github上star最多的是xeogl,所有的功能,包括剖切,聚焦,等等所有功能它都全部做了封装,为什么我们还是选择了其他的开源架构呢,根据数据来看,模型一多,真的卡到爆,一种情况是gpu不够烧,第二种他的算法不够理想,加载很多个BIM模型会出现移动时模型会变形的情况,第三种则是由于xeogl暴露的功能其实不够底层,不好去二次开发,根据技术调研我们采取了另外一个国外开源库xbim,当然,有部分是收钱的,但是基于业务而言其实够用了
-
xbim已经将功能全部暴露出来,如果想使用相对应的BIM模型操作功能,需要自己二次封装,由于公司处于实验阶段,目前针对市面上成熟的例如广联达BIMAPI等,也在考虑阶段,所以开源插件的接口都需要经过一层转换,转换成自己的接口,方便以后切换第三方开源框架
功能浅析
功能快照BCF
BIM模型一般会在设计协同阶段,施工管理阶段进行使用,简单的说就是对出问题的建筑模型位置拍照=>这种操作在国际协议里称之为BCF,按照规定的JSON格式导出格式,并将bast64格式的照片上传
- 拍摄位置上传后,下次点选出问题的图片,可以调用API对模型进行问题复位,更快的发现,记录问题,一般来说,具体问题可能会出现在具体构件上,想要在浩瀚的构件列表找到,需要用一个唯一ID规定,也可以与后端定一个好一个唯一ID
Viewpoint.GetViewpoint(instance, (id: number, model: number) => {
const info = this.models.find(item => item.model === model)
const ID = this.getTreeInfo[`${info.tag}`].map[`${id}`].IFCID
return `${ID}`
})
模型剖析
- 需要对3D模型进行剖面,在6个面对模型进行剖析,需要获取整体6个面,类似于一个长方体的xyz位置 剖面其实是一个等比例缩放的意思,比如把整体面的上面部分初始化为100%,然后缩放成60%
单选构件或者多选构件
- 需要对整体模型进行类封装,将状态封起来,也可以防止内存泄漏当然也可以直接用pinia 直接做成一个仓库,笔者后面有空会写一个demo出来
还有很多功能。。。
性能把控
- 3D模型加载并无难度,比如可以使用异步,减缓等待时间,重点是移动时的渲染问题,如果那台机没有显卡,那可是苦了程序员
关于GPU爆了的解决方案
如何发现自己的GPU爆了?
- windows 电脑打开管理器,移动模型,查看
ps:我的小水管只有一个1050的显卡,没优化之前移动加载10个的模型,直接爆了
- 苹果直接上活动监视器,俺这个刚买的M1 怎么样都没爆。。。咳咳咳
解决方案
- 需要桌面端配合,他们可以在Revit上标记,在多模型的状态下,哪些是表面模型,哪些是嵌套在里面模型的,比如管道模型,当页面移动时,如果加载的模型中,存在管道模型,或者其他内部模型,则隐藏,保留最外层的模型文件,由于移动的时候渲染相对频繁,记得加上一些前置条件,避免反复触发
关于字典
- 涉及到大量数据,数组太多,不能反复map,find,或者filter,不然黄花菜都凉了,最好的莫过于前端做obj,一般来说匹配模型的versionId,modelId,compId就能匹配到对应版本模型下的构件信息,不用反复去循环
关于内存泄漏和适时的卸载模型数据
- 此处可以借鉴Vue3的手法,使用WeakMap做缓冲,Set做唯一,卸载模型的时候,保证数据全部收回
关于30w的模型长啥样
关于项目demo
。。。后续有时间补充