How to start a C# project with VTK

Hello,

I’ll be completely honest… I’m lost and I need your help. I try to utilize VTK in my upcoming C# project and so far I was unable to properly set up my project.

So far I did this: https://gitlab.kitware.com/vtk/vtk/-/blob/master/Documentation/dev/build_windows_vs.md

So, I have a VTK build and everything set up on my machine… What’s next?

I read a lot of forum posts and google searches and most of them recommended ActiviViz which if I’m not mistaken is in two forms: Paid and open-source. Open-source one is 10+ years old (according to Nuget.org) so my question is… is it still relevant?

Don’t get me wrong, I’m not trying to avoid paying for supported ActiViz version. My company simply wants to explore all possibilities before diving into purchasing licences.

Can I use VTK build without using ActiViz? How?
If you have any meaningful C# project example, I would appreciate it very much :))

Hello @petr.raunigr,

@LucasGandel is the maintainer of ActiViz, I believe it could help you (however it seems that he’s off this week)

Hi @petr.raunigr,

I confirm Activiz is the best way to get access to the VTK public API from a C# project.
The open-source version is based on VTK 5.8 and is not maintained anymore. The paid version however is based on the latest VTK version and is still developed actively.

The best is probably to give a try to the paid version by requesting a trial version on the Activiz website. Feel free to contact me if you have any issues trying it.

Activiz extensively uses the PInvoke C# technology to call the unmanaged VTK code. It also takes care of managing the VTK objects lifetime to make VTK smart pointers work with the C# garbage collector. In theory you could write similar code to expose your VTK C++ build in your C# project, but that would require a lot of effort.

Can I use Activez vtkRenderWindow and render c++ vktPolyData in c++ code by clr ?

You would need to create vtkPolyData class in C# to plug it to a mapper and actor before rendering it in the Activiz render window anyway. I did not try it, but it might be possible if you can get a pointer to the “c++” polydata and then use Kitware.mummy.Runtime.Methods.CreateWrappedObject to create the “C#” polydata. However I think converting your C++ code to C# to do everything with Activiz is preferred if possible

I tried, first get c++ vtkPolyData pointer, then create activiz vtkPolyData by pass pointer as the second parameter to function CreateWrappedObject, then I try cast return Object to activiz vtkPolyData, it seems like success, but when I pass it to actor and run, it crash at run time, seems memory interrupt.
vtk version output is:
activiz VTK Version: 9.3.20240515 (C# vtk component version)
cpp vtk version 9.3.20231030(C++ vtk component version)
@LucasGandel

Maybe using the same VTK version as Activiz (git commit tag 5fd6015c) would help, but the problem is probably that the C++ object lifetime is not managed correctly if the mteIndex parameter is wrong.

It might be better to try it the other way, by creating a vtkPolyData in C# and pass its pointer (IntPtr) to a C++ function (void*) that fills the polydata.

1 Like

Thank you for your reply. I compiled VTK with the same version of Activiz(9.3.20240515).
Then I Create vtkPolyData object obj1 and vtkPoints object pts1 by gcnew, then call obj1.SetPoints(pts1), finally send obj1 to native VTK module(by call obj1.GetCppThis().Handle.ToPointer() to convert obj1 to void*) .
but when I run the demo, It crash at native c++ to set obj1 points data, and still seems memory interrupt. looking forward for your reply.
best wishes!
demo url GitHub - yangxingpping/clrVtk
crash screenshot

Thanks for the feedback. The problem on your side may be caused by the use of gcnew, I would need to investigate further. The following approach works well on my side:

C#:

    [DllImport("NativeVTK.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern void PrintPoints(IntPtr points);

    public static void Main(String[] argv)
    {
        vtkSphereSource sphere = vtkSphereSource.New();
        sphere.Update();
        PrintPoints(sphere.GetOutput().GetPoints().GetCppThis().Handle);
    }

C++:

#include "vtkPoints.h"

extern "C" __declspec(dllexport) void PrintPoints(void* pts) {
  vtkPoints* points = static_cast<vtkPoints*>(pts);
  std::cout << "PTS " << points->GetNumberOfPoints() << std::endl;
}
1 Like