[vtkusers] VTK, Matlab, volume rendering, Java

Johnson, G (Greg) G.Johnson at rl.ac.uk
Mon Feb 12 07:26:35 EST 2001


Hi folks,
  At least one person has asked me how I got VTK working within Matlab
(R12), so I thought I'd post a slightly off-topic thread on it.  I knew no
Java at all, and not a great deal about VTK, but I really wanted to drive my
VolumePro rendering board from Matlab, thus...

1.  Install VTK with sources
2.  Recompile vtk with support for 'contrib' turned on and extra
compiler/linker flags for VLI (the VolumePro library).  See
VolumeProVG500Mapper.h for details (add TWO classes, not THREE, as
vtkVolumePro is already there).
2b.  Move DLLs to correct place (/winnt/system32 for me)

3.  Install JDK 1.1.8 (http://java.sun.com/products/jdk/1.1/)

4.  Add the CLASSPATH variable and make it:
	
.;<pathtojdk>\classes;<pathtojdk>\lib\classes.zip;<pathtovtk>\java;<pathtovt
k>\java\vtk.jar
	
(the two VTK items are necessary to include vtkPanel.class which is not
included in vtk.jar (why not I know not)

5.  Add (if necessary) <pathtojdk>\bin to your path.  Try 'javac Test.java'
then 'java Test' to check things so far.  The Test source is in
<pathtovtk>\java.

6.  Run Matlab R12.  (The R12 version is the first to run in a VM, so
previous releases won't work).

7.  type 'which classpath.txt' and then edit that file.  Add to it the
following lines, modifying the third line to wherever you wish to keep your
own java sources.
d:/vtk31/java/vtk.jar
d:/vtk31/java
d:/tomography/java

8.  Restart Matlab.  Use the following sample code to verify everthing is
working:

%cone.m
import vtk.*
panel=vtkPanel;  % essential first step for all VTK java
ren1=vtkRenderer;
renWin=vtkRenderWindow;
renWin.AddRenderer(ren1);
iren=vtkRenderWindowInteractor;
iren.SetRenderWindow(renWin);
cam1=ren1.GetActiveCamera;
cam1.SetEyeAngle(5)

cone=vtkConeSource;
cone.SetResolution(8)
coneMapper=vtkPolyDataMapper;
coneMapper.SetInput(cone.GetOutput);
coneActor=vtkActor;
coneActor.SetMapper(coneMapper);
ren1.AddActor(coneActor);
iren.Initialize;

% end of file

Getting the idea?  Try 'cone' or 'methods vtkConeSource'. 

9.  Now the rendering board.  The problem here (and I imagine in other VTK
applications) is getting the large volumes of data from Matlab through into
vtkVolumeMapper.  First, the tedious way...

% Matlab volume in 'mVolume'
% need to pump it into a vtkStructuredPoints for use in the volume mapper.

nums=vtkScalars;
nums.SetDataType(3);  % 3 is unsigned char, 5 is unsigned short
nums.SetNumberOfComponents(1);
nums.SetNumberOfScalars(prod(size(mVolume)));

for i=0:prod(size(mVolume))-1  % THIS IS GOING TO TAKE A LONG TIME!
  nums.SetScalar(i,mVolume(i+1));
end

vol=vtkStructuredPoints;
vol.SetDimensions(size(mVolume,1),size(mVolume,2),size(mVolume,3));
vol.SetOrigin(0,0,0);
vol.SetSpacing(1,1,1);

vol.GetPointData.SetScalars(nums);


10.  However, if we move the for loop into a small java program, then it
runs much faster.  Still not ideal, but better.  On my P3-850, the Matlab
loop takes  115 seconds for a 100x100x100 8bit volume.  A java loop takes
6.4 seconds - 20x faster!

I don't want to clutter the mail with the gangly java code, so I'll mail it
direct to anyone who asks.  All of you with more Java knowledge than I
(that's all of you, methinks) will probably write your own, anyhow.

The end result is M that looks like this:

nums=M2VTK.Convert(mVolume);  % nice fast Java loop

11.  So, you've got the matlab volume into a vtkScalars.  Now the final bit
to actually render something:

%volPro1.m

import vtk.*
panel=vtkPanel;

% load some sample data
load mri
a=uint8(squeeze(D));

% Create transfer functions for opacity and color
opacityTransferFunction=vtkPiecewiseFunction;
opacityTransferFunction.AddPoint(0,1);
opacityTransferFunction.AddPoint(88,1);

colorTransferFunction=vtkColorTransferFunction;
colorTransferFunction.AddRGBPoint(0.0,.2,.2,0.0);
colorTransferFunction.AddRGBPoint(88, 0,0,1);

% Create properties, mappers, and volume actors
volumeProperty=vtkVolumeProperty;
volumeProperty.SetColor(colorTransferFunction)
volumeProperty.SetScalarOpacity(opacityTransferFunction)
volumeProperty.ShadeOff

%volumeMapper=vtkVolumeTextureMapper2D;  % This works, too
volumeMapper=vtkVolumeProMapper;

vol=vtkStructuredPoints;
vol.SetDimensions(size(a,1),size(a,2),size(a,3));
vol.SetOrigin(0,0,0);
vol.SetSpacing(1,1,1);

tic
nums=M2VTK.Convert(a)
toc
disp('Done allocation!')
vol.GetPointData.SetScalars(nums)

volumeMapper.SetInput(vol);

volume=vtkVolume;
volume.SetMapper(volumeMapper)
volume.SetProperty(volumeProperty)

% Okay now the graphics stuff
ren1=vtkRenderer;
ren1.SetBackground(.2,.2,.4);

renWin=vtkRenderWindow;
renWin.AddRenderer(ren1);
renWin.SetSize(256, 256);

iren=vtkRenderWindowInteractor;
iren.SetRenderWindow(renWin);

ren1.AddVolume(volume);

cam1=ren1.GetActiveCamera;
cam1.ParallelProjectionOn;
cam1.SetParallelScale(40);


renWin.Render

% end of file.


12.  Gosh, that was a bit long winded.  Well, if anyone got down this far,
drop me a line and let me know how you fared.  I can send you the java for
M2VTK, too.

Regards,

Greg

Greg Johnson
g.johnson at rl.ac.uk
Instrumentation Engineer
CLRC Rutherford Appleton Lab
UK




More information about the vtkusers mailing list