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/Include/nmNum/nmSubWxs/nmWxWellboreTrajectoryDispl...

1020 lines
41 KiB
C

#ifndef NMWXWELLBORETRAJECTORYDISPLAY_H
#define NMWXWELLBORETRAJECTORYDISPLAY_H
#include <QWidget>
#include "nmSubWxs_global.h"
#include "nmDefines.h"
class nmDataWellBase;
class QButtonGroup;
class QRadioButton;
class QToolBar;
class QStackedWidget;
class QGroupBox;
class QLabel;
class QMouseEvent;
class QWheelEvent;
#include <QGraphicsRectItem>
#include <QGraphicsEllipseItem>
#include <QGraphicsLineItem>
#include <QGraphicsPathItem>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
// 基础图元类
// 井筒点 (用于垂直井的俯视图,或井筒在纵截面的中心点)
class nmWellborePointGraphicsItem : public QObject, public QGraphicsEllipseItem
{
Q_OBJECT
public:
explicit nmWellborePointGraphicsItem(QGraphicsItem *parent = nullptr);
// 可添加设置特定属性的方法,如颜色、大小等
void setStyle(const QPen& pen, const QBrush& brush);
signals:
// 井点中心位置变化信号,移动时实时发出
void sigPositionChanging(const QPointF& newCenterScenePos);
// 拖动结束信号 (仅在鼠标释放时发出)
void sigDragFinished(const QPointF& finalCenterScenePos);
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
private:
bool m_bIsDragging; // 标记是否正在拖动
QPointF m_dragStartPos; // 记录鼠标按下时的场景坐标
QPointF m_originalPos; // 记录拖动开始时图元的原始位置(左上角)
};
// 井筒线 (用于水平井的俯视图,或纵截面视图的井筒段)
class nmWellboreLineGraphicsItem : public QObject, public QGraphicsLineItem
{
Q_OBJECT
public:
explicit nmWellboreLineGraphicsItem(QGraphicsItem *parent = nullptr);
// 可添加设置特定属性的方法
void setStyle(const QPen& pen);
};
enum PerforationHandleType {
StartHandle, // 起点手柄类型
EndHandle // 终点手柄类型
};
// 射孔手柄类
class nmPerforationHandleItem : public QGraphicsRectItem
{
public:
// 构造函数:需要手柄类型和父级图形项
explicit nmPerforationHandleItem(PerforationHandleType type, QGraphicsItem *parent = nullptr);
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QRectF boundingRect() const override;
private:
PerforationHandleType m_handleType; // 存储手柄的类型
};
// 定义射孔段的当前交互模式
enum PerforationInteractionMode {
Normal, // 正常模式,无特殊交互(鼠标未按下或未拖动)
ResizeStart, // 调整起点MD (用户正在拖动射孔的起点手柄)
ResizeEnd, // 调整终点MD (用户正在拖动射孔的终点手柄)
MoveItem // 移动整个射孔项 (用户正在拖动射孔本体以整体移动)
};
class nmDataPerforation;
// 射孔
class nmPerforationGraphicsItem : public QObject, public QGraphicsRectItem
{
Q_OBJECT
public:
explicit nmPerforationGraphicsItem(nmDataPerforation *pPerData, NM_WELL_MODEL wellType, double wellboreStartAbsoluteMd, double totalWellboreMdLength, QGraphicsItem *parent = nullptr);
~nmPerforationGraphicsItem();
// 启用/禁用编辑模式:在编辑模式下,手柄可见且可拖动
void setEditMode(bool enable);
// 更新图形项(包括射孔本体和手柄)的位置和大小。
// 这个函数是响应数据模型变化的最终更新,它会读取 Model 的真实数据进行渲染。
void updateGraphics();
// 获取关联的射孔段数据
nmDataPerforation* getPerforationData();
// 当井筒视觉或MD信息变化时更新射孔段内部存储的井筒相关数据
void updateWellboreVisuals(const QPointF& wellboreStartScene, const QPointF& wellboreEndScene, double wellboreStartAbsoluteMd, double totalWellboreMdLength);
// 根据裂缝临时位置进行裁剪,实时预览
void updateGraphicsForPreview(qreal fractureTopMD, qreal fractureBottomMD);
// 根据MD值获取井筒上的场景点
QPointF getScenePointFromMd(double md) const;
// 根据场景中的点,找到井筒上最近的点,并返回对应的 MD 值
double getMdFromScenePointOnWellbore(const QPointF& scenePoint) const;
// 获取被裁剪后的MD范围
double getCroppedMdStart();
double getCroppedMdEnd();
// 用于在井身拖动时,根据新井身长度进行实时预览,目前是多段压裂水平井需要
void updateVisualsForWellboreDrag(const QPointF& wellboreStartScene, const QPointF& wellboreEndScene,
double wellboreStartAbsoluteMd, double originalWellboreLength,
double newWellboreLength);
signals:
// 射孔段拖动结束后请求更新数据模型MD位置
void sigRequestPerforationMdUpdate(nmDataPerforation* pPerforationData, double proposedMdStart, double proposedMdEnd);
protected:
// 重写包围盒计算,需要包含射孔本体和手柄的区域,确保全部被绘制和点击检测到
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QRectF boundingRect() const override;
// 重写鼠标事件,用于处理用户交互(按下、移动、释放)
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
private:
nmDataPerforation* m_pPerforationData; // 关联的射孔段数据
bool m_bEditable; // 是否处于编辑状态
PerforationInteractionMode m_eCurrentInteractionMode; // 当前交互模式
QPointF m_lastMouseScenePos; // 鼠标按下时的场景坐标 (用于拖动计算)
double m_initialMdStart; // 拖动开始时的射孔起点MD
double m_initialMdEnd; // 拖动开始时的射孔终点MD
bool m_isDragging; // 标志:当前是否处于拖动操作中 (鼠标按下并移动)
double m_tempDragMdStart; // 拖动过程中视图临时显示的起点MD (只用于局部渲染)
double m_tempDragMdEnd; // 拖动过程中视图临时显示的终点MD (只用于局部渲染)
// 射孔和手柄的样式和尺寸
double m_dPerWidth; // 射孔的视觉宽度
QPen m_handlePen; // 手柄的边框画笔
QBrush m_handleBrush; // 手柄的填充画刷
qreal m_handleSize; // 手柄的尺寸 (正方形的边长)
QPointF m_wellboreStartScenePoint; // 井筒在场景中的起始点
QPointF m_wellboreEndScenePoint; // 井筒在场景中的结束点
double m_wellboreStartAbsoluteMd; // 井筒的绝对MD起始值
double m_totalWellboreMdLength; // 井筒的总MD长度
NM_WELL_MODEL m_eWellType; // 井筒类型
QLineF m_wellboreVisualLine; // 存储井筒的视觉线段
// 射孔手柄 QGraphicsRectItem 成员
nmPerforationHandleItem* m_pStartHandle; // 指向起点手柄的指针
nmPerforationHandleItem* m_pEndHandle; // 指向终点手柄的指针
// 存储被裁剪后的 MD 范围
double m_dCroppedMdStart;
double m_dCroppedMdEnd;
// 私有辅助函数:更新射孔本体和手柄的几何形状
// 这个函数现在必须接受两个MD值参数用于绘制
void updatePerforationAndHandleGeometry(double mdStartToRender, double mdEndToRender);
};
// 裂缝手柄类[线]
class nmFractureLineHandleItem : public QObject, public QGraphicsRectItem
{
Q_OBJECT
public:
explicit nmFractureLineHandleItem(QGraphicsItem *parent = nullptr);
// 信号:通知父项或控制器手柄位置发生变化
// 参数可以包括手柄自身指针和新的局部位置
signals:
void handlePositionChanged(nmFractureLineHandleItem* handle, QPointF newPos, bool IsDragging);
protected:
// 重写鼠标事件
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QRectF boundingRect() const override;
private:
QPointF m_lastMousePos; // 记录上次鼠标位置,用于计算移动增量
bool m_bIsDragging; // 标志:是否正在拖动
};
// 针对多段压裂水平井的多段裂缝图元
class nmHorizontalFractureGraphicsItem : public QObject, public QGraphicsLineItem
{
Q_OBJECT
signals:
// 信号通知父项nmHorizontalFracturedWellTopViewItem裂缝半长发生变化
// newHalfLength: 新的裂缝半长
// isDragging: 是否正在拖动
// fractureIndex: 当前是哪条裂缝(在父列表中)的索引,用于数据模型更新
void fractureHalfLengthChanged(double newHalfLength, bool isDragging, int fractureIndex);
public:
explicit nmHorizontalFractureGraphicsItem(int index, QGraphicsItem *parent = nullptr);
void setStyle(const QPen& pen);
// 更新裂缝线和手柄的位置
void updateFractureLineAndHandles(const QPointF& p1, const QPointF& p2);
// 设置井筒的场景坐标信息和方向向量
void setWellboreInfo(const QPointF& wellboreStartScene, const QPointF& wellboreEndScene);
// 设置编辑模式,控制手柄可见性
void setEditMode(bool enable);
// 获取当前裂缝在父类列表中的索引
int getFractureIndex() const { return m_fractureIndex; }
private slots:
// 接收手柄的信号
void onHandlePositionChanged(nmFractureLineHandleItem* handle, QPointF newHandlePosInParent, bool isDragging);
private:
nmFractureLineHandleItem* m_pHandle1;
nmFractureLineHandleItem* m_pHandle2;
bool m_bEditMode;
int m_fractureIndex; // 当前裂缝在 nmHorizontalFracturedWellTopViewItem 中的索引
QPointF m_wellboreStartScene; // 井筒起始点 (场景坐标)
QPointF m_wellboreEndScene; // 井筒结束点 (场景坐标)
QPointF m_wellboreDirection; // 井筒方向向量 (归一化,场景坐标)
};
class nmDataVerticalFracturedWell;
// 裂缝 (通常是直线)
class nmFractureLineGraphicsItem : public QObject, public QGraphicsLineItem
{
Q_OBJECT
public:
explicit nmFractureLineGraphicsItem(QGraphicsItem *parent = nullptr);
// 可添加设置特定属性的方法
void setStyle(const QPen& pen);
// 设置为编辑模式
void setEditMode(bool enable);
signals:
// 拖拽结束后,发送裂缝几何位置
void sigFractureGeometryChanged(double newHalfLength, double newAngle);
private slots: // 用于接收手柄的信号
void onHandlePositionChanged(nmFractureLineHandleItem* handle, QPointF newPos, bool isDragging);
private:
// 创建矩形手柄
void createHandles();
// 更新手柄位置
void updateHandlesPosition();
// 更新裂缝位置
void updateFractureFromHandle(nmFractureLineHandleItem* draggedHandle, const QPointF& newHandleScenePos, bool isDragging);
private:
bool m_bEditMode; // 表示当前是否处于编辑模式
// 裂缝手柄
nmFractureLineHandleItem* m_pHandle1;
nmFractureLineHandleItem* m_pHandle2;
};
// 枚举手柄的类型,用于父项判断如何缩放
enum HandleType {
NoHandle, // 没有拖动手柄
TopLeftHandle, // 左上角手柄
TopMiddleHandle, // 顶边中点手柄
TopRightHandle, // 右上角手柄
MiddleLeftHandle, // 左边中点手柄
MiddleRightHandle, // 右边中点手柄
BottomLeftHandle, // 左下角手柄
BottomMiddleHandle, // 底边中点手柄
BottomRightHandle // 右下角手柄
};
// nmFractureHandleItem 类继承自 QObject 和 QGraphicsRectItem
// 代表裂缝矩形上的一个可拖动的手柄
class nmFractureRectHandleItem : public QObject, public QGraphicsRectItem {
Q_OBJECT
public:
// 构造函数,需要手柄类型和父项
explicit nmFractureRectHandleItem(HandleType type, QGraphicsItem *parent = nullptr);
~nmFractureRectHandleItem();
// 获取手柄类型
HandleType getHandleType();
signals:
// 信号:手柄开始拖动时发出
void handlePressed(HandleType type, QPointF scenePos);
// 信号:手柄正在拖动时发出
void handleMoved(HandleType type, QPointF scenePos);
// 信号:手柄释放时发出
void handleReleased(HandleType type, QPointF scenePos);
protected:
// 重写鼠标事件处理函数,用于捕获手柄的交互
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QRectF boundingRect() const override;
private:
HandleType m_eHandleType; // 当前手柄的类型
QPointF m_lastMouseScenePos; // 记录鼠标在场景坐标系中的位置,用于计算位移
};
// 绘制截面下的裂缝[矩形]
class nmFractureRectGraphicsItem : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
explicit nmFractureRectGraphicsItem(nmDataVerticalFracturedWell* pDataWell, QGraphicsItem *parent = nullptr);
~nmFractureRectGraphicsItem();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
// 设置编辑模式的公共接口
void setEditMode(bool bEdit);
signals:
// 携带裂缝新的顶部和底部MD
void sigRequestFractureRectUpdate(qreal newTopMD, qreal newBottomMD);
// 拖动过程中实时发送
void sigFractureGeometryChanged(qreal fractureTopMD, qreal fractureBottomMD);
private slots:
// 槽函数响应手柄nmFractureHandleItem发出的信号
void onHandlePressed(HandleType type, QPointF scenePos);
void onHandleMoved(HandleType type, QPointF scenePos);
void onHandleReleased(HandleType type, QPointF scenePos);
private:
void updateFractureGeometry(); // 根据数据更新裂缝矩形的位置和大小
void updateHandlePositions(); // 更新所有手柄的位置,使其与裂缝矩形对齐
void createHandles(); // 创建并初始化八个手柄子项
void destroyHandles(); // 销毁所有手柄子项
private:
nmDataVerticalFracturedWell* m_pDataWell; // 指向裂缝数据模型的指针
bool m_bEditMode; // 是否处于编辑模式
QRectF m_fractureRect; // 裂缝矩形的当前几何信息(本地坐标系)
// 用于手柄的成员变量
QVector<nmFractureRectHandleItem *> m_handles; // 存储八个手柄的指针
qreal m_handleSize; // 手柄的大小(像素)
HandleType m_eCurrentHandle; // 当前正在拖动的手柄类型
QPointF m_lastMouseScenePos; // 记录鼠标在场景坐标系中的位置,用于拖动计算
// 储层边界信息,用于限制裂缝的高度
qreal m_minReservoirTop;
qreal m_maxReservoirBottom;
};
#include <QList>
#include "nmDataLayer.h"
#include <QVector>
// 绘制具有无限水平宽度感的储层组
class nmReservoirGraphicsItems : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
explicit nmReservoirGraphicsItems(QGraphicsItem *parent = nullptr);
~nmReservoirGraphicsItems();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0); // Qt 4 兼容的 nullptr 替代
void setReservoirLayers(const QVector<nmDataLayer*>& layers);
// 获取上下深度
qreal getMinLayerTop();
qreal getMaxLayerBottom();
protected:
QList<nmDataLayer*> m_internalLayers; // 存储内部的层数据
// 缓存层数据的最小顶深度和最大底深度
// qreal m_minLayerTop;
// qreal m_maxLayerBottom;
};
#include <QGraphicsItemGroup>
#include <QGraphicsScene>
// 抽象基类,用于组合和管理特定视图下的井筒基本图元
class nmAbstractWellboreVisual : public QObject, public QGraphicsItemGroup
{
Q_OBJECT
public:
explicit nmAbstractWellboreVisual(QGraphicsItem *parent = nullptr);
virtual ~nmAbstractWellboreVisual();
// 核心虚函数:根据几何数据来创建和更新内部的基本图形项
virtual void updateGeometryVisuals(nmDataWellBase *pDataWell) = 0;
// 获取当前渲染的井数据实例
nmDataWellBase* getWellData();
// 删除指定的射孔图形项并从内部列表中移除
void removePerforationVisual(nmPerforationGraphicsItem* itemToRemove);
// 清空所有射孔段图元
void clearAllPerforationItems();
protected:
// 清除所有子项的通用方法
void clearAllChildItems();
// 用于管理和追踪创建的基本图元,以便在更新时可以清除旧的
QList<nmWellborePointGraphicsItem*> m_listPoints; // 井筒点
QList<nmWellboreLineGraphicsItem*> m_listLines; // 井筒线
QList<nmPerforationGraphicsItem*> m_listPerforations; // 射孔段
QList<nmFractureLineGraphicsItem*> m_listLineFractures; // 裂缝[线]
QList<nmFractureRectGraphicsItem*> m_listRectFractures; // 裂缝[矩形]
// 添加基础图元
void addPoint(nmWellborePointGraphicsItem* item);
void addLine(nmWellboreLineGraphicsItem* item);
void addPerforation(nmPerforationGraphicsItem* item);
void addFractureLine(nmFractureLineGraphicsItem* item);
void addFractureRect(nmFractureRectGraphicsItem* item);
// 指向数据模型的指针不拥有其内存因此使用const
nmDataWellBase *m_pDataWell;
};
// 垂直井 - 俯视图
class nmVerticalWellTopViewItem : public nmAbstractWellboreVisual
{
Q_OBJECT
public:
explicit nmVerticalWellTopViewItem(QGraphicsItem *parent = nullptr);
// 根据几何数据更新图元的可视化表示
void updateGeometryVisuals(nmDataWellBase *pDataWell) override;
void setEditMode(bool enabled); // 编辑模式控制
QPointF getWellPointPosition() const; // 获取当前绿点位置
signals:
// 井点被拖动结束后的信号
void sigWellborePointDragFinished(const QPointF& newScenePos);
private slots:
// 接收井点位置变化的信号,更新虚线连接
void slotUpdateDashLine(const QPointF& newPos);
// 接收井点拖动完成的信号,并转发给控制器
void slotWellborePointDragFinished(const QPointF& finalCenterScenePos);
private:
nmWellborePointGraphicsItem* m_pWellPoint; // 绿色可移动点
nmWellborePointGraphicsItem* m_pOriginalPoint; // 红色固定点(编辑时创建)
QGraphicsLineItem* m_pDashLine; // 虚线连接
};
// 垂直井 - 纵截面视图 (组合图元)
class nmVerticalWellCrossSectionItem : public nmAbstractWellboreVisual
{
Q_OBJECT
public:
explicit nmVerticalWellCrossSectionItem(QGraphicsItem *parent = nullptr);
// 根据几何数据更新图元的可视化表示
void updateGeometryVisuals(nmDataWellBase *pDataWell) override;
// 射孔段编辑状态控制
void setPerforationEditMode(bool enabled);
signals:
// 射孔被拖动结束后的信号,转发给主视图
void sigPerforationDragFinished(nmDataPerforation* pPerforationData, double proposedMdStart, double proposedMdEnd);
};
// 垂直裂缝井 - 俯视图
class nmVerticalFracturedWellTopViewItem : public nmAbstractWellboreVisual
{
Q_OBJECT
public:
explicit nmVerticalFracturedWellTopViewItem(QGraphicsItem *parent = nullptr);
// 根据几何数据更新图元的可视化表示
void updateGeometryVisuals(nmDataWellBase *pDataWell) override;
void setEditMode(bool enabled); // 编辑模式控制
signals:
// 拖拽结束后,发送裂缝几何位置
void sigFracturePosChanged(double newHalfLength, double newAngle);
private:
nmFractureLineGraphicsItem* m_pFracture; // 裂缝
};
// 垂直裂缝井 - 纵截面视图 (组合图元)
class nmVerticalFracturedWellCrossSectionItem : public nmAbstractWellboreVisual
{
Q_OBJECT
public:
explicit nmVerticalFracturedWellCrossSectionItem(QGraphicsItem *parent = nullptr);
// 根据几何数据更新图元的可视化表示
void updateGeometryVisuals(nmDataWellBase *pDataWell) override;
// 设置裂缝编辑模式
void setFractureEditMode(bool enabled);
// 射孔段编辑状态控制
void setPerforationEditMode(bool enabled);
// 获取矩形裂缝MD位置
QRectF getFractureMD();
signals:
// 射孔被拖动结束后的信号,转发给主视图
void sigPerforationDragFinished(nmDataPerforation* pPerforationData, double proposedMdStart, double proposedMdEnd);
// 将裂缝的垂直范围变化请求转发给控制器
void sigRequestFractureRectUpdate(qreal fractureTopMD, qreal fractureBottomMD);
// 拖动裂缝结束后,将更新后的射孔数据传递给控制器
// QMap<数据指针, <起始MD, 结束MD>>
void sigFractureDragFinished(const QMap<nmDataPerforation*, QPair<double, double>>& updatedPerforations);
public slots:
// 响应裂缝垂直范围变化的槽函数,用于动态更新和约束射孔段
void slotFractureConstraintChanged(qreal fractureTopMD, qreal fractureBottomMD);
// 拖动裂缝结束后,调用此槽函数收集数据并发出信号
void slotFractureDragFinished(qreal fractureTopMD, qreal fractureBottomMD);
private:
// 增量更新射孔图元显示
void updatePerforationChildGraphics();
private:
nmFractureRectGraphicsItem* m_pRectFracture;
// 存储 nmDataPerforation 对象与 nmPerforationGraphicsItem 的映射
QMap<nmDataPerforation*, nmPerforationGraphicsItem*> m_mapPerforationItem;
};
// 井筒末端拖动手柄
class nmWellboreEndHandleGraphicsItem : public QObject, public QGraphicsRectItem
{
Q_OBJECT
signals:
// 信号:通知父项或其他控制器手柄在场景中的新位置
void handlePositionChanged(QPointF newScenePos, bool isDragging);
public:
explicit nmWellboreEndHandleGraphicsItem(QGraphicsItem *parent = nullptr);
protected:
// 重写鼠标事件以实现拖动功能
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
private:
QPointF m_lastMouseScenePos; // 记录上次鼠标位置,用于计算移动增量
};
class nmDataHorizontalFracturedWell;
// 多段压裂水平井 - 俯视图
class nmHorizontalFracturedWellTopViewItem : public nmAbstractWellboreVisual
{
Q_OBJECT
public:
explicit nmHorizontalFracturedWellTopViewItem(QGraphicsItem *parent = nullptr);
// 根据几何数据更新图元的可视化表示
void updateGeometryVisuals(nmDataWellBase *pDataWell) override;
void setEditMode(bool enabled); // 编辑模式控制
// 射孔段编辑状态控制
void setPerforationEditMode(bool enabled);
// 获取井筒线
QLineF getWellboreLine();
signals:
// 射孔被拖动结束后的信号,转发给主视图
void sigPerforationDragFinished(nmDataPerforation* pPerforationData, double proposedMdStart, double proposedMdEnd);
// 将裂缝半长变化转发给控制器
void sigFractureHalfLengthChanged(double newHalfLength);
// 井身终点位置发生变化,转发给控制器
void sigWellboreDragFinished(QPointF newScenePos);
private slots:
// 接收井筒末端拖动手柄的位置变化信号
void onEndHandleMoved(QPointF newScenePos, bool isDragging);
// 接收单个裂缝图元发出的半长变化信号
void onSingleFractureHalfLengthChanged(double newHalfLength, bool isDragging, int fractureIndex);
private:
nmWellboreLineGraphicsItem* m_pWellboreLine; // 用于表示井筒的线段
nmWellboreEndHandleGraphicsItem* m_pEndHandle; // 用于表示井筒末端的拖动手柄
QList<nmHorizontalFractureGraphicsItem*> m_listFractures; // 多段压裂水平井裂缝列表
bool m_bEditMode; // 当前编辑状态
QVector<double> m_vecFractureMds; // 缓存裂缝的MD值
};
// 多段压裂水平井裂缝纵截面图元
class nmCrossSectionFractureItem : public QObject, public QGraphicsLineItem
{
Q_OBJECT
public:
explicit nmCrossSectionFractureItem(int fractureIndex, QGraphicsItem *parent = nullptr);
~nmCrossSectionFractureItem();
// 更新裂缝视觉:新增 min/max 储层深度作为约束参数
void updateFractureVisuals(double fractureXPosition, double midPointY, double fractureHeight,
double minReservoirDepth, double maxReservoirDepth);
// 设置编辑模式,控制把手可见性及拖动能力,同时禁用不必要的视觉效果
void setEditMode(bool enable);
signals:
// 同时传递裂缝高度和中点Y坐标
void fractureGeometryChanged(double newHeight, double newMidPointY, bool isDragging, int fractureIndex);
protected:
// 覆盖鼠标事件以启用图元整体拖动
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
// 如果需要更精细控制 ItemIsSelectable 后的选中框,可以重写 paint
// void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
private slots:
// 槽函数:响应把手位置变化(用于调整高度)
void onHandlePositionChanged(nmFractureLineHandleItem* handle, QPointF newHandlePosInParent, bool isDragging);
private:
nmFractureLineHandleItem* m_pTopHandle; // 垂直裂缝的顶部把手
nmFractureLineHandleItem* m_pBottomHandle; // 垂直裂缝的底部把手
bool m_bEditMode; // 当前编辑模式状态
int m_fractureIndex; // 裂缝的索引,用于识别
// 存储当前裂缝的几何信息,方便内部计算和信号发出
double m_currentFractureXPosition; // 裂缝的X坐标 (MD)
double m_currentFractureMidPointY; // 裂缝中心点的Y坐标 (深度)
double m_currentFractureHeight; // 裂缝的总高度
// 储层深度限制
double m_minReservoirDepth;
double m_maxReservoirDepth;
QPointF m_lastMousePos; // 存储上次鼠标位置,用于拖动计算
bool m_isDraggingBody; // 标志位,指示是否正在拖动裂缝本体
};
// 多段压裂水平井 - 纵截面视图 (组合图元)
class nmHorizontalFracturedWellCrossSectionItem : public nmAbstractWellboreVisual
{
Q_OBJECT
public:
explicit nmHorizontalFracturedWellCrossSectionItem(QGraphicsItem *parent = nullptr);
// 根据几何数据更新图元的可视化表示
void updateGeometryVisuals(nmDataWellBase *pDataWell) override;
// 设置编辑模式
void setEditMode(bool enabled);
signals:
// 转发裂缝的高度和中点高度给控制器
void sigFractureGeometryChanged(double newHeight, double newMidPointY);
private slots:
// 接收更新后的裂缝几何位置
void onSingleFractureGeometryChanged(double newHeight, double newMidPointY, bool isDragging, int fractureIndex);
private:
nmDataHorizontalFracturedWell *m_pHFWellData; // 指向水平压裂井数据的特定指针
QList<nmCrossSectionFractureItem*> m_listCrossSectionFractures; // 裂缝图元列表
nmWellboreLineGraphicsItem* m_pWellboreLine; // 井筒线图元指针
nmReservoirGraphicsItems* m_pReservoirsItem; // 储层图元指针,用于获取最大底部深度
bool m_bEditMode; // 编辑模式标志
};
#include <QGraphicsView> // QGraphicsView 是显示 QGraphicsScene 的部件
#include <QGraphicsScene> // QGraphicsScene 管理图形项
#include <QSharedPointer> // 用于管理 WellboreGeometry 的生命周期
class nmDefine;
// 抽象井筒视图基类
// 提供了所有井筒视图的通用功能和接口
class nmAbstractWellboreView : public QGraphicsView
{
Q_OBJECT // 启用Qt的元对象系统
public:
explicit nmAbstractWellboreView(QWidget *parent = nullptr); // 构造函数
virtual ~nmAbstractWellboreView(); // 虚析构函数
// 更新视图的核心方法,根据传入的几何数据模型来更新显示
// 纯虚函数,由子类实现具体视图的更新逻辑
virtual void updateView(nmDataWellBase* geometry) = 0;
// 缩放视图
void zoomIn();
void zoomOut();
// 重置视图变换,纯虚函数,需要子类自己实现
virtual void resetViewTransform() = 0;
signals:
// 添加射孔信号,发送给主视图,发送信号时需要根据井类型+视角共同决定传入哪些参数
void sigRequestAddPerforation(const QPointF& scenePos,
double fractureTopMd = -1.0,
double fractureBottomMd = -1.0,
const QLineF& wellboreVisualLine = QLineF());
// 请求控制器删除射孔的信号
// 参数是待删除射孔的数据指针
void sigRequestDeletePerforation(nmDataPerforation* pPerforationData);
// 当鼠标在视图上移动时发出的信号,提供转换后的场景坐标
void mouseCoordinatesChanged(double x, double y);
void mouseEnteredView(); // 鼠标进入视图区域时发射
void mouseLeftView(); // 鼠标离开视图区域时发射
protected:
// 重写鼠标移动事件以发出坐标信号
void mouseMoveEvent(QMouseEvent *event) override;
// 重写鼠标进入/离开事件以控制鼠标坐标标签
void enterEvent(QEvent *event) override;
void leaveEvent(QEvent *event) override;
// 重写滚轮事件以实现缩放
void wheelEvent(QWheelEvent *event) override;
protected:
QGraphicsScene *m_scene; // 视图所关联的图形场景
nmAbstractWellboreVisual *m_currentWellboreVisual; // 当前场景中显示的井筒组合图元
// 设置场景(在构造函数中调用)
void setupScene();
// 清理旧的井筒图元并准备场景以显示新的图元
void clearAndPrepareScene();
// 工厂方法:根据井类型创建特定视图下的组合图元实例
// 纯虚函数,由子类实现
virtual nmAbstractWellboreVisual* createWellboreVisual(NM_WELL_MODEL type) = 0;
};
// === 内部定义的井筒轨迹俯视图类 ===
class nmWxWellboreTopView : public nmAbstractWellboreView
{
Q_OBJECT
public:
explicit nmWxWellboreTopView(QWidget *parent = nullptr);
// 重写基类的更新视图方法,实现俯视图的更新逻辑
void updateView(nmDataWellBase* geometry) override;
// 传递编辑状态
void setEditMode(bool enabled);
// 传递射孔段编辑状态
void setPerForationEditMode(bool enabled);
// 设置添加射孔段模式
void setAddPerforationMode(bool enable);
// 设置删除模式
void setPerforationDeleteMode(bool enabled);
// 重置视图变换
void resetViewTransform() override;
signals:
// 井筒点在俯视图中被拖拽 (只在拖动结束后发射,转发给主视图)
void sigWellborePointMovedInTopView(const QPointF& newScenePos);
// 射孔在俯视图中被拖拽 (只在拖动结束后发射,转发给控制器)
void sigPerforationDragInTopView(nmDataPerforation* pPerforationData, double proposedMdStart, double proposedMdEnd);
// 拖拽结束后,发送裂缝几何位置
void sigFracturePosChangedInTopView(double newHalfLength, double newAngle);
// 将裂缝半长变化转发给控制器
void sigFractureHalfLengthChanged(double newHalfLength);
// 井身终点位置发生变化,转发给控制器
void sigWellboreDragFinished(QPointF newScenePos);
protected:
// 重写工厂方法,根据井类型创建适合俯视图的组合图元
nmAbstractWellboreVisual* createWellboreVisual(NM_WELL_MODEL type) override;
void mousePressEvent(QMouseEvent *event) override; // 重写鼠标按下事件
private:
bool m_bIsInAddPerforationMode; // 视图内部的添加模式状态
bool m_bIsInDeletePerforationMode; // 删除射孔模式标志
};
// === 内部定义的井筒轨迹纵截面视图类 ===
class nmWxWellboreCrossSectionView : public nmAbstractWellboreView
{
Q_OBJECT
public:
explicit nmWxWellboreCrossSectionView(QWidget *parent = nullptr);
// 重写基类的更新视图方法,实现纵截面视图的更新逻辑
void updateView(nmDataWellBase* geometry) override;
// 传递射孔段编辑状态
void setPerForationEditMode(bool enabled);
// 设置添加射孔段模式
void setAddPerforationMode(bool enable);
// 设置删除模式
void setPerforationDeleteMode(bool enabled);
// 重置视图变换
void resetViewTransform() override;
// 设置裂缝编辑模式
void setFractureEditMode(bool enabled);
signals:
// 射孔在截面图中被拖拽 (只在拖动结束后发射,转发给控制器)
void sigPerforationDragInCrossView(nmDataPerforation* pPerforationData, double proposedMdStart, double proposedMdEnd);
// 将裂缝的垂直范围变化请求转发给控制器
void sigRequestFractureRectUpdate(qreal fractureTopMD, qreal fractureBottomMD);
// 拖动裂缝结束后,将更新后的射孔数据传递给控制器
// QMap<数据指针, <起始MD, 结束MD>>
void sigFractureDragFinished(const QMap<nmDataPerforation*, QPair<double, double>>& updatedPerforations);
// 转发裂缝的高度和中点高度给控制器(多段压裂水平井)
void sigFractureGeometryChanged(double newHeight, double newMidPointY);
protected:
// 重写工厂方法,根据井类型创建适合纵截面视图的组合图元
nmAbstractWellboreVisual* createWellboreVisual(NM_WELL_MODEL type) override;
void mousePressEvent(QMouseEvent *event) override; // 重写鼠标按下事件
void resizeEvent(QResizeEvent *event) override;
private:
bool m_bIsInAddPerforationMode; // 视图内部的添加模式状态
bool m_bIsInDeletePerforationMode; // 删除射孔模式标志
bool m_isInitialFitDone; // 用于确保初始缩放只执行一次
};
// === 内部定义的井筒轨迹3D视图类 ===
class nmWxWellbore3DView : public QWidget
{
Q_OBJECT
public:
explicit nmWxWellbore3DView(QWidget *parent = nullptr);
// 这里可以添加3D View特有的方法和成员
};
// 井筒轨迹显示视图
class NM_SUB_WXS_EXPORT nmWxWellboreTrajectoryDisplay : public QWidget
{
Q_OBJECT
public:
explicit nmWxWellboreTrajectoryDisplay(QWidget *parent = nullptr);
~nmWxWellboreTrajectoryDisplay();
// 设置当前要显示的井数据
void setCurrentWellboreData(nmDataWellBase* pWellData);
// 对当前可见视图设置模式和更新UI
void setEditWellMode(bool enabled); // 用于井筒轨迹编辑模式
void setPerforationEditMode(bool enabled); // 射孔编辑模式
void setAddPerforationMode(bool enabled); // 添加射孔模式
void setDeletePerforationMode(bool enabled); // 删除射孔模式
void setSnapPerforationMode(bool enabled); // 对齐/吸附模式
signals:
// 由视图发出的信号,通知控制器用户请求了某个操作
// 控制器会根据当前状态决定是否激活该模式,并管理模式的互斥性
void requestedEditWellMode(int nCurrentViewId); // 请求编辑井筒/裂缝模式
void requestedEditPerforationsMode(int nCurrentViewId); // 请求编辑射孔模式
void requestedNewPerforationMode(int nCurrentViewId); // 请求添加射孔模式
void requestedDeletePerforationMode(int nCurrentViewId); // 请求删除射孔模式
void requestedSnapPerforationMode(int nCurrentViewId); // 请求吸附射孔模式
// 清理当前视图状态
void sigClearViewStates();
// 通知控制器当前视图已切换
void currentViewChanged(int newViewId);
// 井筒点移动信号 (从俯视图转发而来,发送给控制器)
void sigWellboreTrajectoryPointMoved(const QPointF& newScenePos);
// 射孔段拖动完成信号 (从截面图转发而来,发送给控制器)
void sigPerforationDragFinished(nmDataPerforation* pPerforationData, double proposedMdStart, double proposedMdEnd);
// 在添加射孔模式下,将点击的场景坐标发送给控制器
void sigTryAddNewPerforation(const QPointF& scenePos,
double fractureTopMd = -1.0,
double fractureBottomMd = -1.0,
const QLineF& wellboreVisualLine = QLineF());
// 将待删除的射孔数据发送给控制器
void sigTryDeletePerforation(nmDataPerforation* pPerforationData);
// 拖拽结束后,发送裂缝几何位置
void sigFractureGeometryDragFinished(double newHalfLength, double newAngle);
// 将裂缝的垂直范围变化请求转发给控制器
void sigRequestFractureRectUpdate(qreal fractureTopMD, qreal fractureBottomMD);
// 拖动裂缝结束后,将更新后的射孔数据传递给控制器
// QMap<数据指针, <起始MD, 结束MD>>
void sigFractureDragFinished(const QMap<nmDataPerforation*, QPair<double, double>>& updatedPerforations);
// 将裂缝半长变化转发给控制器
void sigFractureHalfLengthChanged(double newHalfLength);
// 井身终点位置发生变化,转发给控制器
void sigWellboreDragFinished(QPointF newScenePos);
// 转发裂缝的高度和中点高度给控制器(多段压裂水平井)
void sigFractureGeometryChanged(double newHeight, double newMidPointY);
private:
// 私有函数
void initUI();
void createViewOptions();
void createToolBar();
void createViewWidgets();
void connectSignalsSlots();
// 更新工具栏要显示什么
void updateToolBarForCurrentView(int viewIndex);
private slots:
void onViewRadioButtonToggled(int id);
void onZoomOutClicked(); // 缩小
void onHomeViewClicked(); // 复位/恢复
void onZoomInClicked(); // 放大
void onXYClicked(); // 坐标显示
void onEditWellClicked(); // 编辑井筒轨迹(发出请求)
void onLoadClicked(); // 加载
void onEditPerforationsClicked(); // 编辑射孔(发出请求)
void onNewPerforationClicked(); // 添加射孔段(发出请求)
void onDeletePerforationClicked(); // 删除射孔段(发出请求)
void onSnapPerforationClicked(); // 对齐/吸附(发出请求)
// 响应数据模型变化,更新所有视图
void onWellboreDataChanged();
// 接收来自 QGraphicsView 的鼠标坐标信号
void onMouseMovedOnPlot(double x, double y);
void onMouseEnteredAnyView(); // 新增槽函数:鼠标进入任一视图
void onMouseLeftAnyView(); // 新增槽函数:鼠标离开任一视图
public:
// 刷新纵截面视图
void updataCrossSectionView();
private:
// 成员变量
QGroupBox *m_pViewGroupBox;
QButtonGroup *m_pViewButtonGroup;
QRadioButton *m_pTopViewRadio;
QRadioButton *m_pCrossSectionRadio;
QRadioButton *m_p3DViewRadio;
QToolBar *m_pToolBar;
QAction *m_pZoomOutAction; // 缩小
QAction *m_pHomeViewAction; // 复位/恢复
QAction *m_pZoomInAction; // 放大
QAction *m_pXYAction; // 坐标显示
QAction *m_pEditWellAction; // 编辑井筒轨迹
QAction *m_pLoadAction; // 加载
QAction *m_pEditPerforationsAction; // 编辑射孔
QAction *m_pNewPerforationAction; // 添加射孔段
QAction *m_pDeletePerforationAction; // 删除射孔段
QAction *m_pSnapPerforationAction; // 对齐/吸附
QStackedWidget *m_pStackedWidget;
nmWxWellboreTopView *m_pTopViewWidget; // 顶部视图
nmWxWellboreCrossSectionView *m_pCrossSectionViewWidget; // 纵截面视图
nmWxWellbore3DView *m_p3DViewWidget; // 3D视图
// 当前渲染的井数据对象
nmDataWellBase* m_pDataWell;
// 用于显示鼠标坐标的标签
QLabel* m_pMouseCoordLabel;
// 是否启用该标签
bool m_bMouseLabelEnabled;
};
#endif // NMWXWELLBORETRAJECTORYDISPLAY_H