From f62d24e4cec8a061ac6c8c7a2b3a1d4f03c7f391 Mon Sep 17 00:00:00 2001 From: crqiqi77 Date: Thu, 23 Apr 2026 09:10:28 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A3=82=E7=BC=9D=20=E7=94=BB=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logPlus/PickFrac.cpp | 1189 +++++++++++++++++++++++++++++++------ logPlus/PickFrac.h | 213 +++++-- logPlus/formdraw.cpp | 1 + logPlus/qmycustomplot.cpp | 19 +- logPlus/qmycustomplot.h | 6 +- 5 files changed, 1182 insertions(+), 246 deletions(-) diff --git a/logPlus/PickFrac.cpp b/logPlus/PickFrac.cpp index da732f8..ef1f38c 100644 --- a/logPlus/PickFrac.cpp +++ b/logPlus/PickFrac.cpp @@ -1,247 +1,1048 @@ #include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include "MemRdWt.h" #include "PickFrac.h" +#include "qmycustomplot.h" #include "geometryutils.h" +// ==================== CPickFrac 实现 ==================== CPickFrac::CPickFrac(QMyCustomPlot *myCustomPlot, QString strSlfName, QString csCurve, int iMyWidth) + : m_myCustomPlot(myCustomPlot), m_iMyWidth(iMyWidth) { - m_myCustomPlot = myCustomPlot; - m_iMyWidth = iMyWidth; - - m_Name="Frac_Hole.Table"; - m_strDevi = "DEVI"; - m_strHazi = "HAZI"; - + m_currentSlfName = strSlfName; + m_currentTableName = csCurve.isEmpty() ? "Frac_Hole.Table" : csCurve; ReadFracDef(); - - for (int i = 0 ; i < iFracType ; i++) - { - m_bTypeDraw[i] = true; - } - - //支持框选------------------ + for (int i = 0; i < iFracType2; i++) m_bTypeDraw[i] = true; myCustomPlot->m_bDrawCore_PHYSICS = true; - ReadData(strSlfName, csCurve); - -// myCustomPlot->setSelectionRectMode(QCP::SelectionRectMode::srmSelect); -// myCustomPlot->graph(0)->setSelectable(QCP::SelectionType::stMultipleDataRanges);// stSingleData -// myCustomPlot->setInteractions(QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables | QCP::iMultiSelect); // 轴、图例、图表可以被选择,并且是多选的方式 - } -CPickFrac::~CPickFrac(void) +CPickFrac::~CPickFrac() { + qDeleteAll(m_items); m_FracDef.clear(); } +void CPickFrac::setDraggingEnabled(bool enabled) +{ + m_draggingEnabled = enabled; + if (!enabled) { + for (auto item : m_items) item->deactivate(); + } +} + void CPickFrac::ReadFracDef() { m_FracDef.clear(); - QString fracFilePath = GetConfPath() + "FRAC.CFG"; - - // FRAC_DEF_Crack fd; - char str[512],name[512]; - int r,g,b,id; - FILE *fp; - QString qs; - fp = fopen(fracFilePath.toStdString().c_str(),"r"); - if ( fp != nullptr ) - { - fgets(str,256,fp); // 跳过第一行 - while (!feof(fp)) - { - fgets(str,256,fp); - qs = str; + char str[512], name[512]; + int r, g, b; + FILE *fp = fopen(fracFilePath.toStdString().c_str(), "r"); + if (fp) { + fgets(str, 256, fp); + while (!feof(fp)) { + fgets(str, 256, fp); + QString qs = str; qs.trimmed(); - if (qs.length() < 8) break ; - //代码 名称 形状代码(1:正弦曲线 2:连线 3:封闭区域) 颜色(红 绿 蓝) 线宽度 - sscanf(str,"%d %s %d %d %d %d %d",&fd.iCode,name,&fd.iType,&r,&g,&b,&fd.nLineWidth); - fd.crColor = QColor(r,g,b);//RGB(r,g,b); + if (qs.length() < 8) break; + sscanf(str, "%d %s %d %d %d %d %d", &fd.iCode, name, &fd.iType, &r, &g, &b, &fd.nLineWidth); + fd.crColor = QColor(r, g, b); fd.csName = name; - fd.csName = fd.csName.trimmed();//.Trim(); + fd.csName = fd.csName.trimmed(); fd.bDraw = 0; m_FracDef.append(fd); - if ( feof(fp)) - break; + if (feof(fp)) break; } fclose(fp); - } - else - { - sprintf(name,"打开裂缝参数配置文件错误:%s!",str); + } else { + sprintf(name, "打开裂缝参数配置文件错误:%s!", str); QMessageBox::information(nullptr, "读取文件失败", name); } } void CPickFrac::ReadData(QString strSlfName, QString csCurve) { - if(strSlfName.isEmpty()) return; + if (strSlfName.isEmpty()) return; + if (csCurve == "AC" || csCurve.isEmpty()) csCurve = "Frac_Hole.Table"; - if(csCurve=="AC"||csCurve=="") - { - csCurve="Frac_Hole.Table"; + CMemRdWt mrw; + if (!mrw.Open(strSlfName.toStdString().c_str())) return; + + int iIndex = mrw.OpenTable(csCurve.toStdString().c_str()); + if (iIndex < 0) { mrw.Close(); return; } + + int nField = mrw.GetTableFieldCount(iIndex); + int nCount = mrw.GetTableRecordCount(iIndex); + for (int i = 0; i < nCount; ++i) { + FRAC_TABLE_Crack frac; + if (nField == 7) { + FRAC_TABLE_OLD_Crack fracold; + mrw.ReadTable(iIndex, i+1, &fracold); + frac.AorX = fracold.AorX; + frac.DEP = fracold.DEP; + frac.DIPorS = fracold.DIPorS; + frac.DIR = fracold.DIR; + frac.W = fracold.W; + frac.ID = fracold.ID; + frac.XETAorH = fracold.XETAorH; + frac.NUM = 0; + for (int j=0; j<16; ++j) frac.point[j].x = frac.point[j].y = 0; + } else { + mrw.ReadTable(iIndex, i+1, &frac); + } + + for (int j=0; jsetCrackCode(frac.ID); + connect(item, &DraggableCrackItem::dataChanged, this, &CPickFrac::saveToFile); + connect(item, &DraggableCrackItem::removeMe, this, &CPickFrac::onRemoveCrackItem); + m_items.append(item); + + if (iType == 1) { + double h = frac.AorX / 2.0; + double oy = -(frac.DEP + h); + double xScale = 360.0 / m_iMyWidth; + double endX = 360.0 / xScale; + item->setSineData(oy, h, frac.XETAorH, xScale, endX); + } + else if (iType == 2) { + QVector points; + int n = frac.NUM; + for (int j=0; jsetPolylineData(points); + } + else if (iType == 3) { + QVector points; + int n = frac.NUM; + for (int j=0; jsetClosedData(points); + } +} + +bool CPickFrac::eventFilter(QObject *watched, QEvent *event) +{ + return QObject::eventFilter(watched, event); +} + +bool CPickFrac::saveToFile() +{ + static bool isRunning = false; + if (isRunning) return false; + if (m_currentSlfName.isEmpty()) return false; + isRunning = true; + + CMemRdWt *logio = new CMemRdWt(); + if (!logio->Open(m_currentSlfName.toStdString().c_str(), CSlfIO::modeReadWrite)) { + delete logio; + QMessageBox::information(nullptr, "提示", "SLF文件打开失败,请检查!", QMessageBox::Yes); + isRunning = false; + return false; } - QString cs; - int nLineWidth=2; - int nField; - QColor crColor(255,0,0); - FRAC_TABLE_Crack frac; - FRAC_TABLE_OLD_Crack fracold; - CMemRdWt mrw; - char strFracTable[256]; - int i,j,iIndex,nCount,iType=1; + QString tableName = m_currentTableName; + int iIndex = logio->OpenTable(tableName.toStdString().c_str()); + if (iIndex < 0) { + delete logio; + QMessageBox::information(nullptr, "提示", QString("裂缝表 %1 不存在,无法保存!").arg(tableName), QMessageBox::Yes); + isRunning = false; + return false; + } - if (mrw.Open(strSlfName.toStdString().c_str()) ) // 打开井文件 - { - QString name(csCurve); - iIndex=mrw.OpenTable(name.toStdString().c_str()); - if(iIndex>=0) - { - nField=mrw.GetTableFieldCount(iIndex); - nCount=mrw.GetTableRecordCount(iIndex); - cs =""; - for(i=0;iSetTableRecordCount(iIndex, 0); + logio->CloseTable(iIndex); + delete logio; + isRunning = false; + return true; + } + + QMap sortedMap; + for (DraggableCrackItem *item : m_items) { + double depth = item->getDepthForSort(); + sortedMap[depth] = item; + } + logio->SetTableRecordCount(iIndex, sortedMap.size()); + + int recordIndex = 1; + for (auto it = sortedMap.begin(); it != sortedMap.end(); ++it) { + FRAC_TABLE_Crack fracData; + it.value()->getCurrentFracData(fracData); + logio->WriteTable(iIndex, recordIndex, &fracData); + recordIndex++; + } + + logio->CloseTable(iIndex); + delete logio; + isRunning = false; + return true; +} + +void CPickFrac::onRemoveCrackItem(DraggableCrackItem *item) +{ + if (!item) return; + if (m_items.removeOne(item)) { + disconnect(item, nullptr, this, nullptr); + // 延迟删除,确保当前事件完全结束 + QTimer::singleShot(0, item, &QObject::deleteLater); + saveToFile(); + m_myCustomPlot->replot(); + } +} + +// ==================== DraggableCrackItem 实现 ==================== +QPointer DraggableCrackItem::s_activeItem = nullptr; + +DraggableCrackItem::DraggableCrackItem(QCustomPlot *plot, Type type, const QColor &color, int lineWidth) + : QObject(plot), m_plot(plot), m_type(type), m_color(color), m_lineWidth(lineWidth) +{ + if (m_type == TypeA_Sine) { + m_curve = new QCPItemCurve(m_plot); + m_curve->setPen(QPen(m_color, m_lineWidth)); + m_curve->setLayer("overlay"); + auto createTracer = [this](double x, double y) -> QCPItemTracer* { + QCPItemTracer *t = new QCPItemTracer(m_plot); + t->setStyle(QCPItemTracer::tsSquare); + t->setSize(8); + t->setPen(QPen(Qt::black, 1)); + t->setBrush(QBrush(Qt::black)); + t->setSelectable(true); + t->setLayer("overlay"); + t->position->setCoords(x, y); + t->setVisible(false); + return t; + }; + m_tracer1 = createTracer(0,0); + m_tracer2 = createTracer(0,0); + m_plot->installEventFilter(this); + } + else if (m_type == TypeB_Polyline) { + m_plot->installEventFilter(this); + } + else if (m_type == TypeC_Closed) { + m_curveC = new QCPCurve(m_plot->xAxis, m_plot->yAxis); + m_curveC->setPen(QPen(m_color, m_lineWidth)); + m_curveC->setScatterStyle(QCPScatterStyle::ssCircle); + m_curveC->setLineStyle(QCPCurve::lsLine); + m_curveC->setLayer("overlay"); + m_plot->installEventFilter(this); + } +} + +DraggableCrackItem::~DraggableCrackItem() +{ + if (m_type == TypeA_Sine) { + if (m_tracer1) m_plot->removeItem(m_tracer1); + if (m_tracer2) m_plot->removeItem(m_tracer2); + if (m_curve) m_plot->removeItem(m_curve); + } else if (m_type == TypeB_Polyline) { + clearLines(); + } else if (m_type == TypeC_Closed) { + clearPolylineC(); + } + if (s_activeItem == this) s_activeItem = nullptr; +} + +void DraggableCrackItem::setVisible(bool visible) +{ + if (m_pendingDelete) return; + if (m_type == TypeA_Sine) { + if (m_curve) m_curve->setVisible(visible); + if (m_tracer1) m_tracer1->setVisible(visible && (s_activeItem == this)); + if (m_tracer2) m_tracer2->setVisible(visible && (s_activeItem == this)); + } else if (m_type == TypeB_Polyline) { + for (auto &item : m_lines) { + if (item.line) item.line->setVisible(visible); + bool show = visible && (s_activeItem == this); + if (item.startTracer) item.startTracer->setVisible(show); + if (item.endTracer) item.endTracer->setVisible(show); + } + } else if (m_type == TypeC_Closed) { + if (m_curveC) m_curveC->setVisible(visible); + bool show = visible && (s_activeItem == this); + for (auto label : m_labelsC) label->setVisible(show); + } + m_plot->replot(); +} + +void DraggableCrackItem::deactivate() +{ + if (m_type == TypeA_Sine) { + setTracerHighlight(m_tracer1, false); + setTracerHighlight(m_tracer2, false); + m_dragStateA = IdleA; + setDragPointsVisible(false); + } else if (m_type == TypeB_Polyline) { + m_dragStateB = IdleB; + m_draggedLineIndex = -1; + setDragPointsVisible(false); + } else if (m_type == TypeC_Closed) { + m_cDragging = false; + m_draggingPoint = false; + m_draggedPointIndex = -1; + setDragPointsVisible(false); + } + if (s_activeItem == this) s_activeItem = nullptr; + m_plot->replot(); +} + +void DraggableCrackItem::setDragPointsVisible(bool visible) +{ + if (m_type == TypeA_Sine) { + if (m_tracer1) m_tracer1->setVisible(visible); + if (m_tracer2) m_tracer2->setVisible(visible); + } else if (m_type == TypeB_Polyline) { + for (auto &item : m_lines) { + if (item.startTracer) item.startTracer->setVisible(visible); + if (item.endTracer) item.endTracer->setVisible(visible); + } + } else if (m_type == TypeC_Closed) { + for (auto label : m_labelsC) { + if (label) label->setVisible(visible); + } + } + m_plot->replot(); +} + +void DraggableCrackItem::startEditing() +{ + m_editingMode = true; + if (s_activeItem && s_activeItem != this) s_activeItem->deactivate(); + s_activeItem = this; + setDragPointsVisible(true); + if (m_type == TypeB_Polyline) { + clearLines(); + m_isAddingLine = false; + } else if (m_type == TypeC_Closed) { + clearPolylineC(); + m_cFinished = false; + } + m_plot->replot(); +} + +void DraggableCrackItem::finishEditing() +{ + if (!m_editingMode) return; + m_editingMode = false; + if (s_activeItem == this) { + deactivate(); + } + emit dataChanged(); +} + +// ---------- 模式A ---------- +void DraggableCrackItem::setSineData(double depth, double amplitude, double phase, double xScale, double width) +{ + m_depth = depth; + m_endX = width; + m_originalXETAorH = phase; + m_originalAorX = amplitude * 2.0; + m_orig_x1 = m_endX * 0.18; + m_orig_x2 = m_endX * 0.82; + m_orig_y1 = depth + amplitude; + m_orig_y2 = depth - amplitude; + m_orig_startX = 0; + m_orig_endX = m_endX; + m_orig_startDirX = m_endX * 0.3; + m_orig_endDirX = m_endX * 0.7; + updateCurveFromTargets(); + updateCurvePosition(); + updateTracers(); +} + +void DraggableCrackItem::updateCurveFromTargets() +{ + double t1 = m_orig_x1 / m_endX; + double t2 = m_orig_x2 / m_endX; + double u1 = 1 - t1, u2 = 1 - t2; + double P0x = 0, P0y = m_depth; + double P3x = m_endX, P3y = m_depth; + double P1x = m_orig_x1, P2x = m_orig_x2; + double a11 = 3 * u1 * u1 * t1; + double a12 = 3 * u1 * t1 * t1; + double b1 = m_orig_y1 - (u1*u1*u1 * P0y + t1*t1*t1 * P3y); + double a21 = 3 * u2 * u2 * t2; + double a22 = 3 * u2 * t2 * t2; + double b2 = m_orig_y2 - (u2*u2*u2 * P0y + t2*t2*t2 * P3y); + double det = a11 * a22 - a12 * a21; + if (fabs(det) > 1e-6) { + double P1y = (b1 * a22 - a12 * b2) / det; + double P2y = (a11 * b2 - b1 * a21) / det; + m_orig_startDirX = P1x; + m_orig_startDirY = P1y; + m_orig_endDirX = P2x; + m_orig_endDirY = P2y; + } +} + +void DraggableCrackItem::updateCurvePosition() +{ + if (!m_curve) return; + m_curve->start->setCoords(m_orig_startX + m_offsetXA, m_depth + m_offsetYA); + m_curve->end->setCoords(m_orig_endX + m_offsetXA, m_depth + m_offsetYA); + m_curve->startDir->setCoords(m_orig_startDirX + m_offsetXA, m_orig_startDirY + m_offsetYA); + m_curve->endDir->setCoords(m_orig_endDirX + m_offsetXA, m_orig_endDirY + m_offsetYA); +} + +void DraggableCrackItem::updateTracers() +{ + if (!m_tracer1 || !m_tracer2) return; + m_tracer1->position->setCoords(m_orig_x1 + m_offsetXA, m_orig_y1 + m_offsetYA); + m_tracer2->position->setCoords(m_orig_x2 + m_offsetXA, m_orig_y2 + m_offsetYA); +} + +void DraggableCrackItem::setTracerHighlight(QCPItemTracer *tracer, bool highlight) +{ + if (!tracer) return; + if (highlight) { + tracer->setPen(QPen(Qt::red, 2)); + tracer->setBrush(QBrush(Qt::red)); + } else { + tracer->setPen(QPen(Qt::black, 1)); + tracer->setBrush(QBrush(Qt::black)); + } + m_plot->replot(); +} + +// ---------- 模式B ---------- +void DraggableCrackItem::setPolylineData(const QVector &points, double scaleX, double flipY) +{ + clearLines(); + if (points.size() < 2) return; + auto createTracer = [this](double x, double y, const QColor &color) -> QCPItemTracer* { + QCPItemTracer *t = new QCPItemTracer(m_plot); + t->setStyle(QCPItemTracer::tsSquare); + t->setSize(10); + t->setPen(QPen(Qt::black, 1)); + t->setBrush(QBrush(color)); + t->setSelectable(true); + t->setLayer("overlay"); + t->position->setCoords(x, y); + t->setVisible(false); + return t; + }; + for (int i = 0; i < points.size() - 1; ++i) { + QPointF p1 = points[i]; + QPointF p2 = points[i+1]; + QCPItemLine *line = new QCPItemLine(m_plot); + line->setPen(QPen(m_color, m_lineWidth)); + line->setLayer("overlay"); + QCPItemTracer *startTracer = createTracer(p1.x(), p1.y(), Qt::black); + QCPItemTracer *endTracer = createTracer(p2.x(), p2.y(), Qt::black); + LineItem item; + item.startOrig = p1; + item.endOrig = p2; + item.line = line; + item.startTracer = startTracer; + item.endTracer = endTracer; + m_lines.append(item); + i++; + } + updateLinesPosition(); +} + +void DraggableCrackItem::updateLineEndpoints(LineItem &item) +{ + item.startTracer->position->setCoords(item.startOrig.x() + m_offsetXB, item.startOrig.y() + m_offsetYB); + item.endTracer->position->setCoords(item.endOrig.x() + m_offsetXB, item.endOrig.y() + m_offsetYB); +} + +void DraggableCrackItem::updateLinesPosition() +{ + for (auto &item : m_lines) { + item.line->start->setCoords(item.startOrig.x() + m_offsetXB, item.startOrig.y() + m_offsetYB); + item.line->end->setCoords(item.endOrig.x() + m_offsetXB, item.endOrig.y() + m_offsetYB); + updateLineEndpoints(item); + } +} + +void DraggableCrackItem::clearLines() +{ + for (auto &item : m_lines) { + if (item.line) { m_plot->removeItem(item.line); delete item.line; } + if (item.startTracer) { m_plot->removeItem(item.startTracer); delete item.startTracer; } + if (item.endTracer) { m_plot->removeItem(item.endTracer); delete item.endTracer; } + } + m_lines.clear(); + m_plot->replot(); +} + +// ---------- 模式C ---------- +void DraggableCrackItem::setClosedData(const QVector &points, double scaleX, double flipY) +{ + clearPolylineC(); + if (points.size() < 3) return; + m_pointsC = points; + for (int i = 0; i < m_pointsC.size(); ++i) { + QCPItemText *label = new QCPItemText(m_plot); + label->setText(" "); + label->setFont(QFont("Arial", 6, QFont::Bold)); + label->setColor(Qt::black); + label->setBrush(QBrush(Qt::black)); + label->setPen(QPen(Qt::black, 1)); + label->position->setCoords(m_pointsC[i].x(), m_pointsC[i].y()); + label->setPositionAlignment(Qt::AlignCenter); + label->setLayer("overlay"); + label->setVisible(false); + m_labelsC.append(label); + } + m_cFinished = true; + updatePolylineC(true); +} + +void DraggableCrackItem::updatePolylineC(bool closed) +{ + if (!m_curveC) return; + if (m_pointsC.isEmpty()) { + m_curveC->setData(QVector(), QVector()); + return; + } + QVector xs, ys; + for (const auto &p : m_pointsC) { + xs << p.x() + m_offsetXC; + ys << p.y() + m_offsetYC; + } + if (closed && m_pointsC.size() >= 3) { + xs << m_pointsC.first().x() + m_offsetXC; + ys << m_pointsC.first().y() + m_offsetYC; + } + m_curveC->setData(xs, ys); +} + +void DraggableCrackItem::clearPolylineC() +{ + for (auto label : m_labelsC) { + if (label) { + label->setParent(nullptr); + delete label; + } + } + m_labelsC.clear(); + m_pointsC.clear(); + if (m_curveC) m_curveC->setData(QVector(), QVector()); + m_offsetXC = m_offsetYC = 0.0; + m_cFinished = false; + m_cDragging = false; + m_draggingPoint = false; + m_draggedPointIndex = -1; + m_plot->replot(); +} + +// ---------- 保存辅助 ---------- +double DraggableCrackItem::getDepthForSort() const +{ + if (m_type == TypeA_Sine) + return m_depth + m_offsetYA; + else if (m_type == TypeB_Polyline && !m_lines.isEmpty()) + return m_lines.first().startOrig.y() + m_offsetYB; + else if (m_type == TypeC_Closed && !m_pointsC.isEmpty()) + return m_pointsC.first().y() + m_offsetYC; + return 0.0; +} + +void DraggableCrackItem::getCurrentFracData(FRAC_TABLE_Crack &data) const +{ + memset(&data, 0, sizeof(FRAC_TABLE_Crack)); + data.ID = m_crackCode; + + if (m_type == TypeA_Sine) { + double centerY = (m_orig_y1 + m_orig_y2) / 2.0 + m_offsetYA; + double halfHeight = (m_orig_y1 - m_orig_y2) / 2.0; + double savedDEP = -centerY - halfHeight; + double savedAorX = halfHeight * 2.0; + data.DEP = savedDEP; + data.AorX = savedAorX; + data.XETAorH = m_originalXETAorH; + data.NUM = 0; + } + else if (m_type == TypeB_Polyline) { + QVector allPoints; + for (const LineItem &item : m_lines) { + QPointF p1 = item.startOrig + QPointF(m_offsetXB, m_offsetYB); + QPointF p2 = item.endOrig + QPointF(m_offsetXB, m_offsetYB); + allPoints.append(p1); + allPoints.append(p2); + } + QVector uniquePoints; + for (const QPointF &p : allPoints) { + if (uniquePoints.isEmpty() || uniquePoints.last() != p) + uniquePoints.append(p); + } + data.NUM = uniquePoints.size(); + for (int i = 0; i < uniquePoints.size() && i < 16; ++i) { + data.point[i].x = uniquePoints[i].x() * 8.0f; + data.point[i].y = -uniquePoints[i].y(); + } + if (uniquePoints.size() > 0) + data.DEP = uniquePoints[0].y(); + } + else if (m_type == TypeC_Closed) { + QVector finalPoints; + for (const QPointF &p : m_pointsC) { + finalPoints.append(p + QPointF(m_offsetXC, m_offsetYC)); + } + data.NUM = finalPoints.size(); + for (int i = 0; i < finalPoints.size() && i < 16; ++i) { + data.point[i].x = finalPoints[i].x() * 8.0f; + data.point[i].y = -finalPoints[i].y(); + } + if (finalPoints.size() > 0) + data.DEP = finalPoints[0].y(); + } +} + +// ---------- 事件过滤器 ---------- +bool DraggableCrackItem::eventFilter(QObject *obj, QEvent *event) +{ + if (obj != m_plot) return false; + if (m_pendingDelete) return false; // 已标记删除,忽略所有事件 + + // 右键菜单处理 + if (event->type() == QEvent::ContextMenu) { + QContextMenuEvent *ce = static_cast(event); + if (s_activeItem == this) { + QMenu menu; + QAction *deleteAction = menu.addAction("删除裂缝"); + QAction *selectedAction = menu.exec(ce->globalPos()); + if (selectedAction == deleteAction) { + m_pendingDelete = true; + deactivate(); // 清空全局激活指针 + emit removeMe(this); + } + return true; + } + return false; + } + + QMouseEvent *me = static_cast(event); + + if (event->type() == QEvent::MouseButtonPress && me->button() == Qt::LeftButton) { + bool shiftPressed = (me->modifiers() & Qt::ShiftModifier); + + // ===== 模式B:添加线段(Shift) ===== + if (m_type == TypeB_Polyline && shiftPressed) { + if (!m_isAddingLine) { + double x = m_plot->xAxis->pixelToCoord(me->pos().x()); + double y = m_plot->yAxis->pixelToCoord(me->pos().y()); + m_tempPoint = QPointF(x - m_offsetXB, y - m_offsetYB); + m_isAddingLine = true; + return true; + } else { + double x = m_plot->xAxis->pixelToCoord(me->pos().x()); + double y = m_plot->yAxis->pixelToCoord(me->pos().y()); + QPointF p2(x - m_offsetXB, y - m_offsetYB); + QCPItemLine *line = new QCPItemLine(m_plot); + line->setPen(QPen(m_color, m_lineWidth)); + line->setLayer("overlay"); + auto createTracer = [this](double x, double y, const QColor &color) -> QCPItemTracer* { + QCPItemTracer *t = new QCPItemTracer(m_plot); + t->setStyle(QCPItemTracer::tsSquare); + t->setSize(10); + t->setPen(QPen(Qt::black, 1)); + t->setBrush(QBrush(color)); + t->setSelectable(true); + t->setLayer("overlay"); + t->position->setCoords(x + m_offsetXB, y + m_offsetYB); + t->setVisible(false); + return t; + }; + QCPItemTracer *startTracer = createTracer(m_tempPoint.x(), m_tempPoint.y(), Qt::black); + QCPItemTracer *endTracer = createTracer(p2.x(), p2.y(), Qt::black); + LineItem item; + item.startOrig = m_tempPoint; + item.endOrig = p2; + item.line = line; + item.startTracer = startTracer; + item.endTracer = endTracer; + m_lines.append(item); + updateLinesPosition(); + m_isAddingLine = false; + m_plot->replot(); + return true; + } + } + + // ===== 模式C:添加点(Shift,未完成) ===== + if (m_type == TypeC_Closed && shiftPressed && !m_cFinished) { + if (s_activeItem && s_activeItem != this) s_activeItem->deactivate(); + s_activeItem = this; + setDragPointsVisible(true); + double x = m_plot->xAxis->pixelToCoord(me->pos().x()); + double y = m_plot->yAxis->pixelToCoord(me->pos().y()); + QPointF pt(x - m_offsetXC, y - m_offsetYC); + m_pointsC.append(pt); + QCPItemText *label = new QCPItemText(m_plot); + label->setText(" "); + label->setFont(QFont("Arial", 6, QFont::Bold)); + label->setColor(Qt::black); + label->setBrush(QBrush(Qt::black)); + label->setPen(QPen(Qt::black, 1)); + label->position->setCoords(x, y); + label->setPositionAlignment(Qt::AlignCenter); + label->setLayer("overlay"); + label->setVisible(true); + m_labelsC.append(label); + updatePolylineC(false); + m_plot->replot(); + return true; + } + + // ===== 模式C:完成封闭(非Shift,未完成) ===== + if (m_type == TypeC_Closed && !shiftPressed && !m_cFinished) { + if (m_pointsC.size() >= 3) { + m_cFinished = true; + updatePolylineC(true); + m_plot->replot(); + if (m_editingMode) { + finishEditing(); } - else{ - // 扩充后的裂缝表 - mrw.ReadTable(iIndex,i+1,(void*)&frac); + } else { + clearPolylineC(); + } + if (s_activeItem == this) { + s_activeItem->deactivate(); + s_activeItem = nullptr; + } + return true; + } + + // ===== 编辑模式下,模式B:非Shift左键点击空白结束编辑 ===== + if (m_type == TypeB_Polyline && !shiftPressed && m_editingMode && !m_isAddingLine) { + finishEditing(); + return true; + } + + // ===== 模式A:拖拽点或曲线 ===== + if (m_type == TypeA_Sine && !shiftPressed) { + QPointF pixel = me->localPos(); + double d1 = m_tracer1->selectTest(pixel, false); + double d2 = m_tracer2->selectTest(pixel, false); + double curveDist = m_curve->selectTest(pixel, false); + if (d1 >= 0 && d1 < 15 || d2 >= 0 && d2 < 15 || (curveDist >= 0 && curveDist < 5)) { + if (s_activeItem && s_activeItem != this) s_activeItem->deactivate(); + s_activeItem = this; + setDragPointsVisible(true); + if (d1 >= 0 && d1 < 15) { + m_dragStateA = DraggingPoint1; + setTracerHighlight(m_tracer1, true); + } else if (d2 >= 0 && d2 < 15) { + m_dragStateA = DraggingPoint2; + setTracerHighlight(m_tracer2, true); + } else { + m_dragStateA = DraggingCurveA; + m_lastDragPixelA = pixel; } + return true; + } + } - for (j=0; jlocalPos(); + for (int i = 0; i < m_lines.size(); ++i) { + auto &item = m_lines[i]; + if (item.startTracer->selectTest(pixel, false) >= 0 && item.startTracer->selectTest(pixel, false) < 10) { + if (s_activeItem && s_activeItem != this) s_activeItem->deactivate(); + s_activeItem = this; + setDragPointsVisible(true); + m_dragStateB = DraggingStartPoint; + m_draggedLineIndex = i; + m_bDragStart = pixel; + return true; + } + if (item.endTracer->selectTest(pixel, false) >= 0 && item.endTracer->selectTest(pixel, false) < 10) { + if (s_activeItem && s_activeItem != this) s_activeItem->deactivate(); + s_activeItem = this; + setDragPointsVisible(true); + m_dragStateB = DraggingEndPoint; + m_draggedLineIndex = i; + m_bDragStart = pixel; + return true; + } + } + for (int i = 0; i < m_lines.size(); ++i) { + double dist = m_lines[i].line->selectTest(pixel, false); + if (dist >= 0 && dist < 3) { + if (s_activeItem && s_activeItem != this) s_activeItem->deactivate(); + s_activeItem = this; + setDragPointsVisible(true); + m_dragStateB = DraggingLineOverall; + m_bDragStart = pixel; + return true; + } + } + } - // - drawOne(frac, cs, iType, nLineWidth, crColor); - break; + // ===== 模式C:拖拽点或整体(已完成,非编辑模式) ===== + if (m_type == TypeC_Closed && !shiftPressed && m_cFinished && !m_editingMode) { + QPointF pixel = me->localPos(); + int hitPoint = -1; + for (int i = 0; i < m_labelsC.size(); ++i) { + if (m_labelsC[i]->selectTest(pixel, false) >= 0 && m_labelsC[i]->selectTest(pixel, false) < 10) { + hitPoint = i; + break; + } + } + if (hitPoint >= 0) { + if (s_activeItem && s_activeItem != this) s_activeItem->deactivate(); + s_activeItem = this; + setDragPointsVisible(true); + m_draggingPoint = true; + m_draggedPointIndex = hitPoint; + m_cDragStart = pixel; + return true; + } else { + double curveDist = m_curveC ? m_curveC->selectTest(pixel, false) : -1; + if (curveDist >= 0 && curveDist < 3) { + if (s_activeItem && s_activeItem != this) s_activeItem->deactivate(); + s_activeItem = this; + setDragPointsVisible(true); + m_cDragging = true; + m_cDragStart = pixel; + return true; + } else { + if (s_activeItem == this) { + s_activeItem->deactivate(); + s_activeItem = nullptr; } } } - mrw.CloseTable(iIndex); } - mrw.Close(); //关闭井文件 } + + // 鼠标移动 + if (event->type() == QEvent::MouseMove) { + if (s_activeItem != this) return false; + + if (m_type == TypeA_Sine) { + if (m_dragStateA == DraggingPoint1 || m_dragStateA == DraggingPoint2) { + double newY = m_plot->yAxis->pixelToCoord(me->localPos().y()); + double currentY = (m_dragStateA == DraggingPoint1) ? m_orig_y1 : m_orig_y2; + double deltaY = newY - (currentY + m_offsetYA); + double newOrigY = currentY + deltaY; + newOrigY = qBound(m_depth - 100, newOrigY, m_depth + 100); + if (m_dragStateA == DraggingPoint1) m_orig_y1 = newOrigY; + else m_orig_y2 = newOrigY; + updateCurveFromTargets(); + updateCurvePosition(); + updateTracers(); + m_plot->replot(); + return true; + } else if (m_dragStateA == DraggingCurveA) { + QPointF current = me->localPos(); + double oldX = m_plot->xAxis->pixelToCoord(m_lastDragPixelA.x()); + double newX = m_plot->xAxis->pixelToCoord(current.x()); + double oldY = m_plot->yAxis->pixelToCoord(m_lastDragPixelA.y()); + double newY = m_plot->yAxis->pixelToCoord(current.y()); + double dx = newX - oldX; + double dy = newY - oldY; + m_offsetXA += dx; + m_offsetYA += dy; + updateCurvePosition(); + updateTracers(); + m_plot->replot(); + m_lastDragPixelA = current; + return true; + } + } + else if (m_type == TypeB_Polyline && m_dragStateB != IdleB) { + QPointF current = me->localPos(); + double oldX = m_plot->xAxis->pixelToCoord(m_bDragStart.x()); + double newX = m_plot->xAxis->pixelToCoord(current.x()); + double oldY = m_plot->yAxis->pixelToCoord(m_bDragStart.y()); + double newY = m_plot->yAxis->pixelToCoord(current.y()); + double dx = newX - oldX; + double dy = newY - oldY; + if (m_dragStateB == DraggingLineOverall) { + m_offsetXB += dx; + m_offsetYB += dy; + updateLinesPosition(); + } else if (m_dragStateB == DraggingStartPoint || m_dragStateB == DraggingEndPoint) { + int idx = m_draggedLineIndex; + if (idx >= 0 && idx < m_lines.size()) { + LineItem &item = m_lines[idx]; + if (m_dragStateB == DraggingStartPoint) { + item.startOrig.rx() += dx; + item.startOrig.ry() += dy; + } else { + item.endOrig.rx() += dx; + item.endOrig.ry() += dy; + } + item.line->start->setCoords(item.startOrig.x() + m_offsetXB, item.startOrig.y() + m_offsetYB); + item.line->end->setCoords(item.endOrig.x() + m_offsetXB, item.endOrig.y() + m_offsetYB); + updateLineEndpoints(item); + } + } + m_plot->replot(); + m_bDragStart = current; + return true; + } + else if (m_type == TypeC_Closed) { + if (m_cDragging) { + QPointF current = me->localPos(); + double oldX = m_plot->xAxis->pixelToCoord(m_cDragStart.x()); + double newX = m_plot->xAxis->pixelToCoord(current.x()); + double oldY = m_plot->yAxis->pixelToCoord(m_cDragStart.y()); + double newY = m_plot->yAxis->pixelToCoord(current.y()); + double dx = newX - oldX; + double dy = newY - oldY; + m_offsetXC += dx; + m_offsetYC += dy; + for (int i = 0; i < m_pointsC.size(); ++i) { + m_labelsC[i]->position->setCoords(m_pointsC[i].x() + m_offsetXC, m_pointsC[i].y() + m_offsetYC); + } + updatePolylineC(true); + m_plot->replot(); + m_cDragStart = current; + return true; + } else if (m_draggingPoint) { + QPointF current = me->localPos(); + double oldX = m_plot->xAxis->pixelToCoord(m_cDragStart.x()); + double newX = m_plot->xAxis->pixelToCoord(current.x()); + double oldY = m_plot->yAxis->pixelToCoord(m_cDragStart.y()); + double newY = m_plot->yAxis->pixelToCoord(current.y()); + double dx = newX - oldX; + double dy = newY - oldY; + m_pointsC[m_draggedPointIndex].rx() += dx; + m_pointsC[m_draggedPointIndex].ry() += dy; + m_labelsC[m_draggedPointIndex]->position->setCoords(m_pointsC[m_draggedPointIndex].x() + m_offsetXC, + m_pointsC[m_draggedPointIndex].y() + m_offsetYC); + updatePolylineC(true); + m_plot->replot(); + m_cDragStart = current; + return true; + } + } + } + + // 鼠标释放:发射 dataChanged 信号(仅非编辑模式) + if (event->type() == QEvent::MouseButtonRelease && me->button() == Qt::LeftButton) { + if (s_activeItem == this && !m_editingMode) { + if (m_type == TypeA_Sine && m_dragStateA != IdleA) { + setTracerHighlight(m_tracer1, false); + setTracerHighlight(m_tracer2, false); + m_dragStateA = IdleA; + emit dataChanged(); + return true; + } else if (m_type == TypeB_Polyline && m_dragStateB != IdleB) { + m_dragStateB = IdleB; + m_draggedLineIndex = -1; + emit dataChanged(); + return true; + } else if (m_type == TypeC_Closed) { + if (m_cDragging) { + m_cDragging = false; + emit dataChanged(); + return true; + } else if (m_draggingPoint) { + m_draggingPoint = false; + m_draggedPointIndex = -1; + emit dataChanged(); + return true; + } + } + } + } + return false; } -// -void CPickFrac::drawOne(FRAC_TABLE_Crack frac, QString cs, int iType, int nLineWidth, QColor crColor) +// ==================== 新建裂缝 ==================== +bool CPickFrac::createNewCrack(int iType, double depth) { - int j,nPoint=360; - float x,y,h,oy; - float PI,xScale,xx; - PI=2.*3.14159265/(float)nPoint; - h = frac.AorX/2.0; - oy = -(frac.DEP+h); - - xScale=(float)(nPoint)/(float)(m_iMyWidth); - - QPen pPen(crColor, nLineWidth); - QVector xVec, yVec; - - switch ( iType ) - { - case 1: //正弦曲线 - nPoint = 360; - for(j=0; jxAxis->coordToPixel(tempValue) - - xVec.append(x); - yVec.append(y); - } -// for(j=0; jstart->setCoords(yVec[j], xVec[j]); -// qcpItemLine->end->setCoords(yVec[j+1], xVec[j+1]); -// qcpItemLine->setPen(pPen); -// } - - { - // - m_myCustomPlot->addGraph(); - QString strLineName = ""; - if(strLineName=="") - { - strLineName = QString("曲线 %1").arg(m_myCustomPlot->graphCount()); - } - m_myCustomPlot->graph()->setName(strLineName); - m_myCustomPlot->graph()->setData(xVec, yVec); - m_myCustomPlot->graph()->setLineStyle((QCPGraph::LineStyle)(QCPGraph::lsLine));//lsNone 曲线 lsLine - m_myCustomPlot->graph()->setScatterStyle(QCPScatterStyle((QCPScatterStyle::ScatterShape)(QCPScatterStyle::ssDot)));//ssNone点ssDot - // - QPen graphPen; - graphPen.setColor(crColor); - graphPen.setWidthF(nLineWidth); - graphPen.setStyle(Qt::SolidLine);//实线 - m_myCustomPlot->graph()->setPen(graphPen); + // 从配置文件中查找第一个匹配 iType 的定义,获取颜色和线宽 + FRAC_DEF_Crack def; + bool found = false; + for (const FRAC_DEF_Crack &d : m_FracDef) { + if (d.iType == iType) { + def = d; + found = true; + break; } - break; - case 2: //连线 - nPoint = frac.NUM; - for(j=0; jstart->setCoords(frac.point[j].x/8, -frac.point[j].y); - qcpItemLine->end->setCoords(frac.point[j+1].x/8, -frac.point[j+1].y); - qcpItemLine->setPen(pPen); - j++;//j+2 - } - break; - case 3: // 封闭区域 - nPoint = frac.NUM; - for(j=0; jstart->setCoords(frac.point[j].x / 8, -frac.point[j].y); - if(j>=(nPoint-1)) - { - qcpItemLine->end->setCoords(frac.point[0].x / 8, -frac.point[0].y); - } - else - { - qcpItemLine->end->setCoords(frac.point[j+1].x / 8, -frac.point[j+1].y); - } - qcpItemLine->setPen(pPen); - } - break; - case 4: //直线 - nPoint = frac.NUM; - if(nPoint>=2) - { - QCPItemStraightLine *qcpItemLine = new QCPItemStraightLine(m_myCustomPlot); - qcpItemLine->point1->setCoords(frac.point[0].x, -frac.point[0].y);//位置 - qcpItemLine->point2->setCoords(frac.point[1].x, -frac.point[1].y);//位置 - qcpItemLine->setPen(pPen); - } - break; } + if (!found) { + def.iType = iType; + def.crColor = QColor(255, 0, 0); + def.nLineWidth = 2; + } + + if (!m_myCustomPlot) return false; + double xMin = m_myCustomPlot->xAxis->range().lower; + double xMax = m_myCustomPlot->xAxis->range().upper; + double xCenter = (xMin + xMax) / 2.0; + double xWidth = xMax - xMin; + double yPos = -depth; + + DraggableCrackItem *item = nullptr; + + if (iType == 1) { + item = new DraggableCrackItem(m_myCustomPlot, DraggableCrackItem::TypeA_Sine, def.crColor, def.nLineWidth); + double amplitude = 0.5; + double phase = 0.0; + double width = xWidth * 0.8; + double xScale = 360.0 / width; + double centerY = -(depth + amplitude); + item->setSineData(centerY, amplitude, phase, xScale, width); + item->setCrackCode(def.iCode); + connect(item, &DraggableCrackItem::dataChanged, this, &CPickFrac::saveToFile); + connect(item, &DraggableCrackItem::removeMe, this, &CPickFrac::onRemoveCrackItem); + m_items.append(item); + bool saved = saveToFile(); + m_myCustomPlot->replot(); + return saved; + } + else if (iType == 2) { + item = new DraggableCrackItem(m_myCustomPlot, DraggableCrackItem::TypeB_Polyline, def.crColor, def.nLineWidth); + item->setCrackCode(def.iCode); + connect(item, &DraggableCrackItem::dataChanged, this, &CPickFrac::saveToFile); + connect(item, &DraggableCrackItem::removeMe, this, &CPickFrac::onRemoveCrackItem); + m_items.append(item); + item->startEditing(); + m_myCustomPlot->replot(); + return true; + } + else if (iType == 3) { + item = new DraggableCrackItem(m_myCustomPlot, DraggableCrackItem::TypeC_Closed, def.crColor, def.nLineWidth); + item->setCrackCode(def.iCode); + connect(item, &DraggableCrackItem::dataChanged, this, &CPickFrac::saveToFile); + connect(item, &DraggableCrackItem::removeMe, this, &CPickFrac::onRemoveCrackItem); + m_items.append(item); + item->startEditing(); + m_myCustomPlot->replot(); + return true; + } + return false; } diff --git a/logPlus/PickFrac.h b/logPlus/PickFrac.h index b96ed36..cc3819d 100644 --- a/logPlus/PickFrac.h +++ b/logPlus/PickFrac.h @@ -2,75 +2,190 @@ #define DrawFrac_H #include -#include "qmycustomplot.h" +#include +#include +#include +#include +#include -//裂缝 -//const int iFracType=15; +class QMyCustomPlot; +class QCustomPlot; +class QCPItemCurve; +class QCPItemTracer; +class QCPItemLine; +class QCPCurve; +class QCPItemText; -typedef struct tagPOINTF -{ - float x; - float y; -} POINTF; +static const int iFracType2 = 15; -typedef struct -{ - int iCode; //代码 - QString csName;// 名称 - int iType; //形状代码(1:正弦曲线 2:连线 3:封闭区域) - QColor crColor; //颜色(红 绿 蓝) - int nLineWidth;//线宽度 - int bDraw; // 是否显示 -}FRAC_DEF_Crack; +typedef struct tagPOINTF { float x; float y; } POINTF; -typedef struct -{ - float DEP; - float AorX; //XRMI_DYN_DipHeight - float XETAorH;//XRMI_DYN_Azimuth - float W; - float DIPorS;//XRMI_DYN_Dip_APP - float DIR;//XRMI_DYN_Azimuth - float TDIP; //真倾角 Dip_TRU - float TDIR; //真倾向 Azimuth - float ID;//裂缝代码,type - float NUM; - //float X[16],Y[16];//X0,Y0,X1,Y1,X2,Y2,X3,Y3,X4,Y4,X5,Y5,X6,Y6,X7,Y7,X8,Y8,X9,Y9; - POINTF point[16]; -}FRAC_TABLE_Crack; +typedef struct { + int iCode; + QString csName; + int iType; // 1:正弦曲线 2:连线 3:封闭区域 4:直线 + QColor crColor; + int nLineWidth; + int bDraw; +} FRAC_DEF_Crack; -typedef struct -{ +typedef struct { float DEP; float AorX; float XETAorH; float W; float DIPorS; float DIR; - float ID;//裂缝代码 -}FRAC_TABLE_OLD_Crack; + float TDIP; + float TDIR; + float ID; + float NUM; + POINTF point[16]; +} FRAC_TABLE_Crack; + +typedef struct { + float DEP; + float AorX; + float XETAorH; + float W; + float DIPorS; + float DIR; + float ID; +} FRAC_TABLE_OLD_Crack; + +class DraggableCrackItem; + +class CPickFrac : public QObject +{ + Q_OBJECT -class CPickFrac:public QObject -{ - Q_OBJECT public: CPickFrac(QMyCustomPlot *widget, QString strSlfName, QString csCurve, int iMyWidth); - virtual ~CPickFrac(void); + virtual ~CPickFrac(); + + void setDraggingEnabled(bool enabled); + QList getAllItems() const { return m_items; } + bool saveToFile(); + bool createNewCrack(int iType, double depth); // 根据形状类型创建 public: - QString m_Name; - QString m_strDevi, m_strHazi; - QList m_FracDef; - bool m_bTypeDraw[iFracType]; - QMyCustomPlot *m_myCustomPlot; - int m_iMyWidth=0; -public: + int m_iMyWidth = 0; + QList m_FracDef; + bool m_bTypeDraw[iFracType2]; + void ReadFracDef(); void ReadData(QString strSlfName, QString csCurve); - void drawOne(FRAC_TABLE_Crack frac, QString cs, int iType, int nLineWidth, QColor crColor); + void drawOne(FRAC_TABLE_Crack frac, int iType, int nLineWidth, QColor crColor); -public slots: +protected: + bool eventFilter(QObject *watched, QEvent *event) override; +private slots: + void onRemoveCrackItem(DraggableCrackItem *item); + +private: + QList m_items; + bool m_draggingEnabled = true; + QString m_currentSlfName; + QString m_currentTableName; }; + +// ========== 可拖拽裂缝项 ========== +class DraggableCrackItem : public QObject +{ + Q_OBJECT +public: + enum Type { TypeA_Sine, TypeB_Polyline, TypeC_Closed }; + DraggableCrackItem(QCustomPlot *plot, Type type, const QColor &color, int lineWidth); + ~DraggableCrackItem(); + + void setSineData(double depth, double amplitude, double phase, double xScale, double width); + void setPolylineData(const QVector &points, double scaleX = 1.0, double flipY = -1.0); + void setClosedData(const QVector &points, double scaleX = 1.0, double flipY = -1.0); + void setVisible(bool visible); + void deactivate(); + bool eventFilter(QObject *obj, QEvent *event) override; + + // 保存接口 + Type getType() const { return m_type; } + void setCrackCode(int code) { m_crackCode = code; } + int getCrackCode() const { return m_crackCode; } + double getDepthForSort() const; + void getCurrentFracData(FRAC_TABLE_Crack &data) const; + + // 编辑模式 + void startEditing(); + void finishEditing(); + + // 控制所有拖拽点的可见性 + void setDragPointsVisible(bool visible); + + // 获取当前激活的item(静态) + static DraggableCrackItem* getActiveItem() { return s_activeItem; } + +signals: + void dataChanged(); + void removeMe(DraggableCrackItem* item); + +private: + QCustomPlot *m_plot; + Type m_type; + QColor m_color; + int m_lineWidth; + int m_crackCode = 0; + double m_originalXETAorH = 0.0; + double m_originalAorX = 0.0; + + // 模式A + QCPItemCurve *m_curve = nullptr; + QCPItemTracer *m_tracer1 = nullptr, *m_tracer2 = nullptr; + double m_orig_x1, m_orig_x2, m_orig_y1, m_orig_y2; + double m_orig_startX, m_orig_endX, m_orig_startDirX, m_orig_startDirY, m_orig_endDirX, m_orig_endDirY; + double m_offsetXA = 0.0, m_offsetYA = 0.0; + double m_depth = 0.0, m_endX = 0.0; + enum DragStateA { IdleA, DraggingPoint1, DraggingPoint2, DraggingCurveA } m_dragStateA = IdleA; + QPointF m_lastDragPixelA; + + // 模式B + struct LineItem { + QCPItemLine *line; + QCPItemTracer *startTracer, *endTracer; + QPointF startOrig, endOrig; + }; + QList m_lines; + double m_offsetXB = 0.0, m_offsetYB = 0.0; + bool m_isAddingLine = false; + QPointF m_tempPoint; + enum DragStateB { IdleB, DraggingStartPoint, DraggingEndPoint, DraggingLineOverall } m_dragStateB = IdleB; + QPointF m_bDragStart; + int m_draggedLineIndex = -1; + + // 模式C + QCPCurve *m_curveC = nullptr; + QVector m_pointsC; + QVector m_labelsC; + double m_offsetXC = 0.0, m_offsetYC = 0.0; + bool m_cFinished = false, m_cDragging = false, m_draggingPoint = false; + int m_draggedPointIndex = -1; + QPointF m_cDragStart; + + // 编辑模式标志 + bool m_editingMode = false; + bool m_pendingDelete = false; // 标记是否即将删除 + + // 辅助函数 + void updateCurveFromTargets(); + void updateCurvePosition(); + void updateTracers(); + void setTracerHighlight(QCPItemTracer *tracer, bool highlight); + void updateLineEndpoints(LineItem &item); + void updateLinesPosition(); + void clearLines(); + void updatePolylineC(bool closed); + void clearPolylineC(); + + static QPointer s_activeItem; +}; + #endif diff --git a/logPlus/formdraw.cpp b/logPlus/formdraw.cpp index 9a79368..c0f6837 100644 --- a/logPlus/formdraw.cpp +++ b/logPlus/formdraw.cpp @@ -3995,6 +3995,7 @@ void FormDraw::s_addCrack(QString strUuid, QString strSlfName, QString strWellNa //注意,不对调XY轴 curv->m_bX2Y = false; CPickFrac *pickFrac = new CPickFrac(curv, strSlfName, strWaveName, iMyWidth); + curv->m_cPickFrac = pickFrac; // connect(curv, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(s_mouseWheel(QWheelEvent*))); diff --git a/logPlus/qmycustomplot.cpp b/logPlus/qmycustomplot.cpp index 246040c..090493a 100644 --- a/logPlus/qmycustomplot.cpp +++ b/logPlus/qmycustomplot.cpp @@ -2189,8 +2189,23 @@ void QMyCustomPlot::addCrackObject() double depth = editDepth->text().toDouble(); QString type = cbbType->currentText(); QString showNames = ""; - auto curve = new TransparentDraggableCrackObject(this, strUuid, -depth, type, showNames); - m_mapDraggable_CrackObject[strUuid] = curve; + + if("高导缝" == type) + { + this->m_cPickFrac->createNewCrack(1 ,depth); + } + else if("网状缝" == type) + { + this->m_cPickFrac->createNewCrack(2 ,depth); + } + else if("孔洞" == type) + { + this->m_cPickFrac->createNewCrack(3 ,depth); + } +// auto curve = new CPickFrac(this, strUuid, -depth, type, showNames); + +// m_mapDraggable_CrackObject[strUuid] = curve; + // ========= 这里就是你要的结果!========= // qDebug() << "深度:" << depth << " 类型:" << type; } diff --git a/logPlus/qmycustomplot.h b/logPlus/qmycustomplot.h index 9307111..1f72d54 100644 --- a/logPlus/qmycustomplot.h +++ b/logPlus/qmycustomplot.h @@ -5,10 +5,12 @@ #include "LogIO.h" #include "QCPSizeHandleManager.h" #include "qtColorSchemeComboBox.h" +#include "PickFrac.h" #pragma execution_character_set("utf-8") -const int iFracType=15; +const int iFracType = 15; +class CPickFrac; // #define SideWallCoreWidth 1.2 @@ -765,6 +767,8 @@ public: // void Draw_Jykt(); + CPickFrac *m_cPickFrac; + private: };