增加断层,裂缝等图元的参数显示

feature/nm-para-property-20260615
lvjunjie 1 month ago
parent 45400e409f
commit 3a8692b0b1

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!--****************************************************************-->
<!-- 本文档的目的是建立WTAI数值解(NM)模块的参数定义 -->
<!-- 仅包含PEBI求解器所需的储层和井参数 -->
<!-- 仅包含PEBI求解器所需的储层、井和几何对象参数 -->
<!-- Date: 20260615 -->
<!--****************************************************************-->
<!--
参数范围PEBI求解器所需的储层参数和井参数
参数范围PEBI求解器所需的储层、井和几何对象参数
对应 HX_NWTM_MODEL_INPUT 结构体字段
通过 _paraHelper->loadParaDefines() 加载sKey 标识为 s_Nm_Serie
-->
@ -39,4 +39,47 @@
<ParaItem Name="W_Dfc" Alias="裂缝导流能力" Unit="md.m" Default="1000" Max="1e+30" Min="0" Digit="6" Desc="fracture conductivity" />
</ParaGroup>
<ParaGroup Name="" Alias="独立裂缝参数">
<ParaItem Name="F_X0" Alias="起点X0" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fracture start X coordinate" />
<ParaItem Name="F_Y0" Alias="起点Y0" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fracture start Y coordinate" />
<ParaItem Name="F_X1" Alias="终点X1" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fracture end X coordinate" />
<ParaItem Name="F_Y1" Alias="终点Y1" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fracture end Y coordinate" />
<ParaItem Name="F_FC" Alias="导流能力" Unit="md.m" Default="1" Max="1e+30" Min="0" Digit="6" Desc="fracture conductivity" />
</ParaGroup>
<ParaGroup Name="" Alias="断层参数">
<ParaItem Name="FT_X0" Alias="起点X0" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fault start X coordinate" />
<ParaItem Name="FT_Y0" Alias="起点Y0" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fault start Y coordinate" />
<ParaItem Name="FT_X1" Alias="终点X1" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fault end X coordinate" />
<ParaItem Name="FT_Y1" Alias="终点Y1" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fault end Y coordinate" />
</ParaGroup>
<ParaGroup Name="" Alias="矩形边界参数">
<ParaItem Name="BR_XMin" Alias="左边界X" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="rectangle boundary minimum X" />
<ParaItem Name="BR_YMin" Alias="下边界Y" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="rectangle boundary minimum Y" />
<ParaItem Name="BR_XMax" Alias="右边界X" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="rectangle boundary maximum X" />
<ParaItem Name="BR_YMax" Alias="上边界Y" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="rectangle boundary maximum Y" />
</ParaGroup>
<ParaGroup Name="" Alias="圆形边界参数">
<ParaItem Name="BC_CenterX" Alias="圆心X" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="circle boundary center X" />
<ParaItem Name="BC_CenterY" Alias="圆心Y" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="circle boundary center Y" />
<ParaItem Name="BC_Radius" Alias="半径" Unit="m" Default="1" Max="10000" Min="1e-05" Digit="6" Desc="circle boundary radius" />
</ParaGroup>
<ParaGroup Name="" Alias="多边形边界点参数">
<ParaItem Name="BP_X" Alias="X坐标" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="polygon boundary vertex X" />
<ParaItem Name="BP_Y" Alias="Y坐标" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="polygon boundary vertex Y" />
</ParaGroup>
<ParaGroup Name="" Alias="区域参数">
<ParaItem Name="R_Leakage" Alias="泄露系数" Unit="" Default="1" Max="1e+30" Min="0" Digit="6" Desc="region leakage coefficient" />
</ParaGroup>
<ParaGroup Name="" Alias="标记区域参数">
<ParaItem Name="RM_ComW" Alias="储能比" Unit="" Default="1" Max="1" Min="0" Digit="6" Desc="storage ratio" />
<ParaItem Name="RM_ComKr" Alias="流度比" Unit="" Default="1" Max="1000" Min="0.001" Digit="6" Desc="mobility ratio" />
<ParaItem Name="RM_NetToGross" Alias="净毛比" Unit="" Default="1" Max="1" Min="0" Digit="6" Desc="net-to-gross" />
</ParaGroup>
</Root>

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<!--****************************************************************-->
<!-- This file defines parameters for the WTAI Numerical (NM) -->
<!-- module. Only parameters required by the PEBI solver are -->
<!-- included. -->
<!-- module. Only reservoir, well, and geometry parameters -->
<!-- required by the PEBI solver are included. -->
<!-- Date: 20260615 -->
<!--****************************************************************-->
<!--
Parameter scope: reservoir and well parameters required by the PEBI solver
Parameter scope: reservoir, well, and geometry parameters required by the PEBI solver
Corresponds to HX_NWTM_MODEL_INPUT struct fields
Loaded via _paraHelper->loadParaDefines(), sKey = s_Nm_Serie
-->
@ -40,4 +40,47 @@
<ParaItem Name="W_Dfc" Alias="Fracture Conductivity" Unit="md.m" Default="1000" Max="1e+30" Min="0" Digit="6" Desc="fracture conductivity" />
</ParaGroup>
<ParaGroup Name="" Alias="Independent Fracture Parameters">
<ParaItem Name="F_X0" Alias="Start X0" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fracture start X coordinate" />
<ParaItem Name="F_Y0" Alias="Start Y0" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fracture start Y coordinate" />
<ParaItem Name="F_X1" Alias="End X1" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fracture end X coordinate" />
<ParaItem Name="F_Y1" Alias="End Y1" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fracture end Y coordinate" />
<ParaItem Name="F_FC" Alias="Fracture Conductivity" Unit="md.m" Default="1" Max="1e+30" Min="0" Digit="6" Desc="fracture conductivity" />
</ParaGroup>
<ParaGroup Name="" Alias="Fault Parameters">
<ParaItem Name="FT_X0" Alias="Start X0" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fault start X coordinate" />
<ParaItem Name="FT_Y0" Alias="Start Y0" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fault start Y coordinate" />
<ParaItem Name="FT_X1" Alias="End X1" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fault end X coordinate" />
<ParaItem Name="FT_Y1" Alias="End Y1" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="fault end Y coordinate" />
</ParaGroup>
<ParaGroup Name="" Alias="Rectangle Boundary Parameters">
<ParaItem Name="BR_XMin" Alias="Left Boundary X" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="rectangle boundary minimum X" />
<ParaItem Name="BR_YMin" Alias="Bottom Boundary Y" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="rectangle boundary minimum Y" />
<ParaItem Name="BR_XMax" Alias="Right Boundary X" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="rectangle boundary maximum X" />
<ParaItem Name="BR_YMax" Alias="Top Boundary Y" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="rectangle boundary maximum Y" />
</ParaGroup>
<ParaGroup Name="" Alias="Circle Boundary Parameters">
<ParaItem Name="BC_CenterX" Alias="Center X" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="circle boundary center X" />
<ParaItem Name="BC_CenterY" Alias="Center Y" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="circle boundary center Y" />
<ParaItem Name="BC_Radius" Alias="Radius" Unit="m" Default="1" Max="10000" Min="1e-05" Digit="6" Desc="circle boundary radius" />
</ParaGroup>
<ParaGroup Name="" Alias="Polygon Boundary Vertex Parameters">
<ParaItem Name="BP_X" Alias="X Coordinate" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="polygon boundary vertex X" />
<ParaItem Name="BP_Y" Alias="Y Coordinate" Unit="m" Default="0" Max="10000" Min="-10000" Digit="6" Desc="polygon boundary vertex Y" />
</ParaGroup>
<ParaGroup Name="" Alias="Region Parameters">
<ParaItem Name="R_Leakage" Alias="Leakage Coefficient" Unit="" Default="1" Max="1e+30" Min="0" Digit="6" Desc="region leakage coefficient" />
</ParaGroup>
<ParaGroup Name="" Alias="Region Mark Parameters">
<ParaItem Name="RM_ComW" Alias="Storage Ratio" Unit="" Default="1" Max="1" Min="0" Digit="6" Desc="storage ratio" />
<ParaItem Name="RM_ComKr" Alias="Mobility Ratio" Unit="" Default="1" Max="1000" Min="0.001" Digit="6" Desc="mobility ratio" />
<ParaItem Name="RM_NetToGross" Alias="Net-to-Gross" Unit="" Default="1" Max="1" Min="0" Digit="6" Desc="net-to-gross" />
</ParaGroup>
</Root>

@ -1,4 +1,4 @@
#ifndef NMDATAANALYZEMANAGER_H
#ifndef NMDATAANALYZEMANAGER_H
#define NMDATAANALYZEMANAGER_H
#include <QObject>
@ -353,6 +353,10 @@ class NM_DATA_EXPORT nmDataAnalyzeManager : public ZxDataObjectBin
// 获取当前查看井
nmDataWellBase* getCurWellData();
void notifyDataChanged();
/// @brief 对象新增或删除后刷新参数面板,并通知网格更新
void notifyGeometryListChanged();
/// @brief 仅刷新参数面板中的对象名称,避免改名触发网格重建
void notifyParameterObjectNameChanged();
/**
* @brief
@ -551,6 +555,8 @@ class NM_DATA_EXPORT nmDataAnalyzeManager : public ZxDataObjectBin
/// @note wellCode + "_W_XX" 作为注册名,使双向绑定链路适用于井参数
/// @note 增量同步:自动清理已删除井的注册,注册新增井的参数
void syncWellAttrs();
/// @brief 按“对象编码 + XML 参数名”注册几何对象参数
void syncGeometryAttrs();
signals:
void dataChanged();
@ -558,6 +564,8 @@ class NM_DATA_EXPORT nmDataAnalyzeManager : public ZxDataObjectBin
void sigWellAdded(QString wellCode, QString wellName, QStringList baseParas);
/// @brief 井删除信号removeWell 发出)
void sigWellRemoved(QString wellCode, QString wellName);
/// @brief 参数面板中的对象列表或对象名称发生变化
void sigGeometryListChanged();
private:
// 存储井的数据

@ -41,10 +41,35 @@ public:
QVector<QPointF> getFaultPoints() const;
void setFaultPoints(const QVector<QPointF>& vecPts);
nmDataAttribute& getStartX();
nmDataAttribute& getStartY();
nmDataAttribute& getEndX();
nmDataAttribute& getEndY();
bool getPlotVisible() const;
void setPlotVisible(const bool newState);
// 批量赋值后手动通知关联视图刷新。
void notifyDataChanged();
signals:
// 参数面板修改数据后,通知 Binder 刷新图元和左侧属性面板。
void sigFaultDataChanged();
private slots:
void onEndPointAttributeChanged();
private:
void connectAttributeSignals();
void syncEndPointAttributes();
// m_vecPts 首尾点的面板绑定属性,不单独参与序列化。
nmDataAttribute m_startX;
nmDataAttribute m_startY;
nmDataAttribute m_endX;
nmDataAttribute m_endY;
// 防止“点集 -> 属性 -> 点集”递归同步。
bool m_bSyncingEndPoints;
QString m_sFaultName; // 断层名称
QVector<QPointF> m_vecPts; // 断层位置信息
nmDataAttribute m_faultFlowModel; // 断层流动模型

@ -32,6 +32,11 @@ public:
QVector<QPointF> getFracturePoints() const;
void setFracturePoints(const QVector<QPointF>& vecPts);
nmDataAttribute& getStartX();
nmDataAttribute& getStartY();
nmDataAttribute& getEndX();
nmDataAttribute& getEndY();
// Getter and Setter for m_fractureFlowModel
nmDataAttribute& getFractureFlowModel();
void setFractureFlowModel(const nmDataAttribute& fractureFlowModel);
@ -49,8 +54,28 @@ public:
bool getPlotVisible() const;
void setPlotVisible(const bool newState);
// 批量赋值后手动通知关联视图刷新。
void notifyDataChanged();
signals:
// 参数面板修改数据后,通知 Binder 刷新图元和左侧属性面板。
void sigFractureDataChanged();
private slots:
void onEndPointAttributeChanged();
private:
void connectAttributeSignals();
void syncEndPointAttributes();
// m_vecPts 首尾点的面板绑定属性,不单独参与序列化。
nmDataAttribute m_startX;
nmDataAttribute m_startY;
nmDataAttribute m_endX;
nmDataAttribute m_endY;
// 防止“点集 -> 属性 -> 点集”递归同步。
bool m_bSyncingEndPoints;
QString m_sFractureName; // 裂缝名称
QVector<QPointF> m_vecPts; // 裂缝位置信息
nmDataAttribute m_fractureFlowModel; // 裂缝流动类型

@ -6,6 +6,7 @@
#include <QColor>
#include "nmDefines.h"
#include "nmDataAttribute.h"
#include "nmDataBase.h"
@ -29,6 +30,18 @@ class NM_DATA_EXPORT nmDataOutline : public nmDataBase {
QVector<QPointF> getOutlinePoints();
void setOutlinePoints(const QVector<QPointF>& vecPts);
int getOutlinePointCount() const;
nmDataAttribute* getPointXAttribute(int nIndex) const;
nmDataAttribute* getPointYAttribute(int nIndex) const;
nmDataAttribute& getLeftAttribute();
nmDataAttribute& getRightAttribute();
nmDataAttribute& getTopAttribute();
nmDataAttribute& getBottomAttribute();
nmDataAttribute& getCenterXAttribute();
nmDataAttribute& getCenterYAttribute();
nmDataAttribute& getRadiusAttribute();
QVector<int> getFlowTypeList() const;
void setFlowTypeList(const QVector<int>& vecFlowTypeList);
@ -56,7 +69,36 @@ class NM_DATA_EXPORT nmDataOutline : public nmDataBase {
bool hasVisualProps() const;
void setVisualPropsValid(bool bValid);
signals:
// 参数面板修改数据后,通知 Binder 刷新图元。
void sigOutlineDataChanged();
private slots:
void onGeometryAttributeChanged();
private:
void initGeometryAttributes();
void clearPointAttributes();
void syncGeometryAttributes();
void syncPointAttributes();
void syncRectAttributes();
void syncRoundAttributes();
void updateRectPointsFromAttributes();
void updateRoundPointsFromAttributes();
// m_vecPts 及固定几何量的面板绑定属性,不单独参与序列化。
QVector<nmDataAttribute*> m_vPointXAttributes;
QVector<nmDataAttribute*> m_vPointYAttributes;
nmDataAttribute m_left;
nmDataAttribute m_right;
nmDataAttribute m_top;
nmDataAttribute m_bottom;
nmDataAttribute m_centerX;
nmDataAttribute m_centerY;
nmDataAttribute m_radius;
// 防止“点集 -> 属性 -> 点集”递归同步。
bool m_bSyncingGeometryAttributes;
QString m_sName;// 边界名称
QVector<QPointF> m_vecPts; // 边界点的数据;
QVector<int> m_vFlowTypeList; //边界压力类型

@ -51,8 +51,16 @@ public:
void setPenWidth(double dWidth);
QColor getBackgrdColor() const;
void setBackgrdColor(const QColor& clr);
// 批量赋值后手动通知关联视图刷新。
void notifyDataChanged();
signals:
// 参数面板修改数据后,通知 Binder 刷新图元和左侧属性面板。
void sigRegionDataChanged();
private:
void connectAttributeSignals();
QString m_sRegionName; // 复合区名称
QVector<QPointF> m_vecPts; // 复合区位置信息
nmDataAttribute m_regionFlowModel; // 复合区流动类型

@ -49,8 +49,16 @@ public:
bool getPlotVisible() const;
void setPlotVisible(const bool newState);
// 批量赋值后手动通知关联视图刷新。
void notifyDataChanged();
signals:
// 参数面板修改数据后,通知 Binder 刷新图元和左侧属性面板。
void sigRegionMarkDataChanged();
private:
void connectAttributeSignals();
QString m_sRegionMarkName;
bool m_bSelectRegion;
QPointF m_ptPos; // 当前区域标记所在的位置

@ -56,6 +56,8 @@ public:
// 调用:用户画完裂缝后
void createCrackForGraphic(nmObjLineCrack* pGraphic);
// DFN 批量生成时传 false不将裂缝加入独立裂缝参数面板。
void createCrackForGraphic(nmObjLineCrack* pGraphic, bool bNotifyGeometryList);
// 调用:从文件加载,绑定已有裂缝数据到已有图元
void bindCrackToGraphic(nmObjLineCrack* pGraphic, nmDataFracture* pData);
@ -209,6 +211,7 @@ private slots:
void onGraphicLeakageChanged(double leakage);
void onGraphicPointsChanged();
void onGraphicVisibleChanged(bool bVisible);
void onFaultDataChanged();
// 裂缝图元信号 → 数据同步
void onGraphicCrackFlowModelChanged(int model);
@ -216,11 +219,13 @@ private slots:
void onGraphicCrackDwChanged(double dw);
void onGraphicCrackPointsChanged();
void onGraphicCrackVisibleChanged(bool bVisible);
void onFractureDataChanged();
// 边界图元信号 → 数据同步
void onGraphicOutlinePointsChanged();
void onGraphicOutlineFlowTypeChanged();
void onGraphicOutlineVisibleChanged(bool bVisible);
void onOutlineDataChanged();
// 区域标记图元信号 → 数据同步
void onGraphicRegionMarkReservoirTypeChanged(int type);
@ -228,11 +233,13 @@ private slots:
void onGraphicRegionMarkComWChanged(double comW);
void onGraphicRegionMarkNetToGrossChanged(double netToGross);
void onGraphicRegionMarkVisibleChanged(bool bVisible);
void onRegionMarkDataChanged();
// 复合区图元信号 → 数据同步
void onGraphicRegionFlowModelChanged(int model);
void onGraphicRegionLeakageChanged(double leakage);
void onGraphicRegionVisibleChanged(bool bVisible);
void onRegionDataChanged();
// 井图元信号 → 数据同步
void onGraphicWellVisibleChanged(bool bVisible);
@ -249,10 +256,10 @@ private:
// 图元 ←→ 数据 双向信号连接(图元 emit → Binder slot → 数据 setter
void _connectFault(nmObjLineFault* pGraphic, nmDataFault* pData);
// 断开指定图元与本 Binder 的四条信号连接
// 断开指定图元与本 Binder 的信号连接
void _disconnectFault(nmObjLineFault* pGraphic);
// 从数据对象读取值,写入图元本地副本(加载时用)
// 从数据对象读取值,写入图元本地副本(加载及参数变更时用)
void _pushFaultDataToGraphic(nmObjLineFault* pGraphic, nmDataFault* pData);
// 裂缝图元 → 数据 的映射表
@ -264,10 +271,10 @@ private:
// 裂缝图元 ←→ 数据 双向信号连接
void _connectCrack(nmObjLineCrack* pGraphic, nmDataFracture* pData);
// 断开指定裂缝图元与本 Binder 的五条信号连接
// 断开指定裂缝图元与本 Binder 的信号连接
void _disconnectCrack(nmObjLineCrack* pGraphic);
// 从裂缝数据对象读取值,写入图元本地副本(加载时用)
// 从裂缝数据对象读取值,写入图元本地副本(加载及参数变更时用)
void _pushCrackDataToGraphic(nmObjLineCrack* pGraphic, nmDataFracture* pData);
// 边界图元 → 数据 的映射表(三种边界类型共用)
@ -276,13 +283,13 @@ private:
// 已建立信号连接的边界图元集合
QSet<nmObjBase*> m_setBoundOutlineGraphics;
// 边界图元 ←→ 数据 信号连接(三条信号)
// 边界图元 ←→ 数据 信号连接
void _connectOutline(nmObjBase* pGraphic, nmDataOutline* pData);
// 断开指定边界图元与本 Binder 的信号连接
void _disconnectOutline(nmObjBase* pGraphic);
// 从边界数据对象读取值,写入图元本地副本(加载时用)
// 从边界数据对象读取值,写入图元本地副本(加载及参数变更时用)
void _pushOutlineDataToGraphic(nmObjBase* pGraphic, nmDataOutline* pData);
// 测量线图元 → 数据 的映射表
@ -302,7 +309,7 @@ private:
// 断开指定区域标记图元与本 Binder 的信号连接
void _disconnectRegionMark(nmObjRegionMark* pGraphic);
// 从区域标记数据对象读取值,写入图元本地副本(加载时用)
// 从区域标记数据对象读取值,写入图元本地副本(加载及参数变更时用)
void _pushRegionMarkDataToGraphic(nmObjRegionMark* pGraphic, nmDataRegionMark* pData);
// ==================== 复合区图元 ====================
@ -319,7 +326,7 @@ private:
// 断开指定复合区图元与本 Binder 的信号连接
void _disconnectRegion(nmObjRegion* pGraphic);
// 从复合区数据对象读取值,写入图元本地副本(加载时用)
// 从复合区数据对象读取值,写入图元本地副本(加载及参数变更时用)
void _pushRegionDataToGraphic(nmObjRegion* pGraphic, nmDataRegion* pData);
// ==================== 井图元 ====================

@ -1,4 +1,4 @@
#pragma once
#pragma once
#include "iDlgBase.h"
#include "nmSubWxs_global.h"
@ -28,13 +28,13 @@ public:
/// @note 参数列表必须是在系统中配置的参数listParas已经包括了显示顺序
/// 但对于层级,由系统配置来决定
virtual void refreshUIs(QStringList& listParas, bool bReserveOlds = true,
QMap<QString, QString> mapWellNames = QMap<QString, QString>());
QMap<QString, QString> mapObjectNames = QMap<QString, QString>());
/// @brief 从数据管理器重建完整参数面板
/// @note XML 中井参数只定义一份,运行时按 wellCode 创建多个对象分组。
/// @note XML 中参数只定义一份,运行时沿用多井机制按对象编码创建分组。
void rebuildAllParas();
/// @brief 设置数据管理器引用(用于面板重建时获取井列表)
/// @brief 设置数据管理器引用(用于面板重建时获取井和几何对象列表)
void setDataManager(nmDataAnalyzeManager* mgr) { m_pDataManager = mgr; }
// 允许备份/恢复原有的参数内容
@ -75,6 +75,8 @@ public slots:
void slotWellAdded(QString wellCode, QString wellName, QStringList paras);
/// @brief 井删除时按当前井列表刷新面板
void slotWellRemoved(QString wellCode, QString wellName);
/// @brief 几何对象新增、删除或改名后重建参数面板
void slotGeometryListChanged();
protected:
@ -92,7 +94,7 @@ protected:
// Help
QTextEdit* m_pHelpBox;
// 数据管理器引用(用于全量重建面板时获取井列表)
// 数据管理器引用(用于全量重建面板时获取井和几何对象列表)
nmDataAnalyzeManager* m_pDataManager;
signals:

@ -1,4 +1,4 @@
#include "nmDataAnalyzeManager.h"
#include "nmDataAnalyzeManager.h"
#include "nmAttrRegistry.h"
@ -130,6 +130,68 @@ static bool isWellParaAttrName(const QString& name)
return false;
}
// 参数名必须与 XML 定义和参数面板拼接的基础编号完全一致。
struct GeometryParaDesc {
const char* sName;
nmDataAttribute* (*getFractureAttr)(nmDataFracture&);
nmDataAttribute* (*getFaultAttr)(nmDataFault&);
nmDataAttribute* (*getRegionAttr)(nmDataRegion&);
nmDataAttribute* (*getRegionMarkAttr)(nmDataRegionMark&);
};
static nmDataAttribute* getFractureStartX(nmDataFracture& data) { return &data.getStartX(); }
static nmDataAttribute* getFractureStartY(nmDataFracture& data) { return &data.getStartY(); }
static nmDataAttribute* getFractureEndX(nmDataFracture& data) { return &data.getEndX(); }
static nmDataAttribute* getFractureEndY(nmDataFracture& data) { return &data.getEndY(); }
static nmDataAttribute* getFractureFc(nmDataFracture& data) { return &data.getFractureDfc(); }
static nmDataAttribute* getFaultStartX(nmDataFault& data) { return &data.getStartX(); }
static nmDataAttribute* getFaultStartY(nmDataFault& data) { return &data.getStartY(); }
static nmDataAttribute* getFaultEndX(nmDataFault& data) { return &data.getEndX(); }
static nmDataAttribute* getFaultEndY(nmDataFault& data) { return &data.getEndY(); }
static nmDataAttribute* getRegionLeakage(nmDataRegion& data) { return &data.getRegionLeakage(); }
static nmDataAttribute* getRegionMarkComW(nmDataRegionMark& data) { return &data.getComW(); }
static nmDataAttribute* getRegionMarkComKr(nmDataRegionMark& data) { return &data.getComKr(); }
static nmDataAttribute* getRegionMarkNetToGross(nmDataRegionMark& data) { return &data.getNetToGross(); }
static const GeometryParaDesc GEOMETRY_PARA_DESCS[] = {
{"F_X0", &getFractureStartX, NULL, NULL, NULL},
{"F_Y0", &getFractureStartY, NULL, NULL, NULL},
{"F_X1", &getFractureEndX, NULL, NULL, NULL},
{"F_Y1", &getFractureEndY, NULL, NULL, NULL},
{"F_FC", &getFractureFc, NULL, NULL, NULL},
{"FT_X0", NULL, &getFaultStartX, NULL, NULL},
{"FT_Y0", NULL, &getFaultStartY, NULL, NULL},
{"FT_X1", NULL, &getFaultEndX, NULL, NULL},
{"FT_Y1", NULL, &getFaultEndY, NULL, NULL},
{"R_Leakage", NULL, NULL, &getRegionLeakage, NULL},
{"RM_ComW", NULL, NULL, NULL, &getRegionMarkComW},
{"RM_ComKr", NULL, NULL, NULL, &getRegionMarkComKr},
{"RM_NetToGross", NULL, NULL, NULL, &getRegionMarkNetToGross},
};
static const int GEOMETRY_PARA_DESC_COUNT = sizeof(GEOMETRY_PARA_DESCS) / sizeof(GEOMETRY_PARA_DESCS[0]);
static const char* OUTLINE_PARA_NAMES[] = {
"BR_XMin", "BR_YMin", "BR_XMax", "BR_YMax",
"BC_CenterX", "BC_CenterY", "BC_Radius",
"BP_X", "BP_Y"
};
static const int OUTLINE_PARA_NAME_COUNT = sizeof(OUTLINE_PARA_NAMES) / sizeof(OUTLINE_PARA_NAMES[0]);
static bool isGeometryParaAttrName(const QString& name)
{
for (int i = 0; i < GEOMETRY_PARA_DESC_COUNT; ++i) {
if (name.endsWith(QString("_") + GEOMETRY_PARA_DESCS[i].sName)) {
return true;
}
}
for (int i = 0; i < OUTLINE_PARA_NAME_COUNT; ++i) {
if (name.endsWith(QString("_") + OUTLINE_PARA_NAMES[i])) {
return true;
}
}
return false;
}
namespace {
// 清空指定目录下的所有旧文件和子目录,但保留目录本身
bool clearDirectoryContents(const QString& dirPath)
@ -1536,6 +1598,158 @@ void nmDataAnalyzeManager::syncWellAttrs()
}
}
void nmDataAnalyzeManager::syncGeometryAttrs()
{
if (m_pAttrRegistry == NULL) return;
// 沿用井参数注册方式,以“对象编码 + XML 参数名”建立双向绑定。
QSet<QString> activeAttrNames;
int fractureIndex = 0;
foreach (nmDataFracture* pFracture, m_vFractureData)
{
// DFN 裂缝由专用功能批量管理,不作为独立裂缝显示在参数面板中。
if (pFracture == nullptr || pFracture->getFractureType().getValue().toString() == "DFN") {
continue;
}
QString code = QString("FRAC%1").arg(++fractureIndex, 4, 10, QChar('0'));
for (int i = 0; i < GEOMETRY_PARA_DESC_COUNT; ++i)
{
if (GEOMETRY_PARA_DESCS[i].getFractureAttr == NULL) continue;
nmDataAttribute* pAttr = GEOMETRY_PARA_DESCS[i].getFractureAttr(*pFracture);
if (pAttr != NULL)
{
QString name = code + "_" + GEOMETRY_PARA_DESCS[i].sName;
activeAttrNames.insert(name);
m_pAttrRegistry->regAttr(name, pAttr);
}
}
}
for (int faultIndex = 0; faultIndex < m_vFaultData.size(); ++faultIndex)
{
nmDataFault* pFault = m_vFaultData[faultIndex];
if (pFault == nullptr) continue;
QString code = QString("FAULT%1").arg(faultIndex + 1, 4, 10, QChar('0'));
for (int i = 0; i < GEOMETRY_PARA_DESC_COUNT; ++i)
{
if (GEOMETRY_PARA_DESCS[i].getFaultAttr == NULL) continue;
nmDataAttribute* pAttr = GEOMETRY_PARA_DESCS[i].getFaultAttr(*pFault);
if (pAttr != NULL)
{
QString name = code + "_" + GEOMETRY_PARA_DESCS[i].sName;
activeAttrNames.insert(name);
m_pAttrRegistry->regAttr(name, pAttr);
}
}
}
for (int regionIndex = 0; regionIndex < m_vRegionData.size(); ++regionIndex)
{
nmDataRegion* pRegion = m_vRegionData[regionIndex];
if (pRegion == nullptr) continue;
QString code = QString("REGION%1").arg(regionIndex + 1, 4, 10, QChar('0'));
for (int i = 0; i < GEOMETRY_PARA_DESC_COUNT; ++i)
{
if (GEOMETRY_PARA_DESCS[i].getRegionAttr == NULL) continue;
nmDataAttribute* pAttr = GEOMETRY_PARA_DESCS[i].getRegionAttr(*pRegion);
if (pAttr != NULL)
{
QString name = code + "_" + GEOMETRY_PARA_DESCS[i].sName;
activeAttrNames.insert(name);
m_pAttrRegistry->regAttr(name, pAttr);
}
}
}
for (int markIndex = 0; markIndex < m_vRegionMarkData.size(); ++markIndex)
{
nmDataRegionMark* pMark = m_vRegionMarkData[markIndex];
if (pMark == nullptr) continue;
QString code = QString("RMARK%1").arg(markIndex + 1, 4, 10, QChar('0'));
for (int i = 0; i < GEOMETRY_PARA_DESC_COUNT; ++i)
{
if (GEOMETRY_PARA_DESCS[i].getRegionMarkAttr == NULL) continue;
nmDataAttribute* pAttr = GEOMETRY_PARA_DESCS[i].getRegionMarkAttr(*pMark);
if (pAttr != NULL)
{
QString name = code + "_" + GEOMETRY_PARA_DESCS[i].sName;
activeAttrNames.insert(name);
m_pAttrRegistry->regAttr(name, pAttr);
}
}
}
if (m_outlineData != nullptr)
{
if (m_outlineData->getOutlineType() == NM_Rect_Outline_Type)
{
const QString code = "BOUNDARY";
const QStringList names = QStringList() << "BR_XMin" << "BR_YMin" << "BR_XMax" << "BR_YMax";
nmDataAttribute* attrs[] = {
&m_outlineData->getLeftAttribute(),
&m_outlineData->getBottomAttribute(),
&m_outlineData->getRightAttribute(),
&m_outlineData->getTopAttribute()
};
for (int i = 0; i < names.count(); ++i) {
const QString name = code + "_" + names[i];
activeAttrNames.insert(name);
m_pAttrRegistry->regAttr(name, attrs[i]);
}
}
else if (m_outlineData->getOutlineType() == NM_Round_Outline_Type)
{
const QString code = "BOUNDARY";
const QStringList names = QStringList() << "BC_CenterX" << "BC_CenterY" << "BC_Radius";
nmDataAttribute* attrs[] = {
&m_outlineData->getCenterXAttribute(),
&m_outlineData->getCenterYAttribute(),
&m_outlineData->getRadiusAttribute()
};
for (int i = 0; i < names.count(); ++i) {
const QString name = code + "_" + names[i];
activeAttrNames.insert(name);
m_pAttrRegistry->regAttr(name, attrs[i]);
}
}
else if (m_outlineData->getOutlineType() == NM_Polygon_Outline_Type)
{
// 多边形顶点数量动态变化,每个 Point 使用独立对象编码注册 X/Y。
for (int pointIndex = 0; pointIndex < m_outlineData->getOutlinePointCount(); ++pointIndex)
{
const QString code = QString("BVERT%1").arg(pointIndex + 1, 4, 10, QChar('0'));
nmDataAttribute* pX = m_outlineData->getPointXAttribute(pointIndex);
nmDataAttribute* pY = m_outlineData->getPointYAttribute(pointIndex);
if (pX != nullptr)
{
const QString name = code + "_BP_X";
activeAttrNames.insert(name);
m_pAttrRegistry->regAttr(name, pX);
}
if (pY != nullptr)
{
const QString name = code + "_BP_Y";
activeAttrNames.insert(name);
m_pAttrRegistry->regAttr(name, pY);
}
}
}
}
// 精确清理已删除对象、已删除顶点和旧边界类型留下的注册项。
foreach (const QString& name, m_pAttrRegistry->registeredNames())
{
if (isGeometryParaAttrName(name) && !activeAttrNames.contains(name))
{
m_pAttrRegistry->unregAttr(name);
}
}
}
nmDataReservoir nmDataAnalyzeManager::getReservoirDataCopy() const
{
if(m_reservoirData) {
@ -1959,6 +2173,7 @@ bool nmDataAnalyzeManager::removeRegionMarkData(nmDataRegionMark * pData)
if(m_vRegionMarkData[i] == pData) {
delete m_vRegionMarkData[i]; // 释放内存
m_vRegionMarkData.remove(i);
notifyGeometryListChanged();
return true; // 移除成功,返回 true
}
}
@ -1992,8 +2207,14 @@ void nmDataAnalyzeManager::updateRegionMarkData(const QVector<nmDataRegionMark>&
if(m_vRegionMarkData[i]) {
// 只更新内容,不改变指针
*m_vRegionMarkData[i] = newData[i]; // 调用赋值运算符
m_vRegionMarkData[i]->notifyDataChanged();
}
}
// 批量赋值不触发属性信号,完成后统一刷新参数面板。
if (m_pAttrRegistry) {
m_pAttrRegistry->refreshAll();
}
}
nmDataOutline *nmDataAnalyzeManager::createOutline()
@ -2017,6 +2238,7 @@ bool nmDataAnalyzeManager::removeOutlineData()
if(m_outlineData) {
delete m_outlineData; // 删除边界数据对象
m_outlineData = nullptr;
notifyGeometryListChanged();
return true; // 移除成功,返回 true
}
@ -2060,6 +2282,7 @@ bool nmDataAnalyzeManager::removeRegionData(nmDataRegion * pData)
if(m_vRegionData[i] == pData) {
delete m_vRegionData[i]; // 释放内存
m_vRegionData.remove(i);
notifyGeometryListChanged();
return true; // 移除成功,返回 true
}
}
@ -2093,8 +2316,14 @@ void nmDataAnalyzeManager::updateRegionData(const QVector<nmDataRegion>& newData
if(m_vRegionData[i]) {
// 只更新内容,不改变指针
*m_vRegionData[i] = newData[i]; // 调用赋值运算符
m_vRegionData[i]->notifyDataChanged();
}
}
// 批量赋值不触发属性信号,完成后统一刷新参数面板。
if (m_pAttrRegistry) {
m_pAttrRegistry->refreshAll();
}
}
nmDataFracture *nmDataAnalyzeManager::createFracture()
@ -2129,9 +2358,15 @@ bool nmDataAnalyzeManager::removeFractureData(nmDataFracture * pData)
// 遍历 m_vFractureData 数组,找到并移除对应的对象
for(int i = 0; i < m_vFractureData.size(); ++i) {
if(m_vFractureData[i] == pData) {
const bool bNotifyGeometryList =
m_vFractureData[i]->getFractureType().getValue().toString() != "DFN";
delete m_vFractureData[i]; // 释放内存
m_vFractureData.remove(i);
emit dataChanged();
if (bNotifyGeometryList) {
notifyGeometryListChanged();
} else {
notifyDataChanged();
}
return true; // 移除成功,返回 true
}
}
@ -2165,8 +2400,14 @@ void nmDataAnalyzeManager::updateFractureData(const QVector<nmDataFracture>& new
if(m_vFractureData[i]) {
// 只更新内容,不改变指针
*m_vFractureData[i] = newData[i]; // 调用赋值运算符
m_vFractureData[i]->notifyDataChanged();
}
}
// 批量赋值不触发属性信号,完成后统一刷新参数面板。
if (m_pAttrRegistry) {
m_pAttrRegistry->refreshAll();
}
}
@ -2190,7 +2431,7 @@ bool nmDataAnalyzeManager::removeFaultData(nmDataFault * pData)
if(m_vFaultData[i] == pData) {
delete m_vFaultData[i]; // 释放内存
m_vFaultData.remove(i);
emit dataChanged();
notifyGeometryListChanged();
return true; // 移除成功,返回 true
}
}
@ -2224,8 +2465,14 @@ void nmDataAnalyzeManager::updateFaultData(const QVector<nmDataFault>& newData)
if(m_vFaultData[i]) {
// 只更新内容,不改变指针
*m_vFaultData[i] = newData[i]; // 调用赋值运算符
m_vFaultData[i]->notifyDataChanged();
}
}
// 批量赋值不触发属性信号,完成后统一刷新参数面板。
if (m_pAttrRegistry) {
m_pAttrRegistry->refreshAll();
}
}
nmGuiPlot* nmDataAnalyzeManager::getPlot() const
@ -2775,6 +3022,17 @@ void nmDataAnalyzeManager::notifyDataChanged()
emit dataChanged();
}
void nmDataAnalyzeManager::notifyGeometryListChanged()
{
emit sigGeometryListChanged();
emit dataChanged();
}
void nmDataAnalyzeManager::notifyParameterObjectNameChanged()
{
emit sigGeometryListChanged();
}
void nmDataAnalyzeManager::setDisplaySettings(const QVector<DisplaySetting>& displaySettings)
{
m_vecDisplaySettings = displaySettings;

@ -1,21 +1,36 @@
#include "nmDataFault.h"
nmDataFault::nmDataFault(){
nmDataFault::nmDataFault()
: m_bSyncingEndPoints(false) {
QStringList lengthUnits;
lengthUnits << "m" << "cm" << "mm" << "in" << "0.1 in" << "ft" << "mile" << "km";
m_startX = nmDataAttribute("Fault start X", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_startY = nmDataAttribute("Fault start Y", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_endX = nmDataAttribute("Fault end X", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_endY = nmDataAttribute("Fault end Y", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_faultFlowModel = nmDataAttribute("Fault flow model", "Leaky","", UNIT_TYPE_DIMENSIONLESS, QStringList() << "Leaky" << "Composite limit", QStringList());
m_faultLeakage = nmDataAttribute("Fault leakage", 1.0,"",UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
// 图元可见性默认为true
m_bPlotVisible = true;
this->connectAttributeSignals();
}
nmDataFault::nmDataFault(const nmDataFault& other){
nmDataFault::nmDataFault(const nmDataFault& other)
: m_bSyncingEndPoints(false) {
*this = other;
this->connectAttributeSignals();
}
nmDataFault& nmDataFault::operator=(const nmDataFault& other) {
if (this != &other) {
m_sFaultName = other.m_sFaultName;
m_vecPts = other.m_vecPts;
m_startX = other.m_startX;
m_startY = other.m_startY;
m_endX = other.m_endX;
m_endY = other.m_endY;
m_faultFlowModel = other.m_faultFlowModel;
m_faultLeakage = other.m_faultLeakage;
@ -94,6 +109,8 @@ void nmDataFault::FromJsonValue(const rapidjson::Value& jsonValue)
if (jsonValue.HasMember("PlotVisible") && jsonValue["PlotVisible"].IsBool()) {
m_bPlotVisible = jsonValue["PlotVisible"].GetBool();
}
syncEndPointAttributes();
}
/// Getter and Setter for m_faultName
@ -116,6 +133,27 @@ QVector<QPointF> nmDataFault::getFaultPoints() const
void nmDataFault::setFaultPoints(const QVector<QPointF>& vecPts)
{
m_vecPts = vecPts;
syncEndPointAttributes();
}
nmDataAttribute& nmDataFault::getStartX()
{
return m_startX;
}
nmDataAttribute& nmDataFault::getStartY()
{
return m_startY;
}
nmDataAttribute& nmDataFault::getEndX()
{
return m_endX;
}
nmDataAttribute& nmDataFault::getEndY()
{
return m_endY;
}
// Getter and Setter for m_faultFlowModel
@ -145,5 +183,55 @@ bool nmDataFault::getPlotVisible() const{
}
void nmDataFault::setPlotVisible(const bool newState) {
m_bPlotVisible = newState;
m_bPlotVisible = newState;
}
// 批量赋值不会触发属性信号,通过对象级信号统一刷新关联视图。
void nmDataFault::notifyDataChanged()
{
emit sigFaultDataChanged();
}
// 端点属性负责坐标回写,其余属性直接转发为断层数据变化信号。
void nmDataFault::connectAttributeSignals()
{
connect(&m_startX, SIGNAL(sigValueChanged()), this, SLOT(onEndPointAttributeChanged()), Qt::UniqueConnection);
connect(&m_startY, SIGNAL(sigValueChanged()), this, SLOT(onEndPointAttributeChanged()), Qt::UniqueConnection);
connect(&m_endX, SIGNAL(sigValueChanged()), this, SLOT(onEndPointAttributeChanged()), Qt::UniqueConnection);
connect(&m_endY, SIGNAL(sigValueChanged()), this, SLOT(onEndPointAttributeChanged()), Qt::UniqueConnection);
connect(&m_faultFlowModel, SIGNAL(sigValueChanged()), this, SIGNAL(sigFaultDataChanged()), Qt::UniqueConnection);
connect(&m_faultLeakage, SIGNAL(sigValueChanged()), this, SIGNAL(sigFaultDataChanged()), Qt::UniqueConnection);
}
// 图元或文件数据变化后,将点集首尾坐标同步到面板绑定属性。
void nmDataFault::syncEndPointAttributes()
{
if (m_vecPts.size() < 2) {
return;
}
m_bSyncingEndPoints = true;
const QPointF& start = m_vecPts.first();
const QPointF& end = m_vecPts.last();
if (m_startX.getValue().toDouble() != start.x()) m_startX.setValue(start.x());
if (m_startY.getValue().toDouble() != start.y()) m_startY.setValue(start.y());
if (m_endX.getValue().toDouble() != end.x()) m_endX.setValue(end.x());
if (m_endY.getValue().toDouble() != end.y()) m_endY.setValue(end.y());
m_bSyncingEndPoints = false;
}
// 参数面板修改端点坐标后,回写真实点集并通知 Binder 更新图元。
void nmDataFault::onEndPointAttributeChanged()
{
if (m_bSyncingEndPoints || m_vecPts.size() < 2) {
return;
}
m_vecPts.first().setX(m_startX.getValue().toDouble());
m_vecPts.first().setY(m_startY.getValue().toDouble());
m_vecPts.last().setX(m_endX.getValue().toDouble());
m_vecPts.last().setY(m_endY.getValue().toDouble());
emit sigFaultDataChanged();
}

@ -8,7 +8,14 @@
#include <QVariantMap> // 确保 QVariantMap 被包含
#include <QVariantList> // 确保 QVariantList 被包含
nmDataFracture::nmDataFracture() {
nmDataFracture::nmDataFracture()
: m_bSyncingEndPoints(false) {
QStringList lengthUnits;
lengthUnits << "m" << "cm" << "mm" << "in" << "0.1 in" << "ft" << "mile" << "km";
m_startX = nmDataAttribute("Fracture start X", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_startY = nmDataAttribute("Fracture start Y", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_endX = nmDataAttribute("Fracture end X", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_endY = nmDataAttribute("Fracture end Y", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_fractureFlowModel = nmDataAttribute("Fracture flow model", "Finite Conductivity","",UNIT_TYPE_DIMENSIONLESS, QStringList() << "Infinite Conductivity" << "Finite Conductivity", QStringList());
m_fractureDfc = nmDataAttribute("Fracture dFc", 1, "md.m", UNIT_TYPE_CONDUCTIVITY, QStringList(), QStringList() << "md.ft" << "md.m" << "m^3");
m_fractureDw = nmDataAttribute("Fracture dW", 1, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
@ -17,16 +24,24 @@ nmDataFracture::nmDataFracture() {
// 图元可见性默认为true
m_bPlotVisible = true;
this->connectAttributeSignals();
}
nmDataFracture::nmDataFracture(const nmDataFracture& other) {
nmDataFracture::nmDataFracture(const nmDataFracture& other)
: m_bSyncingEndPoints(false) {
*this = other;
this->connectAttributeSignals();
}
nmDataFracture& nmDataFracture::operator=(const nmDataFracture& other) {
if (this != &other) {
m_sFractureName = other.m_sFractureName;
m_vecPts = other.m_vecPts;
m_startX = other.m_startX;
m_startY = other.m_startY;
m_endX = other.m_endX;
m_endY = other.m_endY;
m_fractureFlowModel = other.m_fractureFlowModel;
m_fractureDfc = other.m_fractureDfc;
m_fractureDw = other.m_fractureDw;
@ -116,6 +131,8 @@ void nmDataFracture::FromJsonValue(const rapidjson::Value& jsonValue)
if (jsonValue.HasMember("PlotVisible") && jsonValue["PlotVisible"].IsBool()) {
m_bPlotVisible = jsonValue["PlotVisible"].GetBool(); // 使用m_bPlotVisible
}
syncEndPointAttributes();
}
// Getter and Setter for m_sFractureName
@ -138,6 +155,27 @@ QVector<QPointF> nmDataFracture::getFracturePoints() const
void nmDataFracture::setFracturePoints(const QVector<QPointF>& vecPts)
{
m_vecPts = vecPts;
syncEndPointAttributes();
}
nmDataAttribute& nmDataFracture::getStartX()
{
return m_startX;
}
nmDataAttribute& nmDataFracture::getStartY()
{
return m_startY;
}
nmDataAttribute& nmDataFracture::getEndX()
{
return m_endX;
}
nmDataAttribute& nmDataFracture::getEndY()
{
return m_endY;
}
// Getter and Setter for m_fractureFlowModel
@ -191,3 +229,54 @@ void nmDataFracture::setPlotVisible(const bool newState) {
m_bPlotVisible = newState;
}
// 批量赋值不会触发属性信号,通过对象级信号统一刷新关联视图。
void nmDataFracture::notifyDataChanged()
{
emit sigFractureDataChanged();
}
// 端点属性负责坐标回写,其余属性直接转发为裂缝数据变化信号。
void nmDataFracture::connectAttributeSignals()
{
connect(&m_startX, SIGNAL(sigValueChanged()), this, SLOT(onEndPointAttributeChanged()), Qt::UniqueConnection);
connect(&m_startY, SIGNAL(sigValueChanged()), this, SLOT(onEndPointAttributeChanged()), Qt::UniqueConnection);
connect(&m_endX, SIGNAL(sigValueChanged()), this, SLOT(onEndPointAttributeChanged()), Qt::UniqueConnection);
connect(&m_endY, SIGNAL(sigValueChanged()), this, SLOT(onEndPointAttributeChanged()), Qt::UniqueConnection);
connect(&m_fractureFlowModel, SIGNAL(sigValueChanged()), this, SIGNAL(sigFractureDataChanged()), Qt::UniqueConnection);
connect(&m_fractureDfc, SIGNAL(sigValueChanged()), this, SIGNAL(sigFractureDataChanged()), Qt::UniqueConnection);
connect(&m_fractureDw, SIGNAL(sigValueChanged()), this, SIGNAL(sigFractureDataChanged()), Qt::UniqueConnection);
}
// 图元或文件数据变化后,将点集首尾坐标同步到面板绑定属性。
void nmDataFracture::syncEndPointAttributes()
{
if (m_vecPts.size() < 2) {
return;
}
m_bSyncingEndPoints = true;
const QPointF& start = m_vecPts.first();
const QPointF& end = m_vecPts.last();
if (m_startX.getValue().toDouble() != start.x()) m_startX.setValue(start.x());
if (m_startY.getValue().toDouble() != start.y()) m_startY.setValue(start.y());
if (m_endX.getValue().toDouble() != end.x()) m_endX.setValue(end.x());
if (m_endY.getValue().toDouble() != end.y()) m_endY.setValue(end.y());
m_bSyncingEndPoints = false;
}
// 参数面板修改端点坐标后,回写真实点集并通知 Binder 更新图元。
void nmDataFracture::onEndPointAttributeChanged()
{
if (m_bSyncingEndPoints || m_vecPts.size() < 2) {
return;
}
m_vecPts.first().setX(m_startX.getValue().toDouble());
m_vecPts.first().setY(m_startY.getValue().toDouble());
m_vecPts.last().setX(m_endX.getValue().toDouble());
m_vecPts.last().setY(m_endY.getValue().toDouble());
emit sigFractureDataChanged();
}

@ -1,9 +1,12 @@
#include "nmDataOutline.h"
#include "nmDataJsonTools.h"
#include <QtAlgorithms>
// Constructor
nmDataOutline::nmDataOutline()
: m_sName()
: m_bSyncingGeometryAttributes(false)
, m_sName()
, m_vecPts()
, m_vFlowTypeList()
, m_eOutlineType(NM_Rect_Outline_Type)
@ -15,9 +18,12 @@ nmDataOutline::nmDataOutline()
, m_nBackgrdAlpha(0)
, m_bHasVisualProps(false)
{
initGeometryAttributes();
}
nmDataOutline::nmDataOutline(const nmDataOutline& other) {
nmDataOutline::nmDataOutline(const nmDataOutline& other)
: m_bSyncingGeometryAttributes(false) {
initGeometryAttributes();
*this = other;
}
@ -36,12 +42,15 @@ nmDataOutline& nmDataOutline::operator=(const nmDataOutline& other) {
m_clrBackgrd = other.m_clrBackgrd;
m_nBackgrdAlpha = other.m_nBackgrdAlpha;
m_bHasVisualProps = other.m_bHasVisualProps;
syncGeometryAttributes();
}
return *this;
}
// Destructor
nmDataOutline::~nmDataOutline() {
clearPointAttributes();
}
// 序列化 nmDataOutline 为 RapidJSON Value
@ -170,6 +179,8 @@ void nmDataOutline::FromJsonValue(const rapidjson::Value& jsonValue)
bHasVisual = true;
}
m_bHasVisualProps = bHasVisual;
syncGeometryAttributes();
}
// Getter and Setter for m_sName
@ -188,6 +199,55 @@ QVector<QPointF> nmDataOutline::getOutlinePoints() {
void nmDataOutline::setOutlinePoints(const QVector<QPointF>& vecPts) {
m_vecPts = vecPts;
syncPointAttributes();
if (m_eOutlineType == NM_Rect_Outline_Type) {
syncRectAttributes();
} else if (m_eOutlineType == NM_Round_Outline_Type) {
syncRoundAttributes();
}
}
int nmDataOutline::getOutlinePointCount() const {
return m_vecPts.count();
}
nmDataAttribute* nmDataOutline::getPointXAttribute(int nIndex) const {
if (nIndex < 0 || nIndex >= m_vPointXAttributes.count()) return nullptr;
return m_vPointXAttributes[nIndex];
}
nmDataAttribute* nmDataOutline::getPointYAttribute(int nIndex) const {
if (nIndex < 0 || nIndex >= m_vPointYAttributes.count()) return nullptr;
return m_vPointYAttributes[nIndex];
}
nmDataAttribute& nmDataOutline::getLeftAttribute() {
return m_left;
}
nmDataAttribute& nmDataOutline::getRightAttribute() {
return m_right;
}
nmDataAttribute& nmDataOutline::getTopAttribute() {
return m_top;
}
nmDataAttribute& nmDataOutline::getBottomAttribute() {
return m_bottom;
}
nmDataAttribute& nmDataOutline::getCenterXAttribute() {
return m_centerX;
}
nmDataAttribute& nmDataOutline::getCenterYAttribute() {
return m_centerY;
}
nmDataAttribute& nmDataOutline::getRadiusAttribute() {
return m_radius;
}
QVector<int> nmDataOutline::getFlowTypeList() const {
@ -208,6 +268,7 @@ NM_Data_Outline_Type nmDataOutline::getOutlineType() const
void nmDataOutline::setOutlineType(NM_Data_Outline_Type eOutlineType)
{
m_eOutlineType = eOutlineType;
syncGeometryAttributes();
}
// Getter for m_ptCenter
@ -220,6 +281,7 @@ QPointF nmDataOutline::getCenter() const
void nmDataOutline::setCenter(const QPointF& ptCenter)
{
m_ptCenter = ptCenter;
syncRoundAttributes();
}
// Getter for m_dRadius
@ -232,6 +294,7 @@ double nmDataOutline::getRadius() const
void nmDataOutline::setRadius(double dRadius)
{
m_dRadius = dRadius;
syncRoundAttributes();
}
bool nmDataOutline::getPlotVisible() const{
@ -268,3 +331,180 @@ bool nmDataOutline::hasVisualProps() const {
void nmDataOutline::setVisualPropsValid(bool bValid) {
m_bHasVisualProps = bValid;
}
// 固定几何属性作为参数面板适配层,实际持久化数据仍保存在原有字段中。
void nmDataOutline::initGeometryAttributes()
{
QStringList lengthUnits;
lengthUnits << "m" << "cm" << "mm" << "in" << "0.1 in" << "ft" << "mile" << "km";
m_left = nmDataAttribute("Boundary left X", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_right = nmDataAttribute("Boundary right X", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_top = nmDataAttribute("Boundary top Y", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_bottom = nmDataAttribute("Boundary bottom Y", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_centerX = nmDataAttribute("Boundary center X", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_centerY = nmDataAttribute("Boundary center Y", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
m_radius = nmDataAttribute("Boundary radius", 0.0, "m", UNIT_TYPE_LENGTH, QStringList(), lengthUnits);
connect(&m_left, SIGNAL(sigValueChanged()), this, SLOT(onGeometryAttributeChanged()), Qt::UniqueConnection);
connect(&m_right, SIGNAL(sigValueChanged()), this, SLOT(onGeometryAttributeChanged()), Qt::UniqueConnection);
connect(&m_top, SIGNAL(sigValueChanged()), this, SLOT(onGeometryAttributeChanged()), Qt::UniqueConnection);
connect(&m_bottom, SIGNAL(sigValueChanged()), this, SLOT(onGeometryAttributeChanged()), Qt::UniqueConnection);
connect(&m_centerX, SIGNAL(sigValueChanged()), this, SLOT(onGeometryAttributeChanged()), Qt::UniqueConnection);
connect(&m_centerY, SIGNAL(sigValueChanged()), this, SLOT(onGeometryAttributeChanged()), Qt::UniqueConnection);
connect(&m_radius, SIGNAL(sigValueChanged()), this, SLOT(onGeometryAttributeChanged()), Qt::UniqueConnection);
}
void nmDataOutline::clearPointAttributes()
{
qDeleteAll(m_vPointXAttributes);
qDeleteAll(m_vPointYAttributes);
m_vPointXAttributes.clear();
m_vPointYAttributes.clear();
}
// 根据边界类型,将原有几何数据同步到对应的面板绑定属性。
void nmDataOutline::syncGeometryAttributes()
{
syncPointAttributes();
if (m_eOutlineType == NM_Rect_Outline_Type) {
syncRectAttributes();
} else if (m_eOutlineType == NM_Round_Outline_Type) {
syncRoundAttributes();
}
}
void nmDataOutline::syncPointAttributes()
{
// 矩形和圆形使用固定几何属性,只有多边形需要逐点属性。
if (m_eOutlineType != NM_Polygon_Outline_Type) {
if (!m_vPointXAttributes.isEmpty() || !m_vPointYAttributes.isEmpty()) {
clearPointAttributes();
}
return;
}
if (m_vPointXAttributes.count() != m_vecPts.count() ||
m_vPointYAttributes.count() != m_vecPts.count()) {
clearPointAttributes();
QStringList lengthUnits;
lengthUnits << "m" << "cm" << "mm" << "in" << "0.1 in" << "ft" << "mile" << "km";
for (int i = 0; i < m_vecPts.count(); ++i) {
nmDataAttribute* pX = new nmDataAttribute(QString("Boundary point %1 X").arg(i + 1),
m_vecPts[i].x(), "m", UNIT_TYPE_LENGTH,
QStringList(), lengthUnits);
nmDataAttribute* pY = new nmDataAttribute(QString("Boundary point %1 Y").arg(i + 1),
m_vecPts[i].y(), "m", UNIT_TYPE_LENGTH,
QStringList(), lengthUnits);
pX->setParent(this);
pY->setParent(this);
connect(pX, SIGNAL(sigValueChanged()), this, SLOT(onGeometryAttributeChanged()), Qt::UniqueConnection);
connect(pY, SIGNAL(sigValueChanged()), this, SLOT(onGeometryAttributeChanged()), Qt::UniqueConnection);
m_vPointXAttributes.append(pX);
m_vPointYAttributes.append(pY);
}
}
m_bSyncingGeometryAttributes = true;
for (int i = 0; i < m_vecPts.count(); ++i) {
if (m_vPointXAttributes[i]->getValue().toDouble() != m_vecPts[i].x()) {
m_vPointXAttributes[i]->setValue(m_vecPts[i].x());
}
if (m_vPointYAttributes[i]->getValue().toDouble() != m_vecPts[i].y()) {
m_vPointYAttributes[i]->setValue(m_vecPts[i].y());
}
}
m_bSyncingGeometryAttributes = false;
}
void nmDataOutline::syncRectAttributes()
{
if (m_vecPts.isEmpty()) return;
double left = m_vecPts.first().x();
double right = left;
double top = m_vecPts.first().y();
double bottom = top;
foreach (const QPointF& pt, m_vecPts) {
left = qMin(left, pt.x());
right = qMax(right, pt.x());
top = qMax(top, pt.y());
bottom = qMin(bottom, pt.y());
}
m_bSyncingGeometryAttributes = true;
if (m_left.getValue().toDouble() != left) m_left.setValue(left);
if (m_right.getValue().toDouble() != right) m_right.setValue(right);
if (m_top.getValue().toDouble() != top) m_top.setValue(top);
if (m_bottom.getValue().toDouble() != bottom) m_bottom.setValue(bottom);
m_bSyncingGeometryAttributes = false;
}
void nmDataOutline::syncRoundAttributes()
{
m_bSyncingGeometryAttributes = true;
if (m_centerX.getValue().toDouble() != m_ptCenter.x()) m_centerX.setValue(m_ptCenter.x());
if (m_centerY.getValue().toDouble() != m_ptCenter.y()) m_centerY.setValue(m_ptCenter.y());
if (m_radius.getValue().toDouble() != m_dRadius) m_radius.setValue(m_dRadius);
m_bSyncingGeometryAttributes = false;
}
void nmDataOutline::updateRectPointsFromAttributes()
{
const double left = m_left.getValue().toDouble();
const double right = m_right.getValue().toDouble();
const double top = m_top.getValue().toDouble();
const double bottom = m_bottom.getValue().toDouble();
m_vecPts.clear();
m_vecPts << QPointF(left, top)
<< QPointF(right, top)
<< QPointF(right, bottom)
<< QPointF(left, bottom);
syncPointAttributes();
}
void nmDataOutline::updateRoundPointsFromAttributes()
{
const QPointF center(m_centerX.getValue().toDouble(), m_centerY.getValue().toDouble());
const double radius = m_radius.getValue().toDouble();
m_ptCenter = center;
m_dRadius = radius;
m_vecPts.clear();
m_vecPts << center
<< QPointF(radius, radius)
<< QPointF(center.x(), center.y() - radius)
<< QPointF(center.x() + radius, center.y())
<< QPointF(center.x(), center.y() + radius)
<< QPointF(center.x() - radius, center.y());
syncPointAttributes();
}
// 参数面板修改几何属性后,回写边界数据并通知 Binder 更新图元。
void nmDataOutline::onGeometryAttributeChanged()
{
if (m_bSyncingGeometryAttributes) return;
QObject* pSender = sender();
if (pSender == &m_left || pSender == &m_right ||
pSender == &m_top || pSender == &m_bottom) {
updateRectPointsFromAttributes();
} else if (pSender == &m_centerX || pSender == &m_centerY || pSender == &m_radius) {
updateRoundPointsFromAttributes();
} else {
for (int i = 0; i < m_vecPts.count(); ++i) {
if (pSender == m_vPointXAttributes.value(i, nullptr)) {
m_vecPts[i].setX(m_vPointXAttributes[i]->getValue().toDouble());
break;
}
if (pSender == m_vPointYAttributes.value(i, nullptr)) {
m_vecPts[i].setY(m_vPointYAttributes[i]->getValue().toDouble());
break;
}
}
}
emit sigOutlineDataChanged();
}

@ -12,10 +12,13 @@ nmDataRegion::nmDataRegion(){
// 视觉属性默认值(与 nmObjRegion::init 保持一致)
m_dPenWidth = 0.3;
m_clrBackgrd = QColor(0, 0, 0, 0);
this->connectAttributeSignals();
}
nmDataRegion::nmDataRegion(const nmDataRegion& other){
*this = other; // 使用赋值运算符实现
this->connectAttributeSignals();
}
nmDataRegion& nmDataRegion::operator=(const nmDataRegion& other) {
@ -212,3 +215,16 @@ QColor nmDataRegion::getBackgrdColor() const {
void nmDataRegion::setBackgrdColor(const QColor& clr) {
m_clrBackgrd = clr;
}
// 批量赋值不会触发属性信号,通过对象级信号统一刷新关联视图。
void nmDataRegion::notifyDataChanged()
{
emit sigRegionDataChanged();
}
// 将已有属性的变化汇总为区域数据变化信号,供 Binder 统一处理。
void nmDataRegion::connectAttributeSignals()
{
connect(&m_regionFlowModel, SIGNAL(sigValueChanged()), this, SIGNAL(sigRegionDataChanged()), Qt::UniqueConnection);
connect(&m_regionLeakage, SIGNAL(sigValueChanged()), this, SIGNAL(sigRegionDataChanged()), Qt::UniqueConnection);
}

@ -19,10 +19,12 @@ nmDataRegionMark::nmDataRegionMark()
m_netToGross = nmDataAttribute("NetToGross", 1.0, "", UNIT_TYPE_DIMENSIONLESS, QStringList(), QStringList());
// 图元可见性默认为true
this->connectAttributeSignals();
}
nmDataRegionMark::nmDataRegionMark(const nmDataRegionMark& other) {
*this = other; // 使用赋值运算符实现
this->connectAttributeSignals();
}
nmDataRegionMark& nmDataRegionMark::operator=(const nmDataRegionMark& other) {
@ -189,3 +191,18 @@ bool nmDataRegionMark::getPlotVisible() const{
void nmDataRegionMark::setPlotVisible(const bool newState) {
m_bPlotVisible = newState;
}
// 批量赋值不会触发属性信号,通过对象级信号统一刷新关联视图。
void nmDataRegionMark::notifyDataChanged()
{
emit sigRegionMarkDataChanged();
}
// 将已有属性的变化汇总为标记区域数据变化信号,供 Binder 统一处理。
void nmDataRegionMark::connectAttributeSignals()
{
connect(&m_reservoirType, SIGNAL(sigValueChanged()), this, SIGNAL(sigRegionMarkDataChanged()), Qt::UniqueConnection);
connect(&m_comKr, SIGNAL(sigValueChanged()), this, SIGNAL(sigRegionMarkDataChanged()), Qt::UniqueConnection);
connect(&m_comW, SIGNAL(sigValueChanged()), this, SIGNAL(sigRegionMarkDataChanged()), Qt::UniqueConnection);
connect(&m_netToGross, SIGNAL(sigValueChanged()), this, SIGNAL(sigRegionMarkDataChanged()), Qt::UniqueConnection);
}

@ -1,4 +1,4 @@
#include "nmGridRowUtils.h"
#include "nmGridRowUtils.h"
#include "iGridRowGroup.h"
#include "iParameter.h"
#include "iSysParaHelper.h"
@ -64,7 +64,7 @@ bool nmGridRowUtils::buildRowUtils(QStringList listParas,
bool bDnMode,
QWidget* pWxDlg)
{
// 分离储层参数和井参数
// 分离储层参数和带对象编码前缀的参数。
QStringList listRes;
QMap<QString, QStringList> mapWellParas;
splitWellParas(listParas, listRes, mapWellParas);
@ -74,12 +74,12 @@ bool nmGridRowUtils::buildRowUtils(QStringList listParas,
{
return false;
}
// 构建井分组
// 沿用多井机制构建对象分组。
if (!mapWellParas.isEmpty())
{
buildWellGroups(mapWellParas, bDnMode);
// 分组追加完成后,重新备份、绑定、计算布局
// 对象分组追加完成后,重新备份、绑定、计算布局
bkAllItems();
bindItems();
@ -263,7 +263,7 @@ void nmGridRowUtils::bindItems()
}
// ================================================================
// 多井分组实现
// 多对象分组实现(沿用多井接口)
// ================================================================
void nmGridRowUtils::splitWellParas(QStringList listParas,
@ -302,10 +302,33 @@ void nmGridRowUtils::buildWellGroups(QMap<QString, QStringList>& mapWellParas,
{
bool bProperOrder = true;
// 按wellCode排序遍历
// 沿用多井分组机制,按对象编码排序遍历。
QList<QString> listCodes = mapWellParas.keys();
qSort(listCodes);
// 多边形边界先建立外层分组,各顶点作为其子分组。
nmWellGridRowGroup* pPolygonGroup = nullptr;
foreach (const QString& sCode, listCodes)
{
if (sCode.startsWith("BVERT"))
{
pPolygonGroup = new nmWellGridRowGroup(nullptr);
Q_ASSERT(nullptr != pPolygonGroup);
pPolygonGroup->setParaSrcTag(m_sParaSrcTag);
pPolygonGroup->setTagInner(m_mapWellNames.value("BOUNDARY", tr("PolygonOutline")));
connectSignalsOf(pPolygonGroup);
pPolygonGroup->setDlgBase(this);
pPolygonGroup->initEditor();
pPolygonGroup->configEditor();
pPolygonGroup->setSplitPos(m_dSplitPos);
pPolygonGroup->initOtherEditors();
m_vecGridItems.append(pPolygonGroup);
break;
}
}
foreach (QString sCode, listCodes)
{
QStringList listParas = mapWellParas[sCode];
@ -314,7 +337,7 @@ void nmGridRowUtils::buildWellGroups(QMap<QString, QStringList>& mapWellParas,
continue;
}
// 井前缀,如 "W001_"
// 对象编码前缀,如 "W001_"、"FRAC0001_"。
QString sPrefix = sCode + "_";
// 显示名称
@ -325,12 +348,17 @@ void nmGridRowUtils::buildWellGroups(QMap<QString, QStringList>& mapWellParas,
sWellName = m_mapWellNames[sCode];
}
// 参考多对象 UI 的 Layer 分组:用父节点的 tagLayer 标记对象作用域。
nmWellGridRowGroup* pGroup = new nmWellGridRowGroup(nullptr);
// 用父节点的 tagLayer 标记对象作用域。
iGridRowItem* pParent = sCode.startsWith("BVERT") ? pPolygonGroup : nullptr;
nmWellGridRowGroup* pGroup = new nmWellGridRowGroup(pParent);
Q_ASSERT(nullptr != pGroup);
if (pParent != nullptr)
{
pParent->appendChild(pGroup);
}
pGroup->setParaSrcTag(m_sParaSrcTag);
pGroup->setTagInner(sWellName); // Group 标题
pGroup->setTagLayer(sPrefix); // 井前缀标识
pGroup->setTagLayer(sPrefix); // 对象编码前缀
connectSignalsOf(pGroup);
pGroup->setDlgBase(this);
@ -339,10 +367,28 @@ void nmGridRowUtils::buildWellGroups(QMap<QString, QStringList>& mapWellParas,
pGroup->setSplitPos(m_dSplitPos);
pGroup->initOtherEditors();
m_vecGridItems.append(pGroup);
if (pParent == nullptr)
{
m_vecGridItems.append(pGroup);
}
// 在该分组下构建参数项
_buildRowUtils(listParas, pGroup, bDnMode, bProperOrder);
// 多边形顶点直接显示 X/Y避免每个 Point 下重复一层参数组。
if (pParent != nullptr)
{
foreach (const QString& sPara, listParas)
{
iParameter* p = _paraHelper->getPara(sPara, m_sParaSrcTag);
if (p != nullptr)
{
createAndAddItem(pGroup, p, sPara);
}
}
}
else
{
// 在该分组下构建参数项
_buildRowUtils(listParas, pGroup, bDnMode, bProperOrder);
}
}
}

@ -1,4 +1,4 @@
#include "nmPlotGraphicBinder.h"
#include "nmPlotGraphicBinder.h"
#include "nmObjLineFault.h"
#include "nmDataFault.h"
@ -30,10 +30,30 @@
#include "Defines.h"
#include "iDataTypes.h"
#include "zxSysUtils.h"
#include "IxPtyPano.h"
#include "IxPtyItem.h"
#include <QMetaObject>
#include <QMessageBox>
namespace {
// 参数面板回写图元后,同步当前选中对象的左侧属性项。
void refreshPropertyValue(nmObjBase* pGraphic, const QString& key, const QVariant& value)
{
if (pGraphic == nullptr || !pGraphic->isSelected()) return;
IxPtyPano* pPano = pGraphic->getPtyPano();
if (pPano == nullptr) return;
IxPtyItem* pItem = pPano->findPropertyItem(key);
if (pItem != nullptr && pItem->getValue() != value) {
pItem->setValue(value, pGraphic);
}
}
}
nmPlotGraphicBinder::WellRenderData::WellRenderData()
: valid(false)
, wellType(Vertical_Well)
@ -73,7 +93,7 @@ void nmPlotGraphicBinder::createFaultForGraphic(nmObjLineFault* pGraphic)
// 建立信号连接
_connectFault(pGraphic, pData);
m_pDataMgr->notifyDataChanged();
m_pDataMgr->notifyGeometryListChanged();
}
// 从文件加载:绑定已有数据到已有图元
@ -84,6 +104,7 @@ void nmPlotGraphicBinder::bindFaultToGraphic(nmObjLineFault* pGraphic, nmDataFau
}
// 将数据值推到图元
pGraphic->setName(pData->getFaultName());
_pushFaultDataToGraphic(pGraphic, pData);
// 建立信号连接
@ -122,6 +143,9 @@ void nmPlotGraphicBinder::syncFaultName(nmObjLineFault* pGraphic)
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (pData && pData->getFaultName() != pGraphic->getName()) {
pData->setFaultName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyParameterObjectNameChanged();
}
}
}
@ -149,16 +173,22 @@ void nmPlotGraphicBinder::updateDataMgr(nmDataAnalyzeManager* pDataMgr)
void nmPlotGraphicBinder::_pushFaultDataToGraphic(nmObjLineFault* pGraphic, nmDataFault* pData)
{
// 阻断信号,防止推送中触发反向同步
pGraphic->blockSignals(true);
bool bOldSignalsBlocked = pGraphic->blockSignals(true);
pGraphic->setName(pData->getFaultName());
pGraphic->setAllValues(pData->getFaultPoints());
int flowModel = (pData->getFaultFlowModel().getValue() == tr("Leaky")) ? 0 : 1;
pGraphic->setFaultFlowModel(flowModel);
pGraphic->setFaultLeakage(pData->getFaultLeakage().getValue().toDouble());
pGraphic->blockSignals(false);
pGraphic->blockSignals(bOldSignalsBlocked);
refreshPropertyValue(pGraphic, "ObjLineFaultStartPos.StartPointX", pData->getStartX().getValue());
refreshPropertyValue(pGraphic, "ObjLineFaultStartPos.StartPointY", pData->getStartY().getValue());
refreshPropertyValue(pGraphic, "ObjLineFaultEndPos.EndPointX", pData->getEndX().getValue());
refreshPropertyValue(pGraphic, "ObjLineFaultEndPos.EndPointY", pData->getEndY().getValue());
pGraphic->update();
}
// 建立图元与数据的双向信号连接
@ -175,6 +205,8 @@ void nmPlotGraphicBinder::_connectFault(nmObjLineFault* pGraphic, nmDataFault* p
QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicVisibleChanged(bool)));
QObject::connect(pData, SIGNAL(sigFaultDataChanged()),
this, SLOT(onFaultDataChanged()), Qt::UniqueConnection);
m_mapFaultData[pGraphic] = pData;
@ -198,6 +230,12 @@ void nmPlotGraphicBinder::_disconnectFault(nmObjLineFault* pGraphic)
QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicVisibleChanged(bool)));
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (pData != nullptr) {
QObject::disconnect(pData, SIGNAL(sigFaultDataChanged()),
this, SLOT(onFaultDataChanged()));
}
m_setBoundGraphics.remove(pGraphic);
}
@ -241,7 +279,6 @@ void nmPlotGraphicBinder::onGraphicPointsChanged()
if (!pData) return;
pData->setFaultPoints(pGraphic->getAllValues());
pData->setFaultName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
@ -260,6 +297,18 @@ void nmPlotGraphicBinder::onGraphicVisibleChanged(bool bVisible)
pData->setPlotVisible(bVisible);
}
// 数据参数变更 -> 同步到图元和左侧属性面板
void nmPlotGraphicBinder::onFaultDataChanged()
{
nmDataFault* pData = qobject_cast<nmDataFault*>(sender());
if (!pData) return;
nmObjLineFault* pGraphic = m_mapFaultData.key(pData, nullptr);
if (pGraphic) {
_pushFaultDataToGraphic(pGraphic, pData);
}
}
// 数据变更(预留)
void nmPlotGraphicBinder::onDataChanged()
{
@ -269,6 +318,11 @@ void nmPlotGraphicBinder::onDataChanged()
// 用户画完裂缝后:创建数据对象并建立绑定
void nmPlotGraphicBinder::createCrackForGraphic(nmObjLineCrack* pGraphic)
{
createCrackForGraphic(pGraphic, true);
}
void nmPlotGraphicBinder::createCrackForGraphic(nmObjLineCrack* pGraphic, bool bNotifyGeometryList)
{
if (!pGraphic || !m_pDataMgr) {
return;
@ -293,7 +347,11 @@ void nmPlotGraphicBinder::createCrackForGraphic(nmObjLineCrack* pGraphic)
// 建立信号连接
_connectCrack(pGraphic, pData);
m_pDataMgr->notifyDataChanged();
if (bNotifyGeometryList) {
m_pDataMgr->notifyGeometryListChanged();
} else {
m_pDataMgr->notifyDataChanged();
}
}
// 从文件加载:绑定已有裂缝数据到已有图元
@ -304,6 +362,7 @@ void nmPlotGraphicBinder::bindCrackToGraphic(nmObjLineCrack* pGraphic, nmDataFra
}
// 将数据值推到图元
pGraphic->setName(pData->getFractureName());
_pushCrackDataToGraphic(pGraphic, pData);
// 建立信号连接
@ -342,6 +401,10 @@ void nmPlotGraphicBinder::syncCrackName(nmObjLineCrack* pGraphic)
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (pData && pData->getFractureName() != pGraphic->getName()) {
pData->setFractureName(pGraphic->getName());
// DFN 裂缝不在参数面板中显示,改名时无需重建面板。
if (m_pDataMgr && pData->getFractureType().getValue().toString() != "DFN") {
m_pDataMgr->notifyParameterObjectNameChanged();
}
}
}
@ -349,9 +412,9 @@ void nmPlotGraphicBinder::syncCrackName(nmObjLineCrack* pGraphic)
void nmPlotGraphicBinder::_pushCrackDataToGraphic(nmObjLineCrack* pGraphic, nmDataFracture* pData)
{
// 阻断信号,防止推送中触发反向同步
pGraphic->blockSignals(true);
bool bOldSignalsBlocked = pGraphic->blockSignals(true);
pGraphic->setName(pData->getFractureName());
pGraphic->setAllValues(pData->getFracturePoints());
int flowModel = (pData->getFractureFlowModel().getValue() == tr("Infinite Conductivity")) ? 0 : 1;
pGraphic->setCrackFlowModel(flowModel);
@ -359,7 +422,14 @@ void nmPlotGraphicBinder::_pushCrackDataToGraphic(nmObjLineCrack* pGraphic, nmDa
pGraphic->setCrackDfc(pData->getFractureDfc().getValue().toDouble());
pGraphic->setCrackDw(pData->getFractureDw().getValue().toDouble());
pGraphic->blockSignals(false);
pGraphic->blockSignals(bOldSignalsBlocked);
refreshPropertyValue(pGraphic, "ObjLineCrackStartPos.StartPointX", pData->getStartX().getValue());
refreshPropertyValue(pGraphic, "ObjLineCrackStartPos.StartPointY", pData->getStartY().getValue());
refreshPropertyValue(pGraphic, "ObjLineCrackEndPos.EndPointX", pData->getEndX().getValue());
refreshPropertyValue(pGraphic, "ObjLineCrackEndPos.EndPointY", pData->getEndY().getValue());
refreshPropertyValue(pGraphic, "ObjLineFracture.dFc", pData->getFractureDfc().getValue());
pGraphic->update();
}
// 建立裂缝图元与数据的双向信号连接
@ -379,6 +449,8 @@ void nmPlotGraphicBinder::_connectCrack(nmObjLineCrack* pGraphic, nmDataFracture
QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicCrackVisibleChanged(bool)));
QObject::connect(pData, SIGNAL(sigFractureDataChanged()),
this, SLOT(onFractureDataChanged()), Qt::UniqueConnection);
m_mapCrackData[pGraphic] = pData;
@ -405,6 +477,12 @@ void nmPlotGraphicBinder::_disconnectCrack(nmObjLineCrack* pGraphic)
QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicCrackVisibleChanged(bool)));
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (pData != nullptr) {
QObject::disconnect(pData, SIGNAL(sigFractureDataChanged()),
this, SLOT(onFractureDataChanged()));
}
m_setBoundCrackGraphics.remove(pGraphic);
}
@ -431,9 +509,9 @@ void nmPlotGraphicBinder::onGraphicCrackDfcChanged(double dfc)
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFractureDfc();
attr.setValue(dfc);
pData->setFractureDfc(attr);
if (pData->getFractureDfc().getValue().toDouble() != dfc) {
pData->getFractureDfc().setValue(dfc);
}
}
// 裂缝储能比变更
@ -460,7 +538,6 @@ void nmPlotGraphicBinder::onGraphicCrackPointsChanged()
if (!pData) return;
pData->setFracturePoints(pGraphic->getAllValues());
pData->setFractureName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
@ -479,6 +556,18 @@ void nmPlotGraphicBinder::onGraphicCrackVisibleChanged(bool bVisible)
pData->setPlotVisible(bVisible);
}
// 数据参数变更 -> 同步到图元和左侧属性面板
void nmPlotGraphicBinder::onFractureDataChanged()
{
nmDataFracture* pData = qobject_cast<nmDataFracture*>(sender());
if (!pData) return;
nmObjLineCrack* pGraphic = m_mapCrackData.key(pData, nullptr);
if (pGraphic) {
_pushCrackDataToGraphic(pGraphic, pData);
}
}
// ==================== 边界图元绑定 ====================
// 圆形边界:用户画完后创建数据并绑定
@ -508,7 +597,7 @@ void nmPlotGraphicBinder::createOutlineForGraphic(nmObjRoundOutline* pGraphic)
pData->setBackgrdAlpha(roundClr.alpha());
pData->setVisualPropsValid(true);
double qradius = pGraphic->getAllValues()[2].y() - pGraphic->getAllValues()[0].y();
double qradius = qAbs(pGraphic->getAllValues()[2].y() - pGraphic->getAllValues()[0].y());
pData->setRadius(qradius);
pData->setCenter(pGraphic->getAllValues()[0]);
@ -517,7 +606,7 @@ void nmPlotGraphicBinder::createOutlineForGraphic(nmObjRoundOutline* pGraphic)
_connectOutline(pGraphic, pData);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
m_pDataMgr->notifyGeometryListChanged();
}
}
@ -551,7 +640,7 @@ void nmPlotGraphicBinder::createOutlineForGraphic(nmObjRectOutline* pGraphic)
_connectOutline(pGraphic, pData);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
m_pDataMgr->notifyGeometryListChanged();
}
}
@ -585,7 +674,7 @@ void nmPlotGraphicBinder::createOutlineForGraphic(nmObjPolygonOutline* pGraphic)
_connectOutline(pGraphic, pData);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
m_pDataMgr->notifyGeometryListChanged();
}
}
@ -597,6 +686,7 @@ void nmPlotGraphicBinder::bindOutlineToGraphic(nmObjBase* pGraphic, nmDataOutlin
m_mapOutlineData[pGraphic] = pData;
m_setBoundOutlineGraphics.insert(pGraphic);
pGraphic->setName(pData->getName());
_pushOutlineDataToGraphic(pGraphic, pData);
_connectOutline(pGraphic, pData);
}
@ -606,12 +696,13 @@ void nmPlotGraphicBinder::removeOutlineBinding(nmObjBase* pGraphic)
{
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
_disconnectOutline(pGraphic);
m_mapOutlineData.remove(pGraphic);
if (m_pDataMgr) {
if (m_pDataMgr && pData != nullptr && m_pDataMgr->getOutlineData() == pData) {
m_pDataMgr->removeOutlineData();
m_pDataMgr->notifyDataChanged();
}
}
@ -628,6 +719,9 @@ void nmPlotGraphicBinder::syncOutlineName(nmObjBase* pGraphic)
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (pData && pData->getName() != pGraphic->getName()) {
pData->setName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyParameterObjectNameChanged();
}
}
}
@ -669,17 +763,20 @@ void nmPlotGraphicBinder::syncOutlineVisual(nmObjBase* pGraphic)
pData->setVisualPropsValid(true);
}
// 建立边界图元与数据的信号连接(三条信号)
// 建立边界图元与数据的信号连接
void nmPlotGraphicBinder::_connectOutline(nmObjBase* pGraphic, nmDataOutline* pData)
{
QObject::connect(pGraphic, SIGNAL(sigOutlinePointsChanged()),
this, SLOT(onGraphicOutlinePointsChanged()));
this, SLOT(onGraphicOutlinePointsChanged()), Qt::UniqueConnection);
QObject::connect(pGraphic, SIGNAL(sigOutlineFlowTypeChanged()),
this, SLOT(onGraphicOutlineFlowTypeChanged()));
this, SLOT(onGraphicOutlineFlowTypeChanged()), Qt::UniqueConnection);
QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicOutlineVisibleChanged(bool)));
this, SLOT(onGraphicOutlineVisibleChanged(bool)), Qt::UniqueConnection);
QObject::connect(pData, SIGNAL(sigOutlineDataChanged()),
this, SLOT(onOutlineDataChanged()), Qt::UniqueConnection);
m_setBoundOutlineGraphics.insert(pGraphic);
@ -705,15 +802,29 @@ void nmPlotGraphicBinder::_disconnectOutline(nmObjBase* pGraphic)
QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicOutlineVisibleChanged(bool)));
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (pData != nullptr) {
QObject::disconnect(pData, SIGNAL(sigOutlineDataChanged()),
this, SLOT(onOutlineDataChanged()));
}
if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
pRound->setGraphicBinder(nullptr);
} else if (nmObjRectOutline* pRect = dynamic_cast<nmObjRectOutline*>(pGraphic)) {
pRect->setGraphicBinder(nullptr);
} else if (nmObjPolygonOutline* pPolygon = dynamic_cast<nmObjPolygonOutline*>(pGraphic)) {
pPolygon->setGraphicBinder(nullptr);
}
m_setBoundOutlineGraphics.remove(pGraphic);
}
// 从边界数据对象读取值,写入图元本地副本(加载时用)
// 从边界数据对象读取值,写入图元本地副本(加载及参数变更时用)
void nmPlotGraphicBinder::_pushOutlineDataToGraphic(nmObjBase* pGraphic, nmDataOutline* pData)
{
pGraphic->blockSignals(true);
bool bOldSignalsBlocked = pGraphic->blockSignals(true);
pGraphic->setName(pData->getName());
pGraphic->setAllValues(pData->getOutlinePoints());
QVector<int> flowTypes = pData->getFlowTypeList();
@ -749,7 +860,8 @@ void nmPlotGraphicBinder::_pushOutlineDataToGraphic(nmObjBase* pGraphic, nmDataO
}
}
pGraphic->blockSignals(false);
pGraphic->blockSignals(bOldSignalsBlocked);
pGraphic->update();
}
// ==================== 边界图元信号 → 数据同步 ====================
@ -763,20 +875,38 @@ void nmPlotGraphicBinder::onGraphicOutlinePointsChanged()
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (!pData) return;
pData->setOutlinePoints(pGraphic->getAllValues());
const int nOldPointCount = pData->getOutlinePointCount();
const QVector<QPointF> points = pGraphic->getAllValues();
pData->setOutlinePoints(points);
// 圆形边界额外同步 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();
double radius = qAbs(pts[2].y() - pts[0].y());
pData->setRadius(radius);
pData->setCenter(pts[0]);
}
}
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
if (nOldPointCount != points.count()) {
m_pDataMgr->notifyGeometryListChanged();
} else {
m_pDataMgr->notifyDataChanged();
}
}
}
// 数据参数变更 -> 同步到图元
void nmPlotGraphicBinder::onOutlineDataChanged()
{
nmDataOutline* pData = qobject_cast<nmDataOutline*>(sender());
if (!pData) return;
nmObjBase* pGraphic = m_mapOutlineData.key(pData, nullptr);
if (pGraphic) {
_pushOutlineDataToGraphic(pGraphic, pData);
}
}
@ -938,7 +1068,7 @@ void nmPlotGraphicBinder::createRegionMarkForGraphic(nmObjRegionMark* pGraphic)
// 建立信号连接
_connectRegionMark(pGraphic, pData);
m_pDataMgr->notifyDataChanged();
m_pDataMgr->notifyGeometryListChanged();
}
// 从文件加载:绑定已有区域标记数据到已有图元
@ -980,7 +1110,12 @@ void nmPlotGraphicBinder::syncRegionMarkData(nmObjRegionMark* pGraphic)
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
pData->setRegionMarkName(pGraphic->getName());
if (pData->getRegionMarkName() != pGraphic->getName()) {
pData->setRegionMarkName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyParameterObjectNameChanged();
}
}
pData->setBackgroundColor(pGraphic->getBackgrdColor());
pData->setSelectRegion(pGraphic->getSelectRegion());
@ -1026,9 +1161,9 @@ void nmPlotGraphicBinder::onGraphicRegionMarkComKrChanged(double comKr)
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getComKr();
attr.setValue(comKr);
pData->setComKr(attr);
if (pData->getComKr().getValue().toDouble() != comKr) {
pData->getComKr().setValue(comKr);
}
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
@ -1043,9 +1178,9 @@ void nmPlotGraphicBinder::onGraphicRegionMarkComWChanged(double comW)
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getComW();
attr.setValue(comW);
pData->setComW(attr);
if (pData->getComW().getValue().toDouble() != comW) {
pData->getComW().setValue(comW);
}
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
@ -1060,9 +1195,9 @@ void nmPlotGraphicBinder::onGraphicRegionMarkNetToGrossChanged(double netToGross
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getNetToGross();
attr.setValue(netToGross);
pData->setNetToGross(attr);
if (pData->getNetToGross().getValue().toDouble() != netToGross) {
pData->getNetToGross().setValue(netToGross);
}
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
@ -1106,6 +1241,8 @@ void nmPlotGraphicBinder::_connectRegionMark(nmObjRegionMark* pGraphic, nmDataRe
this, SLOT(onGraphicRegionMarkNetToGrossChanged(double)));
connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicRegionMarkVisibleChanged(bool)));
connect(pData, SIGNAL(sigRegionMarkDataChanged()),
this, SLOT(onRegionMarkDataChanged()), Qt::UniqueConnection);
m_setBoundRegionMarkGraphics.insert(pGraphic);
}
@ -1130,13 +1267,19 @@ void nmPlotGraphicBinder::_disconnectRegionMark(nmObjRegionMark* pGraphic)
disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicRegionMarkVisibleChanged(bool)));
nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr);
if (pData != nullptr) {
disconnect(pData, SIGNAL(sigRegionMarkDataChanged()),
this, SLOT(onRegionMarkDataChanged()));
}
m_setBoundRegionMarkGraphics.remove(pGraphic);
}
// 从数据对象读取值,写入图元本地副本(加载时用)
// 从数据对象读取值,写入图元本地副本(加载及参数变更时用)
void nmPlotGraphicBinder::_pushRegionMarkDataToGraphic(nmObjRegionMark* pGraphic, nmDataRegionMark* pData)
{
pGraphic->blockSignals(true);
bool bOldSignalsBlocked = pGraphic->blockSignals(true);
// 储层类型:字符串 → int
if (pData->getReservoirType().getValue() == "Homogeneous") {
@ -1154,7 +1297,24 @@ void nmPlotGraphicBinder::_pushRegionMarkDataToGraphic(nmObjRegionMark* pGraphic
pts << pData->getPtPos();
pGraphic->setAllValues(pts);
pGraphic->blockSignals(false);
pGraphic->blockSignals(bOldSignalsBlocked);
refreshPropertyValue(pGraphic, "ObjRegionMark.dComW", pData->getComW().getValue());
refreshPropertyValue(pGraphic, "ObjRegionMark.dComKr", pData->getComKr().getValue());
refreshPropertyValue(pGraphic, "ObjRegionMark.NetToGross", pData->getNetToGross().getValue());
pGraphic->update();
}
// 数据参数变更 -> 同步到图元和左侧属性面板
void nmPlotGraphicBinder::onRegionMarkDataChanged()
{
nmDataRegionMark* pData = qobject_cast<nmDataRegionMark*>(sender());
if (!pData) return;
nmObjRegionMark* pGraphic = m_mapRegionMarkData.key(pData, nullptr);
if (pGraphic) {
_pushRegionMarkDataToGraphic(pGraphic, pData);
}
}
// ==================== 复合区图元 ====================
@ -1197,7 +1357,7 @@ void nmPlotGraphicBinder::createRegionForGraphic(nmObjRegion* pGraphic)
// 建立信号连接
_connectRegion(pGraphic, pData);
m_pDataMgr->notifyDataChanged();
m_pDataMgr->notifyGeometryListChanged();
}
// 从文件加载:绑定已有数据到已有图元
@ -1240,7 +1400,12 @@ void nmPlotGraphicBinder::syncRegionData(nmObjRegion* pGraphic)
if (!pData) return;
// 兜底同步:名称、位置
pData->setRegionName(pGraphic->getName());
if (pData->getRegoinName() != pGraphic->getName()) {
pData->setRegionName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyParameterObjectNameChanged();
}
}
pData->setVecPts(pGraphic->getAllValues());
// 视觉属性兜底同步:画笔宽度、填充背景色
@ -1304,9 +1469,9 @@ void nmPlotGraphicBinder::onGraphicRegionLeakageChanged(double leakage)
nmDataRegion* pData = m_mapRegionData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getRegionLeakage();
attr.setValue(leakage);
pData->setRegionLeakage(attr);
if (pData->getRegionLeakage().getValue().toDouble() != leakage) {
pData->getRegionLeakage().setValue(leakage);
}
}
void nmPlotGraphicBinder::onGraphicRegionVisibleChanged(bool bVisible)
@ -1332,6 +1497,8 @@ void nmPlotGraphicBinder::_connectRegion(nmObjRegion* pGraphic, nmDataRegion* pD
this, SLOT(onGraphicRegionLeakageChanged(double)));
connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicRegionVisibleChanged(bool)));
connect(pData, SIGNAL(sigRegionDataChanged()),
this, SLOT(onRegionDataChanged()), Qt::UniqueConnection);
m_setBoundRegionGraphics.insert(pGraphic);
}
@ -1349,15 +1516,21 @@ void nmPlotGraphicBinder::_disconnectRegion(nmObjRegion* pGraphic)
disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicRegionVisibleChanged(bool)));
nmDataRegion* pData = m_mapRegionData.value(pGraphic, nullptr);
if (pData != nullptr) {
disconnect(pData, SIGNAL(sigRegionDataChanged()),
this, SLOT(onRegionDataChanged()));
}
m_setBoundRegionGraphics.remove(pGraphic);
}
// 从数据对象读取值,写入图元本地副本(加载时用)
// 从数据对象读取值,写入图元本地副本(加载及参数变更时用)
void nmPlotGraphicBinder::_pushRegionDataToGraphic(nmObjRegion* pGraphic, nmDataRegion* pData)
{
if (!pGraphic || !pData) return;
pGraphic->blockSignals(true);
bool bOldSignalsBlocked = pGraphic->blockSignals(true);
// 流动模型:字符串 → int
if (pData->getRegionFlowModel().getValue() == "Leaky") {
@ -1374,7 +1547,22 @@ void nmPlotGraphicBinder::_pushRegionDataToGraphic(nmObjRegion* pGraphic, nmData
pGraphic->setPen(pen);
pGraphic->setBackgrdColor(pData->getBackgrdColor());
pGraphic->blockSignals(false);
pGraphic->blockSignals(bOldSignalsBlocked);
refreshPropertyValue(pGraphic, "ObjRegion.Leakage", pData->getRegionLeakage().getValue());
pGraphic->update();
}
// 数据参数变更 -> 同步到图元和左侧属性面板
void nmPlotGraphicBinder::onRegionDataChanged()
{
nmDataRegion* pData = qobject_cast<nmDataRegion*>(sender());
if (!pData) return;
nmObjRegion* pGraphic = m_mapRegionData.key(pData, nullptr);
if (pGraphic) {
_pushRegionDataToGraphic(pGraphic, pData);
}
}
// ==================== 井图元 ====================
@ -1441,15 +1629,20 @@ void nmPlotGraphicBinder::syncWellData(nmObjPointWell* pGraphic)
// 同步名称(用户在属性面板改名后,同步到数据中心和框架数据)
QString sName = pGraphic->getName();
bool bNameChanged = false;
if (!sName.isEmpty()) {
if (pData->getWellName() != sName) {
pData->setWellName(sName);
bNameChanged = true;
}
if (pWellData && pWellData->getName() != sName) {
pWellData->setName(sName);
pWellData->save();
}
}
if (bNameChanged && m_pDataMgr) {
m_pDataMgr->notifyParameterObjectNameChanged();
}
if (pWellData) {
// 数值井数据是分析侧的数据源,这里回写到框架井数据,保证保存工程树时一致。

@ -1,4 +1,4 @@
#include "zxLogInstance.h"
#include "zxLogInstance.h"
#include "iRibbonXmlCmd.h"
#include <QEvent>
#include <QMdiArea>
@ -374,6 +374,10 @@ void nmSubWndUtils::connectWellListSignals(nmDataAnalyzeManager* pDataManager,
QObject::connect(pDataManager, SIGNAL(sigWellRemoved(QString,QString)),
pParaWx, SLOT(slotWellRemoved(QString,QString)),
Qt::UniqueConnection);
// 参数对象新增、删除或改名后重建面板;队列连接避免在图元绘制过程中直接刷新。
QObject::connect(pDataManager, SIGNAL(sigGeometryListChanged()),
pParaWx, SLOT(slotGeometryListChanged()),
static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
}
bool nmSubWndUtils::fillNmDockWxs(iSubWnd* pSubWnd)

@ -484,7 +484,8 @@ void nmWxDFNGenerateDlg::generateFractures()
// 通过 Binder 创建裂缝数据并建立信号连接
nmPlotGraphicBinder* pBinder = plot->graphicBinder();
if (pBinder) {
pBinder->createCrackForGraphic(crack);
// DFN 不进入独立裂缝参数面板,批量生成时也不重复刷新对象列表。
pBinder->createCrackForGraphic(crack, false);
}
// 设置属性为 DFN
nmDataFracture* pData = pBinder ? pBinder->getCrackDataFor(crack) : nullptr;

@ -1,4 +1,4 @@

#include "zxLogInstance.h"
#include "ZxResolutionHelper.h"
#include "zxSysUtils.h"
@ -12,6 +12,11 @@
#include "nmGridRowUtils.h"
#include "nmDataAnalyzeManager.h"
#include "nmDataWellBase.h"
#include "nmDataFracture.h"
#include "nmDataFault.h"
#include "nmDataRegion.h"
#include "nmDataRegionMark.h"
#include "nmDataOutline.h"
#include "nmAttrRegistry.h"
#include <QSet>
@ -57,6 +62,57 @@ QStringList wellParasOf(const QString& wellCode, bool hasPerforation, NM_WELL_MO
return paras;
}
// XML 只定义基础参数名,运行时拼接对象编码以区分多个同类对象。
QStringList fractureParasOf(const QString& fractureCode)
{
return QStringList() << fractureCode + "_F_X0"
<< fractureCode + "_F_Y0"
<< fractureCode + "_F_X1"
<< fractureCode + "_F_Y1"
<< fractureCode + "_F_FC";
}
QStringList faultParasOf(const QString& faultCode)
{
return QStringList() << faultCode + "_FT_X0"
<< faultCode + "_FT_Y0"
<< faultCode + "_FT_X1"
<< faultCode + "_FT_Y1";
}
QStringList regionParasOf(const QString& regionCode)
{
return QStringList() << regionCode + "_R_Leakage";
}
QStringList regionMarkParasOf(const QString& regionMarkCode)
{
return QStringList() << regionMarkCode + "_RM_ComW"
<< regionMarkCode + "_RM_ComKr"
<< regionMarkCode + "_RM_NetToGross";
}
QStringList rectBoundaryParasOf(const QString& boundaryCode)
{
return QStringList() << boundaryCode + "_BR_XMin"
<< boundaryCode + "_BR_YMin"
<< boundaryCode + "_BR_XMax"
<< boundaryCode + "_BR_YMax";
}
QStringList roundBoundaryParasOf(const QString& boundaryCode)
{
return QStringList() << boundaryCode + "_BC_CenterX"
<< boundaryCode + "_BC_CenterY"
<< boundaryCode + "_BC_Radius";
}
QStringList polygonPointParasOf(const QString& pointCode)
{
return QStringList() << pointCode + "_BP_X"
<< pointCode + "_BP_Y";
}
}
nmWxParaPropertyPebi::nmWxParaPropertyPebi(QWidget* parent) :
@ -133,7 +189,7 @@ void nmWxParaPropertyPebi::initUI_HelpBox()
}
void nmWxParaPropertyPebi::refreshUIs(QStringList& listParas, bool bReserveOlds /*= true*/,
QMap<QString, QString> mapWellNames /*= QMap<QString, QString>()*/)
QMap<QString, QString> mapObjectNames /*= QMap<QString, QString>()*/)
{
if (nullptr == m_pMainLayout)
{
@ -163,7 +219,7 @@ void nmWxParaPropertyPebi::refreshUIs(QStringList& listParas, bool bReserveOlds
connect(m_pGridItemUtils, SIGNAL(sigHelpMsg(QString&)),
this, SLOT(slotHelpMsg(QString&)));
m_pMainLayout->addWidget(m_pGridItemUtils);
m_pGridItemUtils->setWellNames(mapWellNames);
m_pGridItemUtils->setWellNames(mapObjectNames);
m_pGridItemUtils->buildRowUtils(listParas, false, this);
// 恢复原有的参数内容
@ -198,7 +254,7 @@ void nmWxParaPropertyPebi::restoreOldParas(QMap<QString, QVariant>& map)
QString sPara = iter.key();
iParameter* p = _paraHelper->getPara(sPara, s_Nm_Serie);
// 带前缀的井参数(如 "W001_W_X")在 XML 中查不到,需剥掉 wellCode 前缀
// 带对象编码前缀的参数在 XML 中查不到,需先剥掉运行时前缀。
if (nullptr == p)
{
QString sBase = m_pGridItemUtils->stripWellPrefix(sPara);
@ -249,9 +305,10 @@ void nmWxParaPropertyPebi::rebuildAllParas()
return;
m_pDataManager->syncWellAttrs();
m_pDataManager->syncGeometryAttrs();
QStringList listParas = reservoirParas();
QMap<QString, QString> mapWellNames;
QMap<QString, QString> mapObjectNames;
QSet<QString> addedWellCodes;
const QVector<nmDataWellBase*> wells = m_pDataManager->getWellDataList();
foreach (nmDataWellBase* pWell, wells)
@ -264,13 +321,105 @@ void nmWxParaPropertyPebi::rebuildAllParas()
continue;
addedWellCodes.insert(sCode);
mapWellNames[sCode] = pWell->getWellName();
mapObjectNames[sCode] = pWell->getWellName();
listParas << wellParasOf(sCode,
pWell->getPerforationCount() > 0,
pWell->getWellType());
}
refreshUIs(listParas, false, mapWellNames);
int fractureIndex = 0;
const QVector<nmDataFracture*> fractures = m_pDataManager->getFractureDataList();
foreach (nmDataFracture* pFracture, fractures)
{
// DFN 裂缝由专用功能批量管理,不作为独立裂缝显示。
if (pFracture == nullptr || pFracture->getFractureType().getValue().toString() == "DFN")
{
continue;
}
const QString sCode = QString("FRAC%1").arg(++fractureIndex, 4, 10, QChar('0'));
mapObjectNames[sCode] = pFracture->getFractureName();
listParas << fractureParasOf(sCode);
}
const QVector<nmDataFault*> faults = m_pDataManager->getFaultDataList();
for (int i = 0; i < faults.size(); ++i)
{
nmDataFault* pFault = faults[i];
if (pFault == nullptr)
continue;
const QString sCode = QString("FAULT%1").arg(i + 1, 4, 10, QChar('0'));
mapObjectNames[sCode] = pFault->getFaultName();
listParas << faultParasOf(sCode);
}
const QVector<nmDataRegion*> regions = m_pDataManager->getRegionDataList();
for (int i = 0; i < regions.size(); ++i)
{
nmDataRegion* pRegion = regions[i];
if (pRegion == nullptr)
continue;
const QString sCode = QString("REGION%1").arg(i + 1, 4, 10, QChar('0'));
mapObjectNames[sCode] = pRegion->getRegoinName();
listParas << regionParasOf(sCode);
}
const QVector<nmDataRegionMark*> regionMarks = m_pDataManager->getRegionMarkDataList();
for (int i = 0; i < regionMarks.size(); ++i)
{
nmDataRegionMark* pRegionMark = regionMarks[i];
if (pRegionMark == nullptr)
continue;
const QString sCode = QString("RMARK%1").arg(i + 1, 4, 10, QChar('0'));
mapObjectNames[sCode] = pRegionMark->getRegionMarkName();
listParas << regionMarkParasOf(sCode);
}
nmDataOutline* pOutline = m_pDataManager->getOutlineData();
if (pOutline != nullptr)
{
QString sOutlineName = pOutline->getName();
if (pOutline->getOutlineType() == NM_Rect_Outline_Type)
{
if (sOutlineName.isEmpty())
{
sOutlineName = tr("RectangleOutline");
}
const QString sCode = "BOUNDARY";
mapObjectNames[sCode] = sOutlineName;
listParas << rectBoundaryParasOf(sCode);
}
else if (pOutline->getOutlineType() == NM_Round_Outline_Type)
{
if (sOutlineName.isEmpty())
{
sOutlineName = tr("CircleOutline");
}
const QString sCode = "BOUNDARY";
mapObjectNames[sCode] = sOutlineName;
listParas << roundBoundaryParasOf(sCode);
}
else if (pOutline->getOutlineType() == NM_Polygon_Outline_Type)
{
if (sOutlineName.isEmpty())
{
sOutlineName = tr("PolygonOutline");
}
const QString sBoundaryCode = "BOUNDARY";
mapObjectNames[sBoundaryCode] = sOutlineName;
for (int i = 0; i < pOutline->getOutlinePointCount(); ++i)
{
const QString sPointCode = QString("BVERT%1").arg(i + 1, 4, 10, QChar('0'));
mapObjectNames[sPointCode] = QString("%1 %2").arg(tr("Point")).arg(i + 1);
listParas << polygonPointParasOf(sPointCode);
}
}
}
refreshUIs(listParas, false, mapObjectNames);
nmAttrRegistry* pReg = m_pDataManager->getAttrRegistry();
if (pReg)
@ -390,3 +539,9 @@ void nmWxParaPropertyPebi::slotWellRemoved(QString wellCode, QString wellName)
Q_UNUSED(wellName);
rebuildAllParas();
}
// 参数对象新增、删除或改名后,按当前数据完整重建对象分组。
void nmWxParaPropertyPebi::slotGeometryListChanged()
{
rebuildAllParas();
}

Loading…
Cancel
Save