How Autodesk Forge viewer manages multiple scenes to select multiple elements

1.1k views Asked by At

I want to understand how Autodesk Forge viewer stores node elements in multiple THREE.Scene objects. There are several scenes:

viewer.impl.scene // The main scene
viewer.impl.overlayScenes // Three overlay scenes: selection, pivot and roll

Whenever an element is selected in Forge viewer, its THREE.Mesh object is added to viewer.impl.overlayScenes.selection.scene.children. However its boundary geometry is always zero, unlike primitive THREE.Mesh objects will have boundaries after executing geometry.computeBoundaryBox()

Because of the zero boundary of Forge elements, I cannot use THREE.Raycaster to project through overlay elements to get their dbIds on mouse pick. How can I select the inner dbId because it will get the outer dbId? The Forge viewer does not allow to select inner object on click on outer object. How to select an element within another element?

The main scene also has empty children. Where are all elements and how can they render on the screen?

It would have better documentation to understand the Forge viewer data structure to have the full API control. I have to learn by myself with viewer3D.js and wgs.js of Autodesk Forge viewer.

1

There are 1 answers

2
Felipe On BEST ANSWER

Here are two methods that shows you how to access the bounding boxes of specific components based on their fragmentIds:

//returns bounding box as it appears in the viewer
// (transformations could be applied)
function getModifiedWorldBoundingBox(fragIds, fragList) {

  var fragbBox = new THREE.Box3();
  var nodebBox = new THREE.Box3();

  fragIds.forEach(function(fragId) {

    fragList.getWorldBounds(fragId, fragbBox);
    nodebBox.union(fragbBox);
  });

  return nodebBox;
 }

 // Returns bounding box as loaded in the file
 // (no explosion nor transformation)
function getOriginalWorldBoundingBox(fragIds, fragList) {

  var fragBoundingBox = new THREE.Box3();
  var nodeBoundingBox = new THREE.Box3();

  var fragmentBoxes = fragList.boxes;

  fragIds.forEach(function(fragId) {
    var boffset = fragId * 6;
    fragBoundingBox.min.x = fragmentBoxes[boffset];
    fragBoundingBox.min.y = fragmentBoxes[boffset+1];
    fragBoundingBox.min.z = fragmentBoxes[boffset+2];
    fragBoundingBox.max.x = fragmentBoxes[boffset+3];
    fragBoundingBox.max.y = fragmentBoxes[boffset+4];
    fragBoundingBox.max.z = fragmentBoxes[boffset+5];
    nodeBoundingBox.union(fragBoundingBox);
  });

  return nodeBoundingBox;
 }

You can find a comprehensive sample from the blog post below:

Getting bounding boxes of each component in the viewer