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
- .jar files: (discussed above)
- Java wrapper libraries:
- For HOOPS/3DGS:
- Windows:
- *hj
.dll* - *hij
.dll*
- *hj
- Linux:
- *hj
.so* - *hij
.so*
- *hj
- Windows:
- For HOOPS/MVO:
- Windows: *hjmvo
.dll* - Linux: *hjmvo
.so*
- Windows: *hjmvo
- For HOOPS/Stream:
- Windows: *hjstream
.dll* - Linux: *hjstream
.so*
- Windows: *hjstream
- For HOOPS/3DGS:
- native libraries:
- For HOOPS/3DGS:
- Windows: *hoops
_vc .dll* - Linux: *hoops
.so*
- Windows: *hoops
- For HOOPS/MVO:
- Windows: *hoops_mvo
_vc .dll* - Linux: *hoops_mvo
.so*
- Windows: *hoops_mvo
- For HOOPS/Stream:
- Windows: *hoops_stream
_vc .dll* - Linux: *hoops_stream
.so*
- Windows: *hoops_stream
- For HOOPS/3DGS:
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.
PMI::String
isPMI_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");
PMI Type/SubType enums are placed in Java packages. For example,
PMI::DiameterModifier::Type
iscom.techsoft.hoops.PMI.DiameterModifier.Type
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);
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);
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.