C#开发BIMFACE系列39 网页集成开发3:审图系统中三维模型比对
在建筑施工图审查系统中,设计单位提交设计完成的模型/图纸,审查专家审查模型/图纸。审查过程中如果发现不符合规范的地方,则流程退回到设计单位,设计单位人员根据审查意见重新调整设计,调整完成后再次提交到审查专家。此时为了便于专家审查,需要知道当前轮次的模型/图纸与上一轮次的模型/图纸发生了哪些异动,针对异动情况进行审查即可。
先看个效果

效果如上图。左侧是当前审查轮次的模型,中间是上一轮次的模型,右侧是2个模型的对比产生的异动列表。
(1)点击“新增构建”中的构件,自动定位到当前轮次中新增的目标构件。异动构件以浅绿色表示。2个模型视角同步移动。

(2)点击“删除构建”中的构件,自动定位到上一轮次中的目标构件,本轮次中的构件被删除,所以不显示。异动构件以浅绿色表示。2个模型视角同步移动。

(3)点击“修改构建”中的构件,自动定位到当前轮次中修改的构件以及上一轮次对应的构件。异动构件以浅绿色表示。2个模型视角同步移动。

BIMFACE之前是没有三维模型联动对比的功能,在我和BIMFACE的技术支持团队的美丽小姐姐沟通后,他们把我的要求纳入了他们产品的需求,经过工程师们加班加点的辛苦付出,很快就实现了该功能。特此感谢BIMFACE团队的所有小伙伴,感谢你们对开发者的信任与接受,感谢你们的辛苦付出。
滴水之恩,当涌泉相报,奉献上个人的BIMFace C#版SDK开源项目。
开源地址:https://gitee.com/NAlps/BIMFace.SDK
作者:张传宁 QQ:905442693 微信:savionzhang
欢迎下载使用,交流、分享。
下面介绍BIMFACE模型对比功能的原理与实现。
模型对比可以对两个文件/模型进行差异性分析,确定两个文件/模型之间构件的几何和属性差异,包括增加的构件、删除的构件和修改的构件。 模型对应可以用于进行文件/模型的版本对比。
特别说明:模型对比是在BIMFACE云端进行的,通常需要5~10分钟。当模型对比完成后,BIMFACE能通知对比结果。
- 您需要将修改前和修改后的模型上传到云端并转换成功以后才能发起模型对比;
- 目前仅支持.rvt单文件的模型对比。
- 通过服务端API发起模型对比(对比前后模型文件的fileId);
- 等待云端对比任务执行;
- 对比完成后,在网页端通过调用JavaScript API实现差异模型的显示;
- 除了显示差异模型,还需要调用服务端API获取对比结果(包括新增、删除、修改的构件列表)。
模型文件经过云端转换后,生成了BIMFACE定义的数据包。因此,要对比两个模型文件,实际上需要对比两个文件的数据包。如下图所示,文件B是文件A修改后的版本,对比完成之后,其结果包括两个部分:
- 几何差异;
- 变更构件及属性。

BIMFACE提供了服务端API,用于发起对比,获取对比状态、获取对比结果。请参考我的博客:
调用服务器端的API获取对比结果后,前端需要使用JS来实现同步联动效果,以及点击异动构件后自动定位到构件所在的视角。
// 同步新旧模型的平移和旋转操作
function correspond() {
latestViewer = latest.getViewer();
var state, focus; prevViewer = prev.getViewer();
view1Bind = function (data) {
//用新模型的状态更新旧模型状态
var latestState = latestViewer.getCurrentState();
prev.setState(latestState);
prev.getViewer().camera.up.copy(latestViewer.getViewer().camera.up);
} view2Bind = function (data) {
//用旧模型的状态更新新模型状态
var prevState = prev.getCurrentState();
latestViewer.setState(prevState);
latestViewer.getViewer().camera.up.copy(prev.getViewer().camera.up);
} //考虑到死循环的影响,不能同时监听render事件,因此以鼠标所在位置模型的监听为主
document.querySelector('#container').addEventListener('mousemove',
function (e) {
if (focus == undefined) {
var width = document.querySelector('.latest').offsetWidth;
if (e.clientX > width) {
focus = 1;
latestViewer.removeEventListener('Rendered', view1Bind);
prev.addEventListener('Rendered', view2Bind);
} else {
focus = 0;
prev.removeEventListener('Rendered', view2Bind);
latestViewer.addEventListener('Rendered', view1Bind);
}
}
}); view1.addEventListener('mouseover',
function (e) {
if (focus == 0) {
return;
}
focus = 0;
// 解绑与重新绑定事件,同步新旧模型的Rendered
prev.removeEventListener('Rendered', view2Bind);
latestViewer.addEventListener('Rendered', view1Bind);
}); view2.addEventListener('mouseover',
function () {
if (focus == 1) {
return;
}
focus = 1;
// 解绑与重新绑定事件,同步新旧模型的Rendered
latestViewer.removeEventListener('Rendered', view1Bind);
prev.addEventListener('Rendered', view2Bind);
}); // 同步新旧模型的Hover事件
prev.addEventListener('ComponentsHoverChanged',
function (e) {
latestViewer.getViewer().modelManager.sceneState.setHoverId(e.objectId);
}); latestViewer.addEventListener('ComponentsHoverChanged',
function (e) {
prev.getViewer().modelManager.sceneState.setHoverId(e.objectId);
}); var ViewerEvent = Glodon.Bimface.Viewer.Viewer3D;
latestViewer.setCameraAnimation(false);
prev.setCameraAnimation(false);
}
//创建异动列表与构件的click事件
function createDom(result) {
// 设置构件差异构件树的UI
var newItems = result.newItems,
deleteItems = result.deleteItems,
changeItems = result.changeItems;
var typeBoxs = document.querySelectorAll('.type-box');
typeBoxs[0].innerHTML =
`<div class="title"><i class="icon arrow"></i><i class="icon-type new"></i>新增构件(${newItems.length})</div>
<ul id="addElement" class="type-ul">${createDomNode(newItems)}</ul>`; // 删除构件列表
typeBoxs[1].innerHTML =
`<div class="title"><i class="icon arrow"></i><i class="icon-type remove"></i>删除构件(${deleteItems.length})</div>
<ul id="removeElement" class="type-ul">${createDomNode(deleteItems)}</ul>`; // 修改构件列表
typeBoxs[2].innerHTML =
`<div class="title"><i class="icon arrow"></i><i class="icon-type revise"></i>修改构件(${changeItems.length})</div>
<ul id="reviseElement" class="type-ul">${createDomNode(changeItems)}</ul>`; // 差异构件树列表
document.querySelector('.compare-content').addEventListener('click',
function (e) {
var element = e.target;
if (element.tagName == 'I' && element.hasClass('arrow')) {
if (element.hasClass('close')) {
element.removeClass('close');
element.parentElement.nextElementSibling.removeClass('close');
} else {
element.addClass('close');
element.parentElement.nextElementSibling.addClass('close');
}
} else if (element.tagName == 'SPAN' && element.getAttribute('type')) {
var type = element.getAttribute('type'),
id = element.parentElement.getAttribute('data-oid');
if (type == 'NEW') {
latestViewer.setSelectedComponentsById([id]);// 高亮选中构件
latestViewer.zoomToSelectedComponents(); // 定位
view1Bind();
} else if (type == 'DELETE') {
prev.setSelectedComponentsById([id]);// 高亮选中构件
prev.zoomToSelectedComponents(); // 定位
view2Bind();
} else {
latestViewer.setSelectedComponentsById([id]); // 高亮选中构件
latestViewer.zoomToSelectedComponents();// 定位;
view1Bind();
prev.setSelectedComponentsById([id]);
}
}
});
}
C#开发BIMFACE系列39 网页集成开发3:审图系统中三维模型比对的更多相关文章
- C#开发BIMFACE系列37 网页集成开发1:审图系统中加载模型或图纸
系列目录 [已更新最新开发文章,点击查看详细] 在之前的<C#开发BIMFACE系列>中主要介绍了BIMFACE平台提供的服务端API接口的封装开发与测试过程. 服务端API测试通 ...
- C#开发BIMFACE系列38 网页集成开发2:审图系统中的模型或图纸批注
系列目录 [已更新最新开发文章,点击查看详细] 在运维或协同的场景中,经常需要对模型或图纸进行批注,及时记录已发现的问题并交给相关负责的人员. 在开始实现功能之前,先了解一下BIMFACE中有 ...
- C#开发BIMFACE系列2 二次开发流程
系列目录 [已更新最新开发文章,点击查看详细] BIMFACE 平台是一个对外开放的平台,建筑行业的相关公司.软件公司或者有 BIM 业务需求的公司都可以注册成为开发者并使用其提供的强大功能. ...
- C#开发BIMFACE系列49 Web网页中加载模型与图纸的技术方案
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在BIMFACE二次系列博客中详细介绍了服务器端API的调用方式,如下列表 C#开发BIMFACE系列1 BIMFAC ...
- C# 开发 BIMFACE 系列
本系列文章主要介绍使用 C# .ASP.NET(MVC)技术对 BIMFace 平台进行二次开发,以满足本公司针对建筑行业施工图审查系统的业务需求,例如图纸模型(PDF 文件.二维 CAD 模型.三维 ...
- C#开发BIMFACE系列50 Web网页中使用jQuery加载模型与图纸
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在前一篇博客<C#开发BIMFACE系列49 Web网页集成BIMFACE应用的技术方案>中介绍了目前市场主流 ...
- C#开发BIMFACE系列40 服务端API之模型集成
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 随着建筑信息化模型技术的发展,越来越多的人选择在云端浏览建筑模型.现阶段的云端模型浏览大多是基于文件级别,一次只可以浏览一 ...
- C#开发BIMFACE系列52 CS客户端集成BIMFACE应用的技术方案
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在我的博客<C#开发BIMFACE系列49 Web网页集成BIMFACE应用的技术方案>.<C#开发BI ...
- C#开发BIMFACE系列46 服务端API之离线数据包下载及结构详解
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在前一篇博客<C#开发BIMFACE系列45 服务端API之创建离线数据包>中通过调用接口成功的创建一个离线数 ...
随机推荐
- Worktile正式入驻飞书,助力企业轻松实现敏捷开发与协作
企业在敏捷研发中时常面临着交付延期.需求不匹配等问题,如何更高效地完成敏捷研发? Worktile携手飞书,为企业用户提供敏捷开发服务,帮助企业实现软件项目的需求管理.缺陷追踪.迭代规划与推进以及效能 ...
- 使用Docsify做文档网站的详细配置教程
使用Docsify做文档网站的详细配置教程 作者:xhemj 没错,它叫Docsify. xhemj的文档中心就是用这个写的 开源地址:https://github.com/docsifyjs/doc ...
- PyTorch大更新!谷歌出手帮助开发,正式支持TensorBoard | 附5大开源项目
大家又少了一个用TensorFlow的理由. 在一年一度的开发者大会F8上,Facebook放出PyTorch的1.1版本,直指TensorFlow"腹地". 不仅宣布支持Tens ...
- 工作日志,Excel导入树结构数据
目录 1. 前言 2. 需求分析 2.1 需求难点 2.2 解决难点 2.3 表格设计 3. 功能实现 3.1 一个分枝 3.2 一个分枝多个树叶 3.3 多个分枝多个树叶 4. 代码事例 4.1 目 ...
- unix中数据缓冲区高速缓冲的设计
目录 1. 概述 2. 缓冲区的设计 2.1 缓冲区头部 2.2 缓冲区的结构 2.3 缓冲区的检索算法 2.3. 申请一个缓冲区算法 getblk 2.3.2 释放一个缓冲区算法 brelse 2. ...
- 如何理解EventLoop--浏览器篇
前言 最近在准备春招,刷到了JS中的主要运行机制--Event Loop,觉得它的实现思路有必要整理一下,以防忘记.关于它在浏览器上的实现,我结合了自己的理解以及示例代码,想用最通俗的语言表达出来.如 ...
- windows Sever 2012 远程提示:由于没有远程桌面授权服务器可以提供许可证,远程会话被中断。请跟服务器管理员联系。
远程windows Sever 2012 时候 远程提示:由于没有远程桌面授权服务器可以提供许可证,远程会话被中断.请跟服务器管理员联系. 原因: windows server可以多用户同时登陆,默认 ...
- spring-cloud-gateway降级
前言 本文主要研究一下 spring cloud gateway 如何集成 hystrix. 当下游接口负载很大,或者接口不通等其他原因导致超时,如果接口不熔断的话将会影响到下游接口得不到喘息,网关也 ...
- 在函数中修改全局变量的值,需要加global关键字
一.引用 使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关键字.如: #! /usr/bin/python a = 1 b = [2, 3] def func(): if ...
- Python学习笔记:迭代器(Iterator)详解
一.可迭代的对象(Iterable) 1.定义:可以直接用在循环的数据类型,如list,tuple,dict,set,str,还有generator(生成器), 和带yield的函数,这些直接可以用在 ...