#######
Loading
#######

The HOOPS Web Viewer component is very flexible when it comes to model loading, supporting a variety of streaming and loading modes with and without a server. While we have discussed the basic steps to load a model at the :doc:`beginning of this section </prog_guide/viewing/data_model/stream_cache/overview>`, we will delve a bit deeper into this topic in this and the following chapters.


Loading a SC model on startup
=============================

If your model is either a folder-based SC model or a compressed or uncompressed SCZ file it means that it needs to be loaded via a websocket connection from the server. In this case, you will have to specify the endpoint URI of the HOOPS Stream Cache Server instance in addition to the model name (which will have to be in a directory the server has access to):

.. literalinclude:: /../../applications/client/docs/PG_Viewing_scloading.ts
	   :start-after: //! [webviewer_scloading1]
	   :end-before: //! [webviewer_scloading1]	
	
Connecting to the server and requesting a server instance is a multi-step process which is outlined in our Building A Basic Application tutorial, as well as the Programming Guide:

* :doc:`Tutorial - Connection to the HOOPS Server </tutorials/basic-app/server-connection>`
* :doc:`Server Overview </prog_guide/servers/overview>`


SCS
---

For scs files, you will generally provide a relative path on your webserver where the SCS file is located. Any standard webserver will suffice as long as it can serve files and has permissions to access scs files in the specified directory.

.. literalinclude:: /../../applications/client/docs/PG_Viewing_scloading.ts
	   :start-after: //! [webviewer_scloading2]
	   :end-before: //! [webviewer_scloading2]
	
Behind the scenes, the HOOPS Web Viewer component is performing a standard HTTP Request to fetch the requested scs file. If you prefer to handle requesting and loading the scs file yourself, you can also pass a memory buffer to the WebViewer constructor. In that case, no endpointuri has to be specified:

.. literalinclude:: /../../applications/client/docs/PG_Viewing_scloading.ts
	   :start-after: //! [webviewer_scloading3]
	   :end-before: //! [webviewer_scloading3]
	
As mentioned in the previous chapter SCS loading (without a HOOPS Server) and loading of SC files through a connection with the HOOPS Server cannot be mixed. Which mode you are in is determined by how Communicator gets initialized. If you are starting with an empty scene this also applies.


Starting the HOOPS Web Viewer component without loading a model
===============================================================

To connect the HOOPS Web Viewer component to the HOOPS Server without loading a model you must provide "_empty" as the model name. Information about ``Communicator.EmptyModelName`` can be found :ref:`here <api_ref/viewing/modules/Communicator:emptymodelname>`:

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


No server connection
====================

To start the HOOPS Web Viewer Component without a server connection and without loading an initial model you have to set the empty parameter:

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


Streaming modes
===============

When a model gets streamed from the HOOPS Server you can choose between three different streaming modes that determine the extent of data that is initially streamed to the HOOPS Web Viewer Component. You can set the various streaming modes via the streamingMode parameter on startup:

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

	
Interactive
===========

This is the default setting for the viewer. In this mode, meshes will be streamed based on their relative size in relation to the active camera. Meshes that are not within the view frustum or below a certain size threshold will not be streamed at all and are left on the server until they pass the minimum size threshold and are inside the view frustum. Meshes that are initially hidden will also not be streamed until they are turned visible. You can adjust the minimum size from which meshes will be streamed by using the :ref:`streamCutoffScale <api_ref/viewing/interfaces/Communicator.WebViewerConfig:streamcutoffscale>` parameter. Properties and user data attached to a node will generally not be streamed and only send to the HOOPS Web Viewer Component when they are specifically requested.

This mode generally works well for most CAD data and ensures good interaction and memory footprint in the viewer by prioritizing the "big and important" stuff based on the current camera. Depending on the type of model you might want to adjust the ``cutoffScale`` value or use the "All" streaming mode. In addition, if your goal is to preserve *server-side* resources this streaming mode might not be ideal as it will require a server connection for the full duration of the viewing session.


All
===

The "All" mode still prioritizes meshes based on their size and if they are inside the view frustum but will keep streaming the model until it is completely loaded including geometry outside the view frustum as well as all user data. You can close the connection to the server (with :ref:`WebViewer.closeConnection() <api_ref/viewing/classes/Communicator.WebViewer:closeconnection>`) after the model has been completely loaded.

	
OnDemand
========

In this mode, only the basic model hierarchy will be sent to the HOOPS Web Viewer component initially. After the model structure has been loaded (see :ref:`here <tutorials/basic-app/hello-web-viewer:registering_callbacks>` for info on how to detect if the model structure is available). You can request nodes to be streamed to the client with the :ref:`model.requestNodes() <api_ref/viewing/classes/Communicator.Model:requestnodes>` function which takes an array of nodeids as input.

This streaming mode is useful if you want to give your users the choice of only loading a subset of a model into your viewer. This could be for performance reasons when dealing with potentially very large assemblies or simply because the user only wants to work on a subset of the model.

.. image:: images/loading-on-demand-model.png

*A model loaded in ``OnDemand`` mode with only a subset of the model requested by the user*


Determine if a model is fully loaded
====================================

If you are in streaming mode and are not using :ref:`streamingMode.All <api_ref/viewing/enums/Communicator.StreamingMode:all>` then chances are that at least some part of the model will still reside on the server so the model will never be fully loaded on the client meaning that you have to keep the server connection active for the duration of the viewing session.

However, if you are in :ref:`streamingMode.All <api_ref/viewing/enums/Communicator.StreamingMode:all>` (or you are viewing an SCS file) all the model data will eventually end up on the client. For SCS models, it is enough to simply wait for the :ref:`XHRonloadend <api_ref/viewing/interfaces/Communicator.CallbackMap:xhronloadend>` or :ref:`modelStructureReady() <api_ref/viewing/interfaces/Communicator.CallbackMap:modelstructureready>` callback to ensure that nothing went wrong with the file request. In ``streamingMode.All`` when connected to a server, the easiest way to detect that a model is fully loaded is to wait for the return promise using :ref:`WebViewer.waitForIdle() <api_ref/viewing/classes/Communicator.WebViewer:waitforidle>`.

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


Switching models
================

If you want to switch from one model to another and you are in streaming mode you can simply call :ref:`model.switchToModel() <api_ref/viewing/classes/Communicator.Model:switchtomodel>` with the name of the new mode you want to load. This will fully delete the current model and its associated resources and reset the viewer and its UI but will not invalidate the canvas that the HOOPS Web Viewer component renders to. This function currently only works for SC models loaded via the HOOPS Server. If you are not connected to the server and want to switch to a different scs file you can use the alternative method below:

.. literalinclude:: /../../applications/client/docs/PG_Viewing_scloading.ts
	   :start-after: //! [webviewer_scloading8]
	   :end-before: //! [webviewer_scloading8]
	
We will discuss the :doc:`loadSubtreeFrom... </prog_guide/viewing/data_model/stream_cache/loading-subtrees>` functions in detail in the next chapter.


Bounding previews
=================

Depending on your network connection and the size of the model it can take time before all the geometry of a model will be streamed to the client. In order to give the user of your application quick visual feedback and allow them to navigate in a model that has only been partially loaded the HOOPS Web Viewer component can display a relevant subset of the model as so-called bounding box previews. 

.. image:: images/loading-on-demand-model.png

*A partially loaded model with bounding previews enabled*

To enable bounding previews, you can set the :doc:`boundingPreviewMode </api_ref/viewing/enums/Communicator.BoundingPreviewMode>` parameter to anything other than ``None`` in the ``WebViewer`` constructor. You should experiment to see which works best for you.

