Preparing your viewing application for multi-model workflows
Being able to aggregate, as we call it, multiple models in a single scene within the Forge viewer is really a recurring topic across all the Cloud Accelerators that my team and myself have been delivering all around the globe.
If your application doesn't handle multi-model scenarii yet, I bet there is a good chance that sooner or later it will require it... So in order to avoid painful refactoring at an advanced stage of your development, it is a good idea to start planning from the scratch.
I already wrote an article on that topic in the past: Model Aggregation Exposed, but today I'm proposing a base template class from which you can derive your viewer extensions that will abstract away some of the plumbing work for you.
When dealing with multi-model workflows, I can think basically about 3 kind of extensions:
- Let's start with the easy ones: extensions that do not care about the models. For example a Screenshot Manager. In that case the extension logic is not affected by loaded models and the code can work the same with any number of models without the need to implement some special handling. This will rarely be the case however.
- Extensions that can handle only one model at a time: for example a chart or graph of some sort that represent visually some properties of the model. In such a case, you may want to consider one of the model as "active" and display the graphics for a single one. You will then need to implement a mechanism to set one of your model active and reload the extension data at this point.
- Extensions that can handle multiple models simultaneously, for example one that contains a treeview or a dropdown menu where all the currently loaded models are represented. In such a case the extension will need to be notified every time a new model is being loaded or has been removed and update its controls accordingly.
In order to simplify the implementation of such "multi-model aware" extensions, I created a base class that my extensions can derive from. The base class acts as an interface which is responsible for setting up all the required event handlers and invoke predefined methods which can be implemented by the derived extension if this one is interested in dealing with that event. I found this gives a lot of structure and avoid code repetition in the extensions I am writing now.
For this to work properly you will need to have one of the extension managing the models: for example exposing controls to load, unload, activate models, and firing events when those actions happens. That is a topic I will present in a later post. Below is the code of the MultiModelExtensionBase.
My first extension supporting multi-models simultaneously is the Selection Filter: give a try at that live demo and load an extra model to the scene. The treeview will show another root entry where you can see each model structure and toggle the selectability of each component.