Search code examples
autodesk-forgeautodesk-viewer

Select objects programatically without triggering SELECTION_CHANGED_EVENT


Is there some way to call viewer.select([...]) from inside selection event listener callback without triggering the Autodesk.Viewing.SELECTION_CHANGED_EVENT?

The following code currently results in an infinite loop, cause viewer.select(...) triggers the Autodesk.Viewing.SELECTION_CHANGED_EVENT. The SetTimeout(...) call is in place only to prevent call stack overflow.

viewer.addEventListener(Autodesk.Viewing.SELECTION_CHANGED_EVENT, () => {
    setTimeout(
        () =>
            viewer.select(
                [
                    ...new Set([
                        ...itemsThatShouldRemainSelected,
                        ...viewer.getSelection(),
                    ]),
                ],
                undefined,
                -1,
            ),
        100,
    );
    console.log('SELECTION_CHANGED_EVENT');
});

Solution

  • Understood! Thanks for sharing the use case.

    After diagnosing into viewer, I found the below, but we still need something to store pre-selected dbIds somewhere.

    To prevent the Autodesk.Viewing.SELECTION_CHANGED_EVENT getting triggered, we can use model.selector.setSelection( dbIds, selectionType ) to bypass the event trigger.

    let model = viewer.getAllModels()[0];
    
    // Select
    model.selector.setSelection( dbIds, selectionType ); //!<<< selectionType is optional.
    
    // clear selections
    model.selector.clearSelection();
    

    Note. The functions above are internal functions used in Viewer3D#select, Viewer3D#clearSelection, which might be changed someday in the future. So, please use them at your own risk.