[vtkusers] Coding Errors in VTK Java

Jeff Lee jeff at cdnorthamerica.com
Tue May 21 17:02:01 EDT 2002


I dug a little deeper and found that the elements of the java array are 
not getting assigned after the call to vtkPoints->getPoint(temp0, 
temp1).  This is how the code needs to look, but I have to munge through 
vtkWrapJava and figure out how to do it...  There are probably other 
places this needs to happen too, so if I get the pattern right, it 
should fix all of them.

extern "C" JNIEXPORT void  JNICALL 
Java_vtk_vtkPoints_GetPoint_127(JNIEnv *env, jobject obj,jint 
id0,jdoubleArray id1)
{
  vtkPoints *op;
  long     temp0;
  float  temp1[3];
  jdouble *tempArray1;
  jboolean isCopy;
  temp0 = id0;
  tempArray1 = (env->GetDoubleArrayElements(id1,&isCopy));
  temp1[0] = (tempArray1)[0];
  temp1[1] = (tempArray1)[1];
  temp1[2] = (tempArray1)[2];

  op = (vtkPoints *)vtkJavaGetPointerFromObject(env,obj,(char *) 
"vtkPoints");
  op->GetPoint(temp0,temp1);

  tempArray1[0] = temp1[0];
  tempArray1[1] = temp1[1];
  tempArray1[2] = temp1[2];

  if (isCopy == JNI_TRUE) {
    env->ReleaseDoubleArrayElements(id1,(jdouble *)tempArray1,0);
  }
}

-Jeff

Jeff Lee wrote:

> Dale,
> One problem is with SetDataTypeToDouble.  Comment that out and you'll 
> get better results.  The implementation for the wrapper languages 
> assumes doubles for vtkPoints. 
> 1) points.GetPoint(slotID, p); -- doesn't work but should (jni isn't 
> modifying p the right way)
> 2) p = points.GetPoint(slotID);  -- works as expected
>
> The problem with 1) is in the JNI wrappers and can be fixed by the 
> following modification:
> (in vtkPointsJava.cxx)
>
> extern "C" JNIEXPORT void  JNICALL 
> Java_vtk_vtkPoints_GetPoint_127(JNIEnv *env, jobject obj,jint 
> id0,jdoubleArray id1)
> {
>  vtkPoints *op;
>  long     temp0;
>  float  temp1[3];
>  void *tempArray1;
>  temp0 = id0;
>  jboolean isCopy;
>  tempArray1 = (void *)(env->GetDoubleArrayElements(id1,&isCopy));
>  temp1[0] = ((jdouble *)tempArray1)[0];
>  temp1[1] = ((jdouble *)tempArray1)[1];
>  temp1[2] = ((jdouble *)tempArray1)[2];
>
>  if (isCopy == JNI_TRUE) {
>    env->ReleaseDoubleArrayElements(id1,(jdouble *)tempArray1,0);
>  }
>
>  op = (vtkPoints *)vtkJavaGetPointerFromObject(env,obj,(char *) 
> "vtkPoints");
>  op->GetPoint(temp0,temp1);
> }
>
> The key difference is the boolean isCopy which lets us know if the 
> memory pointed to by env->GetDoubleArrayElements(id1,&isCopy) will be 
> pinned or not.  I will try to work this into the wrapper when I get time.
>
> -Jeff
>
> Dale Greer wrote:
>
>> Here's a simple class for testing vtkPoints.GetPoint(). It's only 
>> using one
>> point, but it behaves the same as my larger app that uses an array of
>> points.
>>
>> import vtk.*;
>>
>> import java.io.*;
>>
>> public class TestGetPoint {
>> static {
>>  System.loadLibrary("vtkCommonJava");
>>  System.loadLibrary("vtkFilteringJava");
>>  System.loadLibrary("vtkIOJava");
>>  System.loadLibrary("vtkImagingJava");
>>  System.loadLibrary("vtkGraphicsJava");
>>  System.loadLibrary("vtkRenderingJava");
>> }
>>
>> public TestGetPoint() {
>> }
>> public void testing() {
>>  vtkPoints points = new vtkPoints();
>>  points.SetDataTypeToDouble();
>>  int slotID = 0;
>>  double[] p = new double[3];
>>  p[0] = 1.1;
>>  p[1] = 2.2;
>>  p[2] = 3.3;
>>  slotID = points.InsertNextPoint(p);
>>  p[0] = 0;
>>  p[1] = 0;
>>  p[2] = 0;
>>  points.GetPoint(slotID, p);
>>  System.out.println("p1 " + slotID + " " + p[0] + " " + p[1] + " " + 
>> p[2]);
>>  p = points.GetPoint(slotID);
>>  System.out.println("p2 " + slotID + " " + p[0] + " " + p[1] + " " + 
>> p[2]);
>> }
>> public static void main(String[] args) {
>>  TestGetPoint tester = new TestGetPoint ();
>>  tester.testing();
>> }
>> }
>>
>> This is the output.
>>
>> p1 0 0.0 0.0 0.0
>> p2 0 1.100000023841858 1.056176589181958E-38 1.2611686178923354E-44
>>
>> In p1, p is unchanged because Java can't modify an object using a 
>> pointer
>> reference. Java can only pass back objects on the stack.
>> In p2, the first element is returned correctly. I think this is 
>> because Java
>> doubles only add bytes to the mantissa and don't change the exponent, 
>> so you
>> can overlay a float on top of a double structure, and it will be read 
>> the
>> same. But the other two elements of p are incorrect because the bytes 
>> are no
>> longer aligned on the stack. Java is popping three doubles off a 
>> stack that
>> only has three floats. Of course, Java won't let you cast it to a float
>> pointer, so you're stuck.
>>
>> Dale
>>
>> ----- Original Message -----
>> From: "Jeff Lee" <jeff at cdnorthamerica.com>
>> To: "Dale Greer" <dmgreer at airmail.net>
>> Cc: <vtkusers at public.kitware.com>
>> Sent: Tuesday, May 21, 2002 5:14 AM
>> Subject: Re: [vtkusers] Coding Errors in VTK Java
>>
>>
>>> Dale,
>>> Do you have some sample code that exhibits the problem?  I assure you
>>> that what you have below is compeletly valid with jni.
>>> -Jeff
>>>
>>> Dale Greer wrote:
>>>
>>>> There are some fatal coding errors in the Java interface to the vtk
>>>>
>> dll's.
>>
>>>> For example, in vtkPoints, there's a declaration for GetPoint which
>>>>
>> returns
>>
>>>> a pointer to a float on the stack. But in Java, GetPoint returns a
>>>>
>> reference
>>
>>>> to a double array. If GetPoint is used in Java, the first element 
>>>> in the
>>>> double
>>>> array is valid, but the other two are not.
>>>>
>>>> C++
>>>>
>>>> float* vtkPoints::GetPoint( vtkdType id)
>>>>
>>>> Java
>>>>
>>>> private native double[] GetPoint_26(int id0);
>>>> public double[] GetPoint(int id0)
>>>>   { return GetPoint_26(id0); }
>>>>
>>>>
>>>> Even worse, the C++ way to get back an array of doubles is to pass by
>>>> reference in the argument, which isn't possible in Java, but which is
>>>> nevertheless attempted by the autogenerated Java interface to the dll.
>>>>
>>>> C++
>>>>
>>>> void vtkPoints::GetPoint( vtkIdType id, double x[3])
>>>>
>>>> Java
>>>>
>>>> private native void GetPoint_27(int id0,double id1[]);
>>>> public void GetPoint(int id0,double id1[])
>>>>   { GetPoint_27(id0,id1); }
>>>>
>>>>
>>>> Having pinpointed the problem, I'm not sure if I know how to fix 
>>>> this. Is
>>>> there someone else who could put a fix for this into the nightly 
>>>> build?
>>>>
>>>> Dale
>>>>
>>>>
>>>> _______________________________________________
>>>> This is the private VTK discussion list.
>>>> Please keep messages on-topic. Check the FAQ at:
>>>>
>> <http://public.kitware.com/cgi-bin/vtkfaq>
>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://public.kitware.com/mailman/listinfo/vtkusers
>>>>
>>>>
>>>
>>> _______________________________________________
>>> This is the private VTK discussion list.
>>> Please keep messages on-topic. Check the FAQ at:
>>>
>> <http://public.kitware.com/cgi-bin/vtkfaq>
>>
>>> Follow this link to subscribe/unsubscribe:
>>> http://public.kitware.com/mailman/listinfo/vtkusers
>>>
>>
>> _______________________________________________
>> This is the private VTK discussion list. Please keep messages 
>> on-topic. Check the FAQ at: <http://public.kitware.com/cgi-bin/vtkfaq>
>> Follow this link to subscribe/unsubscribe:
>> http://public.kitware.com/mailman/listinfo/vtkusers
>>
>>
>




More information about the vtkusers mailing list