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

283 lines
10 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "nmDataFracture.h"
#include <QVariant>
#include <QVector>
#include "nmDataJsonTools.h"
#include <QPointF> // 确保 QPointF 被包含
#include <QVariantMap> // 确保 QVariantMap 被包含
#include <QVariantList> // 确保 QVariantList 被包含
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());
// 默认裂缝类型是普通裂缝
m_fractureType = nmDataAttribute("Fracture type", "Normal","", UNIT_TYPE_DIMENSIONLESS, QStringList() << "Normal" << "DFN", QStringList());
// 图元可见性默认为true
m_bPlotVisible = true;
this->connectAttributeSignals();
}
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;
m_fractureType = other.m_fractureType;
m_bPlotVisible = other.m_bPlotVisible;
}
return *this;
}
nmDataFracture::~nmDataFracture() {
}
// 序列化 nmDataFracture 为 RapidJSON Value
rapidjson::Value nmDataFracture::ToJsonValue(rapidjson::Document::AllocatorType& allocator) const
{
// 创建一个 RapidJSON 对象类型的值
rapidjson::Value fractureObject(rapidjson::kObjectType);
// 序列化裂缝名称 (m_sFractureName)
// 将 QString 转换为 UTF-8 编码的 C 字符串,并添加到 JSON 中
fractureObject.AddMember("FractureName", rapidjson::Value(m_sFractureName.toStdString().c_str(), allocator).Move(), allocator);
// 序列化裂缝点 (m_vecPts)
rapidjson::Value pointsArray(rapidjson::kArrayType); // 创建一个 RapidJSON 数组类型的值
// 遍历断层点列表
foreach (const QPointF& point , m_vecPts) {
rapidjson::Value pointObject(rapidjson::kObjectType); // 创建一个点对象
pointObject.AddMember("x", point.x(), allocator); // 添加x坐标
pointObject.AddMember("y", point.y(), allocator); // 添加y坐标
pointsArray.PushBack(pointObject, allocator); // 将点对象推入数组
}
fractureObject.AddMember("FracturePoints", pointsArray, allocator); // 将点数组添加到JSON对象
// 序列化 nmDataAttribute 类型的成员 (m_fractureFlowModel, m_fractureDfc, m_fractureDw, m_fractureType)
// 调用 nmDataAttribute 自身的 ToJsonValue 方法进行递归序列化
fractureObject.AddMember("FractureFlowModel", m_fractureFlowModel.ToJsonValue(allocator), allocator);
fractureObject.AddMember("FractureDfc", m_fractureDfc.ToJsonValue(allocator), allocator);
fractureObject.AddMember("FractureDw", m_fractureDw.ToJsonValue(allocator), allocator);
fractureObject.AddMember("FractureType", m_fractureType.ToJsonValue(allocator), allocator);
// 序列化图元可见性 (m_bPlotVisible)
fractureObject.AddMember("PlotVisible", m_bPlotVisible, allocator); // 使用m_bPlotVisible
return fractureObject; // 返回序列化后的 RapidJSON Value
}
// 从 RapidJSON Value 反序列化数据到 nmDataFracture
void nmDataFracture::FromJsonValue(const rapidjson::Value& jsonValue)
{
// 反序列化裂缝名称 (m_sFractureName)
if (jsonValue.HasMember("FractureName") && jsonValue["FractureName"].IsString()) {
m_sFractureName = QString::fromUtf8(jsonValue["FractureName"].GetString());
}
// 反序列化裂缝点 (m_vecPts)
if (jsonValue.HasMember("FracturePoints") && jsonValue["FracturePoints"].IsArray()) {
m_vecPts.clear(); // 清空当前点列表使用m_vecPts
const rapidjson::Value& pointsArray = jsonValue["FracturePoints"]; // 获取点数组节点
// 遍历数组,将每个点对象反序列化到 m_vecPts
for (rapidjson::SizeType i = 0; i < pointsArray.Size(); ++i) {
if (pointsArray[i].IsObject() &&
pointsArray[i].HasMember("x") && pointsArray[i]["x"].IsDouble() &&
pointsArray[i].HasMember("y") && pointsArray[i]["y"].IsDouble()) {
m_vecPts.append(QPointF(pointsArray[i]["x"].GetDouble(), pointsArray[i]["y"].GetDouble()));
}
}
}
// 反序列化 nmDataAttribute 类型的成员 (m_fractureFlowModel, m_fractureDfc, m_fractureDw, m_fractureType)
// 调用 nmDataAttribute 自身的 FromJsonValue 方法进行递归反序列化
if (jsonValue.HasMember("FractureFlowModel") && jsonValue["FractureFlowModel"].IsObject()) {
m_fractureFlowModel.FromJsonValue(jsonValue["FractureFlowModel"]);
}
if (jsonValue.HasMember("FractureDfc") && jsonValue["FractureDfc"].IsObject()) {
m_fractureDfc.FromJsonValue(jsonValue["FractureDfc"]);
}
if (jsonValue.HasMember("FractureDw") && jsonValue["FractureDw"].IsObject()) {
m_fractureDw.FromJsonValue(jsonValue["FractureDw"]);
}
if (jsonValue.HasMember("FractureType") && jsonValue["FractureType"].IsObject()) {
m_fractureType.FromJsonValue(jsonValue["FractureType"]);
}
// 反序列化图元可见性 (m_bPlotVisible)
if (jsonValue.HasMember("PlotVisible") && jsonValue["PlotVisible"].IsBool()) {
m_bPlotVisible = jsonValue["PlotVisible"].GetBool(); // 使用m_bPlotVisible
}
syncEndPointAttributes();
}
// Getter and Setter for m_sFractureName
QString nmDataFracture::getFractureName() const
{
return m_sFractureName;
}
void nmDataFracture::setFractureName(const QString& sFractureName)
{
m_sFractureName = sFractureName;
}
// Getter and Setter for m_vecPts
QVector<QPointF> nmDataFracture::getFracturePoints() const
{
return m_vecPts;
}
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
nmDataAttribute& nmDataFracture::getFractureFlowModel()
{
return m_fractureFlowModel;
}
void nmDataFracture::setFractureFlowModel(const nmDataAttribute& fractureFlowModel)
{
m_fractureFlowModel = fractureFlowModel;
}
// Getter and Setter for m_fractureDfc
nmDataAttribute& nmDataFracture::getFractureDfc()
{
return m_fractureDfc;
}
void nmDataFracture::setFractureDfc(const nmDataAttribute& fractureDfc)
{
m_fractureDfc = fractureDfc;
}
// Getter and Setter for m_fractureDw
nmDataAttribute& nmDataFracture::getFractureDw()
{
return m_fractureDw;
}
void nmDataFracture::setFractureDw(const nmDataAttribute& fractureDw)
{
m_fractureDw = fractureDw;
}
nmDataAttribute& nmDataFracture::getFractureType()
{
return m_fractureType;
}
void nmDataFracture::setFractureType(const nmDataAttribute& fractureType)
{
m_fractureType = fractureType;
}
bool nmDataFracture::getPlotVisible() const{
return m_bPlotVisible;
}
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();
}