#ifndef NMWXVTKRENDERCONTAINERWIDGET_H #define NMWXVTKRENDERCONTAINERWIDGET_H #include "nmRender_global.h" #include #include class QLabel; class QEvent; class QMenu; class QStackedWidget; class QVBoxLayout; class QVTKWidget; class nmVTKCameraController; class nmVTKImageExporter; class nmVTKInteractionManager; class nmVTKScene; class vtkRenderer; class vtkRenderWindow; class vtkRenderWindowInteractor; class vtkInteractorStyle; /** * @brief 可组合的 Qt + VTK 通用渲染容器。 * * 容器独占 Renderer、Scene、相机和交互管理器,但不创建任何业务 Actor。 * 调用方通过 Scene 组织图层,并在一批修改完成后显式调用 renderView。 */ class NM_RENDER_EXPORT nmWxVTKRenderContainerWidget : public QWidget { Q_OBJECT public: /** @brief 创建独立的 VTK 显示外壳,并初始化场景、相机和交互服务。 */ explicit nmWxVTKRenderContainerWidget(QWidget* pParent = NULL); /** @brief 严格按交互、图层、相机、Renderer 的逆序解除资源。 */ virtual ~nmWxVTKRenderContainerWidget(); /** @brief 返回 Qt 承载控件;调用方不得删除或重新设置父对象。 */ QVTKWidget* getVtkWidget() const; /** @brief 返回当前容器独占的 Renderer 非所有权指针。 */ vtkRenderer* getRenderer() const; /** @brief 返回 QVTKWidget 持有的 RenderWindow 非所有权指针。 */ vtkRenderWindow* getRenderWindow() const; /** * @brief 返回 RenderWindow 的 Interactor 非所有权指针。 * @warning 不得直接替换其 InteractorStyle,应使用容器的交互模式接口。 */ vtkRenderWindowInteractor* getInteractor() const; /** @brief 返回当前容器独占的 Scene 非所有权指针。 */ nmVTKScene* getScene() const; /** @brief 安装临时交互样式,并由容器保持其 VTK 引用。 */ bool installInteractionStyle(vtkInteractorStyle* pStyle); /** @brief 将 Interactor 恢复为当前容器独占的默认相机交互样式。 */ bool restoreDefaultInteraction(); /** @brief 清除活动交互模式,但保留容器对 Interactor 的绑定。 */ void clearInteractionStyle(); /** @brief 提交一次渲染;无有效 RenderWindow 时安全返回。 */ void renderView(); /** * @brief 沿 +Z 方向设置正交顶视图并适配当前可见边界,但不立即渲染。 * * 供业务层批量替换几何时使用,调用方应在整批更新结束后统一 renderView。 */ bool fitTopViewWithoutRender(); /** @brief 切换到 VTK 页面并提交一次渲染。 */ void showReadyState(); /** @brief 显示无数据状态,消息由业务调用方提供。 */ void showEmptyState(const QString& sMessage); /** @brief 显示错误状态,消息由业务调用方提供。 */ void showErrorState(const QString& sMessage); /** @brief 显示渲染中状态,消息由业务调用方提供。 */ void showRenderingState(const QString& sMessage); signals: /** * @brief 在公共菜单构造期间同步发出,供调用方追加临时 QAction。 * @warning 接收方不得保存 pMenu;信号返回后菜单即由容器继续管理。 */ void contextMenuAboutToShow(QMenu* pMenu); public slots: /** @brief 恢复透视投影,并按当前可见 Prop 的边界适配相机。 */ void resetCamera(); /** @brief 沿 +Z 方向设置正交顶视图。 */ void setTopView(); /** @brief 沿 -Y 方向设置正交前视图。 */ void setFrontView(); /** @brief 沿 +X 方向设置正交右视图。 */ void setRightView(); /** @brief 设置透视等轴视图。 */ void setIsometricView(); /** @brief 平移相机焦点和位置,将指定世界坐标设为旋转中心。 */ void setRotationCenter(double dX, double dY, double dZ); /** @brief 将旋转中心恢复为当前可见边界的中心。 */ void resetRotationCenter(); protected: /** @brief 只消费 QVTKWidget 的右键按下事件,其余事件保持原分发链。 */ virtual bool eventFilter(QObject* pObject, QEvent* pEvent); private slots: /** @brief 弹出文件对话框并保存当前 RenderWindow 图像。 */ void saveImage(); /** @brief 将当前 RenderWindow 图像复制到系统剪贴板。 */ void copyImage(); /** @brief 打开系统打印对话框并输出当前图像。 */ void printImage(); /** @brief 打开打印预览对话框。 */ void printPreview(); private: Q_DISABLE_COPY(nmWxVTKRenderContainerWidget) enum ViewState { ViewState_Ready = 0, ///< 显示 VTK 渲染页面。 ViewState_Empty, ///< 显示无数据提示页面。 ViewState_Error, ///< 显示错误提示页面。 ViewState_Rendering ///< 显示渲染中提示页面。 }; /** @brief 统一设置非就绪状态的文字、颜色和当前页面。 */ void showMessageState(ViewState eState, const QString& sMessage); /** @brief 判断调用线程是否为 Qt GUI 线程。 */ bool isGuiThread() const; // Qt 对象由父子关系拥有,以下成员只是便于访问的非所有权指针。 QVBoxLayout* m_pMainLayout; QStackedWidget* m_pStateStack; QWidget* m_pStatePage; QLabel* m_pStateLabel; QVTKWidget* m_pVtkWidget; // Renderer 与四个通用服务均为当前容器实例独占,不与其他视图共享状态。 vtkSmartPointer m_pRenderer; nmVTKScene* m_pScene; nmVTKCameraController* m_pCameraController; nmVTKInteractionManager* m_pInteractionManager; nmVTKImageExporter* m_pImageExporter; }; #endif // NMWXVTKRENDERCONTAINERWIDGET_H