# HG changeset patch # User Teemu Piippo # Date 1646497578 -7200 # Node ID 9b655f6fe5a174534c03ba7cc77860683fb488ec # Parent 6da096930534e5e33098b5df5a0f7be2a904aace Added a toggle for setting whether axes are drawn diff -r 6da096930534 -r 9b655f6fe5a1 icons/axes.png Binary file icons/axes.png has changed diff -r 6da096930534 -r 9b655f6fe5a1 ldforge.qrc --- a/ldforge.qrc Sat Mar 05 17:18:44 2022 +0200 +++ b/ldforge.qrc Sat Mar 05 18:26:18 2022 +0200 @@ -28,5 +28,6 @@ icons/close-circle-outline.png icons/navigate-outline.png icons/trash-bin-outline.png + icons/axes.png diff -r 6da096930534 -r 9b655f6fe5a1 src/configurationoptions.txt --- a/src/configurationoptions.txt Sat Mar 05 17:18:44 2022 +0200 +++ b/src/configurationoptions.txt Sat Mar 05 18:26:18 2022 +0200 @@ -16,6 +16,7 @@ option LineAntiAliasing = true option RenderStyle = 0 option DrawWireframe = false +option DrawAxes = true option MainWindowGeometry = QByteArray{} option MainSplitterState = QByteArray{} option RecentFiles = QStringList{} diff -r 6da096930534 -r 9b655f6fe5a1 src/gl/common.h --- a/src/gl/common.h Sat Mar 05 17:18:44 2022 +0200 +++ b/src/gl/common.h Sat Mar 05 18:26:18 2022 +0200 @@ -221,5 +221,6 @@ QColor selectedColor{32, 32, 255}; GLfloat lineThickness = 2.0f; bool lineAntiAliasing = true; + bool drawAxes = true; }; } diff -r 6da096930534 -r 9b655f6fe5a1 src/mainwindow.cpp --- a/src/mainwindow.cpp Sat Mar 05 17:18:44 2022 +0200 +++ b/src/mainwindow.cpp Sat Mar 05 18:26:18 2022 +0200 @@ -88,6 +88,7 @@ this->setRenderStyle(data.payload); }); } + connect(this->ui->actionDrawAxes, &QAction::triggered, this, &MainWindow::setDrawAxes); this->updateTitle(); this->restoreStartupSettings(); this->restoreSettings(); @@ -265,6 +266,13 @@ this->updateRenderPreferences(); } +void MainWindow::setDrawAxes(bool drawAxes) +{ + this->renderPreferences.drawAxes = drawAxes; + this->saveSettings(); + this->updateRenderPreferences(); +} + /** * @brief Handles the "Save" (Ctrl+S) action */ @@ -437,6 +445,7 @@ QAction* action = data.memberInstance(this->ui.get()); action->setChecked(this->renderPreferences.style == data.payload); } + this->ui->actionDrawAxes->setChecked(this->renderPreferences.drawAxes); } /** @@ -448,6 +457,7 @@ this->settings.setRecentFiles(this->recentlyOpenedFiles); this->settings.setMainSplitterState(this->documentSplitterState); this->settings.setRenderStyle(static_cast(this->renderPreferences.style)); + this->settings.setDrawAxes(this->renderPreferences.drawAxes); this->libraries.storeToSettings(&this->settings); } @@ -469,6 +479,7 @@ this->renderPreferences.lineThickness = this->settings.lineThickness(); this->renderPreferences.lineAntiAliasing = this->settings.lineAntiAliasing(); this->renderPreferences.selectedColor = this->settings.selectedColor(); + this->renderPreferences.drawAxes = this->settings.drawAxes(); const QString systemLocale = QLocale::system().name(); const QVariant defaultLocale = this->settings.locale(); this->changeLanguage(defaultLocale.toString()); diff -r 6da096930534 -r 9b655f6fe5a1 src/mainwindow.h --- a/src/mainwindow.h Sat Mar 05 17:18:44 2022 +0200 +++ b/src/mainwindow.h Sat Mar 05 18:26:18 2022 +0200 @@ -44,6 +44,7 @@ void updateRecentlyOpenedDocumentsMenu(); void openRecentFile(); void setRenderStyle(gl::RenderStyle renderStyle); + Q_SLOT void setDrawAxes(bool drawAxes); void actionSave(); void actionSaveAs(); void actionClose(); diff -r 6da096930534 -r 9b655f6fe5a1 src/mainwindow.ui --- a/src/mainwindow.ui Sat Mar 05 17:18:44 2022 +0200 +++ b/src/mainwindow.ui Sat Mar 05 18:26:18 2022 +0200 @@ -63,6 +63,7 @@ + @@ -103,6 +104,7 @@ + @@ -258,6 +260,18 @@ Del + + + true + + + + :/icons/axes.png:/icons/axes.png + + + Draw axes + + diff -r 6da096930534 -r 9b655f6fe5a1 src/ui/canvas.cpp --- a/src/ui/canvas.cpp Sat Mar 05 17:18:44 2022 +0200 +++ b/src/ui/canvas.cpp Sat Mar 05 18:26:18 2022 +0200 @@ -120,6 +120,7 @@ if (this->renderPreferences.style != gl::RenderStyle::PickScene) { // Render axes + if (this->renderPreferences.drawAxes) { glLineWidth(5); glEnable(GL_LINE_SMOOTH); @@ -161,56 +162,9 @@ { QPainter painter{this}; painter.setRenderHint(QPainter::Antialiasing); - QFont font; - //font.setStyle(QFont::StyleItalic); - painter.setFont(font); - QFontMetrics fontMetrics{font}; - const auto renderText = [&](const QString& text, const geom::PointOnRectagle& intersection) + if (this->renderPreferences.drawAxes) { - QPointF position = toQPointF(intersection.position); - const geom::RectangleSide side = intersection.side; - switch (side) - { - case geom::RectangleSide::Top: - position += QPointF{0, static_cast(fontMetrics.ascent())}; - break; - case geom::RectangleSide::Left: - break; - case geom::RectangleSide::Bottom: - position += QPointF{0, static_cast(-fontMetrics.descent())}; - break; - case geom::RectangleSide::Right: - position += QPointF{static_cast(-fontMetrics.horizontalAdvance(text)), 0}; - break; - } - painter.drawText(position, text); - }; - const QRectF box {QPointF{0, 0}, sizeToSizeF(this->size())}; - const QPointF p1 = this->modelToScreenCoordinates(glm::vec3{0, 0, 0}); - - static const struct - { - QString text; - glm::vec3 direction; - } directions[] = - { - {"+𝑥", {1, 0, 0}}, - {"-𝑥", {-1, 0, 0}}, - {"+𝑦", {0, 1, 0}}, - {"-𝑦", {0, -1, 0}}, - {"+𝑧", {0, 0, 1}}, - {"-𝑧", {0, 0, -1}}, - }; - for (const auto& axis : directions) - { - const QPointF x_p = this->modelToScreenCoordinates(axis.direction); - const auto intersection = geom::rayRectangleIntersection( - geom::rayFromPoints(toVec2(p1), toVec2(x_p)), - box); - if (intersection.has_value()) - { - renderText(axis.text, *intersection); - } + this->renderAxesLabels(painter); } if (this->overpaintCallback != nullptr) { @@ -221,6 +175,64 @@ } /** + * @brief Renders labels such as +x at the ends of axes at the screen + * @param painter + */ +void Canvas::renderAxesLabels(QPainter& painter) +{ + QFont font; + //font.setStyle(QFont::StyleItalic); + painter.setFont(font); + QFontMetrics fontMetrics{font}; + const auto renderText = [&](const QString& text, const geom::PointOnRectagle& intersection) + { + QPointF position = toQPointF(intersection.position); + const geom::RectangleSide side = intersection.side; + switch (side) + { + case geom::RectangleSide::Top: + position += QPointF{0, static_cast(fontMetrics.ascent())}; + break; + case geom::RectangleSide::Left: + break; + case geom::RectangleSide::Bottom: + position += QPointF{0, static_cast(-fontMetrics.descent())}; + break; + case geom::RectangleSide::Right: + position += QPointF{static_cast(-fontMetrics.horizontalAdvance(text)), 0}; + break; + } + painter.drawText(position, text); + }; + const QRectF box {QPointF{0, 0}, sizeToSizeF(this->size())}; + const QPointF p1 = this->modelToScreenCoordinates(glm::vec3{0, 0, 0}); + static const struct + { + QString text; + glm::vec3 direction; + } directions[] = + { + {"+𝑥", {1, 0, 0}}, + {"-𝑥", {-1, 0, 0}}, + {"+𝑦", {0, 1, 0}}, + {"-𝑦", {0, -1, 0}}, + {"+𝑧", {0, 0, 1}}, + {"-𝑧", {0, 0, -1}}, + }; + for (const auto& axis : directions) + { + const QPointF x_p = this->modelToScreenCoordinates(axis.direction); + const auto intersection = geom::rayRectangleIntersection( + geom::rayFromPoints(toVec2(p1), toVec2(x_p)), + box); + if (intersection.has_value()) + { + renderText(axis.text, *intersection); + } + } +} + +/** * @brief Draws a polyline to where the specified vector of 3D points would appear on the screen. * @param painter Painter to use to draw with * @param points 3D points to render diff -r 6da096930534 -r 9b655f6fe5a1 src/ui/canvas.h --- a/src/ui/canvas.h Sat Mar 05 17:18:44 2022 +0200 +++ b/src/ui/canvas.h Sat Mar 05 18:26:18 2022 +0200 @@ -47,6 +47,7 @@ bool isGridPerpendicularToScreen(float threshold) const; QVector convertWorldPointsToScreenPoints(const std::vector& worldPoints) const; Q_SLOT void updateCanvasRenderPreferences(); + void renderAxesLabels(QPainter& painter); std::optional gridProgram; std::optional axesProgram; std::optional vertexProgram;