1.0 Introduction

2.0 Compilation and Runtime Information

3.0 Interface Notes


1.0 Introduction

The HOOPS/Winforms integration consists of C# wrappers to HOOPS/3dGS, HOOPS/MVO, HOOPS/Stream and HOOPS/Parasolid . This document describes how to use C# with the different HOOPS/3dAF components. Some familiarity with HOOPS/3dGS and HOOPS/MVO is assumed. This guide discusses specific language features associated with developing with HOOPS in C#. For developers who want to integrate HOOPS with C# GUI toolkits like Winforms and WPF, documentation is provided in the HOOPS/Winforms and HOOPS/WPF, respectively.

1.1 Platform/Compiler Support

The C# base HOOPS applications are supported under Microsoft Visual Studio 2005 (VC8) and Microsoft Visual Studio 2008 (VC9).


2.0 Compilation and Runtime Information

The following steps are required to compile and run a C# based application:

  • Compiling: Your application must reference the HOOPS/3dAF C# wrapper classes.
    • For HOOPS/3dGS: reference
      • hoops<version>_cs<Visual Studio version>.dll
      • hics<version>_cs<Visual Studio version>.dll
    • For HOOPS/MVO: reference hoops_mvo<version>_cs<Visual Studio version>.dll.
    • For HOOPS/Stream: reference hoops_stream<version>_cs<Visual Studio version>.dll.
    • For HOOPS/Parasolid: reference hcsp_bridge<version>_cs90.dll. Note that the Parasolid Bridge is only supported for Microsoft Visual Studio 2008(VC 9).
  • Executing: Ensure that the following native .dlls are in your application's directory or in your PATH.
    • For use of HOOPS/3dGS:
      • hoops<version>_vc<Visual Studio version>.dll
      • hcs<version>.dll
      • hics<version>.dll
    • For use of HOOPS/MVO:
      • hoops_mvo_mgk<version>_vc<Visual Studio version>.dll
      • hcsmvo<version>.dll
    • For use of HOOPS/Stream:
      • hoops_stream<version>_vc<Visual Studio version>.dll
      • hcsstream<version>.dll
    • For use of HOOPS/Parasolid:Note that the Parasolid Bridge is only supported for Microsoft Visual Studio 2008(VC 9).
      • hp_bridge<version>_<Parasolid version>_vc90.dll
      • hcsp_bridge<version>.dll
      • pskernel.dll
      • pskernel_net.dll

The above files are located in your <hoops>/bin/nt_i386_vc<Visual studio="" version>=""> directory.

Note: Both C#.Net and VB.Net application code can access these C# wrappers, because Visual Studio 2005 provides built in support for VB apps to access C# interfaces. You simply include the C# references.


3.0 Interface Notes

3.1 General Usage

The routines and classes of the HOOPS/3dGS, HOOPS/MVO and HOOPS/Stream toolkits are all generally accessible via the C# wrappers, with a few exceptions and notes covered below. Developers should refer to the Reference Manual for each component, and can additionally leverage the Intellisense capability of Visual Studio 2005 to dynamically access listings of class members and function/method argument while programming.

Defines

You should also add this "define" to your document somewhere:

#if _M_X64
  using HLONG = System.Int64;
#else
  using HLONG = System.Int32;
#endif

Then, for 64 bit projects, you should define the _M_X64 (you can name this anything you want). You should use "HLONG" in all places where you would normally use a C "long". This is because C#'s "long" is always 64 bit, whereas C's "long" is often 32 bit, and are incompatible. Using HLONG will help ensure compatability. (You can also simply use ints for 32 bit projects and longs for 64 bit projects, but things may get confusing).

3.2 HOOPS/3dGS-specific

Routine Prefixes

Each routine name, such as Insert_Polyline in your HOOPS program must have a prefix before the name will actually be usable on your computer system. The prefix varies depending on which language you're calling from, and sometimes depending on the brand of the language you're calling from. When calling from C#, all calls to the HOOPS/3dGS API are made through the HCS class, such as:

HCS.Open_Segment("newsegment");
HCS.Insert_Line(0, 0, 0, 1, 1, 1);
HCS.Close_Segment();

HOOPS Routines Available in C#

Most functions available under C are available in C# except for:

Define_Callback_Name
Define_Exit_Handler
UnDefine_Exit_Handler
Define_Callback_Name
UnDefine_Callback_Name
Show_Callback_Name
Set_Driver
QSet_Driver

Two functions are different under C# than C:

UnDefine_Error_Handler
Define_Error_Handler

Both take an HCSU.errfunc object (which is a delegate) as their argument. If null is passed to UnDefine_Error_Handler, it will remove the default HOOPS error handler. If an already registered HCSU.errfunc is passed, that handler will be removed.

Here is an example of declaring an error handler:

public void error_handler(int category, int specific, int severity, int msgc, sbyte ** msgv, int stackc, sbyte ** stackv)
{
}

public void init()
{  
    HCSU.errfunc error_hndlr_ptr = new HCSU.errfunc(error_handler);
    HCS.Define_Error_Handler(error_hndlr_ptr);
    
    HCS.Open_Segment("?picture");
      //  do something
    HCS.Close_Segment();
}

Note: You may have to set your project to "allow unsafe code" in order to use the error handler, as it uses pointers.

Pointers and write-back values

The largest difference between using HOOPS with C# and C is found when you have a write-back value, i.e. you pass a pointer to a function and it writes a value or values to that location. In HOOPS C#, arrays can typically be written to without any extra help, while single variables need a "ref" keyword before the object name (similar to the "&" in C/C++).

For example, the C HOOPS code that uses a char*:

char ex[1024];
    
HC_Show_Alias("?picture", ex);
printf("?picture=%s\n", ex); 

is replaced in C# by StringBuilder:

StringBuilder ex = new StringBuilder(1024);

ex.EnsureCapacity(1024);

HCS.Show_Alias("?picture", ex);

Console.WriteLine("?picture="+ex);

NOTE: The "StringBuilder" type is used for write-back values. Note that before you begin writing into StringBuilder, you should call EnsureCapacity to guarantee your instance has the minimum specified value. You should use the "string" type for constant string values. These are enforced by the function signatures, so you should not be able to pass in the wrong type.

The C HOOPS code that uses &[float_value]:

float x,y,z;
     
HC_QShow_Camera_Position("?picture", &x, &y, &z);
     
printf(" x=%f y=%f z=%f\n", x, y, z); 

is used in a similar manner in C#, with the "ref" keyword:

float x = new float();
float y = new float();
float z = new float();
    
HCS.QShow_Camera_Position("?picture", ref x, ref y, ref z); 
Console.WriteLine(" x="+ x + " y="+ y + " z="+ z); 

Arrays can be used in C# in a similar manner as they are used in C. Thus, the C HOOPS code:

float v1[3] = {1.0f,0.0f,0.0f};
float v2[3] = {0.0f,1.0f,0.0f};
float v3[3];
      
HC_Compute_Cross_Product(v1,v2,v3);
printf("%f %f %f\n", v3[0], v3[1], v3[2]); 

is accomplished in C# by:

float[] v1 = {1.0f,0.0f,0.0f};
float[] v2 = {0.0f,1.0f,0.0f};
float[] v3 = new float[3];
HCS.Compute_Cross_Product(v1,v2,v3);
Console.WriteLine(v3[0] + " " + v3[1] + " " + v3[2]); 

HOOPS Keys

Another difference between using HOOPS with C# and C is found when dealing with HOOPS keys. In C#, you should use HLONG (assuming you defined it as mentioned in the Section 3.1 above). Thus, the C code:

HC_KEY key = 0;

key = HC_Open_Segment("?picture");
   ...
HC_Open_Segment_By_Key(key); 

is replaced in C# by:

HLONG key = 0;

key = HCS.KOpen_Segment("?picture");
   ...
HCS.Open_Segment_By_Key(key); 

Datatype Names and Language Declarations in C#

The C# datatypes translate as follows:

HOOPS HOOPS (HC) type C# type
'string' HC type string
'writes string' const char * StringBuilder
'HC_KEY' HC_KEY HLONG (System.Int32 / System.Int64)
'int' int int
'writes int' +" ref int
'float' float float
'writes float' &float ref float
'point' float[3] float[3]
'writes point' &float float[]
'writes bytes' unsigned char * sbyte[]
'writes ints' +" int[]

HOOPS Intermediate Mode

The HOOPS Intermediate Mode library provides a means for an application to trap the HOOPS update cycle at certain points in the rendering pipeline through a set of callback classes. When you trap the update cycle at a callback point, you can decide what and how something is drawn, or even abort the process itself. The HOOPS I.M. library also provides a set of functions you can call from your callback class to draw to the display in an "immediate mode" style and to query the graphics database and the device characteristics. In the HOOPS/3dGS Programming Guide, you can learn more about HOOPS I.M. and how to implement and use the callback classes.

3.3 HOOPS/MVO-specific

3.3.1 Recent Updates

Prior to Release 17, when developers derived from a HOOPS/MVO class in C#, they could not access protect members. However beginning with Release 17, protected members of a parent HOOPS/MVO class can be accessed just like any member from a child class. For Java developers, protected members are accessed via helper set/get functions with member name appended to the end of set/get.

HOOPS/MVO Classes in C#/Java

A majority of HOOPS/MVO classes are available in C# and Java. However, a number of HOOPS/MVO classes are not provided due to some inherent challenges with the wrapper process.

HOOPS/MVO provides the ability create and modify animations. The HOOPS/MVO animation classes that are accessible in C#/Java are HBhvAnimation and HBhvBehaviorManager. These classes give you the ability to build and manipulate a wide variety of keyframe based behaviors as described in sections 10.1 Introduction to Behaviors and Animations to 10.3 Defining Behaviors for basic animations in the HOOPS/MVO Programming Guide. The classes associated with animation that not accessible in C# are listed below.

The following operators are also not accessible in C#/Java:

A number of input and output handlers are not available in C#/Java. They are listed below.

Although HObject and HObjectManager are both availabe in C#/Java, the HOOPS/MVO child classes associated with HObject are not. These include the following:

Most utility classes are available in C#/Java except for the following:

The following HOOPS/MVO classes are also not accessible via C#/Java:

 

Multiple Inheritance

The concept of multiple inheritance is not supported in C# or Java. Thus, access to certain HOOPS/MVO classes that utilize multiple inheritance is limited. Specifically, these classes were wrapped with only one class inherited. The following is a list of the C++ MVO classes that use multiple inheritance and what single class they now inherit from in C#/Java.

HOOPS/MVO Class Parent Class in C#/Java Parent Classes in C++
HBaseView HUpdateListener HUpdateListener, HMouseListener, HObjectManipulationListener
HTCObjectRotate HBaseOperator HBaseOperator, HTClient

Additionally, the inability to inherit from multiple classes will impede the use of the HEventListener, HEventListenerItem, HEventListenerManager and HEventManager classes. When deriving a class from one of these event classes, it is likely that you will want to derive from another HOOPS/MVO class like HBaseOperator at the same time. Thus the event classes cannot be used in this manner.

Datatypes

Most HOOPS/MVO datatypes are accessible in C#/Java but there are some datatypes that have not gone through the wrapper process. They appear in the C#/Java environment with the SWIGTYPE prefixed to their datatype name. Although methods that use these datatypes can be seen with Intellisense, any code calling these methods will not compile. Below is a list of methods that cannot be called in C#/Java because they used datatypes that have not gone through the wrapper process completely.

HOOPS/MVO Class Inaccessible HOOPS/MVO Method
HAnimationListener public virtual int ObjectCollisionEvent(SWIGTYPE_p_HBhvTargetObject tob)
HAnimationListener public virtual int ObjectNoCollisionEvent(SWIGTYPE_p_HBhvTargetObject tob)
HAnimationListener public virtual int AnimationFinishedEvent(SWIGTYPE_p_HBhvAnimation ainst)
HBaseModel public SWIGTYPE_p_HBhvBehaviorManager GetBhvBehaviorManager()
HBaseModel public void SetBhvBehaviorManager(SWIGTYPE_p_HBhvBehaviorManager BehaviorManager)
HBaseView public bool SetStencilProbe(SWIGTYPE_p_HStencilProbe sp)
HBaseView public SWIGTYPE_p_HUtilityAntialiasing GetAntialiasing()
HBaseView public SWIGTYPE_p_HStencilProbe GetStencilProbe()
HBaseView public SWIGTYPE_p_HSharedKey GetSharedKey()
HDebugZBuffer public void OpenglFinishPicture(SWIGTYPE_p_ht_net_rendition nr, bool swap_buffers)
HImErrorHandler public static void CallbackEntryPoint(int category, int specific, int severity, int msgc, SWIGTYPE_p_p_char msgv, int stackc, SWIGTYPE_p_p_char stackv)
HImUtility public static void set_clip_rectangle(SWIGTYPE_p_ht_net_rendition nr, SWIGTYPE_p_ht_segment_info si)
HImUtility public static void suppress_3d_geometry(SWIGTYPE_p_ht_net_rendition rendition, SWIGTYPE_p_ht_geometry geo3)
HImUtility public static void draw_gradiated_window_background(SWIGTYPE_p_ht_net_rendition rendition, SWIGTYPE_p_ht_int_rectangle extent)
HImUtility public static void draw_annotation_lines(SWIGTYPE_p_ht_net_rendition nr, SWIGTYPE_p_ht_polyline poly)
HImUtility public static void draw_segment_in_background(SWIGTYPE_p_ht_net_rendition nr, SWIGTYPE_p_ht_dc_point points, SWIGTYPE_p_ht_rgba colors, SWIGTYPE_p_ht_plane planes, float[] hparams, int param_width, int param_flags)
HImUtility public static void draw_dc_polyline_infront(SWIGTYPE_p_ht_net_rendition rendition, int count, SWIGTYPE_p_ht_dc_point geo3)
HImUtility public static void draw_device_independent_line_weights(SWIGTYPE_p_ht_net_rendition rendition, int count, SWIGTYPE_p_ht_dc_point geo3)
HImUtility public static void drawTextInfront(SWIGTYPE_p_ht_net_rendition rendition, SWIGTYPE_p_ht_text_info text_info)
HImUtility public static void visible_hlr_polyline(SWIGTYPE_p_ht_net_rendition rendition, int count, SWIGTYPE_p_ht_dc_point geo3)
HIOConnector public virtual bool GetHoopsEntities(IntPtr pKernelEntity, SWIGTYPE_p_vlist_s ret_HoopsKeysList)
HIOConnector public virtual bool GetKernelEntities(MVO_POINTER_SIZED_INT key, SWIGTYPE_p_vlist_s ret_KernelEntitiesList)
HOpCameraWalk public static int ImageAction(SWIGTYPE_p_HImageRegion ii, IntPtr data, SWIGTYPE_p_HButtonState keyup)
HOpCameraWalk public void OnButtonWalk(string action, SWIGTYPE_p_HButtonState buttonstate)
HSelectionSet public virtual SWIGTYPE_p_vlist_s GetSelectionList()
HSensorListener public virtual int SensorActivatedEvent(SWIGTYPE_p_HBhvSensor sensor)
HUtility public static void ShowContentsWithPath(string entitytypes, SWIGTYPE_p_p_vlist_s ret_pathlist, bool storePath, bool includeIncludes, bool filterIncludes)
HUtility public static void ShowContentsWithPath(string entitytypes, SWIGTYPE_p_p_vlist_s ret_pathlist, bool storePath, bool includeIncludes)
HUtility public static void ShowContentsWithPath(string entitytypes, SWIGTYPE_p_p_vlist_s ret_pathlist, bool storePath)
HUtility public static void ShowContentsWithPath(string entitytypes, SWIGTYPE_p_p_vlist_s ret_pathlist)
HUtility public static void MakeViewSnapshot(HBaseView view, int width, int height, SWIGTYPE_p_p_char data)

Note that pointers to vlist and vhash are also not accessible via C# or Java.

Macros and Function Pointers

MVO macros are not available in C#/Java. Function pointers are also not supported. Although methods with function pointers in their signatures can be seen by Intellisense, any calls to them will not compile. Member variables which are function pointers cannot be accessed either. Generally, if a parameter or variable has a data-type prefixed with SWIGTYPE, it is unlikely that it can be used in C# or Java. In the following example, the HIOManager's RegisterConnector method cannot be used in C#/Java because the parameters Create and Free are function pointers. In the C#/Java function declaration, it can be seen that Create and Free have datatypes prefixed with SWIGTYPE.

  
public virtual HIOConnector HIOManager::RegisterConnector(string file_type, SWIGTYPE_p_f_p_void__p_void Create, SWIGTYPE_p_f_p_void__void Free)

The following is a list of methods that cannot be accessed in C#/Java because they have functions pointers in their signature:

HOOPS/MVO Class HOOPS/MVO Method
HBaseView public SWIGTYPE_p_f_p_q_const__char_unsigned_int_p_void__void GetEmitMessageFunction()
HBaseView public SWIGTYPE_p_f_p_ht_net_rendition__void GetEventCheckerCallback()
HBaseView public SWIGTYPE_p_f_unsigned_int_r_int__bool GetKeyStateCallback()
HBaseView public void SetEmitMessageFunction(SWIGTYPE_p_f_p_q_const__char_unsigned_int_p_void__void new_emit_message_function)
HBaseView public void SetEmitMessageFunction(SWIGTYPE_p_f_p_q_const__char_unsigned_int_p_void__void new_emit_message_function, IntPtr user_data)
HBaseView public void SetEventCheckerCallback(SWIGTYPE_p_f_p_ht_net_rendition__void EventChecker)
HBaseView public void SetKeyStateCallback(SWIGTYPE_p_f_unsigned_int_r_int__bool KeyState)
HBaseView public uint SetSignalNotify(int signal, SWIGTYPE_p_f_int_p_void_p_void__bool callback, IntPtr user_data)
HIOManager public HIOConnector RegisterConnector(string file_type, SWIGTYPE_p_f_p_void__p_void Create, SWIGTYPE_p_f_p_void__void Free)
HTClient HTClient(float interval, HTCStyle style, SWIGTYPE_p_f_float_float_p_void__bool tick_function, IntPtr user_data)
HTClient HTClient(float interval, HTCStyle style, SWIGTYPE_p_f_float_float_p_void__bool tick_function)
HTClient public SWIGTYPE_p_f_float_float_p_void__bool GetTickFunction()
HTClient public void SetTickFunction(SWIGTYPE_p_f_float_float_p_void__bool tick_function)

Variant Methods

Although some HOOPS/MVO classes are availabe in C#/Java, not all their methods can be used because of the design of either C# or Java. In these cases, HOOPS provides a variant especially designed for C#/Java users. Below is a list of classes, their inaccessible methods and their C#/Java variants.

Class Inaccessible Method C#/Java Variant Method
HSelectionItem virtual const HC_KEY * HSelectionItem::GetFullPathKeys (HBaseView *view) virtual void HSelectionItem::GetFullPathKeys (HBaseView *view, System.Int32/System.Int64[] path)
HSmartSelItem virtual const HC_KEY *const HSmartSelItem::GetIncludeKeys () const virtual void HSmartSelItem::GetIncludeKeys (System.Int32/System.Int64[] includes) const
HSmartSelItem virtual const HC_KEY * HSmartSelItem::GetFullPathKeys (HBaseView *view) virtual void HSmartSelItem::GetFullPathKeys (HBaseView *view, System.Int32/System.Int64[] path)
HShellObject int const * HShellObject::GetFlist () const void HShellObject::GetFlist (int[] flist) const
HShellVertexData float const *const HShellVertexData::GetFIndexData () const void HShellVertexData::GetFIndexData (float[] data) const

3.4 HOOPS/Parasolid-specific

All the methods needed to use the HOOPS/Parasolid integration module are available in C#. You can read more about them in the HOOPS/Parasolid reference manual. In the C# interface for HOOPS/Parasolid, you will find that Read_Xmt_File and Write_Xmt_File are not included. For Read_Xmt_File, we recommend that instead, you use the native Parasolid C# methods to load object into the Parsolid modeler. Once this is complete, then you import them into HOOPS. The following sample code shows how you can do this.

HFileInputResult Read_Xmt(string filename)
{
  PK.ERROR.code_t result;

  PK.PART.receive_o_t options = new PK.PART.receive_o_t(true);
  options.transmit_format = PK.transmit_format_t.text_c;

  fixed( PK.PART_t **parts = &m_pParts )
  fixed (int* num_parts = &m_numParts)
  {
     result = PK.PART.receive(filename, &options, num_parts, parts);
  }            

  if (result == PK.ERROR.code_t.no_errors)
  {
      HCS.Open_Segment_By_Key(this.GetModelKey());
          HCSP.Render_Entities(m_numParts, (PK.ENTITY_t*)m_pParts, 0, null);
      HCS.Close_Segment();
  }

  return (result == PK.ERROR.code_t.no_errors) ? HFileInputResult.InputOK : HFileInputResult.InputFail;
}

For Write_Xmt_File, we recommend also that you use the native Parasolid C# methods to export information into a file. The following sample code shows how to write an Xmt file.

HFileOutputResult Write_Xmt(string filename)
{
  PK.ERROR.code_t result;

  PK.PART.transmit_o_t options = new PK.PART.transmit_o_t(true);
  options.transmit_format = PK.transmit_format_t.text_c;
            
  result = PK.PART.transmit(m_numParts, m_pParts, filename, &options);            

  return (result == PK.ERROR.code_t.no_errors) ? HFileOutputResult.OutputOK : HFileOutputResult.OutputFail;            
}

The Read_Xmt_File and Write_Xmt_File methods are used in a C# sample program that integrates with HOOPS/Parasolid. It can be found in demo/csharp/csharp_simple_parasolid.