VTK交互系统 3 自定义交互器样式

878 阅读2分钟

我觉得还是从头到尾教大家写一个交互器样式比较好,而不是直接列上一大堆程序。

可能一节到两节就能写完了,因为内容也不复杂。

首先我们把之前写好的数组显示vtk程序放上,我们在它的基础上添加自己想要等功能。

`#include<vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
#include <vtkImageImport.h>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <iostream>
using std::cout;
using std::endl;
#include <vtkInteractorStyleImage.h>


int main(int argc, char *argv[])
{

        vtkSmartPointer<vtkImageImport>imageImport = 
                vtkSmartPointer<vtkImageImport>::New();
        vtkSmartPointer<vtkRenderer>sceneRenderer = 
                vtkSmartPointer<vtkRenderer>::New();
        vtkSmartPointer<vtkImageActor>imageActor = 
                vtkSmartPointer<vtkImageActor>::New();
        vtkSmartPointer<vtkRenderWindow>renderWindow = 
                vtkSmartPointer<vtkRenderWindow>::New();
        vtkSmartPointer<vtkRenderWindowInteractor> interactor = 
                vtkSmartPointer<vtkRenderWindowInteractor>::New();

        renderWindow->SetSize(600,600);
        sceneRenderer->SetBackground(0.8, 0.0, 0.0);
        renderWindow->AddRenderer(sceneRenderer);	
        sceneRenderer->AddActor(imageActor);
        //renderWindow->SetMultiSamples(0);
        interactor->SetRenderWindow(renderWindow);


        int width = 512;//(renderWindow->GetSize())[0];
        int height = 512;//(renderWindow->GetSize())[1];
        //cout << width << "  " << height<<endl;

        const int Size = width* height * 3 * sizeof(unsigned char);
        unsigned char* m_pPixels = (unsigned char*)malloc(Size);

        for (int i = 0;i<width;i++){
                for (int j = 0;j < height;j+=1) {
                        m_pPixels[(i*width + j) * 3] = 0;
                        m_pPixels[(i*width + j) * 3 + 1] = 255;
                        m_pPixels[(i*width + j) * 3 + 2] = 0;
                }
        }
        for (int i = 0;i<20;i++) {
                for (int j = 0;j < 20;j += 1) {
                        m_pPixels[(i*width + j) * 3] = 0;
                        m_pPixels[(i*width + j) * 3 + 1] = 0;
                        m_pPixels[(i*width + j) * 3 + 2] = 255;
                }
        }
        for (int i = 40;i<60;i++) {
                for (int j = 0;j < 20;j += 1) {
                        m_pPixels[(i*width + j) * 3] = 0;
                        m_pPixels[(i*width + j) * 3 + 1] = 0;
                        m_pPixels[(i*width + j) * 3 + 2] = 255;
                }
        }
        imageImport->SetImportVoidPointer(m_pPixels);
        //imageImport->SetDataOrigin(-0.5f * (float)width, -0.5f * (float)height, 0);
        imageImport->SetWholeExtent(0, width - 1, 0, height - 1, 0, 0);
        imageImport->UpdateWholeExtent();
        imageImport->SetDataExtentToWholeExtent();
        imageImport->SetDataScalarTypeToUnsignedChar();
        imageImport->SetNumberOfScalarComponents(3);
        imageImport->Update();



        imageActor->SetInputData(imageImport->GetOutput());
        renderWindow->Render();
        interactor->Start();


        return EXIT_SUCCESS;

}`

这个工程是没有交互器样式的,所以它用的是默认样式。在这里我们开始自定义。

现在,我们加入头文件。

`#include <vtkInteractorStyleImage.h>
#include <vtkInteractorStyleUser.h>
#include <vtkObjectFactory.h>`

然后定义一个类:

`class my3DCameraStyle : public vtkInteractorStyleUser
{
public:
        static my3DCameraStyle* New();
        vtkTypeMacro(my3DCameraStyle, vtkInteractorStyleUser);

        virtual void OnLeftButtonDown(void);
        virtual void OnLeftButtonUp(void);
        virtual void OnRightButtonDown(void);
        virtual void OnRightButtonUp(void);
        virtual void OnMiddleButtonDown(void);
        virtual void OnMiddleButtonUp(void);
        virtual void OnMouseWheelForward(void);
        virtual void OnMouseWheelBackward(void);
        virtual void OnMouseMove(void);

        int m_OldPos[2];
        int m_NewPos[2];
};`

这个类主要就是实现一些虚函数,里面的m_OldPos和m_NewPos是代表鼠标点击的时候和移动的时候用来记录点击位置和移动后的位置,来计算点击然后移动的距离的。这是自己定义的。

然后我们再在主程序里添加:

`vtkSmartPointer<my3DCameraStyle> style =
        vtkSmartPointer<my3DCameraStyle>::New();

interactor->SetInteractorStyle(style);`

创建交互器样式,并把交互器样式添加到窗口交互器中。

然后开始实现类里面的函数:

`vtkStandardNewMacro(my3DCameraStyle);//必须加!!!!
void my3DCameraStyle::OnLeftButtonDown(void)
{
        vtkInteractorStyleUser::OnLeftButtonDown();

}

void my3DCameraStyle::OnLeftButtonUp(void)
{
        vtkInteractorStyleUser::OnLeftButtonUp();

}

void my3DCameraStyle::OnRightButtonDown(void)
{
        vtkInteractorStyleUser::OnRightButtonDown();

}

void my3DCameraStyle::OnRightButtonUp(void)
{
        vtkInteractorStyleUser::OnRightButtonUp();

}

void my3DCameraStyle::OnMiddleButtonDown(void)
{
        vtkInteractorStyleUser::OnMiddleButtonDown();


}

void my3DCameraStyle::OnMiddleButtonUp(void)
{
        vtkInteractorStyleUser::OnMiddleButtonUp();


}

void my3DCameraStyle::OnMouseWheelForward(void)
{
        vtkInteractorStyleUser::OnMouseWheelForward();

};

void my3DCameraStyle::OnMouseWheelBackward(void)
{
        vtkInteractorStyleUser::OnMouseWheelBackward();

};

void my3DCameraStyle::OnMouseMove(void)
{
        // Forward events
        vtkInteractorStyleUser::OnMouseMove();

}`

先不实现任何功能,只是先把函数定义一下。

注意第一句的 vtkStandardNewMacro(my3DCameraStyle); 必须要加上,要让vtk的智能指针知道我们创建的这个变量属于被创建对象的New(),否则会报错。

现在编译一下,能通过。说明我们的交互器没有问题了。下一节开始设计功能。