Get a list of all objects from loaded model - autodesk-forge

I need to get all the properties from all the objects in the currently loaded model.
If I have a list of all the dbIds, I can use the Autodesk.Viewing.Viewer3D.getProperties(dbid,onSuccessCallback,onErrorCallback) method to retrieve them.
Is there a way to get a list of the dbIds of all the objects in the viewer? Or is there a better way to achieve this?

Here is how you can get all the dbIds in the model:
Get all database id's in the model
Now we also have a function to retrieve properties for multiple elements in the Viewer:
getBulkProperties method
I think the above two things are all you need.

You can also use the following Model Derivatives API endpoint to get the list of all the properties for a model: GET :urn/metadata/:guid/properties
This can be done without loading the model in the viewer but needs to be performed server side for security reason. You can expose an endpoint from your own server to your webpage.

Related

dbIds from the Forge Viewer and the Model Derivative API are different

I'm working on creating a forge viewer-based web system linking with my client's BIM360 environment. For the model data extraction part, I refered to the examples below.
(1) https://github.com/xiaodongliang/forgeviewer_embed_in_powerbi_report/tree/master/forge-model-properties-excel
(2) https://github.com/Autodesk-Forge/bim360appstore-model.derivative-nodejs-xls.exporter
However, I realized that the dbIds from the Forge Viewer and the sample codes are different. Is this the reason because of the SVF version discrepancies (i.e., SVF1 vs. SVF2)? If yes, any suggestion to resolve it?
Moreover, some models were not correctly processed when I tried to extract model data using the second example code (i.e., ForgeXLS.js example). The code was not processed after calling "prepareTables" function. It seems like it has issues to conduct "getMetadata", "getHierarchy", and "getProperties" functions. Could you let me know some possible reasons?
SVF version discrepancies
yes, the dbId of SVF is not consistent in all versions of the model. SVF2 dbId can be same in different versions, but the ideal is to take advantage of external id of the object. i.e. build a map from the first version of the model with external id. When you want to use dbId, search the dbId by external id
extract model data using the second example code (i.e., ForgeXLS.js example)
I'd believe it is just because the metadata / properties of the model version sis too large. you may try to add the header forceget when fetching the properties
https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-metadata-guid-properties-GET/

How to create a model browser like objects from Model Derivative API metadata

I am using this call provided by Forge API to get all Model metadata properties.
https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-metadata-guid-properties-GET/
I am getting all parent and child objects returned as separate nodes in the json that I am getting in the response. There is no linkage or relationship property saying that object X is a parent of object Y like we get in Model Browser option of Forge Viewer.
Is there a way possible that we can create this object tree after getting the metadata from Forge Model Derivative API. I really appreciate you help.
You can take advantage of the buildModelTree mentioned in this thread to rebuild the instance tree hierarchy:
https://stackoverflow.com/a/60807152/7745569

Is it possible to load only one specific object from the model(document) when initializing the document in the Forge viewer?

We would like to know if it possible to initialize the viewer to only render an specific object id.
There is a tutorial to extract geometry from a model, but it involves using the derivative to convert geometry to OBJ.
https://forge.autodesk.com/en/docs/model-derivative/v2/tutorials/extract-geometry-from-source-file/
The idea is to create a catalog of objects based on the elements in a model (document). We usually work with Revit files.
Viewer works with dbIds (or nodeIds which are equivalent to objectIds) and may load bubbles (geometry constructs) selectively based on - see live sample here
viewer.loadModel(svfUrl,{ids:[dbIds...]})

Not able to completely hide model in forge viewer

I am trying to hide the complete model in forge-viewer, for that I am calling forge visibility API as follows:
viewer.impl.visibilityManager.setNodeOff(viewer.model.getModelId(),true)
where viewer is a object of GUIViewer3D.
But this is not hidding the complete model, some components in the model are still visible.
I think it is a bug in forge-viewer because if I pass a root node of model to setNodeOff() API it has to hide whole model. I am sure that there is only one model loaded in my viewer session.
Refer this image for the elements which are still visible after calling viewer.impl.visibilityManager.setNodeOff(viewer.model.getModelId(),true)
getModelId() returns model IDs, and the visibility APIs expect node IDs. In order to hide the entire model, consider the following:
viewer.hide(model.getRootId());
Could you try something for me...
Could you try adding the header 'x-ads-force':'true' to the POST job request when you are converting the .RVT file?
Here is the documentation on the API request...
https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/job-POST/#headers
Then, retrieve the URN and feed it to the Forge Viewer, as before, like this example:
https://forge.autodesk.com/en/docs/model-derivative/v2/reference/http/urn-manifest-GET/#example
.
So... What's going on?
When you convert a RVT to a SVF (for the the Forge Viewer), it produces a random set of DBIds.
When you call the GetProperties API, it uses that cached SVF to pull the DBIds and provide you with a result.
Back in August, the GetProperty API engine, was updated. It produces a different order of DBIds compared to the old converted SVF.
Since the old SVF is cached, even if you submit a new job, it will use the old SVF.
To avoid the old SVF, we need to 'force convert' the RVT to SVF conversion, to flush that cache, so that the new SVF is visible and the Forge Viewer can retrieve it.
Once the Forge Viewer can see the new SVF, it should match the DBIds of the GetProperties API.
Complicated huh?
Let me know if that fixes the problem.
As my goal is to completely hide model from viewer, I achieved this by following:
viewer.clearSelection();
viewer.model.setAllVisibility(0);
viewer.impl.toggleGhosting(false);
viewer.impl.toggleGroundShadow(false);
This gives me the required behavior. The elements which I was not able to hide are now hidden through this approach.
to completely hide the model you can isolate an empty list, which will show the whole model ghosted, then you can turn off ghosting globally
viewer.isolate([]);
viewer.setGhosting(false);

zf2 json view script

We are currently trying to set up routes in such a way that the returned content-type can be set using a route parameter. The routing is all working properly now, but there is one problem. If one requests html, then the normal view script is rendered. The data we provide to this script can be anything from a string to a collection of objects, and the view script decides what to show to the user.
If however JSON response is requested, then we just provide the data returned from our controller as JSON. However, some data should not be made publicly available to the user, and hence some filtering is required. Is there any possibility to use JSON view scripts (as in ZF1 with context-switch) in order to support such filtering? Or maybe another method?
There is no such thing as a JSON script which lets you decide what to render and what not. You have to provide the proper data in the view model such that only the data is given that is eligible to be displayed.
I have been thinking about a hook in the JSON renderer so you can filter the view model's data based on the context of the request, but such thing does not exist yet. Unfortunately, you have to select the data in your controller or model.