Data Visualization with Java and VTK

Posted on December 16th, 2011
Previous Article :: Next Article

Introduction

In this post we’ll show you how to develop a simple Java application for visualizing scientific data. We will use The Visualization Toolkit (VTK) for the actual data analysis and rendering and Java Swing libraries for a simple GUI that will allow us to modify the plotted output.

Scientific Data Visualization

The typical output from a simulation code is a large file full of numbers. By itself, such a result is rather meaningless. These numbers correspond to the results at various spatial locations. Scientific visualization is the art of converting these numbers into a graphical format that can be understood and aid us in obtaining a new understanding about some physical problem. For example, consider a CAD/flow simulation of a rocket plume. The simulation grid may consist of millions of nodes and on each node we will have a value corresponding to the local plume density. But we may only be interested in the shape of the plume. We can easily visualize the plume by plotting the isosurface of some critical minimum value.

There are both commercial and open-source solutions for performing data visualization. Of the commercial kind, a popular program is Tecplot. The free alternatives include VisIt from Livermore, and Paraview from Kitware, Inc., the creators of the Visualization Toolkit, VTK. However, sometimes these options may not be quite adequate. For instance, you may be developing your own simulation software and would like to bundle the solver with a simple visualization output that will allow the user to study the results in real-time. This is where VTK comes in. The Visualization Toolkit is an amazing collection of C++ classes for processing and visualizing data. It is the engine that does the actual work. VTK is built on the concept of a visualization pipeline. The pipeline starts at one end with the source data and ends at the other end with an actor that correspond to the data’s visual representation. Along the way, in the pipeline, various operations are applied to obtain the output of interest. In order to add visualization to your program, you simply need to provide the algorithm to build the pipeline. The actual data processing and plotting is performed within the VTK library.

VTK provides a simple graphical window that can be used for plotting and interacting with the data (rotation, panning, zoom, etc..). Such an approach may be sufficient for simple console-based applications. But in order to develop an interactive end-user program, you’ll need to incorporate VTK within the GUI of your application. Luckily for us, VTK ships with a built-in support for both QT and Java. The QT/VTK combination was the basis for our simple visualization program, capVTE. Developed in 2003, capVTE attempted to merge a simplified user interface with the open-source nature of VTK, while at the same time supporting new concepts such as immersed and collaborative visualization. You can read more about capVTE here and here (the latter is the draft version but has color pictures). We are currently rewriting the software, however this time we are developing the code in Java. As discussed previously in our article on Java multithreading, the great benefit of Java is that it comes bundled with a large API. Instead of downloading, configuring, and compiling QT (a task for multiple hours), GUI support is natively built into Java via the Swing library.

VTK JAVA Wrappers

So how do you couple VTK with Java? It’s very easy. VTK comes with support for Java in the form of Java wrappers. In the following sections we show you how to install and configure the VTK / Java development environment and how to use it to build a simple Java GUI-driven application.

We are assuming you already have JDK and a Java development environment such as Netbeans or Eclipse installed. In addition you will need to download the VTK source and build it. This requires a working C++ compiler. On Windows, you can obtain the Microsoft Visual Studio Express Edition for free. Then follow these steps to get started:

  1. Download CMake from cmake.org. CMake is a cross-platform configuration tool for VTK. It will query your system for the available compilers and settings, and will generate the appropriate project files needed to build VTK.
  2. Download VTK source from vtk.org. Make sure to download the Source package and not the Windows Installer.
  3. Unzip the source to some temporary directory.
  4. Configure your project files by running CMake. Specify the location to the source files you just unzipped and also a different directory where to build the files. This build folder is used during the compilation stage, however at the end, files will be installed into the appropriate system folders. Click Configure to start the process. CMake will run for a while performing various system tests. It will finish with another screen with additional options highlighted in red.
  5. Enable Java Wrapping by selecting the appropriate check box (see Figure 1). You will also need to enable the shared libraries. I generally uncheck build tests / examples to reduce the compilation time. Press Configure again. If everything went well, you will see the Generate button become available. Press this button to generate the project files.
  6. cmake customization screen
    Figure 1. Enable “VTK_WRAP_JAVA” during the CMake Configure process
  7. Compile VTK by launching the solution file located in the build folder. If you are using Visual Studio on Microsoft Windows, right click on ALL_BUILD and then select Build. The compiler with churn for a while. Depending on your machine, this may take multiple hours. If you are using make, use the appropriate make command (most likely make all but this was not tested).
  8. Install the system libraries, assuming no errors were encountered, by right clicking on INSTALL and selecting Build. Make sure you run Visual Studio as an administrator for this step. If you do encounter linker errors in the Java wrappers, make sure you are linking against the correct version of Java. My machine is running a 64-bit version of Windows 7. However, I only have the 32-bit C++ compilers. My default Java JDK is the 64-bit version, which resulted in an unresolved symbol “__imp__JAWT_GetAWT@8” linker error in vtkRenderingJava. If you do encounter these types of errors, make sure to download the 32-bit version of Java JDK and link against it by adjusting the input path under Linker->Input property page for the appropriate project.
  9. Check your PATH. The final piece, and likely the biggest headache, is making sure that your Java program can find the required VTK DLLs. These may in turn depend on other DLLs that may not be in the path. Great tool for checking DLL dependencies is Dependency Walker. It took me a while to get everything set up, and in the end, the following directories did the trick. Of course, your setup will likely differ.
    C:WindowsSystem32;C:Program Files (x86)VTKbin;C:Program Files (x86)Javajdk1.6.0_30lib;C:Program Files (x86)Javajre6bin;C:Program Files (x86)Javajre6binclient;C:Program Files (x86)Microsoft Visual Studio 9.0VCredistx86Microsoft.VC90.CRT;
  10. Copy vtk.jar to somewhere safe. This file is located in the bin directory in your VTK build folder. It is better to move it out of here in case you later decide to delete the build directory. It is over 1Gb after all and you don’t need it post Install unless you actually plan to modify the VTK libraries themselves.

Your first VTK/Java Application

VTK comes with an example code for using Java called SimpleVTK.java which you can also find online on VTK’s Java wrapping page. But we have something better for you. Download DemoJavaVTK.java here or see the source listing below. This example is based on the SimpleVTK code but extends its functionality. Instead of showing just a simple cylinder, we combine a surface geometry mesh with isosurfaces and cutting planes that can be toggled on and off. This example represents a common scientific visualization task: show and analyze the computed field due to some prescribed boundary.

Using Netbeans, do the following:

  1. Create a new Java Project with Existing Sources. On the Name and Location screen, uncheck “Create Main Class”.
  2. Copy DemoJavaVTK.java into the src folder in your project folder. The file should automatically appear in Netbeans under your new project.
  3. Include vtk.jar in the project libraries by right-clicking on “Libraries” and selecting “Add JAR/Folder”. Select the vtk.jar file from step 9 above.
  4. Verify the JDK version. It must match the JDK used to build the wrappers. This should only be an issue if you are mixing 64-bit and 32-bit compilers.
  5. Run your first Java VTK application. If everything goes well, you will see a window similar to the one in Figure 2 below. On the other hand, if you see messages such as “vtkCommonJava not loaded” there is an issue with your PATH settings. Check and adjust your system PATH per step 8 above. In the window, you can rotate the view by holding down the left button, pan by holding down the middle button, and zoom with the right button.
isosurface of sphere display
Figure 2. You can show isosurfaces or the cutting planes
cutting planes and isosurface for sphere tessellated sphere
Figure 3. Or both. And if you like, neither.

Details of the Java VTK Demo Code – Including VTK in a Swing Application

You will find the complete source listing below. The code begins with the static block on line 50,

 static 
    {				
        if (!vtkNativeLibrary.LoadAllNativeLibraries()) 
	{
          ....
	}
        vtkNativeLibrary.DisableOutputWindow(null);
    }

This block calls a function in the VTK Java wrapper that attempts to load all required shared libraries (.DLLs). If any library fails to load, the code displays the name of the library, as well as the PATH that is being used in the search. The final call in this block disables the console window that is used by VTK to print various diagnostic messages.

The code next launches the Main function on line 215. This main creates a new Swing JFrame and populates the frame with a single jPanel-derived widget, DemoJavaVTK. This panel is the actual meat of our application. The class DemoJavaVTK is defined as

public class DemoJavaVTK extends JPanel implements ActionListener 
{
  ...
}

The JFrame creation is wrapped inside SwingUtilities’ InvokeLater command, as shown below. This is required since we are directly accessing the GUI in the creation of the VTK panel. This syntax makes sure that our code is executed only once the window manager is running and ready for GUI updates.

SwingUtilities.invokeLater(new Runnable() 
{
@Override
    public void run() 
    {
        JFrame frame = new JFrame("Java and VTK Demo");
        ...
        frame.getContentPane().add(new DemoJavaVTK(), BorderLayout.CENTER);
        ...
     }
});

Building a VTK Java Panel

The real work is being done in the DemoJavaVTK constructor starting on line 67. We first specify BorderLayout. This layout contains a large stretching central widget and small areas around all four borders that can be populated with small widgets like buttons. We will end up placing the interactor window in the central area and will create another panel containing control buttons along the bottom.

We next start building the pipelines. We are generating three actors: isosurfaces, cutting planes, and a surface geometry. We first generate the data source in 1)

/**** 1) INPUT DATA: Sphere Implicit Function ****/
vtkSphere sphere = new vtkSphere();
sphere.SetRadius(radius);
 
vtkSampleFunction sample = new vtkSampleFunction();
sample.SetSampleDimensions(50,50,50);
sample.SetImplicitFunction(sphere);

Here we are using an implicit function to define the data. An implicit function is a function of the form [latex]f(x,y,z) = C[/latex]. In our case, we are using the “sphere” function, which evaluates the distance from the surface of a sphere, [latex](x-x_0)^2 + (y-y_0)^2 + (z-z_0)^2 – r^2[/latex]. This function will evaluate to zero on the surface, and to a non-zero value away from it. The SampleDataDimension command specifies the grid dimensions on which the function will be evaluated. In the general case, this source data would be the output from your simulation. VTK contains many file readers that can easily accomplish the file import.

We next start building the isosurface actor,

/**** 2) PIPELINE 1: Isosurface Actor ****/
/* contour filter - will generate isosurfaces from 3D data*/
vtkContourFilter contour = new vtkContourFilter();
contour.SetInputConnection(sample.GetOutputPort());
contour.GenerateValues(3,0,1);
 
/* mapper, translates polygonal representation to graphics primitives */
vtkPolyDataMapper isoMapper = new vtkPolyDataMapper();
isoMapper.SetInputConnection(contour.GetOutputPort());
 
/*isosurface actor*/
isoActor = new vtkActor();
isoActor.SetMapper(isoMapper);

We create a contour filter that basically reduces the dimensionality of the data. From the 3D volume, this filter will create isosurfaces. We are telling the filter to create 3 equidistant surfaces in the range [0,1]. Negative values correspond to the domain internal to the sphere, and so this range creates surfaces external and including the sphere. This section also introduces you to the concept of the visualization pipeline. We pipe different pieces together using the filter2.SetInputConnection(filter1.GetOutputPort()) syntax. We next create a PolyDataMapper. This is a special algorithm that takes the underlying polygonal representation of the data and translates it into the basic graphics primitives supported by the graphics card. The mapper is next used to create the actor. The actor is the actual object that will be added to the render window to create our scene.

We next perform another similar operation in steps 3) to create the cutting planes. Here we are using an implicit function for a plane to define the cut surface. However, we evaluate the plane function at three values, -0.7, 0, and 0.7 to create three different cutting planes. We also create our own LookupTable (LUT). A LUT maps the actual data values to screen colors. We create a LUT using the default color scheme but with only 5 colors to create a banded effect. The rest of the code consists of building the mapper and the actor in a manner similar to the previous step. One difference is that we change the interpolation/shading method to flat. This will give us a nicer looking cutting plane – without this command the plane would look shiny and metallic.

/**** 3) PIPELINE 2: Cutting Plane Actor ****/
/* define a plane in x-y plane and passing through the origin*/
vtkPlane plane = new vtkPlane();
plane.SetOrigin(0,0,0);
plane.SetNormal(0,0,1);
 
/* cutter, basically interpolates source data onto the plane */
vtkCutter planeCut = new vtkCutter();
planeCut.SetInputConnection(sample.GetOutputPort());
planeCut.SetCutFunction(plane);
/*this will actually create 3 planes at the subspace where the implicit
 * function evaluates to -0.7, 0, 0.7 (0 would be original plane). In 
 * our case this will create three x-y planes passing through 
 * z=-0.7, z=0, and z=+0.7*/
planeCut.GenerateValues(3,-0.7,0.7);
 
/* look up table, we want to reduce number of values to get discrete bands */
vtkLookupTable lut = new vtkLookupTable();
lut.SetNumberOfTableValues(5);
 
/* mapper, using our custom LUT */
vtkPolyDataMapper cutMapper = new vtkPolyDataMapper();
cutMapper.SetInputConnection(planeCut.GetOutputPort());
cutMapper.SetLookupTable(lut);
 
/* cutting plane actor, looks much better with flat shading */
cutActor = new vtkActor();
cutActor.SetMapper(cutMapper);
cutActor.GetProperty().SetInterpolationToFlat();

We then create our final player, the surface geometry actor. This actor is being used to show the geometry of interest. This would typically be the object you are simulating, while the two previous actors correspond to the visualization of computed results. We create a coarse sphere and show the edges. Very often, the surface geometry is imported into the simulation code as a triangulated surface mesh. This visualization is intended to indicate this. We manipulate the actor properties to turn on the edges and set their color to dark gray. We again use the flat shading.

/**** 4) PIPELINE 3: Surface Geometry Actor ****/
/* create polygonal representation of a sphere */
vtkSphereSource surf = new vtkSphereSource();
surf.SetRadius(radius);
 
/* another mapper*/
vtkPolyDataMapper surfMapper = new vtkPolyDataMapper();
surfMapper.SetInputConnection(surf.GetOutputPort());
 
/* surface geometry actor, turn on edges and apply flat shading*/
vtkActor surfActor = new vtkActor();
surfActor.SetMapper(surfMapper);
surfActor.GetProperty().EdgeVisibilityOn();
surfActor.GetProperty().SetEdgeColor(0.2,0.2,0.2);
surfActor.GetProperty().SetInterpolationToFlat();

We then finally start building our display. The heart of this example, and of any Java / VTK integration, is the vtkPanel widget. This GUI component is the piece that does the actual rendering and user interaction. It corresponds to the RenderWindow from the C++ implementation. We access its Renderer, and add the default actors. On startup we only show the geometry and the isosurface. We also change the default zoom and the background color.

/**** 5) RENDER WINDOW ****/
/* vtkPanel - this is the interface between Java and VTK */
renWin = new vtkPanel();
 
/* add the surface geometry plus the isosurface */
renWin.GetRenderer().AddActor(surfActor);
renWin.GetRenderer().AddActor(isoActor);
 
/* the default zoom is whacky, zoom out to see the whole domain */
renWin.GetRenderer().GetActiveCamera().Dolly(0.2); 
renWin.GetRenderer().SetBackground(1, 1, 1);

We next shift gears a bit and create a standard Swing panel containing three buttons. We use the grid layout to stretch the buttons to fill the space. We toggle the isosurface button on by default since we are starting the simulation with the isosurface actor visible.

/**** 6) CREATE PANEL FOR BUTTONS ****/
buttons  = new JPanel();
buttons.setLayout(new GridLayout(1,0));
 
/* isosurface button, clicked by default */
isoButton = new JToggleButton("Isosurfaces",true);
isoButton.addActionListener(this);
 
/* cutting planes button */
slicesButton = new JToggleButton("Slices");
slicesButton.addActionListener(this);
 
/* exit button */
exitButton = new JButton("Exit");
exitButton.addActionListener(this);
 
/* add buttons to the panel */
buttons.add(isoButton); 
buttons.add(slicesButton);
buttons.add(exitButton);

And finally, we fill the BorderLayout with the render window (in center) and the buttons (bottom/south).

/**** 7) POPULATE MAIN PANEL ****/
add(renWin, BorderLayout.CENTER);
add(buttons, BorderLayout.SOUTH);

Button Actions

The example is now almost complete. The only thing that remains is to add code for the buttons. The logic is very simple. We add an actor when the button is pressed down, and remove it when the button is toggled off. We also ask the render window to repaint itself to show the difference in the scene. Without this call, the window would not update until we interact with it.

/*cutting planes button, add or remove cutActor */
if (e.getSource().equals(slicesButton))
{
     if (slicesButton.isSelected())
          renWin.GetRenderer().AddActor(cutActor);
     else
          renWin.GetRenderer().RemoveActor(cutActor);
 
     renWin.Render();
}

And that’s it. Your first Java / VTK application!

Complete Source Listing

  1. import java.awt.BorderLayout;
  2. import java.awt.GridLayout;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5.  
  6. import javax.swing.JButton;
  7. import javax.swing.JToggleButton;
  8. import javax.swing.JFrame;
  9. import javax.swing.JPanel;
  10. import javax.swing.SwingUtilities;
  11.  
  12. import vtk.vtkNativeLibrary;
  13. import vtk.vtkPanel;
  14. import vtk.vtkActor;
  15. import vtk.vtkSphere;
  16. import vtk.vtkSphereSource;
  17. import vtk.vtkSampleFunction;
  18. import vtk.vtkContourFilter;
  19. import vtk.vtkPlane;
  20. import vtk.vtkCutter;
  21. import vtk.vtkLookupTable;
  22. import vtk.vtkPolyDataMapper;
  23.  
  24. /* ************************************************************
  25.  * Demo applications showcasing how to use VTK with Java
  26.  * 
  27.  * Based on SimpleVTK.java example distributed with VTK
  28.  * 
  29.  * For more information see:
  30.  * https://www.particleincell.com/2011/vtk-java-visualization
  31.  * 
  32.  * Information about VTK can be found at:
  33.  * http://vtk.org/
  34.  * 
  35.  * ***********************************************************/
  36.  
  37. public class DemoJavaVTK extends JPanel implements ActionListener 
  38. {
  39.     private static final long serialVersionUID = 1L;
  40.     private vtkPanel renWin;
  41.     private vtkActor cutActor;
  42.     private vtkActor isoActor;
  43.  
  44.     private JPanel buttons;
  45.     private JToggleButton slicesButton;
  46.     private JToggleButton isoButton;
  47.     private JButton exitButton;
  48.  
  49.     /* Load VTK shared librarires (.dll) on startup, print message if not found */
  50.     static 
  51.     {				
  52.         if (!vtkNativeLibrary.LoadAllNativeLibraries()) 
  53. 	{
  54. 	       for (vtkNativeLibrary lib : vtkNativeLibrary.values()) 
  55. 		{
  56.                 	if (!lib.IsLoaded()) 
  57. 				System.out.println(lib.GetLibraryName() + " not loaded");    
  58. 		}
  59.  
  60. 		System.out.println("Make sure the search path is correct: ");
  61. 		System.out.println(System.getProperty("java.library.path"));
  62.         }
  63.         vtkNativeLibrary.DisableOutputWindow(null);
  64.     }
  65.  
  66.     /* Constructor - generates visualization pipeline and adds actors*/
  67.     public DemoJavaVTK() 
  68.     {
  69.         super(new BorderLayout()); /* large center and small border areas*/
  70.  
  71.         double radius = 0.8;	   /*sphere radius*/
  72.  
  73. 	/**** 1) INPUT DATA: Sphere Implicit Function ****/
  74. 	vtkSphere sphere = new vtkSphere();
  75. 	sphere.SetRadius(radius);
  76.  
  77. 	vtkSampleFunction sample = new vtkSampleFunction();
  78. 	sample.SetSampleDimensions(50,50,50);
  79. 	sample.SetImplicitFunction(sphere);
  80.  
  81. 	/**** 2) PIPELINE 1: Isosurface Actor ****/
  82.  
  83. 	/* contour filter - will generate isosurfaces from 3D data*/
  84. 	vtkContourFilter contour = new vtkContourFilter();
  85. 	contour.SetInputConnection(sample.GetOutputPort());
  86. 	contour.GenerateValues(3,0,1);
  87.  
  88. 	/* mapper, translates polygonal representation to graphics primitives */
  89. 	vtkPolyDataMapper isoMapper = new vtkPolyDataMapper();
  90.         isoMapper.SetInputConnection(contour.GetOutputPort());
  91.  
  92. 	/*isosurface actor*/
  93.         isoActor = new vtkActor();
  94.         isoActor.SetMapper(isoMapper);
  95.  
  96. 	/**** 3) PIPELINE 2: Cutting Plane Actor ****/
  97.  
  98. 	/* define a plane in x-y plane and passing through the origin*/
  99. 	vtkPlane plane = new vtkPlane();
  100. 	plane.SetOrigin(0,0,0);
  101. 	plane.SetNormal(0,0,1);
  102.  
  103. 	/* cutter, basically interpolates source data onto the plane */
  104. 	vtkCutter planeCut = new vtkCutter();
  105. 	planeCut.SetInputConnection(sample.GetOutputPort());
  106. 	planeCut.SetCutFunction(plane);
  107. 	/*this will actually create 3 planes at the subspace where the implicit
  108. 	 * function evaluates to -0.7, 0, 0.7 (0 would be original plane). In 
  109. 	 * our case this will create three x-y planes passing through 
  110. 	 * z=-0.7, z=0, and z=+0.7*/
  111. 	planeCut.GenerateValues(3,-0.7,0.7);
  112.  
  113. 	/* look up table, we want to reduce number of values to get discrete bands */
  114. 	vtkLookupTable lut = new vtkLookupTable();
  115. 	lut.SetNumberOfTableValues(5);
  116.  
  117. 	/* mapper, using our custom LUT */
  118. 	vtkPolyDataMapper cutMapper = new vtkPolyDataMapper();
  119.         cutMapper.SetInputConnection(planeCut.GetOutputPort());
  120. 	cutMapper.SetLookupTable(lut);
  121.  
  122. 	/* cutting plane actor, looks much better with flat shading */
  123. 	cutActor = new vtkActor();
  124.         cutActor.SetMapper(cutMapper);
  125. 	cutActor.GetProperty().SetInterpolationToFlat();
  126.  
  127. 	/**** 4) PIPELINE 3: Surface Geometry Actor ****/
  128.  
  129. 	/* create polygonal representation of a sphere */
  130. 	vtkSphereSource surf = new vtkSphereSource();
  131. 	surf.SetRadius(radius);
  132.  
  133. 	/* another mapper*/
  134. 	vtkPolyDataMapper surfMapper = new vtkPolyDataMapper();
  135. 	surfMapper.SetInputConnection(surf.GetOutputPort());
  136.  
  137. 	/* surface geometry actor, turn on edges and apply flat shading*/
  138. 	vtkActor surfActor = new vtkActor();
  139. 	surfActor.SetMapper(surfMapper);
  140. 	surfActor.GetProperty().EdgeVisibilityOn();
  141. 	surfActor.GetProperty().SetEdgeColor(0.2,0.2,0.2);
  142. 	surfActor.GetProperty().SetInterpolationToFlat();
  143.  
  144. 	/**** 5) RENDER WINDOW ****/
  145.  
  146. 	/* vtkPanel - this is the interface between Java and VTK */
  147. 	renWin = new vtkPanel();
  148.  
  149. 	/* add the surface geometry plus the isosurface */
  150. 	renWin.GetRenderer().AddActor(surfActor);
  151. 	renWin.GetRenderer().AddActor(isoActor);
  152.  
  153. 	/* the default zoom is whacky, zoom out to see the whole domain */
  154.         renWin.GetRenderer().GetActiveCamera().Dolly(0.2); 
  155. 	renWin.GetRenderer().SetBackground(1, 1, 1);
  156.  
  157. 	/**** 6) CREATE PANEL FOR BUTTONS ****/
  158. 	buttons  = new JPanel();
  159. 	buttons.setLayout(new GridLayout(1,0));
  160.  
  161.         /* isosurface button, clicked by default */
  162. 	isoButton = new JToggleButton("Isosurfaces",true);
  163.         isoButton.addActionListener(this);
  164.  
  165. 	/* cutting planes button */
  166.         slicesButton = new JToggleButton("Slices");
  167.         slicesButton.addActionListener(this);
  168.  
  169. 	/* exit button */
  170. 	exitButton = new JButton("Exit");
  171.         exitButton.addActionListener(this);
  172.  
  173. 	/* add buttons to the panel */
  174. 	buttons.add(isoButton); 
  175. 	buttons.add(slicesButton);
  176. 	buttons.add(exitButton); 
  177.  
  178. 	/**** 7) POPULATE MAIN PANEL ****/
  179.         add(renWin, BorderLayout.CENTER);
  180.         add(buttons, BorderLayout.SOUTH);	
  181.     }
  182.  
  183.     /* ActionListener that responds to button clicks
  184.      * Toggling iso/slices buttons results in addition or removal
  185.      * of the corresponding actor */
  186.     public void actionPerformed(ActionEvent e) 
  187.     {
  188. 	/*cutting planes button, add or remove cutActor */
  189. 	if (e.getSource().equals(slicesButton))
  190. 	{
  191. 		if (slicesButton.isSelected())
  192. 			renWin.GetRenderer().AddActor(cutActor);
  193. 		else
  194. 			renWin.GetRenderer().RemoveActor(cutActor);
  195.  
  196. 		renWin.Render();
  197. 	}
  198. 	/*isosurface button, add or remove isoActor */
  199. 	else if (e.getSource().equals(isoButton))
  200. 	{
  201. 		if (isoButton.isSelected())
  202. 			renWin.GetRenderer().AddActor(isoActor);
  203. 		else
  204. 			renWin.GetRenderer().RemoveActor(isoActor);
  205. 		renWin.Render();
  206. 	}
  207. 	/*exit button, end application */
  208. 	else if (e.getSource().equals(exitButton)) 
  209. 	{
  210.             System.exit(0);
  211.         }
  212.     }
  213.  
  214.     /* main, creates a new JFrame and populates it with the DemoJavaVTK panel */
  215.     public static void main(String s[]) 
  216.     {
  217.         SwingUtilities.invokeLater(new Runnable() 
  218. 	{
  219.             @Override
  220.             public void run() 
  221. 	    {
  222.                 JFrame frame = new JFrame("Java and VTK Demo");
  223.                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  224.                 frame.getContentPane().setLayout(new BorderLayout());
  225.                 frame.getContentPane().add(new DemoJavaVTK(), BorderLayout.CENTER);
  226.                 frame.setSize(400, 400);
  227.                 frame.setLocationRelativeTo(null);
  228.                 frame.setVisible(true);
  229.             }
  230.         });
  231.     }
  232. }

You can also download the code here: DemoJavaVTK.java. Please feel free to leave a comment or contact us if you have any questions. One of the areas we specialize in here at PIC-C is development of light-weight visualization solutions, and we will gladly work with your company to develop one for your solver.

18 comments to “Data Visualization with Java and VTK”

  1. musta
    April 29, 2012 at 2:22 am

    i am trying to read file.vtk into java and eclipse, can you help me.
    thank you

    • April 30, 2012 at 3:57 am

      Hi Musta, there are several different VTK file formats depending on the sort of data they hold. There is a format for structured meshes, rectilinear meshes, unstructured, etc… These files can also be in the legacy ASCII format or in the new XML format. This documents contains info on the formats: http://www.vtk.org/VTK/img/file-formats.pdf. VTK contains readers for all these file formats, you will find the syntax in the online HTML documentation. However, the best way to learn is by looking at the IO examples. There is also a very active mailing list where you can get many of your questions answered.

  2. musta
    May 3, 2012 at 1:47 am

    hi,thank’s lubos .
    i am new in vtk,
    i am using rectilinear meshes vtk file, but i have some quetion:
    1- how can i read or load this file (file.vtk) in java, i use eclipse and vtk 5.8.0 and vtk.jar ???

    2- there are some one who tell me that i need data structure to save some information from file.vtk ??

  3. Ricardo Corredor
    February 26, 2013 at 2:31 am

    Hi,

    First, thanks for this useful guide! I would like to ask you four questions about this wrapping:

    – The final applications are considerable slower compared to the Qt+VTK ones or, definitively, there is not too much delay in the rendering using Java?

    – How could you create a release version of a Java+VTK application? Will you always need to build & install VTK with the Java options enabled in the computer that you want to run your program?

    – Do you have access to all the filters available in VTK using this wrapping?

    – All the interactions with 3D scenes are captured by the classic VTK Interactors or are they taken by the Java Swing listeners over the “Panel” ?

    Just tell me if maybe I could resend some of these questions to the vtk-users list, however, thanks in advance!

    Have a nice day.

    RaC

    • April 8, 2013 at 4:13 am

      Hi Ricardo, I haven’t done a direct one-to-one speed comparison, but the speed of this application seemed quite fine. On a somewhat related note, I recently converted some simulation code from C++ to Java and when I sent it back to the author, he commented that the Java version runs twice as fast as the C++ one, even in the Release mode. So Java is plenty fast these days and I am thinking that the wrapper adds just a minimum overhead. But this is totally a speculation. About your second question, yes, you can bundle the VTK libraries in the Jar file. You will need version for each platform you plan the code to run on, i.e. DLLs for Windows, .so for Linux, etc… Your Java code can then check if native libraries exist, and if not, deploy the ones from the Jar file. There were few things that were not available and/or working properly in the VTK wrap. These were some esoteric filters that I was able to find a way around. It’s also possible that these are still being worked on and the latest version includes them. Sorry, don’t recollect now exactly what they were. Finally, the VTK interactions are handled the VTK, but I suspect you can add your own listener. But you don’t have to capture mouse strokes and pass them on to the interactor, if that is your question. You just add the RenderWindow, add the actors, and the user can interact with the data with no additional Java code.

      Let me know if you need some more help.

  4. Steven
    May 7, 2013 at 7:18 am

    Hello,

    I recently read your blog article “Data Visualization with Java and VTK” and I am really impressed of it. Can you give me some hints on how to install the VTK-Java-Wrapper server-sidely and how to access VTK-rendered images remotely using HTML and JavaScript? I could not find any example out there…

    • May 8, 2013 at 5:52 am

      Hi Steven,

      I have not actually tried to implement this but it’s on my short list. In theory, you have your PHP script (or what not) run a server-side application that takes in the user input and outputs an image file that you then feed back to the website. Or, you can export VRML for 3D visualization in the browser.

  5. graham seed
    June 27, 2013 at 1:57 pm

    Hi

    I’m trying to get a Java version of VTK – why there are not prebuilt jars for standard platforms I do not know!

    I’m using Win7/64bit and followed the instructions and got the _imp__JAWT_GetAWT@8 linker error as the cmake build is 32bit.

    Ultimately I require a 64bit version to run on a 64bit jvm. So, am I able to generate such a build with the supplied cmake file?

    Having to downloaded VS Express and waiting hours to perform the build I really have to question why VTK make it so difficult for users to get going. It’s presumably tested on the standard platforms so why not simply make the jars/dlls available?

    Graham

    • June 27, 2013 at 2:18 pm

      That’s a really good question for the VTK team. But how were you able to build a 64-bit version with VS Express? The last time I tried this was possible only with the Pro version. The version I had only supported WoW64, not native 64-bit.

  6. Maciek Piekarski
    January 19, 2014 at 11:14 am

    Hi,

    I’ve successfully built the library so now I have vtk.jar in C:\Program Files\VTK\lib and dll’s in C:\Program Files\VTK\bin .
    In Eclipse I’ve created a user library with this .jar and specified the directory with dll’s as the Native Library location.

    Even though (almost) all VTK shared libraries are in this folder they still can’t be loaded. I’ve been trying to make it work for over a day now with no luck…

    Any ideas what could I do?

    • Maciek Piekarski
      January 19, 2014 at 11:26 am

      Well… Appears that all I had to do was:
      Run->Run Configurations->Environment->New: PATH, C:\Program Files\VTK\bin

      Why is it not enough to specify this as the Native library location? That was all I had to do with OpenCV for example…

  7. kulasekaran
    February 27, 2014 at 2:45 am

    How to vtk for image processing in java using NetBeans IDE.

    I have created vtk.jar using visual studio. It works for sample java code.
    I have downloaded java code from here http://www.vtk.org/Wiki/VTK/Examples/Java/Imaging/ImageTest. It throws exception java.lang.UnsatisfiedLinkError: no vtkCommonJava in java.library.path

    how to solve this

  8. reggiej
    May 23, 2014 at 10:57 pm

    Thanks for the inspiration! I had no problems getting an example running on RHEL Linux. Had a little in OS X, but followed:

    http://qt-project.org/forums/viewthread/41538/P15

    to fix a VTK java build issue.

    Any words of advice for integtrating java with VTK and ITK? I would love to make an app that monitors an ITK image registration displaying the progress of the registration in a VTK window.

  9. Sayali Sarpatwar
    April 21, 2015 at 7:24 am

    I have created an application using VTK java wrapper and java swing in Eclipse IDE. Now, I want to make a runnable jar file of the application so that I can run it on the different computer on which VTK is not installed.
    I have created a jar file and have included vtk.jar while creating it. Also I have created a folder in which I am placing the jar file and debug folder (from VTK-bin/bin) which includes all the required dlls. When I am trying to run this jar file on the other computer, it gives exception.
    Kindly tell me where I am going wrong and let me know the correct procedure to create a runnable jar file.

    Thanks in advance!!

    • April 21, 2015 at 2:06 pm

      Hi Sayali, I remember having the same issue when developing a GUI based on this concept for a client. It was few years ago so I can’t remember the details now. I know I tried what you describe, i.e. having the VTK library packed in the Jar and deploying it but I also remember having difficulties with that. I’ll need to dig up this old code to investigate. Stay tuned.

  10. kentmyers
    April 26, 2015 at 4:45 pm

    I haven’t tried running from an executable jar file with VTK yet, but with other native libraries, I designate a folder outside the eclipse environment as my library folder, and put all dlls in that folder. Then I edit the debug configuration and add a VM argument “-Djava.library.path=C:/foldername”. See
    http://stackoverflow.com/questions/957700/how-to-set-the-java-library-path-from-eclipse

  11. Sayali Sarpatwar
    May 20, 2015 at 3:41 am

    The issue regarding executable jar file of VTK application is resolved. I compiled VTK in release mode instead of debug mode. For distribution purpose, debug is not used because of its additional dependencies. Also, I included jre/bin in path environmetal variable of target machine, which I had forgotten to do earlier.
    Now, I am able to run jar file on the machine in which VTK is not installed.

    • May 21, 2015 at 7:16 am

      Excellent, glad to hear that!

Leave a Reply to Sayali Sarpatwar

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile=""> In addition, you can use \( ...\) to include equations.