Back in June I read Michael Norton's MacDevCenter article 3-D Data Visualization on Mac OS X. I am a scientist by trade, but I hadn't made much use of visualization in my research. Michael's article opened my eyes to a whole new way of doing things and showed how easy it could be to turn your garden variety iBook into a powerful scientific ally.
For those of you not familiar with VTK, it is to visualization what Cocoa is to application development: VTK provides a high-level object-oriented framework which allows you to easily visualize 3D data sets without having to write any low-level OpenGL code. OpenGL is used to perform the eventual rendering, but the software developer writes code at a higher level of abstraction. Like Cocoa, VTK can literally save you having to write thousands of lines of source code.
In addition to being a scientist, I am also a Cocoa enthusiast, spending every spare minute of the day writing shareware for Mac OS X. So it wasn't long after reading Michael's article that I began wondering if it were possible to get the best of both worlds in one app: Cocoa's great Application building frameworks, and VTK's equally impressive visualization libraries. It turns out it is very possible to make visualization apps to-die-for with Cocoa and VTK. This article is about how to do just that.
I'll lead you through integrating VTK and Cocoa by way of example: In Part 1 we will learn the general steps required to setup a Cocoa-VTK project, and in Part 2 we will develop a simple Cocoa-VTK 3D animation application. Along the way we will learn how to compile VTK, configure Project Builder, overcome a few incompatibilities between VTK and Cocoa, and even get a quick intro to Objective-C++.
The best place to start in order to get a successful VTK build on Mac OS X is Michael Norton's original MacDevCenter article. Most of what we need to do here is covered there. But there are a few minor differences, so we will quickly move through the steps required to install VTK suitably for use in a Cocoa application.
Firstly, you will need the tool "CMake" to build VTK. If you haven't
installed this already, go to www.cmake.org and download the source code
CMake1.4.5-src-unix.tar.gz. I have found this version to
be stable. Unless you enjoy the thrill of the unknown, I suggest you steer
clear of using CVS to get the source. I encountered problems building VTK
when I used a CVS derived CMake, and you don't want to waste time on CMake
when you could be wasting time on the really fun stuff.
Unpack the CMake source, and change directories:
tar xvzf CMake1.4.5-src-unix.tar.gz cd CMake-1.4.5
Now configure, build, and install CMake
./configure make sudo make install
Note that you need to use "sudo" for the last step, so you will need
to be an administrator, and enter your password at the prompt. The last
thing you need to check is that your PATH environment variable includes
/usr/local/bin directory where cmake gets installed. For
tcsh you need to put this in your
setenv PATH $PATH:/usr/local/bin
and then source the file
With CMake installed, you're ready to install VTK. Because Cocoa has not been supported that long in VTK, you will need a relatively new copy of the source code, and you will need CVS for this. In a terminal window, change to the directory where you would like to install VTK. I will assume this is the directory "Develop" in your home directory, in which case you should issue this command
Now checkout the VTK source code with the following two commands:
cvs -d :pserver:email@example.com:/cvsroot/VTK login
cvs -d :pserver:firstname.lastname@example.org:/cvsroot/VTK checkout -D 09/20/2002 VTK
When asked for a password after the first command, enter
vtk. If you want the very latest sources, leave out the
-D 09/20/2002 in the second command. I had trouble compiling
more recent versions of VTK and found that for this date the code will at
least compile and run, even if it doesn't include cutting edge
developments. Now go and watch the wrestling for half an hour: checking
out the source can take a while.
~/Develop directory, create a directory for
building VTK, which I will call
VTKBuild and change to that
mkdir VTKBuild cd VTKBuild
Issue the following command:
When this completes, you should find a file called
CMakeCache.txt in your VTKBuild directory. This is a
configuration file for the cmake system. We need to make a few changes to
it, so use your favorite editor to search the CMakeCache.txt file for the
following entries, and change them accordingly:
Unlike in Michael Norton's original article, we're going to build
static libraries, so we are leaving the
option OFF. Static libraries make it easier to distribute your app once
you have written it because all binary code is included in the
executable. Your users do not need to install VTK in order to use your
app. (It is possible to embed shared libraries in an app too, but it is
much more involved, so we'll steer clear of it here.)
Run cmake again a couple of times from the VTKBuild directory.
cmake ../VTK; cmake ../VTK
Doing this is advised whenever you make changes to the
CMakeCache.txt file, as it can sometimes require several
iterations before the changes have completely propagated through the whole
Now type ...
... and pray. Just kidding. If all goes well, you should end up with a handful of static libraries in the VTKBuild/bin directory, and you are ready to start on the Cocoa stage of the journey.
Creating a Cocoa/VTK project
As I mentioned previously, in Part 2 we are going to build a small 3D animation program, so we will now start setting up a Project Builder project with that in mind. To begin with, open Project Builder, and choose New Project... from the File menu. Select Cocoa Application, enter the project name "Animoltion", select where you want to have the project folder, and click Finish. (To find out why it is called Animoltion, you will have to wait for our next riveting installment.)
VTK on Mac OS X is based on OpenGL, so we need to add the OpenGL framework--installed on every Mac OS X computer--to our new project. Choose "Add Frameworks..." from the "Project" menu, and browse to the framework bundle
Click "Add", and accept the default options in the dialog that appears. It's not always easy to predict where the framework will appear in your "Files" tab of Project Builder, but it belongs in "Frameworks/Linked Frameworks", so drag it in there.
Now we need to add the VTK libraries to the project. Project Builder doesn't create a "Libraries" group, so we will make one ourselves. Select the root "Animoltion" group in the "Files" tab, and choose "New Group" from the "Project" menu. Enter "Libraries" and press return.
To add the libraries, we need to do something which might seem strange. Project Builder doesn't include an "Add Libraries..." command, so we will use the "Add Frameworks..." command from the "Project" menu. Select this menu item, and browse to the ~/Develop/VTKBuild/bin directory where the VTK libraries were compiled. Select the following libraries:
libvtkCommon.a libvtkFiltering.a libvtkGraphics.a libvtkImaging.a libvtkRendering.a
and click "Add" twice, again accepting the default options in the dialog that appears. If the libraries do not appear in your "Libraries" group, just drag them in there.
We are only half way when it comes to importing VTK into our project; we still haven't got the header files. (This is a big advantage of Apple's frameworks: they include both the library binaries and header files in a single bundle.) Create a new group in the "Other Sources" group, and call it "VTK Headers". The problem we now face is that VTK's header files are distributed over multiple directories. This is where Jaguar's new improved finder can be a big help. (On pre-Jaguar versions of Mac OS X, you will probably need to use Sherlock instead.)
Make the Finder active, and choose "Find..." from the File menu. Choose
to search in "Specific Places" from the popup and add the
directories. Search for files whose name contains
vtk. You will need to add a second search criteria by
pressing the "+" button in order to add
vtk. Click the
"Search" button. When all the files have been found, select them all, and
drag them to the "VTK Headers" group in your Animoltion project. Click
"Add" in the sheet that appears.
By default, Project Builder sets up your project to use prebinding. Since we didn't compile VTK with any prebinding flags set, we need to turn this off in our project. Click the "Targets" tab, and then select the "Animoltion" target. Click "Linker Settings" under "Settings", and deselect the "Prebind" checkbox.