#########
Sandboxes
#########

List of Sandboxes
=================

Note that the package hierarchy in the previous section includes *<gui>_sandbox*. Each platform includes a "sandbox", which is a sample application intended to be used as a starting point for prototyping, testing, and learning the API. Each sandbox contains a viewport and a set of manipulation operators, such as rotation, pan, and zoom. The sandboxes are precompiled and ready to use from your HOOPS Visualize package.

.. csv-table:
	:header: "Project name", "Supported OS", "Description"
	
	"mfc_sandbox", "Windows", "MFC GUI framework for C++"
	"wpf_sandbox", "Windows", "WPF GUI framework for C#"
	"cocoa_sandbox", "macOS", Cocoa GUI framework for C++"
	"qt_sandbox", "Windows, macOS, Linux", "Qt GUI framework for C++ and Qt Creator"
	"ios_sandbox", "iOS", "Cocoa-Touch framework for Objective-C/C++"
	"ios_arkit_sandbox", "iOS", "ARKit Augmented Reality Cocoa-Touch framework for Objective-C/C++"
	"android_sandbox", "Android", "Android SDK framework for Java/C++ and Android Studio"
	"arcore_sandbox", "Android", "ARCore Augmented Reality Android SDK framework for Java/C++ and Android Studio"
	"openvr_sandbox", "Windows", "OpenVR SDK framework for Virtual Reality applications"
	"qt_quick_sandbox", "Windows, Linux, Android", "Our cross-platform sandbox application for desktop and mobile platforms based on Qt Quick - requires Qt Creator"

After starting the sandbox of your choice, open a file using the main menu. Supported file formats are listed :doc:`here </general/supported_file_formats>`. Once the file is loaded, you'll see the model as well as a model browser and segment browser. Also note the various operators, such as orbit, pan, and zoom, which you can use to manipulate your view of the model.

.. _exchange:

.. only:: not spatial

	HOOPS Exchange
	==============
	
	If you have a HOOPS Exchange license, Exchange support can be added to the MFC, WPF, Cocoa, and Qt sandboxes.

	To use Exchange with the WPF sandbox, you must add ``USING_EXCHANGE`` to the list of "Conditional Compilation Symbols" in the WPF Visual Studio project file. You must also add a Reference in the Visual Studio project to *hps_cs_sprk_exchange.dll*. In the properties for the Reference to *hps_cs_sprk_exchange.dll*, set the "Copy Local" property to ``False``.

	To enable Exchange support in all other sandboxes, the project must be compiled with the ``USING_EXCHANGE`` preprocessor flag, and must be linked to *hps_sprk_exchange.lib*.

	When using the sandboxes with Exchange, you need to locate the Exchange libraries for the application by calling ``HPS::World::SetExchangeLibraryDirectory``. Alternatively, you may set the environment variable ``HEXCHANGE_INSTALL_DIR`` to the Exchange path.

	If you load an Exchange file which has configurations, the "Configurations" tab of the model browser will display a list of the configurations in the file. If you double-click on a configuration, that configuration will be loaded from the file, replacing the currently loaded model.

.. _publish:

.. only:: not spatial

	HOOPS Publish
	=============
	
	If you have a HOOPS Publish license, Publish support can be added to the MFC, WPF, and Qt sandboxes. In order to be able to save 3D PDFs you will need to rebuild the sandbox with the ``USING_PUBLISH`` preprocessor definition. You will also need to link against *hps_sprk_publish.lib*.

	When ``USING_PUBLISH`` is defined, the sandboxes look for the ``HPUBLISH_INSTALL_DIR`` environment variable, which needs to be set by the user to point to the Publish installation directory.

	Note that the 3D PDF export is only enabled when those sandboxes are run in Windows, since Publish is currently not supported anywhere else when integrated into HPS.


.. _wpf_sandbox_notes:

WPF Sandbox
===========

The WPF Sandbox supports both WinForms and D3DImage canvases with DX11. For an example on how they are used, see *SprocketsWPFControl.cs* in the wpf_sandbox project. WinForms is the default. If you want to use ``D3DImage``, you'll have to define the ``USE_D3D_IMAGE_CANVAS`` variable as shown in the code. Other relevant lines are::

	public SprocketsWPFControl(HPS.Window.Driver driver, string canvasName)
	{
		_canvas = new HPS.D3DImageCanvas(driver, canvasName);

		// the following line sets the D3D image source
		Source = _canvas.ImageSource;

		Stretch = Stretch.Fill;
		AllowDrop = true;

		SizeChanged += SprocketsWPFControl_SizeChanged;

		HPS.View view = HPS.Factory.CreateView(canvasName);
		Canvas.AttachViewAsLayout(view);
	}

Lastly, you must add a reference to the *sprk_d3dimage* library in order to use D3DImage.


.. _segment_browser:

Segment Browser
---------------
The segment browser is a Microsoft tree control that is included in both the WPF and MFC sandboxes.

The segment browser is a GUI control that allows you to inspect the segment structure of the loaded model. ``SceneTree`` and ``SceneTreeItem`` facilitate populating the tree-view, and they have derived classes located in *CHPSSegmentBrowserPane.cpp* (for MFC), or *SegmentBrowser.cs* (for WPF).

.. _model_browser:

.. only:: not spatial

	Model Browser
	-------------
	
	The model browser is a Microsoft tree control that is included in both the WPF and MFC sandboxes. It is provided in source code form as a reference, to facilitate adding a custom model browser to your application.

	The model browser is a GUI control that allows you to inspect the :doc:`Component hierarchy </prog_guide/0904_component_hierarchy>` of models loaded with either the Exchange or Parasolid interface. Right-clicking on an item in the tree-view brings up a context menu which allows you to show, hide, or isolate an item in the viewport. Selecting  an item in  the viewport will highlight its corresponding item in the tree-view, and vice versa.

	``ComponentTree`` and ``ComponentTreeItem`` facilitate populating the tree control, and they have derived classes located in *CHPSModelBrowserPane.cpp* (for MFC), or *ModelBrowser.cs* (for WPF). Note that the model browser is only applicable when a Component hierarchy is present, such as when a model is loaded using one of the Component integrations.

	.. image: images/browsers.png


.. _toc_cocoa:

.. only:: not spatial

	Cocoa Sandbox
	=============
	
	HOOPS Exchange is not enabled by default for this sandbox. To enable this capability, you must have HOOPS Exchange installed, then follow the instructions below:
	
	#. In the project screen, go to the build settings. Do a search for macros. In the preprocessor macros and next to any architecture/any SDK add ``USING_EXCHANGE``. Make sure it's all caps.

	#. Search for linker, and then go to *Linking > Other linker flags* and double-click to the right of other linker flags. Press the plus that is at the bottom of the window that will open up to add ``-IA3DLIBS`` (all caps) and press enter

	#. Then click the plus at the bottom again to add ``-lhps_sprk_exchange`` (all lowercase)

	#. Set ``HEXCHANGE_INSTALL_DIR`` as an environment variable to the path of the Exchange package

	Once these steps are complete, build the project. Upon a successful build, the sandbox will be able to load Exchange models.


.. _ar_vr:

AR/VR (Augmented Reality / Virtual Reality)
===========================================

Our AR/VR package contains five sandboxes:

* :ref:`OpenVR <general/sandboxes:openvr>`
* :ref:`ARCore <general/sandboxes:arcore>`
* :ref:`ARKit <general/sandboxes:arkit>`

These sandboxes make it possible to view HSF files in a virtual reality headset or on an augmented reality device.


OpenVR
------

This sandbox project is named *openvr_sandbox* in the Visualize sample solution and supports any VR headset compatible with OpenVR.

For OpenVR, you'll need a VR-capable GPU. For current NVIDIA GPUs, this would be a GTX 1060 or better. For AMD, this would be an RX 480 or better.

To get started with OpenVR, follow these steps:
	
#. On your local system, clone OpenVR from the GitHub repository::

	git clone https://github.com/ValveSoftware/openvr

#. Set the ``OPENVR_SDK`` environment variable to the location of your OpenVR root folder.

#. Ensure that the OpenVR binaries are in your PATH.

#. Install the Steam application from: `store.steampowered.com <https://store.steampowered.com>`_

#. Once Steam has been installed, run the application. In the top menu, select Library, go to VR and select "Install SteamVR" and install it on your system.

#. Run SteamVR. From within the SteamVR application, run the installer for your particular hardware (e.g., HTC Vive, Oculus Rift, etc).
		

For **Oculus Rift** only:

* Allow developer apps to run on the Oculus by opening the Oculus app and choosing *Settings->General->Unknown Sources* and toggling it to ON.
		

ARCore
------

This sandbox project is named *arcore_sandbox* and can be found in the Visualize *samples* directory.

To see if your device supports ARCore, please refer to `this page <https://developers.google.com/ar/discover/supported-devices>`_.

**Compiling the App:**

From a build perspective, this app behaves exactly like the *android_sandbox*. No ARCore dependencies need to be installed, since they are pulled from the internet via a Gradle package.

**App Usage:**

The app depends on having ARCore installed as well as the proper camera permissions. The initial screen of the app is a file list view. Selecting a file will launch the rendering activity.

Once the rendering activity is running, it will load the file you selected and display the camera contents as the file loads. When the file load is done, you should start to see points streaming in which identify points-of-interest for ARCore. If pointing the device at a planar surface, planes will be inserted which identify those surfaces.

You may interact with the app in the following ways:


#. Pressing the top-right most button should toggle the visibility for the ARCore debug display geometry (point cloud, detected planes)
#. Tapping the screen once will attempt to anchor an instance of the loaded model to a plane existing at the selected point. If ARCore has not detected a plane which covers this point, no model will be inserted. If a plane is found, the newly inserted model instance will become the "active" anchor. An active anchor should have a blue ring under it.
#. If you have an active anchor, tapping the screen twice will attempt to to translate the anchor (and the attached model) to a new location.
#. If you have an active anchor, pinching the screen will scale your active anchor (and the attached model).
#. If you have an active anchor, touching one finger down and moving it horizontally will rotate your active anchor about its local Y-axis.


ARKit
-----

This sandbox project is named *ios_arkit_sandbox* and is located in the Visualize *samples* directory.

**Compiling the App:**

ARKit requires iOS 11.0 or later, and a device with an A9 processor or later. This sandbox is set up to build against iOS 12, which allows you to use ARKit 2 APIs.

To get up and running with the ARKit sandbox, all you need to do is launch the corresponding Xcode project, attach an ARKit-capable iOS device running iOS 12 or later, and build and deploy the app to that device.

It is not possible to debug AR apps using the simulator, so you need to have an ARKit-capable device on hand to perform any testing.

An app using ARKit will require permission to access the camera, though the sandbox should prompt for this automatically if necessary.

If ARKit will be required for your app, it should be added as a required device capability to the *Info.plist* file (see the *Info.plist* file in the *examples/ios_arkit_sandbox* directory for an example).

The ARKit-specific files in this sandbox are:

* *ARView.h/ARView.mm* - This is just a minimal wrapper around a UIView which Visualize can use to render into via OpenGL ES.

* *ARViewController.h/ARViewController.mm* - This is a view controller associated with the ARView which handles the standard UIView life cycle, sets up gesture recognizers, and acts as the delegate for ARKit callbacks.

* *ARSurface.h/ARSurface.mm* - This is where a majority of the ARKit-Visualize interaction occurs. It handles the usual bind()/release() logic and file importing as in the standard iOS Sandbox, but augments this with the ability to start and stop an AR render loop for Visualize.

* *ARDriverEventHandler.h/ARDriverEventHandler.mm* - This contains code used to pass the camera images to Visualize to draw as the window background.

* *ARUtility.h* - Utility functions used to convert view and projection matrices into a Visualize camera.

Generally, these files (or at least the logic they contain) will be necessary to add ARKit functionality to your own app. Most of the customization that you will likely do will be in the *ARSurface* file and the *ARViewController* file, as these are the points where ARKit and Visualize interact.

**App Usage:**

You pick a file from the file list, and then the app will transition to AR mode, and allow you to place the selected file on planes that ARKit detects. Plane and point geometry that ARKit uses to detect planes can have their visibility toggled with the Plane button in the upper right corner. They will be visible by default.

You can single tap on a plane to place a model anchor. It will have a red circle of geometry underneath it to signify it as an "active" anchor. Active anchors can be rotated by panning left and right on the screen, scaled by pinching, and placed in a new location by double tapping.

If you place a new anchor by single tapping, the old anchor will become inactive, and the newly placed anchor will become active.

The Code1-Code4 buttons are conveniences to allow you to add your own code to run when they are tapped.
The sandbox also caps the number of anchors it allows, though this can be changed in the source.
