I’m experimenting with taking results from the iTwin Changed Elements API and visualizing those results by highlighting the changed elements in CesiumJS, using a tileset from the Mesh Export API.
The Changed Elements API returns a list of elements that have changed and their corresponding ID’s. To highlight them I’m currently setting up my styling in a rather brute force way, essentially one styling condition per element, like below. If the API returns 10000 elements, there will be 10000 styling conditions.
Any chance you have a sandcastle you can share that replicates what you’re seeing?
Does the performance degradation occur more noticeably with the inclusion of the styling conditions? Or is it more just the number of elements, and the styling just makes it worse?
If the bottleneck is really the styling, I wonder - can the iTwin APIs be configured to add a field to the mesh export tileset, like changed or something. Then you could just have a single styling condition based on whether ${changed} === true. (I’m not really familiar with these APIs yet).
@mzschwartz5 my only examples are private data but I’ll try to pull together an example Sandcastle today with some other data.
Degradation is certainly only when styling is on - and only when the conditions array is large.
Most use cases are quite dynamic - make a query and visualize the results. So baking in to a mesh export isn’t really going to work for most scenarios.
Aside from some intermediate preprocessing step that would bake in the data to the mesh export, the only thing I can think of (though not necessarily the only option that exists) would be to upload the model elements to a Texture where a changed element gets a white pixel value and an unchanged element gets a black pixel value.
Then write a CustomShader that samples that texture. As an example of how to create the texture sampler, see this sandcastle (specifically starting at the function makeCheckerboardTexture).
From a quick look at the stack trace, it looks like the value of the ${element} is fetched from the model for each condition. A quick shot would be: ~“Maybe that can somehow be ‘cached’?”. I tried wrapping that into some defines: { ${cachedElement} ... variable, but that didn’t help - it is still delegating down to the whole evaluation. Maybe there is another option, but it’s unlikely that this is possible within the styling language alone. (There’s probably a way to optimize this in CesiumJS, but that would have to be investigated dedicatedly).
The other solution would, of course, be to add a switch in the styling language…
It might be worth looking at BIM Design Model with 3D Tiles and seeing if that approach would scale to hundreds of elements. It progressively builds an element ID to Cesium3DTileFeature[] map so that when an element ID is selected it automatically knows what features to update (setting feature.color instead of using the styling language).
Definitely more complex to implement and I would be worried about elementMap growing too big, but this approach should be much more performant.