Wed, 08 Jun 2022 22:29:44 +0300
More refactor, merged main.h, basics.h and utility.h into one header file basics.h and removed plenty of unused code
--- a/CMakeLists.txt Wed Jun 08 20:41:21 2022 +0300 +++ b/CMakeLists.txt Wed Jun 08 22:29:44 2022 +0300 @@ -68,13 +68,11 @@ src/invert.h src/ldrawalgorithm.h src/libraries.h - src/main.h src/model.h src/parser.h src/polygoncache.h src/ring.h src/uiutilities.h - src/utility.h src/version.h src/vertexmap.h src/gl/axesprogram.h
--- a/src/basics.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/basics.h Wed Jun 08 22:29:44 2022 +0300 @@ -18,13 +18,13 @@ #pragma once #include <algorithm> -#include <cstdio> -#include <cstdlib> -#include <cstring> #include <cmath> +#include <compare> +#include <memory> #include <optional> #include <type_traits> -#include <QMatrix4x4> +#include <QDataStream> +#include <QDebug> #include <QObject> #include <QPointF> #include <QSet> @@ -32,64 +32,24 @@ #include <QStringList> #include <QVariant> #include <QVector> -#include <QVector3D> #include <glm/glm.hpp> - -using GLRotationMatrix = QMatrix4x4; - -enum Axis -{ - X = 0, - Y = 1, - Z = 2 -}; +#include "geometry.h" +#include "functional.h" -enum Result -{ - Success = 0, - PartialSuccess, - Failure -}; - -constexpr bool failed(Result r) -{ - return r == Failure; -} +template<typename T> +using opt = std::optional<T>; -enum Winding -{ - NoWinding, - Anticlockwise, - Clockwise, -}; +Q_DECLARE_METATYPE(glm::vec3) +Q_DECLARE_METATYPE(glm::mat4) -/* - * Special operator definition that implements the XOR operator for windings. - * However, if either winding is NoWinding, then this function returns NoWinding. - */ -inline Winding operator^(Winding one, Winding other) -{ - if (one == NoWinding or other == NoWinding) - return NoWinding; - else - return static_cast<Winding>(static_cast<int>(one) ^ static_cast<int>(other)); -} - -inline Winding& operator^=(Winding& one, Winding other) -{ - one = one ^ other; - return one; -} - +//! \brief count the amount of elements in a basic array template<typename T, int N> -constexpr int countof(T const (&)[N]) +constexpr int countof(T(&)[N]) { return N; } -/** - * @brief casts @c x to a suitable unsigned integer - */ +//! \brief casts @c x to a suitable unsigned integer template<typename T> constexpr auto unsigned_cast(T x) -> std::enable_if_t<std::is_integral_v<T>, std::make_unsigned_t<T>> @@ -97,9 +57,7 @@ return static_cast<std::make_unsigned_t<T>>(x); } -/** - * @brief casts @c x to a suitable signed integer - */ +//! \brief casts @c x to a suitable signed integer template<typename T> constexpr auto signed_cast(T x) -> std::enable_if_t<std::is_integral_v<T>, std::make_signed_t<T>> @@ -107,86 +65,42 @@ return static_cast<std::make_signed_t<T>>(x); } - -/** -* @brief casts floating point values to float, converting non-floating point values causes an error -* @param[in] x floating point value to cast -* @returns float -*/ +//! \brief casts floating point values to float template<typename T> -auto toFloat(T x) -> std::enable_if_t<std::is_floating_point_v<T>, float> +constexpr auto float_cast(T x) + -> std::enable_if_t<std::is_floating_point_v<T>, float> { return static_cast<float>(x); } -/** -* @brief casts floating point values to double, converting non-floating point values causes an error -* @param[in] x floating point value to cast -* @returns double -*/ +//! \brief casts floating point values to double template<typename T> -auto toDouble(T x) -> std::enable_if_t<std::is_floating_point_v<T>, double> +constexpr auto double_cast(T x) + -> std::enable_if_t<std::is_floating_point_v<T>, double> { return static_cast<double>(x); } -/** -* @brief casts floating point values to qreal, converting non-floating point values causes an error -* @param[in] x floating point value to cast -* @returns qreal -*/ +//! \brief casts floating point values to qreal template<typename T> -auto toQreal(T x) -> std::enable_if_t<std::is_floating_point_v<T>, qreal> +constexpr auto qreal_cast(T x) + -> std::enable_if_t<std::is_floating_point_v<T>, qreal> { return static_cast<qreal>(x); } template<int N, typename T, glm::qualifier Q> -inline QPoint toQPoint(const glm::vec<N, T, Q>& vec) +constexpr QPointF toQPointF(const glm::vec<N, T, Q>& vec) { - return {static_cast<int>(vec.x), static_cast<int>(vec.y)}; + return {double_cast(vec.x), double_cast(vec.y)}; } -template<int N, typename T, glm::qualifier Q> -inline QPointF toQPointF(const glm::vec<N, T, Q>& vec) -{ - return {toDouble(vec.x), toDouble(vec.y)}; -} - -inline glm::vec2 toVec2(const QPoint& point) -{ - return {point.x(), point.y()}; -} - -inline glm::vec2 toVec2(const QPointF& point) +constexpr glm::vec2 toVec2(const QPointF& point) { return {point.x(), point.y()}; } -/* - * coalesce(arg1, arg2, ..., argn) - * Returns the first of the given arguments that evaluates to true. - */ -template<typename T> -T coalesce(T&& arg) -{ - // recursion base: 1 argument - return arg; -} -template<typename T, typename... Rest> -std::common_type_t<T, Rest...> coalesce(T&& arg, Rest&&... rest) -{ - // general case: n arguments - return arg ? arg : coalesce(rest...); -} - -/** - * @brief Finds an element in a map and possibly returns a reference to it if find - * @param map - * @param key - * @returns the value or nullptr if not found - */ template<typename T, typename R, typename K> const R* findInMap(const std::map<T, R>& map, K&& key) { @@ -201,12 +115,6 @@ } } -/** - * @brief Finds an element in a map and possibly returns a reference to it if find - * @param map - * @param key - * @returns the value or no value if not found - */ template<typename T, typename R, typename K> R* findInMap(std::map<T, R>& map, K&& key) { @@ -221,10 +129,178 @@ } } +template<typename T, typename R> +void removeFromMap(std::map<T, R>& map, T&& key) +{ + const auto it = map.find(key); + if (it != map.end()) { + map.erase(it); + } +} + template<typename T = float> constexpr std::enable_if_t<std::is_floating_point_v<T>, T> pi = static_cast<T>(M_PIl); -constexpr double infinity = std::numeric_limits<double>::infinity(); + +inline QSizeF sizeToSizeF(const QSize& size) +{ + return {static_cast<qreal>(size.width()), static_cast<qreal>(size.height())}; +} + +//! \brief Hints to the specified vector that a certain amount of new elements +//! are going to be added. +template<typename T> +void reserveMore(std::vector<T>& vector, std::size_t amount) +{ + vector.reserve(vector.size() + amount); +} + +inline QString vectorToString(const glm::vec2& vec) +{ + return QStringLiteral("(%1, %2)") + .arg(double_cast(vec.x)) + .arg(double_cast(vec.y)); +} + +inline QString vectorToString(const glm::vec3& vec) +{ + return QStringLiteral("(%1, %2, %3)") + .arg(double_cast(vec.x)) + .arg(double_cast(vec.y)) + .arg(double_cast(vec.z)); +} + +inline QString vectorToString(const glm::vec4& vec) +{ + return QStringLiteral("%1, %2, %3, %4)") + .arg(double_cast(vec.x)) + .arg(double_cast(vec.y)) + .arg(double_cast(vec.z)) + .arg(double_cast(vec.w)); +} +template<typename T, typename IdentifierType> +struct TypeValue +{ + T value; + auto operator<=>(TypeValue other) const = default; +}; + +template<typename T, typename R> +int qHash(TypeValue<T, R> value) +{ + return qHash(value.value); +} + +/** + * Iterates a @c glm::mat + */ +template<int X, int Y, typename T, glm::qualifier Q, typename Fn> +void iter_matrix(const glm::mat<X, Y, T, Q>& matrix, Fn&& fn) +{ + for (int i = 0; i < X; ++i) + { + for (int j = 0; j < Y; ++j) + { + fn(i, j, matrix[i][j]); + } + } +} + +inline QDataStream& operator<<(QDataStream& stream, const glm::vec3& vec) +{ + return stream << vec.x << vec.y << vec.z; +} + +inline QDataStream& operator>>(QDataStream& stream, glm::vec3& vec) +{ + return stream >> vec.x >> vec.y >> vec.z; +} -Q_DECLARE_METATYPE(glm::vec3) -Q_DECLARE_METATYPE(glm::mat4) +template<int X, int Y, typename T, glm::qualifier Q> +QDataStream& operator<<(QDataStream& stream, const glm::mat<X, Y, T, Q>& mat) +{ + iter_matrix(mat, [&stream](int, int, float x) + { + stream << x; + }); + return stream; +} + +template<int X, int Y, typename T, glm::qualifier Q> +QDataStream& operator>>(QDataStream& stream, glm::mat<X, Y, T, Q>& mat) +{ + iter_matrix(mat, [&stream](int, int, float x) + { + stream >> x; + }); + return stream; +} + +//! \brief Converts a pointer value to an \c std::optional value. If p has a +//! value, it will be copied into the result value. +template<typename T> +std::optional<T> pointerToOptional(const T* p) +{ + std::optional<T> result; + if (p != nullptr) { + result = *p; + } + return result; +} + +// some magic code from https://en.cppreference.com/w/cpp/utility/variant/visit +// for use with std::visit +template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; +template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; + +// http://stackoverflow.com/a/18204188/3629665 +template<typename T> +constexpr T rotl10(T x) +{ + return (x << 10) | ((x >> 22) & 0x000000ff); +} + +template<typename T> +constexpr T rotl20(T x) +{ + return (x << 20) | ((x >> 12) & 0x000000ff); +} + +inline QString quoted(QString string) +{ + if (string.contains("'")) + { + string.replace("\"", "\\\""); + string = "\"" + string + "\""; + } + else + { + string = "'" + string + "'"; + } + return string; +} + +inline QString vertexToString(const glm::vec3& vertex) +{ + return QStringLiteral("%1 %2 %3").arg(vertex.x).arg(vertex.y).arg(vertex.z); +} + +inline QString vertexToStringParens(const glm::vec3& vertex) +{ + return QStringLiteral("(%1 %2 %3)").arg(vertex.x).arg(vertex.y).arg(vertex.z); +} + +inline QString transformToString(const glm::mat4& matrix) +{ + return QStringLiteral("%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12") + .arg(matrix[3][0], matrix[3][1], matrix[3][2]) + .arg(matrix[0][0], matrix[1][0], matrix[2][0]) + .arg(matrix[0][1], matrix[1][1], matrix[2][1]) + .arg(matrix[0][2], matrix[1][2], matrix[2][2]); +} + +template<typename T, glm::qualifier Q> +constexpr unsigned int qHash(const glm::vec<3, T, Q>& key) +{ + return qHash(key.x) ^ rotl10(qHash(key.y)) ^ rotl20(qHash(key.z)); +}
--- a/src/colors.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/colors.h Wed Jun 08 22:29:44 2022 +0300 @@ -18,7 +18,7 @@ #pragma once #include <QColor> -#include "main.h" +#include "basics.h" /** * @brief Represents an LDraw color index (e.g 16, 24, ...)
--- a/src/documentmanager.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/documentmanager.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -188,9 +188,8 @@ if (not bag.missing.empty()) { bag.missing.sort(Qt::CaseInsensitive); - errorStream << format( - tr("The following files could not be opened: %1"), - bag.missing.join(", ")); + errorStream << tr("The following files could not be opened: %1") + .arg(bag.missing.join(", ")); } } @@ -267,8 +266,7 @@ else { errors << tr("Could not open %1 for writing: %2") - .arg(file.fileName()) - .arg(file.errorString()); + .arg(file.fileName(), file.errorString()); return false; } }
--- a/src/geometry.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/geometry.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -1,6 +1,6 @@ #include <glm/gtc/matrix_transform.hpp> #include "geometry.h" -#include "main.h" +#include "basics.h" #include "ring.h" /**
--- a/src/geometry.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/geometry.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,6 +1,32 @@ #pragma once #include <QPolygonF> -#include "basics.h" +#include <glm/glm.hpp> +#include <optional> + +enum Winding +{ + NoWinding, + Anticlockwise, + Clockwise, +}; + +//! \brief XOR operator for winding +constexpr Winding operator^(Winding one, Winding other) +{ + if (one == NoWinding or other == NoWinding) { + return NoWinding; + } + else { + const int xored = static_cast<int>(one) ^ static_cast<int>(other); + return static_cast<Winding>(xored); + } +} + +constexpr Winding& operator^=(Winding& one, Winding other) +{ + one = one ^ other; + return one; +} struct Plane {
--- a/src/gl/common.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/gl/common.h Wed Jun 08 22:29:44 2022 +0300 @@ -41,11 +41,11 @@ void checkForGLErrors(QWidget* parent); inline glm::vec3 colorToVector3(const QColor& color) { - return {toFloat(color.redF()), toFloat(color.greenF()), toFloat(color.blueF())}; + return {float_cast(color.redF()), float_cast(color.greenF()), float_cast(color.blueF())}; } inline glm::vec4 colorToVector4(const QColor& color) { - return {gl::colorToVector3(color), toFloat(color.alphaF())}; + return {gl::colorToVector3(color), float_cast(color.alphaF())}; } }
--- a/src/gl/compiler.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/gl/compiler.h Wed Jun 08 22:29:44 2022 +0300 @@ -17,12 +17,10 @@ */ #pragma once -#include "main.h" +#include "basics.h" #include "gl/common.h" #include "types/boundingbox.h" #include <glm/gtc/type_ptr.hpp> -#include <QMap> -#include <QSet> #include <QOpenGLVertexArrayObject> #include <QOpenGLBuffer> #include <QOpenGLShaderProgram>
--- a/src/gl/partrenderer.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/gl/partrenderer.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -55,9 +55,9 @@ static QVector3D calcQVector3DFromQColor(const QColor& color) { return { - toFloat(color.redF()), - toFloat(color.greenF()), - toFloat(color.blueF()), + float_cast(color.redF()), + float_cast(color.greenF()), + float_cast(color.blueF()), }; } @@ -304,7 +304,7 @@ * @param plane Plane to raycast against * @return world co-ordinates, or no value if the point is behind the camera. */ -std::optional<glm::vec3> PartRenderer::screenToModelCoordinates(const QPoint& point, const Plane& plane) const +std::optional<glm::vec3> PartRenderer::screenToModelCoordinates(const QPointF& point, const Plane& plane) const { const Line line = this->cameraLine(point); std::optional<glm::vec3> result; @@ -332,7 +332,7 @@ return toQPointF(glm::vec2{projected.x, this->height() - projected.y}); } -Line<3> PartRenderer::cameraLine(const QPoint& point) const +Line<3> PartRenderer::cameraLine(const QPointF& point) const { const glm::vec3 p1 = this->unproject({point.x(), point.y(), 0}); const glm::vec3 p2 = this->unproject({point.x(), point.y(), 1});
--- a/src/gl/partrenderer.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/gl/partrenderer.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,6 +1,6 @@ #pragma once #include <QOpenGLWidget> -#include "main.h" +#include "basics.h" #include "gl/common.h" #include "gl/compiler.h" #include "documentmanager.h" @@ -31,9 +31,9 @@ BoundingBox boundingBox; gl::ModelShaders shaders; ModelId highlighted = {0}; - std::optional<glm::vec3> screenToModelCoordinates(const QPoint& point, const Plane& plane) const; + std::optional<glm::vec3> screenToModelCoordinates(const QPointF &point, const Plane& plane) const; QPointF modelToScreenCoordinates(const glm::vec3& point) const; - Line<3> cameraLine(const QPoint& point) const; + Line<3> cameraLine(const QPointF& point) const; glm::vec3 unproject(const glm::vec3& win) const; glm::mat4 projectionMatrix; glm::mat4 viewMatrix;
--- a/src/header.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/header.h Wed Jun 08 22:29:44 2022 +0300 @@ -18,7 +18,7 @@ #pragma once #include <QDate> -#include "main.h" +#include "basics.h" struct LDHeader {
--- a/src/invert.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/invert.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -16,7 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "main.h" +#include "basics.h" #include "model.h" #include "gl/common.h" #include "invert.h"
--- a/src/invert.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/invert.h Wed Jun 08 22:29:44 2022 +0300 @@ -17,9 +17,11 @@ */ #pragma once -#include "main.h" +#include "basics.h" #include "gl/common.h" +enum Axis { X, Y, Z }; + namespace math { glm::mat4 flipmatrix(Axis dimension);
--- a/src/ldrawalgorithm.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/ldrawalgorithm.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,5 +1,5 @@ #pragma once -#include "main.h" +#include "basics.h" #include "model.h" namespace ldraw
--- a/src/libraries.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/libraries.h Wed Jun 08 22:29:44 2022 +0300 @@ -19,7 +19,7 @@ #pragma once #include <QDir> #include <QAbstractTableModel> -#include "main.h" +#include "basics.h" #include "colors.h" class QSettings;
--- a/src/main.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/main.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -64,7 +64,8 @@ QMessageBox::critical( parent, QObject::tr("Problem opening file"), - format(QObject::tr("Could not open %1: %2"), path, errorString)); + QObject::tr("Could not open %1: %2").arg(quoted(path), errorString) + ); } return modelIdOpt; }
--- a/src/main.h Wed Jun 08 20:41:21 2022 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,274 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013 - 2020 Teemu Piippo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once -#include <QString> -#include <QVector> -#include <QSet> -#include <QDebug> -#include <compare> -#include <memory> -#include "basics.h" -#include "utility.h" -#include "geometry.h" -#include "functional.h" - -namespace settingGroups -{ - // List of setting groups - constexpr char mainwindow[] = "mainwindow"; -} - -constexpr std::size_t operator""_z(const unsigned long long int x) -{ - return static_cast<std::size_t>(x); -} - -inline QString operator""_q(const char* string, const unsigned long int length) -{ - Q_UNUSED(length) - return QString{string}; -} - -inline QPointF pointToPointF(const QPoint& point) -{ - return {static_cast<qreal>(point.x()), static_cast<qreal>(point.y())}; -} - -inline QPoint pointFToPoint(const QPointF& point) -{ - return {static_cast<int>(std::round(point.x())), static_cast<int>(std::round(point.y()))}; -} - -inline QSizeF sizeToSizeF(const QSize& size) -{ - return {static_cast<qreal>(size.width()), static_cast<qreal>(size.height())}; -} - -/** - * \brief Hints to the specified vector that a certain amount of new elements are going to be added. - * \param vector vector to consider - * \param amount amount of new elements to expect - */ -template<typename T> -void reserveMore(std::vector<T>& vector, std::size_t amount) -{ - vector.reserve(vector.size() + amount); -} - -inline QString vectorToString(const glm::vec2& vec) -{ - return "(%1, %2)"_q - .arg(toDouble(vec.x)) - .arg(toDouble(vec.y)); -} - -inline QString vectorToString(const glm::vec3& vec) -{ - return "(%1, %2, %3)"_q - .arg(toDouble(vec.x)) - .arg(toDouble(vec.y)) - .arg(toDouble(vec.z)); -} - -inline QString vectorToString(const glm::vec4& vec) -{ - return "(%1, %2, %3, %4)"_q - .arg(toDouble(vec.x)) - .arg(toDouble(vec.y)) - .arg(toDouble(vec.z)) - .arg(toDouble(vec.w)); -} - -template<typename K, typename V> -struct KeyValuePair -{ - K key; - V value; -}; - -template<typename K, typename V, typename IteratorType> -struct MapItemsIterator : IteratorType -{ - template<typename... Ts> - MapItemsIterator(Ts&&... args) : IteratorType{args...} {} - auto operator*() const - { - return KeyValuePair<const K&, V&>{this->key(), this->value()}; - } -}; - -template<typename K, typename V, typename MapType, typename IteratorType> -struct MapItems -{ - MapType& map; - IteratorType begin() - { - return IteratorType(this->map.begin()); - } - - IteratorType end() - { - return IteratorType(this->map.end()); - } -}; - -/* - * Python's dict.items for QMap: use in a for loop to iterate a map to - * get both keys and values. Iteration yields KeyValuePairs. - */ -template<typename K, typename V> -auto items(const QMap<K, V>& map) -{ - return MapItems< - const K&, - const V&, - const QMap<K, V>, - MapItemsIterator<K, const V, typename QMap<K, V>::const_iterator> - >{map}; -} - -template<typename K, typename V> -auto items(QMap<K, V>& map) -{ - return MapItems< - const K&, - V&, - QMap<K, V>, - MapItemsIterator<K, const V, typename QMap<K, V>::iterator> - >{map}; -} - -template<typename T, typename IdentifierType> -struct TypeValue -{ - T value; - bool operator==(TypeValue<T, IdentifierType> other) const - { - return value == other.value; - } - bool operator!=(TypeValue<T, IdentifierType> other) const - { - return value != other.value; - } - bool operator<(TypeValue<T, IdentifierType> other) const - { - return value < other.value; - } - bool operator>(TypeValue<T, IdentifierType> other) const - { - return value > other.value; - } - bool operator<=(TypeValue<T, IdentifierType> other) const - { - return value <= other.value; - } - bool operator>=(TypeValue<T, IdentifierType> other) const - { - return value >= other.value; - } -}; - -template<typename T, typename R> -int qHash(TypeValue<T, R> value) -{ - return qHash(value.value); -} - -/** - * Iterates a @c glm::mat - */ -template<int X, int Y, typename T, glm::qualifier Q, typename Fn> -void iter_matrix(const glm::mat<X, Y, T, Q>& matrix, Fn&& fn) -{ - for (int i = 0; i < X; ++i) - { - for (int j = 0; j < Y; ++j) - { - fn(i, j, matrix[i][j]); - } - } -} - -inline QDataStream& operator<<(QDataStream& stream, const glm::vec3& vec) -{ - return stream << vec.x << vec.y << vec.z; -} - -inline QDataStream& operator>>(QDataStream& stream, glm::vec3& vec) -{ - return stream >> vec.x >> vec.y >> vec.z; -} - -template<int X, int Y, typename T, glm::qualifier Q> -QDataStream& operator<<(QDataStream& stream, const glm::mat<X, Y, T, Q>& mat) -{ - iter_matrix(mat, [&stream](int, int, float x) - { - stream << x; - }); - return stream; -} - -template<int X, int Y, typename T, glm::qualifier Q> -QDataStream& operator>>(QDataStream& stream, glm::mat<X, Y, T, Q>& mat) -{ - iter_matrix(mat, [&stream](int, int, float x) - { - stream >> x; - }); - return stream; -} - -template<std::size_t N, typename T> -std::array<T, N> vectorToArray(const std::vector<T>& x) -{ - std::array<T, N> result; - for (std::size_t i = 0; i < x.size() and i < N; i += 1) - { - result[i] = x[i]; - } - return result; -} - -template<typename T> -std::optional<T> pointerToOptional(const T* p) -{ - std::optional<T> result; - if (p != nullptr) { - result = *p; - } - return result; -} - -template<typename T, typename R> -void removeFromMap(std::map<T, R>& map, T&& key) -{ - const auto it = map.find(key); - if (it != map.end()) { - map.erase(it); - } -} - -template<typename T> -using opt = std::optional<T>; - -// some magic code from https://en.cppreference.com/w/cpp/utility/variant/visit -// for use with std::visit -template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; -template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
--- a/src/model.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/model.h Wed Jun 08 22:29:44 2022 +0300 @@ -19,7 +19,7 @@ #pragma once #include <QAbstractListModel> #include <memory> -#include "main.h" +#include "basics.h" #include "colors.h" struct SubfileReference
--- a/src/parser.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/parser.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -193,7 +193,7 @@ const int code = tokens[0].toInt(&ok_code); if (not ok_code) { - throw BodyParseError{"line type was not an integer"}; + throw BodyParseError{QObject::tr("line type was not an integer")}; } switch (code) { @@ -225,7 +225,7 @@ return Colored<ConditionalEdge>{cedge, pair.second}; } default: - throw BodyParseError{format("bad line type '%1'", code)}; + throw BodyParseError{QObject::tr("bad line type '%1'").arg(code)}; } } catch(const BodyParseError& error)
--- a/src/parser.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/parser.h Wed Jun 08 22:29:44 2022 +0300 @@ -17,7 +17,7 @@ */ #pragma once -#include "main.h" +#include "basics.h" #include "model.h" class Parser : public QObject
--- a/src/polygoncache.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/polygoncache.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,5 +1,5 @@ #pragma once -#include "main.h" +#include "basics.h" #include "model.h" #include "gl/common.h"
--- a/src/settingseditor/librarieseditor.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/settingseditor/librarieseditor.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -48,11 +48,11 @@ const QDir dir{this->ui.newLibraryPath->text()}; if (not dir.exists()) { - QMessageBox::critical(this, + QMessageBox::critical( + this, tr("Library does not exist"), - format( - tr("The directory %1 does not exist."), - quoted(dir.path()))); + tr("The directory %1 does not exist.").arg(quoted(dir.path())) + ); } else { @@ -60,9 +60,8 @@ { QMessageBox::warning(this, tr("Unreadable library"), - format( - tr("The directory %1 cannot be read."), - quoted(dir.path()))); + tr("The directory %1 cannot be read.").arg(quoted(dir.path())) + ); } this->libraries.addLibrary({Library::OfficialLibrary, dir}); this->ui.newLibraryPath->clear();
--- a/src/settingseditor/librarieseditor.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/settingseditor/librarieseditor.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,6 +1,6 @@ #pragma once #include <QWidget> -#include "main.h" +#include "basics.h" #include "libraries.h" class LibrariesEditor : public QWidget
--- a/src/settingseditor/settingseditor.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/settingseditor/settingseditor.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,6 +1,6 @@ #pragma once #include <QDialog> -#include "main.h" +#include "basics.h" #include "librarieseditor.h" #include "libraries.h" #include "uiutilities.h"
--- a/src/types/boundingbox.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/types/boundingbox.h Wed Jun 08 22:29:44 2022 +0300 @@ -21,6 +21,7 @@ struct BoundingBox { + static constexpr double infinity = std::numeric_limits<double>::infinity(); glm::vec3 minimum {infinity, infinity, infinity}; glm::vec3 maximum {-infinity, -infinity, -infinity}; };
--- a/src/ui/canvas.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/ui/canvas.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -383,7 +383,7 @@ glm::vec3 Canvas::cameraVector() const { // Find out where the grid is projected on the screen - const QPoint gridOrigin2d = pointFToPoint(this->modelToScreenCoordinates(this->gridPlane.anchor)); + const QPointF gridOrigin2d = this->modelToScreenCoordinates(this->gridPlane.anchor); // Find out which direction the camera is looking at the grid origin in 3d return glm::normalize(this->cameraLine(gridOrigin2d).direction); }
--- a/src/ui/multiplyfactordialog.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/ui/multiplyfactordialog.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,6 +1,6 @@ #pragma once #include <QDialog> -#include "../main.h" +#include "../basics.h" #include "../widgets/vec3editor.h" namespace Ui
--- a/src/ui/objecteditor.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/ui/objecteditor.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,4 +1,4 @@ #pragma once #include <QWidget> -#include "../main.h" +#include "../basics.h" #include "../model.h"
--- a/src/utility.h Wed Jun 08 20:41:21 2022 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * LDForge: LDraw parts authoring CAD - * Copyright (C) 2013 - 2020 Teemu Piippo - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once -#include "basics.h" - -// http://stackoverflow.com/a/18204188/3629665 -template<typename T> -inline T rotl10(T x) -{ - return (x << 10) | ((x >> 22) & 0x000000ff); -} - -template<typename T> -inline T rotl20(T x) -{ - return (x << 20) | ((x >> 12) & 0x000000ff); -} - -inline QString format(const QString& format_string) -{ - return format_string; -} - -template<typename T, typename... Rest> -QString format(const QString& format_string, T&& arg, Rest&&... rest) -{ - return format(format_string.arg(arg), std::forward<Rest>(rest)...); -} - -inline QString quoted(QString string) -{ - if (string.contains("'")) - { - string.replace("\"", "\\\""); - string = "\"" + string + "\""; - } - else - { - string = "'" + string + "'"; - } - return string; -} - -/** - * @brief Converts the specified vertex to a simple string - * @param vertex vertex to convert - * @return "x y z"-formatted string - */ -inline QString vertexToString(const glm::vec3& vertex) -{ - return format("%1 %2 %3", vertex.x, vertex.y, vertex.z); -} - -inline QString vertexToStringParens(const glm::vec3& vertex) -{ - return format("(%1, %2, %3)", vertex.x, vertex.y, vertex.z); -} - -inline QString transformToString(const glm::mat4& matrix) -{ - return format( - "%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12", - matrix[3][0], - matrix[3][1], - matrix[3][2], - matrix[0][0], - matrix[1][0], - matrix[2][0], - matrix[0][1], - matrix[1][1], - matrix[2][1], - matrix[0][2], - matrix[1][2], - matrix[2][2]); -} - -template<typename T, glm::qualifier Q> -constexpr unsigned int qHash(const glm::vec<3, T, Q>& key) -{ - return qHash(key.x) ^ rotl10(qHash(key.y)) ^ rotl20(qHash(key.z)); -}
--- a/src/vertexmap.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/vertexmap.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,7 +1,7 @@ #ifndef VERTEXMAP_H #define VERTEXMAP_H #include <set> -#include "main.h" +#include "basics.h" #include "model.h" /**
--- a/src/widgets/colorselectdialog.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/widgets/colorselectdialog.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,5 +1,5 @@ #pragma once -#include "../main.h" +#include "../basics.h" #include "../colors.h" #include <QPushButton> #include <QAbstractTableModel>
--- a/src/widgets/matrixeditor.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/widgets/matrixeditor.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -1,4 +1,4 @@ -#include "main.h" +#include "basics.h" #include "matrixeditor.h" #include "ui_matrixeditor.h" #include "../ui/multiplyfactordialog.h" @@ -14,7 +14,7 @@ { for (int row = 0; row < countof(this->spinboxes[0]); row += 1) { - const QString name = "cell"_q + QString::number(column) + QString::number(row); + const QString name = QStringLiteral("cell%1%2").arg(column).arg(row); QDoubleSpinBox** spinbox = &this->spinboxes[column][row]; *spinbox = this->findChild<QDoubleSpinBox*>(name); connect(*spinbox, qOverload<double>(&QDoubleSpinBox::valueChanged), [&]() @@ -23,7 +23,8 @@ }); Q_ASSERT(*spinbox != nullptr); } - QAbstractButton* button = this->findChild<QAbstractButton*>("multiply"_q + QString::number(column)); + const QString multiplyButtonName = QStringLiteral("multiply%1").arg(column); + QAbstractButton* button = this->findChild<QAbstractButton*>(multiplyButtonName); button->setProperty(BUTTON_COLUMN_PROPERTY, column); connect(button, &QAbstractButton::clicked, this, &MatrixEditor::multiplyButtonPressed); }
--- a/src/widgets/matrixeditor.h Wed Jun 08 20:41:21 2022 +0300 +++ b/src/widgets/matrixeditor.h Wed Jun 08 22:29:44 2022 +0300 @@ -1,6 +1,6 @@ #pragma once #include <QWidget> -#include "main.h" +#include "basics.h" namespace Ui { class MatrixEditor;
--- a/src/widgets/vec3editor.cpp Wed Jun 08 20:41:21 2022 +0300 +++ b/src/widgets/vec3editor.cpp Wed Jun 08 22:29:44 2022 +0300 @@ -34,7 +34,7 @@ glm::vec3 Vec3Editor::value() const { - auto get = [](DoubleSpinBox* spinbox){ return toFloat(spinbox->value()); }; + auto get = [](DoubleSpinBox* spinbox){ return float_cast(spinbox->value()); }; return {get(this->ui->x), get(this->ui->y), get(this->ui->z)}; } @@ -43,7 +43,7 @@ auto set = [](DoubleSpinBox* spinbox, float value) { QSignalBlocker blocker{spinbox}; - spinbox->setValue(toQreal(value)); + spinbox->setValue(qreal_cast(value)); }; set(this->ui->x, value.x); set(this->ui->y, value.y);