I am trying to build upon a speckle idea from the last hackatron. the Mass On Speed.
and am i trying to build a webapp that loads a speckle model and then overlays an obj over the model.
i am using typescript for overlaying the obj with the ObjLoader from speckle.
I am using the following code for this:
async function overlayObj(objData: string, id: string) {
if (!viewer) {
console.error("Viewer is not initialized");
return;
}
if (lastLoaded) {
viewer.unloadObject(id);
console.log("Disposed last loaded object");
}
/** Create a loader for the .obj data */
const loader = new ObjLoader(viewer.getWorldTree(), id, objData);
/** Load the obj data */
await viewer.loadObject(loader, false);
// this seems to be sepckle stuff
const tree = viewer.getWorldTree();
// get node from loader.tree.nodeMap with id and set the colour of the object to red
const nodes = viewer.getWorldTree().findId(id);
// Set the color of the object to red
if (nodes && Array.isArray(nodes) && nodes.length > 0) {
for (const node of nodes) {
for (const child of node.children) {
const obj = child.model.raw;
if (obj.isMesh ) {
obj.material.color.set(0xff0000);
console.log(`Node ${node.id} color set to red`);
} else {
console.error(`Node.model is not a THREE.Mesh: ${child.model}`);
}
}
}
} else {
console.error("Node array is empty");
}
// Refresh the viewer
viewer.requestRender();
lastLoaded = loader;
console.log("OBJ file loaded successfully");
}
but this code loads the obj propperly but does not colour it red.
any help on how i can colour the loaded OBJ in red would be appreciated.
i am not getting any errors in the console and it seems that the script changes the material colour, but nothing happens.
i really am a beginner in undestranding programming and how speckle and three work together.
You are trying to apply a material to a BlockInstance which in the context of the OBJ content would be the equivalent of a group that is not displayable in any way.
You are getting the render views, but only applying the material to the first one, renderViews[0] which is a BlockInstance and does not have nor take materials. What you probably want is to apply the material to all the renderViews returned by the call to getRenderViewsForNodeId. Also note thatsetMaterial takes an array of renderviews as it’s first argument.
If you have a look at the live example I’ve prepared for you, you will see that it’s functioning properly