2 Jun 2021

Temporary workaround for mapping between SVF1 and SVF2 IDs

Default blog image

If you're one of our hard-core fans who like living on the edge, and you're experimenting with the new, heavily optimized SVF2 format, you have probably noticed that when converting the same design to both SVF(1) and SVF2, the object IDs do not match. Note that this is by design - SVF2 generates object IDs that are "persistent" (or "stable"), meaning that when you convert a modified version of the design into SVF2 again, objects that haven't been modified will still have the same ID! While this is generally a great property to have, we also understand that many of our customers rely on the "old IDs", and you can rest assured that the Model Derivative service will support mappings between SVF(1) and SVF2 object IDs. But until that feature is available, here's a little workaround (well, a hack) you can try.

Once again, note that this is just a temporary workaround, allowing you to map between SVF and SVF2 IDs until this feature is officially introduced by the Model Derivative service.

The SVF2 pipeline does already generate a mapping file today that can be used to map between the old and new IDs. The Autodesk.Viewing.Model class that's part of Forge Viewer then uses this information, allowing you to map from old IDs to new IDs (using the remapDbId(oldDbId) method), as well as from new IDs to old IDs (using the reverseMapDbId(newDbId) method). Unfortunately, as of today (Forge Viewer version 7.44), this functionality is only available for 2D models. But don't you worry! This is JavaScript we're working with, and as you know, this language is quite... malleable. We can override a couple of methods of the internal PropDbLoader class that handles the loading of property database assets, to make sure that the mapping information is retrieved always, not just for 2D models:

// Override `PropDbLoader#load` so that the svf1/svf2 ID mapping is always loaded.
const _load = Autodesk.Viewing.Private.PropDbLoader.prototype.load;
Autodesk.Viewing.Private.PropDbLoader.prototype.load = function () {
    this.needsDbIdRemap = true;
    _load.call(this);
}

// Override `PropDbLoader#processLoadResult` so that the ID mapping is stored within all models (and not just in 2D models).
const _processLoadResult = Autodesk.Viewing.Private.PropDbLoader.prototype.processLoadResult;
Autodesk.Viewing.Private.PropDbLoader.prototype.processLoadResult = function (result) {
    _processLoadResult.call(this, result);
    this.model.idRemap = result.dbidOldToNew;
}

Note: make sure to run this code after the Autodesk global namespace has already been created, but before loading the SVF2 model.

With our modified PropDbLoader, each SVF2 model we load will include the ID mapping information, and we can easily convert SVF(1) IDs to SVF2 IDs and vice versa:

console.log('New (SVF2) ID:', viewer.model.remapDbId(oldDbId));
console.log('Old (SVF) ID:', viewer.model.reverseMapDbId(newDbId));

A working sample is available in a special branch of the https://github.com/petrbroz/forge-basic-app repository, in this case: sample/svf2-dbid-mapping. To test it out, follow the README file, and when the server app is running, open your browser and go to http://localhost:3000?urn=<urn>, replacing <urn> with a base64-encoded URN of one of your own models that have already been converted to SVF2.

Related Article