SourceForge.net Logo

Programming with VTK .NET Wrappers

Visual Studio Project Setup

Installing and Referencing Wrappers

Download VTK50_bin_wrap. Unzip it, usually so that it makes a directory called C:\Program Files\VTK. Put the C:\Program Files\VTK\bin directory in your path.

Create a C#, VB.NET, or managed C++ project and add the VTK assemblies to your project. A macro, called AddVTKReferencesToProject can do this for you. It is in the distribution as Wrapping/DotNet/VTK.vb. In Visual Studio, you can add references through the menu Project->References. It will show a dialog box. You can also right-click on the references folder in the Solutions window. While the VTK\bin directory contains many dlls, the only assemblies you need to reference are those ending in DotNet.dll. These are vtkCommonDotNet.dll, vtkGraphicsDotNet.dll, vtkFilteringDotNet.dll, vtkIODotNet.dll, vtkGenericFilteringDotNet.dll, vtkHybridDotNet.dll, vtkRenderingDotNet.dll, vtkVolumeRenderingDotNet.dll, and vtkWidgetsDotNet.dll.

If you want your project to run on a machine which does not have Visual Studio installed, don't forget to install the C runtime on that machine. Distributed within Visual Studio is an installer called vcredist_x86.exe. This puts the C runtimes in the WinSxS directory for you.

Using the Control

If you want to use the Windows Forms Control in your project, then download vtkcontrol and unzip it somewhere. It contains an assembly called vtkFormsWindow.dll. The easiest way to use this control is to add it to your toolbox in Visual Studio. Select the menu item View->Toolbox. Right-click in the toolbox area and select Add items on the menu. You have to browse to the vtkFormsWindow.dll and select it. Now when you create a Windows Form in the designer, you can drag the vtkFormsWindowControl to the canvas to include it in your project.

In the download file for the control is a solution which contains both the project to build the control and a small project using that control. In order to compile these, you will have to redirect their references to *DotNet.dll to those on your machine.

Programming Rules

Use the vtk namespace

The wrapper classes are all in a vtk namespace, so vtkRenderWindow is called vtk.vtkRenderWindow. It's redundant, but it's tradition in other wrappers.

New and Delete

When using the VTK library from C++, you instantiate a class by calling New() and dereference it by calling Delete(). With the managed wrapper, instantiate classes as you would any managed class, using gcnew in managed C++ or new in C#.

Managed wrappers do not support the use of Delete(). Instead, the Common Language Runtime's garbage collector will dereference the class before deleting the object for you. If you wish to free memory immediately, then call Dispose() in C#, or delete in managed C++. Once this method is called, do not call methods on that instance again.

Downcasting, dynamic_cast, and is

Each wrapper instance contains a pointer to a native instance. For instance, vtk.vtkRenderWindow contains a pointer to the native ::vtkRenderWindow. The native class, however, may actually be a derived class. For render windows on Windows, it is always the case that vtk.vtkRenderWindow contains a pointer to ::vtkWin32OpenGLRenderWindow.

If you need access to the derived class, use SafeDownCast. Neither dynamic_cast in managed C++ nor the "is" operator in C# will work. For instance, callbacks have a vtk.vtkObject caller as an argument. You would create a render window from this using the following:

vtk.vtkRenderWindow renWin = vtk.vtkRenderWindow.SafeDownCast(caller)

If that cast fails, the result will be a null pointer.

Special Consideration for Windows Display Feature

Every VTK window on the MS Windows operating system is of the subclass vtkWin32OpenGLRenderWindow. When your program closes a window, this subclass has the feature that it will display an warning message. There are two ways to avoid receiving this message.

Either ask the window to clean up its resources before closing,

vtkWin32OpenGLRenderWindow win32Win = vtkWin32OpenGLRenderWindow.SafeDownCast(renWin); win32Win.Clean();

or dispose of the window and interactor yourself in the correct order, instead of allowing the garbage collector to dispose of the window.

renWin.Dispose(); iren.Dispose();

Observers and Callbacks

Add an observer to a class with the following.

renWin.AddObserver((uint) EventIds.AbortCheckEvent, CheckAbort);

There is a variation of this that allows you to pass an argument of type vtk.vtkObject to the callback.

renWin.AddObserver((uint) EventIds.AbortCheckEvent, CheckAbort, calldata);

The receiving callback has the following signature.

public static void CheckAbort(vtkObject caller, uint eventId, object clientData, IntPtr callData) { vtkRenderWindow renWin = vtkRenderWindow.SafeDownCast(caller); if (null != renWin) { renWin.SetAbortRender(1); } }

Note the use of SafeDownCast() to convert the vtkObject to a vtkRenderWindow.

Common Error Messages

inaccessible due to its protection level

This means that you forgot the namespace. You do not have a directive for "using vtk;" and did not refer to vtk.vtkObject. The message is confusing because the compiler is trying to access the native VTK class, ::vtkObject. This class's type, while referenced in the managed assembly, is private.

System.IO.FileNotFoundException before the program loads

Managed code loads native classes on demand, so the program will begin to run before informing you that it cannot find the native Dlls in the path. These are vtkCommon.dll, vtkFiltering.dll, and the rest. Add them to the path or put them with the executable.

System.AccessViolationException

When native code accesses memory it shouldn't, the managed code will sometimes notice and throw a System.AccessViolationException. This does not necessarily mean that the problem is in the native code, though. First examine your code very carefully for proper semantics regarding referencing and dereferencing.

One cause could be that the native code invokes a callback on an object that no longer exists. Did you register a callback from a widget and not keep a reference to that widget? Is there any object you deleted prematurely?

If this error persists, it is possible to compile a debug version of VTK and step into the native code.

VTK .NET home