===========
Annotations
===========

An annotation is a comment, label or description that is associated with a specific part of a model. 	In complex models, it can be useful to identify important elements by labeling or attaching a comment to them.  For instance, if you have model that represents a research facility, the front desk in the lobby might have an annotation that reads "Security Checkpoint."

In the HOOPS database, an annotation, also known as a note, is associated with a specific segment in the model.  To create a new annotation, use the ``HUtilityAnnotation::Insert`` method. When you call this method, you should pass the segment key you want associated with the annotation, the location of the annotation and the location of the target.  If the annotation text is known at the time of creation, you can specify it as well. When the insert method is invoked, it opens a new segment under the associated segment and creates a new annotation object. All the information about the annotation including its text, color, background and face pattern resides in this part of the database.  Once you have set up your annotation, we recommend that you call ``HUtilityAnnotation::Resize``. Calling this method ensures that your annotation will be correctly rendered with all of your specified attributes.

The following is a code sample that creates a marker with an annotation. The annotation is scalable which means that its size is updated as the objects around it scale::

	//Creating a Marker
	HC_Open_Segment_By_Key(m_pHView->GetModelKey());
	HC_KInsert_Marker(0,0,0);

	HPoint target, position;
	target.Set(0,0,0);
	position.Set(1,1,0);

	//Creating a note
	HUtilityAnnotation note;
	note.Insert(target,position,m_pHView->GetModelKey(),m_pHView);
	
	//Setting the Text
	note.SetText("Scalable");
	
	//Setting the font and size.  Using oru, object relative units, indicates 
	//that the annotation should scale with the objects around it.
	note.SetTextFont("name = roman, size = 0.1 oru");
	
	//Calling Resize to ensure that the annotation will be rendered according 
	//to the attribute specifications.
	HC_KEY key = m_pHView->GetIncludeLinkKey();
	note.Resize(1, &key, m_pHView->GetViewKey());
	HC_Close_Segment();

.. csv-table::

	.. image:: images/0210ascalable1.png, .. image:: images/0210ascalable2.png

*An annotation with the scalable text "Roof Access."  As the camera zooms in, the door and the annotation both appear larger.*

The ``HUtilityAnnotation`` class provides methods which let you modify an annotation's attributes.  For instance, you can use the ``HUtilityAnnotation::SetText`` method to change your annotation to read "Security Checkpoint: Clearance Level C" instead of "Security Checkpoint."  In addition to changing the text, you can set the color of the annotation, update the face pattern and change the edge weight.  

Annotations come with a number of predefined background shapes including a cloud, circle and rectangle. This code sample sets a cloud shaped background for its annotation::

	...
	//Creating a note
	HUtilityAnnotation note;
	note.Insert(target,position,m_pHView->GetModelKey(),m_pHView);
	
	//Setting the text
	note.SetText("An annotation with \na cloud background.");
	note.SetTextFont("name = roman, size = 0.1 oru");
	
	//Setting the cloud background
	note.SetBackgroundType(BG_CLOUD);
	
	//Calling Resize to ensure that the annotation will be rendered according 
	//to the attribute specifications.
	HC_KEY key = m_pHView->GetIncludeLinkKey();
	note.Resize(1, &key, m_pHView->GetViewKey());
	HC_Close_Segment();

.. image:: images/0210bcloud.png

*Annotation with a cloud shaped background.*

In addition to the backgrounds shapes that come with HOOPS, you can also create your own background shapes as well. In the following code sample, once an annotation is created, we can get the background segment key. With this key, we can then insert a custom background for the annotation. Example::

	...	
	//Creating the note
	HUtilityAnnotation note;
	note.Insert(target,position,m_pHView->GetModelKey(),m_pHView);
	
	//Inserting the text
	note.SetText("Scaling text with \ncustom background.");
	note.SetTextFont("name = roman, size = 0.1 oru");
	note.SetExtents(150,150,m_pHView->GetViewKey());
	
	//Getting the Background Key 
	HC_Open_Segment_By_Key(note.GetBackgroundSegmentKey());
	{
		//Creating the user-defined background
		HC_Flush_Contents(".","everything");
		HPoint center, normal;
		center.Set(0,0,0);
		normal.Set(0,0,1);
		HC_Insert_Circle_By_Radius(&center,1,&normal);
	}
	HC_Close_Segment();
	
	//Calling Resize to ensure that the annotation will be rendered according 
	//to the attribute specifications.	
	HC_KEY key = m_pHView->GetIncludeLinkKey();
	note.Resize(1, &key, m_pHView->GetViewKey());
	HC_Close_Segment();

.. image:: images/0210ccustomchest.png

*An annotation with a custom circle background identifying one of the vertebrae in the cross section of a human chest.*

HOOPS renders annotations such that they always face the camera regardless of the camera's position or target.  By default, the rendered size of an annotation is based on the text and font specification. In ``HUtilityAnnotation::SetTextFont``, you can specify the font \ref Set_Text_Font_name "name" and \ref Set_Text_Font_size "size" units just like in ``HC_Set_Text_Font``. Using this information, HOOPS calculates the text extents automatically sizing the annotation so that it contains the entire rendered text. If you want the annotation to resize with the objects in your model as the camera zooms in and out, specify the font size in oru, object relative units. On the other hand, if you prefer your annotations to remain a fixed size, define your font size in wru, window relative units. The following code sample shows how to specify text that is nonscalable::

	...
	//Creating an annotation
	HUtilityAnnotation note;
	note.Insert(target,position,m_pHView->GetModelKey(),m_pHView);
	note.SetText("Non-Scalable");

	//Setting the font size using wru, window relative units, which 
	//ensures that the text will not scale.
	note.SetTextFont("name = roman, size = 0.03 wru");
	
	//Calling Resize to ensure that the annotation will be rendered according 
	//to the attribute specifications.			
	HC_KEY key = m_pHView->GetIncludeLinkKey();
	note.Resize(1, &key, m_pHView->GetViewKey());
	HC_Close_Segment();

.. csv-table::
	
	.. image:: images/0210dnonscalable1.png, .. image:: images/0210dnonscalable2.png
	
*Figure showing how the "shatterproof glass" annotation, whose font size was defined in wru, does not scale after the camera zooms out away from the model.*

To override the default behavior and set the annotation size directly, you can use the ``HUtilityAnnotation::SetExtents`` method.  The following code sample creates an annotation with a nonscalable text and then sets the extents of the annotation::

	...
	//Creating annotation
	HUtilityAnnotation note;
	note.Insert(target,position,m_pHView->GetModelKey(),m_pHView);
	note.SetText("Fixed Region with \nnon-scaling text.");
	
	//Setting the font size using wru, window relative units, which 
	//ensures that the text will not scale.
	note.SetTextFont("name = roman, size = 0.03 wru");
	
	//Overriding the default behavior of the annotation 
	//by setting the extents manually.
	note.SetExtents(125,75,m_pHView->GetViewKey());

	//Calling Resize to ensure that the annotation will be rendered according 
	//to the attribute specifications.		
	HC_KEY key = m_pHView->GetIncludeLinkKey();
	note.Resize(1, &key, m_pHView->GetViewKey());
	HC_Close_Segment();

.. csv-table::
	
	.. image:: images/0210ecityextentsa.png, .. image:: images/0210ecityextentsb.png
	
*Shows how a set of annotations defined with a fixed region and a non-scalable font size can be used as a legend for navigating around a model of a city.*

Note that whenever you modify an attribute that affects the size of an annotation, you must call ``HUtilityAnnotation::Resize``. This method recalculates the annotation size and its associated text based on the font specification or the extents if they were manually set. If you find that your annotation is being rendered in an unusual way, we recommend that you check that ``HUtilityAnnotation::Resize`` is being called after your change.

Although ``HUtilityAnnotation`` facilitates the creation and modification of annotations, it does not manage your annotations for you.  This class is primarily a collection of methods to manipulate annotation attributes.  At any given time, only one annotation can be manipulated by ``HUtilityAnnotation``.  When calling methods like ``HUtilityAnnotation::SetColor``, ``HUtilityAnnotation`` only modifies the color of the current annotation associated with it.  To operate on a specific annotation using ``HUtilityAnnotation``, call the ``HUtilityAnnotation::SetNote`` method passing the key to the annotation that you want to modify.
