How to implement a VTK Application using CLR embedded in WPF

741 Views Asked by At

I want to create a VTK Project that should be using WPF for creating the GUI. I found the following post that also tries to explain this problem(VTK Rendering without ActiViz).

I created a CLR class library that implements a VTK pipeline from a VTK example:

#pragma once

#include <Windows.h>

using namespace System;

#include <vtkAlgorithmOutput.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkProperty.h>
#include <vtkNamedColors.h>
#include <vtkCylinderSource.h>

#include <array>

// https://stackoverflow.com/questions/30301087/vtk-render-into-c-sharp

namespace CVTK {
    class MyRender
    {
    public:
        MyRender(HWND parent)
        {
            vtkNew<vtkNamedColors> colors;

            std::array<unsigned char, 4> bkg{{26, 51, 102, 255}};
            colors->SetColor("BkgColor", bkg.data());

            vtkNew<vtkCylinderSource> cylinder;
            cylinder->SetResolution(8);

            vtkNew<vtkPolyDataMapper> cylinderMapper;
            cylinderMapper->SetInputConnection(cylinder->GetOutputPort());

            vtkNew<vtkActor> cylinderActor;
            cylinderActor->SetMapper(cylinderMapper);
            cylinderActor->GetProperty()->SetColor(colors->GetColor4d("Tomato").GetData());
            cylinderActor->RotateX(30.0);
            cylinderActor->RotateY(-45.0);

            renderer = vtkSmartPointer<vtkRenderer>::New();
            renderer->AddActor(cylinderActor);
            renderer->SetBackground(1, 0, 1);
            renderer->ResetCamera();

            renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
            //renderWindow->SetSize(300, 300);
            renderWindow->AddRenderer(renderer);

            interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
            interactor->SetRenderWindow(renderWindow);

            //setting background
            renderWindow->SetParentId(parent);
        }

        void Render()
        {
            //interactor->Initialize();
            renderWindow->Render();
            interactor->Start();
        }

    private:
        vtkSmartPointer<vtkRenderer> renderer;
        vtkSmartPointer<vtkRenderWindow> renderWindow;
        vtkSmartPointer<vtkRenderWindowInteractor> interactor;
    };


    public ref class cMyRender
    {
    public:
        cMyRender(IntPtr parent)
        {
            render = new MyRender((HWND)parent.ToPointer());
        }

        void Render()
        {
            render->Render();
        }


    private:
        MyRender* render;
    };
}

Then I included the dll into a WPF project and tried to render it using the mentioned Post from above:

<Window x:Class="CVTKRendering.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    
    xmlns:local="clr-namespace:CVTKRendering"
    mc:Ignorable="d"
    Title="MainWindow" 
    Height="450" 
    Width="800"
    Loaded="Window_Loaded">
</Window>

namespace CVTKRendering
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();   
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            HwndSource source = (HwndSource)HwndSource.FromVisual(this);
            IntPtr hWnd = source.Handle;
            cMyRender render = new cMyRender(hWnd);
            render.Render();
        }
    }
}

The problem is that nothing is being rendered in the Window. It is completely blank. Any help is appreciated.

0

There are 0 best solutions below