VTK|结合qt创建通用按钮控制显隐(边框、坐标轴、点线面) ...

打印 上一主题 下一主题

主题 1732|帖子 1732|积分 5196

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
增加边框BoundingBox

增加边框BoundingBox并通过按钮控制显隐
必要的全局变量
  1.     // 显示场景
  2.     QVTKOpenGLWidget *m_pScene;
  3.     vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow_;
  4.     vtkSmartPointer<vtkRenderer> renderer_;
  5.     // 边框显示
  6.     vtkSmartPointer<vtkActor> boundingBoxActor_; // 用于存储BoundingBox的Actor
  7.     bool isBoundingBoxVisible_;                  // 控制BoundingBox的显隐状态
  8.     vtkSmartPointer<vtkTextActor> boundingBoxButtonActor_;
复制代码
添加addBoundingBox

  1. void ThreeDimensionalDisplayPage::addBoundingBox(vtkSmartPointer<vtkPolyData> polyData)
  2. {
  3.     if (boundingBoxActor_)
  4.     {
  5.         renderer_->RemoveActor(boundingBoxActor_);
  6.         boundingBoxActor_ = nullptr;
  7.     }
  8.     vtkNew<vtkOutlineFilter> outlineFilter;
  9.     outlineFilter->SetInputData(polyData);
  10.     outlineFilter->Update();
  11.     vtkNew<vtkPolyDataMapper> outlineMapper;
  12.     outlineMapper->SetInputConnection(outlineFilter->GetOutputPort());
  13.     boundingBoxActor_ = vtkSmartPointer<vtkActor>::New();
  14.     boundingBoxActor_->SetMapper(outlineMapper);
  15.     boundingBoxActor_->GetProperty()->SetColor(1.0, 0.0, 0.0);
  16.     boundingBoxActor_->GetProperty()->SetLineWidth(2.0);
  17.     boundingBoxActor_->SetVisibility(isBoundingBoxVisible_); // 根据状态决定是否显示
  18.     renderer_->AddActor(boundingBoxActor_);
  19. }
复制代码
添加BoundingBox控制按钮

  1. void ThreeDimensionalDisplayPage::addBoundingBoxControlButton()
  2. {
  3.     // 避免重复添加
  4.     if (boundingBoxButtonActor_ && renderer_->HasViewProp(boundingBoxButtonActor_))
  5.         return;
  6.     vtkNew<vtkTextActor> textActor;
  7.     textActor->SetInput("Hide Bounding Box");
  8.     vtkTextProperty *textProp = textActor->GetTextProperty();
  9.     textProp->SetFontSize(24);
  10.     textProp->SetColor(0.0, 0.0, 0.0);           // 黑色文字
  11.     textProp->SetBackgroundColor(0.8, 0.8, 0.8); // 灰色背景
  12.     textProp->SetBackgroundOpacity(1.0);
  13.     textProp->SetFrame(1);
  14.     textProp->SetFrameColor(0.0, 0.0, 0.0);
  15.     textActor->SetDisplayPosition(10, 10);
  16.     renderer_->AddActor2D(textActor);
  17.     boundingBoxButtonActor_ = textActor;
  18.     // 注册鼠标点击事件(只注册一次)
  19.     static bool observerAdded = false;
  20.     if (!observerAdded)
  21.     {
  22.         vtkNew<vtkCallbackCommand> clickCallback;
  23.         clickCallback->SetClientData(this);
  24.         clickCallback->SetCallback([](vtkObject *caller, unsigned long, void *clientData, void *)
  25.                                    {
  26.             auto *self = static_cast<ThreeDimensionalDisplayPage *>(clientData);
  27.             int *clickPos = static_cast<vtkRenderWindowInteractor *>(caller)->GetEventPosition();
  28.             int x = clickPos[0];
  29.             int y = clickPos[1];
  30.             // 判断是否点击在按钮上(近似判断)
  31.             int *pos = self->boundingBoxButtonActor_->GetPositionCoordinate()->GetComputedDisplayValue(self->renderer_);
  32.             int btnX = pos[0];
  33.             int btnY = pos[1];
  34.             int width = 220, height = 40;
  35.             if (x >= btnX && x <= btnX + width &&
  36.                 y >= btnY && y <= btnY + height)
  37.             {
  38.                 self->OnBoundingBoxButtonClicked();
  39.             } });
  40.         interactor_->AddObserver(vtkCommand::LeftButtonPressEvent, clickCallback);
  41.         observerAdded = true;
  42.     }
  43.     isBoundingBoxVisible_ = true;
  44. }
复制代码
点击按钮之后的槽函数

  1. void ThreeDimensionalDisplayPage::OnBoundingBoxButtonClicked()
  2. {
  3.     if (!boundingBoxActor_)
  4.         return;
  5.     isBoundingBoxVisible_ = !isBoundingBoxVisible_;
  6.     boundingBoxActor_->SetVisibility(isBoundingBoxVisible_);
  7.     if (boundingBoxButtonActor_)
  8.     {
  9.         boundingBoxButtonActor_->SetInput(isBoundingBoxVisible_ ? "Hide Bounding Box" : "Show Bounding Box");
  10.     }
  11.     renderWindow_->Render();
  12. }
复制代码
添加坐标轴

必要的全局变量,防止重复创建
  1.     // 坐标轴显示
  2.     vtkSmartPointer<vtkAxesActor> axes_;
  3.     vtkSmartPointer<vtkOrientationMarkerWidget> marker_;
复制代码
创建坐标轴
  1. void ThreeDimensionalDisplayPage::addCoordinateAxes()
  2. {
  3.     if (!axes_)
  4.         axes_ = vtkSmartPointer<vtkAxesActor>::New();
  5.     axes_->SetTotalLength(10.0, 10.0, 10.0);
  6.     if (!marker_)
  7.         marker_ = vtkSmartPointer<vtkOrientationMarkerWidget>::New();
  8.     marker_->SetOrientationMarker(axes_);
  9.     marker_->SetOutlineColor(0.9300, 0.5700, 0.1300);
  10.     marker_->SetInteractor(m_pScene->GetInteractor());
  11.     marker_->SetDefaultRenderer(renderer_);
  12.     marker_->SetViewport(0.8, 0.0, 1.0, 0.2);
  13.     marker_->SetEnabled(1);
  14.     marker_->InteractiveOn();
  15. }
复制代码
增加点线面显隐控制按钮

必要的全局变量,防止重复创建
  1.     // 添加控制点线面显隐的按钮到三维显示界面
  2.     void addObjVisibilityControlButtons();
  3.     // 控制面显示槽函数
  4.     void toggleSurfaceVisibility();
  5.     // 控制线显示槽函数
  6.     void toggleWireframeVisibility();
  7.     // 控制点显示槽函数
  8.     void togglePointsVisibility();
  9.     // 控制obj点线面的显隐
  10.     vtkSmartPointer<vtkActor> surfaceActor_;
  11.     vtkSmartPointer<vtkActor> wireframeActor_;
  12.     vtkSmartPointer<vtkActor> pointsActor_;
  13.     // 控制obj点线面显隐的按钮
  14.     vtkSmartPointer<vtkTextActor> surfaceToggleButton_;
  15.     vtkSmartPointer<vtkTextActor> wireframeToggleButton_;
  16.     vtkSmartPointer<vtkTextActor> pointsToggleButton_;
复制代码
添加控制点线面显隐的按钮到三维表现界面

  1. void ThreeDimensionalDisplayPage::addObjVisibilityControlButtons()
  2. {
  3.     // 如果已经创建过按钮,则直接重新添加到 renderer_
  4.     if (surfaceToggleButton_)
  5.     {
  6.         surfaceToggleButton_->SetInput("Hide Surface");
  7.         wireframeToggleButton_->SetInput("Hide Wireframe");
  8.         pointsToggleButton_->SetInput("Hide Points");
  9.         renderer_->AddActor2D(surfaceToggleButton_);
  10.         renderer_->AddActor2D(wireframeToggleButton_);
  11.         renderer_->AddActor2D(pointsToggleButton_);
  12.         return;
  13.     }
  14.     // 按钮文字及初始状态
  15.     std::vector<std::pair<std::string, vtkSmartPointer<vtkTextActor> *>> buttons = {
  16.         {"Hide Surface", &surfaceToggleButton_},
  17.         {"Hide Wireframe", &wireframeToggleButton_},
  18.         {"Hide Points", &pointsToggleButton_}};
  19.     int startY = 60; // 初始 Y 位置
  20.     for (auto &[text, actorPtr] : buttons)
  21.     {
  22.         auto textActor = vtkSmartPointer<vtkTextActor>::New();
  23.         textActor->SetInput(text.c_str());
  24.         auto *textProp = textActor->GetTextProperty();
  25.         textProp->SetFontSize(20);
  26.         textProp->SetColor(0.0, 0.0, 0.0);
  27.         textProp->SetBackgroundColor(0.9, 0.9, 0.9);
  28.         textProp->SetBackgroundOpacity(1.0);
  29.         textProp->SetFrame(1);
  30.         textProp->SetFrameColor(0.0, 0.0, 0.0);
  31.         textActor->SetDisplayPosition(10, startY);
  32.         renderer_->AddActor2D(textActor);
  33.         *actorPtr = textActor;
  34.         startY += 50; // 下一个按钮向下偏移
  35.     }
  36.     // 注册鼠标事件(只注册一次)
  37.     static bool observerAdded = false;
  38.     if (!observerAdded)
  39.     {
  40.         vtkNew<vtkCallbackCommand> clickCallback;
  41.         clickCallback->SetClientData(this);
  42.         clickCallback->SetCallback([](vtkObject *caller, unsigned long, void *clientData, void *)
  43.                                    {
  44.             auto* self = static_cast<ThreeDimensionalDisplayPage*>(clientData);
  45.             int* clickPos = static_cast<vtkRenderWindowInteractor*>(caller)->GetEventPosition();
  46.             int x = clickPos[0];
  47.             int y = clickPos[1];
  48.             std::vector<std::pair<vtkSmartPointer<vtkTextActor>, std::function<void()>>> buttons = {
  49.                 {self->surfaceToggleButton_, [&]() { self->toggleSurfaceVisibility(); }},
  50.                 {self->wireframeToggleButton_, [&]() { self->toggleWireframeVisibility(); }},
  51.                 {self->pointsToggleButton_, [&]() { self->togglePointsVisibility(); }}
  52.             };
  53.             for (auto& [actor, func] : buttons)
  54.             {
  55.                 int* pos = actor->GetPositionCoordinate()->GetComputedDisplayValue(self->renderer_);
  56.                 int bx = pos[0];
  57.                 int by = pos[1];
  58.                 int width = 200, height = 40;
  59.                 if (x >= bx && x <= bx + width &&
  60.                     y >= by && y <= by + height)
  61.                 {
  62.                     func();
  63.                     break;
  64.                 }
  65.             } });
  66.         interactor_->AddObserver(vtkCommand::LeftButtonPressEvent, clickCallback);
  67.         observerAdded = true;
  68.     }
  69. }
复制代码
控制面表现槽函数

  1. void ThreeDimensionalDisplayPage::toggleSurfaceVisibility()
  2. {
  3.     if (surfaceActor_)
  4.     {
  5.         bool visible = surfaceActor_->GetVisibility();
  6.         surfaceActor_->SetVisibility(!visible);
  7.         if (surfaceToggleButton_)
  8.             surfaceToggleButton_->SetInput(visible ? "Show Surface" : "Hide Surface");
  9.         renderWindow_->Render();
  10.     }
  11. }
复制代码
控制线表现槽函数

  1. void ThreeDimensionalDisplayPage::toggleWireframeVisibility()
  2. {
  3.     if (wireframeActor_)
  4.     {
  5.         bool visible = wireframeActor_->GetVisibility();
  6.         wireframeActor_->SetVisibility(!visible);
  7.         if (wireframeToggleButton_)
  8.             wireframeToggleButton_->SetInput(visible ? "Show Wireframe" : "Hide Wireframe");
  9.         renderWindow_->Render();
  10.     }
  11. }
复制代码
控制点表现槽函数

  1. void ThreeDimensionalDisplayPage::togglePointsVisibility()
  2. {
  3.     if (pointsActor_)
  4.     {
  5.         bool visible = pointsActor_->GetVisibility();
  6.         pointsActor_->SetVisibility(!visible);
  7.         if (pointsToggleButton_)
  8.             pointsToggleButton_->SetInput(visible ? "Show Points" : "Hide Points");
  9.         renderWindow_->Render();
  10.     }
  11. }
复制代码
也可以使用qpushbutton举行控制,逻辑更加简单,不必要场景里添加按钮了,创建按钮后直接连接toggleSurfaceVisibility即可。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张春

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表