2017-10-09 5 views
0

J'ai un problème avec les changements de matériel de certains élémentsViewer passe automatiquement par défaut matériel

lorsque la géométrie est chargée:

Code
_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) 
} 

que I`M utilisant pour changer le matériau:

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); 
} 

Cela fonctionne, parce que je vois que les matériaux du modèle sont changés, mais le problème est que les matériaux reviennent au défaut après ~ 1-2 sec. Après cela, je ne peux pas changer de matériau même avec l'exécution manuelle de ce code.

La question est pourquoi Viewer est de verrouillage changement important après 2 sec, comment empêcher

Et peut-être vous serez en mesure de me dire ce que je peux faire mieux avec des changements importants, par exemple. peut-être quelque chose de mieux que l'exécution de mon code après GEOMETRY_LOAD. Le mieux serait de changement avant le premier rendu du modèle

........

indice:

lorsque l'événement de changement de GEOMETRY_LOADED_EVENT à OBJECT_TREE_CREATED_EVENT « parfois », mais seulement parfois il fonctionne bien (les matériaux restent à la fin de travailler avec le modèle), mais surtout quand j'exécute ma méthode après que OBJECT_TREE_CREATED ne fonctionne pas (même en ne fonctionnant pas en l'exécutant manuellement, les matériaux sont en quelque sorte verrouillés). Donc, je pense à ce problème est entre le temps de GEOMETRY_LOAD et OBJECT_TREE_CREATED

Je serai reconnaissant pour toute aide

======================= ======= code complet ==============================

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> 

-autodesk 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; 
}()); 

test 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); 

Répondre

0

J'ai trouvé la solution, tout à fait par hasard ... d'autre chose que j'essayé de faire

avant:

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); 
    } 

après

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); 
    } 

Vraiment Je ne sais pas pourquoi ajouter

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

fait la différence, je n'ai rien vu de tel dans aucun exemple de mise à jour de matériel. Ce qui est intéressant, c'est que ce code est en cours d'exécution pour seulement quelques éléments dans le modèle, mais il fonctionne même pour les éléments que les matériaux ont modifiés auparavant (dans la méthode changeAllElementsMaterial).

@Philippe Leefsma si vous le comprenez pls dire quelque chose de plus pourquoi il fonctionne

0

Jusqu'à présent, je ne peux pas reproduire le problème de mon côté, je suis en utilisant le code suivant (ES7) extrait de cette extension: 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) 
} 

Le onModelCompletedLoad est un événement personnalisé déclenché lorsque les deux GEOMETRY_LOADED_EVENT et OBJECT_TREE_CREATED_EVENT ont été déclenchés.

Jetez un oeil à cet article pour plus de détails: Asynchronous viewer events notification

Je doute que vous pouvez facilement changer les matériaux avant que le modèle est d'abord rendu, mais vous pouvez utiliser une superposition personnalisée qui cache le modèle jusqu'à ce que votre logique personnalisée a effectué toutes les étapes nécessaires, c'est l'approche que je me sers dans mes démos à: https://forge-rcdb.autodesk.io/configurator

Après le chargement d'un modèle, tous les matériaux personnalisés sont persistaient bien:

enter image description here

L'extension matérielle peut être testée en direct à partir de there.

espoir qui aide

+0

ok, maintenant je m 'faire mes affaires après deux événements (OBJECT_TREE_CREATED_EVENT et GEOMETRY_LOADED_EVENT) sont lancés, et ce changement il encore même comportement . Je pense que d'abord je dois savoir pourquoi les matériaux ne peuvent être changés que dans les 2-3 premières secondes –

+0

Si vous pouvez fournir un échantillon reproductible, je vais jeter un oeil. Avez-vous essayé ma démo de matériel? Cela fonctionne vraiment bien là-bas, donc vous devez faire quelque chose de mal ... Vous pouvez également jeter un oeil à viewer.setThemingColor: https://stackoverflow.com/questions/38534862/autodesk-forge-viewer-does-viewer-setthemingcolor- travail-sur-un-dwg-fichier –

+0

J'ai mis à jour ma question, maintenant vous pouvez voir tout le code im en utilisant, vous pouvez l'essayer par vos propres. Maintenant, quand l'extension va charger im ajoutant l'écouteur d'événement pour OBJECT_TREE_CREATED_EVENT. Donc ce que je veux faire ne fonctionne que parfois. Lorsque vous supprimez le commentaire d'un autre écouteur de la méthode de chargement et de l'astuce simple non réussie de la méthode changeModelMaterial, vous devez voir que les matériaux sont mis à jour, puis après ~ 2 sec sont rétablis par défaut. –