当前位置: 首页 > news >正文

VTK|显示三维图像的二维切片

参考:
VTK显示三维图像的二维切片

文章目录

  • 实现类头文件
  • 实现类源文件
  • 如何调用
  • 项目git链接

以中心点坐标横切面

实现类头文件


/*** @file MeshSliceController.h* @brief 该头文件定义了 MeshSliceController 类,用于显示切面图。* @details 该类负责处理与网格切面相关的操作,包括创建切面、显示和隐藏切面,以及更新用于切面操作的网格数据。*          注意注释中提到的比例尺相关内容可能是文档编写错误,实际该类与比例尺无关。* @author qtree* @date 2025年5月14日*/
#ifndef MESHSLICECONTROLLER_H
#define MESHSLICECONTROLLER_H#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>/*** @enum SliceDirection* @brief 定义切面的方向枚举类型。*/
enum SliceDirection
{SLICE_X, ///< 沿 X 轴方向进行切面SLICE_Y, ///< 沿 Y 轴方向进行切面SLICE_Z  ///< 沿 Z 轴方向进行切面
};/*** @class MeshSliceController* @brief 用于管理和显示网格数据切面的类。** 该类提供了显示、隐藏切面,以及更新网格数据的功能。*/
class MeshSliceController
{
public:/*** @brief 构造函数。* @param renderer 用于渲染切面的渲染器。*/MeshSliceController(vtkSmartPointer<vtkRenderer> renderer);/*** @brief 根据指定方向显示切面。* @param direction 切面的方向,取值为 SliceDirection 枚举类型。*/void ShowSlice(SliceDirection direction);/*** @brief 隐藏当前显示的切面。*/void HideSlice();/*** @brief 更新用于切面操作的网格数据。* @param polyData 新的网格数据。*/void UpdatePolyData(vtkSmartPointer<vtkPolyData> polyData);/*** @brief 设置原始网格数据的 Actor。* @param actor 原始网格数据的 Actor。*/void SetOriginalActor(vtkSmartPointer<vtkActor> actor);private:vtkSmartPointer<vtkRenderer> renderer_; ///< 用于渲染切面的渲染器vtkSmartPointer<vtkPolyData> polyData_; ///< 用于切面操作的网格数据vtkSmartPointer<vtkPlane> slicePlane_;           ///< 定义切面的平面vtkSmartPointer<vtkCutter> cutter_;              ///< 用于切割网格数据的切割器vtkSmartPointer<vtkPolyDataMapper> sliceMapper_; ///< 切面数据的映射器vtkSmartPointer<vtkActor> sliceActor_;           ///< 用于显示切面的 ActorvtkSmartPointer<vtkActor> originalActor_; ///< 原始网格数据的 Actor
};#endif // MESHSLICECONTROLLER_H

实现类源文件

#include "MeshSliceController.h"
#include <vtkProperty.h>
#include <vtkBoundingBox.h>
#include <iostream> // 添加标准输出MeshSliceController::MeshSliceController(vtkSmartPointer<vtkRenderer> renderer): renderer_(renderer)
{std::cout << "[MeshSliceController] Constructor called." << std::endl;slicePlane_ = vtkSmartPointer<vtkPlane>::New();cutter_ = vtkSmartPointer<vtkCutter>::New();cutter_->SetCutFunction(slicePlane_);sliceMapper_ = vtkSmartPointer<vtkPolyDataMapper>::New();sliceMapper_->SetInputConnection(cutter_->GetOutputPort());sliceActor_ = vtkSmartPointer<vtkActor>::New();sliceActor_->SetMapper(sliceMapper_);sliceActor_->GetProperty()->SetColor(1.0, 0.0, 0.0); // 红色切面sliceActor_->GetProperty()->SetLineWidth(2.0);sliceActor_->GetProperty()->SetOpacity(1.0);
}void MeshSliceController::ShowSlice(SliceDirection direction)
{if (!polyData_){std::cerr << "[MeshSliceController] polyData_ is null. Cannot show slice." << std::endl;return;}if (originalActor_){std::cout << "[ShowSlice] Hiding original actor." << std::endl;originalActor_->VisibilityOff();}std::cout << "[MeshSliceController] ShowSlice called." << std::endl;double bounds[6];polyData_->GetBounds(bounds);double center[3] = {(bounds[0] + bounds[1]) / 2.0,(bounds[2] + bounds[3]) / 2.0,(bounds[4] + bounds[5]) / 2.0};std::cout << "PolyData bounds: ["<< bounds[0] << ", " << bounds[1] << ", "<< bounds[2] << ", " << bounds[3] << ", "<< bounds[4] << ", " << bounds[5] << "]" << std::endl;switch (direction){case SLICE_X:std::cout << "Slice along X-axis." << std::endl;slicePlane_->SetOrigin(center[0], center[1], center[2]);slicePlane_->SetNormal(1.0, 0.0, 0.0);break;case SLICE_Y:std::cout << "Slice along Y-axis." << std::endl;slicePlane_->SetOrigin(center[0], center[1], center[2]);slicePlane_->SetNormal(0.0, 1.0, 0.0);break;case SLICE_Z:std::cout << "Slice along Z-axis." << std::endl;slicePlane_->SetOrigin(center[0], center[1], center[2]);slicePlane_->SetNormal(0.0, 0.0, 1.0);break;default:std::cerr << "Unknown slice direction!" << std::endl;return;}std::cout << "Origin: (" << center[0] << ", " << center[1] << ", " << center[2] << ")" << std::endl;cutter_->Update();vtkSmartPointer<vtkPolyData> sliceOutput = cutter_->GetOutput();std::cout << "Number of points in slice: " << sliceOutput->GetNumberOfPoints() << std::endl;std::cout << "Number of cells in slice: " << sliceOutput->GetNumberOfCells() << std::endl;if (!renderer_->HasViewProp(sliceActor_)){std::cout << "[MeshSliceController] Adding slice actor to renderer." << std::endl;renderer_->AddActor(sliceActor_);}else{std::cout << "[ShowSlice] Slice actor already exists in renderer." << std::endl;}sliceMapper_->SetInputConnection(cutter_->GetOutputPort());sliceMapper_->Update();renderer_->Render();
}void MeshSliceController::HideSlice()
{if (originalActor_){std::cout << "[HideSlice] Restoring original actor visibility." << std::endl;originalActor_->VisibilityOn();}if (renderer_->HasViewProp(sliceActor_)){std::cout << "[HideSlice] Removing slice actor." << std::endl;renderer_->RemoveActor(sliceActor_);renderer_->Render();}
}void MeshSliceController::UpdatePolyData(vtkSmartPointer<vtkPolyData> polyData)
{std::cout << "[UpdatePolyData] Updating slice polyData, number of points: "<< (polyData ? polyData->GetNumberOfPoints() : 0) << std::endl;polyData_ = polyData;cutter_->SetInputData(polyData_); // 更新切割输入cutter_->Update();
}void MeshSliceController::SetOriginalActor(vtkSmartPointer<vtkActor> actor)
{originalActor_ = actor;
}

如何调用

头文件声明

// 切面图
std::unique_ptr<MeshSliceController> meshSliceController_;

构造函数初始化一次

// 切面图
meshSliceController_ = std::make_unique<MeshSliceController>(renderer_);
meshSliceController_->SetOriginalActor(testActor);
// 传入最终用于渲染的 polydata
meshSliceController_->UpdatePolyData(cylinderSource->GetOutput()); 

构造函数里xyz轴以及隐藏 切面按钮槽函数

connect(btnSliceX, &QPushButton::clicked, this, [=](){ meshSliceController_->ShowSlice(SLICE_X); renderWindow_->Render(); });connect(btnSliceY, &QPushButton::clicked, this, [=](){ meshSliceController_->ShowSlice(SLICE_Y); renderWindow_->Render(); });connect(btnSliceZ, &QPushButton::clicked, this, [=](){ meshSliceController_->ShowSlice(SLICE_Z); renderWindow_->Render(); });connect(hideSlice, &QPushButton::clicked, this, [=](){
if (meshSliceController_)meshSliceController_->HideSlice(); renderWindow_->Render(); });

更新PolyData,通常在加载新的ply和obj文件之后调用


// ✅ 更新切面数据
if (meshSliceController_)
{meshSliceController_->SetOriginalActor(ply_point_actor_);// 传入最终用于渲染的 polydatameshSliceController_->UpdatePolyData(vertexGlyphFilter->GetOutput()); 
}

项目git链接

gitee:https://gitee.com/strange-tree-qian/vtktest
github:https://github.com/qishuqian666/project-vtk-test

相关文章:

  • Pyro:基于PyTorch的概率编程框架
  • 哈夫曼编码:数据压缩的优雅艺术
  • 使用PHP对接东南亚、日本、印度和印度尼西亚股票数据源
  • 洛谷U536262 井底之“鸡” 附视频讲解
  • WEB安全--SQL注入--Oracle注入
  • 【VMware】虚拟机运行 Linux Ubuntu、MAC 安装和配置
  • oracle序列自增问题
  • 如何在 Windows 11 或 10 上安装 Django
  • Springboot 跨域拦截器配置说明
  • 已知6、7、8月月平均气温和标准差,求夏季季平均温度与标准差
  • 《Opensearch-SQL》论文精读:2025年在BIRD的SOTA方法(Text-to-SQL任务)
  • LightRAG 由入门到精通
  • leetcode刷题日记——对称二叉树
  • 使用腾讯云高性能空间部署YOLOv11训练模型
  • C/C++ 知识点:引用临时对象
  • JavaScript篇:前端模块化进化史:从CommonJS到ES6的奇幻之旅
  • Python Django 的 ORM 编程思想及使用步骤
  • 通过vcpkg交叉编译grpc:构建Arm64平台的Docker化开发环境
  • ALTER AGGREGATE使用场景
  • JSON-to-Excel插件 v2.1.2 新增功能批量转换功能
  • 上海文化馆服务宣传周启动,为市民提供近2000项活动
  • 鸿蒙电脑正式发布,余承东:国产软件起步晚,基础弱,探索面向未来的电脑体验
  • 周慧芳任上海交通大学医学院附属上海儿童医学中心党委书记
  • 首届中国人文学科年度发展大会启幕,共话AI时代人文使命
  • 光速晋级!2025年多哈世乒赛孙颖莎4比0战胜对手
  • 林诗栋/蒯曼混双取胜,国乒赢得多哈世乒赛开门红