selectObjects from Selection Extension results in empty box

Hi Speckle community and developers,

I am working with the Speckle Viewer and trying to get it to zoom into specific objects. For testing purposes, I am first using the selectObjects function from the Selection Extension to identify the objects I will then zoom into but this seems to always result in an error saying that it is an empty box, no matter what object ids I provide. Here is a snippet of my code:

const ids = [
    "1a36c201b4e6931d9a05329b062bdd0b" // example object id
  ];

  const handleButtonClick = () => {
    console.log('Button clicked!');
    const cameraController = viewer.getExtension(CameraController);
    const selection = viewer.getExtension(SelectionExtension);
    if (cameraController) {
      console.log(cameraController.controls);
      selection.clearSelection();
      selection.selectObjects(ids);
      cameraController.setCameraView(ids, true);
    } else {
      console.error('Viewer is not initialized');
    }
  };

What would be the best way to fix this? Thanks

Hi @smaderosuffolk

It’s hard to tell what the issue might be. I’ve made a live example that replicates what you are trying to do and it’s working fine. Maybe the ids that you are passing do not have any displayable objects in their inner hierarchies? If you can share the stream along with the object ids that are causing issues I can have a better look

Cheers

I have figured out part of the issue. The zoom in and selection features appear to work when I first initialize and embed them as part of the main function I develop, with snippets of that shown below:

useEffect(() => {
    async function initViewer() {
      try {
        const container = document.getElementById("renderer");
        const params = DefaultViewerParams;
        params.showStats = false;
        params.verbose = false;

        const viewerInstance = new Viewer(container, params);
        await viewerInstance.init();
        setViewer(viewerInstance);

        const cameraController = viewerInstance.createExtension(CameraController);
        viewerInstance.createExtension(SelectionExtension);
        const filterControllerInstance = viewerInstance.createExtension(FilteringExtension);
        setFilterController(filterControllerInstance);

        viewerInstance.on(ViewerEvent.ObjectClicked, (selectionInfo) => {
          if (selectionInfo !== null) {
            const clickedObj = selectionInfo.hits[0].node.model.raw;
            setSelectedObj(clickedObj);
            filterControllerInstance.resetFilters();
            filterControllerInstance.isolateObjects([clickedObj.id]);
            cameraController.setCameraView([clickedObj.id], true); // works
          } else {
            setSelectedObj(null);
            filterControllerInstance.resetFilters();
          }
        });

       ...

    initViewer();

    return () => {
      if (viewer) viewer.dispose();
    };
  }, [projectId, modelId, token]);

The issue only arises when I attempt to create a button for the same feature, which is the code I had previously shown. What could be causing this? Thanks

Are you making sure you are not creating multiple viewer instances by mistake (or otherwise)? There’s a high change there is something wrong at application level.

If you could provide us with a repository that can reproduce the issue we can take a look. Or even better, you can use the live dev environment I used in my previous post. They have ready to go templates for all major frontend templates so it’s super simple to set up

Cheers

Hi Alex, I do believe I am currently making multiple viewer instances but have managed to get my button to work in the live dev environment.

However, the end goal with what it is that I am developing is to use an AI agent to control the viewer. Would it be possible to pass the viewer instance through an API so that it could be used by my agent? Thanks