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/nmSubWxs/nmWxPebiResultViewWidget.h

288 lines
14 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#ifndef NMWXPEBIRESULTVIEWWIDGET_H
#define NMWXPEBIRESULTVIEWWIDGET_H
#include "iDlgBase.h"
#include "nmSubWxs_global.h"
#include "nmPebiResultFilterSettings.h"
#include <QMap>
#include <QPointer>
#include <QSharedPointer>
#include <QString>
#include <QWidget>
class QAction;
class QCheckBox;
class QComboBox;
class QLabel;
class QLineEdit;
class QMenu;
class QPushButton;
class QToolBar;
class iUnitGroup;
class nmDataAnalyzeManager;
class nmWxPebiResultRegionState;
class nmWxPebiVolumeState;
struct nmVolumeSliceSettings;
class nmPebiResultSceneController;
class nmPebiResultSnapshot;
class nmWxPebiResultControlBar;
class nmWxVTKRenderContainerWidget;
class vtkObject;
/** @brief 编辑并原子提交当前结果窗口的独立单元筛选条件。 */
class NM_SUB_WXS_EXPORT nmWxPebiResultFilterSettingsDlg : public iDlgBase
{
Q_OBJECT
public:
/** @param pSceneController 与 pControlBar 均为模态对话框期间有效的非所有权指针。 */
explicit nmWxPebiResultFilterSettingsDlg(
nmPebiResultSceneController* pSceneController,
nmWxPebiResultControlBar* pControlBar,
QWidget* pParent = nullptr);
virtual ~nmWxPebiResultFilterSettingsDlg();
signals:
/** @brief Apply 或 OK 已成功提交筛选条件。 */
void filterSettingsApplied();
private slots:
void onApplyClicked(); ///< 提交但保持对话框打开。
void onOkClicked(); ///< 提交成功后关闭对话框。
void onPropertyChanged(int nIndex); ///< 载入属性完整范围和单位。
void onDisplayUnitChanged(int nIndex); ///< 换算上下限的临时显示单位。
void refreshEditorEnabledState(); ///< 同步条件编辑控件可用性。
private:
Q_DISABLE_COPY(nmWxPebiResultFilterSettingsDlg)
void createUi();
bool initializeFromScene();
bool initializeUnitEditor(const QString& sPropertyId);
bool populateSettings(const nmPebiResultFilterSettings& oSettings);
bool collectSettings(nmPebiResultFilterSettings& oSettings,
QString& sError) const;
bool applyEditor();
bool setPropertyRange(const QString& sPropertyId);
QString formatValue(double dValue) const;
bool parseFiniteValue(const QString& sText, double& dValue) const;
bool convertUnitValue(double dSourceValue,
const QString& sSourceUnit,
const QString& sDestinationUnit,
double& dDestinationValue) const;
nmPebiResultSceneController* m_pSceneController; ///< 非所有权 Scene 真源。
nmWxPebiResultControlBar* m_pControlBar; ///< 非所有权播放和导出状态源。
quint64 m_nExpectedBindingRevision; ///< 打开时的成功绑定序号。
QString m_sExpectedSnapshotId; ///< 打开时的快照稳定 ID。
QString m_sExpectedDisplayPropertyId; ///< 打开时的着色属性 ID。
int m_nExpectedDisplayFrameIndex; ///< 打开时的着色帧。
QMap<QString, QPair<double, double> > m_mapPropertyRanges; ///< 冻结范围。
QString m_sBaseUnit; ///< 当前筛选属性的数据层基础单位。
QString m_sDisplayUnit; ///< 当前对话框选择的临时显示单位。
iUnitGroup* m_pUnitGroup; ///< 全局单位框架拥有,未找到时为空。
nmPebiResultFilterSettings m_oBaselineSettings; ///< 最近成功 Apply 条件。
bool m_bInitialized; ///< 是否完整取得初始 Scene 状态。
QCheckBox* m_pEnableCheck;
QComboBox* m_pPropertyCombo;
QCheckBox* m_pMinimumCheck;
QLineEdit* m_pMinimumEdit;
QCheckBox* m_pMaximumCheck;
QLineEdit* m_pMaximumEdit;
QComboBox* m_pUnitCombo; ///< 上下限共用的临时显示单位。
QPushButton* m_pApplyButton;
QPushButton* m_pOkButton;
};
/**
* @brief 独立的 PEBI 结果场景组合窗口。
*
* 本控件显式观察 DataManager,只组合通用渲染容器、结果 SceneController、
* 底部控制条和右侧 QAction。Manager 当前状态与 Scene 最后成功显示状态分别
* 缓存,因此新快照绑定失败时可以继续检查旧画面。
*/
class NM_SUB_WXS_EXPORT nmWxPebiResultViewWidget : public QWidget
{
Q_OBJECT
public:
/**
* @param pDataManager 非所有权对象,可为空;销毁后窗口自动进入空状态。
* @note 非空 Manager 必须与本窗口同属 Qt GUI 线程。
*/
explicit nmWxPebiResultViewWidget(
nmDataAnalyzeManager* pDataManager,
QWidget* pParent = nullptr);
/** @brief 按控制条、SceneController、渲染容器的顺序解除窗口资源。 */
virtual ~nmWxPebiResultViewWidget();
/**
* @brief 切换显式 Manager;相同指针只同步,不清空当前相机和场景。
* @note 跨线程 Manager 会被拒绝,避免同步读取快照引用时发生数据竞争。
*/
void setDataManager(nmDataAnalyzeManager* pDataManager);
/** @brief 返回当前观察的 Manager;对象销毁后自动返回空指针。 */
nmDataAnalyzeManager* getDataManager() const;
/** @brief 合并重入请求并读取 Manager 最新结果状态。 */
void synchronizeFromDataManager();
/**
* @brief 异步导入单个外部三维文件;也供未来文件拖放入口复用。
* @return 已启动任务返回 true;忙碌或路径为空返回 false,当前画面不变。
*/
bool importVolumeFile(const QString& sFilePath);
/** @brief 返回当前是否正在显示外部三维数据,而非正式计算结果。 */
bool isImportedVolumeMode() const;
private slots:
/** @brief 在完整模型与已应用截面之间切换,首次启用时计算中心截面。 */
void onVolumeSliceToggled(bool bEnabled);
/** @brief 按需打开非模态参数窗口,并绑定当前数据的辅助平面。 */
void onShowVolumeSliceSettings();
/** @brief 校验窗口草稿并事务式提交一次截面。 */
void onApplyVolumeSlice();
/** @brief 将有效参数草稿同步到辅助平面,绝不执行切片计算。 */
void onVolumeSliceDraftChanged();
/** @brief 即时更新辅助平面和原模型的显示偏好。 */
void onVolumeSliceDisplayChanged(bool bShowPlane, bool bShowSource);
/** @brief 隐藏窗口时解绑辅助平面,保留已应用截面。 */
void onVolumeSliceDialogHidden();
/** @brief 接收经过队列合并的拖动预览,检查数据身份后同步输入框。 */
void onVolumeSlicePreview(const QString& sDataId, const nmVolumeSliceSettings& oSettings);
/** @brief 处理松手请求;再次检查当前模型和模式,然后应用当前有效草稿。 */
void onVolumeSliceDragApplied(const QString& sDataId, const nmVolumeSliceSettings& oSettings);
/** @brief 根据窗口、加载任务及旋转中心拾取状态,统一控制平面交互可用性。 */
void synchronizeSliceInteraction();
/** @brief 在当前场景事务结束后的事件循环刷新手柄显隐,避免拾取时残留旧画面。 */
void refreshVolumeSliceView();
/** @brief 从切片菜单选择文件,再启动可取消后台导入。 */
void onImportVolumeRequested();
/** @brief 原子标记取消;不等待或强行终止 Reader。 */
void onCancelVolumeImport();
/** @brief 在线程结束后准备候选场景,成功才提交外部模型画面。 */
void onVolumeImportFinished();
/** @brief 返回仍有效的原结果或最新结果;绑定失败保留外部模型。 */
void onReturnToCalculationResult();
/** @brief 响应快照身份、存在性或新鲜度变化,不响应结果井选择。 */
void onPebiResultStateChanged();
/** @brief Manager 析构时不再读取其成员,直接停止播放并清理场景。 */
void onDataManagerDestroyed(QObject* pObject);
/** @brief 将业务显隐 QAction 追加到通用右键菜单。 */
void appendContextMenuActions(QMenu* pMenu);
/** @brief 转发非阻塞操作错误,但不覆盖绑定失败提示。 */
void onControlOperationFailed(const QString& sError);
/** @brief 明确操作成功后清除旧普通错误,不影响绑定失败状态。 */
void onControlOperationSucceeded();
/** @brief 将 QVTK 视口尺寸同步给结果场景,不主动触发额外渲染。 */
void onViewportSizeChanged(int nWidth, int nHeight);
/** @brief 冻结当前显示状态并执行独立离屏动画导出。 */
void onExportAnimationRequested();
/** @brief 在播放和导出状态防御后打开数据筛选对话框。 */
void onShowFilterSettings();
/** @brief 开始、取消区域压力绘制,或重新显示既有统计面板。 */
void onRegionPressureStatisticsTriggered();
/** @brief 在 VTK 观察者返回后安全处理完成、取消或无效绘制事件。 */
void processPendingRegionInteractionEvent();
/** @brief 同步业务动作并按当前 pressure 帧至多重算一次区域统计。 */
void onResultDisplayStateChanged();
/** @brief 关闭面板并清除区域、统计缓存和闭合轮廓。 */
void onCloseRegionPressureStatistics();
/** @brief 切换色标显隐。 */
void onScalarBarToggled(bool bVisible);
/** @brief 切换比例网格显隐。 */
void onScaleGridToggled(bool bVisible);
/** @brief 切换二维井名显隐。 */
void onWellNamesToggled(bool bVisible);
/** @brief 从 Scene、播放和导出状态统一刷新业务动作。 */
void synchronizeBusinessActions();
private:
Q_DISABLE_COPY(nmWxPebiResultViewWidget)
/** @brief 创建唯一渲染容器、SceneController、工具栏、提示栏和控制条。 */
void createUi();
/** @brief 执行一次非重入的 Manager 最新状态读取和事务提交。 */
void synchronizeOnce();
/** @brief 停止播放、清理 Scene,并把所有业务控件同步为空状态。 */
void clearSceneAndControls(const QString& sEmptyMessage);
/** @brief 保存本轮已经观察到的 Manager 快照身份和新鲜度。 */
void rememberObservedState(
const QSharedPointer<const nmPebiResultSnapshot>& pSnapshot,
const QString& sSnapshotId,
bool bCurrent);
/** @brief 按绑定失败、操作错误的优先级刷新提示栏,无错误时隐藏。 */
void refreshStatusBar();
/** @brief 断开当前 Manager 的两个连接,不访问已经析构的对象。 */
void disconnectDataManager();
/** @brief 汇总播放、导出、绘制和导入任务状态,判定是否允许开始导入。 */
bool canImportVolume() const;
/** @brief 同步切片菜单及外部模式下的业务动作,不触发渲染。 */
void synchronizeVolumeActions();
/** @brief 关闭参数窗口并解绑平面,不渲染;释放数据时同时解除对旧模型的引用。 */
void closeVolumeSliceSettings(bool bReleaseData);
/** @brief 创建区域图层和临时交互样式,并冻结当前 pressure 显示身份。 */
bool startRegionPressureDrawing();
/** @brief 解除临时交互、观察者和控制条锁,不修改已准备的统计区域。 */
void stopRegionPressureDrawing();
/** @brief 清除区域计算与轮廓,可选择提交一次画面刷新。 */
void clearRegionPressureSelection(bool bRenderView);
/** @brief 移除区域图层和面板,供析构在其他渲染对象之前安全收尾。 */
void destroyRegionPressureState();
/** @brief 确保业务 Scene 中存在本窗口独占的区域轮廓图层。 */
bool ensureRegionPressureLayer();
/** @brief 按当前 pressure 帧刷新缓存和面板,相同帧不重复计算。 */
void updateRegionPressureStatistics();
/** @brief 首次需要时创建非模态区域统计面板。 */
void ensureRegionPressureStatisticsDialog();
/** @brief 从最近一次统计结果刷新面板文字,不改变面板显隐。 */
void refreshRegionPressureStatisticsDialog();
/** @brief 显示、前置并激活已经创建的区域统计面板。 */
void showRegionPressureStatisticsDialog();
/** @brief 返回当前是否仍处于多边形绘制事务。 */
bool isRegionPressureDrawing() const;
/** @brief 将 VTK 多边形事件复制到窗口状态并排队到 Qt 事件循环。 */
static void handleRegionPolygonEvent(vtkObject* pCaller,
unsigned long nEventId,
void* pClientData,
void* pCallData);
QPointer<nmDataAnalyzeManager> m_pDataManager; ///< 当前显式注入的 Manager。
nmWxVTKRenderContainerWidget* m_pRenderContainer; ///< 唯一通用 VTK 容器。
nmPebiResultSceneController* m_pSceneController; ///< 唯一结果场景控制器。
nmWxPebiResultControlBar* m_pControlBar; ///< 独占回放控制器和 Timer 的底栏。
QToolBar* m_pToolBar; ///< Qt 父对象拥有的右侧竖向工具栏。
QLabel* m_pStatusLabel; ///< 绑定失败或操作错误的非阻塞提示栏。
QAction* m_pScalarBarAction; ///< 色标显隐动作。
QAction* m_pScaleGridAction; ///< 比例网格显隐动作。
QAction* m_pWellNamesAction; ///< 二维井名显隐动作。
QAction* m_pFilterAction; ///< 打开数据筛选设置的共享动作。
QAction* m_pRegionPressureAction; ///< 绘制区域或显示压力统计的共享动作。
nmWxPebiResultRegionState* m_pRegionState; ///< 独占区域交互、计算和面板状态。
nmWxPebiVolumeState* m_pVolumeState; ///< 独占外部模式、导入线程及待恢复视图状态。
/** @brief Manager 最近一次通知后观察到的快照强引用。 */
QSharedPointer<const nmPebiResultSnapshot> m_pObservedSnapshot;
/** @brief Manager 最近一次通知后观察到的稳定 Snapshot ID。 */
QString m_sObservedSnapshotId;
/** @brief 最近观察到的快照是否仍与当前输入版本一致。 */
bool m_bObservedSnapshotCurrent;
/** @brief 是否已经建立过一份可用于去重的 Manager 观察状态。 */
bool m_bObservedStateValid;
/** @brief Scene 最后一次成功绑定的快照强引用,与观察状态相互独立。 */
QSharedPointer<const nmPebiResultSnapshot> m_pDisplayedSnapshot;
/** @brief Scene 最后一次成功绑定的稳定 Snapshot ID。 */
QString m_sDisplayedSnapshotId;
QString m_sBindingError; ///< 最新 Manager 快照绑定失败的高优先级错误。
QString m_sOperationError; ///< 当前控制条普通操作错误。
bool m_bSynchronizing; ///< 防止 VTK 提交期间递归进入同步。
bool m_bSyncPending; ///< 重入时记录一次待处理请求,结束后循环读取最新状态。
};
#endif // NMWXPEBIRESULTVIEWWIDGET_H