How can I load only specifc objects in the forge viewer using SFV2? - autodesk-forge

SVF2 has different objectids/dbids than SVF1. In this SO-Answer, it was advised to use externalId instead of objectid. However, viewer.loadModel(svfUrl,{ids:[dbIds...]}) takes dbIds to load only specified objects. How can I load only specified objects using SVF2 and the https://developer.api.autodesk.com/modelderivative/v2/regions/eu/designdata/:urn /metadata/:guid/properties endpoint? Can I access the svf2 objectIds anywhere or can I use the externalIds when calling Viewer3d::loadModel?

You're right, there's a difference between the "SVF1 dbIDs" and the "SVF2 dbIDs" - the IDs in SVF2 format are "persistent", meaning that in different versions of the same design file, a single ID will reference the same design element (which was not the case in SVF1).
Unfortunately, there are parts of the platform (like the loadModel viewer method and the /modelderivative/v2/regions/eu/designdata/:urn /metadata/:guid/properties endpoint) that have not "caught up" with SVF2 yet. And before those updates are available, you would have to map "between the old and new dbIDs" manually which is itself another, non-trivial task.

Related

Query properties using the forge-viewer library without rendering model

I'm using the forge-viewer library to display models. I'm wondering if it is possible to at the same time query properties from another model, without rendering the other model or altering the state of the original viewer instance?
Preferably by obtaining a new instance of Autodesk.Viewing.Model, in order to use methods like model.getProperties(...).
Loading with the original viewer instance causes the other model to display in the browser
const document: Autodesk.Viewing.Document = await myLoadDocumentFunction("urn:another-model-urn");
const defaultModel = document.getRoot().getDefaultGeometry();
const model = await viewer.loadDocumentNode(document, defaultModel);
As the documentation states, the options input variable for loadDocumentNode() is passed on to loadModel() so you can check the documentation of that function to see what options are available.
One of them is loadAsHidden which seems to do exactly what you need:
FYI: it should also be possible to create another Viewer instance, make it invisible (e.g. placing it off the screen) and load extra models there: Multiple instances of Autodesk Forge Viewer

Access viewer methods from AggregatedView for more than one model in Autodesk Forge Viewer?

I am loading two different models via AggregatedView.
Although I have access to view.viewer, executing
var view = new Autodesk.Viewing.AggregatedView();
//...
view.viewer.isolate([0]);
only affects one of the two models.
Is there any way I can call viewer methods such as isolate(), show(), hide(), etc. on both models?
Note that many of the Viewer3D methods such as Viewer3D#isolate accept an additional parameter that you can use to specify the model.
And if the method you're interested in doesn't accept the model as one of its parameters, you can often find the same method directly on the Model class, for example, Model#getProperties.

How to use the various Forge Viewer transforms

Below are the various transforms I have found so far using NOP_VIEWER.model.getData().
I'm using the transforms to bring a position into viewer space, and I haven't been able to find any good documentation describing what they all do. My hope here is that this question can help by providing some documentation of the role of these transforms and how/when to use them.
The model originally comes from Revit.
GlobalOffset (Vector3)
placementWithOffset (Matrix4) - seems to be just the inverse of GlobalOffset as a matrix?
placementTransform (Matrix4) - undefined in all models I've tested, I've seen some hints that this is a user defined matrix.
refPointTransform (Matrix4)
Also, there are some transforms in the NOP_VIEWER.model.getData().metadata. These may be Revit specific:
metadata.georeference.positionLL84 (Array[3]) - this is where the model's GPS coords are stored
metadata.georeference.refPointLMV (Array[3]) - no idea what this is, and it has huge and seemingly random values on many models. For example, on my current model it is [-17746143.211481072, -6429345.318822183, 27.360225423452952]
metadata.[custom values].angleToTrueNorth - I guess this is specifying whether the model is aligned to true or magnetic north?
metadata.[custom values].refPointTransform - (Array[12]) - data used to create the refPointTransform matrix above
Can someone help by documenting what these transforms do?
Related: Place a custom object into viewer space using GPS coords
As an alternative solution, the Viewer works with extensions. The Autodesk.Geolocation extension provides a few methods to handle the data structure you mentioned:
Load extension:
let geoExt;
NOP_VIEWER.loadExtension('Autodesk.Geolocation').then((e) => {geoExt = e});
Or get already loaded extension:
let geoExt = NOP_VIEWER.getLoadedExtensions()['Autodesk.Geolocation']
Then use the methods to convert the coordinates
geoExt.lmvToLonLat
geoExt.lonLatToLmv
Here is a quick article on it.
You may .activate() the extension to see additional information on the model geo location.

What is the best way to persist a reference to an item in forge viewer?

Currently, we are importing into forge viewer some revit models.
In the viewer, we want to be able to store into external database some info attached to an element of the model we see in the viewer (for example a door).
We have 3 ways to identify an item:
dbid (e.g 2214)
guid/externalId (e.g. a6aa132d-ccd7-408f-b2f9-ed67350c8c3a-0003b64a)
Revit ID in bracket beside the name (e.g. Roof [243274])
I would need to be able to reference an item on the model in external database, even if the revit model gets updated and reconverted in the middle.
It sounds dbid can change if we convert a new version, so not the good candidate. (https://forums.autodesk.com/t5/view-and-data-api-read-only/are-the-dbids-in-an-objecttree-of-a-revit-model-fixed/m-p/5517214#M757)
Guid seems ok, but we cannot get direct guid to dbid mapping in the viewer, we need 1000s costly web service call (https://forums.autodesk.com/t5/view-and-data-api-read-only/how-to-get-object-s-dbid-from-its-guid/m-p/5226891#M192)
Revit ID sounds just informative
1-Is Guid, the thing we should use to reference items in revit file (even between updates) ?
2-If this is Guid, how can we directly have a mapping from guid to dbid (since all in viewer is handled by dbid) ?
For now I see the solution above
Maybe playing with model-derivative :urn/metadata/:guid/properties to fetch all guid
Maybe there is already this guid->dbid mapping somewhere in the viewer and I miss it (behind getBulkProperties, I saw a getPropertyDb, that could possibly have it)
Thank you
First, to summarize:
Revit ID is a sequential numbering used on Revit desktop, it may be reused and it's not uniqu
Revit GUID is unique (as any GUID) and maintained between versions and exposed on both Viewer (JavaScript library) and Model Derivative GET Properties endpoint as external id
dbId just index used on the model to access geometry, no guarantee will be the same between versions/translations of the model.
Now, the only true identifier you can use to track the same element between versions is the external id (from Revit GUID).
If you want a server-side mapping, use Model Derivative GET Properties on all model views. On the client-side, I would suggest first enumerateLeafNodes and then call getBulkProperties on these nodes to get the external id.

Active viewer model for miltimodel mode

Then several models are loaded in viewer, only one of them is "active". I mean that Object tree is shown for this model and select(),isolate() etc methods are related to it. I try to use following method to set "active" model:
function setActiveModel(model) {
var instanceTree = model.getData().instanceTree;
viewer.modelstructure.setModel(instanceTree);
}
But object tree doesn't change.
Questions are:
That is correct way to change viewer "active" model?
How can I get current "active" model in viewer?
Here is a patched version that supports multi-model switching. It is a drop-in replacement, simply include the file after the viewer3D.js script:
MultiModelStructurePanel.js
Multi-models will be supported soon in a future version of the API.