Autodesk Forge可以将轻量化之后的模型显示在电脑浏览器,并且可以读取模型数据,进行其他更发杂的操作。本人接触不久,本文简单谈谈自己的一些理解。
(至于模型是如何轻量化的,可以直接在Autodesk Forge官网注册一个账号了解了解,官网介绍很详细https://forge.autodesk.com/developer/getting-started,此处不作重点)
模型轻量化之后,轻量化目录中的3d.svf文件是轻量化模型的入口文件,也是我们即将直接用到的文件,至于轻量化之后的文件中具体存些什么,本人没有做过了解,相信如果从事过Revit之类软件建模工作的朋友应该会比较清楚这个。从Autodesk Forge api官网https://forge.autodesk.com/en/docs/viewer/v6/reference/javascript可以看到有很多javascript api,里边有很多函数,我们能做的,就是通过轻量化模型的路径,调用这些api中的函数,在浏览器显示模型,并且获取和操作模型属性等数据。大概过程就是这样。
嗯,不啰嗦了。本文用到的js主要有viewer3D.js以及three.js,后者是前者的依赖,主要用到的官网文档中的Core部分的Model和Viewer3D目录下的一些api。
模型加载主要分两步,构造viewer3D容器,调用初始化方法。
var config = {
extensions: [
"Autodesk.Viewing.ZoomWindow"
],
disabledExtensions: {
measure: false,
section: false,
}
};
var element = document.getElementById('viewer-local');
var viewer = new Autodesk.Viewing.Private.GuiViewer3D(element, config);
从以上代码可以看出,构造容器的方法需要html元素id和配置两个参数,官网给出的配置中只有一个startOnInitialize选项,此处添加扩展ZoomWindow,此扩展的介绍https://forge.autodesk.com/blog/custom-window-selection-forge-viewer-part-i
var options = {
docid: path,
env: 'Local',
offline: 'true',
useADP: false
};
Autodesk.Viewing.Initializer(options, function () {
//viewer.initialize();
viewer.start();
viewer.load(options.docid, undefined, onLoadSuccess, onLoadError);
viewer.addEventListener("selection", function (event) {
Inquiry();
});
});
其中options中的docid对应的是3d.svf文件的绝对路径
在初始化方法中,
viewer.addEventListener("selection", function (event) {
Inquiry();
});
即是设置选中部件时执行的事件。单击事件中的一些常用操作:
viewer.getSelection()
获取构件的id,此id为页面端id,js代码中进行选中,变色等 操作都需要它。
指定id构件变色的方法:
var color = new THREE.Vector4(rgbs[0], rgbs[1], rgbs[2], 1);
viewer.setThemingColor(id, color);
color构造函数中的四个参数分别为三原色(用0到1之间的数表示)+透明度。
viewer.model.getData()方法能获取到包含模型所有数据的对象,浏览器console.log打印结果如下
可以看到其中包含模型路径,模型构件id等信息,其中instanceTree中包含模型的各类id,模型属性,在开发中会较多涉及。
下面的代码作用是在模型加载完成后将数据库id和前台使用的id对应起来。本人开发中遇到这一问题,数据库中存有构件id,但是和前台选中和变色的id不是同一id,因此需要在模型页面将二者对应上,数据库dbid在构件属性中有体现。此功能可能不具有通用性,但是过程中用到的一些函数也是比较常用的。
function onLoadSuccess(event) {
console.log('success');
//debugger;
console.log(viewer.model.getData());
//onloadsuccess执行时tree还未加载完成
viewer.getObjectTree(function success() {
instanceTree = viewer.model.getData().instanceTree;
selectionMap = instanceTree.nodeAccess.dbIdToIndex; //前台selectionid
for (var key in selectionMap) {
viewer.getProperties(selectionMap[key], function (objProp) {
var goujianname = objProp.name;
//工艺_设备_45561 [3315978]
//获取中括号中的后台id
//debugger;
var start = goujianname.indexOf("[");
var end = goujianname.indexOf("]");
if (start != undefined) {
var componentId = goujianname.substring(start + 1, end);
dbid_selMap[componentId]= objProp.dbId;
}
})
}
console.log("tree loaded");
}, function fail() {
alert("tree error");
})
}
大致思路如下,首先是获取instanceTree.nodeAccess.dbIdToIndex集合,此集合中存的是前台用于显示和变色的id(以下称作seletionid),然后遍历此集合,通过getProperties方法获取到构件的属性对象,属性对象中存有数据库中存储的构件id(以下称作dbid),此处是通过截取name属性字符串获取到的。将selectionid和dbid放入map中对应起来,后期要实现二者转换就方便了,可以实现模型和其他构件数据之间的关联。
此处还有一点需要注意,getObjectTree方法。onLoadSuccess是模型加载完成,但是此时instanceTree并没有值,如果直接获取,将得到undefined,此处只能在getObjectTree方法的success回调函数中来获取。