Search, select and focus objects in Speckle in JavaScript

Hi everyone,

I’m Mathilde and I’m working on a project where I need to program a Speckle viewer.
The programming language I’m using is JavaScript.

My goal is to extract specific information from my models. These pieces of information are not always located in the same place within the model trees (two highlighted examples are shown in the screenshots).

The aim is to retrieve these codes, which are used to identify all the elements in my Speckle viewer.
Later, I want to match them with a reference I’ve selected (for example: 0WSwMjjc57dvDi9Q454zCt).

Then, I want to zoom in on these elements within the viewer.

Right now, I’m unable to search for the elements in my code—my program isn’t working…
I need help!

Thank you so much.

async function searchObjectsInSpeckle(viewer, value, propertyName) {
  try {
    const foundObjects = [];
    const worldTree = await viewer.getWorldTree();
    const allObjects = worldTree.getRenderTree();
    console.log("All objects in Speckle", allObjects);
    const pro = await viewer.getObjectProperties();
    console.log("Properties of value", pro);

      for (const node of allObjects) {
        try {
          const properties = await viewer.getObjectProperties(node.model.raw.properties.element.IfcGUID);
          console.log("Properties of node", node.id);
          if (properties && properties[propertyName] === value) {
            foundObjects.push(node.id);
          }
        } catch (error) {
          continue;
        }
      }
    
    return foundObjects;


  } catch (error) {
    console.error(`Error searching objects with ${propertyName} = ${value}:`, error);
    return [];
  }
}

async function selectObjectsInSpeckle(viewer, objectIds) {
  try {
    const selectionExtension = viewer.getExtension(SelectionExtension);
    console.log("Selecting Extension:", selectionExtension);
    if (selectionExtension) {
      await selectionExtension.selectObjects(objectIds);
      console.log("Objects selected in Speckle:", objectIds);
    }
  } catch (error) {
    console.error("Error selecting objects in Speckle:", error);
  }
}

async function focusObjectsInSpeckle(viewer, objectIds) {
  try {
    if (objectIds.length > 0) {
      await viewer.isolateObjects(objectIds);
      await viewer.zoomToObject(objectIds);
    
    }
  } catch (error) {
    console.error("Error focusing objects in Speckle:", error);
  }
}

Hi @Mathilde

Oh no, more hallucinated vibe code :slight_smile: Don’t worry, we got you! I’ll help you with your issue later today

Cheers

Hi @Mathilde

I’ve made this live example for you that illustrates how to achieve what you are looking for, or at the very least something very close to what you are after, since I do not have your model with the exact properties.

As per the documentation, getObjectProperties goes through your model and organizes it’s properties in a more usable way. You only need to call it once and preferably wait until it’s finished.
After, you can query the data it generated for object ids that hold specific property names with specific values like I did in the live example.

I see you are getting a RenderTree, however you are trying to iterate over it. That is not possible, as it’s not iterable. If you want to go over nodes in the tree, the recommended way is to use walkAsync or other methods for finding nodes from WorldTree.

For focusing on objects I see you are trying to use zoomToObject, however that function does not exist in the API. Instead you can use setCameraView from the CameraController which is overloaded to take in multiple combinations of arguments for varied use.

Let us know if you need more help.

Cheers