Hugo Kamps
Hugo Kamps

Reputation: 113

Is there a way to extract the XYZ geometry data from a converted Revit model?

I'm creating a solution that converts a revit model to IFC file format using Autodesk Forge - Model Derivative API. This API hands me a JSON file with the hierarchy of the converted model, and a JSON file with all separate objects and their properties.

After converting the model I need to analyze specific properties from parts of the model. But not all information I need is stored in objects' properties. I also need to use XYZ coordinates of objects to get real results, but I believe the model derivative API doesn't generate XYZ data.

I've already searched all the properties of the objects to see if they contain any kind of data about their location in comparison to other objects, but they don't contain that information. I've searched for other ways to extract geometry/coordinates from Revit, but haven't found a real solution.

https://forge.autodesk.com/en/docs/model-derivative/v2/tutorials/extract-metadata-from-source-file/

In step 5 of this tutorial you can see the data that I have (the properties of each object).

Upvotes: 1

Views: 804

Answers (1)

mossherder
mossherder

Reputation: 155

There is no way to get the XYZ data from the Model Derivative API the way that you are hoping.

I'd also say that if you are looking to convert to IFC, there is already a conversion service for that in the Model Derivative API. But in case you really need a custom file format, here is how you could get XYZ, below.

There are two other options though that you can consider.

  • One, is to use the Design Automation for Revit API. You would be able to make an Addin that pulls the needed data from the headless Revit environment.
  • Another option is to launch a headless Forge Viewer and get the XYZ data of the model from there.

The headless viewer is a tutorial in the Viewer API documentation that you can check out. Here is the code from it (v6) for reference.

var viewerApp; var options = { env: 'AutodeskProduction', accessToken: '' };

  var documentId = 'urn:<YOUR_URN_ID>';
  Autodesk.Viewing.Initializer(options, onInitialized);

  function onInitialized() {
    viewerApp = new Autodesk.Viewing.ViewingApplication('MyViewerDiv');
    viewerApp.registerViewer(viewerApp.k3D, Autodesk.Viewing.Viewer3D);
    viewerApp.loadDocument(documentId, onDocumentLoaded);
  }

  function onDocumentLoaded(lmvDoc) {
    var modelNodes = viewerApp.bubble.search(av.BubbleNode.MODEL_NODE); // 3D designs
    var sheetNodes = viewerApp.bubble.search(av.BubbleNode.SHEET_NODE); // 2D designs
    var allNodes = modelNodes.concat(sheetNodes);
    if (allNodes.length) {
      viewerApp.selectItem(allNodes[0].data);
      if (allNodes.length === 1){
        alert('This tutorial works best with documents with more than one viewable!');
      }
    } else {
      alert('There are no viewables for the provided URN!');
    }
  }

Once you're accessing the viewer, here is some code that you can get the bounding box of an element or elements by dbIds that I've used successfully.

/**
   * Uses dbId element fragments to build boundingbox of element
   * @param {Array<number>} dbIds dbIds of element to find boundingBox
   * @return {THREE.Box3} dbId elements bounding box
   */
  getBoundingBox(dbIds) {
    const totalBox = new THREE.Box3();
    dbIds.forEach((dbId) => {
      const fragBox = new THREE.Box3();
      const fragIds = [];
      const instanceTree = viewer3D.model.getInstanceTree();
      instanceTree.enumNodeFragments(dbId, function(fragId) {
        fragIds.push(fragId);
      });
      const fragList = viewer3D.model.getFragmentList();
      fragIds.forEach(function(fragId) {
        fragList.getWorldBounds(fragId, fragBox);
        totalBox.union(fragBox);
      });
    });
    return totalBox;
  }

From this BoundingBox which is a THREE.Box3 object, you can get some XYZ information about the elements. Also, there is code here using the 'fragments' that will allow you to get different element geometry more specifically if that is more useful for the XYZ you need to define.

Upvotes: 2

Related Questions