Sat, 05 Mar 2022 18:26:18 +0200
Added a toggle for setting whether axes are drawn
icons/axes.png | file | annotate | diff | comparison | revisions | |
ldforge.qrc | file | annotate | diff | comparison | revisions | |
src/configurationoptions.txt | file | annotate | diff | comparison | revisions | |
src/gl/common.h | file | annotate | diff | comparison | revisions | |
src/mainwindow.cpp | file | annotate | diff | comparison | revisions | |
src/mainwindow.h | file | annotate | diff | comparison | revisions | |
src/mainwindow.ui | file | annotate | diff | comparison | revisions | |
src/ui/canvas.cpp | file | annotate | diff | comparison | revisions | |
src/ui/canvas.h | file | annotate | diff | comparison | revisions |
--- 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 @@ <file>icons/close-circle-outline.png</file> <file>icons/navigate-outline.png</file> <file>icons/trash-bin-outline.png</file> + <file>icons/axes.png</file> </qresource> </RCC>
--- 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{}
--- 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; }; }
--- 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<int>(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());
--- 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();
--- 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 @@ <addaction name="actionRenderStylePickScene"/> <addaction name="separator"/> <addaction name="actionAdjustGridToView"/> + <addaction name="actionDrawAxes"/> </widget> <widget class="QMenu" name="menuEdit"> <property name="title"> @@ -103,6 +104,7 @@ <addaction name="actionRenderStyleNormal"/> <addaction name="actionRenderStyleBfc"/> <addaction name="actionRenderStyleRandom"/> + <addaction name="actionDrawAxes"/> </widget> <widget class="QToolBar" name="editToolBar"> <property name="windowTitle"> @@ -258,6 +260,18 @@ <string>Del</string> </property> </action> + <action name="actionDrawAxes"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="icon"> + <iconset resource="../ldforge.qrc"> + <normaloff>:/icons/axes.png</normaloff>:/icons/axes.png</iconset> + </property> + <property name="text"> + <string>Draw axes</string> + </property> + </action> </widget> <resources> <include location="../ldforge.qrc"/>
--- 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<qreal>(fontMetrics.ascent())}; - break; - case geom::RectangleSide::Left: - break; - case geom::RectangleSide::Bottom: - position += QPointF{0, static_cast<qreal>(-fontMetrics.descent())}; - break; - case geom::RectangleSide::Right: - position += QPointF{static_cast<qreal>(-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<qreal>(fontMetrics.ascent())}; + break; + case geom::RectangleSide::Left: + break; + case geom::RectangleSide::Bottom: + position += QPointF{0, static_cast<qreal>(-fontMetrics.descent())}; + break; + case geom::RectangleSide::Right: + position += QPointF{static_cast<qreal>(-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
--- 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<QPointF> convertWorldPointsToScreenPoints(const std::vector<glm::vec3>& worldPoints) const; Q_SLOT void updateCanvasRenderPreferences(); + void renderAxesLabels(QPainter& painter); std::optional<GridProgram> gridProgram; std::optional<AxesProgram> axesProgram; std::optional<VertexProgram> vertexProgram;