|
|
|
|
|
#include "zxLogInstance.h"
|
|
|
|
|
|
#include "ZxBaHelper.h"
|
|
|
|
|
|
#include "ZxResolutionHelper.h"
|
|
|
|
|
|
#include "zxSysUtils.h"
|
|
|
|
|
|
#include "ZxPtyDock.h"
|
|
|
|
|
|
#include "iDockBaseWx.h"
|
|
|
|
|
|
#include "ZxMainWindow.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "ZxSubAxisX.h"
|
|
|
|
|
|
#include "ZxSubAxisY.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "ZxPlot.h"
|
|
|
|
|
|
#include "ZxObjCurve.h"
|
|
|
|
|
|
#include "ZxSubTitle.h"
|
|
|
|
|
|
#include "tCurvePlotScene.h"
|
|
|
|
|
|
#include "tCurvePlotView.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "ZxTableView.h"
|
|
|
|
|
|
#include "ZxTableModel.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "mModuleDefines.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "ZxDataWell.h"
|
|
|
|
|
|
#include "ZxDataProject.h"
|
|
|
|
|
|
#ifdef QT_DEBUG
|
|
|
|
|
|
#include "ZxDataGaugeP.h"
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef QT_DEBUG
|
|
|
|
|
|
#include "nmXmlHelper.h"
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmSubWndGrid.h"
|
|
|
|
|
|
#include "nmDataDemo.h"
|
|
|
|
|
|
#include "nmDataLogFile.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmGuiPlot.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmPebiGridViewData.h"
|
|
|
|
|
|
#include "nmPebiGridViewDataBuilder.h"
|
|
|
|
|
|
#include "nmWxPebiGridViewWidget.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmCalculationUtils.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmCalculationPebiGrid.h"
|
|
|
|
|
|
#include "nmCalculationPebiGridTask.h"
|
|
|
|
|
|
#include "nmDataAnalyzeManager.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "QListWidget.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <QVector>
|
|
|
|
|
|
#include <QProcess>
|
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
|
#include <QStackedLayout>
|
|
|
|
|
|
|
|
|
|
|
|
#include "ZxRstWnd.h"
|
|
|
|
|
|
|
|
|
|
|
|
nmSubWndGrid::nmSubWndGrid(QWidget *parent,
|
|
|
|
|
|
QString sExt,
|
|
|
|
|
|
double pebiGridControl,
|
|
|
|
|
|
bool bGeneratePebiGrid,
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager) :
|
|
|
|
|
|
iSubWndBaseFit(parent, sExt),
|
|
|
|
|
|
m_mainLayout(nullptr),
|
|
|
|
|
|
m_pGridView(nullptr),
|
|
|
|
|
|
m_pDebounceTimer(nullptr),
|
|
|
|
|
|
m_pDataManager(nullptr),
|
|
|
|
|
|
m_pGridTask(nullptr),
|
|
|
|
|
|
m_pGridTaskDataManager(nullptr),
|
|
|
|
|
|
m_pGridGenerationDataManager(nullptr),
|
|
|
|
|
|
m_bGridUpdatePending(false),
|
|
|
|
|
|
m_dPebiGridControl(pebiGridControl),
|
|
|
|
|
|
m_bGeneratePebiGrid(bGeneratePebiGrid)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_sMdiWndType = s_MdiType_DataAnal;
|
|
|
|
|
|
setWindowTitle(tr("nmSubWndGrid"));
|
|
|
|
|
|
setDataManager(pDataManager);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nmSubWndGrid::~nmSubWndGrid()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_pDebounceTimer != nullptr) {
|
|
|
|
|
|
m_pDebounceTimer->stop();
|
|
|
|
|
|
}
|
|
|
|
|
|
// 外部 DLL 不支持安全中止;窗口析构前等待自己的任务退出,避免销毁运行中的 QThread。
|
|
|
|
|
|
if(!m_pGridTask.isNull() && m_pGridTask->isRunning()) {
|
|
|
|
|
|
disconnect(m_pGridTask, nullptr, this, nullptr);
|
|
|
|
|
|
m_pGridTask->wait();
|
|
|
|
|
|
}
|
|
|
|
|
|
// 窗口已经不再提交局部结果,必须结束登记,不能让求解永久等待。
|
|
|
|
|
|
endGridGenerationState(m_pGridGenerationDataManager.data(), false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::setDataManager(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
|
{
|
|
|
|
|
|
nmDataAnalyzeManager* pOldDataManager = m_pDataManager.data();
|
|
|
|
|
|
if(pOldDataManager == pDataManager) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 第一步:只解除旧分析与本窗口的连接,避免切换多次后旧分析继续触发重建。
|
|
|
|
|
|
if(pOldDataManager != nullptr) {
|
|
|
|
|
|
disconnect(pOldDataManager, SIGNAL(dataChanged()),
|
|
|
|
|
|
this, SLOT(onDataManagerChanged()));
|
|
|
|
|
|
// 切换后旧任务只允许自然结束并丢弃结果,不再阻塞旧分析的求解入口。
|
|
|
|
|
|
endGridGenerationState(pOldDataManager, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_pDataManager = pDataManager;
|
|
|
|
|
|
if(pDataManager != nullptr) {
|
|
|
|
|
|
connect(pDataManager, SIGNAL(dataChanged()),
|
|
|
|
|
|
this, SLOT(onDataManagerChanged()),
|
|
|
|
|
|
static_cast<Qt::ConnectionType>(
|
|
|
|
|
|
Qt::QueuedConnection | Qt::UniqueConnection));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 构造阶段保留对话框传入的控制参数;窗口创建完成后的分析切换使用新分析自己的值。
|
|
|
|
|
|
if(m_mainLayout != nullptr && pDataManager != nullptr) {
|
|
|
|
|
|
m_dPebiGridControl = pDataManager->getPebiGridControl();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(m_pDebounceTimer != nullptr) {
|
|
|
|
|
|
m_pDebounceTimer->stop();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 第二步:旧 VTK 页不能作为新分析的失败回退页,否则会继续显示上一分析的网格。
|
|
|
|
|
|
clearGridResultView();
|
|
|
|
|
|
if(m_mainLayout == nullptr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(pDataManager == nullptr) {
|
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(pDataManager->isPebiGridValid()) {
|
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
|
showGridResult();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
showGridLoading();
|
|
|
|
|
|
beginGridGenerationState(pDataManager);
|
|
|
|
|
|
if(!m_pGridTask.isNull()) {
|
|
|
|
|
|
// 外部 DLL 不能安全中止;旧任务自然结束后只补做当前分析的最后一次更新。
|
|
|
|
|
|
m_bGridUpdatePending = true;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
|
updateGrid();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::configWnd(QString sPrevInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
iSubWndBaseFit::configWnd(sPrevInfo);
|
|
|
|
|
|
|
|
|
|
|
|
if(NULL != m_pMainWindow) {
|
|
|
|
|
|
disconnect(this, SIGNAL(sigAppendDock2Main(iDockBaseWx*, Qt::DockWidgetArea)), \
|
|
|
|
|
|
m_pMainWindow, SLOT(slotAppendDock2Main(iDockBaseWx*, Qt::DockWidgetArea)));
|
|
|
|
|
|
connect(this, SIGNAL(sigAppendDock2Main(iDockBaseWx*, Qt::DockWidgetArea)), \
|
|
|
|
|
|
m_pMainWindow, SLOT(slotAppendDock2Main(iDockBaseWx*, Qt::DockWidgetArea)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
initUI();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmSubWndGrid::loadRsts()
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmSubWndGrid::saveRsts()
|
|
|
|
|
|
{
|
|
|
|
|
|
ZxRstWnd* pRstWnd = this->getRstUtilWnd();
|
|
|
|
|
|
if (nullptr == pRstWnd)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return pRstWnd->save();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmSubWndGrid::onConfirmClosing()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 先走基类关闭确认;用户取消关闭时不清理网格数据。
|
|
|
|
|
|
if(!iSubWndBaseFit::onConfirmClosing()) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmCalculationPebiGrid::getInstance()->clearGridData(m_pDataManager.data());
|
|
|
|
|
|
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
|
if(pDataManager != nullptr) {
|
|
|
|
|
|
// 当前窗口选择清除网格缓存后,分析方案也必须同步失效。
|
|
|
|
|
|
pDataManager->invalidatePebiGrid();
|
|
|
|
|
|
pDataManager->clearUnstructuredGrid();
|
|
|
|
|
|
endGridGenerationState(pDataManager, false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::initUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
QWidget* mainWidget = new QWidget(this);
|
|
|
|
|
|
// 设置 mainWidget 的布局和尺寸策略
|
|
|
|
|
|
mainWidget->setLayout(new QStackedLayout(mainWidget)); // 加载背景和网格共用稳定显示区域。
|
|
|
|
|
|
mainWidget->layout()->setContentsMargins(0, 0, 0, 0); // 移除边距
|
|
|
|
|
|
mainWidget->layout()->setSpacing(0); // 移除间距
|
|
|
|
|
|
mainWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 扩展策略
|
|
|
|
|
|
|
|
|
|
|
|
setCentralWidget(mainWidget);
|
|
|
|
|
|
|
|
|
|
|
|
// m_mainLayout 应该直接是 mainWidget 的布局
|
|
|
|
|
|
m_mainLayout = qobject_cast<QStackedLayout*>(mainWidget->layout());
|
|
|
|
|
|
|
|
|
|
|
|
// 通用渲染容器随窗口创建,但没有有效数据时不会创建业务 Mapper 或 Actor。
|
|
|
|
|
|
// 因此空数据、加载和失败都能复用同一状态页,不会落回黑色原生窗口。
|
|
|
|
|
|
m_pGridView = new nmWxPebiGridViewWidget(mainWidget);
|
|
|
|
|
|
m_pGridView->setSizePolicy(QSizePolicy::Expanding,
|
|
|
|
|
|
QSizePolicy::Expanding);
|
|
|
|
|
|
m_mainLayout->addWidget(m_pGridView);
|
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_pGridView);
|
|
|
|
|
|
|
|
|
|
|
|
// 新建成果启动后台划分;加载成果只在已有提交网格时绑定业务图层。
|
|
|
|
|
|
if(m_bGeneratePebiGrid) {
|
|
|
|
|
|
generatePebiGrid();
|
|
|
|
|
|
} else if(!m_pDataManager.isNull() &&
|
|
|
|
|
|
m_pDataManager->isPebiGridValid()) {
|
|
|
|
|
|
showGridResult();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QWidget* nmSubWndGrid::initUiMainWx()
|
|
|
|
|
|
{
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmSubWndGrid::runCmdBy(QString sName, QString sID)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(sID.toInt() == 5401) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmSubWndGrid::generatePebiGrid()
|
|
|
|
|
|
{
|
|
|
|
|
|
// PEBI网格
|
|
|
|
|
|
nmCalculationPebiGrid* pPebiGridGeneratorInstance = nmCalculationPebiGrid::getInstance();
|
|
|
|
|
|
|
|
|
|
|
|
// 当前流程只保留PEBI网格;这里仍写入数据中心,供求解和后处理的旧判断继续使用。
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
|
if(pDataManager == nullptr) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
pDataManager->setGridType(NM_Grid_PEBI);
|
|
|
|
|
|
|
|
|
|
|
|
// 将对话框中的GridControl传给PEBI输入参数GridControl
|
|
|
|
|
|
pPebiGridGeneratorInstance->setGridControl(m_dPebiGridControl,
|
|
|
|
|
|
pDataManager);
|
|
|
|
|
|
// 首次手工生成无需等待防抖窗口。此时 VTK 背景已经完成初始化,任务启动
|
|
|
|
|
|
// 后界面可以立即绘制;连续 dataChanged 仍由 updateGrid() 合并处理。
|
|
|
|
|
|
showGridLoading();
|
|
|
|
|
|
beginGridGenerationState(pDataManager);
|
|
|
|
|
|
onDebounceTimeout();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onDataManagerChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 旧分析在断开前可能已经把信号排入主线程队列,发送者不匹配时不得刷新当前分析。
|
|
|
|
|
|
if(sender() != m_pDataManager.data()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GridControl 由分析方案统一持有,刷新前同步,避免窗口把旧局部值写回。
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
|
if(pDataManager != nullptr) {
|
|
|
|
|
|
m_dPebiGridControl = pDataManager->getPebiGridControl();
|
|
|
|
|
|
}
|
|
|
|
|
|
updateGrid();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::updateGrid()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 角色、产量等只影响求解的变化也会发送 dataChanged;网格仍有效时无需重划。
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
|
if(pDataManager != nullptr && pDataManager->isPebiGridValid()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
showGridLoading();
|
|
|
|
|
|
beginGridGenerationState(pDataManager);
|
|
|
|
|
|
|
|
|
|
|
|
// dataChanged可能连续触发,使用当前窗口自己的定时器合并为一次网格重建
|
|
|
|
|
|
if(!m_pDebounceTimer) {
|
|
|
|
|
|
m_pDebounceTimer = new QTimer(this);
|
|
|
|
|
|
m_pDebounceTimer->setSingleShot(true); // 单次触发
|
|
|
|
|
|
connect(m_pDebounceTimer, SIGNAL(timeout()), this, SLOT(onDebounceTimeout()));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_pDebounceTimer->start(500); // 500ms 防抖
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onDebounceTimeout()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 第一步:任务结束信号回到主线程前仍视为占用,避免覆盖尚未处理的任务指针。
|
|
|
|
|
|
if(!m_pGridTask.isNull()) {
|
|
|
|
|
|
m_bGridUpdatePending = true;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
|
if(pDataManager == nullptr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 第二步:把窗口参数写回所属分析方案,再启动绑定同一管理器的后台任务。
|
|
|
|
|
|
nmCalculationPebiGrid::getInstance()->setGridControl(
|
|
|
|
|
|
m_dPebiGridControl, pDataManager);
|
|
|
|
|
|
// GridControl 写回可能更新输入版本,启动任务前同步本轮最终版本。
|
|
|
|
|
|
beginGridGenerationState(pDataManager);
|
|
|
|
|
|
m_pGridTaskDataManager = pDataManager;
|
|
|
|
|
|
m_pGridTask = new nmCalculationPebiGridTask(pDataManager, this);
|
|
|
|
|
|
connect(m_pGridTask, SIGNAL(pebiGridGenerated(bool)),
|
|
|
|
|
|
this, SLOT(onPebiGridGenerated(bool)), Qt::QueuedConnection);
|
|
|
|
|
|
connect(m_pGridTask, SIGNAL(finished()),
|
|
|
|
|
|
this, SLOT(onPebiGridTaskFinished()));
|
|
|
|
|
|
connect(m_pGridTask, SIGNAL(finished()),
|
|
|
|
|
|
m_pGridTask, SLOT(deleteLater()));
|
|
|
|
|
|
m_pGridTask->start();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onPebiGridGenerated(bool success)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 第一步:信号通过队列回到主线程后才允许写 DataManager。后台任务只保存
|
|
|
|
|
|
// 局部结果;如果用户在划分期间修改了输入,commitResult() 会按版本拒绝。
|
|
|
|
|
|
nmCalculationPebiGridTask* pCompletedTask =
|
|
|
|
|
|
qobject_cast<nmCalculationPebiGridTask*>(sender());
|
|
|
|
|
|
nmDataAnalyzeManager* pTaskDataManager =
|
|
|
|
|
|
m_pGridTaskDataManager.data();
|
|
|
|
|
|
|
|
|
|
|
|
// 只处理窗口当前持有且仍属于当前分析的任务;切换前启动的旧任务直接丢弃。
|
|
|
|
|
|
if(pCompletedTask != m_pGridTask.data() ||
|
|
|
|
|
|
pTaskDataManager == nullptr ||
|
|
|
|
|
|
pTaskDataManager != m_pDataManager.data()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(success) {
|
|
|
|
|
|
success = pCompletedTask->commitResult(pTaskDataManager);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
success = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 第二步:提交成功后创建绑定最新网格的 VTK 页。失败或版本过期时,如果
|
|
|
|
|
|
// 没有排队中的更新,则恢复旧网格或显示失败状态,不能永久停留在加载文字。
|
|
|
|
|
|
if(success) {
|
|
|
|
|
|
showGridResult();
|
|
|
|
|
|
} else if(!hasPendingGridUpdate()) {
|
|
|
|
|
|
showGridFailure();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 连续变化尚未完成时保持活动状态;求解只能在最后一次提交之后继续。
|
|
|
|
|
|
if(!hasPendingGridUpdate()) {
|
|
|
|
|
|
endGridGenerationState(pTaskDataManager, success);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onPebiGridTaskFinished()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 第一步:只清理由当前窗口持有的任务,避免旧 finished 信号覆盖新任务指针。
|
|
|
|
|
|
if(sender() != m_pGridTask.data()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
m_pGridTask = nullptr;
|
|
|
|
|
|
m_pGridTaskDataManager = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
// 第二步:运行期间若又有数据变化,重新启动防抖计时,只补做最后一次网格。
|
|
|
|
|
|
if(m_bGridUpdatePending) {
|
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
|
if(pDataManager != nullptr && pDataManager->isPebiGridValid()) {
|
|
|
|
|
|
showGridResult();
|
|
|
|
|
|
endGridGenerationState(pDataManager, true);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
updateGrid();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::showGridLoading()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_mainLayout == nullptr || m_pGridView == nullptr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 已有成功视图时只切换其内部状态页,网格、Scene、Renderer 和相机均保留。
|
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_pGridView);
|
|
|
|
|
|
m_pGridView->showLoading();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::showGridResult()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_mainLayout == nullptr || m_pGridView == nullptr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if(m_pDataManager.isNull()) {
|
|
|
|
|
|
m_pGridView->clearView();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 网格和井值只在 GUI 线程构建为独立 ViewData;失败时不覆盖已有成功画面。
|
|
|
|
|
|
nmPebiGridViewData oViewData;
|
|
|
|
|
|
QString sError;
|
|
|
|
|
|
if(!nmPebiGridViewDataBuilder::build(
|
|
|
|
|
|
m_pDataManager.data(), &oViewData, &sError)) {
|
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_pGridView);
|
|
|
|
|
|
m_pGridView->showFailure(sError);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 业务控件在窗口生命周期内只创建一次,后续提交只替换 MeshLayer 输入。
|
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_pGridView);
|
|
|
|
|
|
if(!m_pGridView->setViewData(oViewData, &sError)) {
|
|
|
|
|
|
m_pGridView->showFailure(sError);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::clearGridResultView()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_pGridView == nullptr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 切换分析只清空业务数据,稳定的 QVTKWidget、Renderer 和 Scene 不重建。
|
|
|
|
|
|
m_pGridView->clearView();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::showGridFailure()
|
|
|
|
|
|
{
|
|
|
|
|
|
if(m_mainLayout == nullptr || m_pGridView == nullptr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新失败但旧网格仍可显示时保留旧成果;首次生成失败时在正常背景上给出
|
|
|
|
|
|
// 明确状态,避免用户把空白或黑屏误认为程序仍在计算。
|
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_pGridView);
|
|
|
|
|
|
if(m_pGridView->hasViewData()) {
|
|
|
|
|
|
m_pGridView->showFailure(tr(
|
|
|
|
|
|
"Grid generation failed. Current view is the last successful grid."));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
m_pGridView->showFailure(tr("Grid generation failed."));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::beginGridGenerationState(
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(pDataManager == nullptr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(!m_pGridGenerationDataManager.isNull() &&
|
|
|
|
|
|
m_pGridGenerationDataManager.data() != pDataManager) {
|
|
|
|
|
|
endGridGenerationState(m_pGridGenerationDataManager.data(), false);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const nmDataNumericalAnalysisCase* pAnalysisCase =
|
|
|
|
|
|
pDataManager->getNumericalAnalysisCase();
|
|
|
|
|
|
if(pAnalysisCase == nullptr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 只在主线程保存状态和版本,不把窗口或 DataManager 指针交给后台线程。
|
|
|
|
|
|
m_pGridGenerationDataManager = pDataManager;
|
|
|
|
|
|
pDataManager->beginPebiGridGeneration(
|
|
|
|
|
|
pAnalysisCase->getGridInputRevision());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::endGridGenerationState(
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager,
|
|
|
|
|
|
bool bSucceeded)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(pDataManager == nullptr ||
|
|
|
|
|
|
m_pGridGenerationDataManager.data() != pDataManager) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_pGridGenerationDataManager = nullptr;
|
|
|
|
|
|
pDataManager->endPebiGridGeneration(bSucceeded);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmSubWndGrid::hasPendingGridUpdate() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_bGridUpdatePending ||
|
|
|
|
|
|
(m_pDebounceTimer != nullptr && m_pDebounceTimer->isActive());
|
|
|
|
|
|
}
|