0

There is a simular question: How to get location with dbid in 2D

but hasn't been anwsered.

So I have the same question, is there a way to get the object location info using dbid in 2D view?

We have a requirement in our product to mark certain object(s) and save the dbids in external database, and when next time opening the model, we need to use those ids and find the locations and then draw some custom shape to highlight those objects.

I tried to use viewer.impl.highlightObjectNode, but it can only display the object as it is selected, it's very limited on custom vitualization.

2 Answers2

1

Here are some code snippets to access mesh information of Forge fragments, it might help you to find the location of a certain Forge viewer dbId. For more information, you can refer this extentsion: https://github.com/Autodesk-Forge/library-javascript-viewer-extensions/blob/master/src/Autodesk.ADN.Viewing.Extension.MeshData/Autodesk.ADN.Viewing.Extension.MeshData.js

Besides, viewer.impl.highlightObjectNode for highlighting elements only, it cannot be used in other purposes as my experince.

  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 );
Eason Kang
  • 6,155
  • 1
  • 7
  • 24
1

you can also check "viewer.impl.fitToView" in viewer3D.js, this function calculates selected objects union bounding box and fit them to view, so I extract code from this function to get object bounding box center coordinates with it's dbid

function getObjectBound2D(viewer, objectId) {
    var model = viewer.model;
    // This doesn't guarantee that an object tree will be created but it will be pretty likely
    var bounds, bc, i;
    if (model.is2d()) {
        bounds = new THREE.Box3();
        // move this next one up into the calling method
        bc = new avp.BoundsCallback(bounds);

        var dbId2fragId = model.getData().fragments.dbId2fragId;

        var fragIds = dbId2fragId[objectId];
        // fragId is either a single vertex buffer or an array of vertex buffers
        if (Array.isArray(fragIds)) {
            for (var j = 0; j < fragIds.length; j++) {
                // go through each vertex buffer, looking for the object id
                find2DBounds(model, fragIds[j], objectId, bc);
            }
        } else if (typeof fragIds === 'number') {
            // go through the specific vertex buffer, looking for the object id
            find2DBounds(model, fragIds, objectId, bc);
        }

        // should have some real box at this point; check
        if (!bounds.empty()) {
            return bounds;
        }
    }

    function find2DBounds(model, fragId, dbId, bc) {
        var mesh = model.getFragmentList().getVizmesh(fragId);
        var vbr = new avp.VertexBufferReader(mesh.geometry);
        vbr.enumGeomsForObject(dbId, bc);
    }

    function find2DLayerBounds(model, fragId, bc) {
        var mesh = model.getFragmentList().getVizmesh(fragId);
        var vbr = new avp.VertexBufferReader(mesh.geometry);
        var visibleLayerIds = that.getVisibleLayerIds();
        vbr.enumGeomsForVisibleLayer(visibleLayerIds, bc);
    }
};

var objBoundingbox = getObjectBound2D(viewer,dbid);

var objCenterCoordinates = objBoundingbox.center();