【问题标题】:Is it possible to dimm a model except the objects NOT affected by setThemingColor?除了不受 setThemingColor 影响的对象之外,是否可以使模型变暗?
【发布时间】:2021-06-02 08:30:27
【问题描述】:

我们使用查看器(版本 7)来显示 3d 模型使用用户定义的调色板为受影响的对象着色的问题。

模型的剩余对象以灰色调着色。 为了实现这一点,我使用了 setThemingColor 技术:我将 rootid 递归的主题颜色设置为灰色,然后将正确的主题颜色设置为特定的发布对象。

所有使用的颜色都是 THREE.Vector4,不透明度设置为 1。这样,themingColor 不会与对象的“自然”颜色混合,但它会“覆盖”对象。

为了改善用户体验,我们希望允许用户调暗不受问题影响的对象,而不是使用 setThemingColor 设置灰色。

现在的问题是:是否可以在保留选择功能的同时通过将淡化级别指定为查看器隐藏方法的幻影来更改一组对象的颜色(材质?)?

我尝试了以下方法,但没有成功:

        const mat = new THREE.MeshBasicMaterial({ color: 0x00ff00, opacity: 0.925, transparent: false });
        (this.viewer as any).impl.getMaterials().addMaterial('ghost-material', mat, true);
        
        const model = (this.viewer as any).model;
        const tree = model.getInstanceTree();
        const frags = model.getFragmentList();


        [19240, 20373, 34364, 58813].map(dbid => {
            tree.enumNodeFragments(dbid, (fragid) => {
                console.log(fragid);
                frags.setMaterial(fragid, mat);
                (this.viewer as any).impl.invalidate(true);
            }, true);
        });

[19240, 20373, 34364, 58813] 是有效的 dbid。 不透明度几乎为 1,材料不透明,希望能看到一些东西。 我试图使每个片段的查看器无效。 运行此脚本后,3d 模型保持不变。 'ghost-material' 会定期在 matman 上注册,但不会“取代”原生的。

我哪里做错了?

【问题讨论】:

    标签: autodesk-forge autodesk-viewer


    【解决方案1】:

    最重要的是调用方法:

    model.unconsolidate(); // If the model is consolidated, material changes won't have any effect
    

    在将新材料应用于片段之前,如下文所述

    https://forge.autodesk.com/blog/custom-shader-materials-forge-viewer

    正确答案是

            const mat = new THREE.MeshBasicMaterial({ color: 0x00ff00, opacity: 0.925, transparent: false });
            (this.viewer as any).impl.getMaterials().addMaterial('ghost-material', mat, true);
            
            const model = (this.viewer as any).model;
            const tree = model.getInstanceTree();
            const frags = model.getFragmentList();
    
            // without this it is all useless
            model.unconsolidate();
    
            [19240, 20373, 34364, 58813].map(dbid => {
                tree.enumNodeFragments(dbid, (fragid) => {
                    console.log(fragid);
                    frags.setMaterial(fragid, mat);
                    (this.viewer as any).impl.invalidate(true);
                }, true);
            });
    

    【讨论】:

      【解决方案2】:

      是的,这是一个高级主题,但您可以自定义分配给单个对象(片段)的材料。流程如下:

      • 创建自定义的半透明材质,例如简单的THREE.MeshBasicMaterial,并将其添加到查看器的材质管理器中
      • 使用实例树枚举场景中所有对象的片段
      • 使用片段列表检索每个片段的原始材料,将其引用存储在某处,并将其材料设置为您的自定义材料

      代码大致如下:

      const mat = new THREE.MeshBasicMaterial({ color: 0x00ff00, opacity: 0.25, transparent: true });
      viewer.impl.getMaterials().addMaterial('my-material', mat, true);
      const tree = viewer.model.getInstanceTree();
      const frags = viewer.model.getFragmentList();
      tree.enumNodeFragments(tree.getRootId(), (fragid) => { frags.setMaterial(fragid, mat) }, true);
      

      如果需要,重复该过程,并将每个片段重置为其原始材料。

      【讨论】:

      • 这是我使用的方法,但没有成功。我已经编辑了我的问题,提到了您的建议
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 2017-03-12
      • 1970-01-01
      • 2014-09-25
      • 2020-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多