################
Loading subtrees
################

Overview
========

One of the key features of HOOPS Communicator is the ability to load not just a single model into the viewer but to aggregate models freely and with optimal performance while still maintaining full access to the product structure and hierarchy. In this chapter, we will discuss the functions in the HOOPS Web Viewer API that facilitate this type of model aggregation. HOOPS Communicator also supports the related concept of "shattered" assemblies which will be discussed in the next chapter.

To load a model after the HOOPS Web Viewer API has been initialized with either an empty or initially loaded model you must call one of the loadSubtree functions. We will discuss the different variants of those functions shortly, but they generally take the ID of the node under which the new model should be attached as well as the name of the new model. For example, the single line below attaches a model called "microengine" under the node with ID 24. The newly attached model inherits the net matrix of its parent node, meaning that its 3D location in relation to the rest of the model will depend on the node hierarchy above it.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_loadsubtree.ts
	   :start-after: //! [webviewer_loadSubtree]
	   :end-before: //! [webviewer_loadSubtree]


'loadSubtree' variants
======================

The ``loadSubtree`` functions for SCS (non-server) loading and loading via the HOOPS Server have different function signatures but similar functionality. Below we will group those functions depending on whether they are operating on a single model or an XML file describing a product hierarchy.


Functions that operate on a single model
========================================

* :ref:`loadSubtreeFromModel <api_ref/viewing/classes/Communicator.Model:loadsubtreefrommodel>`
* :ref:`loadSubtreeFromScsBuffer <api_ref/viewing/classes/Communicator.Model:loadsubtreefromscsbuffer>`
* :ref:`loadSubtreeFromScsFile <api_ref/viewing/classes/Communicator.Model:loadsubtreefromscsfile>`

The above functions take the ID of the node under which the model should be attached as their first parameter and the model name (model URL or Uint8Array in the case of SCS files) as the second parameter. The third, optional parameter is a configuration object that defines additional parameters. (You can get more info on the LoadSubtreeConfig object :doc:`here </api_ref/viewing/classes/communicator.loadsubtreeconfig>`). All ``loadSubtree`` functions return a promise that resolves after the model has been successfully attached.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_loadsubtree.ts
	   :start-after: //! [webviewer_loadSubtree2]
	   :end-before: //! [webviewer_loadSubtree2]

The code above first creates a new node under the global root node and inserts a new SCS model into that node with visibility initially turned off. After the promise that this function returns has successfully resolved, all the model tree-related information is available, but some mesh geometry might not yet be loaded.


Functions that operate on an XML product hierarchy file
=======================================================

* :ref:`loadSubtreeFromXmlFile <api_ref/viewing/classes/Communicator.Model:loadsubtreefromxmlfile>`
* :ref:`loadSubtreeFromXmlBuffer <api_ref/viewing/classes/Communicator.Model:loadsubtreefromxmlbuffer>`
* :ref:`loadSubtreeFromScsXmlFile <api_ref/viewing/classes/Communicator.Model:loadsubtreefromscsxmlfile>`
* :ref:`loadSubtreeFromScsXmlBuffer <api_ref/viewing/classes/Communicator.Model:loadsubtreefromscsxmlbuffer>`

Instead of a single model, the functions above operate on an XML product hierarchy file (provided either as a URL or a text buffer) and generate a product structure from that XML definition under the specified node. This XML structure references other SC models that will be attached automatically to the current model. We will discuss the format of this XML file as well as the general use-case for this type of "shattered" usage in the next chapter of this Programming Guide.


Node ID offset
==============

When attaching a new model to an existing model, the HOOPS Web Viewer component "shifts" all node IDs of the new model by a fixed amount to avoid conflicting node IDs (two nodes sharing the same node ID) when multiple models are loaded. When you try to connect your user data or business logic with a model, you might want to retrieve the original node IDs for the model. To accomplish this, you need to get the "offset" value for a given node and subtract this value from the current ID of the node. The function :ref:`getNodeIdOffset <api_ref/viewing/classes/Communicator.Model:getnodeidoffset>` retrieves this offset value for a given node:

.. literalinclude:: /../../applications/client/docs/PG_Viewing_loadsubtree.ts
	   :start-after: //! [webviewer_loadSubtree3]
	   :end-before: //! [webviewer_loadSubtree3]
