From 96371b0aa6cad41e6285882af16a33f8fcec7ece Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Tue, 3 Mar 2026 16:02:18 -0700 Subject: [PATCH] refactor: Use gp_Ax2 for geometric calculations in RectangleTool Co-authored-by: aider (gemini/gemini-2.5-pro) --- src/RectangleTool.cpp | 483 +++++++++++++++++++----------------------- 1 file changed, 223 insertions(+), 260 deletions(-) diff --git a/src/RectangleTool.cpp b/src/RectangleTool.cpp index 691d586..038f156 100644 --- a/src/RectangleTool.cpp +++ b/src/RectangleTool.cpp @@ -15,6 +15,10 @@ #include #include #include +#include +#include +#include +#include RectangleTool::RectangleTool(ViewportWidget* viewport) : SketchTool(viewport) @@ -35,14 +39,18 @@ void RectangleTool::activate() void RectangleTool::mousePressEvent(QMouseEvent *event) { + auto currentPlaneOpt = m_viewport->currentPlane(); + if (!currentPlaneOpt) return; + const auto& plane = currentPlaneOpt.value(); + gp_Pnt p; if (!m_isDefining) { if (m_viewport->isSnappingOrigin()) { - p.SetCoord(0, 0, 0); + p = plane.Location(); } else if (m_viewport->isSnappingVertex()) { p = m_viewport->snapVertex(); } else { - QVector3D worldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane()); + QVector3D worldPos = m_viewport->unproject(event->pos(), plane); p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z()); } m_firstRectanglePoint = p; @@ -51,8 +59,8 @@ void RectangleTool::mousePressEvent(QMouseEvent *event) m_viewport->setProperty("heightInput", ""); m_viewport->setProperty("dimensionEditMode", "height"); } else { - QVector3D worldPos; - QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z()); + QVector3D worldPosQ; + gp_Pnt startPos = m_firstRectanglePoint; QString widthInput = m_viewport->property("widthInput").toString(); QString heightInput = m_viewport->property("heightInput").toString(); @@ -71,45 +79,35 @@ void RectangleTool::mousePressEvent(QMouseEvent *event) } if (widthFromInput || heightFromInput) { - QVector3D mousePos = m_viewport->unproject(event->pos(), m_viewport->currentPlane()); - QVector3D mouseDir = mousePos - startPos; - double current_w, current_h; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - current_w = qAbs(mouseDir.x()); - current_h = qAbs(mouseDir.y()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - current_w = qAbs(mouseDir.x()); - current_h = qAbs(mouseDir.z()); - } else { // YZ - current_w = qAbs(mouseDir.y()); - current_h = qAbs(mouseDir.z()); - } + QVector3D mousePosQ = m_viewport->unproject(event->pos(), plane); + gp_Pnt mousePos(mousePosQ.x(), mousePosQ.y(), mousePosQ.z()); + + gp_Pnt2d startPos2d = ElCLib::To2d(startPos, plane); + gp_Pnt2d mousePos2d = ElCLib::To2d(mousePos, plane); + + double current_w = qAbs(mousePos2d.X() - startPos2d.X()); + double current_h = qAbs(mousePos2d.Y() - startPos2d.Y()); + double rect_w = widthFromInput ? inputWidth : current_w; double rect_h = heightFromInput ? inputHeight : current_h; - int signX = (mouseDir.x() >= 0) ? 1 : -1; - int signY = (mouseDir.y() >= 0) ? 1 : -1; - int signZ = (mouseDir.z() >= 0) ? 1 : -1; - worldPos = startPos; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - worldPos.setX(startPos.x() + signX * rect_w); - worldPos.setY(startPos.y() + signY * rect_h); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - worldPos.setX(startPos.x() + signX * rect_w); - worldPos.setZ(startPos.z() + signZ * rect_h); - } else { // YZ - worldPos.setY(startPos.y() + signY * rect_w); - worldPos.setZ(startPos.z() + signZ * rect_h); - } + + int signX = (mousePos2d.X() >= startPos2d.X()) ? 1 : -1; + int signY = (mousePos2d.Y() >= startPos2d.Y()) ? 1 : -1; + + gp_Pnt2d endPos2d(startPos2d.X() + signX * rect_w, startPos2d.Y() + signY * rect_h); + gp_Pnt endPos3d = ElCLib::To3d(endPos2d, plane); + worldPosQ = QVector3D(endPos3d.X(), endPos3d.Y(), endPos3d.Z()); } else { if (m_viewport->isSnappingOrigin()) { - worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0); + const auto& origin = plane.Location(); + worldPosQ.setX(origin.X()); worldPosQ.setY(origin.Y()); worldPosQ.setZ(origin.Z()); } else if (m_viewport->isSnappingVertex()) { - worldPos = QVector3D(m_viewport->snapVertex().X(), m_viewport->snapVertex().Y(), m_viewport->snapVertex().Z()); + worldPosQ = QVector3D(m_viewport->snapVertex().X(), m_viewport->snapVertex().Y(), m_viewport->snapVertex().Z()); } else { - worldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane()); + worldPosQ = m_viewport->unproject(event->pos(), plane); } } - p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z()); + p.SetCoord(worldPosQ.x(), worldPosQ.y(), worldPosQ.z()); emit m_viewport->rectangleAdded(m_firstRectanglePoint, p); deactivate(); } @@ -122,8 +120,12 @@ void RectangleTool::mouseMoveEvent(QMouseEvent *event) void RectangleTool::finalizeCreation() { - QVector3D worldPos; - QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z()); + auto currentPlaneOpt = m_viewport->currentPlane(); + if (!currentPlaneOpt) return; + const auto& plane = currentPlaneOpt.value(); + + QVector3D worldPosQ; + gp_Pnt startPos = m_firstRectanglePoint; QString widthInput = m_viewport->property("widthInput").toString(); QString heightInput = m_viewport->property("heightInput").toString(); @@ -142,41 +144,30 @@ void RectangleTool::finalizeCreation() } if (widthFromInput || heightFromInput) { - QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); - QVector3D mouseDir = mousePos - startPos; - double current_w, current_h; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - current_w = qAbs(mouseDir.x()); - current_h = qAbs(mouseDir.y()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - current_w = qAbs(mouseDir.x()); - current_h = qAbs(mouseDir.z()); - } else { // YZ - current_w = qAbs(mouseDir.y()); - current_h = qAbs(mouseDir.z()); - } + QVector3D mousePosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane); + gp_Pnt mousePos(mousePosQ.x(), mousePosQ.y(), mousePosQ.z()); + + gp_Pnt2d startPos2d = ElCLib::To2d(startPos, plane); + gp_Pnt2d mousePos2d = ElCLib::To2d(mousePos, plane); + + double current_w = qAbs(mousePos2d.X() - startPos2d.X()); + double current_h = qAbs(mousePos2d.Y() - startPos2d.Y()); + double rect_w = widthFromInput ? inputWidth : current_w; double rect_h = heightFromInput ? inputHeight : current_h; - int signX = (mouseDir.x() >= 0) ? 1 : -1; - int signY = (mouseDir.y() >= 0) ? 1 : -1; - int signZ = (mouseDir.z() >= 0) ? 1 : -1; - worldPos = startPos; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - worldPos.setX(startPos.x() + signX * rect_w); - worldPos.setY(startPos.y() + signY * rect_h); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - worldPos.setX(startPos.x() + signX * rect_w); - worldPos.setZ(startPos.z() + signZ * rect_h); - } else { // YZ - worldPos.setY(startPos.y() + signY * rect_w); - worldPos.setZ(startPos.z() + signZ * rect_h); - } + + int signX = (mousePos2d.X() >= startPos2d.X()) ? 1 : -1; + int signY = (mousePos2d.Y() >= startPos2d.Y()) ? 1 : -1; + + gp_Pnt2d endPos2d(startPos2d.X() + signX * rect_w, startPos2d.Y() + signY * rect_h); + gp_Pnt endPos3d = ElCLib::To3d(endPos2d, plane); + worldPosQ = QVector3D(endPos3d.X(), endPos3d.Y(), endPos3d.Z()); } else { - worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + worldPosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane); } gp_Pnt p; - p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z()); + p.SetCoord(worldPosQ.x(), worldPosQ.y(), worldPosQ.z()); emit m_viewport->rectangleAdded(m_firstRectanglePoint, p); deactivate(); @@ -184,216 +175,188 @@ void RectangleTool::finalizeCreation() void RectangleTool::paintGL() { - if (m_isDefining) { - QVector vertices; - QVector3D worldPos; - QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z()); + if (!m_isDefining) return; + auto currentPlaneOpt = m_viewport->currentPlane(); + if (!currentPlaneOpt) return; + const auto& plane = currentPlaneOpt.value(); - QString widthInput = m_viewport->property("widthInput").toString(); - QString heightInput = m_viewport->property("heightInput").toString(); - bool widthFromInput = false; - bool heightFromInput = false; - double inputWidth = 0, inputHeight = 0; + QVector vertices; + QVector3D worldPosQ; + gp_Pnt startPos = m_firstRectanglePoint; - if (!widthInput.isEmpty()) { - bool ok; - inputWidth = widthInput.toDouble(&ok); - if (ok) widthFromInput = true; - } - if (!heightInput.isEmpty()) { - bool ok; - inputHeight = heightInput.toDouble(&ok); - if (ok) heightFromInput = true; - } + QString widthInput = m_viewport->property("widthInput").toString(); + QString heightInput = m_viewport->property("heightInput").toString(); + bool widthFromInput = false; + bool heightFromInput = false; + double inputWidth = 0, inputHeight = 0; - QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); - - if (widthFromInput || heightFromInput) { - QVector3D mouseDir = mousePos - startPos; - double current_w, current_h; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - current_w = qAbs(mouseDir.x()); - current_h = qAbs(mouseDir.y()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - current_w = qAbs(mouseDir.x()); - current_h = qAbs(mouseDir.z()); - } else { // YZ - current_w = qAbs(mouseDir.y()); - current_h = qAbs(mouseDir.z()); - } - double rect_w = widthFromInput ? inputWidth : current_w; - double rect_h = heightFromInput ? inputHeight : current_h; - int signX = (mouseDir.x() >= 0) ? 1 : -1; - int signY = (mouseDir.y() >= 0) ? 1 : -1; - int signZ = (mouseDir.z() >= 0) ? 1 : -1; - worldPos = startPos; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - worldPos.setX(startPos.x() + signX * rect_w); - worldPos.setY(startPos.y() + signY * rect_h); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - worldPos.setX(startPos.x() + signX * rect_w); - worldPos.setZ(startPos.z() + signZ * rect_h); - } else { // YZ - worldPos.setY(startPos.y() + signY * rect_w); - worldPos.setZ(startPos.z() + signZ * rect_h); - } - } else { - worldPos = mousePos; - if (m_viewport->isSnappingOrigin()) { - worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0); - } else if (m_viewport->isSnappingVertex()) { - worldPos.setX(m_viewport->snapVertex().X()); worldPos.setY(m_viewport->snapVertex().Y()); worldPos.setZ(m_viewport->snapVertex().Z()); - } - } - - QVector3D p1 = startPos; - QVector3D p2, p3, p4; - p3 = worldPos; - - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - p2.setX(p3.x()); p2.setY(p1.y()); p2.setZ(p1.z()); - p4.setX(p1.x()); p4.setY(p3.y()); p4.setZ(p1.z()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - p2.setX(p3.x()); p2.setY(p1.y()); p2.setZ(p1.z()); - p4.setX(p1.x()); p4.setY(p1.y()); p4.setZ(p3.z()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) { - p2.setX(p1.x()); p2.setY(p3.y()); p2.setZ(p1.z()); - p4.setX(p1.x()); p4.setY(p1.y()); p4.setZ(p3.z()); - } - - vertices << p1.x() << p1.y() << p1.z(); - vertices << p2.x() << p2.y() << p2.z(); - vertices << p2.x() << p2.y() << p2.z(); - vertices << p3.x() << p3.y() << p3.z(); - vertices << p3.x() << p3.y() << p3.z(); - vertices << p4.x() << p4.y() << p4.z(); - vertices << p4.x() << p4.y() << p4.z(); - vertices << p1.x() << p1.y() << p1.z(); - - m_viewport->shaderProgram()->setUniformValue(m_viewport->colorLoc(), QVector4D(1.0f, 1.0f, 0.0f, 1.0f)); - m_viewport->vbo().bind(); - m_viewport->vbo().allocate(vertices.constData(), vertices.size() * sizeof(GLfloat)); - glDrawArrays(GL_LINES, 0, 8); + if (!widthInput.isEmpty()) { + bool ok; + inputWidth = widthInput.toDouble(&ok); + if (ok) widthFromInput = true; } + if (!heightInput.isEmpty()) { + bool ok; + inputHeight = heightInput.toDouble(&ok); + if (ok) heightFromInput = true; + } + + QVector3D mousePosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane); + gp_Pnt mousePos(mousePosQ.x(), mousePosQ.y(), mousePosQ.z()); + + if (widthFromInput || heightFromInput) { + gp_Pnt2d startPos2d = ElCLib::To2d(startPos, plane); + gp_Pnt2d mousePos2d = ElCLib::To2d(mousePos, plane); + + double current_w = qAbs(mousePos2d.X() - startPos2d.X()); + double current_h = qAbs(mousePos2d.Y() - startPos2d.Y()); + + double rect_w = widthFromInput ? inputWidth : current_w; + double rect_h = heightFromInput ? inputHeight : current_h; + + int signX = (mousePos2d.X() >= startPos2d.X()) ? 1 : -1; + int signY = (mousePos2d.Y() >= startPos2d.Y()) ? 1 : -1; + + gp_Pnt2d endPos2d(startPos2d.X() + signX * rect_w, startPos2d.Y() + signY * rect_h); + gp_Pnt endPos3d = ElCLib::To3d(endPos2d, plane); + worldPosQ = QVector3D(endPos3d.X(), endPos3d.Y(), endPos3d.Z()); + } else { + worldPosQ = mousePosQ; + if (m_viewport->isSnappingOrigin()) { + const auto& origin = plane.Location(); + worldPosQ.setX(origin.X()); worldPosQ.setY(origin.Y()); worldPosQ.setZ(origin.Z()); + } else if (m_viewport->isSnappingVertex()) { + worldPosQ.setX(m_viewport->snapVertex().X()); worldPosQ.setY(m_viewport->snapVertex().Y()); worldPosQ.setZ(m_viewport->snapVertex().Z()); + } + } + + gp_Pnt p1_3d = startPos; + gp_Pnt p3_3d(worldPosQ.x(), worldPosQ.y(), worldPosQ.z()); + gp_Pnt2d p1_2d = ElCLib::To2d(p1_3d, plane); + gp_Pnt2d p3_2d = ElCLib::To2d(p3_3d, plane); + + gp_Pnt2d p2_2d(p3_2d.X(), p1_2d.Y()); + gp_Pnt2d p4_2d(p1_2d.X(), p3_2d.Y()); + + gp_Pnt p2_3d = ElCLib::To3d(p2_2d, plane); + gp_Pnt p4_3d = ElCLib::To3d(p4_2d, plane); + + vertices << p1_3d.X() << p1_3d.Y() << p1_3d.Z(); + vertices << p2_3d.X() << p2_3d.Y() << p2_3d.Z(); + vertices << p2_3d.X() << p2_3d.Y() << p2_3d.Z(); + vertices << p3_3d.X() << p3_3d.Y() << p3_3d.Z(); + vertices << p3_3d.X() << p3_3d.Y() << p3_3d.Z(); + vertices << p4_3d.X() << p4_3d.Y() << p4_3d.Z(); + vertices << p4_3d.X() << p4_3d.Y() << p4_3d.Z(); + vertices << p1_3d.X() << p1_3d.Y() << p1_3d.Z(); + + m_viewport->shaderProgram()->setUniformValue(m_viewport->colorLoc(), QVector4D(1.0f, 1.0f, 0.0f, 1.0f)); + m_viewport->vbo().bind(); + m_viewport->vbo().allocate(vertices.constData(), vertices.size() * sizeof(GLfloat)); + glDrawArrays(GL_LINES, 0, 8); } void RectangleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) { - if (m_isDefining) { - QVector3D worldPos; - QVector3D p1_3d(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z()); + if (!m_isDefining) return; + auto currentPlaneOpt = m_viewport->currentPlane(); + if (!currentPlaneOpt) return; + const auto& plane = currentPlaneOpt.value(); - QString widthInput = m_viewport->property("widthInput").toString(); - QString heightInput = m_viewport->property("heightInput").toString(); - bool widthFromInput = false; - bool heightFromInput = false; - double inputWidth = 0, inputHeight = 0; + QVector3D worldPosQ; + gp_Pnt p1_3d = m_firstRectanglePoint; - if (!widthInput.isEmpty()) { - bool ok; - inputWidth = widthInput.toDouble(&ok); - if (ok) widthFromInput = true; - } - if (!heightInput.isEmpty()) { - bool ok; - inputHeight = heightInput.toDouble(&ok); - if (ok) heightFromInput = true; - } + QString widthInput = m_viewport->property("widthInput").toString(); + QString heightInput = m_viewport->property("heightInput").toString(); + bool widthFromInput = false; + bool heightFromInput = false; + double inputWidth = 0, inputHeight = 0; - QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + if (!widthInput.isEmpty()) { + bool ok; + inputWidth = widthInput.toDouble(&ok); + if (ok) widthFromInput = true; + } + if (!heightInput.isEmpty()) { + bool ok; + inputHeight = heightInput.toDouble(&ok); + if (ok) heightFromInput = true; + } - if (widthFromInput || heightFromInput) { - QVector3D mouseDir = mousePos - p1_3d; - double current_w, current_h; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - current_w = qAbs(mouseDir.x()); - current_h = qAbs(mouseDir.y()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - current_w = qAbs(mouseDir.x()); - current_h = qAbs(mouseDir.z()); - } else { // YZ - current_w = qAbs(mouseDir.y()); - current_h = qAbs(mouseDir.z()); - } - double rect_w = widthFromInput ? inputWidth : current_w; - double rect_h = heightFromInput ? inputHeight : current_h; - int signX = (mouseDir.x() >= 0) ? 1 : -1; - int signY = (mouseDir.y() >= 0) ? 1 : -1; - int signZ = (mouseDir.z() >= 0) ? 1 : -1; - worldPos = p1_3d; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - worldPos.setX(p1_3d.x() + signX * rect_w); - worldPos.setY(p1_3d.y() + signY * rect_h); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - worldPos.setX(p1_3d.x() + signX * rect_w); - worldPos.setZ(p1_3d.z() + signZ * rect_h); - } else { // YZ - worldPos.setY(p1_3d.y() + signY * rect_w); - worldPos.setZ(p1_3d.z() + signZ * rect_h); - } - } else { - worldPos = mousePos; - if (m_viewport->isSnappingOrigin()) { - worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0); - } else if (m_viewport->isSnappingVertex()) { - worldPos.setX(m_viewport->snapVertex().X()); worldPos.setY(m_viewport->snapVertex().Y()); worldPos.setZ(m_viewport->snapVertex().Z()); - } - } - QVector3D p3_3d = worldPos; - QVector3D p2_3d, p4_3d; + QVector3D mousePosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane); + gp_Pnt mousePos(mousePosQ.x(), mousePosQ.y(), mousePosQ.z()); - double w, h; + if (widthFromInput || heightFromInput) { + gp_Pnt2d startPos2d = ElCLib::To2d(p1_3d, plane); + gp_Pnt2d mousePos2d = ElCLib::To2d(mousePos, plane); - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - p2_3d.setX(p3_3d.x()); p2_3d.setY(p1_3d.y()); p2_3d.setZ(p1_3d.z()); - p4_3d.setX(p1_3d.x()); p4_3d.setY(p3_3d.y()); p4_3d.setZ(p1_3d.z()); - w = qAbs(p3_3d.x() - p1_3d.x()); - h = qAbs(p3_3d.y() - p1_3d.y()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - p2_3d.setX(p3_3d.x()); p2_3d.setY(p1_3d.y()); p2_3d.setZ(p1_3d.z()); - p4_3d.setX(p1_3d.x()); p4_3d.setY(p1_3d.y()); p4_3d.setZ(p3_3d.z()); - w = qAbs(p3_3d.x() - p1_3d.x()); - h = qAbs(p3_3d.z() - p1_3d.z()); - } else { // YZ - p2_3d.setX(p1_3d.x()); p2_3d.setY(p3_3d.y()); p2_3d.setZ(p1_3d.z()); - p4_3d.setX(p1_3d.x()); p4_3d.setY(p1_3d.y()); p4_3d.setZ(p3_3d.z()); - w = qAbs(p3_3d.y() - p1_3d.y()); - h = qAbs(p3_3d.z() - p1_3d.z()); - } + double current_w = qAbs(mousePos2d.X() - startPos2d.X()); + double current_h = qAbs(mousePos2d.Y() - startPos2d.Y()); - painter.setRenderHint(QPainter::Antialiasing); - QFontMetrics fm(painter.font()); + double rect_w = widthFromInput ? inputWidth : current_w; + double rect_h = heightFromInput ? inputHeight : current_h; + int signX = (mousePos2d.X() >= startPos2d.X()) ? 1 : -1; + int signY = (mousePos2d.Y() >= startPos2d.Y()) ? 1 : -1; - // Width dimension - QVector3D widthTextPos3D = (p1_3d + p2_3d) / 2.0f; - QVector3D screenPosW = m_viewport->project(widthTextPos3D, modelView, projection, m_viewport->rect()); - if (screenPosW.z() < 1.0f) { - QString widthText = widthFromInput ? widthInput : QString::number(w, 'f', 2); - QRect textRect = fm.boundingRect(widthText + "__"); - textRect.moveCenter(screenPosW.toPoint() + QPoint(0, (p3_3d.z() > p1_3d.z() || p3_3d.y() > p1_3d.y()) ? -15 : 15)); - if (m_viewport->property("dimensionEditMode").toString() == "width") { - painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(64, 128, 255)); - } else { - painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(50, 50, 50)); - } - painter.setPen(Qt::white); - painter.drawText(textRect, Qt::AlignCenter, widthText); - } - - // Height dimension - QVector3D heightTextPos3D = (p2_3d + p3_3d) / 2.0f; - QVector3D screenPosH = m_viewport->project(heightTextPos3D, modelView, projection, m_viewport->rect()); - if (screenPosH.z() < 1.0f) { - QString heightText = heightFromInput ? heightInput : QString::number(h, 'f', 2); - QRect textRect = fm.boundingRect(heightText + "__"); - textRect.moveCenter(screenPosH.toPoint() + QPoint((p3_3d.x() > p1_3d.x()) ? 15 : -15, 0)); - if (m_viewport->property("dimensionEditMode").toString() == "height") { - painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(64, 128, 255)); - } else { - painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(50, 50, 50)); - } - painter.setPen(Qt::white); - painter.drawText(textRect, Qt::AlignCenter, heightText); + gp_Pnt2d endPos2d(startPos2d.X() + signX * rect_w, startPos2d.Y() + signY * rect_h); + gp_Pnt endPos3d = ElCLib::To3d(endPos2d, plane); + worldPosQ = QVector3D(endPos3d.X(), endPos3d.Y(), endPos3d.Z()); + } else { + worldPosQ = mousePosQ; + if (m_viewport->isSnappingOrigin()) { + const auto& origin = plane.Location(); + worldPosQ.setX(origin.X()); worldPosQ.setY(origin.Y()); worldPosQ.setZ(origin.Z()); + } else if (m_viewport->isSnappingVertex()) { + worldPosQ.setX(m_viewport->snapVertex().X()); worldPosQ.setY(m_viewport->snapVertex().Y()); worldPosQ.setZ(m_viewport->snapVertex().Z()); } } + gp_Pnt p3_3d(worldPosQ.x(), worldPosQ.y(), worldPosQ.z()); + gp_Pnt p2_3d, p4_3d; + + gp_Pnt2d p1_2d = ElCLib::To2d(p1_3d, plane); + gp_Pnt2d p3_2d = ElCLib::To2d(p3_3d, plane); + gp_Pnt2d p2_2d(p3_2d.X(), p1_2d.Y()); + p2_3d = ElCLib::To3d(p2_2d, plane); + + double w = qAbs(p3_2d.X() - p1_2d.X()); + double h = qAbs(p3_2d.Y() - p1_2d.Y()); + + painter.setRenderHint(QPainter::Antialiasing); + QFontMetrics fm(painter.font()); + + QVector3D p1_q(p1_3d.X(), p1_3d.Y(), p1_3d.Z()); + QVector3D p2_q(p2_3d.X(), p2_3d.Y(), p2_3d.Z()); + QVector3D p3_q(p3_3d.X(), p3_3d.Y(), p3_3d.Z()); + + // Width dimension + QVector3D widthTextPos3D = (p1_q + p2_q) / 2.0f; + QVector3D screenPosW = m_viewport->project(widthTextPos3D, modelView, projection, m_viewport->rect()); + if (screenPosW.z() < 1.0f) { + QString widthText = widthFromInput ? widthInput : QString::number(w, 'f', 2); + QRect textRect = fm.boundingRect(widthText + "__"); + textRect.moveCenter(screenPosW.toPoint() + QPoint(0, (p3_2d.Y() > p1_2d.Y()) ? -15 : 15)); + if (m_viewport->property("dimensionEditMode").toString() == "width") { + painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(64, 128, 255)); + } else { + painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(50, 50, 50)); + } + painter.setPen(Qt::white); + painter.drawText(textRect, Qt::AlignCenter, widthText); + } + + // Height dimension + QVector3D heightTextPos3D = (p2_q + p3_q) / 2.0f; + QVector3D screenPosH = m_viewport->project(heightTextPos3D, modelView, projection, m_viewport->rect()); + if (screenPosH.z() < 1.0f) { + QString heightText = heightFromInput ? heightInput : QString::number(h, 'f', 2); + QRect textRect = fm.boundingRect(heightText + "__"); + textRect.moveCenter(screenPosH.toPoint() + QPoint((p3_2d.X() > p1_2d.X()) ? 15 : -15, 0)); + if (m_viewport->property("dimensionEditMode").toString() == "height") { + painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(64, 128, 255)); + } else { + painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(50, 50, 50)); + } + painter.setPen(Qt::white); + painter.drawText(textRect, Qt::AlignCenter, heightText); + } }