==========================
Intermediate Mode Overview
==========================

HOOPS is a retained graphics database system. You create a scene by inserting geometry and setting attributes in a segment tree maintained by HOOPS. When you call ``Update_Display`` (or you request input), the system traverses the segment tree and draws the picture on the display device. With the classic HOOPS library, additions and modifications to the segment tree cannot be made while HOOPS is traversing the tree. 

HOOPS I.M. routines complement the classic HOOPS library and provide for traversal-time modifications of the segment tree walk. The I.M. library provides a means for the application to trap the HOOPS update cycle at certain points in the rendering pipeline, by means of a callback mechanism. When you trap the traversal at a callback point, you can make decisions about what and how something is drawn, or even abort the traversal process itself. In addition to the callback mechanism, the HOOPS I.M. library provides a set of functions you can call from your callback functions to draw to the display in an "immediate mode" style and to query the graphics database and the device characteristics.

The HOOPS selection feature also involves a traversal of the graphics database contained in the segment tree. However, the selection traversal does not draw on the display. Rather, it computes the screen positions of objects in the database to determine which objects have been hit by selection events. HOOPS I.M. provides callback points at which you can trap the selection traversal as well as the update traversal.
 
 
Usage Examples
==============
 
You would use HOOPS I.M. when you want your application to be able to make traversal-time decisions about the rendering or selection process, or to accomplish special processing that is not provided by the built-in HOOPS traversal process. Here are some examples of situations for I.M. use:

* You may want the graphical representation of your data, i.e. the actual primitives and attribute values used, to depend on the viewing parameters or the screen transformation. In particular, if your model has a hierarchy of scale and the view is zoomed out sufficiently far, then you may want to skip the rendering of entire subtrees that would appear very small on the display. 

* You may want to define your own version of a HOOPS primitive. For example, you could implement a spline drawing algorithm through the HOOPS polyline primitive, using the polyline vertices as spline control points. In this case, you would intercept at one of the callback points in the polyline drawing pipeline, and substitute your own spline drawing routine for the HOOPS polyline drawing routine. 

* If your graphics database is voluminous, you may want to avoid spending the memory needed for HOOPS to duplicate in its database some of the same information already  contained in your application's private data structures. Using HOOPS I.M. in an  "immediate mode" style allows you to pass some of your primitives to HOOPS one at a time in I.M. callbacks, rather than storing them in HOOPS segments. 

* In a real-time application, you may want to be able to modify the picture being 
  displayed according to input received during traversal. 


The Update Cycle
================

To perform a display update, HOOPS clears the screen, then traverses the segment tree. Each segment can contain a list of inserted geometry elements, some attribute settings, and possibly a list of pointers to owned segments.Attributes are inherited down the tree while some are inherited upwards. Some attributes, such as the net modelling matrix, are accumulated down the tree. The traversal process keeps track of the current values of the attributes as it walks the tree. A  rendition is a structure that contains a value for each of the defined HOOPS attributes. The net rendition is the set of attribute values that apply to a particular segment when it is processed by the traversal.  Geometry stored in the segment is specified in terms of the 3D object coordinates that the application uses in inserting primitives. 

At each segment, the HOOPS system processes the list of geometry elements, and passes each geometry element through a rendering pipeline to produce the pixels that are written to the screen (possibly subject to a Z-buffer test). These rendering computations include a transformation pipeline that applies the net modelling transformation to map the geometry to world coordinates, and then applies the viewing transformations and screen transformations, which are defined by the camera attributes, to map the geometry to the device coordinates that place objects on the display surface. More details on the definition of device coordinates are given below.   

We can describe the traversal process and rendering pipeline in terms of a hierarchy of methods. At the top level is the method that walks the tree. A submethod of the tree walk is "draw segment", which processes all the geometry in a segment, and recursively processes its subsegments. "draw segment" is the highest level method that you can trap within the HOOPS I.M. library. HOOPS geometry elements are of several types - polygon, polyline, circle, circular arc, text, marker, mesh, shell, etc.  See the discussion of ``HIC_Show_Geometry_Type`` in the reference section for the complete list of geometry types. The "draw segments" method traverses a segment's list of geometry elements and applies a method "draw 3d ..." to each geometry element according to its type "...".  Each "draw 3d ..." method must perform the necessary modelling and viewing transformations and eventually call on lower-level "draw dc ..." drawing methods, which draw primitives specified in device coordinates. For some of the geometry types, the  "draw 3d ..." method must decompose the object into smaller objects of one or more types. Thus, a mesh or shell will be decomposed into multiple faces and edges and so give rise to a number of  "draw dc ..." calls.   
   
For the text primitives, HOOPS I.M. offers the ability to trap the pipeline at an intermediate level,  "draw text", between the "draw 3d text" and "draw dc text" levels of the method hierarchy. In addition, there is a provision for trapping the method  "draw windows", which paints a window background and the method "draw window frame", which draws a frame around a window.  The next section presents in detail the set of methods that you can trap with HOOPS I.M. callbacks. 

.. image:: images/08_01_IMCallbackHighlevel.gif

*High level view of drawing pipeline*


Callback Points
===============

HOOPS I.M. provides the following set of callback points at which you can trap the traversal process. These are entry points to methods in the rendering pipeline for which you can define callbacks. Here they are listed in order of higher to lower levels (with respect to their level in the rendering pipeline), along with a brief description of the standard default behavior of the method. 
   

Draw Segment Callbacks
----------------------

The "draw segment" callback is called at the beginning of processing each segment for which it is in effect. As for all but the callback points, a "draw segment" callback is inherited by all the subsegments of the segment on which it is set. 

The "draw segment tree" callback is like "draw segment", except that the callback is not inherited by subsegments of the segment on which it is set. This is the one exception to the rule that callbacks are inherited by subsegments. It is provided because it is frequently the case that a callback function can make a decision about the processing of the subsegment hierarchy below a given segment when the given segment is first encountered in the traversal and so does not need to be called back for every descendent segment. 

*Callbacks:* \ref Set_Callback_draw_segment "draw segment", \ref Set_Callback_draw_segment_tree "draw segment tree"
     
	 
Draw Window Callbacks
---------------------

The "draw window" callback is called to fill in the segment's window with the background pattern, subject to the current hard clip limits   

The "draw window frame" callback is called to draw a frame around a segment's window. 

*Callbacks:* \ref Set_Callback_draw_window "draw window", \ref Set_Callback_draw_window_frame "draw window frame"


Draw 3D Geometry Callbacks
--------------------------

The "draw 3d geometry" callback point allows you to trap the  "draw 3d ..." method for all of the HOOPS 3D geometry types(ellipses, circles, arcs, etc).

.. image:: images/08_01_IMPolylineHierarchy.gif

*The 3D geometry drawing pipeline*

There are callback points in HOOPS that allow you to trap specifically the  "draw 3d ..." methods for each of the geometry types: marker, polyline, polygon, text, tristrip, polyedge, polymarker, ellipses, circles, arcs, etc. The first three of these essentially apply the transformations needed to map object coordinates to device coordinates, then call on the corresponding "draw dc ..." method. Text processing is somewhat more complex. See the discussion of "draw text" below for more information on the work of the "draw 3d text" method. Tristrip, polyedge, and polymarkers are associated with HOOPS shells.

.. image:: images/08_01_IMFacesHierarchy.gif

*The callback flow for shells, meshes and grids*
 
If you set a callback both at "draw 3d geometry" and at one of the type-specific callback points like "draw 3d marker", "draw 3d polyline", "draw 3d polygon", or "draw 3d text", then the latter prevails and your "draw 3d geometry" callback will not be called for geometry elements of that type.

*Callbacks:* \ref Set_Callback_draw_3d_geometry "draw 3d geometry", \ref Set_Callback_draw_3d_marker "draw 3d marker", \ref Set_Callback_draw_3d_polyline "draw 3d polyline", \ref Set_Callback_draw_3d_polygon "draw 3d polygon", \ref Set_Callback_draw_3d_text "draw 3d text", \ref Set_Callback_draw_3d_tristrip "draw 3d tristrip", \ref Set_Callback_draw_3d_polyedge "draw 3d polyedge", \ref Set_Callback_draw_3d_polymarker "draw 3d polymarker", \ref Set_Callback_draw_3d_image "draw 3d image", \ref Set_Callback_draw_3d_grid "draw 3d grid", \ref Set_Callback_draw_3d_mesh "draw 3d mesh", \ref Set_Callback_draw_3d_shell "draw 3d shell", \ref Set_Callback_draw_3d_sphere "draw 3d sphere", \ref Set_Callback_draw_3d_cylinder "draw 3d cylinder", \ref Set_Callback_draw_3d_polycylinder "draw 3d polycylinder", \ref Set_Callback_draw_3d_nurbs_curve "draw 3d nurbs curve", \ref Set_Callback_draw_3d_nurbs_surface "draw 3d nurbs surface", \ref Set_Callback_draw_3d_isoline "draw 3d isoline"
   

Draw Text Callback
------------------

The "draw text" callback is at an intermediate level of the text processing, below the level of 
"draw 3d text". Like "draw 3d text", the "draw text" method is called once for each inserted text string. The higher level passes to "draw text" an intermediate text information structure, which contains the results of certain computations that apply to the string as a whole. The computations performed by the "draw 3d text" level include the effects on the text reference point of modelling transformation, camera, text font size, text spacing, extra space, text alignment, text path, text rotation, and text slant attributes. Finally, the intermediate text information structure will contain some intermediate results, which depend on the coordinate transformations and the text attributes, and which might be needed to apply the per-character transformations as required by the text font transformability attribute.  The work of the standard "draw text" method is to reconcile the text attributes called for by the application with the capabilities of the requested font, and to complete the computations needed to draw the text. In particular, the "draw text" method is responsible for applying the per character transformations when appropriate and for applying atmospheric attenuation (fog) to text when it is called for.  If the text is finally to be drawn in a font provided by the hardware, the window system, or the driver, then "draw text" eventually calls on a driver-level "draw dc text" method, which does not have an I.M callback point. Otherwise, "draw text" causes the text to be stroked out, using the ordinary geometry drawing provisions, through "draw 3d text stroke" and "draw 3d text area" when per-character transformations are in effect, or directly through "draw dc text stroke" and "draw dc text area" otherwise. 

*Callbacks:* \ref Set_Callback_draw_text "draw text", \ref Set_Callback_draw_3d_text "draw 3d text"

.. image:: images/08_01_IMTextHierarchy.gif

*The draw text drawing pipeline*


Draw 3D Text, Area, and Stroke Callbacks
----------------------------------------

These "draw 3d text area" and "draw 3d text stroke" are effectively entry points to the "draw 3d polygon" and "draw 3d polyline" methods respectively, when the latter are called from the "draw text" level in the process of drawing characters of transformable stroked text. This includes text drawn from the built-in stroked font or user defined fonts. 

*Callbacks:* \ref Set_Callback_draw_3d_text_area "draw 3d text area", \ref Set_Callback_draw_3d_text_stroke "draw 3d text stroke"
   
   
Draw DC Geometry Callbacks
--------------------------

These are used to draw the respective objects, specified in device coordinates, subject to the relevant attribute values in the net rendition. Device coordinates are 3D floating-point coordinates. The x and y device coordinates are in pixel units, with origin at the lower left. When the graphics platform has a windowing system, the xy origin of the device coordinates may be at the lower left of the screen or at the lower left of the outer window, which is the window-system window that contains the HOOPS picture. The device driver determines which origin is used. In any case, at traversal time, you can determine the location of the device coordinate origin with respect to your HOOPS window by calling ``HIC_Show_Window_Extent``. The device z coordinate is relevant only when Z-buffering is in effect. 

The standard method for "draw dc edge" is exactly the same as "draw dc polyline", except that it uses the edge attributes in the net rendition rather than the line attributes. "draw dc line" is a special case of "draw dc polyline", specialized to the two-vertex polyline (line segment). It is called only from "draw dc colorized line", after the latter has changed the line color attribute according to its argument.  

.. image:: images/08_01_IMPolygonHierarchy.gif

*The drawing pipeline for polygons*
	
	
	Note on cutting planes:
	When cutting planes are present, some callbacks such as "draw dc face" will not be called. When cutting planes are involved, faces are triangulated, and they need a "draw dc triangle" callback instead. 
 

*Callbacks:* \ref Set_Callback_draw_dc_marker "draw dc marker", \ref Set_Callback_draw_dc_polyline "draw dc polyline", \ref Set_Callback_draw_dc_line "draw dc line", \ref Set_Callback_draw_dc_edge "draw dc edge", \ref Set_Callback_draw_dc_face "draw dc face", \ref Set_Callback_draw_dc_triangle "draw dc triangle", \ref Set_Callback_draw_dc_polytriangle "draw dc polytriangle"


Colorized Callbacks
-------------------

These are used to draw the respective objects with an RGB color passed as an argument to the method, 
rather than with the color specified by the rendition. These are called typically in the processing 
of geometry elements of a constant color, when the color has been computed by HOOPS, as in the case 
of lighting or fog. Each of the standard  "draw dc colorized ..." methods changes the relevant color 
attributes in the rendition and then calls on the corresponding  "draw dc ..." method. 

.. image:: images/08_01_IMMarkerHierarchy.gif

*The drawing pipeline for markers*


*Callbacks:* \ref Set_Callback_draw_dc_colorized_marker "draw dc colorized marker", \ref Set_Callback_draw_dc_colorized_polymarker "draw dc colorized polymarker", \ref Set_Callback_draw_dc_colorized_line "draw dc colorized line", \ref Set_Callback_draw_dc_colorized_polyline "draw dc colorized polyline", \ref Set_Callback_draw_dc_colorized_face "draw dc colorized face", \ref Set_Callback_draw_dc_colorized_triangle "draw dc colorized triangle", \ref Set_Callback_draw_dc_colorized_polytriangle "draw dc colorized polytriangle"
   
   
Draw DC Cut Line
----------------

The software path for drawing cut lines from cutting planes adds a lot of overhead, resulting in poor performance. To offset this, a "draw dc cut line" callback has been added. Using this, a program can "compute" the cutting lines by drawing the scene with them visible, storing the cut lines, turning the visibility of cut lines back off (restoring the fast path drawing), and inserting the stored lines as real geometry. 

*Callbacks:* \ref Set_Callback_draw_dc_cut_line "draw dc cut line"

  
Lighting Interpolation Callbacks
--------------------------------

The "draw dc gourad ..." and "draw dc phong ..." callbacks are used to draw the respective objects with color interpolated from vertex colors passed as arguments. 

*Callbacks:* \ref Set_Callback_draw_dc_gouraud_line "draw dc gouraud line", \refSet_Callback_draw_dc_gouraud_triangle "draw dc gouraud triangle", \refSet_Callback_draw_dc_gouraud_polytriangle "draw dc gouraud polytriangle", \refSet_Callback_draw_dc_gouraud_polyline "draw dc gouraud polyline", \refSet_Callback_draw_dc_phong_polytriangle "draw dc phong polytriangle", \ref Set_Callback_draw_dc_phong_polyline "draw dc phong polyline"


Driver Callbacks
----------------

The driver startup and driver shutdown callbacks are called when the HOOPS driver instances are created and destroyed. As callback points they provide hooks in case the application needs to do something special. However, these points DO NOT CORRESPOND to any existing HIC functions. Therefore developers must make sure that their callback functions return, so that HOOPS can continue startup or shutdown normally. 

*Callbacks:* \ref Set_Callback_driver_startup "driver startup", \ref Set_Callback_driver_shutdown "driver shutdown"


Finish Picture Callback
-----------------------

The "finish picture" callback is called when the HOOPS driver finishes drawing to a device. Can be used to access device-specific data using device-native functions. An example would be a frame buffer grab from OpenGL using glReadPixels.

*Callbacks:* \ref Set_Callback_finish_picture "finish picture"


HLR Callbacks
--------------

These callback points will be executed when hidden line is the active hidden surface removal algorithm. In this case the visible lines and markers will be accessible through the "hlr polyline" and "hlr marker" callbacks, while the hidden geometry can be accessed through the  "hlr hidden polyline" and "hlr hidden marker" callbacks. 

*Callbacks:* \ref Set_Callback_hlr_polyline "hlr polyline", 
\ref Set_Callback_hlr_marker "hlr marker", 
\ref Set_Callback_hlr_hidden_polyline "hlr hidden polyline", 
\ref Set_Callback_hlr_hidden_marker "hlr hidden marker"


Select Segment Callbacks
------------------------

These are called for processing the respective database elements in the course of a selection traversal. Setting a callback for "select 3d geometry" causes the callback function to be called for all the other geometry elements for which a specific "select ..." callback has not been set. "select segment tree" behaves for selection just as "draw segment tree" does for drawing, that is, it is only called on the segment that specifies it, not inherited and called on every subsegment the way "select segment" (and "draw segment") are. Selection traversal is initiated by a ``Get_Selection``, ``Show_Selection``, or ``Compute_Selection`` call. Given the locator screen coordinates for a selection event (or in the arguments of a ``Compute_Selection`` call), the system traverses the database and performs essentially the same computations as when updating the display, but draws nothing on the screen. Rather, the screen locations covered by each selectable geometry item are tested against the specified locator coordinates for hits. Hit criteria include proximity, area intersection, or volume intersection. During selection traversal the system keeps a list of 	selected elements, i.e. those encountered elements that are selectable according to the selectability attribute, and which are hit according to the hit criteria. The list of selected elements is ordered by proximity and by z coordinate. 

Its length is limited by the \ref Set_Heuristics_related_selection_limit "related selection limit" heuristic. At the end of the selection traversal, the application can examine the selected elements with the various ``Show_Selection`` functions and  ``Find_Related_Selection``. 
 	
*Callbacks:* \ref Set_Callback_select_segment "select segment", 
\ref Set_Callback_select_segment_tree "select segment tree", \ref Set_Callback_select_window "select window",
\ref Set_Callback_select_text "select text", \ref Set_Callback_select_3d_geometry "select 3d geometry",
\ref Set_Callback_select_3d_marker "select 3d marker", \ref Set_Callback_select_3d_polyline "select 3d polyline",
\ref Set_Callback_select_3d_polygon "select 3d polygon", \ref Set_Callback_select_text "select 3d text"


Database Activity Callbacks
---------------------------

These callback points will be activated when there is a modification to the segment tree under the point where the callback is set. The callback returns both the old and the new activity flags as well as the segment on which the change initially occurred. This callback is called when the actual database edit occurs, and is independent of a call to ``Update_Display``.	

*Callbacks:*

Set_Callback_segment_activity_change "segment activity change"
	

Creating and Setting Callbacks
==============================

Now that we have discussed the various callback points available through HOOPS I.M., you can implement your own callback functions. First, determine at which point you want to intercept HOOPS in the update cycle. This is important because it will tell you what parameters your function needs to accept. Once your function is created, you must register it with HOOPS. Callbacks are applied to a specific segment. So, to set your callback, open your target segment. Then, set your callback indicating the callback point and your function's callback name.

Once you are done with your callback, you should unset and unregister your callback.  To find out 
if a specific callback has been set, you can use ``Show_Existence`` as seen in the following sample code::
  
	if (HC_Show_Existence ("callback = draw dc polyline"))
	{
		AfxMessageBox("Draw DC Polyline callback is set.");
	}


Callbacks for C Developers
--------------------------

For C Developers, the process mentioned above for creating and setting callbacks can be followed 
verbatim.  To review, please follow the steps below:
  
  
#. Create a function which accepts the parameters for the desired callback point.
#. Register your callback with ``Define_Callback_Name``.
#. Open the segment in which you want to intercept the update cycle.
#. Set the callback with ``Set_Callback`` or ``Set_Callback_With_Data`` passing the callback point and the name you gave your callback in ``Define_Callback_Name``.
#. Use ``UnSet_Callback`` and ``UnDefine_Callback_Name`` to unset and unregister your callback function, respectively.
  
The following sample code shows how a function is used to intercept the \ref Set_Callback_draw_dc_polyline "draw dc polylines" callback point. The function``MyPatternedLine`` is implemented with same signature as the analogous I.M. function, ``HIC_Draw_DC_Polyline``.  In ``main``, ``MyPatterenedLines`` is registered with the name *patterned lines* in a call to ``Define_Callback_Name``. After a segment is created with a line inserted in it, the callback point, \ref Set_Callback_draw_dc_polyline "draw dc polylines", is set with the *patterned lines* callback function by using ``Set_Callback``::
  
	extern "C" {
	typedef void (*him_function)(HC_ANY_ARGS);
	}
	#define HIM_FUNCTION(function) (him_function)(function)

	/* types of indexed user options */
	#define MY_LINE_PATTERN		0

	/* values for MY_LINE_PATTERN user option */
	#define PURPLE_DASHES		0

	/* The callback function for Draw DC Polylines */
	void MyPatternedLine (HIC_Rendition	const *rendition, int count, HIC_DC_Point const *points) 
	{
		long kind;
		HIC_Rendition	const *new_rendition;
		HIC_RGB purple = {1.0f, 0.0f, 1.0f};

		kind = (long)HIC_Show_User_Option_By_Index (rendition, MY_LINE_PATTERN);

		if (kind == PURPLE_DASHES) {

			/* If the user option for MY_LINE_PATTERNED is PURPLE_DASHES, 
			we set the line style to dashes and set the line color to purple. */ 
			new_rendition = HIC_New_Rendition (rendition);
			HIC_Set_Line_Style (new_rendition, "- -");
			HIC_Set_Line_Color (new_rendition, &purple);
			HIC_Draw_DC_Polyline (new_rendition, count, points);
			HIC_Free_Rendition (new_rendition);
			
		} else {
			/* draw the original line */
			HIC_Draw_DC_Polyline (rendition, count, points);
		}  
	}

	void main ()
	{
		HPoint		pts[4];
		pts[0].x = -0.75f; pts[0].y =  0.25f; pts[0].z =  0.0f;
		pts[1].x = -0.5f; pts[1].y =  0.0f; pts[1].z =  0.0f;
		pts[2].x =  0.5f; pts[2].y =  0.0f; pts[2].z =  0.0f;
		pts[3].x =  0.75f; pts[3].y = -0.25f; pts[3].z =  0.0f;

		HC_Define_Callback_Name ("patterned lines", HIM_FUNCTION(MyPatternedLine));

		HC_Open_Segment ("");
			/* Setting the callback point at draw dc polylines and linking to our callback function*/
			HC_Set_Callback ("draw dc polylines = patterned lines");
			HC_Set_User_Index (MY_LINE_PATTERN, (void *)PURPLE_DASHES);
			HC_Insert_Polyline (4,pts);
		HC_Close_Segment ();
		
		HC_Update_Display();
	}


Callbacks for C++/C#/Java Developers
------------------------------------

For C++/C#/Java developers, creating and setting callbacks involves a slightly different process although all actions previously described remain the same underneath. Instead of including *hic.h*, you will include *hic_wraph.h*. This file defines a set of classes that correspond to each callback point available in HOOPS Intermediate Mode. Once you have included this file, you can follow the steps below to set up your callbacks.

.. raw:: html

	<ol>
		<li>Find the class that corresponds to the callback point you want to intercept.  The class and 
		the callback point have the same name.
		<li>Derive your own callback class from the target callback class.
			<ul>
				<li>Override the constructor passing in your own callback name.
				<li>Implement the abstract callback function.
			</ul>

		<li>Open the segment in which you want to intercept the update cycle at the target callback point.
		<li>Create an instance of your new callback class passing the key of the target segment.  Now your 
		callback has been defined and set.
		<li>Delete the instance of your callback class when you want to unset and undefine your callback.
	</ol>

The sample code below shows how you can create and set a callback at \ref Set_Callback_draw_dc_polyline "draw dc polylines". A callback is set up by deriving a new class from ``Draw_DC_Polyline`` called ``MyPatternedLine``. A new constructor is created that passes a callback name to the parent constructor. ``Draw_DC_Polyline::draw_dc_polyline()`` is an abstract method which HOOPS will call when the interception point is reached. So to use this callback, draw_dc_polyline must implemented be in MyPatternedLine. Like in the C example, the function looks at the value of the user option ``MY_LINE_PATTERN`` to see if it is ``PURPLE_DASHES``.  Then it draws a purple line with dashes. Otherwise, it calls ``HIC_Draw_DC_Polyline`` passing the original rendition::

	#include "hic_wrap.h"
	/* types of indexed user options */
	#define MY_LINE_PATTERN		0

	/* values for MY_LINE_PATTERN user option */
	#define PURPLE_DASHES		0

	class MyPatternedLine : public Draw_DC_Polyline
	{
	public:
		/*creating a new constructor with a name "Patterned Lines"*/
		MyPatternedLine(HC_KEY key, void * data=0) : Draw_DC_Polyline(key, "My Patterned Lines", data) {}

		/*Implementing the abstract draw_dc_polyline method*/
		virtual void draw_dc_polyline(HIC_Rendition const *nr, int count, HIC_DC_Point const *points)
		{
			long kind;
			HIC_Rendition	const *new_rendition;
			HIC_RGB purple = {1.0f, 0.0f, 1.0f};
		
			/*getting the value for user option*/
			kind = (long)HIC_Show_User_Option_By_Index (nr, MY_LINE_PATTERN);
		
			if (kind == PURPLE_DASHES) {
				/* If the user option for MY_LINE_PATTERNED is PURPLE_DASHES, 
				we set the line style to dashes and set the line color to purple. */ 
				new_rendition = HIC_New_Rendition (nr);
				HIC_Set_Line_Style (new_rendition, "- -");
				HIC_Set_Line_Color (new_rendition, &purple);
				HIC_Draw_DC_Polyline (new_rendition, count, points);
				HIC_Free_Rendition (new_rendition);
				
			} else {
				/* draw the original line */
				HIC_Draw_DC_Polyline (nr, count, points);
			}
		}
	};

	void main()
	{
		HPoint		pts[4];
		pts[0].x = -0.75f; pts[0].y =  0.25f; pts[0].z =  0.0f;
		pts[1].x = -0.5f; pts[1].y =  0.0f; pts[1].z =  0.0f;
		pts[2].x =  0.5f; pts[2].y =  0.0f; pts[2].z =  0.0f;
		pts[3].x =  0.75f; pts[3].y = -0.25f; pts[3].z =  0.0f;

		HC_Open_Segment_By_Key(m_pHView->GetModelKey());
			HC_KEY key = HC_KOpen_Segment("Purple Dashed Line");
				/*creating an instance of the new callback class which registers the 
				callback and sets it at the given key*/	
				MyPatternedLine * patternedPolyline = new MyPatternedLine(key);

				HC_Set_User_Index (MY_LINE_PATTERN, (void *)PURPLE_DASHES);
				HC_Insert_Polyline (4,pts);

			HC_Close_Segment();
		HC_Close_Segment();
		
		HC_Update_Display();

		/*unsetting and unregistering the callback by deleting the instance of the class*/
		delete patternedPolyline;
	}


HOOPS I.M. Functions
====================

HOOPS I.M. provides a library of functions that you can call from your callback functions to access the services of the HOOPS system. Presently, these functions are available only from callback functions written in C or C++. Their names all begin with ``HIC_``. You should refrain from calling most of the functions of classic HOOPS from your HOOPS I.M. callback functions. There are some exceptions; in particular, it is generally all right to call the classic ``Compute_...``  functions. But calling classic HOOPS functions that alter or query the database can have unpredictable results. For each callback point, there is a HOOPS I.M. function ``HIC_`` that you can call to pass control back to the standard default method for that callback point. The argument list of the callback is indicated with the ``HIC_...``  function. You can find the declarations of the argument types on the reference pages for the ``HIC_...``  functions.  Here is the correspondence between callback points and the standard default functions.

.. raw:: html

	<table class="table_style1">
	<tr>
	  <TD>draw segment</TD>
	  <TD>``HIC_Draw_Segment (nr, seg_info)``</TD>
	</tr>
	<TR>
	  <TD>
		 draw segment tree</TD>
	  <TD>
		  ``HIC_Draw_Segment (nr, seg_info)``</TD>
	</TR>
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>
	<TR>
	  <TD>
		 draw text</TD>
	  <TD>
		  ``HIC_Draw_Text (nr, text_info)``</TD>
	</TR>
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>	
	<TR>
	  <TD>
		 draw 3d marker</TD>
	  <TD>
		  ``HIC_Draw_3D_Marker (nr, marker)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d polymarker</TD>
	  <TD>
		  ``HIC_Draw_3D_Polymarker (nr, polymarker)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d polyline</TD>
	  <TD>
		  ``HIC_Draw_3D_Polyline (nr, polyline)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d infinite line</TD>
	  <TD>
		  ``HIC_Draw_3D_Infinite_Line (nr, polyline)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d polygon</TD>
	  <TD>
		  ``HIC_Draw_3D_Polygon (nr, polygon)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d ellipse</TD>
	  <TD>
		  ``HIC_Draw_3D_Ellipse (nr, ellipse)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d elliptical arc</TD>
	  <TD>
		  ``HIC_Draw_3D_Elliptical_Arc (nr, arc)``</TD>
	</TR>
	 <TR>
	  <TD>
		 draw 3d geometry</TD>
	  <TD>
		  ``HIC_Draw_3D_Geometry (nr, geometry)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d text</TD>
	  <TD>
		  ``HIC_Draw_3D_Text (nr, text)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d text stroke</TD>
	  <TD>
		  ``HIC_Draw_3D_Polyline (nr, polyline)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d text area</TD>
	  <TD>
		  ``HIC_Draw_3D_Polygon (nr, polygon)``</TD>
	</TR>
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d sphere</TD>
	  <TD>
		  ``HIC_Draw_3D_Sphere (nr, sphere)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d cylinder</TD>
	  <TD>
		  ``HIC_Draw_3D_Cylinder (nr, cylinder)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d polycylinder</TD>
	  <TD>
		  ``HIC_Draw_3D_PolyCylinder (nr, polycylinder)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d nurbs curve</TD>
	  <TD>
		  ``HIC_Draw_3D_NURBS_Curve (nr, curve)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d nurbs surface</TD>
	  <TD>
		  ``HIC_Draw_3D_NURBS_Surface (nr, surface)``</TD>
	</TR>
	 <TR>
	  <TD>
		 draw 3d polyedge</TD>
	  <TD>
		  ``HIC_Draw_3D_Polyedge (nr, polyedge)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d isolines</TD>
	  <TD>
		  ``HIC_Draw_3D_Polyedge (nr, polyedge)``</TD>
	</TR>	
	<TR>
	  <TD>
		 draw 3d tristrip</TD>
	  <TD>
		``HIC_Draw_3D_Tristrip (nr, tristrip)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d polyhedron</TD>
	  <TD>
		  ``HIC_Draw_3D_Polyhedron (nr, polyhedron)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d shell</TD>
	  <TD>
		  ``HIC_Draw_3D_Shell (nr, shell)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw 3d mesh</TD>
	  <TD>
		``HIC_Draw_3D_Mesh (nr, mesh)``</TD>
	</TR>	
	<TR>
	  <TD>
		 draw 3d grid</TD>
	  <TD>
		``HIC_Draw_3D_Grid (nr, grid)``</TD>
	</TR>	
	  <TR>
	  <TD>
		 draw 3d image</TD>
	  <TD>
		``HIC_Draw_3D_Image (nr, image)``</TD>
	</TR>	
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>
	<TR>
	  <TD>
		 draw dc marker</TD>
	  <TD>
		  ``HIC_Draw_DC_Marker (nr, point)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw dc colorized marker</TD>
	  <TD>
		  ``HIC_Draw_DC_Colorized_Marker (nr, point, color)``</TD>
	</TR>	
	<TR>
	  <TD>
		 draw dc polymarker</TD>
	  <TD>
		  ``HIC_Draw_DC_Polymarker (nr, count, point, rotations, size_fixups)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw dc colorized polymarker</TD>
	  <TD>
		  ``HIC_Draw_DC_Colorized_Polymarker (nr, count, point, color, single, rotations, size_fixups)``</TD>
	</TR>
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>	
	<TR>
	  <TD>
		 draw dc line</TD>
	  <TD>
		  ``HIC_Draw_DC_Line (nr, points)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw dc colorized line</TD>
	  <TD>
		  ``HIC_Draw_DC_Colorized_Line (nr, points, color)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw dc gouraud line</TD>
	  <TD>
		  ``HIC_Draw_DC_Gouraud_Line (nr, points, colors)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw dc reshaded line</TD>
	  <TD>
		  ``HIC_Draw_DC_Reshaded_Line (nr, points, colors, planes, params, param_width, param_flags)``</TD>
	</TR>				
	<TR>	
	  <TD>
		 draw dc polyline</TD>
	  <TD>
		  ``HIC_Draw_DC_Polyline (nr, count, points)``</TD>
	</TR>
	<TR>	
	  <TD>
		 draw dc colorized polyline</TD>
	  <TD>
		  ``HIC_Draw_DC_Colorized_Polyline (nr, count, points, color, single)``</TD>
	</TR>
	<TR>	
	  <TD>
		 draw dc gouraud polyline</TD>
	  <TD>
		  ``HIC_Draw_DC_Gouraud_Polyline (nr, count, points, colors)``</TD>
	</TR>
	<TR>	
	  <TD>
		 draw dc phong polyline</TD>
	  <TD>
		  ``HIC_Draw_DC_Phong_Polyline (nr, count, points, colors, planes)``</TD>
	</TR>
	<TR>	
	  <TD>
		 draw dc textured polyline</TD>
	  <TD>
		  ``HIC_Draw_DC_Textured_Polyline (nr, count, points, colors, planes, params, param_width, param_flags)``</TD>
	</TR>				
	<TR>
	 <TD>
		 draw dc edge</TD>
	  <TD>
		  ``HIC_Draw_DC_Polyline (nr, count, point)``</TD>
	</TR>      
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>	
	<TR>
	  <TD>
		 draw dc face</TD>
	  <TD>
		  ``HIC_Draw_DC_Face (nr, count, points)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw dc colorized face</TD>
	  <TD>
		  ``HIC_Draw_DC_Colorized_Face (nr, count, points, color)``</TD>
	</TR>
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>	
	<TR>
	  <TD>
		 draw dc triangle</TD>
	  <TD>
		  ``HIC_Draw_DC_Triangle (nr, points)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw dc colorized triangle</TD>
	  <TD>
		  ``HIC_Draw_DC_Colorized_Triangle (nr, points, color)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw dc gouraud triangle</TD>
	  <TD>
		  ``HIC_Draw_DC_Gouraud_Triangle (nr, points, colors)``</TD>
	</TR>
	<TR>
	 <TD>
		 draw dc reshaded triangle</TD>
	  <TD>
		  ``HIC_Draw_DC_Reshaded_Triangle (nr, points, colors, planes, params, param_width, param_flags)``</TD>
	</TR>
	<TR>
	 <TD>
		 draw dc polytriangle</TD>
	  <TD>
		  ``HIC_Draw_DC_Polytriangle (nr, count, points)``</TD>
	</TR>
	<TR>
	 <TD>
		 draw dc colorized polytriangle</TD>
	  <TD>
		  ``HIC_Draw_DC_Colorized_Polytriangle (nr, count, points, color, single)``</TD>
	</TR>
	<TR>
	 <TD>
		 draw dc gouraud polytriangle</TD>
	  <TD>
		  ``HIC_Draw_DC_Gouraud_Polytriangle (nr, count, points, colors)``</TD>
	</TR>
	<TR>
	 <TD>
		 draw dc phong polytriangle</TD>
	  <TD>
		  ``HIC_Draw_DC_Phong_Polytriangle (nr, count, points, colors, planes)``</TD>
	</TR>
	<TR>
	 <TD>
		 draw dc textured polytriangle</TD>
	  <TD>
		  ``HIC_Draw_DC_Textured_Polytriangle (nr, count, points, colors, planes, params, param_width, param_flags)``</TD>
	</TR>						
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>	
	<TR>
	  <TD>
		 draw dc text stroke</TD>
	  <TD>
		  ``HIC_Draw_DC_Polyline (nr, count, points)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw dc text area</TD>
	  <TD>
		  ``HIC_Draw_DC_Face (nr, count, points)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw window</TD>
	  <TD>
		  ``HIC_Draw_Window (nr, extent)``</TD>
	</TR>
	<TR>
	  <TD>
		 draw window frame</TD>
	  <TD>
		  ``HIC_Draw_Window_Frame (nr, extent frame, calc)``</TD>
	</TR>
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>
	<TR>
	  <TD>
		 driver startup<br>
		driver shutdown</TD>
	  <TD>
		  No corresponding HIC functions. User callback MUST return for normal startup and shutdown to continue.  </TD>
	</TR>
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>
	<TR>
	  <TD>
		 finish picture<br>
	  </TD>
	  <TD>
		  ``HIC_Finish_Picture (nr, swap_buffers)``</TD>
	</TR>
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>
	<TR>
	  <TD>
		 hlr polyline</TD>
	  <TD>
		 ``HIC_Draw_DC_Polyline (nr, count, points)``</TD>
	</TR>
	<TR>
	  <TD>
		 hlr marker</TD>
	  <TD>
		 ``HIC_Draw_DC_Marker (nr, point)``</TD>
	</TR>
	<TR>
	  <TD>
		 hlr hidden polyline</TD>
	  <TD>
		 ``HIC_Draw_DC_Polyline (nr, count, points)``</TD>
	</TR>
	<TR>
	  <TD>
		 hlr hidden marker</TD>
	  <TD>
		 ``HIC_Draw_DC_Marker (nr, point)``</TD>
	</TR>
	<TR>
	  <TD>&nbsp;
	  </TD>
	  <TD>&nbsp;
	  </TD>
	</TR>
	<TR>
	  <TD>
		 select 3d marker</TD>
	  <TD>
		 ``HIC_Select_Geometry (nr, marker)``</TD>
	</TR>
	<TR>
	  <TD>
		 select 3d polyline</TD>
	  <TD>
		  ``HIC_Select_Geometry (nr, polyline)``</TD>
	</TR>
	<TR>
	  <TD>
		 select 3d polygon</TD>
	  <TD>
		``HIC_Select_Geometry (nr, polygon)``</TD>
	</TR>
	<TR>
	  <TD>
		 select text<br>
		select 3d text</TD>
	  <TD>
		  ``HIC_Select_Geometry (nr, text)``</TD>
	</TR>
	<TR>
	  <TD>
		 select 3d geometry</TD>
	  <TD>
		  ``HIC_Select_Geometry (nr, geometry)``</TD>
	</TR>
	<TR>
	  <TD>
		 select window</TD>
	  <TD>
		  ``HIC_Select_Window (nr, wind_info)``</TD>
	</TR>
	<TR>
	  <TD>
		 select segment<br>
		select segment tree</TD>
	  <TD>
		  ``HIC_Select_Segment (nr, seg_info)``</TD>
	</TR>	
	</table>
