初学vtk,很多都不懂,于是开始探索之路。这篇主要是vtk绘制直线的示例。
本文通过集中不同的方式,来创建三位空间中的直线,由单一的直线到多条直线。
本人使用的是QtCreator开发的vtk相关的程序。
QtCreator的版本:
vtk库的版本:vtk9.2
不同的vtk版本可能代码中会相差一些,本文只适用上述指定的开发环境下的编码运行。
这里创建的是其它项目-》Empty qmake Project项目,即空项目。
创建完空项目之后,编写pro文件,其pro文件中的内容如下:
QT += core #引入qt的核心模块,以防需要使用
CONFIG += c++11 vtk9.2 #使用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 += \
mian.cpp
#配置vtk的环境
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
环境配置略有不同,因为这里引入了pri文件,vtk的环境配置,需要自己自行配置。这里不提供。
编写完pro文件之后,添加新文件main.cpp。
main.cpp的代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//注意:不加下面的初始化模块,程序运行时不会有窗口展现(啥也没有)
#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[])
{
//vtkLineSource直接通过设置直线的两个端点(point1和point2)来确定一条直线。
// Create two points, P0 and P1
double p0[3] = {1.0, 0.0, 0.0};
double p1[3] = {0.0, 1.0, 0.0};
vtkNew<vtkLineSource> lineSource;
lineSource->SetPoint1(p0);
lineSource->SetPoint2(p1);
lineSource->Update();
// Visualize
vtkNew<vtkNamedColors> colors;
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputData(lineSource->GetOutput());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->SetLineWidth(4);
actor->GetProperty()->SetColor(colors->GetColor3d("Peacock").GetData());
vtkNew<vtkRenderer> renderer;
renderer->SetBackground(colors->GetColor3d("Silver").GetData());
renderer->AddActor(actor);
renderer->GetActiveCamera()->SetPosition(1, 1, 1);//设置相机的位置
renderer->GetActiveCamera()->SetFocalPoint(0, 0, 0);//设置相机的焦距,默认的焦距为(0,0,0)
renderer->ResetCamera();
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("Line");
renderWindow->SetSize(600, 400);
renderWindow->SetPosition(800,400);//设置渲染窗口再屏幕坐标中的位置
renderWindow->Render();
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return 0;
}
示例二也是在QtCreator下创建的空项目,其创建的项目的方式上面也有提到,这里不做讲解。创建好空项目之后,需要编写pro文件,同时也需要添加新文件main.cpp,下面直接上代码。
pro文件内容
QT += core
#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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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[2][3] = {{3.4,2.3,8.0},{12.0,34.5,6.7}};
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> cellArray = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
cellArray->InsertNextCell(2);
for(int i = 0;i < 2;++i)
{
points->InsertPoint(i,dPoints[i]);
cellArray->InsertCellPoint(i);
}
polyData->SetPoints(points);
polyData->SetLines(cellArray);
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polyData);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(0.94,0.502,0.502);
vtkSmartPointer<vtkRenderer> render = vtkSmartPointer<vtkRenderer>::New();
render->AddActor(actor);
render->SetBackground(0,0,0);
render->ResetCamera();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(render);
renderWindow->SetSize(400,350);
renderWindow->Render();
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
interactor->Initialize();
interactor->Start();
return 0;
}
该示例中采用vtkLine创建直线。pro文件中的内容与上面pro文件中的内容相同。下面直接上代码:
main.cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2)//渲染
VTK_MODULE_INIT(vtkInteractionStyle)//交互样式
VTK_MODULE_INIT(vtkRenderingFreeType)//文本图像
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2)//体素
vtkSmartPointer<vtkPolyData> createPolyDataByPointArray()
{
double dPoints[2][3] = {{3.4,2.3,8.0},{12.0,34.5,6.7}};
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> cellArray = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
cellArray->InsertNextCell(2);
for(int i = 0;i < 2;++i)
{
points->InsertPoint(i,dPoints[i]);
cellArray->InsertCellPoint(i);
}
polyData->SetPoints(points);
polyData->SetLines(cellArray);
return polyData;
}
vtkSmartPointer<vtkPolyData> createPolyDataByVtkLineSource()
{
double dPoints[][3] = {{2.3,4.6,8.6},{23.0,6.5,7.6}};
vtkSmartPointer<vtkLineSource> lineSource = vtkSmartPointer<vtkLineSource>::New();
lineSource->SetPoint1(dPoints[0]);
lineSource->SetPoint2(dPoints[1]);
lineSource->Update();
return lineSource->GetOutput();
}
vtkSmartPointer<vtkPolyData> createPolyDataByVtkLine()
{
double dPoints[2][3] = {{3.2,6.7,8.9},{12.3,4.6,8.9}};
vtkSmartPointer<vtkPoints> point = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkLine> line = vtkSmartPointer<vtkLine>::New();
for(int i = 0; i < 2; ++i)
{
point->InsertNextPoint(dPoints[i]);
line->GetPointIds()->SetId(i,i);
}
vtkSmartPointer<vtkCellArray> cellArray = vtkSmartPointer<vtkCellArray>::New();
cellArray->InsertNextCell(line);
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(point);
polyData->SetLines(cellArray);
return polyData;
}
int main(int argc,char *argv[])
{
// 本例中的三种创建直线的方式,可以通过释放掉下面的注释来逐个验证
// vtkSmartPointer polyData = createPolyDataByPointArray();
// vtkSmartPointer polyData = createPolyDataByVtkLineSource();
vtkSmartPointer<vtkPolyData> polyData = createPolyDataByVtkLine();
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputData(polyData);
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(0.94,0.502,0.502);
vtkSmartPointer<vtkRenderer> render = vtkSmartPointer<vtkRenderer>::New();
render->AddActor(actor);
render->SetBackground(0,0,0);
render->ResetCamera();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(render);
renderWindow->SetSize(400,350);
renderWindow->Render();
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
interactor->Initialize();
interactor->Start();
return 0;
}
运行结果同上面的运行结果一样。
本文中创建单根直线,提供了三种创建直线的方式,vtkLineSource,vtkLine,vtkPolyData。
其中vtkLineSource通过两个点创建直线,最后获取polyData添加到mapper中。vtkLine与vtkPolyLine的区别是vtkLine创建单个直线,而vtkPolyLine可以创建多个直线。