说明:研究QT+VTK有段时间了,准备把学到的东西分享给大家,这篇博客以VS+QT+VTK为主进行展开学习的。
VTK学习
- VTK安装和使用教程
- VTK入门级教程
- 设计界面vtkStudy.ui的操作
- vtkStudy.h
- 头文件说明
- 完整代码
- vtkStudy.cpp
- 绘制球体
- 绘制长方体
- 绘制圆柱
- 绘制圆锥
- 绘制圆台
- 绘制圆弧台
- 合并几何体
- 完整代码
- 运行结果
VTK安装和使用教程
详细VTK安装教程我写了一篇博客,博客链接: https://blog.csdn.net/HXX904/article/details/133639010?spm=1001.2014.3001.5502
VTK库导入VS教程,博客链接: https://blog.csdn.net/HXX904/article/details/133650565?spm=1001.2014.3001.5502
这些准备好之后,就可以开始QT+VTK代码编写之旅了。
VTK入门级教程
项目创建以及VTK库导入就不多说了,直接进入正题。
这是我创建的项目,项目名称大家随意起。
设计界面vtkStudy.ui的操作
创建一个Widge控件,选中Widget控件右击,点击提升为。
在提升的类名称中编辑:QVTKOpenGLNativeWidget。然后点击添加。
进行勾选,并点击提升。
vtkStudy.h
头文件说明
//该头文件包含了用于生成球体几何数据的类。
#include <vtkSphereSource.h>
//该头文件包含了用于将vtkPolyData数据映射为可视化对象的类。
#include <vtkPolyDataMapper.h>
//该头文件包含了表示可视化对象的类,可以将vtkPolyDataMapper封装为一个可视化对象。
#include "vtkActor.h"
///该头文件包含了用于设置可视化对象属性(例如颜色、透明度等)的类。
#include <vtkProperty.h>
//该头文件包含了管理和渲染可视化对象的类,可以将多个vtkActor添加到vtkRenderer中进行渲染。
#include "vtkRenderer.h"
//该头文件包含了与特定平台无关的OpenGL渲染窗口类,用于在不同的图形界面(如Qt)中显示渲染结果。
#include <vtkGenericOpenGLRenderWindow.h>
//该头文件包含了用于生成立方体几何数据的类。
#include <vtkCubeSource.h>
//该头文件包含了用于生成线段几何数据的类。
#include <vtkLineSource.h>
//该头文件包含了用于从线段数据生成管道(圆柱体)几何数据的类。
#include <vtkTubeFilter.h>
//该头文件包含了用于生成圆锥几何数据的类。
#include <vtkConeSource.h>
//该头文件包含了用于旋转挤压操作,将2D几何数据沿轴线进行旋转和拉伸生成3D几何数据的类。
#include <vtkRotationalExtrusionFilter.h>
//该头文件包含了用于对vtkPolyData应用变换操作的类。
#include <vtkTransformPolyDataFilter.h>
//该头文件包含了表示几何变换的类,可以用于平移、旋转、缩放等操作。
#include <vtkTransform.h>
//该头文件包含了用于将多个vtkPolyData数据合并为一个vtkPolyData数据的类。
#include <vtkAppendPolyData.h>
//该头文件包含了用于生成参数样条曲线几何数据的类。
#include <vtkParametricSpline.h>
//该头文件包含了用于计算参数化函数的几何数据的类,可以根据给定的参数化函数生成几何数据。
#include <vtkParametricFunctionSource.h>
//该头文件包含了用于将任何vtkDataSet转换为vtkPolyData的类,可以将各种类型的几何数据转换为vtkPolyData进行后续处理和可视化。
#include <vtkGeometryFilter.h>
完整代码
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_vtkStudy.h"
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include "vtkActor.h"
#include <vtkProperty.h>
#include "vtkRenderer.h"
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkCubeSource.h>
#include <vtkLineSource.h>
#include <vtkTubeFilter.h>
#include <vtkConeSource.h>
#include <vtkRotationalExtrusionFilter.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkTransform.h>
#include <vtkAppendPolyData.h>
#include <vtkParametricSpline.h>
#include <vtkParametricFunctionSource.h>
#include <vtkGeometryFilter.h>
class vtkStudy : public QMainWindow
{
Q_OBJECT
std::vector<vtkSmartPointer<vtkSphereSource>> sphereSources; //用于保存多个球体源对象
std::vector<vtkSmartPointer<vtkCubeSource>> cubeSources; //用于保存多个长方体源对象
std::vector<vtkSmartPointer<vtkTubeFilter>> tubeSources; //用于保存多个柱体源对象
std::vector<vtkSmartPointer<vtkTransformPolyDataFilter>> ctctransformFilter;//用于保存多个圆台源对象
std::vector<vtkSmartPointer<vtkConeSource>> coneSources; //用于保存多个圆锥体源对象
std::vector<vtkSmartPointer<vtkTransformPolyDataFilter>> arctransformFilter;//用于保存多个圆弧台源对象
public:
vtkStudy(QWidget *parent = nullptr);
~vtkStudy();
//绘制常见的几何体
void DrawSphere();//绘制球体
void DrawCube();//绘制长方体
void DrawCylinder();//绘制圆柱
void DrawCone();//绘制圆锥
void DrawCircularFrustum();//绘制圆台
void DrawCircularArc();//绘制圆弧台
void MergeGeometry();//合并创建的几何体
private:
Ui::vtkStudyClass ui;
};
vtkStudy.cpp
绘制球体
// 创建一个球体源
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetCenter(0.0, 0.0, 0.0); // 设置球体中心坐标
sphereSource->SetRadius(3); // 设置球体半径
sphereSource->SetPhiResolution(100); // 设置球体的纬线分辨率
sphereSource->SetThetaResolution(100); // 设置球体的经线分辨率
sphereSource->Update(); // 更新球体数据
绘制长方体
// 创建立方体源对象
vtkSmartPointer<vtkCubeSource> cubeSource =
vtkSmartPointer<vtkCubeSource>::New();
// 设置立方体的中心位置和长宽高
cubeSource->SetCenter(4, 0, 0); // 设置立方体中心坐标
cubeSource->SetXLength(1); // 设置立方体在 X 方向上的长度
cubeSource->SetYLength(2); // 设置立方体在 Y 方向上的长度
cubeSource->SetZLength(3); // 设置立方体在 Z 方向上的长度
cubeSource->Update(); // 更新立方体源的信息
绘制圆柱
// 创建线源对象
vtkSmartPointer<vtkLineSource> line =
vtkSmartPointer<vtkLineSource>::New();
// 设置线的起点和终点坐标
line->SetPoint1(6, 0, 0);
line->SetPoint2(10, 0, 0);
// 创建管道化处理对象
vtkSmartPointer<vtkTubeFilter> tube
= vtkSmartPointer<vtkTubeFilter>::New();
// 将线源的输出连接到管道中
tube->SetInputConnection(line->GetOutputPort());
// 设置生成圆柱体的半径、边数以及是否封闭处理
tube->SetRadius(2); // 设置半径
tube->SetNumberOfSides(100); // 设置边数
tube->SetCapping(1); // 是否进行封闭处理,1 表示进行封闭处理
tube->Update(); // 更新管道信息
绘制圆锥
// 创建锥体源对象
vtkSmartPointer<vtkConeSource> coneSource =
vtkSmartPointer<vtkConeSource>::New();
// 设置锥体的中心位置、底面半径、高度和分辨率
coneSource->SetCenter(14, 0, 0); // 设置锥体中心坐标
coneSource->SetRadius(2); // 设置底面半径
coneSource->SetHeight(4); // 设置高度
coneSource->SetResolution(100); // 设置分辨率
// 更新锥体源的信息
coneSource->Update();
绘制圆台
// 创建存储点的对象
vtkNew<vtkPoints> points;
points->InsertPoint(0, 0, 0.0, 18);
points->InsertPoint(1, 2, 0.0, 18);
points->InsertPoint(2, 4, 0.0, 18 + 4);
points->InsertPoint(3, 0.0, 0.0, 18 + 4);
// 创建存储线段的对象
vtkNew<vtkCellArray> lines;
lines->InsertNextCell(4); // 线段的点数
lines->InsertCellPoint(0);
lines->InsertCellPoint(1);
lines->InsertCellPoint(2);
lines->InsertCellPoint(3);
// 创建 PolyData 对象,并设置点和线信息
vtkNew<vtkPolyData> profile;
profile->SetPoints(points);
profile->SetLines(lines);
// 创建旋转拉伸滤波器对象
vtkSmartPointer<vtkRotationalExtrusionFilter> extrude =
vtkSmartPointer<vtkRotationalExtrusionFilter>::New();
extrude->SetInputData(profile);
extrude->SetAngle(360.0); // 完整的旋转一周
extrude->SetResolution(100);
// 创建旋转变换对象,并绕 Y 轴旋转 90 度
vtkSmartPointer<vtkTransform> transform =
vtkSmartPointer<vtkTransform>::New();
transform->RotateY(90.0);
// 创建 TransformPolyDataFilter 对象,并连接旋转拉伸滤波器的输出
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter =
vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter->SetInputConnection(extrude->GetOutputPort());
transformFilter->SetTransform(transform);
绘制圆弧台
// 创建线段1
vtkSmartPointer<vtkLineSource> lineSource1 = vtkSmartPointer<vtkLineSource>::New();
lineSource1->SetPoint1(3, 0, 24);
lineSource1->SetPoint2(0, 0, 24);
// 创建线段2
vtkSmartPointer<vtkLineSource> lineSource2 = vtkSmartPointer<vtkLineSource>::New();
lineSource2->SetPoint1(0, 0, 24);
lineSource2->SetPoint2(0, 0, 30);
// 创建线段3
vtkSmartPointer<vtkLineSource> lineSource3 = vtkSmartPointer<vtkLineSource>::New();
lineSource3->SetPoint1(0, 0, 30);
lineSource3->SetPoint2(6, 0, 30);
// 创建参数化样条曲线
vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(6, 0, 30);
double X1 = 6, Y1 = 30;
double X2 = 3, Y2 = 24;
double R = 10;
// 计算两点连线的中点坐标
double midX = (X1 + X2) / 2;
double midY = (Y1 + Y2) / 2;
// 计算两点连线的斜率
double slope = (Y2 - Y1) / (X2 - X1);
// 计算两点连线的垂直平分线斜率的倒数
double perpendicularSlope = -1 / slope;
// 计算两点连线的长度
double distance = std::sqrt(std::pow((X2 - X1), 2) + std::pow((Y2 - Y1), 2));
// 计算垂直平分线与两点连线中点的距离
double perpendicularDistance = std::sqrt(std::pow(R, 2) - std::pow((distance / 2), 2));
// 计算圆心坐标
double x1 = midX + perpendicularDistance / std::sqrt(1 + std::pow(perpendicularSlope, 2));
double y1 = midY + perpendicularSlope * (x1 - midX);
double x2 = (X1 + X2) / 2, y2 = (Y1 + Y2) / 2;
double CenterX = 2 * x2 - x1, CenterY = 2 * y2 - y1;
double x3 = CenterX, y3 = CenterY;
double x4 = (X1 + X2) / 2, y4 = (Y1 + Y2) / 2;
double k = (y4 - y3) / (x4 - x3);
double b = y3 - k * x3;
double a = k * k + 1;
double b2 = 2 * b * k - 2 * k * CenterY - 2 * CenterX;
double c = CenterX * CenterX - R * R + (b - CenterY) * (b - CenterY);
// 计算与圆相交的点坐标
double X = (-1.0 * b2 + sqrt(b2 * b2 - 4 * a * c)) / (2 * a);
double Y = k * X + b;
// 添加样条曲线上的点
points->InsertNextPoint(X, 0, Y);
points->InsertNextPoint(3, 0, 24);
spline->SetPoints(points);
// 创建一个用于存储多个几何对象的容器
vtkSmartPointer<vtkAppendPolyData> appendPolyData = vtkSmartPointer<vtkAppendPolyData>::New();
// 将线段1添加到容器中
appendPolyData->AddInputConnection(lineSource1->GetOutputPort());
appendPolyData->Update();
// 将线段2添加到容器中
appendPolyData->AddInputConnection(lineSource2->GetOutputPort());
appendPolyData->Update();
// 将线段3添加到容器中
appendPolyData->AddInputConnection(lineSource3->GetOutputPort());
appendPolyData->Update();
// 创建参数化函数的源对象
vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New();
functionSource->SetParametricFunction(spline);
functionSource->Update();
// 将参数化函数生成的曲线添加到容器中
appendPolyData->AddInputConnection(functionSource->GetOutputPort());
appendPolyData->Update();
// 提取容器中的几何数据
vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkSmartPointer<vtkGeometryFilter>::New();
geometryFilter->SetInputData(appendPolyData->GetOutput());
geometryFilter->Update();
// 获取提取后的几何数据
vtkSmartPointer<vtkPolyData> yprofiles = geometryFilter->GetOutput();
// 创建旋转挤压滤波器
vtkSmartPointer<vtkRotationalExtrusionFilter> extrude = vtkSmartPointer<vtkRotationalExtrusionFilter>::New();
extrude->SetInputData(yprofiles);
extrude->SetAngle(360);
extrude->SetResolution(360);
// 创建变换对象并绕Y轴旋转90度
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
transform->RotateY(90.0);
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter->SetInputConnection(extrude->GetOutputPort());
transformFilter->SetTransform(transform);
合并几何体
// 创建一个vtkAppendPolyData对象,用于将多个PolyData数据合并成一个
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
// 将各种类型的几何数据添加到vtkAppendPolyData对象中
for (const auto& sphere : sphereSources) {
sphere->Update();
appendFilter->AddInputData(sphere->GetOutput());
}
for (const auto& cube : cubeSources) {
cube->Update();
appendFilter->AddInputData(cube->GetOutput());
}
for (const auto& tube : tubeSources) {
tube->Update();
appendFilter->AddInputData(tube->GetOutput());
}
for (const auto& ctc : ctctransformFilter) {
ctc->Update();
appendFilter->AddInputData(ctc->GetOutput());
}
for (const auto& cone : coneSources) {
cone->Update();
appendFilter->AddInputData(cone->GetOutput());
}
for (const auto& arc : arctransformFilter) {
arc->Update();
appendFilter->AddInputData(arc->GetOutput());
}
// 对合并后的vtkPolyData进行渲染,创建vtkPolyDataMapper对象
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(appendFilter->GetOutputPort());
// 创建vtkActor对象,并将vtkPolyDataMapper设置为其Mapper
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// 设置Actor的颜色为红色
actor->GetProperty()->SetColor(255.0 / 255.0, 0.0 / 255.0, 0.0 / 255.0);
// 创建vtkRenderer对象,并设置背景颜色为黑色
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->SetBackground(0, 0, 0);
// 将Actor添加到Renderer中
renderer->AddActor(actor);
// 创建vtkGenericOpenGLRenderWindow对象,并将Renderer设置为其Renderer
vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
renderWindow->AddRenderer(renderer);
// 将vtkGenericOpenGLRenderWindow对象设置为Qt界面上的RenderWindow
ui.widget->setRenderWindow(renderWindow);
完整代码
#include "vtkStudy.h"
vtkStudy::vtkStudy(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//绘制常见的几何体
DrawSphere();//绘制球体
DrawCube();//绘制长方体
DrawCylinder();//绘制圆柱
DrawCone();//绘制圆锥
DrawCircularFrustum();//绘制圆台
DrawCircularArc();//绘制圆弧台
MergeGeometry();//将绘制的几何体进行合并
}
vtkStudy::~vtkStudy()
{}
void vtkStudy::DrawSphere()
{
// 创建一个球体源
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetCenter(0.0, 0.0, 0.0); // 设置球体中心坐标
sphereSource->SetRadius(2); // 设置球体半径
sphereSource->SetPhiResolution(100); // 设置球体的纬线分辨率
sphereSource->SetThetaResolution(100); // 设置球体的经线分辨率
sphereSource->Update(); // 更新球体数据
sphereSources.push_back(sphereSource);
}
void vtkStudy::DrawCube()
{
// 创建立方体源对象
vtkSmartPointer<vtkCubeSource> cubeSource =
vtkSmartPointer<vtkCubeSource>::New();
// 设置立方体的中心位置和长宽高
cubeSource->SetCenter(4, 0, 0); // 设置立方体中心坐标
cubeSource->SetXLength(1); // 设置立方体在 X 方向上的长度
cubeSource->SetYLength(2); // 设置立方体在 Y 方向上的长度
cubeSource->SetZLength(3); // 设置立方体在 Z 方向上的长度
cubeSource->Update(); // 更新立方体源的信息
cubeSources.push_back(cubeSource);
}
void vtkStudy::DrawCylinder()
{
// 创建线源对象
vtkSmartPointer<vtkLineSource> line =
vtkSmartPointer<vtkLineSource>::New();
// 设置线的起点和终点坐标
line->SetPoint1(6, 0, 0);
line->SetPoint2(10, 0, 0);
// 创建管道化处理对象
vtkSmartPointer<vtkTubeFilter> tube
= vtkSmartPointer<vtkTubeFilter>::New();
// 将线源的输出连接到管道中
tube->SetInputConnection(line->GetOutputPort());
// 设置生成圆柱体的半径、边数以及是否封闭处理
tube->SetRadius(2); // 设置半径
tube->SetNumberOfSides(100); // 设置边数
tube->SetCapping(1); // 是否进行封闭处理,1 表示进行封闭处理
// 更新管道信息
tube->Update();
tubeSources.push_back(tube);
}
void vtkStudy::DrawCone()
{
// 创建锥体源对象
vtkSmartPointer<vtkConeSource> coneSource =
vtkSmartPointer<vtkConeSource>::New();
// 设置锥体的中心位置、底面半径、高度和分辨率
coneSource->SetCenter(14, 0, 0); // 设置锥体中心坐标
coneSource->SetRadius(2); // 设置底面半径
coneSource->SetHeight(4); // 设置高度
coneSource->SetResolution(100); // 设置分辨率
// 更新锥体源的信息
coneSource->Update();
coneSources.push_back(coneSource);
}
void vtkStudy::DrawCircularFrustum()
{
// 创建存储点的对象
vtkNew<vtkPoints> points;
points->InsertPoint(0, 0, 0.0, 18);
points->InsertPoint(1, 2, 0.0, 18);
points->InsertPoint(2, 4, 0.0, 18 + 4);
points->InsertPoint(3, 0.0, 0.0, 18 + 4);
// 创建存储线段的对象
vtkNew<vtkCellArray> lines;
lines->InsertNextCell(4); // 线段的点数
lines->InsertCellPoint(0);
lines->InsertCellPoint(1);
lines->InsertCellPoint(2);
lines->InsertCellPoint(3);
// 创建 PolyData 对象,并设置点和线信息
vtkNew<vtkPolyData> profile;
profile->SetPoints(points);
profile->SetLines(lines);
// 创建旋转拉伸滤波器对象
vtkSmartPointer<vtkRotationalExtrusionFilter> extrude =
vtkSmartPointer<vtkRotationalExtrusionFilter>::New();
extrude->SetInputData(profile);
extrude->SetAngle(360.0); // 完整的旋转一周
extrude->SetResolution(100);
// 创建旋转变换对象,并绕 Y 轴旋转 90 度
vtkSmartPointer<vtkTransform> transform =
vtkSmartPointer<vtkTransform>::New();
transform->RotateY(90.0);
// 创建 TransformPolyDataFilter 对象,并连接旋转拉伸滤波器的输出
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter =
vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter->SetInputConnection(extrude->GetOutputPort());
transformFilter->SetTransform(transform);
ctctransformFilter.push_back(transformFilter);
}
void vtkStudy::DrawCircularArc()
{
// 创建线段1
vtkSmartPointer<vtkLineSource> lineSource1 = vtkSmartPointer<vtkLineSource>::New();
lineSource1->SetPoint1(3, 0, 24);
lineSource1->SetPoint2(0, 0, 24);
// 创建线段2
vtkSmartPointer<vtkLineSource> lineSource2 = vtkSmartPointer<vtkLineSource>::New();
lineSource2->SetPoint1(0, 0, 24);
lineSource2->SetPoint2(0, 0, 30);
// 创建线段3
vtkSmartPointer<vtkLineSource> lineSource3 = vtkSmartPointer<vtkLineSource>::New();
lineSource3->SetPoint1(0, 0, 30);
lineSource3->SetPoint2(6, 0, 30);
// 创建参数化样条曲线
vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(6, 0, 30);
double X1 = 6, Y1 = 30;
double X2 = 3, Y2 = 24;
double R = 10;
// 计算两点连线的中点坐标
double midX = (X1 + X2) / 2;
double midY = (Y1 + Y2) / 2;
// 计算两点连线的斜率
double slope = (Y2 - Y1) / (X2 - X1);
// 计算两点连线的垂直平分线斜率的倒数
double perpendicularSlope = -1 / slope;
// 计算两点连线的长度
double distance = std::sqrt(std::pow((X2 - X1), 2) + std::pow((Y2 - Y1), 2));
// 计算垂直平分线与两点连线中点的距离
double perpendicularDistance = std::sqrt(std::pow(R, 2) - std::pow((distance / 2), 2));
// 计算圆心坐标
double x1 = midX + perpendicularDistance / std::sqrt(1 + std::pow(perpendicularSlope, 2));
double y1 = midY + perpendicularSlope * (x1 - midX);
double x2 = (X1 + X2) / 2, y2 = (Y1 + Y2) / 2;
double CenterX = 2 * x2 - x1, CenterY = 2 * y2 - y1;
double x3 = CenterX, y3 = CenterY;
double x4 = (X1 + X2) / 2, y4 = (Y1 + Y2) / 2;
double k = (y4 - y3) / (x4 - x3);
double b = y3 - k * x3;
double a = k * k + 1;
double b2 = 2 * b * k - 2 * k * CenterY - 2 * CenterX;
double c = CenterX * CenterX - R * R + (b - CenterY) * (b - CenterY);
// 计算与圆相交的点坐标
double X = (-1.0 * b2 + sqrt(b2 * b2 - 4 * a * c)) / (2 * a);
double Y = k * X + b;
// 添加样条曲线上的点
points->InsertNextPoint(X, 0, Y);
points->InsertNextPoint(3, 0, 24);
spline->SetPoints(points);
// 创建一个用于存储多个几何对象的容器
vtkSmartPointer<vtkAppendPolyData> appendPolyData = vtkSmartPointer<vtkAppendPolyData>::New();
// 将线段1添加到容器中
appendPolyData->AddInputConnection(lineSource1->GetOutputPort());
appendPolyData->Update();
// 将线段2添加到容器中
appendPolyData->AddInputConnection(lineSource2->GetOutputPort());
appendPolyData->Update();
// 将线段3添加到容器中
appendPolyData->AddInputConnection(lineSource3->GetOutputPort());
appendPolyData->Update();
// 创建参数化函数的源对象
vtkSmartPointer<vtkParametricFunctionSource> functionSource = vtkSmartPointer<vtkParametricFunctionSource>::New();
functionSource->SetParametricFunction(spline);
functionSource->Update();
// 将参数化函数生成的曲线添加到容器中
appendPolyData->AddInputConnection(functionSource->GetOutputPort());
appendPolyData->Update();
// 提取容器中的几何数据
vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkSmartPointer<vtkGeometryFilter>::New();
geometryFilter->SetInputData(appendPolyData->GetOutput());
geometryFilter->Update();
// 获取提取后的几何数据
vtkSmartPointer<vtkPolyData> yprofiles = geometryFilter->GetOutput();
// 创建旋转挤压滤波器
vtkSmartPointer<vtkRotationalExtrusionFilter> extrude = vtkSmartPointer<vtkRotationalExtrusionFilter>::New();
extrude->SetInputData(yprofiles);
extrude->SetAngle(360);
extrude->SetResolution(360);
// 创建变换对象并绕Y轴旋转90度
vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
transform->RotateY(90.0);
vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformFilter->SetInputConnection(extrude->GetOutputPort());
transformFilter->SetTransform(transform);
// 将变换后的数据添加到一个容器中(这里没有给出arctransformFilter的定义,需要自行定义)
arctransformFilter.push_back(transformFilter);
}
void vtkStudy::MergeGeometry()
{
// 创建一个vtkAppendPolyData对象,用于将多个PolyData数据合并成一个
vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
// 将各种类型的几何数据添加到vtkAppendPolyData对象中
for (const auto& sphere : sphereSources) {
sphere->Update();
appendFilter->AddInputData(sphere->GetOutput());
}
for (const auto& cube : cubeSources) {
cube->Update();
appendFilter->AddInputData(cube->GetOutput());
}
for (const auto& tube : tubeSources) {
tube->Update();
appendFilter->AddInputData(tube->GetOutput());
}
for (const auto& ctc : ctctransformFilter) {
ctc->Update();
appendFilter->AddInputData(ctc->GetOutput());
}
for (const auto& cone : coneSources) {
cone->Update();
appendFilter->AddInputData(cone->GetOutput());
}
for (const auto& arc : arctransformFilter) {
arc->Update();
appendFilter->AddInputData(arc->GetOutput());
}
// 对合并后的vtkPolyData进行渲染,创建vtkPolyDataMapper对象
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(appendFilter->GetOutputPort());
// 创建vtkActor对象,并将vtkPolyDataMapper设置为其Mapper
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
// 设置Actor的颜色为红色
actor->GetProperty()->SetColor(255.0 / 255.0, 0.0 / 255.0, 0.0 / 255.0);
// 创建vtkRenderer对象,并设置背景颜色为黑色
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->SetBackground(0, 0, 0);
// 将Actor添加到Renderer中
renderer->AddActor(actor);
// 创建vtkGenericOpenGLRenderWindow对象,并将Renderer设置为其Renderer
vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
renderWindow->AddRenderer(renderer);
// 将vtkGenericOpenGLRenderWindow对象设置为Qt界面上的RenderWindow
ui.widget->setRenderWindow(renderWindow);
}
运行结果
可进行缩放、旋转、平移。