You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Include/nmNum/nmRender/nmWxVTKRenderContainerWidget.h

207 lines
9.2 KiB
C

#ifndef NMWXVTKRENDERCONTAINERWIDGET_H
#define NMWXVTKRENDERCONTAINERWIDGET_H
#include "nmRender_global.h"
#include "nmVTKViewCommandController.h"
#include <QWidget>
#include <vtkSmartPointer.h>
class QLabel;
class QEvent;
class QMenu;
class QStackedWidget;
class QVBoxLayout;
class QVTKWidget;
class nmVTKCameraController;
class nmVTKImageExporter;
class nmVTKInteractionManager;
class nmVTKOrientationMarkerController;
class nmVTKRotationCenterMarkerLayer;
class nmVTKRotationCenterPicker;
class nmVTKScene;
class vtkProp;
class vtkRenderer;
class vtkRenderWindow;
class vtkRenderWindowInteractor;
class vtkInteractorStyle;
/**
* @brief Qt + VTK
*
* Renderer Scene Scene
* Actor Scene
* Scene
*/
class NM_RENDER_EXPORT nmWxVTKRenderContainerWidget : public QWidget
{
Q_OBJECT
public:
/** @brief 创建独立的 VTK 显示外壳,并初始化场景、相机、交互和方向轴服务。 */
explicit nmWxVTKRenderContainerWidget(QWidget* pParent = nullptr);
/** @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 返回业务 Sceneclear() 不影响容器内部系统图层。 */
nmVTKScene* getScene() const;
/** @brief 返回当前容器独占的通用命令控制器非所有权指针。 */
nmVTKViewCommandController* getViewCommandController() const;
/** @brief 返回当前容器独占的方向轴控制器非所有权指针。 */
nmVTKOrientationMarkerController*
getOrientationMarkerController() const;
/** @brief 设置工具栏和右键菜单可使用的通用命令集合。 */
void setViewCommandCapabilities(
nmVTKViewCommandController::ViewCommands eCommands);
/** @brief 注册唯一可拾取几何;传入 nullptr 会取消模式并隐藏中心标记。 */
void setRotationCenterPickTarget(vtkProp* pTarget);
/** @brief 返回当前是否正在等待用户选择旋转中心。 */
bool isRotationCenterPicking() const;
/** @brief 隐藏旋转中心标记,不修改独立中心或相机且不主动渲染。 */
void hideRotationCenterMarker();
/** @brief 安装临时交互样式,并由容器保持其 VTK 引用。 */
bool installInteractionStyle(vtkInteractorStyle* pStyle);
/** @brief 将 Interactor 恢复为当前容器独占的默认相机交互样式。 */
bool restoreDefaultInteraction();
/** @brief 清除活动交互模式,但保留容器对 Interactor 的绑定。 */
void clearInteractionStyle();
/** @brief 提交一次渲染;无有效 RenderWindow 时安全返回。 */
void renderView();
/**
* @brief 沿 +Z
*
* 使 renderView
*/
bool fitTopViewWithoutRender();
/** @brief 将独立旋转中心设为可见边界中心,但不修改画面或立即渲染。 */
bool resetRotationCenterWithoutRender();
/** @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);
/** @brief 将容器确认后的拾取状态同步给公共 QAction。 */
void rotationCenterPickingChanged(bool bPicking);
public slots:
/** @brief 按固定倍率 1.2 放大,成功后统一渲染一次。 */
void zoomIn();
/** @brief 按固定倍率 1.0 / 1.2 缩小。 */
void zoomOut();
/** @brief 保持观察方向和投影方式,仅适配当前可见边界。 */
void fitView();
/** @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();
/** @brief 请求开始或取消一次性旋转中心拾取模式。 */
void setRotationCenterPickingEnabled(bool bEnabled);
protected:
/** @brief 优先处理拾取事件,再处理 QVTKWidget 的右键菜单。 */
virtual bool eventFilter(QObject* pObject, QEvent* pEvent);
private slots:
/** @brief 焦点切换完成后取消仍处于活动或待消费释放状态的拾取。 */
void cancelRotationCenterPickingAfterFocusOut();
/** @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 修改独立中心和可选标记但不渲染,由外层统一提交画面。 */
bool applyRotationCenter(double dX,
double dY,
double dZ,
bool bShowMarker);
/** @brief 取消模式、恢复光标并同步 QAction不修改既有中心标记。 */
void cancelRotationCenterPicking();
/** @brief 处理一次拾取事件;返回 true 表示事件必须停止向 VTK 传播。 */
bool handleRotationCenterPickEvent(QEvent* pEvent);
/** @brief 仅同步 Marker 世界几何,不主动渲染。 */
void synchronizeRotationCenterMarker();
/** @brief Ready、能力、主目标及独立中心均有效时显示标记。 */
void updateRotationCenterMarkerVisibility();
/** @brief 按目标、Marker 和当前交互样式同步命令的额外可用条件。 */
void updateRotationCenterCommandAvailability();
/** @brief 通过系统 Scene 稳定 ID 校验 Marker Layer 非所有权指针。 */
nmVTKRotationCenterMarkerLayer* getRotationCenterMarkerLayer() const;
/** @brief 判断调用线程是否为 Qt GUI 线程。 */
bool isGuiThread() const;
// Qt 对象由父子关系拥有,以下成员只是便于访问的非所有权指针。
QVBoxLayout* m_pMainLayout;
QStackedWidget* m_pStateStack;
QWidget* m_pStatePage;
QLabel* m_pStateLabel;
QVTKWidget* m_pVtkWidget;
// Renderer 与通用服务均为当前容器实例独占,不与其他视图共享状态。
vtkSmartPointer<vtkRenderer> m_pRenderer;
nmVTKScene* m_pScene; ///< 公开给业务控制器的图层集合。
nmVTKScene* m_pSystemScene; ///< 容器私有装饰图层集合,不对外暴露。
nmVTKCameraController* m_pCameraController;
nmVTKInteractionManager* m_pInteractionManager;
nmVTKImageExporter* m_pImageExporter;
nmVTKViewCommandController* m_pViewCommandController;
nmVTKOrientationMarkerController* m_pOrientationMarkerController;
nmVTKRotationCenterPicker* m_pRotationCenterPicker; ///< 本容器独占。
nmVTKRotationCenterMarkerLayer* m_pRotationCenterMarkerLayer; ///< 系统 Scene 所有。
};
#endif // NMWXVTKRENDERCONTAINERWIDGET_H