|
|
|
|
|
#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 "nmWxGridVTKContainerWidget.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmCalculationUtils.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmCalculationPebiGrid.h"
|
|
|
|
|
|
#include "nmCalculationPebiGridTask.h"
|
|
|
|
|
|
#include "nmDataAnalyzeManager.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "QListWidget.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <QVector>
|
|
|
|
|
|
#include <QProcess>
|
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
|
|
|
|
|
|
|
#include "ZxRstWnd.h"
|
|
|
|
|
|
|
|
|
|
|
|
nmSubWndGrid::nmSubWndGrid(QWidget *parent,
|
|
|
|
|
|
QString sExt,
|
|
|
|
|
|
double pebiGridControl,
|
|
|
|
|
|
bool bGeneratePebiGrid,
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager) :
|
|
|
|
|
|
iSubWndBaseFit(parent, sExt),
|
|
|
|
|
|
m_mainLayout(nullptr),
|
|
|
|
|
|
m_vtkWidget(nullptr),
|
|
|
|
|
|
m_pDebounceTimer(nullptr),
|
|
|
|
|
|
m_pDataManager(pDataManager),
|
|
|
|
|
|
m_pGridTask(nullptr),
|
|
|
|
|
|
m_bGridUpdatePending(false),
|
|
|
|
|
|
m_dPebiGridControl(pebiGridControl),
|
|
|
|
|
|
m_bGeneratePebiGrid(bGeneratePebiGrid)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_sMdiWndType = s_MdiType_DataAnal;
|
|
|
|
|
|
setWindowTitle(tr("nmSubWndGrid"));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nmSubWndGrid::~nmSubWndGrid()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 外部 DLL 不支持安全中止;窗口析构前等待自己的任务退出,避免销毁运行中的 QThread。
|
|
|
|
|
|
if(!m_pGridTask.isNull() && m_pGridTask->isRunning()) {
|
|
|
|
|
|
disconnect(m_pGridTask, nullptr, this, nullptr);
|
|
|
|
|
|
m_pGridTask->wait();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::initUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
QWidget* mainWidget = new QWidget(this);
|
|
|
|
|
|
// 设置 mainWidget 的布局和尺寸策略
|
|
|
|
|
|
mainWidget->setLayout(new QVBoxLayout(mainWidget)); // 确保 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<QVBoxLayout*>(mainWidget->layout());
|
|
|
|
|
|
|
|
|
|
|
|
// 当前不是加载进来的网格,都需要根据Map几何生成新的PEBI网格
|
|
|
|
|
|
if (m_bGeneratePebiGrid)
|
|
|
|
|
|
{
|
|
|
|
|
|
generatePebiGrid();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
{
|
|
|
|
|
|
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);
|
|
|
|
|
|
// 生成PEBI非结构化网格对象
|
|
|
|
|
|
return pPebiGridGeneratorInstance->meshGenPebi(pDataManager);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::updateGrid()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 角色、产量等只影响求解的变化也会发送 dataChanged;网格仍有效时无需重划。
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
|
if(pDataManager != nullptr && pDataManager->isPebiGridValid()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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_pGridTask->isRunning()) {
|
|
|
|
|
|
m_bGridUpdatePending = true;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmDataAnalyzeManager* pDataManager = m_pDataManager.data();
|
|
|
|
|
|
if(pDataManager == nullptr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 第二步:把窗口参数写回所属分析方案,再启动绑定同一管理器的后台任务。
|
|
|
|
|
|
nmCalculationPebiGrid::getInstance()->setGridControl(
|
|
|
|
|
|
m_dPebiGridControl, pDataManager);
|
|
|
|
|
|
m_pGridTask = new nmCalculationPebiGridTask(pDataManager, this);
|
|
|
|
|
|
connect(m_pGridTask, SIGNAL(pebiGridGenerated(bool)),
|
|
|
|
|
|
this, SLOT(onPebiGridGenerated(bool)));
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!success) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 删除旧的 VTK 控件
|
|
|
|
|
|
if (m_vtkWidget) {
|
|
|
|
|
|
m_mainLayout->removeWidget(m_vtkWidget);
|
|
|
|
|
|
delete m_vtkWidget;
|
|
|
|
|
|
m_vtkWidget = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 创建新的 VTK 控件,并将其加入布局
|
|
|
|
|
|
m_vtkWidget = new nmWxGridVTKContainerWidget(m_pDataManager.data(), this);
|
|
|
|
|
|
// 设置新创建的 nmWxGridVTKContainerWidget 的尺寸策略**
|
|
|
|
|
|
m_vtkWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // 扩展策略
|
|
|
|
|
|
m_mainLayout->addWidget(m_vtkWidget);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmSubWndGrid::onPebiGridTaskFinished()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 第一步:只清理由当前窗口持有的任务,避免旧 finished 信号覆盖新任务指针。
|
|
|
|
|
|
if(sender() == m_pGridTask.data()) {
|
|
|
|
|
|
m_pGridTask = nullptr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 第二步:运行期间若又有数据变化,重新启动防抖计时,只补做最后一次网格。
|
|
|
|
|
|
if(m_bGridUpdatePending) {
|
|
|
|
|
|
m_bGridUpdatePending = false;
|
|
|
|
|
|
updateGrid();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|