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/nmPlot/nmPlotGraphicBinder.cpp

1109 lines
32 KiB
C++

#include "nmPlotGraphicBinder.h"
#include "nmObjLineFault.h"
#include "nmDataFault.h"
#include "nmObjLineCrack.h"
#include "nmDataFracture.h"
#include "nmObjRoundOutline.h"
#include "nmObjRectOutline.h"
#include "nmObjPolygonOutline.h"
#include "nmDataOutline.h"
#include "nmObjLineMeasure.h"
#include "nmDataMeasure.h"
#include "nmObjRegionMark.h"
#include "nmDataRegionMark.h"
#include "nmObjBase.h"
#include "nmDataAnalyzeManager.h"
#include <QMetaObject>
nmPlotGraphicBinder::nmPlotGraphicBinder(nmDataAnalyzeManager* pDataMgr, QObject* parent)
: QObject(parent)
, m_pDataMgr(pDataMgr)
{
}
// 用户画完断层后:创建数据对象并建立绑定
void nmPlotGraphicBinder::createFaultForGraphic(nmObjLineFault* pGraphic)
{
if (!pGraphic || !m_pDataMgr) {
return;
}
// 创建数据对象
nmDataFault* pData = m_pDataMgr->createFault();
// 将图元值推入数据
pData->setFaultName(pGraphic->getName());
pData->setFaultPoints(pGraphic->getAllValues());
// 建立信号连接
_connectFault(pGraphic, pData);
m_pDataMgr->notifyDataChanged();
}
// 从文件加载:绑定已有数据到已有图元
void nmPlotGraphicBinder::bindFaultToGraphic(nmObjLineFault* pGraphic, nmDataFault* pData)
{
if (!pGraphic || !pData) {
return;
}
// 将数据值推到图元
_pushFaultDataToGraphic(pGraphic, pData);
// 建立信号连接
_connectFault(pGraphic, pData);
}
// 删除图元:断开连接并移除数据
void nmPlotGraphicBinder::removeFaultBinding(nmObjLineFault* pGraphic)
{
if (!pGraphic) {
return;
}
// 断开信号
_disconnectFault(pGraphic);
// 从数据中心移除
if (m_mapFaultData.contains(pGraphic)) {
nmDataFault* pData = m_mapFaultData.value(pGraphic);
if (pData && m_pDataMgr) {
m_pDataMgr->removeFaultData(pData);
}
m_mapFaultData.remove(pGraphic);
}
}
nmDataFault* nmPlotGraphicBinder::getFaultDataFor(nmObjLineFault* pGraphic)
{
return m_mapFaultData.value(pGraphic, nullptr);
}
// 名称同步:检测图元名称与数据名称是否一致,不一致则同步
void nmPlotGraphicBinder::syncFaultName(nmObjLineFault* pGraphic)
{
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (pData && pData->getFaultName() != pGraphic->getName()) {
pData->setFaultName(pGraphic->getName());
}
}
// 切换分析时更新绑定的 DataManager
// 旧图元已由 deleteAllPlotObjs 清除,清理残留映射避免悬空指针
void nmPlotGraphicBinder::updateDataMgr(nmDataAnalyzeManager* pDataMgr)
{
m_mapFaultData.clear();
m_setBoundGraphics.clear();
m_mapCrackData.clear();
m_setBoundCrackGraphics.clear();
m_mapOutlineData.clear();
m_setBoundOutlineGraphics.clear();
m_mapMeasureData.clear();
m_mapRegionMarkData.clear();
m_setBoundRegionMarkGraphics.clear();
m_pDataMgr = pDataMgr;
}
// 将数据值推到图元本地副本
void nmPlotGraphicBinder::_pushFaultDataToGraphic(nmObjLineFault* pGraphic, nmDataFault* pData)
{
// 阻断信号,防止推送中触发反向同步
pGraphic->blockSignals(true);
pGraphic->setName(pData->getFaultName());
int flowModel = (pData->getFaultFlowModel().getValue() == tr("Leaky")) ? 0 : 1;
pGraphic->setFaultFlowModel(flowModel);
pGraphic->setFaultLeakage(pData->getFaultLeakage().getValue().toDouble());
pGraphic->blockSignals(false);
}
// 建立图元与数据的双向信号连接
void nmPlotGraphicBinder::_connectFault(nmObjLineFault* pGraphic, nmDataFault* pData)
{
QObject::connect(pGraphic, SIGNAL(sigFlowModelChanged(int)),
this, SLOT(onGraphicFlowModelChanged(int)));
QObject::connect(pGraphic, SIGNAL(sigLeakageChanged(double)),
this, SLOT(onGraphicLeakageChanged(double)));
QObject::connect(pGraphic, SIGNAL(sigPointsChanged()),
this, SLOT(onGraphicPointsChanged()));
QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicVisibleChanged(bool)));
m_mapFaultData[pGraphic] = pData;
m_setBoundGraphics.insert(pGraphic);
pGraphic->setGraphicBinder(this);
}
// 断开图元与本 Binder 的所有信号连接
void nmPlotGraphicBinder::_disconnectFault(nmObjLineFault* pGraphic)
{
QObject::disconnect(pGraphic, SIGNAL(sigFlowModelChanged(int)),
this, SLOT(onGraphicFlowModelChanged(int)));
QObject::disconnect(pGraphic, SIGNAL(sigLeakageChanged(double)),
this, SLOT(onGraphicLeakageChanged(double)));
QObject::disconnect(pGraphic, SIGNAL(sigPointsChanged()),
this, SLOT(onGraphicPointsChanged()));
QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicVisibleChanged(bool)));
m_setBoundGraphics.remove(pGraphic);
}
// 图元属性变更 → 同步到数据
// 流动模型变更
void nmPlotGraphicBinder::onGraphicFlowModelChanged(int model)
{
nmObjLineFault* pGraphic = qobject_cast<nmObjLineFault*>(sender());
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFaultFlowModel();
attr.setValue(model == 0 ? tr("Leaky") : tr("Composite Limit"));
pData->setFaultFlowModel(attr);
}
// 渗漏率变更
void nmPlotGraphicBinder::onGraphicLeakageChanged(double leakage)
{
nmObjLineFault* pGraphic = qobject_cast<nmObjLineFault*>(sender());
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFaultLeakage();
attr.setValue(leakage);
pData->setFaultLeakage(attr);
}
// 点坐标变更
void nmPlotGraphicBinder::onGraphicPointsChanged()
{
nmObjLineFault* pGraphic = qobject_cast<nmObjLineFault*>(sender());
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (!pData) return;
pData->setFaultPoints(pGraphic->getAllValues());
pData->setFaultName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 可见性变更
void nmPlotGraphicBinder::onGraphicVisibleChanged(bool bVisible)
{
nmObjLineFault* pGraphic = qobject_cast<nmObjLineFault*>(sender());
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (!pData) return;
pData->setPlotVisible(bVisible);
}
// 数据变更(预留)
void nmPlotGraphicBinder::onDataChanged()
{
}
// ============ 裂缝绑定 ============
// 用户画完裂缝后:创建数据对象并建立绑定
void nmPlotGraphicBinder::createCrackForGraphic(nmObjLineCrack* pGraphic)
{
if (!pGraphic || !m_pDataMgr) {
return;
}
// 创建数据对象
nmDataFracture* pData = m_pDataMgr->createFracture();
// 将图元值推入数据
pData->setFractureName(pGraphic->getName());
pData->setFracturePoints(pGraphic->getAllValues());
// 建立信号连接
_connectCrack(pGraphic, pData);
m_pDataMgr->notifyDataChanged();
}
// 从文件加载:绑定已有裂缝数据到已有图元
void nmPlotGraphicBinder::bindCrackToGraphic(nmObjLineCrack* pGraphic, nmDataFracture* pData)
{
if (!pGraphic || !pData) {
return;
}
// 将数据值推到图元
_pushCrackDataToGraphic(pGraphic, pData);
// 建立信号连接
_connectCrack(pGraphic, pData);
}
// 删除裂缝图元:断开连接并移除数据
void nmPlotGraphicBinder::removeCrackBinding(nmObjLineCrack* pGraphic)
{
if (!pGraphic) {
return;
}
// 断开信号
_disconnectCrack(pGraphic);
// 从数据中心移除
if (m_mapCrackData.contains(pGraphic)) {
nmDataFracture* pData = m_mapCrackData.value(pGraphic);
if (pData && m_pDataMgr) {
m_pDataMgr->removeFractureData(pData);
}
m_mapCrackData.remove(pGraphic);
}
}
nmDataFracture* nmPlotGraphicBinder::getCrackDataFor(nmObjLineCrack* pGraphic)
{
return m_mapCrackData.value(pGraphic, nullptr);
}
// 名称同步:检测图元名称与数据名称是否一致,不一致则同步
void nmPlotGraphicBinder::syncCrackName(nmObjLineCrack* pGraphic)
{
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (pData && pData->getFractureName() != pGraphic->getName()) {
pData->setFractureName(pGraphic->getName());
}
}
// 将裂缝数据值推到图元本地副本
void nmPlotGraphicBinder::_pushCrackDataToGraphic(nmObjLineCrack* pGraphic, nmDataFracture* pData)
{
// 阻断信号,防止推送中触发反向同步
pGraphic->blockSignals(true);
pGraphic->setName(pData->getFractureName());
int flowModel = (pData->getFractureFlowModel().getValue() == tr("Infinite Conductivity")) ? 0 : 1;
pGraphic->setCrackFlowModel(flowModel);
pGraphic->setCrackDfc(pData->getFractureDfc().getValue().toDouble());
pGraphic->setCrackDw(pData->getFractureDw().getValue().toDouble());
pGraphic->blockSignals(false);
}
// 建立裂缝图元与数据的双向信号连接
void nmPlotGraphicBinder::_connectCrack(nmObjLineCrack* pGraphic, nmDataFracture* pData)
{
QObject::connect(pGraphic, SIGNAL(sigFlowModelChanged(int)),
this, SLOT(onGraphicCrackFlowModelChanged(int)));
QObject::connect(pGraphic, SIGNAL(sigDfcChanged(double)),
this, SLOT(onGraphicCrackDfcChanged(double)));
QObject::connect(pGraphic, SIGNAL(sigDwChanged(double)),
this, SLOT(onGraphicCrackDwChanged(double)));
QObject::connect(pGraphic, SIGNAL(sigPointsChanged()),
this, SLOT(onGraphicCrackPointsChanged()));
QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicCrackVisibleChanged(bool)));
m_mapCrackData[pGraphic] = pData;
m_setBoundCrackGraphics.insert(pGraphic);
pGraphic->setGraphicBinder(this);
}
// 断开裂缝图元与本 Binder 的所有信号连接
void nmPlotGraphicBinder::_disconnectCrack(nmObjLineCrack* pGraphic)
{
QObject::disconnect(pGraphic, SIGNAL(sigFlowModelChanged(int)),
this, SLOT(onGraphicCrackFlowModelChanged(int)));
QObject::disconnect(pGraphic, SIGNAL(sigDfcChanged(double)),
this, SLOT(onGraphicCrackDfcChanged(double)));
QObject::disconnect(pGraphic, SIGNAL(sigDwChanged(double)),
this, SLOT(onGraphicCrackDwChanged(double)));
QObject::disconnect(pGraphic, SIGNAL(sigPointsChanged()),
this, SLOT(onGraphicCrackPointsChanged()));
QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicCrackVisibleChanged(bool)));
m_setBoundCrackGraphics.remove(pGraphic);
}
// 裂缝流动模型变更
void nmPlotGraphicBinder::onGraphicCrackFlowModelChanged(int model)
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFractureFlowModel();
attr.setValue(model == 0 ? tr("Infinite Conductivity") : tr("Finite Conductivity"));
pData->setFractureFlowModel(attr);
}
// 裂缝导流能力变更
void nmPlotGraphicBinder::onGraphicCrackDfcChanged(double dfc)
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFractureDfc();
attr.setValue(dfc);
pData->setFractureDfc(attr);
}
// 裂缝储能比变更
void nmPlotGraphicBinder::onGraphicCrackDwChanged(double dw)
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFractureDw();
attr.setValue(dw);
pData->setFractureDw(attr);
}
// 裂缝点坐标变更
void nmPlotGraphicBinder::onGraphicCrackPointsChanged()
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
pData->setFracturePoints(pGraphic->getAllValues());
pData->setFractureName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 裂缝可见性变更
void nmPlotGraphicBinder::onGraphicCrackVisibleChanged(bool bVisible)
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
pData->setPlotVisible(bVisible);
}
// ==================== 边界图元绑定 ====================
// 圆形边界:用户画完后创建数据并绑定
void nmPlotGraphicBinder::createOutlineForGraphic(nmObjRoundOutline* pGraphic)
{
if (!pGraphic || !m_pDataMgr) return;
// 清理旧边界图元的绑定(数据中心同一时间只持有一个边界数据)
QList<nmObjBase*> oldGraphics = m_mapOutlineData.keys();
foreach (nmObjBase* pOld, oldGraphics) {
if (pOld != pGraphic) {
_disconnectOutline(pOld);
m_mapOutlineData.remove(pOld);
}
}
nmDataOutline* pData = m_pDataMgr->createOutline();
pData->setName(pGraphic->getName());
pData->setOutlinePoints(pGraphic->getAllValues());
pData->setFlowTypeList(pGraphic->m_vFlowTypeList);
pData->setOutlineType(NM_Data_Outline_Type::NM_Round_Outline_Type);
// 视觉属性同步到数据
pData->setPenWidth(pGraphic->getPen().widthF());
QColor roundClr = pGraphic->getBackgrdColor();
pData->setBackgrdColor(roundClr);
pData->setBackgrdAlpha(roundClr.alpha());
pData->setVisualPropsValid(true);
double qradius = pGraphic->getAllValues()[2].y() - pGraphic->getAllValues()[0].y();
pData->setRadius(qradius);
pData->setCenter(pGraphic->getAllValues()[0]);
m_mapOutlineData[pGraphic] = pData;
m_setBoundOutlineGraphics.insert(pGraphic);
_connectOutline(pGraphic, pData);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 矩形边界:用户画完后创建数据并绑定
void nmPlotGraphicBinder::createOutlineForGraphic(nmObjRectOutline* pGraphic)
{
if (!pGraphic || !m_pDataMgr) return;
// 清理旧边界图元的绑定(数据中心同一时间只持有一个边界数据)
QList<nmObjBase*> oldGraphics = m_mapOutlineData.keys();
foreach (nmObjBase* pOld, oldGraphics) {
if (pOld != pGraphic) {
_disconnectOutline(pOld);
m_mapOutlineData.remove(pOld);
}
}
nmDataOutline* pData = m_pDataMgr->createOutline();
pData->setName(pGraphic->getName());
pData->setOutlinePoints(pGraphic->getAllValues());
pData->setFlowTypeList(pGraphic->m_vFlowTypeList);
pData->setOutlineType(NM_Data_Outline_Type::NM_Rect_Outline_Type);
pData->setPenWidth(pGraphic->getPen().widthF());
pData->setBackgrdColor(pGraphic->getBackgrdColor());
pData->setBackgrdAlpha(pGraphic->getBackgrdAlpha());
pData->setVisualPropsValid(true);
m_mapOutlineData[pGraphic] = pData;
m_setBoundOutlineGraphics.insert(pGraphic);
_connectOutline(pGraphic, pData);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 多边形边界:用户画完后创建数据并绑定
void nmPlotGraphicBinder::createOutlineForGraphic(nmObjPolygonOutline* pGraphic)
{
if (!pGraphic || !m_pDataMgr) return;
// 清理旧边界图元的绑定(数据中心同一时间只持有一个边界数据)
QList<nmObjBase*> oldGraphics = m_mapOutlineData.keys();
foreach (nmObjBase* pOld, oldGraphics) {
if (pOld != pGraphic) {
_disconnectOutline(pOld);
m_mapOutlineData.remove(pOld);
}
}
nmDataOutline* pData = m_pDataMgr->createOutline();
pData->setName(pGraphic->getName());
pData->setOutlinePoints(pGraphic->getAllValues());
pData->setFlowTypeList(pGraphic->m_vFlowTypeList);
pData->setOutlineType(NM_Data_Outline_Type::NM_Polygon_Outline_Type);
pData->setPenWidth(pGraphic->getPen().widthF());
pData->setBackgrdColor(pGraphic->getBackgrdColor());
pData->setBackgrdAlpha(pGraphic->getBackgrdAlpha());
pData->setVisualPropsValid(true);
m_mapOutlineData[pGraphic] = pData;
m_setBoundOutlineGraphics.insert(pGraphic);
_connectOutline(pGraphic, pData);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 从文件加载,绑定已有边界数据到已有图元
void nmPlotGraphicBinder::bindOutlineToGraphic(nmObjBase* pGraphic, nmDataOutline* pData)
{
if (!pGraphic || !pData) return;
m_mapOutlineData[pGraphic] = pData;
m_setBoundOutlineGraphics.insert(pGraphic);
_pushOutlineDataToGraphic(pGraphic, pData);
_connectOutline(pGraphic, pData);
}
// 删除边界图元前,断开绑定并从数据中心移除
void nmPlotGraphicBinder::removeOutlineBinding(nmObjBase* pGraphic)
{
if (!pGraphic) return;
_disconnectOutline(pGraphic);
m_mapOutlineData.remove(pGraphic);
if (m_pDataMgr) {
m_pDataMgr->removeOutlineData();
m_pDataMgr->notifyDataChanged();
}
}
// 查找边界图元对应的数据指针
nmDataOutline* nmPlotGraphicBinder::getOutlineDataFor(nmObjBase* pGraphic)
{
return m_mapOutlineData.value(pGraphic, nullptr);
}
// 名称同步setName 不发信号,由图元在 paintBack 中调用
void nmPlotGraphicBinder::syncOutlineName(nmObjBase* pGraphic)
{
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (pData && pData->getName() != pGraphic->getName()) {
pData->setName(pGraphic->getName());
}
}
// 视觉属性兜底同步paintBack 中调用,确保画笔宽度、填充色、透明度始终同步到数据中心
void nmPlotGraphicBinder::syncOutlineVisual(nmObjBase* pGraphic)
{
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (!pData) return;
// 画笔宽度
QPen pen = pGraphic->getPen();
double penWidth = pen.widthF();
if (pData->getPenWidth() != penWidth) {
pData->setPenWidth(penWidth);
}
// 填充背景色和透明度
QColor backgrdColor;
int backgrdAlpha = 0;
if (nmObjRectOutline* pRect = dynamic_cast<nmObjRectOutline*>(pGraphic)) {
backgrdColor = pRect->getBackgrdColor();
backgrdAlpha = pRect->getBackgrdAlpha();
} else if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
backgrdColor = pRound->getBackgrdColor();
backgrdAlpha = backgrdColor.alpha(); // 圆形透明度嵌入在 QColor 中
} else if (nmObjPolygonOutline* pPolygon = dynamic_cast<nmObjPolygonOutline*>(pGraphic)) {
backgrdColor = pPolygon->getBackgrdColor();
backgrdAlpha = pPolygon->getBackgrdAlpha();
}
if (pData->getBackgrdColor().rgb() != backgrdColor.rgb()) {
pData->setBackgrdColor(backgrdColor);
}
if (pData->getBackgrdAlpha() != backgrdAlpha) {
pData->setBackgrdAlpha(backgrdAlpha);
}
pData->setVisualPropsValid(true);
}
// 建立边界图元与数据的信号连接(三条信号)
void nmPlotGraphicBinder::_connectOutline(nmObjBase* pGraphic, nmDataOutline* pData)
{
QObject::connect(pGraphic, SIGNAL(sigOutlinePointsChanged()),
this, SLOT(onGraphicOutlinePointsChanged()));
QObject::connect(pGraphic, SIGNAL(sigOutlineFlowTypeChanged()),
this, SLOT(onGraphicOutlineFlowTypeChanged()));
QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicOutlineVisibleChanged(bool)));
m_setBoundOutlineGraphics.insert(pGraphic);
// 注入 Binder 指针到图元
if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
pRound->setGraphicBinder(this);
} else if (nmObjRectOutline* pRect = dynamic_cast<nmObjRectOutline*>(pGraphic)) {
pRect->setGraphicBinder(this);
} else if (nmObjPolygonOutline* pPolygon = dynamic_cast<nmObjPolygonOutline*>(pGraphic)) {
pPolygon->setGraphicBinder(this);
}
}
// 断开边界图元与本 Binder 的信号连接
void nmPlotGraphicBinder::_disconnectOutline(nmObjBase* pGraphic)
{
QObject::disconnect(pGraphic, SIGNAL(sigOutlinePointsChanged()),
this, SLOT(onGraphicOutlinePointsChanged()));
QObject::disconnect(pGraphic, SIGNAL(sigOutlineFlowTypeChanged()),
this, SLOT(onGraphicOutlineFlowTypeChanged()));
QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicOutlineVisibleChanged(bool)));
m_setBoundOutlineGraphics.remove(pGraphic);
}
// 从边界数据对象读取值,写入图元本地副本(加载时用)
void nmPlotGraphicBinder::_pushOutlineDataToGraphic(nmObjBase* pGraphic, nmDataOutline* pData)
{
pGraphic->blockSignals(true);
pGraphic->setName(pData->getName());
QVector<int> flowTypes = pData->getFlowTypeList();
bool bPushVisual = pData->hasVisualProps();
if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
pRound->m_vFlowTypeList = flowTypes;
if (bPushVisual) {
QPen pen = pRound->getPen();
pen.setWidthF(pData->getPenWidth());
pRound->setPen(pen);
QColor clr = pData->getBackgrdColor();
clr.setAlpha(pData->getBackgrdAlpha());
pRound->setBackgrdColor(clr);
}
} else if (nmObjRectOutline* pRect = dynamic_cast<nmObjRectOutline*>(pGraphic)) {
pRect->m_vFlowTypeList = flowTypes;
if (bPushVisual) {
QPen pen = pRect->getPen();
pen.setWidthF(pData->getPenWidth());
pRect->setPen(pen);
pRect->setBackgrdColor(pData->getBackgrdColor());
pRect->setBackgrdAlpha(pData->getBackgrdAlpha());
}
} else if (nmObjPolygonOutline* pPolygon = dynamic_cast<nmObjPolygonOutline*>(pGraphic)) {
pPolygon->m_vFlowTypeList = flowTypes;
if (bPushVisual) {
QPen pen = pPolygon->getPen();
pen.setWidthF(pData->getPenWidth());
pPolygon->setPen(pen);
pPolygon->setBackgrdColor(pData->getBackgrdColor());
pPolygon->setBackgrdAlpha(pData->getBackgrdAlpha());
}
}
pGraphic->blockSignals(false);
}
// ==================== 边界图元信号 → 数据同步 ====================
// 边界点坐标变更
void nmPlotGraphicBinder::onGraphicOutlinePointsChanged()
{
nmObjBase* pGraphic = qobject_cast<nmObjBase*>(sender());
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (!pData) return;
pData->setOutlinePoints(pGraphic->getAllValues());
// 圆形边界额外同步 radius 和 center
if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
QVector<QPointF> pts = pRound->getAllValues();
if (pts.count() >= 3) {
double radius = pts[2].y() - pts[0].y();
pData->setRadius(radius);
pData->setCenter(pts[0]);
}
}
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 边界流动类型变更
void nmPlotGraphicBinder::onGraphicOutlineFlowTypeChanged()
{
nmObjBase* pGraphic = qobject_cast<nmObjBase*>(sender());
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (!pData) return;
QVector<int> flowTypes;
if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
flowTypes = pRound->m_vFlowTypeList;
} else if (nmObjRectOutline* pRect = dynamic_cast<nmObjRectOutline*>(pGraphic)) {
flowTypes = pRect->m_vFlowTypeList;
} else if (nmObjPolygonOutline* pPolygon = dynamic_cast<nmObjPolygonOutline*>(pGraphic)) {
flowTypes = pPolygon->m_vFlowTypeList;
}
pData->setFlowTypeList(flowTypes);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 边界可见性变更
void nmPlotGraphicBinder::onGraphicOutlineVisibleChanged(bool bVisible)
{
nmObjBase* pGraphic = qobject_cast<nmObjBase*>(sender());
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (!pData) return;
pData->setPlotVisible(bVisible);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// ==================== 测量线图元 ====================
// 用户画完测量线后:获取数据对象并建立绑定
void nmPlotGraphicBinder::createMeasureForGraphic(nmObjLineMeasure* pGraphic)
{
if (!pGraphic || !m_pDataMgr) {
return;
}
// 获取测量数据单例
nmDataMeasure* pData = m_pDataMgr->getMeasureData();
// 将图元坐标推入数据
QVector<QPointF> pts = pGraphic->getAllValues();
if (pts.count() >= 2) {
QPointF pStart = pts[0];
QPointF pEnd = pts[1];
double dLength = QLineF(pStart, pEnd).length();
if (pEnd != pStart) {
pData->setStartPoint(pStart);
pData->setEndPoint(pEnd);
} else {
pData->setCurrentPoint(pStart);
}
nmDataAttribute lenAttr = pData->getLength();
lenAttr.setValue(dLength);
pData->setLength(lenAttr);
}
// 建立映射
m_mapMeasureData[pGraphic] = pData;
pGraphic->setGraphicBinder(this);
m_pDataMgr->notifyDataChanged();
}
// 删除测量线图元:移除映射(不删除数据对象,由 DataManager 管理)
void nmPlotGraphicBinder::removeMeasureBinding(nmObjLineMeasure* pGraphic)
{
if (!pGraphic) {
return;
}
m_mapMeasureData.remove(pGraphic);
}
// 坐标同步:从数据对象读取起点终点,写回图元(拟合功能修改数据后由 paintBack 调用)
void nmPlotGraphicBinder::syncMeasurePoints(nmObjLineMeasure* pGraphic)
{
if (!pGraphic || !m_pDataMgr) return;
nmDataMeasure* pData = m_mapMeasureData.value(pGraphic, nullptr);
if (!pData) return;
QPointF startPt = pData->getStartPoint();
QPointF endPt = pData->getEndPoint();
// 仅在坐标确实变化时才更新,避免每次绘制都无谓写入
QVector<QPointF> currentPts = pGraphic->getAllValues();
if (currentPts.count() >= 2 &&
currentPts[0] == startPt && currentPts[1] == endPt) {
return;
}
pGraphic->blockSignals(true);
QVector<QPointF> pts;
pts << startPt << endPt;
pGraphic->setAllValues(pts);
pGraphic->blockSignals(false);
}
// ==================== 区域标记图元 ====================
// 用户画完区域标记后:创建数据对象并建立绑定
void nmPlotGraphicBinder::createRegionMarkForGraphic(nmObjRegionMark* pGraphic)
{
if (!pGraphic || !m_pDataMgr) {
return;
}
// 创建数据对象
nmDataRegionMark* pData = m_pDataMgr->createRegionMark();
// 将图元值推入数据
pData->setRegionMarkName(pGraphic->getName());
QVector<QPointF> pts = pGraphic->getAllValues();
if (pts.count() >= 1) {
pData->setPtPos(pts[0]);
}
// 储层类型int → 字符串
nmDataAttribute attr = pData->getReservoirType();
if (pGraphic->getResevoirType() == 0) {
attr.setValue("Homogeneous");
} else {
attr.setValue("Dual porosity pseudo steady state");
}
pData->setReservoirType(attr);
// 综合压缩系数、净毛比
nmDataAttribute comKrAttr = pData->getComKr();
comKrAttr.setValue(pGraphic->getComKr());
pData->setComKr(comKrAttr);
nmDataAttribute comWAttr = pData->getComW();
comWAttr.setValue(pGraphic->getComW());
pData->setComW(comWAttr);
nmDataAttribute ntgAttr = pData->getNetToGross();
ntgAttr.setValue(pGraphic->getNetToGross());
pData->setNetToGross(ntgAttr);
// 建立信号连接
_connectRegionMark(pGraphic, pData);
m_pDataMgr->notifyDataChanged();
}
// 从文件加载:绑定已有区域标记数据到已有图元
void nmPlotGraphicBinder::bindRegionMarkToGraphic(nmObjRegionMark* pGraphic, nmDataRegionMark* pData)
{
if (!pGraphic || !pData) {
return;
}
// 将数据值推到图元本地副本
_pushRegionMarkDataToGraphic(pGraphic, pData);
// 建立信号连接
_connectRegionMark(pGraphic, pData);
}
// 删除区域标记图元:从数据中心移除数据并断开信号
void nmPlotGraphicBinder::removeRegionMarkBinding(nmObjRegionMark* pGraphic)
{
if (!pGraphic) {
return;
}
_disconnectRegionMark(pGraphic);
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (pData && m_pDataMgr) {
m_pDataMgr->removeRegionMarkData(pData);
}
m_mapRegionMarkData.remove(pGraphic);
}
// 兜底同步:名称、位置(由 paintBack 调用)
void nmPlotGraphicBinder::syncRegionMarkData(nmObjRegionMark* pGraphic)
{
if (!pGraphic) return;
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
pData->setRegionMarkName(pGraphic->getName());
QVector<QPointF> pts = pGraphic->getAllValues();
if (pts.count() >= 1) {
pData->setPtPos(pts[0]);
}
}
// 查找区域标记图元对应的数据指针
nmDataRegionMark* nmPlotGraphicBinder::getRegionMarkDataFor(nmObjRegionMark* pGraphic)
{
return m_mapRegionMarkData.value(pGraphic, nullptr);
}
// 图元信号 → 数据同步
void nmPlotGraphicBinder::onGraphicRegionMarkReservoirTypeChanged(int type)
{
nmObjRegionMark* pGraphic = qobject_cast<nmObjRegionMark*>(sender());
if (!pGraphic) return;
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getReservoirType();
if (type == 0) {
attr.setValue("Homogeneous");
} else {
attr.setValue("Dual porosity pseudo steady state");
}
pData->setReservoirType(attr);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
void nmPlotGraphicBinder::onGraphicRegionMarkComKrChanged(double comKr)
{
nmObjRegionMark* pGraphic = qobject_cast<nmObjRegionMark*>(sender());
if (!pGraphic) return;
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getComKr();
attr.setValue(comKr);
pData->setComKr(attr);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
void nmPlotGraphicBinder::onGraphicRegionMarkComWChanged(double comW)
{
nmObjRegionMark* pGraphic = qobject_cast<nmObjRegionMark*>(sender());
if (!pGraphic) return;
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getComW();
attr.setValue(comW);
pData->setComW(attr);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
void nmPlotGraphicBinder::onGraphicRegionMarkNetToGrossChanged(double netToGross)
{
nmObjRegionMark* pGraphic = qobject_cast<nmObjRegionMark*>(sender());
if (!pGraphic) return;
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getNetToGross();
attr.setValue(netToGross);
pData->setNetToGross(attr);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
void nmPlotGraphicBinder::onGraphicRegionMarkVisibleChanged(bool bVisible)
{
nmObjRegionMark* pGraphic = qobject_cast<nmObjRegionMark*>(sender());
if (!pGraphic) return;
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
pData->setPlotVisible(bVisible);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 建立信号连接
void nmPlotGraphicBinder::_connectRegionMark(nmObjRegionMark* pGraphic, nmDataRegionMark* pData)
{
if (!pGraphic || !pData) return;
m_mapRegionMarkData[pGraphic] = pData;
pGraphic->setGraphicBinder(this);
if (m_setBoundRegionMarkGraphics.contains(pGraphic)) {
return;
}
connect(pGraphic, SIGNAL(sigResevoirTypeChanged(int)),
this, SLOT(onGraphicRegionMarkReservoirTypeChanged(int)));
connect(pGraphic, SIGNAL(sigComKrChanged(double)),
this, SLOT(onGraphicRegionMarkComKrChanged(double)));
connect(pGraphic, SIGNAL(sigComWChanged(double)),
this, SLOT(onGraphicRegionMarkComWChanged(double)));
connect(pGraphic, SIGNAL(sigNetToGrossChanged(double)),
this, SLOT(onGraphicRegionMarkNetToGrossChanged(double)));
connect(pGraphic, SIGNAL(sigRegionMarkVisibleChanged(bool)),
this, SLOT(onGraphicRegionMarkVisibleChanged(bool)));
m_setBoundRegionMarkGraphics.insert(pGraphic);
}
// 断开信号连接
void nmPlotGraphicBinder::_disconnectRegionMark(nmObjRegionMark* pGraphic)
{
if (!pGraphic) return;
if (!m_setBoundRegionMarkGraphics.contains(pGraphic)) {
return;
}
disconnect(pGraphic, SIGNAL(sigResevoirTypeChanged(int)),
this, SLOT(onGraphicRegionMarkReservoirTypeChanged(int)));
disconnect(pGraphic, SIGNAL(sigComKrChanged(double)),
this, SLOT(onGraphicRegionMarkComKrChanged(double)));
disconnect(pGraphic, SIGNAL(sigComWChanged(double)),
this, SLOT(onGraphicRegionMarkComWChanged(double)));
disconnect(pGraphic, SIGNAL(sigNetToGrossChanged(double)),
this, SLOT(onGraphicRegionMarkNetToGrossChanged(double)));
disconnect(pGraphic, SIGNAL(sigRegionMarkVisibleChanged(bool)),
this, SLOT(onGraphicRegionMarkVisibleChanged(bool)));
m_setBoundRegionMarkGraphics.remove(pGraphic);
}
// 从数据对象读取值,写入图元本地副本(加载时用)
void nmPlotGraphicBinder::_pushRegionMarkDataToGraphic(nmObjRegionMark* pGraphic, nmDataRegionMark* pData)
{
pGraphic->blockSignals(true);
// 储层类型:字符串 → int
if (pData->getReservoirType().getValue() == "Homogeneous") {
pGraphic->setResevoirType(0);
} else {
pGraphic->setResevoirType(1);
}
pGraphic->setComKr(pData->getComKr().getValue().toDouble());
pGraphic->setComW(pData->getComW().getValue().toDouble());
pGraphic->setNetToGross(pData->getNetToGross().getValue().toDouble());
// 位置
QVector<QPointF> pts;
pts << pData->getPtPos();
pGraphic->setAllValues(pts);
pGraphic->blockSignals(false);
}