fix: Position linear dimension opposite angle to avoid overlap

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
2026-02-16 20:28:17 -07:00
parent f5c7f6d326
commit 7f304bf1f3

View File

@@ -318,6 +318,60 @@ void ViewportWidget::paintGL()
float lineLength = lineVec.length();
if (lineLength > 1e-6) {
double refAngle, lineAngle, angleDiff;
{
QVector3D refDir;
if (property("isChainedLine").toBool()) {
refDir = property("previousLineDirection").value<QVector3D>();
} else {
if (m_currentPlane == SketchPlane::XY || m_currentPlane == SketchPlane::XZ) refDir = QVector3D(1, 0, 0);
else refDir = QVector3D(0, 1, 0);
}
if (angleFromInput) {
QVector3D currentMouseWorldPos = unproject(m_currentMousePos, m_currentPlane);
QVector3D mouseVec = currentMouseWorldPos - startPos;
double mouseAngle;
if (m_currentPlane == SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
else if (m_currentPlane == SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
double refAngleForQuadrant;
if (m_currentPlane == SketchPlane::XY) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
else if (m_currentPlane == SketchPlane::XZ) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
else refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
double relativeMouseAngle = mouseAngle - refAngleForQuadrant;
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
while (relativeMouseAngle > 180.0) relativeMouseAngle -= 360.0;
if (relativeMouseAngle >= 90 || relativeMouseAngle < -90) {
refDir = -refDir;
}
} else {
if (property("isChainedLine").toBool()) {
refDir = -refDir;
}
}
if (m_currentPlane == SketchPlane::XY) {
refAngle = atan2(refDir.z(), refDir.x());
lineAngle = atan2(lineVec.z(), lineVec.x());
} else if (m_currentPlane == SketchPlane::XZ) {
refAngle = atan2(refDir.y(), refDir.x());
lineAngle = atan2(lineVec.y(), lineVec.x());
} else { // YZ
refAngle = atan2(refDir.z(), refDir.y());
lineAngle = atan2(lineVec.z(), lineVec.y());
}
angleDiff = lineAngle - refAngle;
while (angleDiff <= -M_PI) angleDiff += 2 * M_PI;
while (angleDiff > M_PI) angleDiff -= 2 * M_PI;
lineAngle = refAngle + angleDiff;
}
vertices.clear();
QVector3D perpVec;
@@ -329,6 +383,10 @@ void ViewportWidget::paintGL()
perpVec = QVector3D(0, -lineVec.z(), lineVec.y()).normalized();
}
if (angleDiff >= 0) {
perpVec = -perpVec;
}
float offset = 0.05f * -m_camera->zoom();
QVector3D dimStart = startPos + offset * perpVec;
QVector3D dimEnd = worldPos + offset * perpVec;
@@ -365,58 +423,6 @@ void ViewportWidget::paintGL()
// Draw angle dimension
vertices.clear();
QVector3D refDir;
if (property("isChainedLine").toBool()) {
refDir = property("previousLineDirection").value<QVector3D>();
} else {
if (m_currentPlane == SketchPlane::XY || m_currentPlane == SketchPlane::XZ) refDir = QVector3D(1, 0, 0);
else refDir = QVector3D(0, 1, 0);
}
if (angleFromInput) {
QVector3D currentMouseWorldPos = unproject(m_currentMousePos, m_currentPlane);
QVector3D mouseVec = currentMouseWorldPos - startPos;
double mouseAngle;
if (m_currentPlane == SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
else if (m_currentPlane == SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
double refAngleForQuadrant;
if (m_currentPlane == SketchPlane::XY) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
else if (m_currentPlane == SketchPlane::XZ) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
else refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
double relativeMouseAngle = mouseAngle - refAngleForQuadrant;
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
while (relativeMouseAngle > 180.0) relativeMouseAngle -= 360.0;
if (relativeMouseAngle >= 90 || relativeMouseAngle < -90) {
refDir = -refDir;
}
} else {
if (property("isChainedLine").toBool()) {
refDir = -refDir;
}
}
double refAngle, lineAngle;
if (m_currentPlane == SketchPlane::XY) {
refAngle = atan2(refDir.z(), refDir.x());
lineAngle = atan2(lineVec.z(), lineVec.x());
} else if (m_currentPlane == SketchPlane::XZ) {
refAngle = atan2(refDir.y(), refDir.x());
lineAngle = atan2(lineVec.y(), lineVec.x());
} else { // YZ
refAngle = atan2(refDir.z(), refDir.y());
lineAngle = atan2(lineVec.z(), lineVec.y());
}
double angleDiff = lineAngle - refAngle;
while (angleDiff <= -M_PI) angleDiff += 2 * M_PI;
while (angleDiff > M_PI) angleDiff -= 2 * M_PI;
lineAngle = refAngle + angleDiff;
const int numSegments = 30;
const float radius = 0.1f * -m_camera->zoom();
for (int i = 0; i <= numSegments; ++i) {
@@ -651,41 +657,7 @@ void ViewportWidget::paintGL()
QVector3D lineVec = worldPos - startPos;
if (lineVec.length() > 1e-6) {
QVector3D perpVec;
if (m_currentPlane == SketchPlane::XY) {
perpVec = QVector3D(-lineVec.z(), 0, lineVec.x()).normalized();
} else if (m_currentPlane == SketchPlane::XZ) {
perpVec = QVector3D(-lineVec.y(), lineVec.x(), 0).normalized();
} else if (m_currentPlane == SketchPlane::YZ) {
perpVec = QVector3D(0, -lineVec.z(), lineVec.y()).normalized();
}
float offset = 0.05f * -m_camera->zoom();
QVector3D dimStart = startPos + offset * perpVec;
QVector3D dimEnd = worldPos + offset * perpVec;
QVector3D textPos3D = (dimStart + dimEnd) / 2.0f + 0.015f * -m_camera->zoom() * perpVec;
QVector3D screenPos = project(textPos3D, model, projection, rect());
painter.setRenderHint(QPainter::Antialiasing);
QFontMetrics fm(painter.font());
if (screenPos.z() < 1.0f) {
dimText = lengthFromInput ? dimInput : QString::number(lineLength, 'f', 2);
QRect textRect = fm.boundingRect(dimText + "_");
textRect.moveCenter(screenPos.toPoint());
if (property("dimensionEditMode").toString() == "length") {
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, dimText);
}
// Angle dimension text
double refAngle, lineAngle;
QVector3D refDir;
if (property("isChainedLine").toBool()) {
refDir = property("previousLineDirection").value<QVector3D>();
@@ -723,7 +695,6 @@ void ViewportWidget::paintGL()
}
}
double refAngle, lineAngle;
if (m_currentPlane == SketchPlane::XY) {
refAngle = atan2(refDir.z(), refDir.x());
lineAngle = atan2(lineVec.z(), lineVec.x());
@@ -740,7 +711,46 @@ void ViewportWidget::paintGL()
while (angleDiff > M_PI) angleDiff -= 2 * M_PI;
lineAngle = refAngle + angleDiff;
double angleDiffDegrees = qRadiansToDegrees(lineAngle - refAngle);
QVector3D perpVec;
if (m_currentPlane == SketchPlane::XY) {
perpVec = QVector3D(-lineVec.z(), 0, lineVec.x()).normalized();
} else if (m_currentPlane == SketchPlane::XZ) {
perpVec = QVector3D(-lineVec.y(), lineVec.x(), 0).normalized();
} else if (m_currentPlane == SketchPlane::YZ) {
perpVec = QVector3D(0, -lineVec.z(), lineVec.y()).normalized();
}
if (angleDiff >= 0) {
perpVec = -perpVec;
}
float offset = 0.05f * -m_camera->zoom();
QVector3D dimStart = startPos + offset * perpVec;
QVector3D dimEnd = worldPos + offset * perpVec;
QVector3D textPos3D = (dimStart + dimEnd) / 2.0f + 0.015f * -m_camera->zoom() * perpVec;
QVector3D screenPos = project(textPos3D, model, projection, rect());
painter.setRenderHint(QPainter::Antialiasing);
QFontMetrics fm(painter.font());
if (screenPos.z() < 1.0f) {
dimText = lengthFromInput ? dimInput : QString::number(lineLength, 'f', 2);
QRect textRect = fm.boundingRect(dimText + "_");
textRect.moveCenter(screenPos.toPoint());
if (property("dimensionEditMode").toString() == "length") {
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, dimText);
}
// Angle dimension text
double angleDiffDegrees = qRadiansToDegrees(angleDiff);
while (angleDiffDegrees <= -180.0) angleDiffDegrees += 360.0;
while (angleDiffDegrees > 180.0) angleDiffDegrees -= 360.0;