1

I am trying to get geometry data one element at a time such as vertices. What I tried so far:

  • fragproxy = viewer.gui.impl.getFragmentProxy(model,fragid) gives me some kind of geometry, but not any vertices, which I can access by dbId

  • frags = viewer.gui.model.getFragmentList() gives me a fragId to dbId map but no no connection from dbId to geometry

Does anyone know a method to get the geometry with the vertices ?

Daniel Ignjat
  • 73
  • 1
  • 1
  • 7

1 Answers1

0

The positions value of the following code snippets is the vertices what you want.

  function getLeafFragIds( model, leafId ) {
    const instanceTree = model.getData().instanceTree;
    const fragIds = [];

    instanceTree.enumNodeFragments( leafId, function( fragId ) {
      fragIds.push( fragId );
    });

    return fragIds;
  }

  function getComponentGeometry( viewer, dbId ) {

    const fragIds = getLeafFragIds( viewer.model, dbId );

    let matrixWorld = null;

    const meshes = fragIds.map( function( fragId ) {

      const renderProxy = viewer.impl.getRenderProxy( viewer.model, fragId );

      const geometry = renderProxy.geometry;
      const attributes = geometry.attributes;
      const positions = geometry.vb ? geometry.vb : attributes.position.array;

      const indices = attributes.index.array || geometry.ib;
      const stride = geometry.vb ? geometry.vbstride : 3;
      const offsets = geometry.offsets;

      matrixWorld = matrixWorld || renderProxy.matrixWorld.elements;

      return {
        positions,
        indices,
        offsets,
        stride
      };
    });

    return {
      matrixWorld,
      meshes
    };
  }

  var meshInfo = getComponentGeometry( viewer, 1234 );

Since this information of the Forge fragment is stored in a flatten storage, please check the demo extension Autodesk.ADN.Viewing.Extension.MeshData.js if you want to rebuild the meshing relationship.

Hope it helps!

Community
  • 1
  • 1
Eason Kang
  • 6,155
  • 1
  • 7
  • 24
  • Thank you for your answer. The function returns a really big positions array with close to 400k entries. Do you know how to reduce it to a reasonable number? Considering 3 entries in the position array are one vertex and dividing by faces, I should get 4 entries per face, but I get 22k entries. – Daniel Ignjat May 25 '18 at 07:57
  • This function should be applied to leaf nodes [say InstanceTree.getChildCount( dbId ) is zero], i.e. Revit Element for example, not the Category node. Besides, you will get one more fragments if the selected item is complex. – Eason Kang May 25 '18 at 08:03
  • I just tested with `instanceTree.getChildCount(dbId)` and my the element i use for testing has no childs, its just a Revit wall. My goal is that I want to do collision detection with a custom made bounding box. My idea was to iterate through all dbIds and get the vertices from every element one by one and check if it collides with my bounding box. – Daniel Ignjat May 25 '18 at 08:13
  • Forge fragment is made of a set of triangular meshes, so there might be 6 vertices to represent a face at least with my experience. You can use the Autodesk.ADN.Viewing.Extension.MeshData.js mentioned above to see what it looks like. – Eason Kang May 25 '18 at 08:18
  • Here is a SO discuss showing how to draw bounding box from Forge fragments, please have a try: https://stackoverflow.com/questions/43871636/accurate-bounding-box-of-an-object – Eason Kang May 25 '18 at 08:21
  • Thank you for your help! So I analyzed these methods and tested them and it resulted in 49k THREE.Vector3. The way I see it is that a frag ID connects to multiple dbIds so I get a whole lot of geometry for a whole lot of parts. I have no way of knowing which dbId has which geometry. So when I am looking for a part that intersects with my bounding box, I get 49k positions with no relation to a part. I only need the geometry from dbId – Daniel Ignjat May 25 '18 at 11:53
  • I have found while exploring the scenes of the THREE.js that the same geometry which is the result that I stated before are also accessible through the scenes, although still no reference to dbIds. I think forge just draws everything and then cares about the parts – Daniel Ignjat May 25 '18 at 12:27