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

506 lines
13 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 <QPainter>
#include <ZxSerializer.h>
#include "IxPtyPano.h"
#include "ZxBaseUtil.h"
#include "ZxSubAxisX.h"
#include "ZxSubAxisY.h"
#include "nmObjLineCrackTool.h"
#include "ZxPlot.h"
#include "ZxObjText.h"
#include "nmObjLineCrack.h"
#include "nmDataAnalyzeManager.h"
ZX_DEFINE_DYNAMIC(nObjLineFracture, nmObjLineCrack)
nmObjLineCrack::nmObjLineCrack()
{
m_sObjTag = "nObjLineFracture";
nmObjLineCrack::init("", NULL, NULL);
}
nmObjLineCrack::nmObjLineCrack(const QString& sName, \
ZxSubAxisX* pAxisX, \
ZxSubAxisY* pAxisY)
{
m_sObjTag = "nObjLineFracture";
nmObjLineCrack::init(sName, pAxisX, pAxisY);
}
nmObjLineCrack::~nmObjLineCrack()
{
// 裂缝数据由DataManager统一释放图元只保存引用。
m_fractureData = nullptr;
}
void nmObjLineCrack::init(const QString& sName, \
ZxSubAxisX* pAxisX, \
ZxSubAxisY* pAxisY)
{
nmObjBase::init(sName, pAxisX, pAxisY);
nmObjLineCrack::initFlags();
m_oPen = QPen(QBrush(Qt::red), \
0.3f, Qt::SolidLine);
m_fractureData = nullptr;
loadTempl();
// 连接图元可见性信号和槽
connect(this, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onObjVisibleChanged(bool)));
}
void nmObjLineCrack::initTools()
{
m_pTool = new nmObjLineCrackTool();
nmObjBase::initTools();
}
void nmObjLineCrack::initFlags()
{
setLockPos(false);
setLockSize(false);
setReadOnly(false);
}
bool nmObjLineCrack::hitTest(const QPointF& pt)
{
return nmObjBase::hitTest(pt);
}
bool nmObjLineCrack::_runHitTest(const QPointF& pt, int& nOption, int& nSubIndex)
{
if(!nmObjBase::_runHitTest(pt, nOption, nSubIndex)) {
return false;
}
nOption = -1;
nSubIndex = 0;
if(NULL == m_pAxisX || NULL == m_pAxisY) {
return false;
}
QVector<QPointF> pts = getPosOf(m_vecPoints);
// 点
double r = 1.f;
for(int i = 0; i < pts.count(); i++) {
QPointF ptTopLeft = QPointF(pts[i].x() - r,
pts[i].y() - r);
QSizeF sz = QSizeF(r * 2.f, r * 2.f);
QRectF rt = QRectF(ptTopLeft, sz);
bool b = rt.contains(pt);
if(b) {
nOption = (int)OHO_Point;
nSubIndex = i;
return true;
}
}
// 线
for(int i = 0; i < pts.count(); i++) {
int n1 = i;
int n2 = (i == pts.count() - 1 ? 0 : i + 1);
if(_isNearLine(pt, pts[n1], pts[n2], 1.f * 2)) {
// 判断当前线是否已经存在
if(m_oHitOption == OHO_Bound && m_pTool->isLeftDown()) {
// 添加新节点
pts.insert(i + 1, pt);
m_vecPoints.clear();
m_vecPoints = getValueOf(pts);
nOption = (int)OHO_Point;
nSubIndex = i + 1;
return true;
}
nOption = (int)OHO_Bound;
nSubIndex = i;
return true;
}
}
nOption = (int)OHO_None;
nSubIndex = -1;
return false;
}
bool nmObjLineCrack::runMove(const QPointF& pt1,
const QPointF& pt2)
{
if(isLockPos()) {
return false;
}
if(NULL == m_pAxisX || NULL == m_pAxisY) {
return false;
}
int nCount = m_vecPoints.count();
QVector<QPointF> vecPts = getPosOf(m_vecPoints); // 屏幕值
if(m_oHitOption == OHO_Point && m_nHitIndex >= 0) {
// 如果是点,不用计算偏移量,直接将该点移动到鼠标抬起的位置即可
vecPts[m_nHitIndex] = pt2;
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
return moveToPos(vecPts);
} else if(m_oHitOption == OHO_Bound && m_nHitIndex >= 0) {
for(int i = 0; i < nCount; i++) {
vecPts[i] = offsetPoint(vecPts[i], pt1, pt2);
}
m_dOffsetX = pt2.x() - pt1.x();
m_dOffsetY = pt2.y() - pt1.y();
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
return moveToPos(vecPts);
} else {
return false;
}
return true;
}
void nmObjLineCrack::paintBack(QPainter* painter, const ZxPaintParam& param)
{
if(NULL == m_pAxisX || NULL == m_pAxisY || \
m_pAxisX->getRangeMin() == m_pAxisX->getRangeMax() || \
m_pAxisY->getRangeMin() == m_pAxisY->getRangeMax()) {
return;
}
painter->save();
QVector<QPointF> pts = getPosOf(m_vecPoints);
// 动态更新裂缝基础数据
if(m_fractureData != nullptr) {
m_fractureData->setFractureName(m_sName);
m_fractureData->setFracturePoints(m_vecPoints);
}
// 不选中的状态
if(!pts.empty()) {
QPen pen = m_oPen;
painter->setPen(pen);
for(int i = 0; i < pts.count() - 1; i++) {
painter->drawLine(pts[i], pts[i + 1]);
}
//将名称置于中间线段下方
QFont ft = qApp->font();
ft.setPointSize(8);
painter->setFont(ft);
painter->setPen(Qt::black);
int nSegments = pts.count() - 1;
int middleIndex = (nSegments - 1) / 2;
QPointF startPoint = pts[middleIndex];
QPointF endPoint = pts[middleIndex + 1];
// 计算中点坐标
QPointF middlePoint((startPoint.x() + endPoint.x()) / 2,
(startPoint.y() + endPoint.y()) / 2);
// 计算线段的方向角度
double dx = endPoint.x() - startPoint.x();
double dy = endPoint.y() - startPoint.y();
double angle = qAtan2(dy, dx) * 180.0 / M_PI;
// 偏移距离
double offsetDistance = -3.0;
// 线段长度
double length = std::sqrt(dx * dx + dy * dy);
// 计算一个垂直于线段方向的单位向量:
QPointF offset(0, 0);
if(length > 0) {
// 选用 (dy, -dx) 作为垂直方向,正负号可根据想要的偏移朝向做调整
offset = QPointF(offsetDistance * (dy / length),
offsetDistance * (-dx / length));
}
// 最终文字基准点:在原中点的基础上加上垂直方向的偏移
QPointF textPos = middlePoint + offset;
painter->save();
painter->translate(textPos);
painter->rotate(angle);
QRectF textRect(-50, -10, 100, 20);
ZxDrawHelper::drawText(painter,
textRect,
Qt::AlignCenter | Qt::AlignVCenter,
m_sName);
painter->restore();
}
if(isSelected()) { //选中状态下
for(int i = 0; i < pts.count(); i++) {
float w = 2.2f;
QPointF pt = pts[i];
QRectF rect(pt.x() - w * 0.5f, pt.y() - w * 0.5f, w, w);
if(m_nHitIndex == i && m_oHitOption == OHO_Point) { // 填充节点
QBrush br(Qt::red);
painter->fillRect(rect, br);
} else {
painter->setPen(QColor(0, 0, 128));
painter->drawRect(rect);
}
// 击中线
if(m_nHitIndex == i && m_oHitOption == OHO_Bound) {
nmDataLogFile::getInstance()->writeLog("select line " + QString::number(i));
QPen pen(Qt::DashLine);
//pen.setWidth(1); // 设置线条宽度
// pen.setColor(Qt::green); // 设置线条颜色
painter->setPen(pen);
for(int i = 0; i < pts.count() - 1; i++) {
painter->drawLine(pts[i], pts[i + 1]);
}
}
}
}
painter->restore();
}
int nmObjLineCrack::getCrackFlowModel()
{
if(m_fractureData->getFractureFlowModel().getValue() == tr("Infinite Conductivity"))
return 0;
else
return 1;
}
void nmObjLineCrack::setCrackFlowModel(int newCrackFlowModel)
{
nmDataAttribute tempAttr = m_fractureData->getFractureFlowModel();
if(newCrackFlowModel == 0) {
tempAttr.setValue(tr("Infinite Conductivity"));
} else {
tempAttr.setValue(tr("Finite Conductivity"));
}
m_fractureData->setFractureFlowModel(tempAttr);
}
double nmObjLineCrack::getCrackDfc()
{
return m_fractureData->getFractureDfc().getValue().toDouble();
}
void nmObjLineCrack::setCrackDfc(double newCrackDfc)
{
// 从Data中取数据
nmDataAttribute tempAttr = m_fractureData->getFractureDfc();
tempAttr.setValue(newCrackDfc);
m_fractureData->setFractureDfc(tempAttr);
}
double nmObjLineCrack::getCrackDw()
{
return m_fractureData->getFractureDw().getValue().toDouble();
}
void nmObjLineCrack::setCrackDw(double newCrackDw)
{
// 从Data中取数据
nmDataAttribute tempAttr = m_fractureData->getFractureDw();
tempAttr.setValue(newCrackDw);
m_fractureData->setFractureDw(tempAttr);
}
void nmObjLineCrack::onSerialize(ZxSerializer* ser)
{
nmObjBase::onSerialize(ser);
int flowModel;
if(m_fractureData->getFractureFlowModel().getValue() == tr("Infinite Conductivity"))
flowModel = 0;
else
flowModel = 1;
ser->write("FlowModel", flowModel);
ser->write("dFc", m_fractureData->getFractureDfc().getValue().toDouble());
ser->write("dW", m_fractureData->getFractureDw().getValue().toDouble());
}
void nmObjLineCrack::onDeserialize(ZxSerializer* ser)
{
nmObjBase::onDeserialize(ser);
int flowModel;
double fractureDfc;
double fractureDw;
ser->read("FlowModel", flowModel);
ser->read("dFc", fractureDfc);
ser->read("dW", fractureDw);
this->setCrackFlowModel(flowModel);
this->setCrackDfc(fractureDfc);
this->setCrackDw(fractureDw);
}
void nmObjLineCrack::onSaveTempl(ZxSerializer* ser)
{
nmObjBase::onSaveTempl(ser);
int flowModel;
if(m_fractureData->getFractureFlowModel().getValue() == tr("Infinite Conductivity"))
flowModel = 0;
else
flowModel = 1;
ser->write("FlowModel", flowModel);
ser->write("dFc", m_fractureData->getFractureDfc().getValue().toDouble());
ser->write("dW", m_fractureData->getFractureDw().getValue().toDouble());
}
void nmObjLineCrack::onLoadTempl(ZxSerializer* ser)
{
nmObjBase::onLoadTempl(ser);
int flowModel;
double fractureDfc;
double fractureDw;
ser->read("FlowModel", flowModel);
ser->read("dFc", fractureDfc);
ser->read("dW", fractureDw);
this->setCrackFlowModel(flowModel);
this->setCrackDfc(fractureDfc);
this->setCrackDw(fractureDw);
}
void nmObjLineCrack::fillPtyPano(IxPtyPano* sheet)
{
nmObjBase::fillPtyPano(sheet);
IxPtyItem* pProp = ZX_PROP("ObjLineFracture.FlowModel", getCrackFlowModel, setCrackFlowModel);
if(NULL != pProp) {
QStringList listTags;
listTags << tr("Infinite Conductivity") << tr("Finite Conductivity");
QList<QVariant> listIndexes;
listIndexes << 0 << 1;
pProp->getPtyPano();
pProp->setOptions(listTags, listIndexes);
}
ZX_PROP("ObjLineFracture.dFc", getCrackDfc, setCrackDfc);
ZX_PROP("ObjLineFracture.dW", getCrackDw, setCrackDw);
// 裂缝起点位置
ZX_PROP("ObjLineCrackStartPos.StartPointX", getStartX, setStartX);
ZX_PROP("ObjLineCrackStartPos.StartPointY", getStartY, setStartY);
// 裂缝终点位置
ZX_PROP("ObjLineCrackEndPos.EndPointX", getEndX, setEndX);
ZX_PROP("ObjLineCrackEndPos.EndPointY", getEndY, setEndY);
}
void nmObjLineCrack::setFractureData(nmDataFracture* newFractureData)
{
m_fractureData = newFractureData;
}
nmDataFracture* nmObjLineCrack::getFractureData() const
{
return m_fractureData;
}
void nmObjLineCrack::afterCreated()
{
m_fractureData = nmDataAnalyzeManager::getCurrentInstance()->createFracture();
m_fractureData->setFractureName(m_sName);
m_fractureData->setFracturePoints(m_vecPoints);
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
}
void nmObjLineCrack::removeData()
{
if(m_fractureData) {
// 从数据中心移除该数据
nmDataAnalyzeManager::getCurrentInstance()->removeFractureData(m_fractureData);
m_fractureData = nullptr;
}
}
double nmObjLineCrack::getStartX()
{
return m_fractureData->getFracturePoints().first().x();
}
void nmObjLineCrack::setStartX(double newValue)
{
m_vecPoints.first().setX(newValue);
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
}
double nmObjLineCrack::getStartY()
{
return m_fractureData->getFracturePoints().first().y();
}
void nmObjLineCrack::setStartY(double newValue)
{
m_vecPoints.first().setY(newValue);
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
}
double nmObjLineCrack::getEndX()
{
return m_fractureData->getFracturePoints().last().x();
}
void nmObjLineCrack::setEndX(double newValue)
{
m_vecPoints.last().setX(newValue);
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
}
double nmObjLineCrack::getEndY()
{
return m_fractureData->getFracturePoints().last().y();
}
void nmObjLineCrack::setEndY(double newValue)
{
m_vecPoints.last().setY(newValue);
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
}
void nmObjLineCrack::setLockForDFN()
{
setLockPos(true);
setLockSize(true);
setReadOnly(true);
}
void nmObjLineCrack::onObjVisibleChanged(bool bIsVisible)
{
if(m_fractureData != nullptr) {
m_fractureData->setPlotVisible(bIsVisible);
}
}