|
|
|
|
@ -67,6 +67,7 @@ nmSubWndGrid::nmSubWndGrid(QWidget *parent,
|
|
|
|
|
m_pDataManager(nullptr),
|
|
|
|
|
m_pGridTask(nullptr),
|
|
|
|
|
m_pGridTaskDataManager(nullptr),
|
|
|
|
|
m_pGridGenerationDataManager(nullptr),
|
|
|
|
|
m_bGridUpdatePending(false),
|
|
|
|
|
m_dPebiGridControl(pebiGridControl),
|
|
|
|
|
m_bGeneratePebiGrid(bGeneratePebiGrid)
|
|
|
|
|
@ -79,11 +80,16 @@ nmSubWndGrid::nmSubWndGrid(QWidget *parent,
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
@ -97,6 +103,8 @@ void nmSubWndGrid::setDataManager(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
if(pOldDataManager != nullptr) {
|
|
|
|
|
disconnect(pOldDataManager, SIGNAL(dataChanged()),
|
|
|
|
|
this, SLOT(onDataManagerChanged()));
|
|
|
|
|
// 切换后旧任务只允许自然结束并丢弃结果,不再阻塞旧分析的求解入口。
|
|
|
|
|
endGridGenerationState(pOldDataManager, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pDataManager = pDataManager;
|
|
|
|
|
@ -135,6 +143,7 @@ void nmSubWndGrid::setDataManager(nmDataAnalyzeManager* pDataManager)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showGridLoading();
|
|
|
|
|
beginGridGenerationState(pDataManager);
|
|
|
|
|
if(!m_pGridTask.isNull()) {
|
|
|
|
|
// 外部 DLL 不能安全中止;旧任务自然结束后只补做当前分析的最后一次更新。
|
|
|
|
|
m_bGridUpdatePending = true;
|
|
|
|
|
@ -189,6 +198,7 @@ bool nmSubWndGrid::onConfirmClosing()
|
|
|
|
|
// 当前窗口选择清除网格缓存后,分析方案也必须同步失效。
|
|
|
|
|
pDataManager->invalidatePebiGrid();
|
|
|
|
|
pDataManager->clearUnstructuredGrid();
|
|
|
|
|
endGridGenerationState(pDataManager, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
@ -261,6 +271,7 @@ bool nmSubWndGrid::generatePebiGrid()
|
|
|
|
|
// 首次手工生成无需等待防抖窗口。此时 VTK 背景已经完成初始化,任务启动
|
|
|
|
|
// 后界面可以立即绘制;连续 dataChanged 仍由 updateGrid() 合并处理。
|
|
|
|
|
showGridLoading();
|
|
|
|
|
beginGridGenerationState(pDataManager);
|
|
|
|
|
onDebounceTimeout();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
@ -283,6 +294,7 @@ void nmSubWndGrid::updateGrid()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showGridLoading();
|
|
|
|
|
beginGridGenerationState(pDataManager);
|
|
|
|
|
|
|
|
|
|
// dataChanged可能连续触发,使用当前窗口自己的定时器合并为一次网格重建
|
|
|
|
|
if(!m_pDebounceTimer) {
|
|
|
|
|
@ -310,6 +322,8 @@ void nmSubWndGrid::onDebounceTimeout()
|
|
|
|
|
// 第二步:把窗口参数写回所属分析方案,再启动绑定同一管理器的后台任务。
|
|
|
|
|
nmCalculationPebiGrid::getInstance()->setGridControl(
|
|
|
|
|
m_dPebiGridControl, pDataManager);
|
|
|
|
|
// GridControl 写回可能更新输入版本,启动任务前同步本轮最终版本。
|
|
|
|
|
beginGridGenerationState(pDataManager);
|
|
|
|
|
m_pGridTaskDataManager = pDataManager;
|
|
|
|
|
m_pGridTask = new nmCalculationPebiGridTask(pDataManager, this);
|
|
|
|
|
connect(m_pGridTask, SIGNAL(pebiGridGenerated(bool)),
|
|
|
|
|
@ -347,9 +361,14 @@ void nmSubWndGrid::onPebiGridGenerated(bool success)
|
|
|
|
|
// 没有排队中的更新,则恢复旧网格或显示失败状态,不能永久停留在加载文字。
|
|
|
|
|
if(success) {
|
|
|
|
|
showGridResult();
|
|
|
|
|
} else if(!m_bGridUpdatePending) {
|
|
|
|
|
} else if(!hasPendingGridUpdate()) {
|
|
|
|
|
showGridFailure();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 连续变化尚未完成时保持活动状态;求解只能在最后一次提交之后继续。
|
|
|
|
|
if(!hasPendingGridUpdate()) {
|
|
|
|
|
endGridGenerationState(pTaskDataManager, success);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onPebiGridTaskFinished()
|
|
|
|
|
@ -365,10 +384,11 @@ void nmSubWndGrid::onPebiGridTaskFinished()
|
|
|
|
|
if(m_bGridUpdatePending) {
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
if(pDataManager != nullptr &&
|
|
|
|
|
pDataManager->isPebiGridValid() &&
|
|
|
|
|
m_vtkWidget == nullptr) {
|
|
|
|
|
showGridResult();
|
|
|
|
|
if(pDataManager != nullptr && pDataManager->isPebiGridValid()) {
|
|
|
|
|
if(m_vtkWidget == nullptr) {
|
|
|
|
|
showGridResult();
|
|
|
|
|
}
|
|
|
|
|
endGridGenerationState(pDataManager, true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
updateGrid();
|
|
|
|
|
@ -431,3 +451,46 @@ void nmSubWndGrid::showGridFailure()
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_pGridLoadingLabel);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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());
|
|
|
|
|
}
|
|
|
|
|
|