Today’s post is a follow-on from the first part where we looked at integrating Hyperion sprites into Dasher. (The posts are independent, though, so you don’t have to read the first one if you’re only interested in integrating heatmaps.)
I was supposed to publish this at the beginning of the week, but I ended up getting bogged down by a couple of urgent projects – both of which I’m happy to say have led to me making some interesting enhancements to Dasher, which is, at least, something.
Anyway, the topic I wanted to share is the approach for integrating Hyperion’s surface shading back into its original host (i.e. Dasher). I was highly apprehensive of this task, I fully admit: I’d understood that I needed to have a Revit-based workflow with AECModelData available (and even to generate master views) for our model: neither of which is available to us with Dasher’s Navisworks-based workflow. (We export NWC files from Revit to avoid the messiness of dealing with multiple files, and – and this was the primary driver – this approach gave use rooms back before the master views capability was introduced into Forge’s Model Derivative service.)
The good news was that when looking into the process to set up the surface shading environment, I realised there’s an optional RoomLevelsMap you can pass in if you have the mapping between levels, rooms and sensor devices established elsewhere. This was all information we derive through Forge properties and project configuration settings, so it was actually pretty easy to populate this object and pass it in. Here’s the code that does that (although it does rely on some state inside Dasher, so you should think of this as pseudocode in case you need to implement something similar):
Otherwise the implementation was pretty painless: I just followed the excellent instructions in the documentation provided by the Hyperion team.
There was an additional step needed to generate fragIds for the various room objects: this is normally done automatically by a call to SurfaceShadingData.initialize(model): it turned out that for Navisworks models to work, the call to enumNodeFragments() needed to have the third parameter (requesting the operation to recurse) set to true, as the default is false. And because Navisworks probably has a more fragmented (or perhaps indirect) approach when it comes to geometry organisation, so the fragment is not a direct child of the geometry. Or something like that. I admit I don’t understand all the ins and outs of this. Anyway – this has now been fixed in an internal release, and will make its way into a public one before we know it. (Just bear this in mind if you’re implementing heatmaps for Navisworks models using v7.43 – perhaps even v7.44 – or earlier of the Forge viewer and the heatmaps aren’t showing up: it might well be due to this issue.)
Integrating Hyperion is certainly allowing me to rip out big chunks of old Dasher code, which feels so good. I also switched across to use their hideTextures() method (inspired by a similar Dasher feature), and decided to demote the UI for enabling the hiding of textures to the user settings, rather than taking up space in the Dasher toolbar. While I was at it, I rejigged the icons for some of features that were staying: we now have a paint drop for surface shading, and used the eye that it had before for occlusion (this makes more sense, frankly). We also replaced the sensor dots icon – which was previously a set of scales, to indicate measurement – for a pin/placemarker, which I feel is more logical.
It’s frankly awesome to see how well Hyperion has slotted into Dasher, and how well it performs. The team has done a great job of streamlining the original implementation and making it easy to consume/adopt. There are still types of heatmap that we manage on our own, for now – the 2D panels that allow you to compare different sensor types, but also the Types By Level UI – but it’s great to be able to gradual reduce the amount of code in the project (although, being honest, the code ends up building up elsewhere in the codebase, soon enough.)
In the end I did start looking at what it would take to switch across to using Revit for our models. It is pretty easy to host multiple models with a single master model inside BIM360 – you just need to upload using "the “upload linked files” option. So far so good. I did need to make some tweaks to Dasher to allow it to deal with the different property structure available inside Revit models – as the export process does shift the hierarchy around somewhat – but it wasn’t too hard. I did find the coordinate space to be different between the two environments, which meant that sensors placed locally in Dasher (rather than being defined by the model) needed some remapping, as well as the initial view onto the model.
All of this was just grunt work and straightforward enough to work through. The main blocker came when I tried to use Hyperion with the master views generated for my model: it turns out that master views do not pick up geometry (including rooms) stored in linked models. Which is definitely an issue for the way our main Dasher model has been built, as rooms are stored in the model for the respective unit (the NEST building is highly modular). Many thanks to Eason Kang from the Developer Advocacy and Support team for his help digging into this problem. I’m hoping the Hyperion team (or the DAS team, for that matter) is able to share something to help with this, as it would be unfortunate if every developer hitting this had to build something themselves. I’m looking forward to implementing a Revit-based workflow in Dasher, and this seems to be the main outstanding blocker.
This was a look at what it took to integrate volumetric heatmaps for rooms, which has historically been the main focus of Dasher. We do apply heatmaps to the surface of objects – such as the MX3D bridge – so I’m going to spend some time looking at that over the coming weeks, too. As an alternative to volumetric shading of rooms, the Hyperion team have also provided a planar heatmap that can be put at the bottom or top of your room volumes – depending on which makes most sense – I also expect to spend some time looking at that, too.