之前学习VTK多边形vtkPolyData类时,vtkPolyData内部是由几何结构和拓扑结构组成。
几何结构是离散点坐标组成,是点的集合;
拓扑结构是描述离散点之间的相互关系的信息,拓扑结构的最小组成单位是单元,每个单元是由几个点的vtkIdType描述的;不同个数的点ID可以描述三角、四边、多边、立体图形等各种图元信息;
定义单元需要指定单元的类型以及一些有序的点ID(vtkIdType);
使用vtkPolyData创建多边形,需要输入点集合、单元集合、标量集合;
立方体
立方体有八个顶点、六个面以及十二条边组成;在可视化中,使用六个面就能组成立方体;那么在立方体的vtkPolyData中几何结构就是八个顶点,拓扑结构就是八个顶点分别组合的六个面;
步骤:
1.设定立方体的边长为1,起点从(0,0,0)开始;将八个顶点放入vtkPoints points
中;
2.根据八个顶点的ID,组成vtkIdType pts[6][4]
,pts
中每行表示一个单元信息,是由4个点id组成的四边形;注意:这些id必须按照顺时针或逆时针方向排列。
3.将每个点对应的标量属性数据放入vtkFloatArray
,标量数据个数必须与点的个数相同;
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkCamera.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
int main() {
int i;
static float x[8][3] = {
{
0,0,0},{
1,0,0},{
1,1,0},{
0,1,0},
{
0,0,1},{
1,0,1},{
1,1,1},{
0,1,1}
};
static vtkIdType pts[6][4] = {
{
0,1,2,3},{
4,5,6,7},{
0,1,5,4},
{
1,2,6,5},{
2,3,7,6},{
3,0,4,7}
};
vtkNew<vtkPolyData> cube;
vtkNew<vtkPoints> points;
vtkNew<vtkCellArray> polys;
vtkNew<vtkFloatArray> scalars;
for (int i = 0; i < 8; i++) points->InsertPoint(i, x[i]);
for (int i = 0; i < 6; i++) polys->InsertNextCell(4, pts[i]);
for (int i = 0; i < 8; i++) scalars->InsertTuple1(i, i);
cube->SetPoints(points);
cube->SetPolys(polys);
cube->GetPointData()->SetScalars(scalars);
vtkNew<vtkPolyDataMapper> cubeMapper;
cubeMapper->SetInputData(cube);
cubeMapper->SetScalarRange(0, 7);
vtkNew<vtkActor> cubeActor;
cubeActor->SetMapper(cubeMapper);
vtkNew<vtkCamera> camera;
camera->SetPosition(1, 1, 1);
camera->SetFocalPoint(0, 0, 0);
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renderer->AddActor(cubeActor);
renderer->SetActiveCamera(camera);
renderer->ResetCamera();
renderer->SetBackground(1, 1, 1);
renWin->SetSize(300, 300);
renWin->Render();
iren->Initialize();
iren->Start();
return 0;
}
使用SetLines
,显示多边形的边框线;
vtkNew<vtkPolyData> cube;
vtkNew<vtkPoints> points;
vtkNew<vtkCellArray> lines;
for (int i = 0; i < 8; i++) points->InsertPoint(i, x[i]);
lines->InsertNextCell(5);
for (unsigned long i = 0; i < 4; ++i) {
lines->InsertCellPoint(i);
}
lines->InsertCellPoint(0);
lines->InsertNextCell(5);
for (unsigned long i = 0; i < 4; ++i) {
lines->InsertCellPoint(i + 4);
}
lines->InsertCellPoint(4);
for (int i = 0; i < 4; i++) {
lines->InsertNextCell(2);
lines->InsertCellPoint(i);
lines->InsertCellPoint(i + 4);
}
cube->SetPoints(points);
cube->SetLines(lines);
四面体
四面体是由四个三角面和四个顶点组成;
参照立方体的做法,polys
是由四个三角形组成;
const int num_points = 4;
static float x[num_points][3] = {
{
0,0,0},{
1,0,0},{
0.5,1,0},{
0.5,0.5,1}
};
static vtkIdType pts[4][3] = {
{
0,1,2},{
0,1,3},{
1,2,3},{
0,2,3}
};
vtkNew<vtkPolyData> cube;
vtkNew<vtkPoints> points;
vtkNew<vtkCellArray> polys;
vtkNew<vtkFloatArray> scalars;
for (int i = 0; i < num_points; i++) points->InsertPoint(i, x[i]);
for (int i = 0; i < 4; i++) polys->InsertNextCell(3, pts[i]);
for (int i = 0; i < num_points; i++) scalars->InsertTuple1(i, i);
cube->SetPoints(points);
cube->SetPolys(polys);
cube->GetPointData()->SetScalars(scalars);
vtkNew<vtkPolyData> cube;
vtkNew<vtkPoints> points;
vtkNew<vtkCellArray> lines;
for (int i = 0; i < num_points; i++) points->InsertPoint(i, x[i]);
for (int i = 0; i < num_points - 1; i++) {
lines->InsertNextCell(2);
lines->InsertCellPoint(i);
lines->InsertCellPoint(num_points - 1);
lines->InsertNextCell(2);
lines->InsertCellPoint(i);
lines->InsertCellPoint((i + 1) % (num_points - 1));
}
cube->SetPoints(points);
cube->SetLines(lines);
金字塔
金字塔形状,由五个顶点和五个面,四个三角平面加上一个四边形平面;
参照立方体的做法,polys
有两部分组成,一部分是形状相同的三角形,一部分是四边形;
#include "pch.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkCamera.h"
#include "vtkActor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
int main() {
const int num_points = 5;
static float x[num_points][3] = {
{
0,0,0},{
1,0,0},{
1,1,0},{
0,1,0},{
0.5,0.5,1}
};
static vtkIdType pts[4][3] = {
{
0,1,4},{
1,2,4},{
2,3,4},{
3,0,4}
};
vtkNew<vtkPolyData> cube;
vtkNew<vtkPoints> points;
vtkNew<vtkCellArray> polys;
vtkNew<vtkFloatArray> scalars;
for (int i = 0; i < num_points; i++) points->InsertPoint(i, x[i]);
for (int i = 0; i < 4; i++) polys->InsertNextCell(3, pts[i]);
polys->InsertNextCell(4);
for (int i = 0; i < 4; i++) {
polys->InsertCellPoint(i);
}
for (int i = 0; i < num_points; i++) scalars->InsertTuple1(i, i);
cube->SetPoints(points);
cube->SetPolys(polys);
cube->GetPointData()->SetScalars(scalars);
vtkNew<vtkPolyDataMapper> cubeMapper;
cubeMapper->SetInputData(cube);
cubeMapper->SetScalarRange(0, 7);
vtkNew<vtkActor> cubeActor;
cubeActor->SetMapper(cubeMapper);
vtkNew<vtkCamera> camera;
camera->SetPosition(1, 1, 1);
camera->SetFocalPoint(0, 0, 0);
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renderer->AddActor(cubeActor);
renderer->SetActiveCamera(camera);
renderer->ResetCamera();
renderer->SetBackground(1, 1, 1);
renWin->SetSize(300, 300);
renWin->Render();
iren->Initialize();
iren->Start();
return 0;
}
使用四面体的边框绘制代码,绘制金字塔的边框线;