2 Aug 2021

Map between SVF1 and SVF2 DBids using Server-only

INTRODUCTION

Forge Model Derivative Service (MD API) takes your 70+ formats, and converts them to Geometry and Properties "meta-data"

Say you have a Chair model (Autodesk Inventor)...

...then you can use MD API to output an "OBJ geometry file" as well as all the properties meta-data, for say, the wood leg (see diagram #2 below).  

The ID of the geometry, will match the ID of the properties, unless you explicitly use SVF1 and SVF2 in a mixed environment.

 

USING A MIXTURE OF SVF1 & SVF2

With the release of SVF2, the interface behavior was updated for Forge Properties to work with both SVF1 and SVF2.  

If you converted BIM360 files to OBJ files via Model Derivative Service, or if you use forge-convert-utils to generate a glTF, then you might have noticed the comments next to each Mesh node, shows an SVF v1 DBID.  If you make a query to Forge Properties API, you get meshes (or objectIDs) with a SVF v2 DBID.  

This is a mixed environment.  We need a way to map between SVF1 and SVF2 dbIds, on the server, and not using a browser.
 

 

 

NODEJS SOLUTION

Thankfully, we can map between SVF2 DBIDs and SVF1 DBIDs.  Let's create a simple Proxy Service of the Forge Properties API, that conveniently does the mapping so the DBIDs match for BIM360 content !

 

LOOKUP TABLE

Start by using Petr's remapping example.  We will "swizzle" between SVF1 DBIDs and SVF2 DBIDs, and back again, via a "Lookup Table" module.

Under the hood, the "Lookup Table" is a single file 'dbid.idx', which I download with a BIM360 Access-Token (or Forge 2-legged).  My code, then decodes it's bytes, into a javascript array, which we will use to map back and forth between SVF1 and SVF2 DBIDs.

const lookupTable = new Uint32Array(buff.buffer, buff.byteOffset, buff.byteLength / Uint32Array.BYTES_PER_ELEMENT);

Let's take this "lookup table" module, and expand it into a "Service" to mimic the Forge Properties...  
...a "Proxy"
 

 

PROXY SERVICE

The Proxy Service looks just like the Forge Properties Service, except it translates any SVF2 DBIDs it finds inside the JSON, and remaps them back into SVF1 DBIDs.

 

For the Forge Properties metadata query endpoint, we have objectIDs in a Tree structure, so I need to recursively traverse the tree and do the 'swizzle'.  Here's the code:

 

  // recursively travese json tree and swizzle svf1 objectids into svf2
  function swizzleNode(currentNode) {
    for(var index in currentNode.objects) {
      var node = currentNode.objects[index];
      if(node.objectid) {
          node.svf2 = node.objectid;
          node.objectid = dbidIdx[node.svf2];
      }
      swizzleNode(node);
    }
  }
  swizzleNode(json.data.objects[0]);

 

Now the Geometry matches the Properties -  Hurray !

Just point your server, to my "Proxy Server" and you should be back in business (https://forge-properties-proxy.herokuapp.com/)

 

 

DETAILS

Here are the three endpoints:

...which replace:

NOTE:  This is a demonstration Proxy Service.  It will continue to run until the end of the year YMMV.

You can deploy it yourself here:  

GITHUB: https://github.com/wallabyway/properties-proxy

LIVEhttps://forge-properties-proxy.herokuapp.com/
 

As always, feel free to reach out to me via forge.help@autodesk.com or via Calendly

Twitter: @micbeale

 

 

Related Article