|
|
|
|
|
#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 onRangeEdited(); ///< 用户输入时更新高精度提示,不改写正在编辑的文字。
|
|
|
|
|
|
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);
|
|
|
|
|
|
/** @brief 保存基础单位草稿并按成组格式回填两个显示字段。 */
|
|
|
|
|
|
void writeRangeValues(const double dBaseRange[2], const double dDisplayRange[2]);
|
|
|
|
|
|
/** @brief 未编辑边界沿用原值,已编辑边界按当前单位完整解析。 */
|
|
|
|
|
|
bool readRangeValue(int nIndex, double& dBaseValue, QString* pError = nullptr) 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 条件。
|
|
|
|
|
|
double m_dEditorBaseRange[2]; ///< 最近回填的完整精度基础单位草稿。
|
|
|
|
|
|
QString m_sRangeDisplayTexts[2]; ///< 最近回填的简洁文字,用于识别未编辑字段。
|
|
|
|
|
|
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
|