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 ¢er)
{
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 ¢er)
{
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源码安装配置下载链接请参考本专题第六节。