BIM轻量化之路(五)-多文件加载及缓存
一、多文件加载
通过revit将很多专业文件合并成一个文件,稍微大点的文件合并的过程也会很痛苦,然后导出的GLTF文件很大threejs加载往往会内存溢出,一般来说一个文件大于50M,THREEJS就不好加载进来,往往会内存溢出,对于互联网上的加载,超过30M的文件加载用户体验及其差。所以需要对多文件进行分部加载,使用load多个文件加载至场景渲染。
部分代码:
CsscModelCore.prototype.loadGitfDraco = function(instance){let gLTFLoader = new THREE.GLTFLoader()let dracoLoader = new THREE.DRACOLoader();dracoLoader.setDecoderPath('/js/plugin/threejs/examples/js/libs/draco/gltf/');dracoLoader.setDecoderConfig({ type: 'js' });gLTFLoader.setDRACOLoader(dracoLoader);loadCsscModel(instance.settings.urls[0],instance.settings.urls,gLTFLoader,instance);
}
function loadCsscModel(url,urls,gLTFLoader,instance){let indexUrl = 0;for (let i = 0; i < urls.length; i++) {if(urls[i] == url){indexUrl = i;break;}}$('#loadding_total').html('总计:'+urls.length+"个文件,当前:"+indexUrl+".");gLTFLoader.load(url, function(obj) {obj.scene.rotateY(Math.PI);instance.scene.add(obj.scene);instance.setCenter(instance);if(indexUrl < urls.length -1){//递归加载文件loadCsscModel(urls[indexUrl+1],urls,gLTFLoader,instance);}else{instance.render();$('#loading').hide();}}, onProgress);
}
- 通过数组和递归将模型加载至场景
- 加载时可以增加遮罩提示用户加载进度
效果如下:

二、缓存的使用
1.threejs的cache
新版的threejs支持了缓存的机制,load的数据文件会存储在本地
Cache 的结构:
var Cache = {enabled: false,files: {},add: function ( key, file ) {if ( this.enabled === false ) { return; }// console.log( 'THREE.Cache', 'Adding key:', key );this.files[ key ] = file;},get: function ( key ) {if ( this.enabled === false ) { return; }// console.log( 'THREE.Cache', 'Checking key:', key );return this.files[ key ];},remove: function ( key ) {delete this.files[ key ];},clear: function () {this.files = {};}};
threejs在加载文件的时候会首先判断Cache中是否存在已加载的文件,如果已经加载直接从缓存中读取
代码片段(示例):
load: function ( url, onLoad, onProgress, onError ) {if ( url === undefined ) { url = ''; }if ( this.path !== undefined ) { url = this.path + url; }url = this.manager.resolveURL( url );var scope = this;var cached = Cache.get( url );//判断是否存在加载数据if ( cached !== undefined ) {scope.manager.itemStart( url );......
2.Cache与IndexedDB
每次刷新页面都会重新拉取模型文件,不能读取本地缓存,影响用户体验,所以需要将模型数据手动加载至浏览器缓存,对于比较大的数据存储在IndexedDB中是比较合适的,IndexedDB允许储存大量数据,能建立索引,这些都是 LocalStorage 所不具备的,更接近 NoSQL 数据库,可按照key,value的方式操作。
通过与threejs 的Cache结合,我们可以实现首次刷新页面从服务端拉取数据,再次刷新从IndexedDB获取模型数据,减少带宽的使用率,提高threejs加载速度。
代码片段:
function intThreejsCache(){let request = window.indexedDB.open("modelDB", 1);request.onupgradeneeded = (ev) => {modelDb = ev.target.result;if (!modelDb.objectStoreNames.contains('info')) {modelDb.createObjectStore('info');}console.log("数据库创建成功");}request.onsuccess = (ev) => {console.log("数据库打开成功");modelDb=ev.target.result;THREE.Cache.enabled = true;//开启缓存let transaction = modelDb.transaction(["info"], "readwrite");let objectStoreModelDB = transaction.objectStore("info");objectStoreModelDB.openCursor().onsuccess = function (event) {var cursor = event.target.result;if (cursor) {if(viewer.settings.urls.indexOf(cursor.key)>-1){console.log("indexdb加载模型:"+cursor.key);//将文件存入到threejs 的cache中THREE.Cache.add( cursor.key, cursor.value );}cursor.continue();}};transaction.oncomplete=function(event){viewer.Init();}}request.onerror = (ev) => {console.log("打开数据库失败:"+ev.target.message);}
}
- 每次刷新页面判断IndexedDB中是否存在需要加载的URL文件资源,可根据版本号、名称等判断是否为最新资源,存在则直接加载至cache中
- 每次load完模型后,将url的文件资源更新至IndexedDB中

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
