In Dasher we have some interesting functionality to isolate parts of the building by level. This is increasingly something you can do via “out of the box” Forge viewer functionality, but we’ve found a couple of reasons to go beyond that basic capability:
- Not all elements or objects are assigned to the correct level.
- Some elements – such as those belonging to the building facade or perhaps internal pipes – transcend levels, and so don’t behave well.
It’s of course possible to split elements/objects that belong to the second category, but we tend to take the approach of allowing certain objects to be hidden completely from the “per-level” view of a building. This allows us to add things like ceilings or lights to the list, which allows the individual levels to be displayed much more cleanly and in a way that’s more useful to the user.
Originally when we implemented this “ignoreAtLevel” list, we did so as a list of dbIds. This was overall a bad idea, as it wasn’t sustainable from version to version of a model. After that we tried using the Revit ElementId, which was a little better at dealing with versions, but was still subject to problems. In the end we decided to maintain a list of elements’ UniqueIds: while not guaranteed to be unique (for more on this topic read Jeremy’s excellent post) they are much less likely to get remapped when combining model content from multiple sources or with models being edited in a worksharing environment.
When I first created these list it was a really manual process: I went through and selected each object to be hidden – one by one – and then used the Model Browser to get the object’s grandparent in the hierarchy. This was usually the object that contained the UniqeId for that particular element. What a pain!
This worked for a while, but clearly doesn’t scale well. So I decided to implement a mechanism that allows you to select objects in the Forge viewer and then query their UniqueIds (via the object itself, its direct ancestor or its grandparent) and then get a list of these UniqueIds that can be copy & pasted into the JSON settings file where we persist this information.
For this I needed a helper function that takes a list of dbIds (those selected in the viewer) and returns a list of property values (whether UniqueIds or something else). We use TypeScript, but it should be easy for people to convert it to JavaScript, as needed.
Calling this function, passing in a catName of “Element Properties” and a propName of “UniqueId”, results in UniqueIds for the specified dbIds being passed into the callback function for storage or display to the user.
To make it easier to manage what objects have been added to our “ignoreAtLevel” list, I also decided to go the other way and let the user request the viewer to select all the objects that have been listed there. For this I needed another helper function that creates a list of dbIds from a list of UniqueIds.
The results of calling this method can then be set to the viewer’s selection property.
The typical workflow I have in mind is to gradually build up the list of objects you want to hide – selecting them in chunks, to avoid messing up and having to start over – and then capturing their UniqueIds and adding them to a list (in the text editor of your choice). Once the list is “complete”, you can request to select these objects in the viewer and then request UniqueIds for the selected objects for saving to your settings. (I know this sounds circular, but it’s a handy way to rationalise the list, sorting it in order of the dbIds and removing any duplicate selections.)
All this is capability that has been added to Dasher for administrators to better manage projects, so isn’t something you can try out in the online demo, unfortunately. Nonetheless I hope thie technique is something that’s useful for people implementing comparable capabilities in their own tools.
I’m just about to head into our Soho office for my first full day at the first Forge Accelerator being held there. It’s really nice to see some familiar faces – more on this is a coming post.