More refactor, merged main.h, basics.h and utility.h into one header file basics.h and removed plenty of unused code

Wed, 08 Jun 2022 22:29:44 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Wed, 08 Jun 2022 22:29:44 +0300
changeset 206
654661eab7f3
parent 205
1a4342d80de7
child 207
5315358a7d91

More refactor, merged main.h, basics.h and utility.h into one header file basics.h and removed plenty of unused code

CMakeLists.txt file | annotate | diff | comparison | revisions
src/basics.h file | annotate | diff | comparison | revisions
src/colors.h file | annotate | diff | comparison | revisions
src/documentmanager.cpp file | annotate | diff | comparison | revisions
src/geometry.cpp file | annotate | diff | comparison | revisions
src/geometry.h file | annotate | diff | comparison | revisions
src/gl/common.h file | annotate | diff | comparison | revisions
src/gl/compiler.h file | annotate | diff | comparison | revisions
src/gl/partrenderer.cpp file | annotate | diff | comparison | revisions
src/gl/partrenderer.h file | annotate | diff | comparison | revisions
src/header.h file | annotate | diff | comparison | revisions
src/invert.cpp file | annotate | diff | comparison | revisions
src/invert.h file | annotate | diff | comparison | revisions
src/ldrawalgorithm.h file | annotate | diff | comparison | revisions
src/libraries.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/main.h file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
src/parser.cpp file | annotate | diff | comparison | revisions
src/parser.h file | annotate | diff | comparison | revisions
src/polygoncache.h file | annotate | diff | comparison | revisions
src/settingseditor/librarieseditor.cpp file | annotate | diff | comparison | revisions
src/settingseditor/librarieseditor.h file | annotate | diff | comparison | revisions
src/settingseditor/settingseditor.h file | annotate | diff | comparison | revisions
src/types/boundingbox.h file | annotate | diff | comparison | revisions
src/ui/canvas.cpp file | annotate | diff | comparison | revisions
src/ui/multiplyfactordialog.h file | annotate | diff | comparison | revisions
src/ui/objecteditor.h file | annotate | diff | comparison | revisions
src/utility.h file | annotate | diff | comparison | revisions
src/vertexmap.h file | annotate | diff | comparison | revisions
src/widgets/colorselectdialog.h file | annotate | diff | comparison | revisions
src/widgets/matrixeditor.cpp file | annotate | diff | comparison | revisions
src/widgets/matrixeditor.h file | annotate | diff | comparison | revisions
src/widgets/vec3editor.cpp file | annotate | diff | comparison | revisions
src/widgets/vec3editor.h file | annotate | diff | comparison | revisions
--- 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);
--- a/src/widgets/vec3editor.h	Wed Jun 08 20:41:21 2022 +0300
+++ b/src/widgets/vec3editor.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
 {

mercurial