HOOPS for Java Developers

Introduction

The HOOPS/Java integration consists of Java wrappers to HOOPS/3DGS, HOOPS/MVO, and HOOPS/Stream. This document describes how to use the HOOPS/Java integration to build a Java application that incorporates the HOOPS/3DF components. Some familiarity with Java, HOOPS/3DGS, and HOOPS/MVO is assumed.

Platform/Compiler Support

The HOOPS/Java integration is supported under the J2SE Development Kit 6.0 (JDK 6.0), on the Windows 32-bit and 64-bit platforms. It is also supported on Linux platforms.

Compilation and Runtime Information

The following steps are required to compile and run a HOOPS/Java based application:

Compiling: You must place the HOOPS/3DF and HOOPS/Java .jar files in your classpath. This can either be done via the command line for both compiling and running, or it can be set in the manifest file for your project. The files are:

  • HJ.jar

  • HIJ.jar

  • HJMVO.jar

  • HJSTREAM.jar

  • HJCanvas.jar

Executing: Ensure that the following files are in your application's directory.
  • .jar files: (discussed above)
  • Java wrapper libraries:
    • For HOOPS/3DGS:
      • Windows:
        • *hj.dll*
        • *hij.dll*
      • Linux:
        • *hj.so*
        • *hij.so*
    • For HOOPS/MVO:
      • Windows: *hjmvo.dll*
      • Linux: *hjmvo.so*
    • For HOOPS/Stream:
      • Windows: *hjstream.dll*
      • Linux: *hjstream.so*
  • native libraries:
    • For HOOPS/3DGS:
      • Windows: *hoops_vc.dll*
      • Linux: *hoops.so*
    • For HOOPS/MVO:
      • Windows: *hoops_mvo_vc.dll*
      • Linux: *hoops_mvo.so*
    • For HOOPS/Stream:
      • Windows: *hoops_stream_vc.dll*
      • Linux: *hoops_stream.so*

The above files should all be located in your <hoops>/bin/nt_<platform>_<Visual Studio Version> directory on Windows, and your <hoops>/bin directory under Linux.

For Linux platforms, prior to execution, you must execute two export commands. Below is a list based on the platform you are using:

For 32-bit Linux (on a 32-bit machine ONLY):

$ cd bin/linux
$ export LD_LIBRARY_PATH=./:../../Dev_Tools/hoops_3dgs/lib/linux/
$ export LD_PRELOAD=./libhoops<version>.so:./libopengl2<version>hdi.so

For 64-bit Linux (on a 64-bit machine ONLY):

$ cd bin/linux_x86_64
$ export LD_LIBRARY_PATH=./:../../Dev_Tools/hoops_3dgs/lib/linux_x86_64/
$ export LD_PRELOAD=./libhoops<version>.so:./libopengl2<version>hdi.so

Interface Notes: General Usage

The routines and classes of the HOOPS/3DGS, HOOPS/MVO and HOOPS/Stream toolkits are all generally accessible via the Java wrappers, with a few exceptions and notes covered below. Developers should refer to the API reference manual for each component, and can additionally leverage the Intellisense capabilities of the NetBeans IDE to see listings of class members and function/method arguments.

HOOPS/3DGS-specific

Routine Prefixes

Each HOOPS/3DGS 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 Java, all calls to the HOOPS/3GS API are made through the HJ class, such as:

StringBuffer ex = new StringBuffer ("");
HJ.Show_Alias("?picture", ex);

Multi-Threading

You must call Define_System_Options("multi-threading=full") as your first HOOPS call. This is because Java apps must be thought of as multi-threaded, since the garbage collector will run on a separate thread and may trigger HOOPS calls on a separate thread if it invokes certain destructors.

HOOPS Routines Available in Java

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

  • Define_Callback_Name

  • Define_Exit_Handler

  • UnDefine_Exit_Handler

  • Define_Callback_Name

  • UnDefine_Callback_Name

  • Show_Callback_Name

  • Define_Error_Handler

Differences Between Using HOOPS With Java and C

The largest difference between using HOOPS with Java 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. Because Java does not have pointers, we have to use other means of passing in by reference.

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 Java by StringBuffer:

StringBuffer ex = new StringBuffer (1024);

HJ.Show_Alias("?picture", ex);
System.out.println("?picture="+ex);

NOTE: You must always pass a new or empty StringBuffer, as HJ uses append internally to return the string. You must also call ensureCapacity to guarantee the buffer has a minimum size before anything can be written into it. For example:

StringBuffer buf = new StringBuffer();
buf.ensureCapacity(1024);
HJ.Show_Color(buf);

The C HOOPS code that uses &[float_value]:

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

…is replaced in Java by single element float arrays:

float[] x = new float[1];
float[]  y = new float[1];
float[]  z = new float[1];

HJ.Open_Segment("?picture");
HJ.Show_Camera_Position(x, y, z);
HJ.Close_Segment();
System.out.println("x=" + x[0] + "y=" + y[0] + "z=" + z[0]);

Arrays can be used in Java 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 replaced in Java by::

float[] v1 = {1.0f,0.0f,0.0f};
float[] v2 = {0.0f,1.0f,0.0f};
float[] v3 = new float[3];
HJ.Compute_Cross_Product(v1,v2,v3);
System.out.println( v3[0]+" "+v3[1]+" "+ v3[2]);

It’s important to allocate enough room in the array, lest HOOPS writes into unallocated memory and causes a segfault.

HOOPS Keys

Another difference when using HOOPS with Java is found when dealing with HOOPS keys. In Java, you should use the Java long:

long key = 0;

key = HJ.Open_Segment("?picture");
   ...
HJ.Open_Segment_By_Key(key);

Datatype Names and Language Declarations in Java

The Java datatypes translate as follows:

HOOPS HOOPS (HC) type Java type
'string' const char * String
'writes string' char * StringBuffer
'HC_KEY' HC_KEY long
'int' int int
'writes int' &int int[1]
'float' float float
'writes float' &float float[1]
'point' float[3] float[3]
'writes point' &float float[]
'writes bytes' unsigned char * byte[]
'writes ints' &int 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.

Any callback class, which has a virtual function with an array as a parameter, is not available in Java. This is because Java doesn’t have any concept of a pointer so functions with array arguments cannot be mapped properly.

HOOPS/MVO and HOOPS/Stream

The capabilities and limitations of HOOPS/MVO for Java are largely analogous to those of C#. After reviewing this section, you can learn more by clicking here.

Member Variables

Member variables are accessed via helper set/get functions with a capitalized member name appended to the end of set/get. For example:

C++:

  • class: HOpCameraManipulate

  • member: m_pRelativeOrbitOperator

Java:

  • class: HOpCameraManipulate

  • method: HBaseOperator getM_pRelativeOrbitOperator()

Note that the first letter after “get” or “set” – in this case, “M” from m_pRelativeOrbitOperator – is capitalized for Java accessor methods.

Array Handling

Methods in the C++ classes which return arrays (as a return type) return the array through a parameter in Java

Example signature:

public GetWorldBounding(float[] values, int count);

Sample usage:

// tk is a valid BstreamFileToolkit
float[] bounds = new float[6];
tk.GetWorldBounding(bounds, 6);

Array member variables return the array via a get_[variable name] method and are read-only

Example signature:

public get_point_list(HPoint[] values, int count);

Sample usage:

// shell is valid HShell
// values is valid HPoint[] array
shell.get_point_list(values, values.length);

``HFileInputResult`` and ``HFileOutputResult``

You should use the enum HFileIOResult wherever HFileInputResult or HFileOutputResult are mentioned in our documentation. For example:

HFileIOResult result = myView.GetModel().Read("c:/datasets/bnc.hsf", myView);

if (result != HFileIOResult.HIO_OK)
{
  // ... error
}

``HUtilityPMI`` Usage

The HUtilityPMI classes have several caveats.

  1. PMI::String is PMI_String in Java. For example:

    PMI_String[] datum_labels = new  PMI_String[3];
    datum_labels[0]  = new PMI_String("A-B");
    datum_labels[1]  = new PMI_String("C");
    datum_labels[2]  = new PMI_String("D");
    
  2. PMI Type/SubType enums are placed in Java packages. For example, PMI::DiameterModifier::Type is com.techsoft.hoops.PMI.DiameterModifier.Type

  3. Enum array parameters (in or out) and Enum output params require Java int[] arrays

Out param example - 1st param in GetDiameterModifierType.

C++ prototype:

class  PMI::FeatureControlFrameEntity<br />
void  GetDiameterModifierType(DiameterModifier::Type & out_diameter_modifier_type, TextAttributes & out_text_attributes) const;

Java code:

FeatureControlFrameEntity  fcf = new FeatureControlFrameEntity(HJ.Create_Segment("pmi/fcf"));
int[]  diameter_modifier_type = new int[1];
TextAttributes[]  label_attributes;
fcf.GetDiameterModifierType(diameter_modifier_type,  text_attributes);
  1. Array param example - 4th param in SetDatumReferences

C++ prototype:

class  PMI::FeatureControlFrameEntity
void  SetDatumReferences(unsigned int in_count, String const in_labels[],  TextAttributes const in_label_attributes[],DatumModifier::Type  const in_modifiers[], TextAttributes const in_modifier_attributes[]);

Java code:

int[]  datum_modifiers = new int[3];
datum_modifiers[0]  =  com.techsoft.hoops.PMI.DatumModifier.Type.MaximumMaterialCondition.swigValue();
datum_modifiers[1]  =  com.techsoft.hoops.PMI.DatumModifier.Type.RegardlessOfFeatureSize.swigValue();
datum_modifiers[2]  = com.techsoft.hoops.PMI.DatumModifier.Type.LeastMaterialCondition.swigValue();
//  ... declare/populate other variables
fcf.SetDatumReferences(3,  datum_labels, datum_label_attributes, datum_modifiers,  datum_modifier_attributes);
  1. Casting between PMI enums and Java int

To convert a Java PMI enum to an int value, use [enum value].swigValue(). For example:

int v =  com.techsoft.hoops.PMI.DatumModifier.Type.MaximumMaterialCondition.swigValue();

To convert from an int to an enum, use [enum].swigToEnum(). For example:

int[]  tolerance_type = new int[1];
fcf.GetToleranceType(tolerance_type,  text_attributes);
com.techsoft.hoops.PMI.Tolerance.Type  e = com.techsoft.hoops.PMI.Tolerance.Type.swigToEnum(tolerance_type[0])

HOOPS/Stream Notes

Do not use BStreamFileToolkit::PrepareBuffer. Instead, do the following:

  • Call HJSTREAM.PrepareBuffer(BStreamFileToolkit tk, byte[] b, int s), to setup the buffer.

  • Call HJSTREAM.ReleaseBuffer(byte[] b, int s) to retrieve the next buffer of HSF data from the toolkit. This would be called before processing the buffer of HSF data.