Forge InstanceTree getNodeType() returning 0 - autodesk-forge

I would like to filter the elements according to their native category (not using ACC) so I'm looking at the InstanceTree of the Viewer. According to the documentation the InstanceTree's getNodeType() method should return an integer (from viewer.js file NODE_TYPE should be: 0x0, 0x1, 0x2 ... 0x7), but what I get from my Revit model is always a value of 0. What does it stay for?
I'm interested to the abstract collection of objects (e.g. Doors)...is there a better approach?
Thanks

Even though the node types are exposed by the instance tree, they are more of an internal implementation detail that probably won't be helpful for what you're trying to do. FYI these are the meanings of the different values:
0x0 - NODE_TYPE_ASSEMBLY
0x1 - NODE_TYPE_INSERT
0x2 - NODE_TYPE_LAYER
0x3 - NODE_TYPE_COLLECTION
0x4 - NODE_TYPE_COMPOSITE
0x5 - NODE_TYPE_MODEL
0x6 - NODE_TYPE_GEOMETRY
0x7 - NODE_TYPE_BITS
If you're interested in classifying objects in models coming from Revit designs, you could use the standard Viewer API such as search, getProperties, or getBulkProperties, and use some of the object properties. For Revit designs specifically, each object will include a property called Category that can be something like Revit Doors, Revit Curtain Panels, etc.

Related

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

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.

Accessing regmap RegFields

I am trying to find a clean way to access the regmap that is used with *RegisterNode for creating documentation and testing files. The TLRegisterNode has methods for generating the json through some Annotations. These are done in the regmap method by adding them to the ElaborationArtefacts object. Other protocols don't seem to have these annotations.
Is there anyway to iterate over the "regmap" Register Fields post elaboration or during?
I cannot just access the regmap as it's not really a val/var since it's a method. I can't quite figure out where this information is being stored. I don't really believe it's actually "storing" any information as much as it is simply creating the hardware to attach the specified logic to the RegisterNode based logic.
The JSON output is actually fine for me as I could just write a post processing script to convert JSON to my required formats, but I'm wondering if I can access this information OR if I could add a custom function call at the end. I cannot extend the case class *RegisterNode, but I'm not sure if it's possible to add custom functions to run at the end of the regmap method.
Here is something I threw together quickly:
//in *RegisterRouter.scala
def customregmap(customFunc: (RegField.Map*) => Unit, mapping: RegField.Map*) = {
regmap(mapping:_*)
customFunc(mapping:_*)
}
def regmap(mapping: RegField.Map*) = {
//normal stuff
}
A user could then create a custom function to run and pass it to the regmap or to the RegisterRouter
def myFunc(mapping: RegField.Map*): Unit = {
println("I'm doing my custom function for regmap!")
}
// ...
node.customregmap(myFunc,
0x0 -> coreControlRegFields,
0x4 -> fdControlRegFields,
0x8 -> fdControl2RegFields,
)
This is just a quick example I have. I believe what would be better, if something like this was possible, would be to have a Seq of functions that could be added to the RegisterNode that are ran at the end of the regmap method, similar to how TLRegisterNode currently works. So a user could add an arbitrary number and you still use the regmap call.
Background (not directly part of question):
I have a unified register script that I have built over the years in which I describe the registers for a particular IP. It works very similar to the RegField/node.regmap, except it obviously doesn't know about diplomacy and the like. It will generate the Verilog, but also a variety of files for DV (basic `defines for simple verilog simulations and more complex uvm_reg_block defines also with the ability to describe multiple of the IPs for a subsystem all the way up to an SoC level). It will also print out C Header files for SW and Sphinx reStructuredText for documentation.
Diplomacy actually solves one of the main issues I've been dealing with so I'm obviously trying to push most of my newer designs to Chisel/Diplo.
I ended up solving this by creating my own RegisterNode which is the same as the rocketchip RegisterNodes except that I use a different Elaboration Artifact to grab the info and store it for later.

Where exactly does trainable_variables method belong in Tensorflow?

I'm a newbie in both deep learning and tensorflow and now trying to learn how to implement deep learning codes based on function API (not keras) by following example codes.
Inside the codes I'm looking at, I found out sources saying 'gradients=tape.gradient(loss,model.trainable variables)'
I intuitionally got what trainable variables mean, however in order to understand clearly,I tried to search on tensorflow documentation (which module or class the method belongs to, which are key arguments, etc) ,but I wasn't able to find the information I want. ('trainable variables' method was not in their documentation index and I'm wondering why)
So can anyone please tell me the module/class which trainable_variable method belongs to, and which arguments it takes, and also how it is able to judge and get all the trainable variables from the model ?
The reason you did not find this method is because trainable_variables is not a method, but an attribute/property. The Model class has a trainable_variables attribute, which is not documented officialy. It is inherited from the base class Layer, and to put it shortly, the list (of trainable variables) gets populated as new layers are added, since all layers have an init parameter trainable (this comes from base class Layer too). You can check the source code if you want to: "the source of the property", "adding new weights to layer appends to the list".

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.