===============
API Conventions
===============


The HOOPS Visualize Desktop API is implemented in C++ and C#. In this manual, C++ syntax will be favored in the general case, although C# code examples are provided. The two APIs have been engineered to be as similar as possible - please see :ref:`this section <language-specific>` for a list of significant differences. All classes are members of the ``HPS`` namespace. For the sake of brevity, the code snippets provided as examples in this programming guide do not always explicitly declare the ``HPS`` namespace identifier for class names. To use the HOOPS Visualize Desktop API, you must include *hps.h* in your C++ source.


.. _using_keys:

Using Keys and Objects
======================

Almost every HOOPS Visualize Desktop object is derived from ``HPS::Object``. One method that is shared among all objects 
is ``HPS::Object::Type()``. This method is useful for identifying and comparing objects, especially when the objects have been downcasted. For example, consider the ``HPS::ShellKey`` type, which derives from ``HPS::Key``. A function might return a ``HPS::Key``, and you would like to know what type of key you have. The ``Type()`` function will provide this information:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_examining_type.cpp
		   :start-after: //! [examining_type]
		   :end-before: //! [examining_type]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_examining_type.cs
		   :start-after: //! [examining_type]
		   :end-before: //! [examining_type]
		   
		   
.. _identifying_keys:

Identifying Keys
===================================================================================

``Type()``, ``ObjectType()``, ``HasType()``, and ``Empty()`` are all members of the superclass ``HPS::Object``. When using keys, it is always better to check the type if there is ever any doubt of its validity. The code snippet above shows the normal way to do this. A valid key will return ``Type::<typename>`` - for example, a shell key will return ``Type::ShellKey``. An invalid key will return ``HPS::Object::Type::None``. Attempting to use an invalid key will result in an ``HPS::InvalidObjectException``.

However, you should be aware that ``Type()`` can cause a negative impact on performance if many calls are made repeatedly. This is because HOOPS Visualize Desktop must read-lock the database to ensure that any creation or deletion operations (which are asynchronous) are completed before it can determine the state of any object with absolute certainty. This is why we recommend only calling ``Type()`` when the object's type is truly in doubt, and never in a tight loop. If you are certain of the object's type, there is no need to call ``Type()``. Instead, construct the target object and use it normally. Consider placing this code inside a try/catch block as a defensive measure. For example, you could do the following:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_examining_type.cpp
		   :start-after: //! [assuming_type]
		   :end-before: //! [assuming_type]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_examining_type.cs
		   :start-after: //! [assuming_type]
		   :end-before: //! [assuming_type]
		   
``ObjectType()`` differs in that it returns a static value tied to the typename of your variable, whereas ``Type()`` will tell you what the underlying derived type is. For instance, if you retrieve several ``HPS::Key`` objects from a selection event, ``ObjectType()`` will *always* return ``HPS::Type::Key`` but ``Type()`` will return the derived type, such as ``HPS::Type::ShellKey``, ``HPS::Type::SegmentKey``, ``HPS::Type::TextKey``, etc...

.. only:: not spatial 

	``HasType()`` can be used in two different ways. First, it lets you know if your object derives from a certain type. For example, if you have an ``HPS::Key`` variable, you can call ``HasType(HPS::Type::GeometryKey)`` if you just want to know if it is any type of geometry key (geometry keys represent items like shells, NURBS curves, text, etc). Secondly, it lets you test masks such as ``HPS::Type::ExchangeMask`` (masks don't have an equivalent object you can instantiate) to see if the object you are working with is any type related to Exchange. 

.. only:: spatial

	``HasType()`` can be used to determine if your object derives from a certain type. For example, if you have an ``HPS::Key`` variable, you can call ``HasType(HPS::Type::GeometryKey)`` if you just want to know if it is any type of geometry key (geometry keys represent items like shells, NURBS curves, text, etc).

``Empty()`` can be used to determine if an existing object has been modified. The function generally asks the question "Does this object have any information?" For example, in the case of a :ref:`kit <using_kits>`, it checks to see if any settings have been made. All fresh new kits are "empty", but that does not make them invalid.


Common Actions
--------------

Most actions in HOOPS Visualize Desktop have a common prefix which indicates what type of action will occur. The following is a list of the most common action prefixes:

*Set:* Set allows you to specify a value for an attribute or characteristic for the associated class. For example, the ``HPS::CameraControl`` has 'set' methods that allow you to specify the values for camera target, field, projection, etc.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_2_a.cpp
		   :start-after: //! [camera_projection]
		   :end-before: //! [camera_projection]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_2_a.cs
		   :start-after: //! [camera_projection]
		   :end-before: //! [camera_projection]

*Unset:* Unset is the opposite of Set. All subsegments will inherit the new value unless explicitly overridden. If you set a value for a specific attribute on a segment or piece of geometry and then want to remove the local attribute so that the default or parent attribute can be inherited, use Unset. Because HOOPS Visualize Desktop assumes there is at least a default value for every segment, most attributes of a window segment cannot be unset. The exception is :ref:`user data <prog_guide/0101_database:User data>`, which can be unset.

*Show:* Show allows you to get information about the associated object or attribute. For instance, the ``HPS::VisibilityControl`` has 'show' methods which let you know the geometry primitives that will be visible. Show functions always return a ``bool`` value which indicates whether the value was set locally on the segment (for inherited values, it would return ``false``).

*Insert:* Insert is primarily used for adding geometry to a segment in the database. This is a database action which alters the segment tree. For instance, there is a method for inserting every type of geometry into a ``HPS::SegmentKey``.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_insert_example.cpp
		   :start-after: //! [insert_example]
		   :end-before: //! [insert_example]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_insert_example.cs
		   :start-after: //! [insert_example]
		   :end-before: //! [insert_example]
		   

*Delete:* Delete allows you to remove something from the database. This method is available on any key.

*Assignment:* Assignment behaves differently depending on the object type. 
When using the assignment operator with objects such as keys, the result of the assignment is that both keys will refer to the same underlying object in the internal database. When operating on other object types, such as ``HPS::UTF8`` objects or :ref:`kits <prog_guide/0101_database:Using kits to instantiate geometry>`, assignment can be thought of as copying a container.

*Define:* Define is used for the creation of definitions such as textures, line styles and glyphs. Definitions are created in portfolios and then applied to their respective geometry primitives via the 'Set' action.

*Edit:* Edit is primarily for geometry. Once you have inserted your geometry, you might want to change specific pieces of information. 
Edit gives you finer grained control within a characteristic set. For instance, editable geometry characteristics include face lists, vertex 
lists, planes, or line weight.


*Update:* Update is the action used to draw the scene. Update is only available from a ``HPS::WindowKey`` or a :doc:`view hierarchy <0301_core>` object, such as ``HPS::Canvas`` or ``HPS::View``.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_update.cpp
		   :start-after: //! [update]
		   :end-before: //! [update]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_update.cs
		   :start-after: //! [update]
		   :end-before: //! [update]
		   
There are some instances where you will need to use ``Update`` in a slightly different way. For more information, see :doc:`section 7 <0701_rendering>` of the Programming Guide, which covers rendering.


.. _keypath:

Using a KeyPath
---------------

A ``HPS::KeyPath`` is an ordered list of keys that forms an unambiguous chain from a scene graph leaf to its root. Because a HOOPS Visualize Desktop segment can [non-recursively] :ref:`include <prog_guide/0101_database:Include segments>` any other segment an arbitrary number of times, the geometry within the included segment can potentially be instanced multiple times. In this case, how would one reference a single piece of the instanced geometry? You can do this with a ``HPS::KeyPath``. For example, if you would like to :doc:`highlight <0604_highlighting>` a shell in an included segment, you would need to build a key path from the geometry back to the root segment. Note that it is only necessary to specify the ambiguous keys, (such as include links) since HOOPS Visualize Desktop can determine simple parent-child relationships on its own. Consider the diagram below which shows a triangle shell which has been included multiple times:

.. image:: images/key_path.png

*Representation of a scene graph with include links (denoted by dashed lines). In the main tree, the left segment will have the triangle included twice, and the right segment will include it once.*

Since the triangle segments are included, the geometry within them is copied to multiple places in the scene at render time even though the segment has only one associated database key. In order for HOOPS Visualize Desktop to distinguish one particular triangle from the other triangle instances, the key path must be provided to resolve the ambiguity. The key path is built from the leaf to the root. In this simple case, only the shell key and the include link is needed:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_keypath.cpp
		   :start-after: //! [keypath]
		   :end-before: //! [keypath]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_keypath.cs
		   :start-after: //! [keypath]
		   :end-before: //! [keypath]
		   

Determining Net Attributes
--------------------------

Key paths are also used to determine a segment's net attributes. A net attribute is the value that is calculated for a particular attribute after the tree has been walked down to that point. It may not always be obvious what the value of the attribute is because a segment could be included at any point in the tree and inherit whatever attribute is set on the parent. Again, a key path removes this ambiguity by referencing the include links associated with the segment. For example, to show the net camera on an included segment, build the key path for that segment and use:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_keypath.cpp
		   :start-after: //! [shownet]
		   :end-before: //! [shownet]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_keypath.cs
		   :start-after: //! [shownet]
		   :end-before: //! [shownet]
		   

.. _database_interaction:

Database Interaction
====================

When interacting with the database, three types of activities are primarily performed:

#. Retrieving information from the database
#. Inserting information into database
#. Changing information in the database


Information Retrieval
---------------------

The retrieval of information is achieved via the *Show* method.  For any given HOOPS Visualize Desktop object, if it has a method whose name begins with *Show*, you know that you can query information with it. You can show information into a kit or individual data structures. In the sample code below, we retrieve camera information from ``mySegmentKey`` in two different ways: showing into a kit and using the ``HPS::CameraControl`` to query information.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_2_a.cpp
		   :start-after: //! [010302_a]
		   :end-before: //! [010302_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_2_a.cs
		   :start-after: //! [010302_a]
		   :end-before: //! [010302_a]

As shown above, you can achieve the same task using either a kit or a control. Which method you choose depends on the situation as well as your own style preference.


Information Creation
--------------------

Inserting information into the database includes the insertion of geometry, creation of subsegments, and creation of style definitions (textures, material palettes, glyphs, etc.). When you create one of these elements, a newly created object is returned so that you can perform further actions with it. Here is an example of creation and insertion:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_2_bcd.cpp
		   :start-after: //! [010302_b]
		   :end-before: //! [010302_b]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_2_bcd.cs
		   :start-after: //! [010302_b]
		   :end-before: //! [010302_b]
		   

Information Modification
------------------------

The modification of existing information in the database is often performed on attributes but also can be performed on some geometry types like shells and meshes. Attribute modification is performed by *Set* and *Unset* while changes to geometry can be made via the *Edit* method. There are two ways to modify information in the database. You can make direct modifications to the database or group them into a transactional object.

In direct modification, you access a database object, choose an action, determine the object and pass any required parameters. The request for the modification will be dispatched immediately. For example, in the code snippet below, text is rendered in bold:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_2_bcd.cpp
		   :start-after: //! [010302_c]
		   :end-before: //! [010302_c]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_2_bcd.cs
		   :start-after: //! [010302_c]
		   :end-before: //! [010302_c]
		   

If we set the text color to yellow, we make another call to the database:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_2_bcd.cpp
		   :start-after: //! [010302_d]
		   :end-before: //! [010302_d]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_2_bcd.cs
		   :start-after: //! [010302_d]
		   :end-before: //! [010302_d]

These examples show an efficient way to make quick modifications to the database.

Often, it is desirable to make changes to the state of the database in order to convey an idea. For instance, imagine a scene with a number of annotations in it. Whenever you want to bring attention to a specific annotation, you might highlight the text in the annotation. Each time the highlighting is applied, you could make two database calls:

* set text to bold
* change the text color to yellow  

A better way to do this would be to create a kit that encapsulates the highlight state. The following example demonstrates the idea:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_2_e.cpp
		   :start-after: //! [010302_e]
		   :end-before: //! [010302_e]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_2_e.cs
		   :start-after: //! [010302_e]
		   :end-before: //! [010302_e]
		   
This may seem like a logical solution, and indeed it is in certain situations. However, it can quickly become unwieldy if your highlight style has many attributes to set. The most robust way to accomplish this is to use one of the more advanced :doc:`styling <0403_styles>` or :ref:`conditional styling <prog_guide/0403_styles:Using conditional styles>` approaches. For more information on the benefits of using kits, see the explanation on kits in :ref:`the next subsection <prog_guide/0102_api_conventions:Using kits as transactional objects>`.


.. _using_kits:

Using Kits as Transactional Objects
===================================

If you want to make multiple changes that require complex manipulations, it is more efficient to perform these operations outside of the database, logically group them, and then commit them all at once. You can do this with transactional objects called *kits*. For most database objects, there is an analogous kit object that exists outside of the database. Every setting that exists for a key, you can apply to a kit. Below is a sample list describing some database objects and their analogous transactional objects:

.. csv-table::
	:header: "Database object", "Transactional object"
	
	"HPS::ShellKey", "HPS::ShellKit"
	"HPS::LineKey", "HPS::LineKit"
	"HPS::CylinderKey", "HPS::CylinderKit"
	
While it is possible to insert an object into the HOOPS Visualize Desktop database and subsequently modify it, this is not the most efficient way. The example below makes four database calls:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_3_abc.cpp
		   :start-after: //! [010303_a]
		   :end-before: //! [010303_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_3_abc.cs
		   :start-after: //! [010303_a]
		   :end-before: //! [010303_a]

Using transactional objects, we can accomplish the same task outside of the database and then commit it atomically to the database using a kit.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_3_abc.cpp
		   :start-after: //! [010303_b]
		   :end-before: //! [010303_b]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_3_abc.cs
		   :start-after: //! [010303_b]
		   :end-before: //! [010303_b]
		   
If you need to modify an existing object, the same recommendations apply. If you're modifying just one or two attributes, it may be better to operate directly on the associated key. However, when adjusting multiple values, the kit is usually faster:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_3_abc.cpp
		   :start-after: //! [010303_c]
		   :end-before: //! [010303_c]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_3_abc.cs
		   :start-after: //! [010303_c]
		   :end-before: //! [010303_c]

Since a transactional object groups operations together, HOOPS Visualize Desktop provides kits not just for database objects like shells and lines but also for some high-level segment attributes such as cameras. Kits exist only in memory and don't actually write or read from the database - they write and read from their own container.


.. _attribute_controls:

Attribute Controls
==================

While a particular segment may or may not include geometry, every segment has a set of attributes. When a local attribute is unset, its value will revert to the inherited value from the parent segment. Window segments have a set of default attributes applied to them by HOOPS Visualize Desktop, thus, a value for every attribute is guaranteed. Unlike kits, controls are tied to a segment key and each set and unset will trigger a database write and each show will trigger a database read.

Certain attributes are compound and require multiple parts to have meaning. A camera is one example. A camera has, among other things, a position, a target, and a field of view. In this case, manipulating and examining a key's attributes is accomplished using a special control. A *control* is a utility class that enables you to manipulate compound attributes. To access the camera attribute, you would use the ``HPS::CameraControl``.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_4_a.cpp
		   :start-after: //! [010304_a]
		   :end-before: //! [010304_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_4_a.cs
		   :start-after: //! [010304_a]
		   :end-before: //! [010304_a]
		   
A control performs very specific actions.  It can show, set and unset attribute values. You can deduce which control you need to request from an ``HPS::Key`` by learning their naming convention. A control's name begins with the attribute category that it accesses::

<AttributeCategory>Control

For instance, the name ``HPS::VisibilityControl``, tells us from the name that it can show, set, and unset visibility attributes. However, when getting attribute values using attribute controls, be aware that only those attributes explicitly set on the local segment can be retrieved. If you need to find the value of an inherited attribute, use a key path as described in :ref:`this section <keypath>`.

Additionally, if you are querying a segment in an isolated segment tree, be aware that it may not have a value for a particular attribute. This is because isolated root segments have no parent and are not initialized with default attribute values. The following code snippet shows the typical logic required for deterimining whether the line visibility attribute has been set, and if so, whether it is true or false:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_4_a.cpp
		   :start-after: //! [show_logic]
		   :end-before: //! [show_logic]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_4_a.cs
		   :start-after: //! [show_logic]
		   :end-before: //! [show_logic]


.. _method_chaining:

Method Chaining
===============

Transactional objects have another feature that increases their efficiency.  When you call a 
set method on a kit, the method returns the very same kit.  This is part of the method chaining 
feature in HOOPS Visualize Desktop. The method chaining allows you to make multiple attribute modifications in one 
code statement::

<subject> <action & object> <action & object> <action & object>

Let's take another look at our ``highlightText`` kit.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_5_abcdef.cpp
		   :start-after: //! [010305_a]
		   :end-before: //! [010305_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_5_abcdef.cs
		   :start-after: //! [010305_a]
		   :end-before: //! [010305_a]

From ``highlightText``, our ``HPS::TextKit`` transactional object, we call the ``TextKit::SetBold`` method.  This method returns the very same ``HPS::TextKit``.  This allows us to modify another attribute inside the ``HPS::TextKit`` such as color. Let's take a look at how we can set bold and color using method chaining:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_5_abcdef.cpp
		   :start-after: //! [010305_b]
		   :end-before: //! [010305_b]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_5_abcdef.cs
		   :start-after: //! [010305_b]
		   :end-before: //! [010305_b]
		   
At the end of the above call, ``highlightText`` has set the attributes for bold and color in the ``HPS::TextKit``. Now, let's take a look at how to apply these changes to the database:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_5_abcdef.cpp
		   :start-after: //! [010305_c]
		   :end-before: //! [010305_c]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_5_abcdef.cs
		   :start-after: //! [010305_c]
		   :end-before: //! [010305_c]

Although we have used the *Set* action in our discussion, this applies to *Unset* and *Edit* methods as well.

In Summary
----------

In review of the previous sections, there are three ways to modify attributes within the database:

#. Modify one piece of information at a time executing a database transaction each time.

	.. tabs::

		.. group-tab:: C++
		
			.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_5_abcdef.cpp
			   :start-after: //! [010305_d]
			   :end-before: //! [010305_d]
			   
		.. group-tab:: C#

			.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_5_abcdef.cs
			   :start-after: //! [010305_d]
			   :end-before: //! [010305_d]
		   
	
#. Modify multiple pieces of information outside of the database through a kit and then commit them with one database transaction.

	.. tabs::

		.. group-tab:: C++
		
			.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_5_abcdef.cpp
			   :start-after: //! [010305_e]
			   :end-before: //! [010305_e]
			   
		.. group-tab:: C#

			.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_5_abcdef.cs
			   :start-after: //! [010305_e]
			   :end-before: //! [010305_e]
	
#. Modify multiple pieces of information outside of the database through a kit via method chaining and then commit them with one database transaction.

	.. tabs::

		.. group-tab:: C++
		
			.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_5_abcdef.cpp
			   :start-after: //! [010305_f]
			   :end-before: //! [010305_f]
			   
		.. group-tab:: C#

			.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_5_abcdef.cs
			   :start-after: //! [010305_f]
			   :end-before: //! [010305_f]
			   
The above methods accomplish the same task in different ways. The approach you take will be based the your application's needs and your style preference.


.. _text_encoding:

Text Encoding
=============

When using the C++ interface, the ``UTF8`` class is used as a replacement for character arrays. As its name suggests, it is an implementation of the UTF-8 standard, used to represent any character in the Unicode character set. All strings you pass to HOOPS Visualize Desktop are assumed to be UTF-8 encoded and any string that comes out of HOOPS Visualize Desktop will be UTF-8 encoded (however, strings that are already UTF-8 encoded should not be doubly encoded). The ``UTF8`` class is made available to facilitate this process. When calling a function, any string returned to the caller is encapsulated in a ``UTF8`` object.

If you need to pass wide-character data to HOOPS Visualize Desktop, you need to convert it into a format that it understands. The ``UTF8`` class facilitates that in two ways. The first is a constructor that can create a ``UTF8`` object from a wide character (``wchar_t``) string. The second is an implicit cast operator from a ``UTF8`` object to a ``char const *``, essentially allowing a ``UTF8`` object to be used as a character string. So, given a function such as::

	HPS::TextKit::SetText(char const * in_utf8);

...you can do something like:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_5_abcdef.cpp
			:start-after: //! [wide_text]
			:end-before: //! [wide_text]

			   
A locale can optionally be set on the ``UTF8`` class. The locale is passed as the second parameter to the constructor. Internally, we use ``setlocale`` from ``locale.h`` (see `http://www.cplusplus.com/reference/clocale/setlocale/ <http://www.cplusplus.com/reference/clocale/setlocale/>`_), so any parameter acceptable to that function is legal for our ``UTF8`` class. Note that leaving the parameter unspecified, or passing an empty string, forces ``UTF8`` to use the default locale of the environment.

When using C#, the ``UTF8`` class is not applicable. Use the C# ``String`` class instead. ``String`` is UTF-16 encoded, but the HOOPS Visualize Desktop API will implicitly convert any C# ``String`` passed to it.


.. _enumerations:

Enumerations as Parameters
==========================

Except for those that map to objects or native data types, HOOPS Visualize Desktop uses enumerations for all options passed as function parameters. The code sample below shows the enum for specifying the ``DirectX11`` driver.

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_create_standalone_window.cpp
		   :start-after: //! [standalone]
		   :end-before: //! [standalone]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_create_standalone_window.cs
		   :start-after: //! [standalone]
		   :end-before: //! [standalone]
		   

The *Concept* Class
-------------------

In the example above, ``HPS::Window`` is a *concept* class. A concept class is a class that contains only enums and possibly static functions. The constructor is private because they are not intended to be instantiated. The purpose of the concept class is simply to contain enums and facilitate their access by all instantiated objects.


.. _multithreading:

Multi-Threading
===============

HOOPS Visualize Desktop is completely thread-safe. However, there are very few application use-cases where it is beneficial to call the API from multiple threads of execution. This is because HOOPS Visualize Desktop internally creates threads as needed to optimize performance. All calls to the HOOPS Visualize Desktop API are routed through an internal dispatcher which is able to divide processing work among threads. For example, when updating a scene, HOOPS Visualize Desktop will automatically queue that action on a rendering thread. The same logic applies to areas such as Database interactions and internal memory management.

Additionally, many of the most time-consuming operations - which would normally be candidates for multi-threading - depend on the Database being locked in a read-only state. For example, when updating the scene, the Database is locked in a read-only state. While the Database is locked, interaction is limited to read-only operations such as query, export, or selection.  Any operations that modify the scene-graph, such as setting attributes, modifying graphical primitives, camera rotations, or highlighting are considered 'write' operations and require the Database to be unlocked, so building a complex multi-threaded framework where your application accesses the HOOPS Visualize Desktop API from multiple threads is unlikely to provide any benefit. It is legal to perform 'write' operations while the Database is locked because HOOPS Visualize Desktop is thread-safe, but such operations will simply be queued until the read lock is lifted.

If you feel you have use-cases or can achieve potential performance gains by accessing the HOOPS Visualize Desktop API from multiple threads in your application, we strongly encourage you to contact Developer Support for general programming advice and feedback about potential concurrency gains that you may expect.

General Tips
------------

If you ever access the HOOPS Visualize Desktop API from multiple threads, it becomes imperative to diligently check for errors and exceptions. For example, one of your threads could try to use a Database object (such as a segment or graphical primitive) that no longer exists. Be sure to always check for ``HPS::IOException`` when interacting with Database objects. If you wish to synchronize the Database to ensure that all internally queued events have been processed, you would call ``HPS::Database::Synchronize``.


.. _language-specific:

Language-Specific Notes
=======================

Data Type Differences Between C++ and C#
----------------------------------------

#. In order to simplify the interface, prevent bounding errors, and provide a general convenience, all C++ array types have been ``typedef``'d as STL ``vector``. In C#, however, this distinction is meaningless as arrays are supported at a higher level by the language itself. The general naming convention in C# is to drop the  ``Array`` suffix in favor of simply defining these types as arrays. Equivalent examples are provided below:

.. tabs::

	.. group-tab:: C++
	
		.. literalinclude:: ../../../internals/tests/docs/source/cpp/00700_1_3_8_a.cpp
		   :language: cpp
		   :start-after: //! [010308_a]
		   :end-before: //! [010308_a]
		   
	.. group-tab:: C#

		.. literalinclude:: ../../../internals/tests/docs/source/cs/00700_1_3_8_a.cs
		   :language: cs
		   :start-after: //! [010308_a]
		   :end-before: //! [010308_a]

#. Some HOOPS Visualize Desktop functions accept a ``size_t`` parameter. As C# does not use ``size_t``, you should use ``ulong`` in its place. While this will result in some waste in 32-bit Windows, it will enable addressing very large arrays in 64-bit systems.


C# "is" Equality Checks
------------------------

Performing **is** equality checks on C# objects returned by HOOPS Visualize Desktop is only valid for types which contain virtual functions that it may invoke. For example, operators will be cached as they have many virtual functions such as ``OnMouseMove`` which HOOPS Visualize Desktop may invoke. Thus, pushing an operator, popping it, then comparing this using **is** to the original object will work as expected. However, when you supply a class like ``HPS::ShellKey`` (that has no virtual functions) to an HOOPS Visualize Desktop interface and then retrieve it, **is** will not return ``true`` even if ``==`` or ``Equals`` evaluates to ``true``.


Deleting Objects in C#
----------------------

In HOOPS Visualize Desktop, C# wrappers own a memory reference for each C++ object they are referencing. When the C# objects are garbage collected (or when ``Dispose()`` is called), it frees the C++ memory it allocated. This does NOT remove the key from the scene graph, it just removes the memory the C# wrapper allocated.

If you want to delete the key from the scene graph you need to call the ``Delete()`` method. Generally, there is no need to call ``Dispose()`` manually, as the C# garbage collector will take care of that for you. However, calling ``Dispose()`` manually can be beneficial in certain situations. For example, imagine you are creating and destroying many temporary C# objects quickly in a tight loop. Calling ``Dispose()`` allows these C# objects to have some partial deterministic destruction, which should result in lower memory usage.


Initialization of Certain Structures in C#
------------------------------------------

In C++, ``HPS::SimpleCuboid and ``HPS::SimpleSphere`` are initialized to be invalid. In C#, ``HPS.SimpleCuboid`` and ``HPS.SimpleSphere`` are initialized to zero-sized geometry centered at the origin.


Float Functions
---------------

Unlike in C++, the C# ``HPS.Float.Equals`` function does not have an implementation for arrays.


Show Functions
--------------

C++ ``Show`` functions may not set the value of output parameters if the ``Show`` function fails. C# ``Show`` functions will always assign a value to ``out`` parameters, even if the ``Show`` fails.


Protected C++ Members Not Available in C#
-----------------------------------------

In the C++ API, certain classes contain member variables with the ``protected`` access modifier. These member variables cannot be directly accessed in the C# API, although in most cases their values can be manipulated via ``public`` getters/setters or constructors. 

One example is the ``mouse_trigger`` variable from the ``HPS::Operator`` class, which can be directly accessed in C++ but can only be accessed via getters and setters in the C# version of that class.


Using WPF with C#
-----------------

``HPS.D3DImageCanvas`` is the canvas class you should employ for using C# with WPF (please see :ref:`this page <general/sandboxes:WPF Sandbox>` for usage details). Please note that regardless of which driver interface you are using, *d3dcompiler_XX.dll* **MUST** be distributed with your application (if it doesn't already exist in the execution environment) when using C# with WPF.


Rendering Fast Synchronous Updates When Using D3DImageCanvas
------------------------------------------------------------

When submitting many synchronous updates quickly while using ``HPS.D3DImageCanvas``, it is possible that some of the intermediate updates will not be rendered by WPF. This happens when the underlying D3DImage does not get displayed by the WPF renderer before HOOPS Visualize Desktop has rendered the next frame or frames. If it is important for every update to be rendered to the screen, this problem can be sidestepped by dispatching updates on the WPF render thread directly, in your application code. This can be done as follows::

	// _win is of type MainWindow
	_win.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render, new Action(delegate()
	{
		GetCanvas().UpdateWithNotifier().Wait();
	}));


.. _misc:

Miscellaneous Notes
===================

Edges vs. Lines
---------------

HOOPS Visualize Desktop allows access to object attributes using the associated :ref:`attribute control <attribute_controls>`. It should be noted that *lines* and *edges* are completely different geometric entities, and thus are handled differently. In HOOPS Visualize Desktop, an edge is a part of any facetted geometry, such as shells, meshes, NURBS surfaces, circles, ellipses, spheres, and cylinders. Edge attributes are controlled using the ``HPS::EdgeAttributeControl``, which is available from the ``HPS::SegmentKey``.

Lines are parts of non-faceted geometry such as line segments, NURBS curves, and arcs. Line attributes are controlled using the ``HPS::LineAttributeControl``, which is available from the ``SegmentKey``.


Default Rotation Units
----------------------

When supplying a rotation value to an HOOPS Visualize Desktop function, the default unit is degrees, not radians.


Error Handling
--------------

In addition to normal runtime exceptions issued by the client application, HOOPS Visualize Desktop will issue errors and exceptions of its own as conditions dictate. Ideally, your application would respond to the errors as appropriate to the situation, and HOOPS Visualize Desktop provides a way to do this using an error handling mechanism that you can customize. Errors and warnings are issued through the event handling system, which is detailed along with exceptions in :doc:`a separate section <1001_event_handling>`.

