Setting materials for specific nodes

Hi there!

Could I ask about how to set materials for nodes? I have two arrays which contain the selected nodes and the unselected nodes. The intention here is to make the unselected translucent to view the selected ones better within the whole model. However, I get the error that setMaterial is not a function of the viewer. I’m using a SolidJS signal to store the viewer, logging the viewer itself seems to have no issue.

Would greatly appreciate any help!

  const selNodes = []
  const unselNodes = []

  const worldTree = speckleViewer().getWorldTree();
  const renderTree = worldTree.getRenderTree();

  var _ = worldTree.walk((node) => {
    const rawModelData = node['model']['raw'];
    const category = rawModelData['category'];
    if (category=='Doors'){
      if ('definition' in rawModelData){
        const familyName = rawModelData['definition']['family']
        if (familyName == "MLD_DOR_Timber_Single_SS"){
          selNodes.push(node);
        }
      }
    }
    else {
      unselNodes.push(node);
    }
    return true;
  })

  unselNodes.forEach(node => {
    const rvs = renderTree.getRenderViewsForNode(node);
    console.log(rvs);
    const materialData = {
      color: 0xee0022,
      opacity: 0.3,
      roughness: 1,
      metalness: 0,
      vertexColors: false,
    };
    speckleViewer().setMaterial(rvs, materialData);
  })
1 Like

Hi @JovinLim

You’re getting the error because setMaterial is not a member of the Viewer class, but of the SpeckleRenderer class. So you’d need to do

speckleViewer().getRenderer().setMaterial(rvs, materialData)

You can find the complete API reference in the official docs

Cheers

1 Like

@JovinLim
Additionally, I would recommend the following approach:

const rvs = []
unselNodes.forEach(node => {
  rvs.push(...renderTree.getRenderViewsForNode(node))
})

const materialData = {
  color: 0xee0022,
  opacity: 0.3,
  roughness: 1,
  metalness: 0,
  vertexColors: false,
};

speckleViewer().setMaterial(rvs, materialData);

Both yours and the above approaches will do the same thing, but this one is more performant because you batch rvs in a single call rather than making potentially many calls with few rvs.

Cheers

1 Like

Ah! I was following the rendering example and missed out looking at the SpeckleRenderer core…
Thank you so much for your help, it worked like a charm.

4 Likes