From 79c78f060178a8473889782e56a8d40223f4c495 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Tue, 3 Mar 2026 16:07:13 -0700 Subject: [PATCH] refactor: Refactor LineTool to use gp_Ax2 for sketch plane operations Co-authored-by: aider (gemini/gemini-2.5-pro) --- src/LineTool.cpp | 478 ++++++++++++++++++++++++----------------------- 1 file changed, 242 insertions(+), 236 deletions(-) diff --git a/src/LineTool.cpp b/src/LineTool.cpp index 750536c..e2b5c89 100644 --- a/src/LineTool.cpp +++ b/src/LineTool.cpp @@ -13,6 +13,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include LineTool::LineTool(ViewportWidget* viewport) : SketchTool(viewport) @@ -34,6 +40,10 @@ void LineTool::activate() void LineTool::mousePressEvent(QMouseEvent *event) { + auto currentPlaneOpt = m_viewport->currentPlane(); + if (!currentPlaneOpt) return; + const auto& plane = currentPlaneOpt.value(); + gp_Pnt p; QString dimInput = m_viewport->property("dimensionInput").toString(); QString angleInput = m_viewport->property("angleInput").toString(); @@ -64,19 +74,23 @@ void LineTool::mousePressEvent(QMouseEvent *event) if (m_viewport->property("isChainedLine").toBool()) { refDir = m_viewport->property("previousLineDirection").value(); } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refDir = QVector3D(1, 0, 0); - else refDir = QVector3D(0, 1, 0); + const auto& xDir = plane.XDirection(); + refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } - QVector3D currentMouseWorldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPos = m_viewport->unproject(event->pos(), plane); QVector3D mouseVec = currentMouseWorldPos - startPos; - double mouseAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x())); - else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y())); - double refAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x())); - else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y())); + + gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z()); + gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z()); + gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z()); + + gp_Pnt2d startPnt2d = ElCLib::To2d(startPnt, plane); + gp_Pnt2d mousePnt2d = ElCLib::To2d(mousePnt, plane); + gp_Dir2d refDir2d = ElCLib::To2d(plane, refDirGp); + + gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d); + double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X())); + double refAngle = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X())); double relativeMouseAngle = mouseAngle - refAngle; while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0; while (relativeMouseAngle > 180.0) relativeMouseAngle -= 360.0; @@ -91,10 +105,9 @@ void LineTool::mousePressEvent(QMouseEvent *event) snappedAngle = -inputAngleDegrees; } double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle); - QVector3D finalDir; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad)); - else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad)); + gp_Dir2d finalDir2d(cos(finalAngleRad), sin(finalAngleRad)); + gp_Dir finalDir3d = ElCLib::To3d(finalDir2d, plane); + QVector3D finalDir(finalDir3d.X(), finalDir3d.Y(), finalDir3d.Z()); double lineLength; if (lengthFromInput) lineLength = inputLength; else { @@ -103,34 +116,37 @@ void LineTool::mousePressEvent(QMouseEvent *event) } worldPos = startPos + lineLength * finalDir; } else if (lengthFromInput) { - QVector3D currentMouseWorldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPos = m_viewport->unproject(event->pos(), plane); QVector3D dir = (currentMouseWorldPos - startPos); if (dir.length() > 1e-6) { dir.normalize(); worldPos = startPos + inputLength * dir; } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos = startPos + QVector3D(inputLength, 0, 0); - else worldPos = startPos + QVector3D(0, inputLength, 0); + const auto& xDir = plane.XDirection(); + worldPos = startPos + inputLength * QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } } p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z()); } else { 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()); - if (m_viewport->isSnappingHorizontal()) { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setY(m_firstLinePoint.Y()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setZ(m_firstLinePoint.Z()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setZ(m_firstLinePoint.Z()); - } else if (m_viewport->isSnappingVertical()) { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setX(m_firstLinePoint.X()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setX(m_firstLinePoint.X()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setY(m_firstLinePoint.Y()); + QVector3D worldPosQ = m_viewport->unproject(event->pos(), plane); + gp_Pnt worldPos(worldPosQ.x(), worldPosQ.y(), worldPosQ.z()); + + if (m_viewport->isSnappingHorizontal() || m_viewport->isSnappingVertical()) { + gp_Pnt2d worldPos2d = ElCLib::To2d(worldPos, plane); + gp_Pnt2d firstPoint2d = ElCLib::To2d(m_firstLinePoint, plane); + if (m_viewport->isSnappingHorizontal()) { + worldPos2d.SetY(firstPoint2d.Y()); + } else { // vertical + worldPos2d.SetX(firstPoint2d.X()); + } + worldPos = ElCLib::To3d(worldPos2d, plane); } - p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z()); + p = worldPos; } } @@ -157,27 +173,27 @@ void LineTool::mousePressEvent(QMouseEvent *event) void LineTool::mouseMoveEvent(QMouseEvent *event) { + auto currentPlaneOpt = m_viewport->currentPlane(); + if (!m_isDefining || !currentPlaneOpt) return; + const auto& plane = currentPlaneOpt.value(); + bool oldIsSnappingHorizontal = m_viewport->isSnappingHorizontal(); bool oldIsSnappingVertical = m_viewport->isSnappingVertical(); m_viewport->setSnappingHorizontal(false); m_viewport->setSnappingVertical(false); if (m_isDefining && !m_viewport->isSnappingOrigin() && !m_viewport->isSnappingVertex()) { - QVector3D worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); - QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z()); - QVector3D delta = worldPos - startPos; + QVector3D worldPosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane); + gp_Pnt worldPos(worldPosQ.x(), worldPosQ.y(), worldPosQ.z()); + gp_Pnt startPos = m_firstLinePoint; - if (delta.length() > 1e-6) { + gp_Pnt2d worldPos2d = ElCLib::To2d(worldPos, plane); + gp_Pnt2d startPos2d = ElCLib::To2d(startPos, plane); + gp_Vec2d delta(startPos2d, worldPos2d); + + if (delta.Magnitude() > 1e-6) { const double snapAngleThreshold = qDegreesToRadians(2.0); - double angle = 0; - - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - angle = atan2(delta.y(), delta.x()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - angle = atan2(delta.z(), delta.x()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) { - angle = atan2(delta.z(), delta.y()); - } + double angle = atan2(delta.Y(), delta.X()); if (qAbs(sin(angle)) < sin(snapAngleThreshold)) { m_viewport->setSnappingHorizontal(true); @@ -194,6 +210,10 @@ void LineTool::mouseMoveEvent(QMouseEvent *event) void LineTool::finalizeCreation() { + auto currentPlaneOpt = m_viewport->currentPlane(); + if (!currentPlaneOpt) return; + const auto& plane = currentPlaneOpt.value(); + QVector3D worldPos; QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z()); // This is duplicated from paintGL to ensure consistent line creation @@ -220,19 +240,23 @@ void LineTool::finalizeCreation() if (m_viewport->property("isChainedLine").toBool()) { refDir = m_viewport->property("previousLineDirection").value(); } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refDir = QVector3D(1, 0, 0); - else refDir = QVector3D(0, 1, 0); + const auto& xDir = plane.XDirection(); + refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } - QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); QVector3D mouseVec = currentMouseWorldPos - startPos; - double mouseAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x())); - else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y())); - double refAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x())); - else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y())); + + gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z()); + gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z()); + gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z()); + + gp_Pnt2d startPnt2d = ElCLib::To2d(startPnt, plane); + gp_Pnt2d mousePnt2d = ElCLib::To2d(mousePnt, plane); + gp_Dir2d refDir2d = ElCLib::To2d(plane, refDirGp); + + gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d); + double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X())); + double refAngle = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X())); double relativeMouseAngle = mouseAngle - refAngle; while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0; while (relativeMouseAngle > 180.0) relativeMouseAngle -= 360.0; @@ -247,10 +271,9 @@ void LineTool::finalizeCreation() snappedAngle = -inputAngleDegrees; } double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle); - QVector3D finalDir; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad)); - else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad)); + gp_Dir2d finalDir2d(cos(finalAngleRad), sin(finalAngleRad)); + gp_Dir finalDir3d = ElCLib::To3d(finalDir2d, plane); + QVector3D finalDir(finalDir3d.X(), finalDir3d.Y(), finalDir3d.Z()); double lineLength; if (lengthFromInput) lineLength = inputLength; else { @@ -259,17 +282,17 @@ void LineTool::finalizeCreation() } worldPos = startPos + lineLength * finalDir; } else if (lengthFromInput) { - QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); QVector3D dir = (currentMouseWorldPos - startPos); if (dir.length() > 1e-6) { dir.normalize(); worldPos = startPos + inputLength * dir; } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos = startPos + QVector3D(inputLength, 0, 0); - else worldPos = startPos + QVector3D(0, inputLength, 0); + const auto& xDir = plane.XDirection(); + worldPos = startPos + inputLength * QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } } else { - worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + worldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); } gp_Pnt p; @@ -289,6 +312,10 @@ void LineTool::finalizeCreation() void LineTool::paintGL() { if (m_isDefining) { + auto currentPlaneOpt = m_viewport->currentPlane(); + if (!currentPlaneOpt) return; + const auto& plane = currentPlaneOpt.value(); + QVector vertices; QVector3D worldPos; QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z()); @@ -316,26 +343,24 @@ void LineTool::paintGL() if (m_viewport->property("isChainedLine").toBool()) { refDir = m_viewport->property("previousLineDirection").value(); } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - refDir = QVector3D(1, 0, 0); - } else { // YZ - refDir = QVector3D(0, 1, 0); - } + const auto& xDir = plane.XDirection(); + refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } - QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); QVector3D mouseVec = currentMouseWorldPos - startPos; - // Quadrant snapping - double mouseAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x())); - else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y())); + gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z()); + gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z()); + gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z()); - double refAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x())); - else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y())); + gp_Pnt2d startPnt2d = ElCLib::To2d(startPnt, plane); + gp_Pnt2d mousePnt2d = ElCLib::To2d(mousePnt, plane); + gp_Dir2d refDir2d = ElCLib::To2d(plane, refDirGp); + + gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d); + double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X())); + double refAngle = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X())); double relativeMouseAngle = mouseAngle - refAngle; while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0; @@ -353,10 +378,9 @@ void LineTool::paintGL() } double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle); - QVector3D finalDir; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad)); - else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad)); + gp_Dir2d finalDir2d(cos(finalAngleRad), sin(finalAngleRad)); + gp_Dir finalDir3d = ElCLib::To3d(finalDir2d, plane); + QVector3D finalDir(finalDir3d.X(), finalDir3d.Y(), finalDir3d.Z()); double lineLength; if (lengthFromInput) { @@ -368,33 +392,34 @@ void LineTool::paintGL() worldPos = startPos + lineLength * finalDir; } else if (lengthFromInput) { - QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); QVector3D dir = (currentMouseWorldPos - startPos); if (dir.length() > 1e-6) { dir.normalize(); worldPos = startPos + inputLength * dir; } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - worldPos = startPos + QVector3D(inputLength, 0, 0); - } else { - worldPos = startPos + QVector3D(0, inputLength, 0); - } + const auto& xDir = plane.XDirection(); + worldPos = startPos + inputLength * QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } } else { - worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + worldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); + gp_Pnt worldPosPnt(worldPos.x(), worldPos.y(), worldPos.z()); + if (m_viewport->isSnappingOrigin()) { - worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0); + worldPosPnt = plane.Location(); } else if (m_viewport->isSnappingVertex()) { - worldPos.setX(m_viewport->snapVertex().X()); worldPos.setY(m_viewport->snapVertex().Y()); worldPos.setZ(m_viewport->snapVertex().Z()); - } else if (m_viewport->isSnappingHorizontal()) { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setY(m_firstLinePoint.Y()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setZ(m_firstLinePoint.Z()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setZ(m_firstLinePoint.Z()); - } else if (m_viewport->isSnappingVertical()) { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setX(m_firstLinePoint.X()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setX(m_firstLinePoint.X()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setY(m_firstLinePoint.Y()); + worldPosPnt = m_viewport->snapVertex(); + } else if (m_viewport->isSnappingHorizontal() || m_viewport->isSnappingVertical()) { + gp_Pnt2d worldPos2d = ElCLib::To2d(worldPosPnt, plane); + gp_Pnt2d firstPoint2d = ElCLib::To2d(m_firstLinePoint, plane); + if (m_viewport->isSnappingHorizontal()) { + worldPos2d.SetY(firstPoint2d.Y()); + } else { // vertical + worldPos2d.SetX(firstPoint2d.X()); + } + worldPosPnt = ElCLib::To3d(worldPos2d, plane); } + worldPos.setX(worldPosPnt.X()); worldPos.setY(worldPosPnt.Y()); worldPos.setZ(worldPosPnt.Z()); } vertices << m_firstLinePoint.X() << m_firstLinePoint.Y() << m_firstLinePoint.Z(); @@ -416,23 +441,25 @@ void LineTool::paintGL() if (m_viewport->property("isChainedLine").toBool()) { refDir = m_viewport->property("previousLineDirection").value(); } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refDir = QVector3D(1, 0, 0); - else refDir = QVector3D(0, 1, 0); + const auto& xDir = plane.XDirection(); + refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } if (angleFromInput) { - QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); QVector3D mouseVec = currentMouseWorldPos - startPos; - double mouseAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x())); - else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y())); + gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z()); + gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z()); + gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z()); - double refAngleForQuadrant; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.y(), refDir.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.x())); - else refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.y())); + gp_Pnt2d startPnt2d = ElCLib::To2d(startPnt, plane); + gp_Pnt2d mousePnt2d = ElCLib::To2d(mousePnt, plane); + gp_Dir2d refDir2d = ElCLib::To2d(plane, refDirGp); + + gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d); + double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X())); + double refAngleForQuadrant = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X())); double relativeMouseAngle = mouseAngle - refAngleForQuadrant; while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0; @@ -447,16 +474,14 @@ void LineTool::paintGL() } } - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - refAngle = atan2(refDir.y(), refDir.x()); - lineAngle = atan2(lineVec.y(), lineVec.x()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - refAngle = atan2(refDir.z(), refDir.x()); - lineAngle = atan2(lineVec.z(), lineVec.x()); - } else { // YZ - refAngle = atan2(refDir.z(), refDir.y()); - lineAngle = atan2(lineVec.z(), lineVec.y()); - } + gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z()); + gp_Dir lineDirGp(lineVec.x(), lineVec.y(), lineVec.z()); + + gp_Dir2d refDir2d = ElCLib::To2d(plane, refDirGp); + gp_Dir2d lineDir2d = ElCLib::To2d(plane, lineDirGp); + + refAngle = atan2(refDir2d.Y(), refDir2d.X()); + lineAngle = atan2(lineDir2d.Y(), lineDir2d.X()); angleDiff = lineAngle - refAngle; while (angleDiff <= -M_PI) angleDiff += 2 * M_PI; @@ -466,14 +491,11 @@ void LineTool::paintGL() vertices.clear(); - QVector3D perpVec; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - perpVec = QVector3D(-lineVec.y(), lineVec.x(), 0).normalized(); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - perpVec = QVector3D(-lineVec.z(), 0, lineVec.x()).normalized(); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) { - perpVec = QVector3D(0, -lineVec.z(), lineVec.y()).normalized(); - } + gp_Dir lineDirGp(lineVec.x(), lineVec.y(), lineVec.z()); + gp_Dir2d lineDir2d = ElCLib::To2d(plane, lineDirGp); + gp_Dir2d perpDir2d(-lineDir2d.Y(), lineDir2d.X()); + gp_Dir perpDir3d = ElCLib::To3d(perpDir2d, plane); + QVector3D perpVec(perpDir3d.X(), perpDir3d.Y(), perpDir3d.Z()); if (angleDiff < 0) { perpVec = -perpVec; @@ -520,9 +542,11 @@ void LineTool::paintGL() for (int i = 0; i <= numSegments; ++i) { double angle = refAngle + (lineAngle - refAngle) * i / numSegments; QVector3D p; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) p = startPos + radius * QVector3D(cos(angle), sin(angle), 0); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) p = startPos + radius * QVector3D(cos(angle), 0, sin(angle)); - else p = startPos + radius * QVector3D(0, cos(angle), sin(angle)); + const auto& xDir = plane.XDirection(); + const auto& yDir = plane.YDirection(); + QVector3D u_axis(xDir.X(), xDir.Y(), xDir.Z()); + QVector3D v_axis(yDir.X(), yDir.Y(), yDir.Z()); + p = startPos + radius * (cos(angle) * u_axis + sin(angle) * v_axis); vertices << p.x() << p.y() << p.z(); } glLineWidth(1.0f); @@ -540,17 +564,13 @@ void LineTool::paintGL() // End arrowhead QVector3D endPoint(vertices[vertices.size()-3], vertices[vertices.size()-2], vertices[vertices.size()-1]); double endAngle = lineAngle; + const auto& xDir = plane.XDirection(); + const auto& yDir = plane.YDirection(); + QVector3D u_axis(xDir.X(), xDir.Y(), xDir.Z()); + QVector3D v_axis(yDir.X(), yDir.Y(), yDir.Z()); QVector3D radialDir_end, tangentDir_end; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - radialDir_end = QVector3D(cos(endAngle), sin(endAngle), 0); - tangentDir_end = QVector3D(-sin(endAngle), cos(endAngle), 0); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - radialDir_end = QVector3D(cos(endAngle), 0, sin(endAngle)); - tangentDir_end = QVector3D(-sin(endAngle), 0, cos(endAngle)); - } else { - radialDir_end = QVector3D(0, cos(endAngle), sin(endAngle)); - tangentDir_end = QVector3D(0, -sin(endAngle), cos(endAngle)); - } + radialDir_end = cos(endAngle) * u_axis + sin(endAngle) * v_axis; + tangentDir_end = -sin(endAngle) * u_axis + cos(endAngle) * v_axis; QVector3D arc_arrow_base_end = endPoint - sign * arcArrowLength * tangentDir_end; QVector3D arc_arrowP1_end = arc_arrow_base_end + arcArrowWidth * radialDir_end; QVector3D arc_arrowP2_end = arc_arrow_base_end - arcArrowWidth * radialDir_end; @@ -561,16 +581,8 @@ void LineTool::paintGL() QVector3D startPoint(vertices[0], vertices[1], vertices[2]); double startAngle = refAngle; QVector3D radialDir_start, tangentDir_start; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - radialDir_start = QVector3D(cos(startAngle), sin(startAngle), 0); - tangentDir_start = QVector3D(-sin(startAngle), cos(startAngle), 0); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - radialDir_start = QVector3D(cos(startAngle), 0, sin(startAngle)); - tangentDir_start = QVector3D(-sin(startAngle), 0, cos(startAngle)); - } else { - radialDir_start = QVector3D(0, cos(startAngle), sin(startAngle)); - tangentDir_start = QVector3D(0, -sin(startAngle), cos(startAngle)); - } + radialDir_start = cos(startAngle) * u_axis + sin(startAngle) * v_axis; + tangentDir_start = -sin(startAngle) * u_axis + cos(startAngle) * v_axis; QVector3D arc_arrow_base_start = startPoint + sign * arcArrowLength * tangentDir_start; QVector3D arc_arrowP1_start = arc_arrow_base_start + arcArrowWidth * radialDir_start; QVector3D arc_arrowP2_start = arc_arrow_base_start - arcArrowWidth * radialDir_start; @@ -589,29 +601,21 @@ void LineTool::paintGL() QVector3D midPoint = (startPos + worldPos) / 2.0; const float indicatorSize = 0.02f * -m_viewport->camera()->zoom(); const float indicatorOffset = 0.02f * -m_viewport->camera()->zoom(); + const auto& xDir = plane.XDirection(); + const auto& yDir = plane.YDirection(); + QVector3D u_axis(xDir.X(), xDir.Y(), xDir.Z()); + QVector3D v_axis(yDir.X(), yDir.Y(), yDir.Z()); + + QVector3D p1, p2; if (m_viewport->isSnappingHorizontal()) { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - vertices << midPoint.x() - indicatorSize << midPoint.y() + indicatorOffset << midPoint.z(); - vertices << midPoint.x() + indicatorSize << midPoint.y() + indicatorOffset << midPoint.z(); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - vertices << midPoint.x() - indicatorSize << midPoint.y() << midPoint.z() + indicatorOffset; - vertices << midPoint.x() + indicatorSize << midPoint.y() << midPoint.z() + indicatorOffset; - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) { - vertices << midPoint.x() << midPoint.y() - indicatorSize << midPoint.z() + indicatorOffset; - vertices << midPoint.x() << midPoint.y() + indicatorSize << midPoint.z() + indicatorOffset; - } + p1 = midPoint - indicatorSize * v_axis + indicatorOffset * u_axis; + p2 = midPoint + indicatorSize * v_axis + indicatorOffset * u_axis; } else { // m_isSnappingVertical - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - vertices << midPoint.x() + indicatorOffset << midPoint.y() - indicatorSize << midPoint.z(); - vertices << midPoint.x() + indicatorOffset << midPoint.y() + indicatorSize << midPoint.z(); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - vertices << midPoint.x() + indicatorOffset << midPoint.y() << midPoint.z() - indicatorSize; - vertices << midPoint.x() + indicatorOffset << midPoint.y() << midPoint.z() + indicatorSize; - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) { - vertices << midPoint.x() << midPoint.y() + indicatorOffset << midPoint.z() - indicatorSize; - vertices << midPoint.x() << midPoint.y() + indicatorOffset << midPoint.z() + indicatorSize; - } + p1 = midPoint - indicatorSize * u_axis + indicatorOffset * v_axis; + p2 = midPoint + indicatorSize * u_axis + indicatorOffset * v_axis; } + vertices << p1.x() << p1.y() << p1.z(); + vertices << p2.x() << p2.y() << p2.z(); m_viewport->vbo().bind(); m_viewport->vbo().allocate(vertices.constData(), vertices.size() * sizeof(GLfloat)); glDrawArrays(GL_LINES, 0, 2); @@ -622,6 +626,10 @@ void LineTool::paintGL() void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection) { if (m_isDefining) { + auto currentPlaneOpt = m_viewport->currentPlane(); + if (!currentPlaneOpt) return; + const auto& plane = currentPlaneOpt.value(); + QVector3D worldPos; QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z()); QString dimText; @@ -651,25 +659,24 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa if (m_viewport->property("isChainedLine").toBool()) { refDir = m_viewport->property("previousLineDirection").value(); } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - refDir = QVector3D(1, 0, 0); - } else { // YZ - refDir = QVector3D(0, 1, 0); - } + const auto& xDir = plane.XDirection(); + refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } - QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); QVector3D mouseVec = currentMouseWorldPos - startPos; - double mouseAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x())); - else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y())); + gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z()); + gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z()); + gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z()); - double refAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x())); - else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y())); + gp_Pnt2d startPnt2d = ElCLib::To2d(startPnt, plane); + gp_Pnt2d mousePnt2d = ElCLib::To2d(mousePnt, plane); + gp_Dir2d refDir2d = ElCLib::To2d(plane, refDirGp); + + gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d); + double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X())); + double refAngle = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X())); double relativeMouseAngle = mouseAngle - refAngle; while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0; @@ -687,10 +694,9 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa } double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle); - QVector3D finalDir; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad)); - else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad)); + gp_Dir2d finalDir2d(cos(finalAngleRad), sin(finalAngleRad)); + gp_Dir finalDir3d = ElCLib::To3d(finalDir2d, plane); + QVector3D finalDir(finalDir3d.X(), finalDir3d.Y(), finalDir3d.Z()); if (lengthFromInput) { lineLength = inputLength; @@ -702,33 +708,34 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa } else if (lengthFromInput) { lineLength = inputLength; - QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); QVector3D dir = (currentMouseWorldPos - startPos); if (dir.length() > 1e-6) { dir.normalize(); worldPos = startPos + inputLength * dir; } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - worldPos = startPos + QVector3D(inputLength, 0, 0); - } else { - worldPos = startPos + QVector3D(0, inputLength, 0); - } + const auto& xDir = plane.XDirection(); + worldPos = startPos + inputLength * QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } } else { - worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + worldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane); + gp_Pnt worldPosPnt(worldPos.x(), worldPos.y(), worldPos.z()); + if (m_viewport->isSnappingOrigin()) { - worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0); + worldPosPnt = plane.Location(); } else if (m_viewport->isSnappingVertex()) { - worldPos.setX(m_viewport->snapVertex().X()); worldPos.setY(m_viewport->snapVertex().Y()); worldPos.setZ(m_viewport->snapVertex().Z()); - } else if (m_viewport->isSnappingHorizontal()) { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setY(m_firstLinePoint.Y()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setZ(m_firstLinePoint.Z()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setZ(m_firstLinePoint.Z()); - } else if (m_viewport->isSnappingVertical()) { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setX(m_firstLinePoint.X()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setX(m_firstLinePoint.X()); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setY(m_firstLinePoint.Y()); + worldPosPnt = m_viewport->snapVertex(); + } else if (m_viewport->isSnappingHorizontal() || m_viewport->isSnappingVertical()) { + gp_Pnt2d worldPos2d = ElCLib::To2d(worldPosPnt, plane); + gp_Pnt2d firstPoint2d = ElCLib::To2d(m_firstLinePoint, plane); + if (m_viewport->isSnappingHorizontal()) { + worldPos2d.SetY(firstPoint2d.Y()); + } else { // vertical + worldPos2d.SetX(firstPoint2d.X()); + } + worldPosPnt = ElCLib::To3d(worldPos2d, plane); } + worldPos.setX(worldPosPnt.X()); worldPos.setY(worldPosPnt.Y()); worldPos.setZ(worldPosPnt.Z()); lineLength = (worldPos - startPos).length(); } @@ -739,24 +746,26 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa if (m_viewport->property("isChainedLine").toBool()) { refDir = m_viewport->property("previousLineDirection").value(); } else { - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refDir = QVector3D(1, 0, 0); - else refDir = QVector3D(0, 1, 0); + const auto& xDir = plane.XDirection(); + refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z()); } - QVector3D currentMouseWorldPosForText = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane()); + QVector3D currentMouseWorldPosForText = m_viewport->unproject(m_viewport->currentMousePos(), plane); QVector3D mouseVecForText = currentMouseWorldPosForText - startPos; if (angleFromInput) { if (mouseVecForText.length() > 1e-6) { - double mouseAngle; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVecForText.y(), mouseVecForText.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVecForText.z(), mouseVecForText.x())); - else mouseAngle = qRadiansToDegrees(atan2(mouseVecForText.z(), mouseVecForText.y())); + gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z()); + gp_Pnt mousePnt(currentMouseWorldPosForText.x(), currentMouseWorldPosForText.y(), currentMouseWorldPosForText.z()); + gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z()); - double refAngleForQuadrant; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.y(), refDir.x())); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.x())); - else refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.y())); + gp_Pnt2d startPnt2d = ElCLib::To2d(startPnt, plane); + gp_Pnt2d mousePnt2d = ElCLib::To2d(mousePnt, plane); + gp_Dir2d refDir2d = ElCLib::To2d(plane, refDirGp); + + gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d); + double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X())); + double refAngleForQuadrant = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X())); double relativeMouseAngle = mouseAngle - refAngleForQuadrant; while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0; @@ -772,30 +781,25 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa } } - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - refAngle = atan2(refDir.y(), refDir.x()); - lineAngle = atan2(lineVec.y(), lineVec.x()); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - refAngle = atan2(refDir.z(), refDir.x()); - lineAngle = atan2(lineVec.z(), lineVec.x()); - } else { // YZ - refAngle = atan2(refDir.z(), refDir.y()); - lineAngle = atan2(lineVec.z(), lineVec.y()); - } + gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z()); + gp_Dir lineDirGp(lineVec.x(), lineVec.y(), lineVec.z()); + + gp_Dir2d refDir2d = ElCLib::To2d(plane, refDirGp); + gp_Dir2d lineDir2d = ElCLib::To2d(plane, lineDirGp); + + refAngle = atan2(refDir2d.Y(), refDir2d.X()); + lineAngle = atan2(lineDir2d.Y(), lineDir2d.X()); double angleDiff = lineAngle - refAngle; while (angleDiff <= -M_PI) angleDiff += 2 * M_PI; while (angleDiff > M_PI) angleDiff -= 2 * M_PI; lineAngle = refAngle + angleDiff; - QVector3D perpVec; - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) { - perpVec = QVector3D(-lineVec.y(), lineVec.x(), 0).normalized(); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) { - perpVec = QVector3D(-lineVec.z(), 0, lineVec.x()).normalized(); - } else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) { - perpVec = QVector3D(0, -lineVec.z(), lineVec.y()).normalized(); - } + gp_Dir lineDirGp(lineVec.x(), lineVec.y(), lineVec.z()); + gp_Dir2d lineDir2d = ElCLib::To2d(plane, lineDirGp); + gp_Dir2d perpDir2d(-lineDir2d.Y(), lineDir2d.X()); + gp_Dir perpDir3d = ElCLib::To3d(perpDir2d, plane); + QVector3D perpVec(perpDir3d.X(), perpDir3d.Y(), perpDir3d.Z()); if (angleDiff < 0) { perpVec = -perpVec; @@ -838,9 +842,11 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa QVector3D textPos3DAngle; float textOffset = 0.035f * -m_viewport->camera()->zoom(); - if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) textPos3DAngle = startPos + (radius + textOffset) * QVector3D(cos(midAngle), sin(midAngle), 0); - else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) textPos3DAngle = startPos + (radius + textOffset) * QVector3D(cos(midAngle), 0, sin(midAngle)); - else textPos3DAngle = startPos + (radius + textOffset) * QVector3D(0, cos(midAngle), sin(midAngle)); + const auto& xDir = plane.XDirection(); + const auto& yDir = plane.YDirection(); + QVector3D u_axis(xDir.X(), xDir.Y(), xDir.Z()); + QVector3D v_axis(yDir.X(), yDir.Y(), yDir.Z()); + textPos3DAngle = startPos + (radius + textOffset) * (cos(midAngle) * u_axis + sin(midAngle) * v_axis); QVector3D screenPosAngle = m_viewport->project(textPos3DAngle, modelView, projection, m_viewport->rect()); if (screenPosAngle.z() < 1.0f) {