You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmSubWnd/nmSubWndUtils.cpp

1087 lines
36 KiB
C++

#include "zxLogInstance.h"
#include "iRibbonXmlCmd.h"
#include <QDebug>
#include "zxSysUtils.h"
#include "ZxUiBase.h"
#include "ZxMainWindow.h"
#include "ZxTabWidget.h"
#include "TreeWxMain.h"
#include "iDockBaseWx.h"
#include "iModuleHelper.h"
#include "ZxDataWell.h"
#include "ZxDataProject.h"
#include "nmFrameworkTest.h"
#include "iSubWndFitting.h"
#ifdef MY_OWN_GRID
#include "iSubWndGrid.h"
#else
#include "nmSubWndDemo.h"
#endif
#include "nmSubWndUtils.h"
#include "nmSubWndMain.h"
#include "nmSubWndGrid.h"
#include "nmSubWndPostprocessing.h"
#include "nmWxGridDlg.h"
#include "nmWxPostprocessingAnimationWidget.h"
#include "nmGuiPlot.h"
#include "ZxObjBase.h"
#include "nmDataAnalyzeManager.h"
#include "iRibbonXmlTab.h"
#include "nmWxParameterProperty.h"
#include "nmWxNumericalDesign.h"
#include "nmDataOutline.h"
#include "ZxRstWnd.h"
#include "nmWxChangeAnal.h"
#include "nmDataAxis.h"
namespace {
// 判断指定相态下是否至少有一个PVT曲线结果
bool hasPvtCurve(iSubWndFitting* pSubWndF, PvtFluidType eType, const QStringList& listParas)
{
if(pSubWndF == nullptr) {
return false;
}
for(int i = 0; i < listParas.size(); ++i) {
VecDouble vecX;
QVector<double> vecY;
pSubWndF->getPvtRstOf(eType, listParas[i], vecX, vecY);
if(!vecX.isEmpty()) {
return true;
}
}
return false;
}
}
nmSubWndUtils* nmSubWndUtils::getInstance()
{
static nmSubWndUtils s_instance; // 在第一次调用时创建唯一实例
return &s_instance;
}
nmSubWndUtils::nmSubWndUtils()
{
m_pMainWnd = nullptr;
m_pTabWx = nullptr;
}
nmSubWndUtils::~nmSubWndUtils() {}
iSubWnd* nmSubWndUtils::createSubWnd(const iRibbonXmlCmd* pCmdInfo, \
const ZxMainWindow* pMainWnd, \
bool& bCreatedNewOne)
{
if (nullptr == pCmdInfo)
{
return nullptr;
}
// TODO 此处是自行控制是否单一模式
bool bOnlyOneForCurTabWx = true;
return makesureSubWnd(pCmdInfo->m_sID, pCmdInfo->m_sExtInfo, \
pMainWnd, bCreatedNewOne, \
bOnlyOneForCurTabWx);
}
iSubWnd* nmSubWndUtils::makesureSubWnd(QString sID, QString sExt, \
const ZxMainWindow* pMainWnd, \
bool& bCreatedNewOne, \
bool bOnlyOneForCurTabWx /*= true*/)
{
Q_ASSERT (nullptr != pMainWnd);
//单一模式,则先查找,如果已经存在,则直接返回
if (bOnlyOneForCurTabWx)
{
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx(); //仅仅在当前TabWx下查找此处可以根据需要调整
if (nullptr != pTabWx)
{
for (int i = 0; i < pTabWx->count(); i++)
{
iSubWnd* pSubWnd = dynamic_cast<iSubWnd*>(pTabWx->widget(i));
if (nullptr != pSubWnd)
{
if (_isSame(sID, pSubWnd->getWndID()))
{
bCreatedNewOne = false;
// TODO 根据需要,是否需要激活当前
if (i != pTabWx->currentIndex())
{
pTabWx->setCurrentIndex(i);
}
return pSubWnd;
}
}
}
}
}
// 创建新的
bCreatedNewOne = true;
iSubWnd* pSubWnd = nullptr;
// Here is your own codes
int nID = sID.toInt();
if(nID == 5118) {
// TODO提示应该先打开一个分析
//QMessageBox::information(pSubWnd, tr("error"), tr("please open an analyze!"));
// 判断油藏参数是否已经初始化
//if(nmDataAnalyzeManager::getCurrentInstance()->getReservoirData() == nullptr) {
// // 初始化油藏参数
// nmDataAnalyzeManager::getCurrentInstance()->createReservoir();
// // 初始化PVT
// nmDataAnalyzeManager::getCurrentInstance()->initPvtParaFromSubFit();
//}
// 1、获取当前窗体下的所有流动段分析
// 选择一个流动段分析里的数据作为当前地图要展示的数据
// TODO2、没有流动段分析
if(nmDataAnalyzeManager::getCurrentFitting() != nullptr) {
nmSubWndMain* pSubWndMain = new nmSubWndMain(NULL, sExt);
pSubWnd = pSubWndMain;
} else {
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
QMessageBox::information(pMainWnd1, tr("No Data"), tr("please open an Fitting and click Numerical button"));
}
} else if(nID == 5114) {
// PEBI GridControl控制参数对应HX_NWTM_GRID_INPUT::GridControl
double dPebiGridControl = 150.0;
bool bGeneratePebiGrid = true;
// 判断是否是加载进来的数据,如果不是加载进来的,则需要添加设置网格信息的对话框
if(!nmDataAnalyzeManager::getCurrentInstance()->m_bIsLoadData) {
// 当前只保留PEBI网格弹窗只需要设置GridControl
nmWxGridDlg dlg(&dPebiGridControl);
if(dlg.exec() == QDialog::Rejected) {
return NULL;
}
} else {
// 更新标志
nmDataAnalyzeManager::getCurrentInstance()->m_bIsLoadData = false;
bGeneratePebiGrid = false;
}
// 创建PEBI网格窗口新建数据时生成网格加载数据时直接展示已加载结果。
nmSubWndGrid* pSubWndGrid = new nmSubWndGrid(NULL, sExt, dPebiGridControl, bGeneratePebiGrid);
disconnect(nmDataAnalyzeManager::getCurrentInstance(), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()));
connect(nmDataAnalyzeManager::getCurrentInstance(), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()), Qt::QueuedConnection);
pSubWnd = pSubWndGrid;
} else if(nID == 5116) {
// 后处理
nmSubWndPostprocessing* pSubWndPostProcessing = new nmSubWndPostprocessing(NULL, sExt);
pSubWnd = pSubWndPostProcessing;
}
if(NULL != pSubWnd) {
// TODO 此处根据需要设置 改变 标识
pSubWnd->setModified(true);
}
return pSubWnd;
}
bool nmSubWndUtils::runCmdBySpecial(const iRibbonXmlCmd* pCmdInfo, \
const ZxMainWindow* pMainWnd)
{
//nmSubWndUtils* pUtilsInstance = nmSubWndUtils::getInstance();
// 第一次创建TODO或者打开另一个窗体时连接槽函数避免多次调用
//if (pUtilsInstance->m_pMainWnd == nullptr || pUtilsInstance->m_pMainWnd != pMainWnd)
//{
// // 第一次操作时连接tab的槽函数
// ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
// if (nullptr != pMainWnd1)
// {
// pUtilsInstance->m_pMainWnd = pMainWnd1;
// ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx();
// if (nullptr != pTabWx){
// disconnect(pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
// connect(pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
// }
// }
//}
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
nmSubWndUtils* pUtilsInstance = nmSubWndUtils::getInstance();
if(nullptr != pMainWnd1) {
ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx();
if(nullptr != pTabWx) {
if(pUtilsInstance->m_pTabWx == nullptr || pUtilsInstance->m_pTabWx != pTabWx) {
pUtilsInstance->m_pTabWx = pTabWx;
disconnect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
connect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
}
}
}
if(nullptr == pCmdInfo) {
return false;
}
// 20250310 测试Release崩溃问题暂时放开
//#ifdef QT_DEBUG
// 专门提供给数值模块,进行一些框架代码的调试
if (_isSame(pCmdInfo->m_sID, "5999"))
{
nmFrameworkTest::testFrmCodes(pCmdInfo, pMainWnd);
return true;
}
//#endif
return runCmdBySpecial(pCmdInfo->m_sID, pCmdInfo->m_sExtInfo, pMainWnd);
}
bool nmSubWndUtils::runCmdBySpecial(QString sID, QString sExt, \
const ZxMainWindow* pMainWnd)
{
// Here is your own codes
if(_isSame(sID, "12345")) {
QMessageBox::information(nullptr, zxAppDescEN, QObject::tr("I am abc"));
return true;
} if(_isSame(sID, "5130")) {
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
// 创建并显示对话框
nmWxChangeAnal analChangeDlg(nullptr, pMainWnd1);
// 执行对话框并判断返回值
if(analChangeDlg.exec() == QDialog::Accepted) {
}
return true;
} else {
return false;
}
}
bool nmSubWndUtils::isEnableOfID_Common(QString sID, QString sName, \
const bool bLicensed, \
const ZxMainWindow* pMainWnd)
{
// 20250310 测试Release崩溃问题暂时放开
//#ifdef QT_DEBUG
// 专门提供给数值模块,进行一些框架代码的调试
if (_isSame(sID, "5999"))
{
return (true);
}
//#endif
bool b1 = (nullptr != zxCurProject);
// Here is your own codes
if (_isSame(sID, "5101"))
{
return (true);
}
else if (_isSame(sID, "5002")) //或者 _isSame(sName, "PropertyLoad")
{
// <Cmd ID="5002" Bounds="0,1,2,1" Name="PropertyLoad" Alias="属性导入"
// TODO 只有当前窗体为流动分析或者流动段选择的情况下才能点击
bool bOk = false;
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
if (nullptr != pMainWnd1)
{
iSubWnd* pSubWnd = pMainWnd1->getCurSubWnd(); //当前窗体
if (nullptr != pSubWnd)
{
QString sCurID = pSubWnd->getWndID();
bOk = (_isSame(sCurID, "3003") || _isSame(sCurID, "3004")
// || _isSame(sCurID, "6001") //TODO 这是试井设计页面,待定
);
}
}
return bOk;
} else if(_isSame(sName, "NmMap")) {
return (b1 && bLicensed);
} else if(_isSame(sName, "NmAnalChange")) {
return (b1 && bLicensed);
}
else
{
return false;
}
}
bool nmSubWndUtils::dealwithRibbonTab(iRibbonXmlTab* pTab, \
const ZxMainWindow* pMainWnd)
{
return false; //your own codes
}
bool nmSubWndUtils::fillNmDockWxs(iSubWnd* pSubWnd)
{
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
Q_ASSERT(nullptr != pSubWndF);
if(pSubWndF == nullptr) {
return false;
}
// 如果当前分析没有对应相态的PVT相关参数提示并返回
//PvtFluidType eType = pSubWndF->getBasicPft();
//bool bHasPvtData = false;
//if(eType == WFT_Oil) {
// bHasPvtData = hasPvtCurve(pSubWndF, WFT_Oil, QStringList() << "Rs" << "Bo" << "Co" << "Rhoo" << "Miuo");
//} else if(eType == WFT_Gas) {
// bHasPvtData = hasPvtCurve(pSubWndF, WFT_Gas, QStringList() << "Rv" << "Bg" << "Cg" << "Miug" << "Rhog" << "Zg");
//} else if(eType == WFT_Water) {
// bHasPvtData = hasPvtCurve(pSubWndF, WFT_Water, QStringList() << "Rsw" << "Bw" << "Cw" << "Miuw" << "Rhow");
//} else if(eType == WFT_Oil_Water) {
// bHasPvtData = hasPvtCurve(pSubWndF, WFT_Oil, QStringList() << "Rs" << "Bo" << "Co" << "Rhoo" << "Miuo")
// || hasPvtCurve(pSubWndF, WFT_Water, QStringList() << "Rsw" << "Bw" << "Cw" << "Miuw" << "Rhow");
//}
//if(!bHasPvtData) {
// QString appDir = QCoreApplication::applicationDirPath();
// appDir = appDir.section('/', 0, -2); // 获取上一级目录
// QMessageBox msgBox;
// msgBox.setWindowTitle(tr("PVT Data Missing"));
// msgBox.setText(tr("Please check if PVT parameters have been calculated in the analysis."));
// msgBox.setIconPixmap(QPixmap(appDir + "/Res/Icon/NmPVTDataMissMessage.png")); // PVT 参数计算向导
// msgBox.setStandardButtons(QMessageBox::Ok);
// msgBox.exec();
// return false;
//}
iDockBaseWx* pWxDockNm1 = pSubWndF->getNmDockWx(0);
iDockBaseWx* pWxDockNm2 = pSubWndF->getNmDockWx(1);
Q_ASSERT (nullptr != pWxDockNm1);
Q_ASSERT (nullptr != pWxDockNm2);
if (pWxDockNm1->widget() != nullptr && pWxDockNm2->widget() != nullptr)
{
return true; //已经设定的话,则不再处理
}
// 获取当前井并检查类型是否支持
ZxDataWell* pWellData = zxCurWell;
if(pWellData == nullptr) {
return false;
}
QString wellClass = pWellData->getWellClassEn();
// 定义支持的井类型列表
QStringList supportedTypes;
supportedTypes << "VerticalWell" << "VerticalFracturedWell" << "HorizontalMultiFracturedWell";
if (!supportedTypes.contains(wellClass)) {
QMessageBox::warning(nullptr, tr("Unsupported Well Type"),
tr("The current well type '%1' is not supported for numerical modeling.\n"
"Supported types: Vertical, Vertical Fractured, and Horizontal Multi-Fractured Wells.")
.arg(pWellData->getWellClassCn()));
return false;
}
// 进入到这里,说明是新打开的流动段分析,所以需要动态创建数据管理中心
// 根据分析窗口创建唯一的数据管理对象
nmDataAnalyzeManager* pDataManager = nmDataAnalyzeManager::getInstanceByFitting(pSubWndF);
Q_ASSERT(nullptr != pDataManager);
if(pDataManager == nullptr) {
return false;
}
// 设置当前分析窗体
nmDataAnalyzeManager::setCurrentFitting(pSubWndF);
// TODO初始化坐标轴相关信息
nmDataAxis* pAxisData = pDataManager->getAxisData();
if(pAxisData == nullptr) {
pAxisData = new nmDataAxis;
// 将 pAxisData 存入数据中心
nmDataAnalyzeManager::getCurrentInstance()->setAxisData(pAxisData);
}
// 读取解析解的参数
// 1.1 初始化油藏参数
pDataManager->createReservoir();
// 1.2 初始化PVT参数
pDataManager->initPvtParaFromSubFit();
// 1.3 初始化当前井数据
pDataManager->initCurWellData();
// 1.4 初始化边界数据
nmDataWellBase* pCurWell = pDataManager->getCurWellData();
Q_ASSERT(nullptr != pCurWell);
if(pCurWell == nullptr) {
return false;
}
double dX = pCurWell->getX().getValue().toDouble();
double dY = pCurWell->getY().getValue().toDouble();
// 解析解相关参数
QMap<QString, QVariant> mapAnaParas;
mapAnaParas.clear();
pSubWndF->getBrotherDockParas(mapAnaParas, false);
Q_ASSERT(mapAnaParas.count() > 0);
// 解析解边界类型
m_Bdy_Type oBdyType = BT_None;
QString sKey = "Bdy";
if(mapAnaParas.contains(sKey)) {
int n = mapAnaParas[sKey].toInt();
if(n <= (int)BT_Rect) {
oBdyType = m_Bdy_Type(n);
}
}
// 边界距离(是井点到四周的直线距离)
if(oBdyType == BT_Rect || oBdyType == BT_Circle) {
// 设置边界数据
if(oBdyType == BT_Rect) {
// 矩形边界
VecDouble vecBdyDiss;
vecBdyDiss.clear();
QStringList list;
list << "ne" << "se" << "we" << "ee";
for(int i = 0; i < list.count(); i++) {
QString s = list[i];
if(mapAnaParas.contains(s)) {
vecBdyDiss << mapAnaParas[s].toDouble();
}
}
double top_dist = vecBdyDiss[0];
double right_dist = vecBdyDiss[1];
double bottom_dist = vecBdyDiss[2];
double left_dist = vecBdyDiss[3];
// 计算四个顶点的坐标
QPointF topLeft(dX - left_dist, dY + top_dist); // 左上角
QPointF topRight(dX + right_dist, dY + top_dist); // 右上角
QPointF bottomRight(dX + right_dist, dY - bottom_dist); // 右下角
QPointF bottomLeft(dX - left_dist, dY - bottom_dist); // 左下角
// 创建边界点集合
QVector<QPointF> vecBoundaryPoints;
vecBoundaryPoints << topLeft << topRight << bottomRight << bottomLeft;
// 创建矩形边界数据对象
nmDataOutline* pOutlineData = pDataManager->createOutline();
Q_ASSERT(pOutlineData);
if(pOutlineData == nullptr) {
return false;
}
// 设置默认边界名称
pOutlineData->setName("");
// 设置边界点
pOutlineData->setOutlinePoints(vecBoundaryPoints);
// 设置边界类型
pOutlineData->setOutlineType(NM_Rect_Outline_Type);
// 设置流型列表假设全部为0
QVector<int> vecFlowTypes(vecBoundaryPoints.size(), 0);
pOutlineData->setFlowTypeList(vecFlowTypes);
} else {
// 圆形边界
QString s = "re";
double dRadius = 0.0;
if(mapAnaParas.contains(s)) {
dRadius = mapAnaParas[s].toDouble();
}
// 创建圆形边界数据对象
nmDataOutline* pOutlineData = pDataManager->createOutline();
Q_ASSERT(pOutlineData);
if(pOutlineData == nullptr) {
return false;
}
// 设置默认边界名称
pOutlineData->setName("");
// 设置半径
pOutlineData->setRadius(dRadius);
// 设置圆心
pOutlineData->setCenter(QPointF(dX, dY));
// 设置边界类型
pOutlineData->setOutlineType(NM_Data_Outline_Type::NM_Round_Outline_Type);
// 设置流型列表假设全部为0
QVector<int> vecFlowTypes(1, 0);
pOutlineData->setFlowTypeList(vecFlowTypes);
// 创建存储点的向量
QVector<QPointF> vecPoints;
// 放入圆心
vecPoints.append(QPointF(dX, dY));
// 放入半径
vecPoints.append(QPointF(dRadius, dRadius));
// 计算圆上的四个关键点并放入向量(上、右、下、左)
vecPoints.append(QPointF(dX, dY - dRadius));
vecPoints.append(QPointF(dX + dRadius, dY));
vecPoints.append(QPointF(dX, dY + dRadius));
vecPoints.append(QPointF(dX - dRadius, dY));
// 添加到数据中
pOutlineData->setOutlinePoints(vecPoints);
}
} else {
// 如果解析解这里没有设置边界,数值解设置默认边界
// 创建默认矩形边界数据对象
nmDataOutline* pDefaultOutlineData = pDataManager->createOutline();
Q_ASSERT(pDefaultOutlineData);
if(pDefaultOutlineData == nullptr) {
return false;
}
// 设置默认边界名称
pDefaultOutlineData->setName("");
// 设置边界点
QVector<QPointF> vecPoints;
vecPoints << QPointF(-1000.00, 1000.00)
<< QPointF(1000.00, 1000.00)
<< QPointF(1000.00, -1000.00)
<< QPointF(-1000.00, -1000.00);
pDefaultOutlineData->setOutlinePoints(vecPoints);
// 设置边界类型
pDefaultOutlineData->setOutlineType(NM_Rect_Outline_Type);
// 设置流型列表假设全部为0
QVector<int> vecFlowTypes(vecPoints.size(), 0);
pDefaultOutlineData->setFlowTypeList(vecFlowTypes);
}
// 1.6 创建时间步设置相关数据
pDataManager->createTimeStep();
// 创建敏感性分析数据
pDataManager->createSensitiveData();
// TODO创建nmSubWndMain的作用主要是因为求解函数在这个类里后续应该拆分掉
nmSubWndMain* pSubWndMain = new nmSubWndMain(NULL, "");
ZxMainWindow* pMainWnd = pSubWndF->getMainWindow();
// 设置当前窗口到Map
pSubWndMain->setMainWindow(pMainWnd);
pWxDockNm1->setWindowTitle(tr("Generate numerical model")); //改变Title
pWxDockNm2->setWindowTitle(tr("Parameters"));
//QTextEdit* pWx1 = new QTextEdit("This is demo for upper");
//QTextEdit* pWx2 = new QTextEdit("This is demo for lower");
nmWxNumericalDesign* pAnalWx = new nmWxNumericalDesign();
nmWxParameterProperty* pParaWx = new nmWxParameterProperty();
// 建立求解调用连接
connect(pAnalWx, SIGNAL(sigGenerateClicked()),
pSubWndMain, SLOT(onGenerateButtonClicked()));
// 建立更新参数栏连接
//connect(pAnalWx, SIGNAL(sigIncludeWells()),
// pParaWx, SLOT(onUpdate()));
// 井图元更新连接
// connect(pAnalWx, SIGNAL(sigUpdateWellPlot(nmDataAnalyzeManager*)),
// pSubWndMain, SLOT(slotUpdateWellPlotByDataManager(nmDataAnalyzeManager*)));
// QTextEdit* pWx1 = new CustomParaWx("This is demo for upper");
// pWx1->...
Q_ASSERT(nullptr != pAnalWx);
Q_ASSERT(nullptr != pParaWx);
pWxDockNm1->setWidget(pAnalWx);
pWxDockNm2->setWidget(pParaWx);
return true; //your own codes
}
bool nmSubWndUtils::getAnaDockParas(iSubWnd* pSubWnd)
{
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
Q_ASSERT(nullptr != pSubWndF);
if(pSubWndF == nullptr) {
return false;
}
//////////////////////////////////////////////////////////////////
// 如下代码,请根据需要在合适位置借鉴参照编写
QMap<QString, QVariant> mapAnaParas;//当前解析解的参数
mapAnaParas.clear();
pSubWndF->getBrotherDockParas(mapAnaParas, false);
Q_ASSERT(mapAnaParas.count() > 0);
// 解析解边界类型
m_Bdy_Type oBdyType = BT_None;
QString sKey = "Bdy";
if (mapAnaParas.contains(sKey))
{
int n = mapAnaParas[sKey].toInt();
if (n <= (int)BT_Rect)
{
oBdyType = m_Bdy_Type(n);
}
}
// 边界距离(是井点到四周的直线距离)
if (oBdyType == BT_Rect || oBdyType == BT_Circle)
{
VecDouble vecBdyDiss;
vecBdyDiss.clear();
int nCount = (oBdyType == BT_Rect ? 4 : 1);
for (int i = 1; i <= nCount; i++)
{
QString sRealBdyName = getBdyRealNameOf(i, mapAnaParas); //sRealBdyName为map中边界距离key的真实内容
sKey = sRealBdyName;
if (!sKey.isEmpty() && mapAnaParas.contains(sKey))
{
vecBdyDiss << mapAnaParas[sKey].toDouble();
}
else
{
Q_ASSERT (false);//TODO
}
}
// 说明对于BT_RectvecBdyDiss中存放的四个距离数值依次为ne/下se/左we/右ee
// 对于BT_CirclevecBdyDiss中存放的是圆形半径r
}
//////////////////////////////////////////////////////////////////
return true;
}
QString nmSubWndUtils::getBdyRealNameOf(int xIndex, QMap<QString, QVariant>& map)
{
QStringList list;
list << "ne" << "se" << "we" << "ee" << "re";
int n = -1;
for (int i = 0; i < list.count(); i++)
{
QString s = list[i];
if (map.find(s) != map.end())
{
n++;
if (n == xIndex - 1)//TODO -1,从1开始
{
return s;
}
}
}
//m_sError = QString("Bdy name of 'x%1'' not found.").arg(xIndex);
//zxLogRunF(m_sError);
return "";
}
bool nmSubWndUtils::nmCalAndFresh(iSubWnd* pSubWnd, \
const ZxMainWindow* pMainWnd)
{
return false;
}
bool nmSubWndUtils::saveRsts(iSubWnd* pSubWnd, \
QString sRstName, \
const ZxMainWindow* pMainWnd)
{
Q_ASSERT(nullptr != pSubWnd);
if(pSubWnd == nullptr) {
return false;
}
// 流动段分析窗体
if(pSubWnd->getWndID() == "3004") {
// 转换为Fitting窗口
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
if(pSubWndF == nullptr) {
return false;
}
// 根据窗体指针,找到创建的对应的数据管理对象
nmDataAnalyzeManager*pDataManager = nmDataAnalyzeManager::findManagerByFitting(pSubWndF);
// 如果不存在,则说明当前分析窗体没有做数值解,不需要做保存处理
if(pDataManager == nullptr) {
return false;
}
// 如果存在,则对当前分析数据进行保存
if(!pDataManager->saveNmResult(sRstName, pSubWndF)) {
return false;
}
} else if(pSubWnd->getWndID() == "5118") {
return true;
} else if(pSubWnd->getWndID() == "5114") {
return true;
}
// TODOMap窗口保存、网格窗口保存
return true;
}
bool nmSubWndUtils::loadRsts(iSubWnd* pSubWnd, \
QString sRstName, \
const ZxMainWindow* pMainWnd)
{
Q_ASSERT(nullptr != pSubWnd);
if(pSubWnd == nullptr) {
return false;
}
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
nmSubWndUtils* pUtilsInstance = nmSubWndUtils::getInstance();
if(nullptr != pMainWnd1) {
ZxTabWidget* pTabWx = pMainWnd1->getCurTabWx();
if(nullptr != pTabWx) {
if(pUtilsInstance->m_pTabWx == nullptr || pUtilsInstance->m_pTabWx != pTabWx) {
pUtilsInstance->m_pTabWx = pTabWx;
disconnect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
connect(pUtilsInstance->m_pTabWx, SIGNAL(currentChanged(int)), pUtilsInstance, SLOT(slotHandleTabChange(int)));
}
}
}
// 处理流动段分析窗口数据
if(pSubWnd->getWndID() == "3004") {
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
if(pSubWndF == nullptr) {
return false;
}
// 获取当前分析窗体Code
ZxRstWnd* pRstWnd = pSubWndF->getRstUtilWnd();
if(pRstWnd == nullptr) {
return false;
}
QString sRstUtilWndCode = pRstWnd->getCode();
ZxDataWell* pCurrentWell = pSubWndF->getDataWell();
if(pCurrentWell == nullptr) {
return false;
}
// 获取该分析所在的目录
QString sDir = ZxBaseUtil::getWellDirOf(pCurrentWell->getName(), "Nm");
sDir += sRstName + "/" + sRstUtilWndCode;
// 判断分析目录是否存在
bool bDirExists = nmDataAnalyzeManager::isDirExist(sDir);
// 如果不存在,则说明没有保存数值解的参数
if(!bDirExists) {
return false;
}
// 存在,说明保存了数值解的参数,需要解析文件里的数据到数据中心
// 动态创建数据中心类
nmDataAnalyzeManager* pDataManager = nmDataAnalyzeManager::getInstanceByFitting(pSubWndF);
if(pDataManager == nullptr) {
return false;
}
// 设置当前操作的是哪一个分析
nmDataAnalyzeManager::setCurrentFitting(pSubWndF);
// 加载本地文件的数据到数据中心里的数据体里
pDataManager->loadNmResult(sDir);
// 加载当前分析中的PVT数据
pDataManager->initPvtParaFromSubFit();
// 切换左侧参数视图
pSubWndF->swapAnaNmDocks(true);
iDockBaseWx* pWxDockNm1 = pSubWndF->getNmDockWx(0);
iDockBaseWx* pWxDockNm2 = pSubWndF->getNmDockWx(1);
Q_ASSERT(nullptr != pWxDockNm1);
Q_ASSERT(nullptr != pWxDockNm2);
if(pWxDockNm1 == nullptr || pWxDockNm2 == nullptr) {
return false;
}
if(pWxDockNm1->widget() != nullptr && pWxDockNm2->widget() != nullptr) {
return true; //已经设定的话,则不再处理
}
// 创建Map暂时
nmSubWndMain* pSubWndMain = new nmSubWndMain(NULL, "");
ZxMainWindow* pMainWnd1 = const_cast<ZxMainWindow*>(pMainWnd);
pSubWndMain->setMainWindow(pMainWnd1);
//pWxDockNm1->setWindowTitle(tr("Dock1's Title"));
//pWxDockNm2->setWindowTitle(tr("Dock2's Title"));
pWxDockNm1->setWindowTitle(tr("Generate numerical model")); //改变Title
pWxDockNm2->setWindowTitle(tr("Parameters"));
// 自定义窗体指针
nmWxNumericalDesign* pAnalWx = new nmWxNumericalDesign();
nmWxParameterProperty* pParaWx = new nmWxParameterProperty();
Q_ASSERT(nullptr != pAnalWx);
Q_ASSERT(nullptr != pParaWx);
// 建立求解调用连接
connect(pAnalWx, SIGNAL(sigGenerateClicked()),
pSubWndMain, SLOT(onGenerateButtonClicked()));
// 建立更新参数栏连接
connect(pAnalWx, SIGNAL(sigIncludeWells()),
pParaWx, SLOT(onUpdate()));
// 井图元更新连接
// connect(pAnalWx, SIGNAL(sigUpdateWellPlot(nmDataAnalyzeManager*)),
// pSubWndMain, SLOT(slotUpdateWellPlotByDataManager(nmDataAnalyzeManager*)));
//connect(pAnalWx, SIGNAL(sigIncludeWells()),
// pParaWx, SLOT(onUpdate()));
pWxDockNm1->setWidget(pAnalWx);
pWxDockNm2->setWidget(pParaWx);
// 判断是否保存了时间步数据
if(!pDataManager->isTimeStepDataEmpty()) {
QString sErrorMessage;
// 刷新场图
QWidget* p3DWidget = pSubWndF->getFitSubRstWxOf(FSRT_Nm3D, true, &sErrorMessage);
// 创建 vtkWidget
nmWxPostprocessingAnimationWidget* pVtkWidget = nullptr;
pVtkWidget = new nmWxPostprocessingAnimationWidget();
if(p3DWidget == nullptr || pVtkWidget == nullptr) {
delete pVtkWidget;
return false;
}
// 先清理
// 获取当前布局
QLayout* p3DLayout = p3DWidget->layout();
if(p3DLayout) {
// 移除布局中的所有控件
QLayoutItem* item;
while((item = p3DLayout->takeAt(0))) {
if(item->widget()) {
// 删除控件
delete item->widget();
}
delete item; // 删除布局项
}
// 删除布局
delete p3DLayout;
}
// 确保布局被移除
p3DWidget->setLayout(nullptr);
// 创建一个垂直布局管理器
QVBoxLayout* p3DnewLayout = new QVBoxLayout(p3DWidget);
// 将现有的控件添加到布局中
p3DnewLayout->addWidget(pVtkWidget);
// 设置 widget 的布局
p3DWidget->setLayout(p3DnewLayout);
// 刷新结果参数
// 结果参数界面
QWidget* pRstWidget = pSubWndF->getFitSubRstWxOf(FSRT_NmRst, true, &sErrorMessage);
if(pRstWidget == nullptr) {
return false;
}
// 创建结果参数界面
nmWxResultParameters* pResultWidget = new nmWxResultParameters;
// 先清理
// 获取当前布局
QLayout* pRstLayout = pRstWidget->layout();
if(pRstLayout) {
// 移除布局中的所有控件
QLayoutItem* item;
while((item = pRstLayout->takeAt(0))) {
if(item->widget()) {
// 删除控件
delete item->widget();
}
delete item; // 删除布局项
}
// 删除布局
delete pRstLayout;
}
// 确保布局被移除
pRstWidget->setLayout(nullptr);
// 创建一个垂直布局管理器
QVBoxLayout* pRstnewLayout = new QVBoxLayout(pRstWidget);
// 将现有的控件添加到布局中
pRstnewLayout->addWidget(pResultWidget);
// 设置 widget 的布局
pRstWidget->setLayout(pRstnewLayout);
}
}
//// 请根据需要确定,文件存储的路径
//QString sDir = ZxBaseUtil::getCurWellDirOf("Nm");
////iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
////Q_ASSERT(nullptr != pSubWndF);
//QString sRstUtilWndCode = pSubWnd->getRstUtilWnd()->getCode();
//QByteArray ba = QByteArray();//这是你读取出来的内容
//ZxUiBase* pWx = nullptr; //your own widget
//if (nullptr != pWx && !ba.isNull())
//{
// // 根据二进制内容更新窗体内容
// // 注意loadFromByteArr是 iWxBasePVT模块中的接口如果需要请参考下面源码进行自行实现
// //pWx->loadFromByteArr(ba);
//}
// 如果需要把二进制内容更新至其它如double数组、map等存入可以参照 ZxBaHelper 提供的接口
// 其它代码
return true;
}
// 如果需要加载某个窗体继承自ZxUiBase并且实现了序列化接口onSerialize/onDeserialize
// 则可以参照如下进行
#ifdef _SCAN_OLD_CODES_
bool iWxBase::saveAsByteArr(QByteArray& v)
{
QString sRoot = this->objectName() + "abc";
ZxXpfDoc xpf(sRoot);
ZxSerializer ser(&xpf, true);
onSerialize(&ser);
QDataStream out(&v, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_8);
if (xpf.save(out))
{
return true;
}
else
{
return false;
}
return true;
}
bool iWxBase::loadFromByteArr(QByteArray& v)
{
QDataStream in(&v, QIODevice::ReadOnly);
// quint32 nVer = ser->getDocDate();
// if (nVer > (quint32)(20180101))
// {
// in.setVersion(QDataStream::Qt_4_8);
// }
// else
{
in.setVersion(QDataStream::Qt_4_8);
}
QString sRoot = this->objectName() + "abc";
ZxXpfDoc xpf(sRoot);
if (!xpf.load(in))
{
zxLogRunW(tr("Failed to load ByteArray"));
return false;
}
ZxSerializer ser(&xpf, false);
onDeserialize(&ser);
return true;
}
#endif
void nmSubWndUtils::slotHandleTabChange(int index)
{
// 找到索引对应的流动段分析窗体
if(m_pTabWx == nullptr) {
return;
}
if(index >= 0 && index < m_pTabWx->count()) {
iSubWnd* pSubWnd = dynamic_cast<iSubWnd*>(m_pTabWx->widget(index));
if(pSubWnd == nullptr) {
return;
}
// 切换的是流动段分析
if(pSubWnd->getWndID() == "3004") {
iSubWndFitting* pSubWndF = dynamic_cast<iSubWndFitting*>(pSubWnd);
if(pSubWndF == nullptr) {
return;
}
// 查找有没有对应的数据中心实例
nmDataAnalyzeManager* pDataManger = nmDataAnalyzeManager::findManagerByFitting(pSubWndF);
if(pDataManger != nullptr && nmDataAnalyzeManager::getCurrentFitting() != pSubWndF) {
// 有对应的实例,并且不是当前分析
nmDataAnalyzeManager::setCurrentFitting(pSubWndF);
ZxMainWindow* pMainWnd = pSubWndF->getMainWindow();
Q_ASSERT(nullptr != pMainWnd);
if(pMainWnd == nullptr) {
return;
}
// 如果地图和网格窗体存在,则更新
QVector<iSubWnd*> vecSubWnds = pMainWnd->getAllSubWndsOf(m_pTabWx);
foreach(iSubWnd* pSub, vecSubWnds) {
nmSubWndMain* pMap = dynamic_cast<nmSubWndMain*>(pSub);
if(nullptr != pMap) {
// 更新地图相关信息
pMap->updateMapByDataManager(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF));
}
// TODO网格更新
nmSubWndGrid* pSubWndGrid = dynamic_cast<nmSubWndGrid*>(pSub);
if(nullptr != pSubWndGrid) {
// 更新网格
disconnect(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()));
connect(nmDataAnalyzeManager::getInstanceByFitting(pSubWndF), SIGNAL(dataChanged()), pSubWndGrid, SLOT(updateGrid()), Qt::QueuedConnection);
// 手动更新
pSubWndGrid->updateGrid();
}
}
}
}
}
}