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

VTK|箱体切割器

文章目录

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

效果

请添加图片描述

实现类头文件

/*** @file BoxClipperController.h* @brief 该头文件定义了 BoxClipperController 类,用于管理基于盒子的网格数据裁剪操作。* @details 该类提供了使用 vtkBoxWidget 对网格数据进行裁剪的功能,允许用户通过交互方式调整裁剪盒子的位置和大小,*          并实时更新裁剪结果。* @author qtree* @date 2025年5月16日*/
#ifndef BOXCLIPPERCONTROLLER_H
#define BOXCLIPPERCONTROLLER_H#include <vtkSmartPointer.h>
#include <vtkCallbackCommand.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkObjectBase.h>class vtkRenderWindowInteractor;
class vtkBoxWidget;
class vtkPlanes;
class vtkClipPolyData;
class vtkPolyData;
class vtkActor;
class vtkRenderer;/*** @class BoxClipperController* @brief 用于管理基于盒子的网格数据裁剪操作的控制器类。** 该类提供了使用 vtkBoxWidget 对网格数据进行裁剪的功能,允许用户通过交互方式调整裁剪盒子的位置和大小,* 并实时更新裁剪结果。*/
class BoxClipperController
{
public:/*** @brief 构造函数。** 初始化 BoxClipperController 实例,并关联渲染窗口交互器和渲染器。** @param interactor 用于处理用户交互的渲染窗口交互器。* @param renderer 用于渲染裁剪结果的渲染器。*/BoxClipperController(vtkRenderWindowInteractor *interactor, vtkRenderer *renderer);/*** @brief 设置输入数据并替换原始的 Actor。** 该方法设置用于裁剪的输入网格数据,并将原始的 Actor 替换为裁剪后的 Actor。** @param input 用于裁剪的输入网格数据。* @param originalActor 原始的 Actor,将被裁剪后的 Actor 替换。*/void SetInputDataAndReplaceOriginal(vtkSmartPointer<vtkPolyData> input, vtkActor *originalActor);/*** @brief 启用或禁用裁剪功能。** 该方法控制 vtkBoxWidget 的显示和交互状态,从而启用或禁用裁剪功能。** @param enabled 若为 true,则启用裁剪功能;若为 false,则禁用裁剪功能。*/void SetEnabled(bool enabled);/*** @brief 获取裁剪后的 Actor。** 返回经过裁剪操作后生成的 Actor。** @return 裁剪后的 Actor 的智能指针。*/vtkSmartPointer<vtkActor> GetClippedActor();private:vtkSmartPointer<vtkBoxWidget> boxWidget;               ///< 用于用户交互的盒子小部件,用于定义裁剪区域vtkSmartPointer<vtkPlanes> clipPlanes;                 ///< 由盒子小部件定义的裁剪平面vtkSmartPointer<vtkClipPolyData> clipper;              ///< 用于执行裁剪操作的 VTK 过滤器vtkSmartPointer<vtkActor> clippedActor;                ///< 裁剪后的网格数据对应的 ActorvtkSmartPointer<vtkPolyData> inputData;                ///< 用于裁剪的输入网格数据vtkSmartPointer<vtkRenderer> renderer;                 ///< 用于渲染裁剪结果的渲染器vtkSmartPointer<vtkRenderWindowInteractor> interactor; ///< 用于处理用户交互的渲染窗口交互器vtkActor *originalActor;                               ///< 原始的 Actor,将被裁剪后的 Actor 替换/*** @brief 更新裁剪结果。** 当盒子小部件的位置或大小发生变化时,该方法会重新执行裁剪操作并更新裁剪后的 Actor。*/void UpdateClipping();
};#endif // BOXCLIPPERCONTROLLER_H

实现类源文件

#include "BoxClipperController.h"#include <vtkBoxWidget.h>
#include <vtkPlanes.h>
#include <vtkPolyData.h>
#include <vtkClipPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkCommand.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>BoxClipperController::BoxClipperController(vtkRenderWindowInteractor *interactor, vtkRenderer *renderer): interactor(interactor), renderer(renderer)
{originalActor = nullptr;// 裁剪用平面集(由 BoxWidget 生成)clipPlanes = vtkSmartPointer<vtkPlanes>::New();// 裁剪器:使用 box widget 的平面集进行裁剪clipper = vtkSmartPointer<vtkClipPolyData>::New();// 映射器连接裁剪器的输出vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();mapper->SetInputConnection(clipper->GetOutputPort());// 显示裁剪后模型的 actorclippedActor = vtkSmartPointer<vtkActor>::New();clippedActor->SetMapper(mapper);// 初始化 box widget 控件boxWidget = vtkSmartPointer<vtkBoxWidget>::New();boxWidget->SetInteractor(interactor); // 控制器绑定boxWidget->SetPlaceFactor(1.0);       // 控制缩放比例boxWidget->HandlesOn();               // 显示操作手柄// 添加裁剪更新事件监听器vtkSmartPointer<vtkCallbackCommand> callback = vtkSmartPointer<vtkCallbackCommand>::New();callback->SetClientData(this); // 把当前类传入回调中callback->SetCallback([](vtkObject *caller, unsigned long, void *clientData, void *callData){auto self = static_cast<BoxClipperController *>(clientData);self->UpdateClipping(); // 当 box widget 改变时更新裁剪});boxWidget->AddObserver(vtkCommand::InteractionEvent, callback); // 绑定观察者
}
// 设置原始输入数据与原始 actor(不拥有生命周期)
void BoxClipperController::SetInputDataAndReplaceOriginal(vtkSmartPointer<vtkPolyData> input, vtkActor *original)
{originalActor = original; // 不用智能指针,不控制生命周期inputData = input;clipper->SetInputData(inputData);boxWidget->SetInputData(inputData);boxWidget->PlaceWidget();UpdateClipping(); // 更新 planes 和裁剪结果
}void BoxClipperController::SetEnabled(bool enabled)
{boxWidget->SetEnabled(enabled ? 1 : 0); // 开启或关闭 box 控件if (enabled){if (originalActor && renderer->HasViewProp(originalActor)){renderer->RemoveActor(originalActor); // 移除原始 actor}renderer->AddActor(clippedActor); // 启用裁剪后显示 actor}else{renderer->RemoveActor(clippedActor);if (originalActor){renderer->AddActor(originalActor);}}renderer->GetRenderWindow()->Render();
}void BoxClipperController::UpdateClipping()
{vtkSmartPointer<vtkPlanes> planes = vtkSmartPointer<vtkPlanes>::New();boxWidget->GetPlanes(planes);     // 获取当前 box widget 对应的平面clipper->SetClipFunction(planes); // 使用这些平面裁剪clipper->InsideOutOn();           // 保留 box 内部数据clipper->Update();                // 更新裁剪结果
}vtkSmartPointer<vtkActor> BoxClipperController::GetClippedActor()
{return clippedActor;
}

如何调用

头文件声明

// 箱形剪控制器
std::unique_ptr<BoxClipperController> boxClipper_;
bool boxClipper_enabled_;

构造函数里初始化
切割需要把原来的模型隐藏才能看出切割后的,所以把原始数据和原模型都传递到类中控制显隐


boxClipper_ = std::make_unique<BoxClipperController>(interactor_, renderer_);
boxClipper_enabled_ = false;
boxClipper_->SetInputDataAndReplaceOriginal(cylinderSource->GetOutput(), testActor);

控制箱体切割器显隐按钮槽函数


connect(cross_section, &QPushButton::clicked, this, [=](){ boxClipper_enabled_ = !boxClipper_enabled_;boxClipper_->SetEnabled(boxClipper_enabled_); });

更新数据之后调用


boxClipper_->SetInputDataAndReplaceOriginal(vertexGlyphFilter->GetOutput(),ply_point_actor_);
boxClipper_enabled_ = false;
boxClipper_->SetEnabled(boxClipper_enabled_);

项目git链接

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

相关文章:

  • 【git进阶】git rebase(变基)
  • 前端子项目打包集成主项目实战指南
  • SOC-ESP32S3部分:1、ESP32开发IDF-5.4环境搭建
  • RV1126多线程获取SMARTP的GOP模式数据和普通GOP模式数据
  • 第二届parloo杯的RSA_Quartic_Quandary
  • 系统架构设计师考前冲刺笔记-第3章-软件架构设计
  • Pod 节点数量
  • 【Redis】快速列表结构
  • 没有公网ip怎么端口映射外网访问?使用内网穿透可以解决
  • upload-labs通关笔记-第12关 文件上传之白名单GET法
  • 氩气模块压力异常时的维修方法,要注意仪器的安全操作规范,避免对仪器造成二次损坏
  • Python训练营打卡 Day30
  • JavaWeb:Spring配置文件( @ConfigurationProperties)
  • centos把jar包配置成服务并设置开机自启
  • AIGC工具平台-卡通图片2D转绘3D
  • Docker构建 Dify 应用定时任务助手
  • linux系统双击EXE运行,在统信UOS上无缝运行EXE!统信Windows应用兼容引擎V3来了
  • PyTorch模型保存方式
  • 【软考-架构】15、软件架构的演化和维护
  • 力扣热题100之删除链表的倒数第N个节点
  • 李在明遭遇暗杀威胁,韩国警方锁定两名嫌疑人
  • 经济日报评论员:拧紧“带头过紧日子”的制度螺栓
  • 网约车司机猝死,平台和保险公司均拒绝赔偿,法院判了
  • 马上评|中药液涉嫌添加安眠药?药品安全儿戏不得
  • 国家统计局:4月全国规模以上工业增加值同比增长6.1%
  • 国家统计局:1-4月份,全国固定资产投资同比增长4.0%