Getting the model object properties in the right display units - autodesk-forge

I need to show all the properties of a selected object in the viewer. Is there a method that translates the native model information taking in consideration the units selected by the user in the viewer config? That is, if the model contains information expressed in imperial units and the viewer's Display Unit is set as millimeters, is there a way to automatically convert the different units?
I found the autodesk.unit.unit list in this post related to Revit but I haven't found useful information about this topic in Forge documentation.

If you want to change the display unit by Viewer API, here is the code snippet:
// Display units
viewer.prefs.set(Autodesk.Viewing.Private.Prefs.DISPLAY_UNITS, 'm');
// Display Units Precision
viewer.prefs.set(Autodesk.Viewing.Private.Prefs.DISPLAY_UNITS_PRECISION, 4);
//Get human-readable unit names
Autodesk.Viewing.Private.displayUnits
//Get values for changing display units
Autodesk.Viewing.Private.displayUnitsEnum
//Get human-readable Display Units Precisions
Autodesk.Viewing.Private.displayUnitsPrecision
//Get values for changing Display Units Precisions
Autodesk.Viewing.Private.displayUnitsPrecisionEnum
Or you can also consider using Profile settings: https://forge.autodesk.com/en/docs/viewer/v7/developers_guide/advanced_options/profiles/
const customIfcProfileSettings = {
settings: {
displayUnits: 'm',
displayUnitsPrecision: 4
}
};
const customIfcProfile = new Autodesk.Viewing.Profile(customIfcProfileSettings);
// Updates viewer settings encapsulated witihn a Profile.
// This method will also load and unload extensions referenced by the Profile.
viewer.setProfile(customIfcProfile);​

Related

Temporal Analysis using SoilGrids -GEE

SoilGrids provides the mapping of different properties of soil. I have executed their sample code on Google Earth Engine and it's working fine:
var sand_mean = ee.Image('projects/soilgrids-isric/sand_mean')
//print example image metadata and description
print(sand_mean)
//Add all layer to Map
Map.addLayer(sand_mean.select('sand_0-5cm_mean'),{min: 50, max: 1000,palette: ['5d5851','635a4b','6a5b44','715c3d','785e36','7e5f30','856129','8c6222','92641c','996515','a0660e','a66808','ad6901']},'SoilGrids250m 2.0 - Sand content ISRIC_0_5cm')
//Set basemap to Hybrid view
Map.setOptions('HYBRID')
But my question is can we do temporal analysis using soilGrids? I can't find filterDate property. So, is it possible to see the change in the subsequent years (temporal analysis)?

Forge viewer: how to isolate custom objects?

We use custom objects to visualize ifc space data (mostly rooms). As a guidance, we used this very helpful blog. After drawing the objects, we would also like to select the custom objects from outside and isolate them in the viewer. As the tutorial suggests, we change the model builder's changeFragmentsDbId function to set DbIds that do not exist yet and therefor do not overlap with already existing DbIds. One approach is to use the negative space [-1, -2, -3...] for our custom objects DbIds like this:
const roomFragId = this.modelBuilder.addFragment(roomGeometryId, materialName, transform);
this.modelBuilder.changeFragmentsDbId(roomFragId, -roomFragId);
Another one is to find the maximum DbId (eg. 4905) and use numbers higher than this maximum DbId for our custom objects DbIds (eg. [4906, 4907, 4908...]):
const roomFragId = this.modelBuilder.addFragment(roomGeometryId, materialName, transform);
this.modelBuilder.changeFragmentsDbId(roomFragId, maxDbId + roomFragId);
However, when we try to isolate a custom drawn object (viewer.isolate(-1) or viewer.isolate(4906)), the viewer kind of refreshs itself, but no object gets isolated...
Thus, we would like to know how we can isolate custom objects?
The other way, when we select the object in the viewer works for the negative space approach => we get the DbId (eg. -1) in the aggregate selection event.
Thank you for any kind of help!
To isolate or select custom objects created by the SceneBuilder ext, you need to pass model object to Viewer3D#isolate / Viewer3D#select like the below. Otherwise, viewer will use viewer.model instead.
viewer.isolate( [4906, 4907, 4908...], this.modelBuilder.model )
viewer.select( [4906, 4907, 4908...], this.modelBuilder.model )

combine model on Autodesk Forge

I have couple of questions about combine model on forge viewer (load list urn to 1 viewer):
when i combine model. i only can get data from 1 main model in that combine. for instance, 
var instanceTree = GlobalViewer.model.getData().instanceTree;
var allDbIdsStr = Object.keys(instanceTree.nodeAccess.dbIdToIndex);
var list = allDbIdsStr.map(function (id) { return parseInt(id) });
list will return all dbid of main model, how can i access all data of all model when i combine?
what is the unique id for object in combine model. i do some function with dbid and i realize it can appear in others model too.
When i combine 3d model(revit) with 2d model(autocad). it has 2 case: if 3d model load first i can rotate like normal, if 2d model load first i cant rotate the model any more. how can i force it always can rotate?
Autocad unit seems different with model in viewer. it always scale down compare with the model. how can i fix that?
Appreciate any comments,
Regarding #1: viewer.model obviously only references one of the models (I believe it's the last one you loaded), but you can use viewer.getVisibleModels() or viewer.getHiddenModels() to get other loaded models as well.
Regarding #2: dbIDs are only unique within a single model; many of the viewer methods accept an additional parameter specifying the model on which to operate, for example, you could say viewer.select([123, 456], oneOfMyModels).
Regarding #3: that's a good question; loading a 2D model first puts the viewer into 2D viewing mode (where only zoom and pan is allowed); if you know you will be working with 3D models, I'd recommend always loading those first
Regarding #4: yes, each loaded model can have different units; when loading a model using the loadDocumentNode method you can specify additional options (for example, a placement transform for the loaded geometries), and one of them is an object called applyScaling, for example, like so:
viewer.loadDocumentNode(doc, viewable, {
applyScaling: { to: 'mm' }
});

Autodesk Forge External ID for Navisworks File

We are trying to export dimensional properties for elements using Forge Viewer with getBulkProperties method. For Revit files, the method works fine, but for Navisworks files, we cannot get any useful properties directly.
As we investigate into the problem, we found that the all the externalId for Navisworks file are in the format of slash separated integers (e.g. 1/2/2/1/1). If we chop off the last integer from externalId (in this case, using 1/2/2/1), and get the properties of the corresponding element, then we can have some useful dimensional properties, and the value matches the information we see on desktop version of Navisworks.
Does the externalId for Navisworks encoding implies a tree structure? (I am assuming 1/2/2/1 is the parent of 1/2/2/1/1 in this case). What could explain our issue that by just chopping off the last integer, we can get the information we need? Is this a reliable way to get dimensional properties?
A small experiment to reproduce this in Chrome console:
selected = AutodeskViewer.getSelection()[0]
AutodeskViewer.getProperties(selected, console.log)
/* {dbId: Array(1), properties: Array(0), externalId: "12/6/0/0/0/0"} */
/* We don't have any useful properties here */
// Get External ID mapping
map = {}; AutodeskViewer.model.getExternalIdMapping(ext_map => {map = ext_map})
// Chopoff the last integer, and run getProperties again
AutodeskViewer.getProperties(map['12/6/0/0/0'], console.log)
/* {dbId: 78085, properties: Array(151), externalId: "12/6/0/0/0", name: "Floor"} */
/* We get useful dimensional properties */

How to use Ext.state.LocalStorageProvider?

How to setup Ext.state.LocalStorageProvider so it saves states for all items?
LocalStorageProvide is a HTML5 Local Storage wrapper for Ext JS. You can make use of the local storage provided the browser you use support it.
The storage is based on key/value pairs. You can store up to 5MB (I think thats the specification and some browsers don't provide that much space. I am not sure of the size limit) and use simple APIs of the LocalStorageProvider to store and retrieve data. Storing the state is NOT automated! You should know when to store, and when to retrieve!
You can make use of the set & get method to store and retrieve values. Here is an example:
var store = Ext.state.LocalStorageProvider.create();
store.set('record',rec); //This could be a object like (Ext.data.Model)
You can retrieve the data (may be in initComponent of a form etc) using:
var rec = store.get('record');
form.loadRecord(rec); // Load the form with the saved data...