How to emulate the Material picker via the API

I’d like to emulate what the material picker does via the API. ie. I’d like to control which material is visible from their material names. Which API functions should I be looking at to do this?

The following functions/properties will be helpful:

  • Viewer.findMaterial(materialName) returns a Material for the material with the given name.

  • Viewer.findMeshesWithMaterial(materialName) returns a list of Meshes having material of the given name assigned.

  • Viewer.findNodesOfType(nodeType) returns a list of Nodes of the given type. Node type is a string and is equivalent to the object type name in the “Objects” tab of the scene editor.

  • node.mesh returns a Mesh attached to the scene node, if the node has one.

  • Viewer.setMaterialForMesh(material, mesh) assigns the given Material to the given Mesh.

Materials and node types used in the API calls must be editable, see: GitHub - shapespark/shapespark-viewer-api: JavaScript API for interacting with the Shapespark 3D scene..

1 Like

Thanks, those functions helped.

I was wondering if it’s possible to obtain the materials that are active by default when the model is loaded? ie. I would like to know if it’s possible to get the material that’s used as the “Material to replace” in the material picker?

I’m currently doing something like the following to replace the current material with another…

let meshes = viewer.findMeshesWithMaterial(active_material_name)
let new_material = viewer.findMaterial(new_material_name)
meshes.forEach((mesh) => {
  viewer.setMaterialForMesh(new_material, mesh)
})
active_material_name = new_material_name

I’m currently hard coding the initial active material name for the first material swap, but I was wondering if there’s a way to detect it via the API?

It’s possible if you know which scene object to check active material on:

const nodes = viewer.findNodesOfType('<OBJECT-TYPE>');
// Assuming there is an object type called <OBJECT-TYPE> in the scene, and it contains a mesh.
const material = nodes[0].mesh.material;

The object type must be marked as editable with viewer.setNodeTypeEditable('<OBJECT-TYPE') when the scene is loaded.