VTK学习(入门级教程,包括安装和使用)~持续更新中

发布时间:2023年12月17日

说明:研究QT+VTK有段时间了,准备把学到的东西分享给大家,这篇博客以VS+QT+VTK为主进行展开学习的。

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库导入就不多说了,直接进入正题。

这是我创建的项目,项目名称大家随意起。

Alt

设计界面vtkStudy.ui的操作

创建一个Widge控件,选中Widget控件右击,点击提升为
Alt
在提升的类名称中编辑:QVTKOpenGLNativeWidget。然后点击添加。
Alt
进行勾选,并点击提升。
Alt

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);
}

运行结果

可进行缩放、旋转、平移。
ALT

文章来源:https://blog.csdn.net/HXX904/article/details/134856789
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。