Missing revit ID in instance elements - autodesk-forge

When processing a translated model's data using the get properties request in the forge model derivative API, a model I'm testing doesn't return the revit ID as part of any instance element. The format I'm used to seeing is something like "Railing [5707296]" for a railing instance element, but the properties JSON response don't show the [5707296] in the result. Is this a recent change with the API? Is there a setting I need to enable this? The revit ID is a useful value for us and we'd like to retrieve it. It's strange that the viewer shows the ID, as expected, but that same entity in the get properties request does not show the ID. This is from a Revit 2022 model.
JSON response:
...
{
"objectid": 410,
"name": "Railing", // <-- I would expect this to be "Railing [5707296]"
"externalId": "1c277e31-8d23-4dc2-96e6-b1ac60f1c07a-0053ce49",
"properties": {
...
}
},
...
Same element selected in the viewer shows the name I would expect:

Thanks to Eason & Jeremy, I learned that the last substring of the externalId is a hex-encoded representation of the Revit element ID. This means that I can derive the Revit element ID from the externalId, and I don't need to parse it from the element name.
const externalId = '110717dd-74ae-4656-b586-fb1c03e9905a-00030954';
const splitArr = externalId.split('-');
console.log(parseInt(splitArr[splitArr.length - 1], 16)); // 198996 ✅
Source: https://thebuildingcoder.typepad.com/blog/2009/02/uniqueid-dwf-and-ifc-guid.html

Please note that the Forge externalId probably corresponds to the Revit UniqueId. I would recommend always using the unique id to identify elements, if possible, since it is more reliable than the element id.

I think this is happening because of SVF2/OTG. The Revit ID is also missing in the viewer when forcing the new format with https://forge.autodesk.com/en/docs/model-derivative/v2/developers_guide/notes/
Seems like there is no simple way to get the Revit ID at the moment. Maybe a workaround is possible using something like https://forge.autodesk.com/blog/temporary-workaround-mapping-between-svf1-and-svf2-ids (see Alex's accepted answer for a good workaround)
Edit: I just realized that the missing Revit Id in my viewer was the result of a poorly implemented custom property panel. Everything works as expected using the default property panel.

Related

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 )

Model object properties identification

We are using SQLite property database to get information about object's properties. The problem we are facing with is property identification. For each property we have:
id: looks like it is just an autoincremental id and it can be used to
identify property between two versions of the same model
name: for .rvt models it is mostly unique, but there are some duplications
sometimes (for example the same property with different flags,
readonly and not); for .ifc files it is not unique at all
category + displayName: the problem with this
fields is that after using design automation API (to change and
re-save model) category/displayName can be translated into English
(but initially they can be, for example, in German)
Now we are using the combination of 'name + category + displayName' to identify the property, but it is not the solution, because this combination still is not unique in some rare cases (it is data lost for us) and it doesn't solve the problem with property names translation using Design Automation API.
Any ideas how to identify properties will be helpful! Thanks
For a given element, the externalId should be unique within that model (at the model level, the urn is unique). There is no unique identification for properties.
I'm interested in understand this workflow better, are you able to have a quick talk? Please use this link to book a time.

data.medicare.gov/resource/4pq5-n9py.json Numbers as Dates

Calling the API https://data.medicare.gov/resource/4pq5-n9py.json returns erratic results.
{
...
"reported_cna_staffing_hours_per_resident_per_day" : "2.53304",
"cycle_2_number_of_complaint_health_deficiencies" : "2017-06-22T00:00:00",
"cycle_2_health_deficiency_score" : "0",
...
}
I believe cycle_2_number_of_complaint_health_deficiencies should be a number. The data on the website is correct so I'm assuming that it is a problem with the API
It appears that field is defined as a floating timestamp. It appears the human readable name, Rating Cycle 1 Standard Survey Health Date, differs from the API name which you see on the API call. Looks like it's more an issue with confusing naming conventions.
Take a look at the metadata page for the underlying API names.

In CouchDB how do you take in parameters from REST call

Hi so I'm new to CouchDB looks great so far, but really struggling with what must be simple to do!
I have documents structured as:
{
"_id" : "245431e914ce42e6b2fc6e09cb00184d",
"_rev": "3-2a69f0325962b93c149204aa3b1fa683",
"type": "student",
"studentID": "12345678",
"Name": "Test",
"group: "A"
}
And would like to access them them with queries such as http://couchIP/student?group=A or something like that. Are Views what I need here? I don't understand how to take the parameter from the query in the Map functions in Views. example:
function(doc,req) {
if(req.group==='A'){
emit(doc.id, doc.name);
}
}
Is my understanding of how Couch is working wrong or what's my problem here? Thanks in advance, I'm sure this is Couch 101
Already read through http://guide.couchdb.org/ but it didn't really answer the question!
You need views to achieve the desired results.
Define the following map function inside a view of a design document. ( let's name the view "byGroup" and assume this lives in a design document named "_design/students" )
function(doc) {
if(doc.group){
emit(doc.group,null);
}
}
Results can be obtained from the following url
http://couchIP:5984/dbname/_design/students/_view/byGroup?startkey="A"&endkey="A"&include_docs=true
To have friendly url couchdb also provides url rewriting options.
You need to some further reading about views and the relevance that they return key/pair values.
It's not clear what you want to return from the view so I'll guess. If you want to return the whole document you'd create a view like:
function (doc) { emit(doc.group, doc) };
This will emit the group name as a key which you can lookup against, the whole doc will be returned as the value when you look it up.
If you want to just have access to the names of those users you want to do something like:
function (doc) { emit(doc.group, doc.name) };
Your question arises from a misconception about what a view does. Views use map/reduce to generate a representation of your data. You have no control of the output of your view in your query because the view is updated according to changes in your DB documents only.
Using a list is also not a good option. It may seem that you can use knowledge of your request in your list to generate a different output depending on the query parameters but this is wrong because couchdb uses ETags for caching and this means that most times you will get the same answer regardless of your list parameters since the underlying documents won't have changed. There is a trick though to fool couchdb in this case and this implies using two different alternating users but I wouldn't even try this way because surely there are easier ways to achieve your objectives and you can probably solve your problem using group as a key in your map function.

Vaadin edit json response

Im using Vaadin as the framework to represent a presentation layer for my application.
I have a trouble with the Vaadin Table listing. I load 1000 rows with 5 columms (yes I need to load all 1000, there is also an option to load less. =)) but this is not very fast when using Vaadin. When I look at the Json sent I realize that there are lots of variables that i dont whant to be sent for everu table row.
This is the response i have as of now:
"domaindom-000000938.co_uk",
["17",
{"id": "PID783","readonly":true,"locale": "en_EN","format": "yyyy-MM-dd","strict":true,"wn":false,"parsable":true,
"v":{"day":7,"month":2,"year":2011}}],
["17",
{"id": "PID784","readonly":true,"locale": "en_EN","format": "yyyy-MM-dd","strict":true,"wn":false,"parsable":true,
"v":{"day":7,"month":2,"year":2011}}],
["17",
{"id": "PID785","readonly":true,"locale": "en_EN","format": "yyyy-MM-dd","strict":true,"wn":false,"parsable":true,
"v":{"day":7,"month":2,"year":2012}}],
"","","ENG"],
["tr",{"key":206},"
I would like to transform this Json to be more like
"domaindom-000000938.co_uk",
["17",
{"id": "PID783","locale": "en_EN",,"strict":true,"wn":false,"v1":"2011-07-02", "v2":"2011-02-07", "v3":"2012-02-07"}],
As you can see I have removed a couple of variables and inserted the date varialble in the same clauses.
So my quiestion is this. In Vaadin, how do I modify the way Vaadin creates the Json response? I currently use the BeanItemContainer to hold my objects like this:
public BeanItemContainer getPagedDataSource(){
List<Object> mylist = DAO.getDAO().createQuery(query, index, max);
return new BeanItemContainer<Object>(type, mylist);
}
Thanks for any help or feedback!
/Marthin
First, that JSON is part of Vaadin's internal communication and you should not modify it. However, if you wish to check it out, it is the JsonPaintTarget along with the paintContent-method of the component in question (the Table) that creates the JSON.
Vaadin today operates in an unprecedented way. Everything will change in the application must be sent to the client. On the client side, each component is treated separately and therefore the response must address all components changed.
Each row in the table is a separate component because the answer is so long.
My proposed solution:
write your own implementation of the table - hard
the imposition of restrictions - easy, but it's prosthesis