第一节《FreeWorld对VTK封装介绍》

本文介绍了如何使用FreeWorld库封装VTK,包括将VTK的vtkRenderer嵌入到Qt的QVTKOpenGLNativeWidget中,以及FreeWorld库中的FreeModelView类,用于提供三维显示窗口、鼠标交互事件和模型封装。还讨论了为何选择QVTKOpenGLNativeWidget以及VTK的鼠标交互事件处理。最后,预告了后续会讲解更多FreeWorld库的细节。
摘要由CSDN通过智能技术生成

       Hello大家好,VTK提供了vtkRenderer如何嵌入到QWidget中,初学者在使用时,图形软件框架不知如何设计,本人在此分享个人使用心得。我会通过介绍FreeWorld这个库,让大家了解VTK常用技巧,以及常用的API,还有一些可能大家在网上找不到的vtk api用法,以及会介绍vtk中现有版本存在的bug或不足等问题。在文章结束时我会分享FreeWorld库所有代码给大家。

        FreeWorld封装了VTK三维窗口,鼠标交互事件信号、各种常用模型封装、各种常用方法封装,下面现介绍FreeWorld中窗口类FreeModelView

        图形图像处理类项目,首先要有三维显示窗口、显示的内容(三维模型)、鼠标的交互处理。所以我们先要有这三个东西,然后将这三个东西添加到Qt环境中;

        VTK提供了多种方式将三维窗口嵌入到QWidget中,我使用的是QVTKOpenGLNativeWidget,为什么选用它呢,其他怎么不用,其实我都用过,其他的都遇到过种种小问题,最后选择了QVTKOpenGLNativeWidget。创建新的类FreeModelView继承QVTKOpenGLNativeWidget,这时就可以把这个窗口当做QWidget使用,添加到你的界面布局,三维窗口具备鼠标交互事件、添加移除vtkActor、相机相关接口、视口矩阵接口、6视图接口等等,后续小伙伴们可以自己拓展。此类主要是把VTK渲染器VTKRenderer与VTK鼠标交互器管理起来。

        注意事项:小伙伴如果阅读了代码后是否发现VTK的鼠标交互事件为什么非要转到FreeModelView中的函数,其实这么做就是为了将代码整齐度更高一些考虑的,并且FreeModelView中的鼠标交互事件函数中什么也没做,只是将信号发送出去,这样是减少业务代码在FreeModelView中,业务模型想使用鼠标交互事件,只需要连接FreeModelView的信号就可以了。

#ifndef FREEMODELVIEW_H
#define FREEMODELVIEW_H
#include "FreeWorld_global.h"
#include <QVTKOpenGLNativeWidget.h>
#include <vtkRenderer.h>
#include <vtkCamera.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkBox.h>
#include <vtkExtractPoints.h>
#include <vtkOrientationMarkerWidget.h>
#include "FreeInteratorStyleTrackballCamera.h"
#include <vtkProp.h>
#include "FreeVector.hxx"
#include <QLabel>
#include <QMovie>
#include "FreeImageObject.h"
/**
 * @brief The FreeModelView class
 * 图形显示窗口
 */
class FREEWORLD_EXPORT FreeModelView : public QVTKOpenGLNativeWidget
{
    Q_OBJECT
public:
    /**
     * @brief The SIX_VIEW enum 视口切换枚举
     */
    enum SIX_VIEW
    {
        SV_TOP = 0,
        SV_BOTTOM,
        SV_LEFT,
        SV_RIGHT,
        SV_FRONT,
        SV_BACK,
        SV_COUNT
    };
    FreeModelView(QWidget *parent = nullptr);
    ~FreeModelView();
    void setInteractorStyle(FreeInteratorStyleTrackballCamera* style);
    void setBackgroundColor(double r, double g, double b);
    void setBackgroundJPG(std::string filePath);
    void setBackgroundPNG(std::string filePath);
    void OnMouseMove();
    void OnLeftButtonDown();
    void OnLeftButtonUp();
    void OnMiddleButtonDown();
    void OnMiddleButtonUp();
    void OnRightButtonDown();
    void OnRightButtonUp();
    void OnMouseWheelForward();
    void OnMouseWheelBackward();
    void OnKeyPress();
    void OnKeyRelease();
    void updateView();
    void resetCamera(double scale = 0);
    vtkSmartPointer<FreeInteratorStyleTrackballCamera> getViewInteratorStyle() const;

    void addActors(std::vector<vtkProp *> actors);                                          // 添加actor
    void removeActors(std::vector<vtkProp *> actors);                                       // 移除actor
    void addActor(vtkProp *actor);                                                          // 添加actor
    void removeActor(vtkProp *actor);                                                       // 移除actor
    void addVolume(vtkVolume* volume);                                                      // 添加体数据
    void removeVolume(vtkVolume* volume);                                                   // 移除体数据

    vtkCamera* getCamera();                                                                 // 获取相机指针
    FreeVector getCameraPos();                                                              // 获取相机位置
    vtkMatrix4x4 *getCurrentMatrix();                                                       // 获取当前变换矩阵
    FreeVector getViewPlaneNormal();                                                        // 获取指向屏幕方向
    void setIsShowAxesActor(bool value);                                                    // 设置是否显示左下角坐标系
    vtkRenderer* getRenderer();                                                             // 获取渲染器指针
    void viewDirection(double x, double y, double z,
                       double lookX, double lookY, double lookZ,
                       double upX, double upY, double upZ);                                 // 设置相机位置
    void setSixView(SIX_VIEW view);                                                         // 设置6视口
    bool getIsLeftPress() const;                                                            // 鼠标左键是否按下
    bool getIsRightPress() const;                                                           // 鼠标右键是否按下



signals:
    void SignalMouseMove(int x, int y, vtkRenderer* render);
    void SignalLeftButtonDown(int x, int y, vtkRenderer* render);
    void SignalLeftButtonUp(int x, int y, vtkRenderer* render);
    void SignalMiddleButtonDown(int x, int y, vtkRenderer* render);
    void SignalMiddleButtonUp(int x, int y, vtkRenderer* render);
    void SignalRightButtonDown(int x, int y, vtkRenderer* render);
    void SignalRightButtonUp(int x, int y, vtkRenderer* render);
    void SignalMouseWheelForward();
    void SignalMouseWheelBackward();
    void SignalKeyPress(std::string keyName);
    void SignalKeyRelease(std::string keyName);

protected:
    vtkSmartPointer<vtkRenderer> renderer; // 渲染器
    vtkSmartPointer<FreeInteratorStyleTrackballCamera> viewInteratorStyle; // 轨迹球交互
    vtkSmartPointer<vtkOrientationMarkerWidget> axesWidget; // 左下角坐标轴
    bool isShowAxesActor = true; // 是否显示左下角坐标轴
    bool isLeftPress;   // 鼠标左键是否按下
    bool isRightPress;  // 鼠标右键是否按下
};

#endif // FREEMODELVIEW_H
#include "FreeModelView.h"
#include <vtkProperty.h>
#include <vtkConeSource.h>
#include "vtkAxesActor.h"
#include "vtkOrientationMarkerWidget.h"
#include "vtkMatrix4x4.h"
#include "vtkJPEGReader.h"
#include "vtkTexture.h"
#include "vtkGenericOpenGLRenderWindow.h"
#include "vtkCellData.h"
#include "vtkPNGReader.h"
#include <vtkAutoInit.h>
#include <vtkWindowToImageFilter.h>
#include <vtkExtractVOI.h>
#include <vtkImageCast.h>
#include <vtkWorldPointPicker.h>
#include <vtkImageResize.h>

VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2)
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
#pragma execution_character_set("utf-8")
FreeModelView::FreeModelView(QWidget *parent) : QVTKOpenGLNativeWidget(parent)
{
    renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->GetActiveCamera()->ParallelProjectionOn();
    renderer->GetActiveCamera()->SetPosition(0, 0, 1000);
    renderer->GetActiveCamera()->ComputeViewPlaneNormal();
    this->renderWindow()->AddRenderer(renderer);

    // 交互器
    viewInteratorStyle = vtkSmartPointer<FreeInteratorStyleTrackballCamera>::New();
    this->renderWindow()->GetInteractor()->SetInteractorStyle(viewInteratorStyle);
    viewInteratorStyle->setFreeModelView(this);
    setBackgroundColor(1, 1, 1);

    // 坐标轴
    vtkSmartPointer<vtkAxesActor> axes =
            vtkSmartPointer<vtkAxesActor>::New();
    axes->SetXAxisLabelText("X");
    axes->SetYAxisLabelText("Y");
    axes->SetZAxisLabelText("Z");
    axes->SetTotalLength(2, 2, 2);
    axes->SetVisibility(true);
    axesWidget = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
    axesWidget->SetOutlineColor(0.93, 0.57, 0.13);
    axesWidget->SetInteractor(this->renderWindow()->GetInteractor());
    axesWidget->SetOrientationMarker(axes);
    axesWidget->SetViewport(0, 0, 0.1, 0.2);
    axesWidget->SetEnabled(1);
    axesWidget->InteractiveOff();
    this->setMouseTracking(true);
    isLeftPress = false;
    isRightPress = false;
}

FreeModelView::~FreeModelView()
{

}

void FreeModelView::setInteractorStyle(FreeInteratorStyleTrackballCamera *style)
{
    this->renderWindow()->GetInteractor()->SetInteractorStyle(style);
}

void FreeModelView::setBackgroundColor(double r, double g, double b)
{
    renderer->SetBackground(r, g, b);
    this->updateView();
}

void FreeModelView::setBackgroundJPG(std::string filePath)
{
    auto texture = vtkSmartPointer<vtkTexture>::New();
    auto reader = vtkSmartPointer<vtkJPEGReader>::New();
    reader->SetFileName(filePath.c_str());
    reader->Update();
    texture->SetInputConnection(reader->GetOutputPort());
    renderer->TexturedBackgroundOn();
    renderer->SetBackgroundTexture(texture);
    this->updateView();
}

void FreeModelView::setBackgroundPNG(std::string filePath)
{
    auto texture = vtkSmartPointer<vtkTexture>::New();
    auto reader = vtkSmartPointer<vtkPNGReader>::New();
    reader->SetFileName(filePath.c_str());
    reader->Update();
    texture->SetInputConnection(reader->GetOutputPort());
    renderer->TexturedBackgroundOn();
    renderer->SetBackgroundTexture(texture);
    this->updateView();
}

void FreeModelView::OnMouseMove()
{
    int* pickPos = this->renderWindow()->GetInteractor()->GetEventPosition();
    updataMagnifyingGlass(pickPos[0], pickPos[1]);
    emit SignalMouseMove(pickPos[0], pickPos[1], renderer);
}

void FreeModelView::OnLeftButtonDown()
{
    isLeftPress = true;
    int* pickPos = this->renderWindow()->GetInteractor()->GetEventPosition();
    clickGif(pickPos[0], this->height() - pickPos[1]);
    emit SignalLeftButtonDown(pickPos[0], pickPos[1], renderer);
}

void FreeModelView::OnLeftButtonUp()
{
    isLeftPress = false;
    int* pickPos = this->renderWindow()->GetInteractor()->GetEventPosition();
    emit SignalLeftButtonUp(pickPos[0], pickPos[1], renderer);
}

void FreeModelView::OnMiddleButtonDown()
{
    int* pickPos = this->renderWindow()->GetInteractor()->GetEventPosition();
    emit SignalMiddleButtonDown(pickPos[0], pickPos[1], renderer);
}

void FreeModelView::OnMiddleButtonUp()
{
    int* pickPos = this->renderWindow()->GetInteractor()->GetEventPosition();
    emit SignalMiddleButtonUp(pickPos[0], pickPos[1], renderer);
}

void FreeModelView::OnRightButtonDown()
{
    isRightPress = true;
    int* pickPos = this->renderWindow()->GetInteractor()->GetEventPosition();
    emit SignalRightButtonDown(pickPos[0], pickPos[1], renderer);
}

void FreeModelView::OnRightButtonUp()
{
    isRightPress = false;
    int* pickPos = this->renderWindow()->GetInteractor()->GetEventPosition();
    emit SignalRightButtonUp(pickPos[0], pickPos[1], renderer);
}

void FreeModelView::OnMouseWheelForward()
{
    emit SignalMouseWheelForward();
}

void FreeModelView::OnMouseWheelBackward()
{
    emit SignalMouseWheelBackward();
}

void FreeModelView::OnKeyPress()
{
    char* keyName = this->renderWindow()->GetInteractor()->GetKeySym();
    if(keyName)
    {
        emit SignalKeyPress(keyName);
    }
}

void FreeModelView::OnKeyRelease()
{
    char* keyName = this->renderWindow()->GetInteractor()->GetKeySym();
    if(keyName)
    {
        emit SignalKeyRelease(keyName);
    }
}

void FreeModelView::updateView()
{
    this->renderWindow()->Render();
}

void FreeModelView::resetCamera(double scale)
{
    renderer->ResetCamera();
    if(scale != 0)
        this->renderer->GetActiveCamera()->SetParallelScale(scale);
    this->renderer->ResetCameraClippingRange();
    this->renderWindow()->Render();
}


vtkSmartPointer<FreeInteratorStyleTrackballCamera> FreeModelView::getViewInteratorStyle() const
{
    return viewInteratorStyle;
}

void FreeModelView::addActors(std::vector<vtkProp *> actors)
{
    for(int i = 0; i < actors.size(); i++)
    {
        vtkProp *prop = actors[i];
        if(!prop)
        {
            continue;
        }
        addActor(prop);
    }
}

void FreeModelView::removeActors(std::vector<vtkProp *> actors)
{
    for(int i = 0; i < actors.size(); i++)
    {
        removeActor(actors[i]);
    }
}

void FreeModelView::addActor(vtkProp *actor)
{
    renderer->AddActor(actor);
    renderer->Modified();
}

void FreeModelView::removeActor(vtkProp *actor)
{
    renderer->RemoveActor(actor);
    renderer->Modified();
}

void FreeModelView::addVolume(vtkVolume *volume)
{
    renderer->AddVolume(volume);
}

void FreeModelView::removeVolume(vtkVolume *volume)
{
    renderer->RemoveVolume(volume);
}

vtkCamera *FreeModelView::getCamera()
{
    return renderer->GetActiveCamera();
}

FreeVector FreeModelView::getCameraPos()
{
    double* cameraPos = renderer->GetActiveCamera()->GetPosition();
    return FreeVector(cameraPos[0], cameraPos[1], cameraPos[2]);
}

vtkMatrix4x4 *FreeModelView::getCurrentMatrix()
{
    return renderer->GetActiveCamera()->GetViewTransformMatrix();
}

FreeVector FreeModelView::getViewPlaneNormal()
{
    double* n = renderer->GetActiveCamera()->GetViewPlaneNormal();
    FreeVector planeNormal(n[0], n[1], n[2]);
    return planeNormal;
}

void FreeModelView::setIsShowAxesActor(bool value)
{
    if(value)
    {
        axesWidget->SetEnabled(1);
    } else {
        axesWidget->SetEnabled(0);
    }
}

vtkRenderer *FreeModelView::getRenderer()
{
    return renderer;
}

void FreeModelView::viewDirection(double x, double y, double z, double lookX, double lookY, double lookZ, double upX, double upY, double upZ)
{
    renderer->GetActiveCamera()->SetPosition(x, y, z);    // 相机位置
    renderer->GetActiveCamera()->SetFocalPoint(lookX, lookY, lookZ);    // 焦点位置
    renderer->GetActiveCamera()->SetViewUp(upX, upY, upZ);    // 朝上方向
    updateView();
}

void FreeModelView::setSixView(SIX_VIEW view)
{
    switch (view)
    {
    case SV_TOP:
        viewDirection(0, 0, 0, 0, 0, -1, 0, 1, 0);
        break;
    case SV_BOTTOM:
        viewDirection(0, 0, 0, 0, 0, 1, 0, -1, 0);
        break;
    case SV_LEFT:
        viewDirection(0, 0, 0, -1, 0, 0, 0, 0, 1);
        break;
    case SV_RIGHT:
        viewDirection(0, 0, 0, 1, 0, 0, 0, 0, 1);
        break;
    case SV_FRONT:
        viewDirection(0, 0, 0, 0, 1, 0, 0, 0, 1);
        break;
    case SV_BACK:
        viewDirection(0, 0, 0, 0, -1, 0, 0, 0, 1);
        break;
    default:
        break;
    }
}

bool FreeModelView::getIsLeftPress() const
{
    return isLeftPress;
}

bool FreeModelView::getIsRightPress() const
{
    return isRightPress;
}

        三维模型类,三维模型类有很多种、点、球、圆柱、箭头、线段、网格模型、我将这些成为模型类,VTK中将模型添加到三维世界中需要VTKActor vtkMapper来连接vtkRenderer,所以我的模型类是将这些对象指针管理起来,下面演示一个网格模型类的相关接口:

#ifndef FREEPOLYDATA_H
#define FREEPOLYDATA_H
#include <vtkPolyData.h>
#include "FreeWorld_global.h"
#include <vtkOBBTree.h>
#include <vtkKdTree.h>
#include "FreeVector.hxx"
#include "FreeActorArray.hxx"
#include <vtkMatrix4x4.h>
#include "mutex"
/**
 * @brief The FreePolyData class
 * 非结构化网格模型
 */
class FREEWORLD_EXPORT FreePolyData
{
public:
    enum MAP_TYPE
    {
        DIST_MIN,                       // 距离最近的交点
        DIST_MIN_LINEFRONT,             // 投影点前方,距离最近的点
        DIST_MIN_LINEFRONT_CELLFRONT,   // 投影点前方,距离最近的点,交到三角形正面
        DIST_MIN_LINEFRONT_CELLBACK     // 投影点前方,距离最近的点,交到三角形背面
    };
    FreePolyData();
    ~FreePolyData();
    vtkPolyData *getPolyData();
    FreeVector getPoint(int& index);                                                                                    // 获取单点
    std::vector<FreeVector> getPoints(std::vector<int>& indexs);                                                        // 获取点集
    FreeVector getCellNormal(const int& index);                                                                         // 获取面法向,如果没有计算面法向,会自动计算当前面的法向
    FreeVector getPointNormal(const int& index);                                                                        // 获取点法向,如果没有计算点法向,返回0,0,0
    void buildOBBTree();                                                                                                // 构建ObbTree
    vtkSmartPointer<vtkOBBTree> getOBBTree();                                                                           // 获取ObbTree
    void buildKdtree();                                                                                                 // 构建Kdtree
    vtkSmartPointer<vtkKdTree> getKdTree();                                                                             // 获取Kdtree
    void findClosestPoint(FreeVector &p, int& output);                                                                  // 获取最近点
    void findClosestPoint(FreeVector &p, FreeVector& output);                                                           // 获取最近点
    void findClosestPoints(const FreeVector &p, double r, std::vector<int>& output);                                    // 获取范围内的点
    void findClosestPoints(const FreeVector &p, double r, std::vector<FreeVector>& output);                             // 获取范围内的点
    void findCurveRangePoints(const std::vector<FreeVector>& curve, double r, std::vector<int>& output);                // 获取曲线范围内的点
    void findCurveRangePoints(const std::vector<FreeVector>& curve, double r, std::vector<FreeVector>& output);         // 获取曲线范围内的点
    void buildNormal(int type);                                                                                         // 计算法向,0点法向 1面法相
    bool loadPolyDataSTL(std::string filePath);                                                                         // 加载stl模型
    void savePolyDataSTL(std::string filePath);                                                                         // 保存stl模型
    void loadPolyDataVTK(std::string filePath);                                                                         // 加载vtk模型
    void savePolyDataVTK(std::string filePath);                                                                         

    FreeActorArray *getActorArray();                                                                                    // 获取显示用的Actor
    void clean();                                                                                                       // 去除重复点
    std::vector<std::vector<FreeVector> > findAllBorder();                                                              // 查找所有边
    std::vector<FreeVector> findNearestBorder(FreeVector p);                                                            // 查找最近边
    std::vector<FreeVector> findMaxBorder();                                                                            // 查找点数最多边
    void reverseSurface();                                                                                              // 所有面片翻转
    std::vector<int> getAdjPoints(int id);                                                                              // 获取点1邻域点
    vtkSmartPointer<vtkMatrix4x4> getMatrix();                                                                          // 获取模型坐标系
    void setMatrix(vtkSmartPointer<vtkMatrix4x4> newMatrix);                                                            // 设置模型坐标系
    void setMatrix(const FreeVector& nx, const FreeVector& ny, const FreeVector& nz, const FreeVector& center);         // 设置坐标系
    void getMatrix(FreeVector& nx, FreeVector& ny, FreeVector& nz, FreeVector& center);                                 // 获取坐标系
    FreeVector getXAxis();                                                                                              // 获取X轴
    FreeVector getYAxis();                                                                                              // 获取Y轴
    FreeVector getZAxis();                                                                                              // 获取Z轴
    FreeVector getCenter();                                                                                             // 获取中心
    void meshToTriangle();                                                                                              // 网格进行三角化
    int pointMappingToPolyData(const FreeVector& p, const FreeVector& n, MAP_TYPE mapType, FreeVector& outPut);         // 点向模型上投影,obbTree提供算法
    int pointMappingToPolyData(const FreeVector& p, const FreeVector& n, double range, FreeVector& outPut);             // 点向模型上投影,遍历三角形进行计算求交
    void setBufferPolyData(vtkSmartPointer<vtkPolyData> newBufferPolyData);                                             // 设置缓存区数据指针
    void swapBufferPolyData();                                                                                          // 如果缓存区有数据将缓存数据复制到当前polyData中

protected:
    vtkSmartPointer<vtkPolyData> polyData;      // 网格模型
    vtkSmartPointer<vtkOBBTree> obbTree;        // obb求交计算
    vtkSmartPointer<vtkKdTree> kdTree;          // 计算最近点
    FreeActorArray* actor;                      // vtkActor显示类
    vtkSmartPointer<vtkMatrix4x4> matrix;       // 记录模型坐标系

    std::mutex bufferMutex;                     // 模型缓存区锁
    vtkSmartPointer<vtkPolyData> bufferPolyData; // 缓存区数据,当多线程操作时,可以利用缓存区,线程中进行保存数据,主线程进行更新数据
};

#endif // FREEPOLYDATA_H
#include "FreePolyData.hxx"
#include <vtkObjectFactory.h>
#include <vtkPolyDataNormals.h>
#include <vtkSTLReader.h>
#include <vtkSTLWriter.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyDataWriter.h>
#include <vtkCleanPolyData.h>
#include <vtkFeatureEdges.h>
#include <vtkStripper.h>
#include <vtkCleanPolyData.h>
#include <vtkCellLocator.h>
#include <vtkGenericCell.h>
#include <set>
#include <vtkTriangleFilter.h>
#include <vtkCellData.h>
#include <vtkPointData.h>
#include <vtkTriangle.h>

FreePolyData::FreePolyData()
{
    polyData = vtkSmartPointer<vtkPolyData>::New();
    actor = new FreeActorArray;
    actor->setInputData(polyData);
    bufferPolyData = NULL;
    matrix = vtkSmartPointer<vtkMatrix4x4>::New();
}

FreePolyData::~FreePolyData()
{
    if(actor)
    {
        delete actor;
    }
}

FreeVector FreePolyData::getPoint(int &index)
{
    return FreeVector(polyData->GetPoint(index));

}

std::vector<FreeVector> FreePolyData::getPoints(std::vector<int> &indexs)
{
    std::vector<FreeVector> points;
    for(int i = 0; i < indexs.size(); i++)
    {
        points.push_back(getPoint(indexs[i]));
    }
    return points;
}

FreeVector FreePolyData::getCellNormal(const int &index)
{
    if(index >= polyData->GetNumberOfCells())
    {
        return FreeVector(0, 0, 0);
    }
    if(polyData->GetCellData()->GetNormals())
    {
        FreeVector res;
        double* n = polyData->GetCellData()->GetNormals()->GetTuple3(index);
        res.Set(n[0], n[1], n[2]);
        return res;
    } else {
        vtkCell* cell = polyData->GetCell(index);
        double v1[3], v2[3], v3[3], n[3];
        polyData->GetPoint(cell->GetPointId(0), v1);
        polyData->GetPoint(cell->GetPointId(1), v2);
        polyData->GetPoint(cell->GetPointId(2), v3);
        vtkTriangle::ComputeNormal(v1, v2, v3, n);
        FreeVector res;
        res.Set(n[0], n[1], n[2]);
        return res;
    }
    return FreeVector(0, 0, 0);
}

FreeVector FreePolyData::getPointNormal(const int &index)
{
    if(index >= polyData->GetNumberOfCells())
    {
        return FreeVector(0, 0, 0);
    }
    if(polyData->GetPointData()->GetNormals())
    {
        FreeVector res;
        double* n = polyData->GetPointData()->GetNormals()->GetTuple3(index);
        res.Set(n[0], n[1], n[2]);
        return res;
    }
    return FreeVector(0, 0, 0);
}

void FreePolyData::buildOBBTree()
{
    obbTree = vtkSmartPointer<vtkOBBTree>::New();
    obbTree->SetDataSet(polyData);
    obbTree->BuildLocator();
}

vtkSmartPointer<vtkOBBTree> FreePolyData::getOBBTree()
{
    return obbTree;
}
void FreePolyData::buildKdtree()
{
    kdTree = vtkSmartPointer<vtkKdTree>::New();
    kdTree->BuildLocatorFromPoints(polyData->GetPoints());
}
vtkSmartPointer<vtkKdTree> FreePolyData::getKdTree()
{
    return kdTree;
}

void FreePolyData::findClosestPoint(FreeVector &p, int &output)
{
    if(kdTree == NULL)
    {
        buildKdtree();
    }
    double closestPointDist;
    output = kdTree->FindClosestPoint(p.GetData(), closestPointDist);
}

void FreePolyData::findClosestPoint(FreeVector &p, FreeVector &output)
{
    int index;
    findClosestPoint(p, index);
    output = getPoint(index);
}

void FreePolyData::findClosestPoints(const FreeVector &p, double r, std::vector<int> &output)
{
    if(kdTree == NULL)
    {
        buildKdtree();
    }
    vtkSmartPointer<vtkIdList> result = vtkSmartPointer<vtkIdList>::New();
    kdTree->FindPointsWithinRadius(r, p.GetData(), result);
    for(int i = 0; i < result->GetNumberOfIds(); i++)
    {
        output.push_back(result->GetId(i));
    }
}

void FreePolyData::findClosestPoints(const FreeVector &p, double r, std::vector<FreeVector> &output)
{
    std::vector<int> indexs;
    findClosestPoints(p, r, indexs);
    for(int i = 0; i < indexs.size(); i++)
    {
        output.push_back(getPoint(indexs[i]));
    }
}

void FreePolyData::findCurveRangePoints(const std::vector<FreeVector>& curve, double r, std::vector<int> &output)
{
    std::vector<bool> mark(polyData->GetNumberOfPoints(), false);
    for(int i = 0; i < curve.size(); i++)
    {
        FreeVector p = curve[i];
        std::vector<int> tempPoints;
        findClosestPoints(p, r, tempPoints);
        for(int j = 0; j < tempPoints.size(); j++)
        {
            if(mark[tempPoints[j]])
            {
                continue;
            }
            mark[tempPoints[j]] = true;
            output.push_back(tempPoints[j]);
        }
    }
}

void FreePolyData::findCurveRangePoints(const std::vector<FreeVector> &curve, double r, std::vector<FreeVector> &output)
{
    std::vector<int> indexs;
    findCurveRangePoints(curve, r, indexs);
    output = getPoints(indexs);
}

void FreePolyData::buildNormal(int type)
{
    vtkSmartPointer<vtkPolyDataNormals> pdNormals =
        vtkSmartPointer<vtkPolyDataNormals>::New();
    pdNormals->SetInputData(polyData);
    if(type == 0)
    {
        pdNormals->SetComputePointNormals(1);
        pdNormals->SetComputeCellNormals(0);
    } else {
        pdNormals->SetComputeCellNormals(1); //关闭单元法向量计算
        pdNormals->SetComputePointNormals(0);
    }
    pdNormals->SetNonManifoldTraversal(false);
    pdNormals->SetSplitting(0);
    pdNormals->Update();
    polyData->DeepCopy(pdNormals->GetOutput());
}

bool FreePolyData::loadPolyDataSTL(std::string filePath)
{
    vtkSmartPointer<vtkSTLReader> dataReader = vtkSmartPointer<vtkSTLReader>::New();
    dataReader->SetFileName(filePath.c_str());
    dataReader->SetScalarTags(1);
    dataReader->Update();
    if(dataReader->GetOutput() != nullptr)
    {
        polyData->DeepCopy(dataReader->GetOutput());
    } else {
        return false;
    }
    return true;
}

void FreePolyData::savePolyDataSTL(std::string filePath)
{
    vtkSmartPointer<vtkSTLWriter> dataWriter = vtkSmartPointer<vtkSTLWriter>::New();
    dataWriter->SetFileName(filePath.c_str());
    dataWriter->SetInputData(polyData);
    dataWriter->Write();
}

void FreePolyData::loadPolyDataVTK(std::string filePath)
{
    vtkSmartPointer<vtkPolyDataReader> dataReader = vtkSmartPointer<vtkPolyDataReader>::New();
    dataReader->SetFileName(filePath.c_str());
    dataReader->Update();
    polyData->DeepCopy(dataReader->GetOutput());
}

void FreePolyData::savePolyDataVTK(std::string filePath)
{
    vtkSmartPointer<vtkPolyDataWriter> vtkWriter = vtkSmartPointer<vtkPolyDataWriter>::New();
    vtkWriter->SetInputData(polyData);
    vtkWriter->SetFileName(filePath.c_str());
    vtkWriter->Write();
}

FreeActorArray *FreePolyData::getActorArray()
{
    return actor;
}

void FreePolyData::clean()
{
    vtkNew<vtkCleanPolyData> cleanF;
    cleanF->SetInputData(polyData);
    cleanF->Update();
    polyData->DeepCopy(cleanF->GetOutput());
}

std::vector<std::vector<FreeVector> > FreePolyData::findAllBorder()
{
    std::vector<std::vector<FreeVector> > loops;
    vtkSmartPointer<vtkFeatureEdges> boundaryEdges =
            vtkSmartPointer<vtkFeatureEdges>::New();
    boundaryEdges->SetInputData(polyData);
    boundaryEdges->BoundaryEdgesOn();
    boundaryEdges->FeatureEdgesOff();
    boundaryEdges->ManifoldEdgesOff();
    boundaryEdges->NonManifoldEdgesOff();
    boundaryEdges->Update();
    vtkSmartPointer<vtkStripper> stripper =
            vtkSmartPointer<vtkStripper>::New();
    stripper->SetInputData(boundaryEdges->GetOutput());
    stripper->JoinContiguousSegmentsOn();
    stripper->Update();
    vtkSmartPointer<vtkCleanPolyData> cleanPolyData = vtkSmartPointer<vtkCleanPolyData>::New();
    cleanPolyData->SetInputData(stripper->GetOutput());
    cleanPolyData->Update();
    for(int i = 0; i < cleanPolyData->GetOutput()->GetNumberOfCells(); i++)
    {
        vtkCell* cell = cleanPolyData->GetOutput()->GetCell(i);
        std::vector<FreeVector> loop;
        for(int j = 0; j < cell->GetPoints()->GetNumberOfPoints(); j++)
        {
            double* ver = cell->GetPoints()->GetPoint(j);
            loop.push_back(FreeVector(ver));
        }
        if(loop.size() > 0)
        {
            loops.push_back(loop);
        }
    }
    return loops;

}

std::vector<FreeVector> FreePolyData::findNearestBorder(FreeVector p)
{
    vtkSmartPointer<vtkFeatureEdges> boundaryEdges =
            vtkSmartPointer<vtkFeatureEdges>::New();
    boundaryEdges->SetInputData(polyData);
    boundaryEdges->BoundaryEdgesOn();
    boundaryEdges->FeatureEdgesOff();
    boundaryEdges->ManifoldEdgesOff();
    boundaryEdges->NonManifoldEdgesOff();
    boundaryEdges->Update();
    vtkSmartPointer<vtkStripper> stripper =
            vtkSmartPointer<vtkStripper>::New();
    stripper->SetInputData(boundaryEdges->GetOutput());
    stripper->JoinContiguousSegmentsOn();
    stripper->Update();
    vtkSmartPointer<vtkCleanPolyData> cleanPolyData = vtkSmartPointer<vtkCleanPolyData>::New();
    cleanPolyData->SetInputData(stripper->GetOutput());
    cleanPolyData->Update();

    auto cellLocator = vtkSmartPointer<vtkCellLocator>::New();
    cellLocator->SetDataSet(cleanPolyData->GetOutput());
    cellLocator->BuildLocator();

    auto assistCell = vtkSmartPointer<vtkGenericCell>::New();
    double closestPoint[3];//the coordinates of the closest point will be returned here
    double closestPointDist2; //the squared distance to the closest point will be returned here
    vtkIdType cellId; //the cell id of the cell containing the closest point will be returned here
    int subId;
    cellLocator->FindClosestPoint(p.GetData(), closestPoint, assistCell, cellId, subId, closestPointDist2);
    vtkCell* cell = cleanPolyData->GetOutput()->GetCell(cellId);
    std::vector<FreeVector> loop;
    for(int j = 0; j < cell->GetPoints()->GetNumberOfPoints(); j++)
    {
        double* ver = cell->GetPoints()->GetPoint(j);
        loop.push_back(FreeVector(ver));
    }
    return loop;
}

std::vector<FreeVector> FreePolyData::findMaxBorder()
{
    vtkSmartPointer<vtkFeatureEdges> boundaryEdges =
            vtkSmartPointer<vtkFeatureEdges>::New();
    boundaryEdges->SetInputData(polyData);
    boundaryEdges->BoundaryEdgesOn();
    boundaryEdges->FeatureEdgesOff();
    boundaryEdges->ManifoldEdgesOff();
    boundaryEdges->NonManifoldEdgesOff();
    boundaryEdges->Update();
    vtkSmartPointer<vtkStripper> stripper =
            vtkSmartPointer<vtkStripper>::New();
    stripper->SetInputData(boundaryEdges->GetOutput());
    stripper->JoinContiguousSegmentsOn();
    stripper->Update();
    vtkSmartPointer<vtkCleanPolyData> cleanPolyData = vtkSmartPointer<vtkCleanPolyData>::New();
    cleanPolyData->SetInputData(stripper->GetOutput());
    cleanPolyData->Update();

    std::vector<FreeVector> outputPoints;
    for(int i = 0; i < cleanPolyData->GetOutput()->GetNumberOfCells(); i++)
    {
        vtkCell* cell = cleanPolyData->GetOutput()->GetCell(i);
        if(outputPoints.size() < cell->GetPoints()->GetNumberOfPoints())
        {
            outputPoints.clear();
            for(int j = 0; j < cell->GetPoints()->GetNumberOfPoints(); j++)
            {
                double* ver = cell->GetPoints()->GetPoint(j);
                outputPoints.push_back(FreeVector(ver));
            }
        }
    }
    return outputPoints;
}

void FreePolyData::reverseSurface()
{
    for(int i = 0; i < polyData->GetNumberOfCells(); i++)
    {
        polyData->ReverseCell(i);
    }
}

std::vector<int> FreePolyData::getAdjPoints(int id)
{
    vtkSmartPointer<vtkIdList> idLists = vtkSmartPointer<vtkIdList>::New();
    polyData->GetPointCells(id, idLists);
    std::set<int> neighPoints;
    for(int i = 0; i < idLists->GetNumberOfIds(); i++)
    {
        vtkCell* cell = polyData->GetCell(idLists->GetId(i));
        int v1 = cell->GetPointId(0);
        int v2 = cell->GetPointId(1);
        int v3 = cell->GetPointId(2);
        if(v1 != i)
        {
            neighPoints.insert(v1);
        }
        if(v2 != i)
        {
            neighPoints.insert(v2);
        }
        if(v3 != i)
        {
            neighPoints.insert(v3);
        }

    }
    std::vector<int> adjs;
    for(auto it:neighPoints)
    {
        adjs.push_back(it);
    }
    return adjs;
}

vtkSmartPointer<vtkMatrix4x4> FreePolyData::getMatrix()
{
    return matrix;
}

void FreePolyData::setMatrix(vtkSmartPointer<vtkMatrix4x4> newMatrix)
{
    matrix->DeepCopy(newMatrix);
}

void FreePolyData::setMatrix(const FreeVector &nx, const FreeVector &ny, const FreeVector &nz, const FreeVector &center)
{
    matrix->SetElement(0, 0, nx[0]); matrix->SetElement(1, 0, nx[1]); matrix->SetElement(2, 0, nx[2]);
    matrix->SetElement(0, 1, ny[0]); matrix->SetElement(1, 1, ny[1]); matrix->SetElement(2, 1, ny[2]);
    matrix->SetElement(0, 2, nz[0]); matrix->SetElement(1, 2, nz[1]); matrix->SetElement(2, 2, nz[2]);
    matrix->SetElement(0, 3, center[0]); matrix->SetElement(1, 3, center[1]); matrix->SetElement(2, 3, center[2]);
}

void FreePolyData::getMatrix(FreeVector &nx, FreeVector &ny, FreeVector &nz, FreeVector &center)
{
    nx[0] = matrix->GetElement(0, 0); nx[1] = matrix->GetElement(1, 0); nx[2] = matrix->GetElement(2, 0);
    ny[0] = matrix->GetElement(0, 1); ny[1] = matrix->GetElement(1, 1); ny[2] = matrix->GetElement(2, 1);
    nz[0] = matrix->GetElement(0, 2); nz[1] = matrix->GetElement(1, 2); nz[2] = matrix->GetElement(2, 2);
    center[0] = matrix->GetElement(0, 3); center[1] = matrix->GetElement(1, 3); center[2] = matrix->GetElement(2, 3);
}

FreeVector FreePolyData::getXAxis()
{
    FreeVector nx;
    nx[0] = matrix->GetElement(0, 0); nx[1] = matrix->GetElement(1, 0); nx[2] = matrix->GetElement(2, 0);
    return nx;
}

FreeVector FreePolyData::getYAxis()
{
    FreeVector ny;
    ny[0] = matrix->GetElement(0, 1); ny[1] = matrix->GetElement(1, 1); ny[2] = matrix->GetElement(2, 1);
    return ny;
}

FreeVector FreePolyData::getZAxis()
{
    FreeVector nz;
    nz[0] = matrix->GetElement(0, 2); nz[1] = matrix->GetElement(1, 2); nz[2] = matrix->GetElement(2, 2);
    return nz;
}

FreeVector FreePolyData::getCenter()
{
    FreeVector center;
    center[0] = matrix->GetElement(0, 3); center[1] = matrix->GetElement(1, 3); center[2] = matrix->GetElement(2, 3);
    return center;
}

void FreePolyData::meshToTriangle()
{
    vtkNew<vtkTriangleFilter> triangleFilter;
    triangleFilter->SetInputData(polyData);
    triangleFilter->Update();
    polyData->DeepCopy(triangleFilter->GetOutput());
}

int FreePolyData::pointMappingToPolyData(const FreeVector &p, const FreeVector &n, MAP_TYPE mapType, FreeVector &outPut)
{
    FreeVector p1 = p;
    FreeVector p2 = p;
    p1.move(n, -100000);
    p2.move(n, 100000);
    vtkSmartPointer<vtkPoints> intersectPoints = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkIdList> intersectCells = vtkSmartPointer<vtkIdList>::New();
    if(obbTree == NULL)
    {
        buildOBBTree();
    }
    obbTree->IntersectWithLine(p1.GetData(), p2.GetData(), intersectPoints, intersectCells);

    int outPutID = -1;
    double dist = 10000000;
    for(int i = 0; i < intersectPoints->GetNumberOfPoints(); i++)
    {
        double resP[3];
        intersectPoints->GetPoint(i, resP);
        int cellID = intersectCells->GetId(i);
        FreeVector theP(resP);

        if(mapType == DIST_MIN) // 所有交点
        {
            double d = theP.point3Distance(p);
            if(d < dist)
            {
                dist = d;
                outPut = theP;
                outPutID = cellID;
            }
        } else if(mapType == DIST_MIN_LINEFRONT) { // 投影点前方的
            FreeVector n1 = p2 - p;
            FreeVector n2 = theP - p;
            if(n1*n2 > 0)
            {
                double d = theP.point3Distance(p);
                if(d < dist)
                {
                    dist = d;
                    outPut = theP;
                    outPutID = cellID;
                }
            }
        } else if(mapType == DIST_MIN_LINEFRONT_CELLFRONT){
            FreeVector n1 = p2 - p;
            FreeVector n2 = theP - p;
            FreeVector cellNormal = getCellNormal(cellID);
            if(n1*n2 > 0 && cellNormal*n2 < 0)
            {
                double d = theP.point3Distance(p);
                if(d < dist)
                {
                    dist = d;
                    outPut = theP;
                    outPutID = cellID;
                }
            }
        } else if(mapType == DIST_MIN_LINEFRONT_CELLFRONT) {
            FreeVector n1 = p2 - p;
            FreeVector n2 = theP - p;
            FreeVector cellNormal = getCellNormal(cellID);
            if(n1*n2 > 0 && cellNormal*n2 > 0)
            {
                double d = theP.point3Distance(p);
                if(d < dist)
                {
                    dist = d;
                    outPut = theP;
                    outPutID = cellID;
                }
            }
        }
    }
    return outPutID;
}

int FreePolyData::pointMappingToPolyData(const FreeVector &p, const FreeVector &n, double range, FreeVector &outPut)
{
    if(kdTree == NULL)
    {
        buildKdtree();
    }
    FreeVector p1 = p;
    FreeVector p2 = p;
    p1.move(n, -100);
    p2.move(n, 100);
    vtkSmartPointer<vtkIdList> result = vtkSmartPointer<vtkIdList>::New();
    kdTree->FindPointsWithinRadius(range, p.GetData(), result);
    std::vector<bool> pointMark(polyData->GetNumberOfPoints(), false);
    for(int i = 0; i < result->GetNumberOfIds(); i++)
    {
        pointMark[result->GetId(i)] = true;
    }

    for(int i = 0; i < polyData->GetNumberOfCells(); i++)
    {
        vtkCell* cell = polyData->GetCell(i);
        int v1 = cell->GetPointId(0);
        int v2 = cell->GetPointId(1);
        int v3 = cell->GetPointId(2);
        if(pointMark[v1]||pointMark[v2]||pointMark[v3])
        {

            double t;
            double intersectionCoordinates[3];
            double parametricCoordinates[3];
            int subId;
            int res = cell->IntersectWithLine(p1.GetData(), p2.GetData(), 0.0001, t, intersectionCoordinates, parametricCoordinates, subId);
            if(res == 1)
            {
                outPut = FreeVector(intersectionCoordinates[0], intersectionCoordinates[1], intersectionCoordinates[2]);
                return i;
            }

        }

    }
    return -1;
}

void FreePolyData::setBufferPolyData(vtkSmartPointer<vtkPolyData> newBufferPolyData)
{
    bufferMutex.lock();
    bufferPolyData = newBufferPolyData;
    bufferMutex.unlock();
}

void FreePolyData::swapBufferPolyData()
{
    bufferMutex.lock();
    if(bufferPolyData)
    {
        polyData->DeepCopy(bufferPolyData);
        bufferPolyData = NULL;
    }
    bufferMutex.unlock();
}

vtkPolyData* FreePolyData::getPolyData()
{
    return polyData;
}


        鼠标交互类,VTK提供了鼠标交互事件,已经替我们完成了轨迹器三维旋转、VTK鼠标交互的虚函数在vtkInteractorStyleTrackballCamera中,所以我们继承这个类,然后将鼠标事件传递给我们自己写的FreeModelView类:

#ifndef FREEINTERATORSTYLETRACKBALLCAMERA_H
#define FREEINTERATORSTYLETRACKBALLCAMERA_H
#include "FreeWorld_global.h"
#include <vtkInteractorStyleTrackballCamera.h>

class FreeModelView;
/**
 * @brief The FreeInteratorStyleTrackballCamera class
 * 重写鼠标轨迹球交互事件
 */
class FREEWORLD_EXPORT FreeInteratorStyleTrackballCamera : public vtkInteractorStyleTrackballCamera
{
public:
    /**
     * @brief New 无说明
     * @return
     */
    static FreeInteratorStyleTrackballCamera* New();
    vtkTypeMacro(FreeInteratorStyleTrackballCamera, vtkInteractorStyleTrackballCamera);
    /**
     * @brief FreeInteratorStyleTrackballCamera
     * 构造函数
     */
    FreeInteratorStyleTrackballCamera();
    /**
     * @brief setFreeModelView 设置图形窗口,需要将交互事件传递给图形环境进行处理
     * @param modelView 图形环境
     */
    void setFreeModelView(FreeModelView* modelView);
    /**
     * @brief OnMouseMove 鼠标移动事件
     */
    virtual void OnMouseMove();
    /**
     * @brief OnLeftButtonDown 左键按下事件
     */
    virtual void OnLeftButtonDown();
    /**
     * @brief OnLeftButtonUp 左键抬起
     */
    virtual void OnLeftButtonUp();
    /**
     * @brief OnMiddleButtonDown 滚轮按下
     */
    virtual void OnMiddleButtonDown();
    /**
     * @brief OnMiddleButtonUp 滚轮抬起
     */
    virtual void OnMiddleButtonUp();
    /**
     * @brief OnRightButtonDown 右键按下
     */
    virtual void OnRightButtonDown();
    /**
     * @brief OnRightButtonUp 右键抬起
     */
    virtual void OnRightButtonUp();
    /**
     * @brief OnMouseWheelForward 滚轮向前滚动
     */
    virtual void OnMouseWheelForward();
    /**
     * @brief OnMouseWheelBackward 滚轮向后滚动
     */
    virtual void OnMouseWheelBackward();
    /**
     * @brief OnKeyPress 键盘按下
     */
    virtual void OnKeyPress();
    /**
     * @brief OnKeyRelease 键盘抬起
     */
    virtual void OnKeyRelease();
    /**
     * @brief setIsEnableMouseMove 设置鼠标移动是否可用
     * @param newIsEnableMouseMove
     */
    void setIsEnableMouseMove(bool newIsEnableMouseMove);
    /**
     * @brief setIsEnableLeftButtonDown 设置左键按下是否可用
     * @param newIsEnableLeftButtonDown
     */
    void setIsEnableLeftButtonDown(bool newIsEnableLeftButtonDown);
    /**
     * @brief setIsEnableLeftButtonUp 设置左键抬起是否可用
     * @param newIsEnableLeftButtonUp
     */
    void setIsEnableLeftButtonUp(bool newIsEnableLeftButtonUp);
    /**
     * @brief setIsEnableMiddleButtonDown 设置滚轮按下是否可用
     * @param newIsEnableMiddleButtonDown
     */
    void setIsEnableMiddleButtonDown(bool newIsEnableMiddleButtonDown);
    /**
     * @brief setIsEnableMiddleButtonUp 设置滚轮抬起是否可用
     * @param newIsEnableMiddleButtonUp
     */
    void setIsEnableMiddleButtonUp(bool newIsEnableMiddleButtonUp);
    /**
     * @brief setIsEnableRightButtonDown 设置右键按下是否可用
     * @param newIsEnableRightButtonDown
     */
    void setIsEnableRightButtonDown(bool newIsEnableRightButtonDown);
    /**
     * @brief setIsEnableRightButtonUp 设置右键抬起是否可用
     * @param newIsEnableRightButtonUp
     */
    void setIsEnableRightButtonUp(bool newIsEnableRightButtonUp);
    /**
     * @brief setIsEnableMouseWheelForward 设置滚轮向前是否可用
     * @param newIsEnableMouseWheelForward
     */
    void setIsEnableMouseWheelForward(bool newIsEnableMouseWheelForward);
    /**
     * @brief setIsEnableMouseWheelBackward 设置滚轮向后是否可用
     * @param newIsEnableMouseWheelBackward
     */
    void setIsEnableMouseWheelBackward(bool newIsEnableMouseWheelBackward);
    /**
     * @brief setIsEnableKeyPress 设置键盘按下是否可用
     * @param newIsEnableKeyPress
     */
    void setIsEnableKeyPress(bool newIsEnableKeyPress);
    /**
     * @brief setIsEnableKeyRelease 设置键盘抬起是否可用
     * @param newIsEnableKeyRelease
     */
    void setIsEnableKeyRelease(bool newIsEnableKeyRelease);
    /**
     * @brief setLeftRightSwap 设置鼠标左右键是否进行交换,通过设置此参数实现三维旋转使用左键,还是右键,默认右键旋转
     * @param newLeftRightSwap false 左键旋转,true右键旋转
     */
    void setLeftRightSwap(bool newLeftRightSwap);

private:
    FreeModelView* modelView;
    bool isEnableMouseMove;
    bool isEnableLeftButtonDown;
    bool isEnableLeftButtonUp;
    bool isEnableMiddleButtonDown;
    bool isEnableMiddleButtonUp;
    bool isEnableRightButtonDown;
    bool isEnableRightButtonUp;
    bool isEnableMouseWheelForward;
    bool isEnableMouseWheelBackward;
    bool isEnableKeyPress;
    bool isEnableKeyRelease;
private:
    bool leftRightSwap; // 左右键是否交换
};
#include "FreeInteratorStyleTrackballCamera.h"
#include <vtkObjectFactory.h>
#include "FreeModelView.h"

vtkStandardNewMacro(FreeInteratorStyleTrackballCamera);
FreeInteratorStyleTrackballCamera::FreeInteratorStyleTrackballCamera()
{
    modelView = NULL;
    isEnableMouseMove = true;
    isEnableLeftButtonDown = true;
    isEnableLeftButtonUp = true;
    isEnableMiddleButtonDown = true;
    isEnableMiddleButtonUp = true;
    isEnableRightButtonDown = true;
    isEnableRightButtonUp = true;
    isEnableMouseWheelForward = true;
    isEnableMouseWheelBackward = true;
    isEnableKeyPress = true;
    isEnableKeyRelease = true;
    leftRightSwap = true;
}

void FreeInteratorStyleTrackballCamera::setFreeModelView(FreeModelView *modelView)
{
    this->modelView = modelView;
}

void FreeInteratorStyleTrackballCamera::OnMouseMove()
{
    if(isEnableMouseMove)
    {
        vtkInteractorStyleTrackballCamera::OnMouseMove();
    }

    if(modelView == NULL)
    {
        return;
    }
    modelView->OnMouseMove();
}

void FreeInteratorStyleTrackballCamera::OnLeftButtonDown()
{
    if(isEnableLeftButtonDown)
    {
        if(leftRightSwap == false)
        {
            vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
        }
    }

    if(modelView == NULL)
    {
        return;
    }
    modelView->OnLeftButtonDown();
}

void FreeInteratorStyleTrackballCamera::OnLeftButtonUp()
{
    if(isEnableLeftButtonUp)
    {
        if(leftRightSwap == false)
        {
            vtkInteractorStyleTrackballCamera::OnLeftButtonUp();
        }
    }

    if(modelView == NULL)
    {
        return;
    }
    modelView->OnLeftButtonUp();
}

void FreeInteratorStyleTrackballCamera::OnMiddleButtonDown()
{
    if(isEnableMiddleButtonDown)
    {
        vtkInteractorStyleTrackballCamera::OnMiddleButtonDown();
    }

    if(modelView == NULL)
    {
        return;
    }
    modelView->OnMiddleButtonDown();
}

void FreeInteratorStyleTrackballCamera::OnMiddleButtonUp()
{
    if(isEnableMiddleButtonUp)
    {
        vtkInteractorStyleTrackballCamera::OnMiddleButtonUp();
    }

    if(modelView == NULL)
    {
        return;
    }
    modelView->OnMiddleButtonUp();
}

void FreeInteratorStyleTrackballCamera::OnRightButtonDown()
{
    if(isEnableRightButtonDown)
    {
        if(leftRightSwap)
        {
            vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
        }
    }
    if(modelView == NULL)
    {
        return;
    }
    modelView->OnRightButtonDown();
}

void FreeInteratorStyleTrackballCamera::OnRightButtonUp()
{
    if(isEnableRightButtonUp)
    {
        if(leftRightSwap)
        {
            vtkInteractorStyleTrackballCamera::OnLeftButtonUp();
        }
    }

    if(modelView == NULL)
    {
        return;
    }
    modelView->OnRightButtonUp();
}

void FreeInteratorStyleTrackballCamera::OnMouseWheelForward()
{
    if(isEnableMouseWheelForward)
    {
        vtkInteractorStyleTrackballCamera::OnMouseWheelForward();
    }
    if(modelView == NULL)
    {
        return;
    }
    modelView->OnMouseWheelForward();
}

void FreeInteratorStyleTrackballCamera::OnMouseWheelBackward()
{
    if(isEnableMouseWheelBackward)
    {
        vtkInteractorStyleTrackballCamera::OnMouseWheelBackward();
    }
    if(modelView == NULL)
    {
        return;
    }
    modelView->OnMouseWheelBackward();
}

void FreeInteratorStyleTrackballCamera::OnKeyPress()
{
    if(isEnableKeyPress == false)
    {
        return;
    }
    if(modelView == NULL)
    {
        return;
    }
    modelView->OnKeyPress();
}

void FreeInteratorStyleTrackballCamera::OnKeyRelease()
{
    if(isEnableKeyRelease == false)
    {
        return;
    }
    if(modelView == NULL)
    {
        return;
    }
    modelView->OnKeyRelease();
}

void FreeInteratorStyleTrackballCamera::setIsEnableMouseMove(bool newIsEnableMouseMove)
{
    isEnableMouseMove = newIsEnableMouseMove;
}

void FreeInteratorStyleTrackballCamera::setIsEnableLeftButtonDown(bool newIsEnableLeftButtonDown)
{
    isEnableLeftButtonDown = newIsEnableLeftButtonDown;
}

void FreeInteratorStyleTrackballCamera::setIsEnableLeftButtonUp(bool newIsEnableLeftButtonUp)
{
    isEnableLeftButtonUp = newIsEnableLeftButtonUp;
}

void FreeInteratorStyleTrackballCamera::setIsEnableMiddleButtonDown(bool newIsEnableMiddleButtonDown)
{
    isEnableMiddleButtonDown = newIsEnableMiddleButtonDown;
}

void FreeInteratorStyleTrackballCamera::setIsEnableMiddleButtonUp(bool newIsEnableMiddleButtonUp)
{
    isEnableMiddleButtonUp = newIsEnableMiddleButtonUp;
}

void FreeInteratorStyleTrackballCamera::setIsEnableRightButtonDown(bool newIsEnableRightButtonDown)
{
    isEnableRightButtonDown = newIsEnableRightButtonDown;
}

void FreeInteratorStyleTrackballCamera::setIsEnableRightButtonUp(bool newIsEnableRightButtonUp)
{
    isEnableRightButtonUp = newIsEnableRightButtonUp;
}

void FreeInteratorStyleTrackballCamera::setIsEnableMouseWheelForward(bool newIsEnableMouseWheelForward)
{
    isEnableMouseWheelForward = newIsEnableMouseWheelForward;
}

void FreeInteratorStyleTrackballCamera::setIsEnableMouseWheelBackward(bool newIsEnableMouseWheelBackward)
{
    isEnableMouseWheelBackward = newIsEnableMouseWheelBackward;
}

void FreeInteratorStyleTrackballCamera::setIsEnableKeyPress(bool newIsEnableKeyPress)
{
    isEnableKeyPress = newIsEnableKeyPress;
}

void FreeInteratorStyleTrackballCamera::setIsEnableKeyRelease(bool newIsEnableKeyRelease)
{
    isEnableKeyRelease = newIsEnableKeyRelease;
}

void FreeInteratorStyleTrackballCamera::setLeftRightSwap(bool newLeftRightSwap)
{
    leftRightSwap = newLeftRightSwap;
}

本章到此结束,公开的代码中会有一些没有讲述的类,后续我会慢慢给大家一一讲解,如有问题疑问请留言。

FreeWorld源码安装配置下载链接请参考本专题第六节。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
VTK(Visualization Toolkit)是一个用于3D数据可视化和图形处理的开源软件库。如果你想将VTK封装为窗口,可以使用VTKQt渲染部分。 以下是VTK封装为窗口的一些基本步骤: 1. 创建一个Qt应用程序并添加VTK依赖项。 2. 在应用程序窗口中添加一个QVTKWidget部件。 3. 创建一个vtkRenderWindow对象,将其设置为QVTKWidget部件的渲染窗口。 4. 创建一个vtkRenderer对象,并将其添加到vtkRenderWindow中。 5. 可以使用vtkActor和vtkMapper等对象创建一个3D场景。 6. 将创建的vtkActor和vtkMapper对象添加到vtkRenderer对象中。 7. 调用vtkRenderWindow的Render方法来呈现3D场景。 以下是一个简单的示例代码,演示如何将VTK封装为窗口: ```python import vtk from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QGridLayout from PyQt5.QtWidgets import QFrame from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor class MainWindow(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.frame = QFrame() self.vl = QGridLayout() self.vtkWidget = QVTKRenderWindowInteractor(self.frame) self.vl.addWidget(self.vtkWidget) self.ren = vtk.vtkRenderer() self.vtkWidget.GetRenderWindow().AddRenderer(self.ren) self.iren = self.vtkWidget.GetRenderWindow().GetInteractor() # Create source source = vtk.vtkConeSource() source.SetHeight(3.0) source.SetRadius(1.0) source.SetResolution(10) # Create mapper mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(source.GetOutputPort()) # Create actor actor = vtk.vtkActor() actor.SetMapper(mapper) # Add actor to the scene self.ren.AddActor(actor) self.ren.ResetCamera() self.vtkWidget.Render() self.setCentralWidget(self.frame) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() app.exec_() ``` 这段代码创建了一个带有一个VTK场景的Qt窗口,其中场景由一个圆锥体组成。你可以根据自己的需要修改场景内容和渲染方式。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

《雨声》

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值