|
|
|
|
@ -49,6 +49,8 @@
|
|
|
|
|
#include <QVector>
|
|
|
|
|
#include <QProcess>
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
#include <QLabel>
|
|
|
|
|
#include <QStackedLayout>
|
|
|
|
|
|
|
|
|
|
#include "ZxRstWnd.h"
|
|
|
|
|
|
|
|
|
|
@ -60,6 +62,7 @@ nmSubWndGrid::nmSubWndGrid(QWidget *parent,
|
|
|
|
|
iSubWndBaseFit(parent, sExt),
|
|
|
|
|
m_mainLayout(nullptr),
|
|
|
|
|
m_vtkWidget(nullptr),
|
|
|
|
|
m_pGridLoadingLabel(nullptr),
|
|
|
|
|
m_pDebounceTimer(nullptr),
|
|
|
|
|
m_pDataManager(pDataManager),
|
|
|
|
|
m_pGridTask(nullptr),
|
|
|
|
|
@ -134,7 +137,7 @@ void nmSubWndGrid::initUI()
|
|
|
|
|
{
|
|
|
|
|
QWidget* mainWidget = new QWidget(this);
|
|
|
|
|
// 设置 mainWidget 的布局和尺寸策略
|
|
|
|
|
mainWidget->setLayout(new QVBoxLayout(mainWidget)); // 确保 mainWidget 有自己的布局
|
|
|
|
|
mainWidget->setLayout(new QStackedLayout(mainWidget)); // 加载背景和网格共用稳定显示区域。
|
|
|
|
|
mainWidget->layout()->setContentsMargins(0, 0, 0, 0); // 移除边距
|
|
|
|
|
mainWidget->layout()->setSpacing(0); // 移除间距
|
|
|
|
|
mainWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 扩展策略
|
|
|
|
|
@ -142,25 +145,27 @@ void nmSubWndGrid::initUI()
|
|
|
|
|
setCentralWidget(mainWidget);
|
|
|
|
|
|
|
|
|
|
// m_mainLayout 应该直接是 mainWidget 的布局
|
|
|
|
|
m_mainLayout = qobject_cast<QVBoxLayout*>(mainWidget->layout());
|
|
|
|
|
|
|
|
|
|
// 当前不是加载进来的网格,都需要根据Map几何生成新的PEBI网格
|
|
|
|
|
if (m_bGeneratePebiGrid)
|
|
|
|
|
{
|
|
|
|
|
m_mainLayout = qobject_cast<QStackedLayout*>(mainWidget->layout());
|
|
|
|
|
|
|
|
|
|
// 第一步:先建立轻量加载页。颜色与网格 Renderer 保持一致,后台任务尚未
|
|
|
|
|
// 返回时也能立即绘制正常背景,不会显示空 QVTKWidget 的黑色原生窗口。
|
|
|
|
|
m_pGridLoadingLabel = new QLabel(tr("Generating grid..."), mainWidget);
|
|
|
|
|
m_pGridLoadingLabel->setAlignment(Qt::AlignCenter);
|
|
|
|
|
m_pGridLoadingLabel->setSizePolicy(QSizePolicy::Expanding,
|
|
|
|
|
QSizePolicy::Expanding);
|
|
|
|
|
m_pGridLoadingLabel->setStyleSheet(
|
|
|
|
|
"QLabel { color: white; font-size: 14px; "
|
|
|
|
|
"background: qlineargradient(x1:0, y1:0, x2:0, y2:1, "
|
|
|
|
|
"stop:0 rgb(0, 128, 255), stop:1 rgb(171, 209, 240)); }");
|
|
|
|
|
m_mainLayout->addWidget(m_pGridLoadingLabel);
|
|
|
|
|
|
|
|
|
|
// 第二步:新建成果在渲染窗口就绪后立即启动后台划分;加载成果则直接显示
|
|
|
|
|
// DataManager 中已有的网格,不进入生成状态。VTK 页只在网格有效后创建。
|
|
|
|
|
if(m_bGeneratePebiGrid) {
|
|
|
|
|
generatePebiGrid();
|
|
|
|
|
} else {
|
|
|
|
|
showGridResult();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_vtkWidget = new nmWxGridVTKContainerWidget(m_pDataManager.data(), this);
|
|
|
|
|
m_vtkWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 扩展策略
|
|
|
|
|
m_mainLayout->addWidget(m_vtkWidget);
|
|
|
|
|
|
|
|
|
|
// 首次创建
|
|
|
|
|
//if(generatePebiGrid()) {
|
|
|
|
|
// // nmWxGridVTKContainerWidget 的尺寸策略
|
|
|
|
|
// m_vtkWidget = new nmWxGridVTKContainerWidget(this);
|
|
|
|
|
// m_vtkWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 扩展策略
|
|
|
|
|
// m_mainLayout->addWidget(m_vtkWidget);
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QWidget* nmSubWndGrid::initUiMainWx()
|
|
|
|
|
@ -192,8 +197,11 @@ bool nmSubWndGrid::generatePebiGrid()
|
|
|
|
|
// 将对话框中的GridControl传给PEBI输入参数GridControl
|
|
|
|
|
pPebiGridGeneratorInstance->setGridControl(m_dPebiGridControl,
|
|
|
|
|
pDataManager);
|
|
|
|
|
// 生成PEBI非结构化网格对象
|
|
|
|
|
return pPebiGridGeneratorInstance->meshGenPebi(pDataManager);
|
|
|
|
|
// 首次手工生成无需等待防抖窗口。此时 VTK 背景已经完成初始化,任务启动
|
|
|
|
|
// 后界面可以立即绘制;连续 dataChanged 仍由 updateGrid() 合并处理。
|
|
|
|
|
showGridLoading();
|
|
|
|
|
onDebounceTimeout();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::updateGrid()
|
|
|
|
|
@ -204,6 +212,8 @@ void nmSubWndGrid::updateGrid()
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showGridLoading();
|
|
|
|
|
|
|
|
|
|
// dataChanged可能连续触发,使用当前窗口自己的定时器合并为一次网格重建
|
|
|
|
|
if(!m_pDebounceTimer) {
|
|
|
|
|
m_pDebounceTimer = new QTimer(this);
|
|
|
|
|
@ -230,9 +240,9 @@ void nmSubWndGrid::onDebounceTimeout()
|
|
|
|
|
// 第二步:把窗口参数写回所属分析方案,再启动绑定同一管理器的后台任务。
|
|
|
|
|
nmCalculationPebiGrid::getInstance()->setGridControl(
|
|
|
|
|
m_dPebiGridControl, pDataManager);
|
|
|
|
|
m_pGridTask = new nmCalculationPebiGridTask(pDataManager, this);
|
|
|
|
|
m_pGridTask = new nmCalculationPebiGridTask(pDataManager, this);
|
|
|
|
|
connect(m_pGridTask, SIGNAL(pebiGridGenerated(bool)),
|
|
|
|
|
this, SLOT(onPebiGridGenerated(bool)));
|
|
|
|
|
this, SLOT(onPebiGridGenerated(bool)), Qt::QueuedConnection);
|
|
|
|
|
connect(m_pGridTask, SIGNAL(finished()),
|
|
|
|
|
this, SLOT(onPebiGridTaskFinished()));
|
|
|
|
|
connect(m_pGridTask, SIGNAL(finished()),
|
|
|
|
|
@ -242,21 +252,24 @@ void nmSubWndGrid::onDebounceTimeout()
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onPebiGridGenerated(bool success)
|
|
|
|
|
{
|
|
|
|
|
if (!success) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 删除旧的 VTK 控件
|
|
|
|
|
if (m_vtkWidget) {
|
|
|
|
|
m_mainLayout->removeWidget(m_vtkWidget);
|
|
|
|
|
delete m_vtkWidget;
|
|
|
|
|
m_vtkWidget = nullptr;
|
|
|
|
|
}
|
|
|
|
|
// 第一步:信号通过队列回到主线程后才允许写 DataManager。后台任务只保存
|
|
|
|
|
// 局部结果;如果用户在划分期间修改了输入,commitResult() 会按版本拒绝。
|
|
|
|
|
nmCalculationPebiGridTask* pCompletedTask =
|
|
|
|
|
qobject_cast<nmCalculationPebiGridTask*>(sender());
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
if(success && pCompletedTask != nullptr && pDataManager != nullptr) {
|
|
|
|
|
success = pCompletedTask->commitResult(pDataManager);
|
|
|
|
|
} else {
|
|
|
|
|
success = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建新的 VTK 控件,并将其加入布局
|
|
|
|
|
m_vtkWidget = new nmWxGridVTKContainerWidget(m_pDataManager.data(), this);
|
|
|
|
|
// 设置新创建的 nmWxGridVTKContainerWidget 的尺寸策略**
|
|
|
|
|
m_vtkWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 扩展策略
|
|
|
|
|
m_mainLayout->addWidget(m_vtkWidget);
|
|
|
|
|
// 第二步:提交成功后创建绑定最新网格的 VTK 页。失败或版本过期时,如果
|
|
|
|
|
// 没有排队中的更新,则恢复旧网格或显示失败状态,不能永久停留在加载文字。
|
|
|
|
|
if(success) {
|
|
|
|
|
showGridResult();
|
|
|
|
|
} else if(!m_bGridUpdatePending) {
|
|
|
|
|
showGridFailure();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onPebiGridTaskFinished()
|
|
|
|
|
@ -272,3 +285,51 @@ void nmSubWndGrid::onPebiGridTaskFinished()
|
|
|
|
|
updateGrid();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::showGridLoading()
|
|
|
|
|
{
|
|
|
|
|
if(m_pGridLoadingLabel == nullptr || m_mainLayout == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pGridLoadingLabel->setText(tr("Generating grid..."));
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_pGridLoadingLabel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::showGridResult()
|
|
|
|
|
{
|
|
|
|
|
if(m_mainLayout == nullptr || m_pDataManager.isNull()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 网格已经在主线程完整提交,此处一次创建新的 VTK 页,不会向用户暴露
|
|
|
|
|
// 没有 RenderWindow 的中间状态。
|
|
|
|
|
if(m_vtkWidget != nullptr) {
|
|
|
|
|
m_mainLayout->removeWidget(m_vtkWidget);
|
|
|
|
|
delete m_vtkWidget;
|
|
|
|
|
m_vtkWidget = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_vtkWidget = new nmWxGridVTKContainerWidget(
|
|
|
|
|
m_pDataManager.data(), centralWidget());
|
|
|
|
|
m_vtkWidget->setSizePolicy(QSizePolicy::Expanding,
|
|
|
|
|
QSizePolicy::Expanding);
|
|
|
|
|
m_mainLayout->addWidget(m_vtkWidget);
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_vtkWidget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::showGridFailure()
|
|
|
|
|
{
|
|
|
|
|
if(m_mainLayout == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新失败但旧网格仍可显示时保留旧成果;首次生成失败时在正常背景上给出
|
|
|
|
|
// 明确状态,避免用户把空白或黑屏误认为程序仍在计算。
|
|
|
|
|
if(m_vtkWidget != nullptr) {
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_vtkWidget);
|
|
|
|
|
} else if(m_pGridLoadingLabel != nullptr) {
|
|
|
|
|
m_pGridLoadingLabel->setText(tr("Grid generation failed"));
|
|
|
|
|
m_mainLayout->setCurrentWidget(m_pGridLoadingLabel);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|