使用vtk库创建三维空间中的点
- 引言
- 开发环境
- 示例一
- 项目结构
- 实现代码
- 运行效果
- 示例二
- 项目结构
- 实现代码
- 运行效果
- 总结
引言
本文仅适合初学者。
本文不提供vtk动态库的生成,以及在QtCreator中的引进vtk时的配置。
本文先由示例一开始,然后再在示例一的基础上进行改进,最后呈现出满天星的效果。其中示例一仅是在三维空间中展示一些点,即使用vtk创建点;示例二在示例一基础之上,进行改动。最后呈现的效果如下:
开发环境
使用vtk9.2的库,在QtCreator中创建空项目。其中QtCreator使用的是4.11.2,Qt的版本是5.14.2。
示例一
项目结构
实现代码
由于创建的空项目,所以项目创建之后只有一个空的.pro文件,需要自己编写pro文件,pro文件的内容如下:
testVtkPoints.pro
QT += core #gui
#greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11 vtk9.2
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
SOUPDIR = $$PWD/../../SOUPdependency
vtk9.2 {
contains(QT_ARCH, x86_64) {
include($$SOUPDIR/vtk-9.2/vtk-9.2.pri)
} else {
include($$SOUPDIR/vtk-9.2-2017-omp-win32/vtk-9.2.pri)
}
DEFINES += vtkEventDataButton3D=vtkEventDataDevice3D
DEFINES += vtkEventDataMove3D=vtkEventDataDevice3D
}
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
main.cpp
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyData.h>
#include<vtkCamera.h>
//注意:不加下面的初始化模块,程序运行时不会有窗口展现(啥也没有)
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);//渲染
VTK_MODULE_INIT(vtkInteractionStyle);//交互样式
VTK_MODULE_INIT(vtkRenderingFreeType)//文本图像
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2)//体素
int main(int argc,char*argv[])
{
double dPoints[8][3] = {{0.2,2.1,3.1},{1.0,2.6,7.0},{5.0,9.2,5.0},{21.0,3.0,4.5},{5.6,7.2,4.9},{4.5,6.3,9.0},{13.0,3.4,5.6},{26.0,7.8,5.6}};
vtkSmartPointer<vtkPolyData> polyData =vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> cellArrays = vtkSmartPointer<vtkCellArray>::New();
cellArrays->InsertNextCell(8);//指定点的个数
for(int i = 0; i < 8;++i)
{
points->InsertPoint(i,dPoints[i]);
cellArrays->InsertCellPoint(i);
}
polyData->SetPoints(points);
polyData->SetVerts(cellArrays);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polyData);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> render = vtkSmartPointer<vtkRenderer>::New();
render->AddActor(actor);
render->ResetCamera();
render->SetBackground(0.12,0.56,1);
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(render);
renderWindow->SetSize(600,500);
renderWindow->Render();
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
interactor->Initialize();
interactor->Start();
return 0;
}
运行效果
由于视频制作的时候背景上出现了许多白色斑点,故而上面的视频呈现的效果不是很好。
示例二
由于示例一呈现的效果,让我想起了漫天星星的感觉,故而想做个漫天星星来看看。在上面的示例一的基础上,进行改进。
项目结构
其结构和示例一一样。
实现代码
其中pro文件不变,改变的是main.cpp.
main.cpp
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
//注意:不加下面的初始化模块,程序运行时不会有窗口展现(啥也没有)
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);//渲染
VTK_MODULE_INIT(vtkInteractionStyle);//交互样式
VTK_MODULE_INIT(vtkRenderingFreeType)//文本图像
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2)//体素
vtkSmartPointer<vtkActor> createActor(int nCount,double pPointSet[][3],double dPointSize = 1.0)
{
vtkSmartPointer<vtkPolyData> polyData =vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> cellArrays = vtkSmartPointer<vtkCellArray>::New();
cellArrays->InsertNextCell(nCount);//指定点的个数
for(int i = 0; i < nCount;++i)
{
points->InsertPoint(i,pPointSet[i]);
cellArrays->InsertCellPoint(i);
}
polyData->SetPoints(points);
polyData->SetVerts(cellArrays);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polyData);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetPointSize(dPointSize);
return actor;
}
int main(int argc,char*argv[])
{
double dPoints[8][3] = {{0.2,2.1,3.1},{1.0,2.6,7.0},{5.0,9.2,5.0},{21.0,3.0,4.5},{5.6,7.2,4.9},{4.5,6.3,9.0},{13.0,3.4,5.6},{26.0,7.8,5.6}};
vtkSmartPointer<vtkActor> actor = createActor(8,dPoints,2);
double dPoint1s[8][3] = {{5.2,2.1,3.1},{1.0,22.6,7.0},{5.0,19.2,5.0},{11.0,3.0,4.5},{5.6,23.2,4.9},{4.5,12.3,9.0},{13.0,6.4,5.6},{6.0,7.8,5.6}};
vtkSmartPointer<vtkActor> actor1 = createActor(8,dPoint1s,3);
double dPoint2s[24][3] = {{25.2,2.1,3.1},{12.0,22.6,7.0},{5.0,1.2,5.0},{11.0,3.0,5.5},{5.6,33.2,4.9},{4.5,22.3,9.0},{13.0,2.4,5.6},{6.0,5.8,5.6},
{5.2,2.1,13.1},{1.0,2.6,7.0},{5.0,19.2,15.0},{11.0,13.0,4.5},{5.6,2.2,42.9},{4.5,11.3,23.0},{13.0,6.3,5.6},{6.0,7.8,5.6},
{5.2,12.1,3.1},{1.0,32.6,7.0},{5.0,9.2,5.0},{11.0,3.0,14.5},{5.6,23.2,4.9},{4.5,12.3,9.0},{13.0,6.4,5.6},{6.0,9.8,5.6}};
vtkSmartPointer<vtkActor> actor2 = createActor(24,dPoint2s);
vtkSmartPointer<vtkRenderer> render = vtkSmartPointer<vtkRenderer>::New();
render->AddActor(actor);
render->AddActor(actor1);
render->AddActor(actor2);
render->ResetCamera();
render->SetBackground(0.12,0.56,1);
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(render);
renderWindow->SetSize(600,500);
renderWindow->Render();
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
interactor->Initialize();
interactor->Start();
return 0;
}
运行效果
没有插入太多的点,动图这里就不再展示。
总结
以对象actor为准,向渲染器中加入对象actor,一个渲染器中可以加入多个对象,每一个对象可以通过其属性设置其颜色,大小等。数据源经映射器映射,为对象中设置映射器。实际上渲染窗口最终展示的便为我们创建的对象。此些文本,为自己理解。