##################
Working with units
##################

How units are expressed
=======================

Units are expressed as a multiple of millimeters. For example, an inch unit will be expressed as 25.4, a meter unit as 1000, and a millimeter unit as 1.

You can get the unit value by calling the :ref:`Model::getNodeUnitMultiplier() <api_ref/typedoc/classes/Communicator.Model:getnodeunitmultiplier>` method on the model object.

You can also use :ref:`Util::formatWithUnit() <api_ref/viewing/modules/Communicator.Util:formatwithunit>` to convert 
your measurement value to a formatted string.

Here's an example using the command line in a browser console, with "hwv" representing the Communicator.WebViewer object:

.. code-block:: none

	> hwv.getModel().getNodeUnitMultiplier()
	> 25.4
	> Communicator.MeasureUtils.formatWithUnit(128, hwv.getModel().getNodeUnitMultiplier())
	> "128.00inch"


Unit authoring
--------------

Using the :doc:`AssemblyTree lib </api_ref/data_import/libsc/classSC_1_1Store_1_1AssemblyTree>` you can specify the unit when creating a node with the :ref:`setNodeUnit() <api_ref/data_import/libsc/classSC_1_1Store_1_1AssemblyTree:a20e384ae09dc6288f3949fa0427f5088>` method.

If the unit value changes from one node to another it is your responsibility to scale the scene accordingly. For example, assuming your root node is defined in millimeters and you create a subnode defined as inches, then you'll have to set a scale matrix, so that your inch object fits into the millimeter scene.

More generally speaking, the unit set on the root node is the unit that will be used for measurement. For instance, if you're importing from a CAD format where the assembly is defined in meters and you then import a cube in inches and another in centimeters, you will always do your measurement in the unit defined on the root node (in this case, meters). 

Unit information is also serialized into the XML::

	<ProductOccurence Id="0" Name="Cube" Behaviour="1" Children="1" Unit="25.400000">


Building a scene with mixed units
---------------------------------

Suppose we've defined a cube using inches. If we load this model into the WebViewer and measure it, we get the following results:


.. image:: images/measuring_cube.png

*The length of the edge of the cube is 3.35 inches (85 millimeters)*

Now we restart and load a scene in millimeters.

.. image:: images/load_millimeters.png

We then load the cube into this existing scene:

.. code-block:: js

    const model = hwv.model;
    const newNode = model.createNode(null, "Cube");
    model.loadSubtreeFromModel(newNode, "cube");

The cube, which is defined in inches, will then be measured in millimeters because it gets imported in millimeters. In this case, |HCNOW| will automatically scale the imported object to make it fit to the existing scene unit.

.. image:: images/fit_existing_scene.png

In some cases you might not want the object to automatically scale to fit the unit of the existing scene. This can be turned off by calling the :ref:`setEnableAutomaticUnitScaling <api_ref/typedoc/classes/Communicator.Model:setenableautomaticunitscaling>` method of the ``Model`` object.
	
In this case, the cube won't be rescaled to fit millimeter units and will be a lot smaller relative to the other object in the scene:

.. image:: images/inches_to_millimeters.png
