2017-10-09 41 views
0

我有个问题与查看器自动地改变材料为默认

当几何加载一些元件的材料的变化:

_this.viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT,() => { 
    changeModelMaterial() 
}); 

... 

const changeModelMaterial =() => { 
    const grey = new THREE.Color(0.5, 0.5, 0.5); 
    let dbIds = getDbIds() 
    changeAllElementsMaterial(grey) 
    setMaterialOfDbIds(dbIds) 
} 

代码I`M使用改变材料:

const changeAllElementsMaterial = (color) => { 
    const fragmentList = _this.viewer.model.getFragmentList(); 
    for (let materialId of fragmentList.materialids) { 
     if (fragmentList.materialmap[materialId]) { 
      fragmentList.materialmap[materialId].map = null 
      fragmentList.materialmap[materialId].color = color 
      fragmentList.materialmap[materialId].needsUpdate = true; 
     } 
    } 
    _this.viewer.impl.invalidate(true); 
} 

const setMaterialOfDbIds = (dbIds) => { 
    var color_diffuse = 0xAB00EE; 
    var color_specular = 0xEEABEE; 
    var colorM = new THREE.MeshPhongMaterial({ 
     color: color_diffuse, 
     specular: color_specular 
    }); 
    _this.viewer.impl.matman().addMaterial(
     'ADN-Material-' + 
     "common color material", // or a GUID 
     colorM, 
     true); 

    for (let dbId of dbIds) { 
     _this.viewer.model.getData().instanceTree.enumNodeFragments(dbId, function (fragId) { 
      _this.viewer.model.getFragmentList().setMaterial(fragId, colorM); 

     }); 
    } 
    _this.viewer.impl.invalidate(true); 
} 

它的工作原理是因为我看到模型的材质发生了变化,但问题是材料在1-2秒后回到默认状态。

之后,即使手动运行此代码,我也无法更改材料。

问题是,为什么查看器锁定这个2秒后发生重大变化,如何防止它

,也许你会能告诉我,我可以用材料的变化做的更好,例如。也许更好的是在GEOMETRY_LOAD之后运行我的代码。最好是变材料之前,首先绘制模型

的........

提示:

当从GEOMETRY_LOADED_EVENT变化事件OBJECT_TREE_CREATED_EVENT“有时”,但只是有时它工作得很好(材料停留在使用模型的工作结束时),但大多数情况下,当我在OBJECT_TREE_CREATED之后运行我的方法时,它无法工作(即使没有通过手动运行,材料以某种方式锁定也无法工作)。所以我怀疑问题是GEOMETRY_LOAD的时间和OBJECT_TREE_CREATED之间

我会任何帮助

感谢======================= =======完整的代码==============================

的index.html

<div id="main"> 
    <div id="MyViewerDiv"></div> 
    <button id="open-nav-button" onClick="showDocInfo()">test</button> 
</div> 
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/three.min.js"></script> 
<script src="https://developer.api.autodesk.com/derivativeservice/v2/viewers/viewer3D.min.js"></script> 

<script type="text/javascript" src="lib/jquery.min.js"></script> 

<script src="js/autodesk-viewer.js"></script> 
<script src="js/extension/test-extension.js"></script> 

<script> 
    const autodeskViewer = new AutodeskViewer() 
    const showDocInfo =() => { 
     autodeskViewer.showDocInfo() 
    } 
</script> 

欧特克-viewer.js

var AutodeskViewer = (function() { 
function AutodeskViewer() { 
    var _this = this; 
    this.urn = 'urn:dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6Zm9yZ2UtamF2YS1zYW1wbGUtYXBwLTFzcGduazdqcWpxdjhmYXV0YmNzd2R0cGdvN3VtNWY1L1BPQy1Gb3JnZS1JVCUyMDIwMTclMjBSdWNoXzEwMDUxNy5ud2Q'; 

    this.initializeViewer = function (containerId, documentId) { 
     _this.viewerApp = new Autodesk.Viewing.ViewingApplication(containerId); 
     var config = { 
      extensions: ['TestExtension'] 
     }; 
     _this.viewerApp.registerViewer(_this.viewerApp.k3D, Autodesk.Viewing.Private.GuiViewer3D, config); 
     _this.viewerApp.loadDocument(documentId, _this.onDocumentLoadSuccess, _this.onDocumentLoadFailure); 
    } 

    this.onDocumentLoadSuccess = function (doc) { 
     const viewables = _this.viewerApp.bubble.search(av.BubbleNode.MODEL_NODE); 
     if (viewables.length === 0) { 
      return; 
     } 
     _this.viewerApp.selectItem(viewables[0].data, _this.onItemLoadSuccess, _this.onItemLoadFail); 
     _this.viewer3d = _this.viewerApp.getCurrentViewer(); 
    } 

    this.onDocumentLoadFailure = (viewerErrorCode) => {} 

    this.onItemLoadSuccess = (viewer) => { 
     _this.viewer = viewer 
    } 

    this.onItemLoadFail = (errorCode) => {} 

    this.initialize =() => { 
     var options = { 
      env: 'AutodeskProduction', 
      getAccessToken: _this.getToken, 
      refreshToken: _this.getToken 
     }; 
     Autodesk.Viewing.Initializer(options, _this.initCallback); 
    }; 

    this.initCallback = function() { 
     _this.initializeViewer('MyViewerDiv', _this.urn, '3d'); 
    }; 
    this.getToken = function (onGetAccessToken) { 
     $.get("forge/oauth/token") 
      .done(function (data) { 
       token = data 
       onGetAccessToken(token, 60 * 60); 
      }) 
      .fail(function (error) { 
       console.log('ERROR', error); 
      }); 
    }; 

    this.showDocInfo = function() {}; 
    this.initialize(); 
} 

return AutodeskViewer; 
}()); 

试验extension.js

var _self; 
var _viewer; 
var _tempValue = 0; 

function TestExtension(viewer, options) { 
    Autodesk.Viewing.Extension.call(this, viewer, options); 
    _self = this; 
    _viewer = viewer; 
} 

const changeModelMaterial =() => { 
    // _tempValue++; 
    // if (_tempValue == 2) { 
    const elements = [4340, 4342, 4344, 4346, 4348, 4367, 4371, 4375, 4380, 4452, 4468, 4488, 4503, 4517, 4520, 4522, 4524, 4526, 4528, 4530] 

    changeAllElementsMaterial(new THREE.Color(0.5, 0.5, 0.5)) 
    setMaterialOfDbIds(elements) 
    _tempValue = 0 
    // } 
} 

const changeAllElementsMaterial = (color) => { 
    var fragmentList = _viewer.model.getFragmentList(); 
    for (let materialId of fragmentList.materialids) { 
     if (fragmentList.materialmap[materialId]) { 
      fragmentList.materialmap[materialId].map = null 
      fragmentList.materialmap[materialId].color = color 
      fragmentList.materialmap[materialId].needsUpdate = true; 
     } 
    } 
    _viewer.impl.invalidate(true); 
} 

const setMaterialOfDbIds = (dbIds) => { 
    var colorM = new THREE.MeshPhongMaterial({ 
     color: new THREE.Color(0xAB00EE) 
    }); 

    for (let dbId of dbIds) { 
     _viewer.model.getData().instanceTree.enumNodeFragments(dbId, function (fragId) { 
      _viewer.model.getFragmentList().setMaterial(fragId, colorM); 

     }); 
    } 
    _viewer.impl.invalidate(true); 
} 

TestExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype); 
TestExtension.prototype.constructor = TestExtension; 

TestExtension.prototype.load = function() { 
    _viewer.addEventListener(Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT, changeModelMaterial) 
    // _viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, changeModelMaterial) 
    return true 
}; 

TestExtension.prototype.unload = function() { 
    return true 
}; 

Autodesk.Viewing.theExtensionManager.registerExtension('TestExtension', TestExtension); 

回答

0

我找到了解决办法,很意外......其他的事我试着做

前:

const setMaterialOfDbIds = (dbIds) => { 
     var color_diffuse = 0xAB00EE; 
     var color_specular = 0xEEABEE; 
     var colorM = new THREE.MeshPhongMaterial({ 
      color: color_diffuse, 
      specular: color_specular 
     }); 
     _this.viewer.impl.matman().addMaterial("common color material", colorM, true); 

     for (let dbId of dbIds) { 
      _this.viewer.model.getData().instanceTree.enumNodeFragments(dbId, function (fragId) { 
       _this.viewer.model.getFragmentList().setMaterial(fragId, colorM); 
      }); 
     } 
     _this.viewer.impl.invalidate(true); 
    } 

const setMaterialOfDbIds = (dbIds) => { 
     var color_diffuse = 0xAB00EE; 
     var color_specular = 0xEEABEE; 
     var colorM = new THREE.MeshPhongMaterial({ 
      color: color_diffuse, 
      specular: color_specular 
     }); 
     _this.viewer.impl.matman().addMaterial("common color material", colorM, true); 

     for (let dbId of dbIds) { 
      _this.viewer.model.getData().instanceTree.enumNodeFragments(dbId, function (fragId) { 
       _this.viewer.model.getFragmentList().setMaterial(fragId, colorM); 
       var fragProxy = _this.viewer.impl.getFragmentProxy(_this.viewer.model, fragId) 
       fragProxy.updateAnimTransform() 
      }); 
     } 
     _this.viewer.impl.invalidate(true); 
    } 

真的我不知道为什么加入

var fragProxy = _this.viewer.impl.getFragmentProxy(_this.viewer.model, fragId) 
fragProxy.updateAnimTransform() 

做出了改变,我没有看到任何更新材料的例子。 有趣的是,这段代码仅仅为模型中的几个元素运行,但它甚至适用于那些材质之前改变过的元素(在changeAllElementsMaterial方法中)。

@Philippe Leefsma如果你明白了请告诉更多的东西,为什么它的工作原理

0

到目前为止,我无法重现我这边的问题,我使用从扩展提取下面的代码(ES7):Viewing.Extension.Material

createColorMaterial (color) { 

    const material = new THREE.MeshPhongMaterial({ 
    specular: new THREE.Color(color), 
    side: THREE.DoubleSide, 
    reflectivity: 0.0, 
    color 
    }) 

    const materials = this.viewer.impl.getMaterials() 

    materials.addMaterial(
    this.guid(), 
    material, 
    true) 

    return material 
} 

async onModelCompletedLoad() { 

    const material = this.createColorMaterial(0xFF0000) 

    const model = this.viewer.model 

    const fragIds = await Toolkit.getFragIds(model) 

    fragIds.forEach((fragId) => { 

    model.getFragmentList().setMaterial(
     fragId, material) 
    }) 

    this.viewer.impl.sceneUpdated(true) 
} 

onModelCompletedLoad是当GEOMETRY_LOADED_EVENTOBJECT_TREE_CREATED_EVENT已被解雇时自定义事件启动。

看看这篇文章了解详情:Asynchronous viewer events notification

我怀疑你可以很容易地改变材料首先呈现的模型之前,但是你可以使用隐藏模式,直到您的定制逻辑有一个自定义叠加完成所有必需的步骤,这是我用我的演示的方法:https://forge-rcdb.autodesk.io/configurator

加载模型之后,所有的自定义材料被罚款坚持:

enter image description here

材料扩展可以从there进行实时测试。

希望帮助

+0

好了,现在我真的做我的东西后两个事件(OBJECT_TREE_CREATED_EVENT和GEOMETRY_LOADED_EVENT)被解雇,而这一变化仍具有相同的行为。 我认为首先我必须找出为什么材料只能在2-3秒内改变 –

+0

如果您可以提供可重现的样品,我会看看。你有没有尝试我的材料演示?肯定在那里工作得很好,所以你一定是做错了什么......你也可以看看viewer.setThemingColor:https://stackoverflow.com/questions/38534862/autodesk-forge-viewer-does-viewer-setthemingcolor- work-on-a-converted-dwg-file –

+0

我更新了我的问题,现在您可以看到所有使用的代码,您可以自己尝试。现在,当扩展将加载为OBJECT_TREE_CREATED_EVENT添加事件侦听器。所以我想要做的只是有时候。当你从加载方法中取消其他监听器的注释并从changeModelMaterial方法中取消简单的窍门时,你应该看到材料被更新,然后〜2秒后恢复为默认值。 –