Sun, 26 Jan 2020 14:29:30 +0200
replaced matrix and vertex classes with glm
--- a/CMakeLists.txt Sun Jan 26 01:06:27 2020 +0200 +++ b/CMakeLists.txt Sun Jan 26 14:29:30 2020 +0200 @@ -29,13 +29,11 @@ src/invert.cpp src/main.cpp src/mainwindow.cpp - src/matrix.cpp src/model.cpp src/modeleditcontext.cpp src/parser.cpp src/uiutilities.cpp src/version.cpp - src/vertex.cpp src/gl/compiler.cpp src/gl/partrenderer.cpp src/linetypes/comment.cpp @@ -63,7 +61,6 @@ src/main.h src/mainwindow.h src/maths.h - src/matrix.h src/model.h src/modeleditcontext.h src/parser.h @@ -71,7 +68,6 @@ src/uiutilities.h src/utility.h src/version.h - src/vertex.h src/gl/common.h src/gl/compiler.h src/gl/partrenderer.h
--- a/src/basics.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/basics.h Sun Jan 26 14:29:30 2020 +0200 @@ -31,6 +31,7 @@ #include <QVariant> #include <QVector> #include <QVector3D> +#include <glm/glm.hpp> using GLRotationMatrix = QMatrix4x4; @@ -83,3 +84,6 @@ { return N; } + +Q_DECLARE_METATYPE(glm::vec3) +Q_DECLARE_METATYPE(glm::mat4)
--- a/src/gl/common.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/gl/common.h Sun Jan 26 14:29:30 2020 +0200 @@ -22,7 +22,6 @@ #include <QGenericMatrix> #include "basics.h" #include "colors.h" -#include "vertex.h" namespace gl { @@ -33,13 +32,7 @@ static const QMatrix4x4 bottomCameraMatrix = {1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1}; static const QMatrix4x4 backCameraMatrix = {-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1}; static const QMatrix4x4 rightCameraMatrix = {0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1}; - - // Conversion matrix from LDraw to OpenGL coordinates. - static const QMatrix4x4 ldrawToGL = {1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1}; - static constexpr QRgb BlackRgb = 0xff000000; - static constexpr GLfloat near = 1.0f; - static constexpr GLfloat far = 10000.0f; struct Polygon; } @@ -53,7 +46,7 @@ ConditionalEdge }; Type type; - Point3D vertices[4]; + glm::vec3 vertices[4]; Color color; linetypes::Id id; @@ -91,15 +84,15 @@ namespace gl { - inline Polygon edgeLine(const Point3D& v_1, const Point3D& v_2, Color color, linetypes::Id id) + inline Polygon edgeLine(const glm::vec3& v_1, const glm::vec3& v_2, Color color, linetypes::Id id) { return {Polygon::EdgeLine, {v_1, v_2}, color, id}; } inline Polygon triangle( - const Point3D& v_1, - const Point3D& v_2, - const Point3D& v_3, + const glm::vec3& v_1, + const glm::vec3& v_2, + const glm::vec3& v_3, Color color, linetypes::Id id) { @@ -107,10 +100,10 @@ } inline Polygon quadrilateral( - const Point3D& v_1, - const Point3D& v_2, - const Point3D& v_3, - const Point3D& v_4, + const glm::vec3& v_1, + const glm::vec3& v_2, + const glm::vec3& v_3, + const glm::vec3& v_4, Color color, linetypes::Id id) { @@ -118,10 +111,10 @@ } inline Polygon conditionalEdge( - const Point3D& v_1, - const Point3D& v_2, - const Point3D& control_1, - const Point3D& control_2, + const glm::vec3& v_1, + const glm::vec3& v_2, + const glm::vec3& control_1, + const glm::vec3& control_2, Color color, linetypes::Id id) {
--- a/src/gl/compiler.cpp Sun Jan 26 01:06:27 2020 +0200 +++ b/src/gl/compiler.cpp Sun Jan 26 14:29:30 2020 +0200 @@ -166,9 +166,9 @@ reserveMore(normalsBuffer, polygon.numPolygonVertices() * 3_z); for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) { - const Point3D& v1 = vertexRing[i - 1]; - const Point3D& v2 = vertexRing[i]; - const Point3D& v3 = vertexRing[i + 1]; + const glm::vec3& v1 = vertexRing[i - 1]; + const glm::vec3& v2 = vertexRing[i]; + const glm::vec3& v3 = vertexRing[i + 1]; const QVector3D normal = QVector3D::crossProduct(v3 - v2, v1 - v2).normalized(); for (const GLfloat coord : {normal.x(), normal.y(), normal.z()}) normalsBuffer.push_back(coord); @@ -179,7 +179,7 @@ // Transform vertices so that they're suitable for GL rendering for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) { - Point3D& point = polygon.vertices[i]; + glm::vec3& point = polygon.vertices[i]; this->boundingBox.consider(polygon.vertices[i]); vertexBuffer.push_back(static_cast<GLfloat>(point.x)); vertexBuffer.push_back(static_cast<GLfloat>(point.y)); @@ -212,7 +212,7 @@ return color; } -Point3D gl::Compiler::modelCenter() const +glm::vec3 gl::Compiler::modelCenter() const { return boxCenter(this->boundingBox); }
--- a/src/gl/compiler.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/gl/compiler.h Sun Jan 26 14:29:30 2020 +0200 @@ -20,7 +20,6 @@ #include "main.h" #include "gl/common.h" #include "types/boundingbox.h" -#include <glm/glm.hpp> #include <glm/gtc/type_ptr.hpp> #include <QMap> #include <QSet> @@ -54,7 +53,7 @@ void buildPolygon(Polygon polygon, std::vector<GLfloat>* vboData); std::size_t vboSize(gl::ArrayClass arrayClass) const; QColor getColorForPolygon(const gl::Polygon& polygon); - Point3D modelCenter() const; + glm::vec3 modelCenter() const; double modelDistance() const; void initialize(); void bindVertexArray(gl::ArrayClass arrayClass);
--- a/src/invert.cpp Sun Jan 26 01:06:27 2020 +0200 +++ b/src/invert.cpp Sun Jan 26 14:29:30 2020 +0200 @@ -18,7 +18,6 @@ #include "main.h" #include "model.h" -#include "matrix.h" #include "gl/common.h" #include "invert.h" @@ -73,10 +72,11 @@ /* * Returns a matrix that causes a flip on the given dimension. */ -Matrix4x4 math::flipmatrix(const Axis dimension) +glm::mat4 math::flipmatrix(const Axis dimension) { - Matrix4x4 result = identity4x4; - result(static_cast<int>(dimension), static_cast<int>(dimension)) = -1; + glm::mat4 result = glm::mat4(); + const int k = static_cast<int>(dimension); + result[k][k] = -1; return result; }
--- a/src/invert.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/invert.h Sun Jan 26 14:29:30 2020 +0200 @@ -18,14 +18,13 @@ #pragma once #include "main.h" -#include "matrix.h" #include "gl/common.h" bool isflat(class Model* model, Axis* axis); namespace math { - Matrix4x4 flipmatrix(Axis dimension); + glm::mat4 flipmatrix(Axis dimension); } //void invert(LDObject* obj, class DocumentManager* context);
--- a/src/linetypes/conditionaledge.cpp Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/conditionaledge.cpp Sun Jan 26 14:29:30 2020 +0200 @@ -1,10 +1,10 @@ #include "conditionaledge.h" linetypes::ConditionalEdge::ConditionalEdge( - const Point3D& point_1, - const Point3D& point_2, - const Point3D& controlPoint_1, - const Point3D& controlPoint_2, + const glm::vec3& point_1, + const glm::vec3& point_2, + const glm::vec3& controlPoint_1, + const glm::vec3& controlPoint_2, const Color color_index) : Edge{point_1, point_2, color_index}, controlPoint_1{controlPoint_1}, @@ -12,7 +12,7 @@ { } -linetypes::ConditionalEdge::ConditionalEdge(const QVector<Point3D>& vertices, const Color color) : +linetypes::ConditionalEdge::ConditionalEdge(const QVector<glm::vec3>& vertices, const Color color) : Edge{vertices[0], vertices[1], color}, controlPoint_1{vertices[2]}, controlPoint_2{vertices[3]} @@ -24,9 +24,9 @@ switch (property) { case Property::ControlPoint1: - return controlPoint_1; + return QVariant::fromValue(controlPoint_1); case Property::ControlPoint2: - return controlPoint_2; + return QVariant::fromValue(controlPoint_2); default: return Edge::getProperty(property); } @@ -40,9 +40,9 @@ switch (property) { case Property::ControlPoint1: - controlPoint_1 = value.value<Point3D>(); + controlPoint_1 = value.value<glm::vec3>(); case Property::ControlPoint2: - controlPoint_2 = value.value<Point3D>(); + controlPoint_2 = value.value<glm::vec3>(); default: return Edge::setProperty(property, value); } @@ -51,6 +51,6 @@ QString linetypes::ConditionalEdge::textRepresentation() const { return Edge::textRepresentation() + utility::format("%1 %2", - vertexToStringParens(controlPoint_1), - vertexToStringParens(controlPoint_2)); + utility::vertexToStringParens(controlPoint_1), + utility::vertexToStringParens(controlPoint_2)); }
--- a/src/linetypes/conditionaledge.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/conditionaledge.h Sun Jan 26 14:29:30 2020 +0200 @@ -11,18 +11,18 @@ public: ConditionalEdge() = default; ConditionalEdge( - const Point3D& point_1, - const Point3D& point_2, - const Point3D& controlPoint_1, - const Point3D& controlPoint_2, + const glm::vec3& point_1, + const glm::vec3& point_2, + const glm::vec3& controlPoint_1, + const glm::vec3& controlPoint_2, const Color colorIndex = colors::edge); - ConditionalEdge(const QVector<Point3D>& vertices, const Color color); + ConditionalEdge(const QVector<glm::vec3>& vertices, const Color color); QVariant getProperty(Property property) const override; SetPropertyResult setProperty( Property property, const QVariant& value) override; QString textRepresentation() const override; private: - Point3D controlPoint_1 = {}; - Point3D controlPoint_2 = {}; + glm::vec3 controlPoint_1 = {}; + glm::vec3 controlPoint_2 = {}; };
--- a/src/linetypes/edge.cpp Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/edge.cpp Sun Jan 26 14:29:30 2020 +0200 @@ -1,14 +1,14 @@ #include "edge.h" linetypes::Edge::Edge( - const Point3D& point_1, - const Point3D& point_2, + const glm::vec3& point_1, + const glm::vec3& point_2, const Color color_index) : ColoredObject{color_index}, point_1{point_1}, point_2{point_2} {} -linetypes::Edge::Edge(const QVector<Point3D>& vertices, const Color color) : +linetypes::Edge::Edge(const QVector<glm::vec3>& vertices, const Color color) : ColoredObject{color}, point_1{vertices[0]}, point_2{vertices[1]} @@ -20,9 +20,9 @@ switch (property) { case Property::Point1: - return point_1; + return QVariant::fromValue(point_1); case Property::Point2: - return point_2; + return QVariant::fromValue(point_2); default: return BaseClass::getProperty(property); } @@ -34,10 +34,10 @@ switch (property) { case Property::Point1: - point_1 = value.value<Point3D>(); + point_1 = value.value<glm::vec3>(); return SetPropertyResult::Success; case Property::Point2: - point_2 = value.value<Point3D>(); + point_2 = value.value<glm::vec3>(); return SetPropertyResult::Success; default: return BaseClass::setProperty(property, value); @@ -46,7 +46,7 @@ QString linetypes::Edge::textRepresentation() const { - return utility::format("%1 %2", vertexToStringParens(point_1), vertexToStringParens(point_2)); + return utility::format("%1 %2", utility::vertexToStringParens(point_1), utility::vertexToStringParens(point_2)); } void linetypes::Edge::getPolygons(
--- a/src/linetypes/edge.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/edge.h Sun Jan 26 14:29:30 2020 +0200 @@ -11,9 +11,9 @@ public: using BaseClass = ColoredObject; Edge() = default; - Edge(const Point3D& point_1, const Point3D& point_2, + Edge(const glm::vec3& point_1, const glm::vec3& point_2, const Color colorIndex = colors::edge); - Edge(const QVector<Point3D>& vertices, const Color color); + Edge(const QVector<glm::vec3>& vertices, const Color color); QVariant getProperty(Property property) const override; SetPropertyResult setProperty( Property property, @@ -21,6 +21,6 @@ QString textRepresentation() const override; void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override; private: - Point3D point_1 = {}; - Point3D point_2 = {}; + glm::vec3 point_1 = {}; + glm::vec3 point_2 = {}; };
--- a/src/linetypes/object.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/object.h Sun Jan 26 14:29:30 2020 +0200 @@ -4,7 +4,6 @@ #include <QStringView> #include "main.h" #include "colors.h" -#include "vertex.h" #include "gl/common.h" namespace linetypes
--- a/src/linetypes/quadrilateral.cpp Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/quadrilateral.cpp Sun Jan 26 14:29:30 2020 +0200 @@ -1,17 +1,17 @@ #include "quadrilateral.h" linetypes::Quadrilateral::Quadrilateral( - const Point3D& point_1, - const Point3D& point_2, - const Point3D& point_3, - const Point3D& point_4, + const glm::vec3& point_1, + const glm::vec3& point_2, + const glm::vec3& point_3, + const glm::vec3& point_4, Color color_index) : ColoredObject{color_index}, points{point_1, point_2, point_3, point_4} { } -linetypes::Quadrilateral::Quadrilateral(const QVector<Point3D>& vertices, const Color color) : +linetypes::Quadrilateral::Quadrilateral(const QVector<glm::vec3>& vertices, const Color color) : ColoredObject{color}, points{vertices[0], vertices[1], vertices[2], vertices[3]} { @@ -22,13 +22,13 @@ switch (id) { case Property::Point1: - return points[0]; + return QVariant::fromValue(points[0]); case Property::Point2: - return points[1]; + return QVariant::fromValue(points[1]); case Property::Point3: - return points[2]; + return QVariant::fromValue(points[2]); case Property::Point4: - return points[3]; + return QVariant::fromValue(points[3]); default: return ColoredObject::getProperty(id); } @@ -42,16 +42,16 @@ switch (id) { case Property::Point1: - points[0] = value.value<Point3D>(); + points[0] = value.value<glm::vec3>(); return SetPropertyResult::Success; case Property::Point2: - points[1] = value.value<Point3D>(); + points[1] = value.value<glm::vec3>(); return SetPropertyResult::Success; case Property::Point3: - points[2] = value.value<Point3D>(); + points[2] = value.value<glm::vec3>(); return SetPropertyResult::Success; case Property::Point4: - points[3] = value.value<Point3D>(); + points[3] = value.value<glm::vec3>(); return SetPropertyResult::Success; default: return ColoredObject::setProperty(id, value); @@ -61,10 +61,10 @@ QString linetypes::Quadrilateral::textRepresentation() const { return utility::format("%1 %2 %3 %4", - vertexToStringParens(points[0]), - vertexToStringParens(points[1]), - vertexToStringParens(points[2]), - vertexToStringParens(points[3])); + utility::vertexToStringParens(points[0]), + utility::vertexToStringParens(points[1]), + utility::vertexToStringParens(points[2]), + utility::vertexToStringParens(points[3])); } void linetypes::Quadrilateral::getPolygons(
--- a/src/linetypes/quadrilateral.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/quadrilateral.h Sun Jan 26 14:29:30 2020 +0200 @@ -11,17 +11,17 @@ public: Quadrilateral() = default; Quadrilateral( - const Point3D &point_1, - const Point3D &point_2, - const Point3D &point_3, - const Point3D &point_4, + const glm::vec3 &point_1, + const glm::vec3 &point_2, + const glm::vec3 &point_3, + const glm::vec3 &point_4, Color colorIndex = colors::main); - Quadrilateral(const QVector<Point3D>& vertices, const Color color); + Quadrilateral(const QVector<glm::vec3>& vertices, const Color color); QVariant getProperty(Property id) const override; SetPropertyResult setProperty(Property id, const QVariant& value) override; QString textRepresentation() const override; void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override; void invert() override; private: - Point3D points[4] = {{}}; + glm::vec3 points[4] = {{}}; };
--- a/src/linetypes/subfilereference.cpp Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/subfilereference.cpp Sun Jan 26 14:29:30 2020 +0200 @@ -2,7 +2,7 @@ #include "documentmanager.h" #include "invert.h" -linetypes::SubfileReference::SubfileReference(const Matrix4x4& transformation, +linetypes::SubfileReference::SubfileReference(const glm::mat4& transformation, const QString& referenceName, const Color color) : ColoredObject{color}, @@ -32,7 +32,7 @@ switch (property) { case Property::Transformation: - this->transformation = value.value<Matrix4x4>(); + this->transformation = value.value<glm::mat4>(); return SetPropertyResult::Success; case Property::ReferenceName: this->referenceName = value.toString(); @@ -44,7 +44,7 @@ QString linetypes::SubfileReference::textRepresentation() const { - return referenceName + " " + vertexToStringParens(this->position()); + return referenceName + " " + utility::vertexToStringParens(this->position()); } void linetypes::SubfileReference::getPolygons( @@ -54,14 +54,16 @@ Model* model = this->resolve(context->documents); if (model != nullptr) { - const bool needInverting = math::det(this->transformation) < 0; + const bool needInverting = glm::determinant(this->transformation) < 0; const std::vector<gl::Polygon> modelPolygons = model->getPolygons(context->documents); polygons.reserve(polygons.size() + modelPolygons.size()); for (gl::Polygon polygon : modelPolygons) { for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1) { - polygon.vertices[i] = math::transform(polygon.vertices[i], this->transformation); + glm::vec4 vertex {polygon.vertices[i], 1}; + vertex = this->transformation * vertex; + polygon.vertices[i] = vertex; } if (needInverting != this->isInverted) { @@ -77,9 +79,9 @@ } } -Point3D linetypes::SubfileReference::position() const +glm::vec3 linetypes::SubfileReference::position() const { - return {this->transformation(0, 3), this->transformation(1, 3), this->transformation(2, 3)}; + return {this->transformation[3][0], this->transformation[3][1], this->transformation[3][2]}; } void linetypes::SubfileReference::invert()
--- a/src/linetypes/subfilereference.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/subfilereference.h Sun Jan 26 14:29:30 2020 +0200 @@ -1,6 +1,5 @@ #pragma once #include "object.h" -#include "matrix.h" class Model; @@ -14,18 +13,18 @@ public: SubfileReference() = default; SubfileReference( - const Matrix4x4& transformation, + const glm::mat4& transformation, const QString &referenceName, const Color color = colors::main); QVariant getProperty(Property property) const override; SetPropertyResult setProperty(Property property, const QVariant& value) override; QString textRepresentation() const override; void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override; - Point3D position() const; + glm::vec3 position() const; void invert() override; private: Model* resolve(DocumentManager* documents) const; - Matrix4x4 transformation; + glm::mat4 transformation; QString referenceName; bool isInverted = false; };
--- a/src/linetypes/triangle.cpp Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/triangle.cpp Sun Jan 26 14:29:30 2020 +0200 @@ -1,16 +1,16 @@ #include "triangle.h" linetypes::Triangle::Triangle( - const Point3D& point_1, - const Point3D& point_2, - const Point3D& point_3, + const glm::vec3& point_1, + const glm::vec3& point_2, + const glm::vec3& point_3, Color color_index) : ColoredObject{color_index}, points{point_1, point_2, point_3} { } -linetypes::Triangle::Triangle(const QVector<Point3D>& vertices, const Color color) : +linetypes::Triangle::Triangle(const QVector<glm::vec3>& vertices, const Color color) : ColoredObject{color}, points{vertices[0], vertices[1], vertices[2]} { @@ -21,11 +21,11 @@ switch (id) { case Property::Point1: - return points[0]; + return QVariant::fromValue(points[0]); case Property::Point2: - return points[1]; + return QVariant::fromValue(points[1]); case Property::Point3: - return points[2]; + return QVariant::fromValue(points[2]); default: return ColoredObject::getProperty(id); } @@ -37,13 +37,13 @@ switch (id) { case Property::Point1: - points[0] = value.value<Point3D>(); + points[0] = value.value<glm::vec3>(); return SetPropertyResult::Success; case Property::Point2: - points[1] = value.value<Point3D>(); + points[1] = value.value<glm::vec3>(); return SetPropertyResult::Success; case Property::Point3: - points[2] = value.value<Point3D>(); + points[2] = value.value<glm::vec3>(); return SetPropertyResult::Success; default: return ColoredObject::setProperty(id, value); @@ -53,9 +53,9 @@ QString linetypes::Triangle::textRepresentation() const { return utility::format("%1 %2 %3", - vertexToStringParens(points[0]), - vertexToStringParens(points[1]), - vertexToStringParens(points[2])); + utility::vertexToStringParens(points[0]), + utility::vertexToStringParens(points[1]), + utility::vertexToStringParens(points[2])); } void linetypes::Triangle::getPolygons(
--- a/src/linetypes/triangle.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/linetypes/triangle.h Sun Jan 26 14:29:30 2020 +0200 @@ -10,17 +10,17 @@ public: Triangle() = default; Triangle( - const Point3D &point_1, - const Point3D &point_2, - const Point3D &point_3, + const glm::vec3 &point_1, + const glm::vec3 &point_2, + const glm::vec3 &point_3, Color colorIndex = colors::main); - Triangle(const QVector<Point3D>& vertices, const Color color); + Triangle(const QVector<glm::vec3>& vertices, const Color color); QVariant getProperty(Property id) const override; SetPropertyResult setProperty(Property id, const QVariant& value) override; QString textRepresentation() const override; void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override; void invert() override; private: - Point3D points[3] = {{}}; + glm::vec3 points[3] = {{}}; };
--- a/src/maths.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/maths.h Sun Jan 26 14:29:30 2020 +0200 @@ -18,6 +18,7 @@ #pragma once #include <cmath> +#include "utility.h" namespace math { @@ -90,3 +91,8 @@ return arg + sum<T>(rest...); } } + +inline unsigned int qHash(const glm::vec3& key) +{ + return qHash(key.x) ^ utility::rotl10(qHash(key.y)) ^ utility::rotl20(qHash(key.z)); +}
--- a/src/matrix.cpp Sun Jan 26 01:06:27 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +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/>. - */ - -#include "matrix.h" -#include "vertex.h" - -Matrix4x4 combine(const Matrix3x3& topLeft, const Point3D& translation) -{ - return {{ - {topLeft(0, 0), topLeft(0, 1), topLeft(0, 2), translation.x}, - {topLeft(1, 0), topLeft(1, 1), topLeft(1, 2), translation.y}, - {topLeft(2, 0), topLeft(2, 1), topLeft(2, 2), translation.z}, - {0, 0, 0, 1} - }}; -} - -/* - * Computes the determinant of a 3×3 matrix with each variable passed in row-major order. - */ -qreal math::det(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f, qreal g, qreal h, qreal i) -{ - return a*e*i + b*f*g + c*d*h - a*f*h - b*d*i - c*e*g; -} - -/* - * Computes the determinant of a 2×2 matrix. - */ -qreal math::det(const Matrix<2, 2>& matrix) -{ - return matrix(0, 0) * matrix(1, 1) - matrix(0, 1) * matrix(1, 0); -} - -/* - * Computes the determinant of a 3×3 matrix. - */ -qreal math::det(const Matrix3x3& matrix) -{ - return math::sum( - +matrix(0, 0) * matrix(1, 1) * matrix(2, 2), - -matrix(0, 0) * matrix(1, 2) * matrix(2, 1), - -matrix(0, 1) * matrix(1, 0) * matrix(2, 2), - +matrix(0, 1) * matrix(1, 2) * matrix(2, 0), - +matrix(0, 2) * matrix(1, 0) * matrix(2, 1), - -matrix(0, 2) * matrix(1, 1) * matrix(2, 0)); -} - -/* - * Computes the determinant of a 4×4 matrix. - */ -qreal math::det(const Matrix4x4& matrix) -{ - qreal sum = 0; - - for (int column : {0, 1, 2, 3}) - { - int column_1 = (column >= 1) ? 0 : 1; - int column_2 = (column >= 2) ? 1 : 2; - int column_3 = (column >= 3) ? 2 : 3; - sum += ((column % 1) ? -1 : 1) * math::det( - matrix(1, column_1), matrix(1, column_2), matrix(1, column_3), - matrix(2, column_1), matrix(2, column_2), matrix(2, column_3), - matrix(3, column_1), matrix(3, column_2), matrix(3, column_3)); - } - - return sum; -}
--- a/src/matrix.h Sun Jan 26 01:06:27 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +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 <QGenericMatrix> -#include <type_traits> - -template<int Rows, int Columns, typename T = double> -struct MatrixIterator; - -template<int Rows, int Columns> -struct MatrixIndex -{ - int row; - int column; -}; - -template<int Rows, int Columns, typename T = double> -struct Matrix -{ - using Iterator = MatrixIterator<Rows, Columns, T>; - T values[Rows][Columns]; - Iterator begin() - { - return {*this, {0, 0}}; - } - Iterator end() - { - return {*this, {Rows, 0}}; - } - T& operator()(int row, int column) - { - return this->values[row][column]; - } - T operator()(int row, int column) const - { - return this->values[row][column]; - } - T& operator[](const MatrixIndex<Rows, Columns>& index) - { - return (*this)(index.row, index.column); - } - T operator[](const MatrixIndex<Rows, Columns>& index) const - { - return (*this)(index.row, index.column); - } -}; - -template<int Rows, int Columns, typename T> -struct MatrixIterator -{ - struct Value - { - const MatrixIndex<Rows, Columns> index; - decltype(std::declval<Matrix<Rows, Columns, T>>()(0, 0)) value; - }; - Matrix<Rows, Columns, T>& matrix; - MatrixIndex<Rows, Columns> index; -}; - -template<int Rows, int Columns> -auto& operator++(MatrixIndex<Rows, Columns>& index) -{ - index.column += 1; - if (index.column >= Columns) - { - index.row += 1; - index.column -= Columns; - } - return index; -} - -template<int Rows, int Columns> -bool operator==( - const MatrixIndex<Rows, Columns>& one, - const MatrixIndex<Rows, Columns>& other) -{ - return one.row == other.row and one.column == other.column; -} -template<int Rows, int Columns, typename T> -auto& operator++(MatrixIterator<Rows, Columns, T>& iterator) -{ - ++iterator.index; - return iterator; -} - -template<int Rows, int Columns, typename T> -bool operator==( - const MatrixIterator<Rows, Columns, T>& one, - const MatrixIterator<Rows, Columns, T>& other) -{ - return &one.matrix == &other.matrix and one.index == other.index; -} - -template<int Rows, int Columns, typename T> -bool operator!=( - const MatrixIterator<Rows, Columns, T>& one, - const MatrixIterator<Rows, Columns, T>& other) -{ - return not (one == other); -} - -template<int Rows, int Columns, typename T> -auto operator*(MatrixIterator<Rows, Columns, T>& iterator) - -> typename MatrixIterator<Rows, Columns, T>::Value -{ - return {iterator.index, iterator.matrix[iterator.index]}; -} - -template<int Rows, int Columns, typename T> -QGenericMatrix<Rows, Columns, T> matrixToQGenericMatrix(const Matrix<Rows, Columns, T>& matrix) -{ - return {matrix.values}; -} - -template<int Rows, int Columns, typename T> -Matrix<Rows, Columns, T> matrixFromQGenericMatrix(const QGenericMatrix<Rows, Columns, T&> matrix) -{ - Matrix<Rows, Columns, T> result; - for (auto& cell : result) - { - matrix(cell.index.row, cell.index.column) = result[cell.index]; - } - return result; -} - -using Matrix3x3 = Matrix<3, 3>; -Q_DECLARE_METATYPE(Matrix3x3); -using Matrix4x4 = Matrix<4, 4>; -Q_DECLARE_METATYPE(Matrix4x4); - -template<int Rows, int Columns, typename T> -QDataStream& operator<<(QDataStream& stream, const Matrix<Rows, Columns, T>& matrix) -{ - for (auto& cell : matrix) - { - stream << cell.value; - } - return stream; -} - -template<int Rows, int Columns, typename T> -QDataStream& operator>>(QDataStream& stream, Matrix<Rows, Columns, T>& matrix) -{ - for (auto& cell : matrix) - { - stream >> cell.value; - } - return stream; -} - -Matrix4x4 combine(const Matrix3x3& topLeft, const struct Point3D& translation); - -static constexpr Matrix3x3 identity3x3 {{{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}}; -static constexpr Matrix4x4 identity4x4 {{{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}}; - -namespace math -{ - qreal det(qreal a, qreal b, qreal c, qreal d, qreal e, qreal f, qreal g, qreal h, qreal i); - qreal det(const Matrix<2, 2>& matrix); - qreal det(const Matrix3x3& matrix); - qreal det(const Matrix4x4& matrix); -}
--- a/src/parser.cpp Sun Jan 26 01:06:27 2020 +0200 +++ b/src/parser.cpp Sun Jan 26 14:29:30 2020 +0200 @@ -92,7 +92,7 @@ if (partTypeString.startsWith("Unofficial_")) partTypeString = partTypeString.mid(strlen("Unofficial_")); header.type = typeStrings.value(partTypeString, LDHeader::Part); - header.qualfiers = 0; + header.qualfiers = {}; if (tokens.contains("Alias")) header.qualfiers |= LDHeader::Alias; if (tokens.contains("Physical_Color")) @@ -279,7 +279,7 @@ } } -static Point3D vertexFromStrings( +static glm::vec3 vertexFromStrings( const QStringList& tokens, const int startingPosition) { @@ -296,9 +296,9 @@ return {x, y, z}; } -static Matrix3x3 matrixFromStrings(const QStringList& tokens, const int startingPosition) +static glm::mat4 matrixFromStrings(const QStringList& tokens, const int startingPosition, const int positionStartingIndex) { - Matrix3x3 result; + glm::mat4 result = glm::mat4{1}; for (int i = 0; i < 9; i += 1) { const int row = i / 3; @@ -309,7 +309,18 @@ throw BodyParseError{"too few tokens available"}; } bool ok; - result(row, column) = tokens[index].toFloat(&ok); + // note that glm::mat4 is column-major + result[column][row] = tokens[index].toFloat(&ok); + if (not ok) + { + throw BodyParseError{"non-numeric values for matrix"}; + } + } + for (int i = 0; i < 3; i += 1) + { + bool ok; + const auto value = tokens[i + positionStartingIndex].toFloat(&ok); + result[3][i] = value; if (not ok) { throw BodyParseError{"non-numeric values for matrix"}; @@ -347,10 +358,9 @@ throw BodyParseError{"wrong amount of tokens in a type-1 line"}; } const Color color = colorFromString(tokens[colorPosition]); - const Point3D position = vertexFromStrings(tokens, positionPosition); - const Matrix3x3 transform = matrixFromStrings(tokens, transformPosition); + const glm::mat4 transform = matrixFromStrings(tokens, transformPosition, positionPosition); const QString& name = tokens[namePosition]; - return std::make_unique<linetypes::SubfileReference>(combine(transform, position), name, color); + return std::make_unique<linetypes::SubfileReference>(transform, name, color); } template<typename T, int NumVertices> @@ -366,7 +376,7 @@ throw BodyParseError{"wrong amount of tokens"}; } const Color color = colorFromString(tokens[colorPosition]); - QVector<Point3D> vertices; + QVector<glm::vec3> vertices; vertices.reserve(NumVertices); for (int i = 0; i < NumVertices; i += 1) {
--- a/src/types/boundingbox.cpp Sun Jan 26 01:06:27 2020 +0200 +++ b/src/types/boundingbox.cpp Sun Jan 26 14:29:30 2020 +0200 @@ -18,13 +18,13 @@ #include "boundingbox.h" -BoundingBox& BoundingBox::operator<<(const Point3D& vertex) +BoundingBox& BoundingBox::operator<<(const glm::vec3& vertex) { this->consider(vertex); return *this; } -void BoundingBox::consider(const Point3D& vertex) +void BoundingBox::consider(const glm::vec3& vertex) { this->minimum.x = math::min(vertex.x, this->minimum.x); this->minimum.y = math::min(vertex.y, this->minimum.y); @@ -37,19 +37,19 @@ /* * Returns the length of the bounding box on the longest measure. */ -double longestMeasure(const BoundingBox& box) +float longestMeasure(const BoundingBox& box) { if (box != emptyBoundingBox) { - const double dx = std::abs(box.minimum.x - box.maximum.x); - const double dy = std::abs(box.minimum.y - box.maximum.y); - const double dz = std::abs(box.minimum.z - box.maximum.z); - const double size = std::max(std::max(dx, dy), dz); - return std::max(size / 2.0, 1.0); + const float dx = std::abs(box.minimum.x - box.maximum.x); + const float dy = std::abs(box.minimum.y - box.maximum.y); + const float dz = std::abs(box.minimum.z - box.maximum.z); + const float size = std::max(std::max(dx, dy), dz); + return std::max(size / 2.0f, 1.0f); } else { - return 0.0; + return 0.0f; } } @@ -57,7 +57,7 @@ /* * Yields the center of the bounding box. */ -Point3D boxCenter(const BoundingBox& box) +glm::vec3 boxCenter(const BoundingBox& box) { if (box != emptyBoundingBox) { @@ -69,16 +69,16 @@ } else { - return origin; + return glm::vec3{0, 0, 0}; } } /* * Returns the length of the bounding box's space diagonal. */ -double spaceDiagonal(const BoundingBox& box) +float spaceDiagonal(const BoundingBox& box) { - return math::distance(box.minimum, box.maximum); + return glm::distance(box.minimum, box.maximum); } bool operator==(const BoundingBox &box_1, const BoundingBox &box_2)
--- a/src/types/boundingbox.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/types/boundingbox.h Sun Jan 26 14:29:30 2020 +0200 @@ -17,21 +17,22 @@ */ #pragma once -#include "vertex.h" +#include "basics.h" +#include "maths.h" class BoundingBox { public: - void consider(const Point3D& vertex); - Point3D minimum {math::infinity, math::infinity, math::infinity}; - Point3D maximum {-math::infinity, -math::infinity, -math::infinity}; - BoundingBox& operator<<(const Point3D& v); + void consider(const glm::vec3& vertex); + glm::vec3 minimum {math::infinity, math::infinity, math::infinity}; + glm::vec3 maximum {-math::infinity, -math::infinity, -math::infinity}; + BoundingBox& operator<<(const glm::vec3& v); }; -static constexpr BoundingBox emptyBoundingBox = {}; -Point3D boxCenter(const BoundingBox& box); -double longestMeasure(const BoundingBox& box); -double spaceDiagonal(const BoundingBox& box); +inline const BoundingBox emptyBoundingBox = {}; +glm::vec3 boxCenter(const BoundingBox& box); +float longestMeasure(const BoundingBox& box); +float spaceDiagonal(const BoundingBox& box); bool operator==(const BoundingBox& box_1, const BoundingBox& box_2); bool operator!=(const BoundingBox& box_1, const BoundingBox& box_2);
--- a/src/utility.h Sun Jan 26 01:06:27 2020 +0200 +++ b/src/utility.h Sun Jan 26 14:29:30 2020 +0200 @@ -70,4 +70,9 @@ { return std::find(std::begin(container), std::end(container), value) != std::end(container); } + + inline QString vertexToStringParens(const glm::vec3& vertex) + { + return utility::format("(%1, %2, %3)", vertex.x, vertex.y, vertex.z); + } }
--- a/src/vertex.cpp Sun Jan 26 01:06:27 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,221 +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/>. - */ - -#include "main.h" -#include "vertex.h" - -/* -void Vertex::transform(const Matrix& matrix, const Vertex& pos) -{ - double x2 = (matrix(0, 0) * x) + (matrix(0, 1) * y) + (matrix(0, 2) * z) + pos.x; - double y2 = (matrix(1, 0) * x) + (matrix(1, 1) * y) + (matrix(1, 2) * z) + pos.y; - double z2 = (matrix(2, 0) * x) + (matrix(2, 1) * y) + (matrix(2, 2) * z) + pos.z; - this->x = x2; - this->y = y2; - this->z = z2; -} -*/ - -Point3D::CoordinateType& Point3D::get(Axis axis) -{ - switch (axis) - { - case X: - return this->x; - case Y: - return this->y; - case Z: - return this->z; - default: - throw std::runtime_error("Non-axis given to Vertex::operator[]"); - } -} - -Point3D::CoordinateType Point3D::get(Axis axis) const -{ - switch (axis) - { - case X: - return this->x; - case Y: - return this->y; - case Z: - return this->z; - default: - return 0; - } -} - -Point3D::operator QVariant() const -{ - return QVariant::fromValue(*this); -} - -void Point3D::assign(Axis axis, CoordinateType value) -{ - this->get(axis) = value; -} - -Point3D VertexFromVector(const QVector3D& vector) -{ - return {vector.x(), vector.y(), vector.z()}; -} - -Point3D operator*(const Point3D& point, Point3D::CoordinateType scalar) -{ - return {point.x * scalar, point.y * scalar, point.z * scalar}; -} - -Point3D& operator+=(Point3D& point, const QVector3D& other) -{ - point.x += other.x(); - point.y += other.y(); - point.z += other.z(); - return point; -} - -Point3D operator+(Point3D point, const QVector3D& other) -{ - point += other; - return point; -} - - -QVector3D vertexToVector(const Point3D& vertex) -{ - return { - static_cast<float>(vertex.x), - static_cast<float>(vertex.y), - static_cast<float>(vertex.z) - }; -} - -Point3D operator-(Point3D point, const QVector3D& vector) -{ - point -= vector; - return point; -} - -Point3D& operator-=(Point3D& point, const QVector3D& vector) -{ - point.x -= vector.x(); - point.y -= vector.y(); - point.z -= vector.z(); - return point; -} - -QVector3D operator-(const Point3D& point, const Point3D& other) -{ - return { - static_cast<float>(point.x - other.x), - static_cast<float>(point.y - other.y), - static_cast<float>(point.z - other.z) - }; -} - -Point3D& operator*=(Point3D& point, Point3D::CoordinateType scalar) -{ - point.x *= scalar; - point.y *= scalar; - point.z *= scalar; - return point; -} - -bool operator==(const Point3D& point, const Point3D& other) -{ - return point.x == other.x and point.y == other.y and point.z == other.z; -} - -bool operator!=(const Point3D& point, const Point3D& other) -{ - return not (point == other); -} - -bool operator<(const Point3D& point, const Point3D& other) -{ - if (not qFuzzyCompare(point.x, other.x)) - return point.x < other.x; - else if (not qFuzzyCompare(point.y, other.y)) - return point.y < other.y; - else - return point.z < other.z; -} - -/* - * Transforms the specified vertex with a transformation matrix - */ -Point3D math::transform(const Point3D& point, const Matrix4x4& matrix) -{ - return { - matrix(0, 0) * point.x - + matrix(0, 1) * point.y - + matrix(0, 2) * point.z - + matrix(0, 3), - matrix(1, 0) * point.x - + matrix(1, 1) * point.y - + matrix(1, 2) * point.z - + matrix(1, 3), - matrix(2, 0) * point.x - + matrix(2, 1) * point.y - + matrix(2, 2) * point.z - + matrix(2, 3), - }; -} - -/* - * Returns the distance from one vertex to another. - */ -qreal math::distance(const Point3D& one, const Point3D& other) -{ - return (one - other).length(); -} - -/* - * Returns a vertex with all coordinates inverted. - */ -Point3D operator-(const Point3D& vertex) -{ - return {-vertex.x, -vertex.y, -vertex.z}; -} - -/* - * Inserts this vertex into a data stream. This is needed for vertices to be - * stored in QSettings. - */ -QDataStream& operator<<(QDataStream& out, const Point3D& vertex) -{ - return out << vertex.x << vertex.y << vertex.z; -} - -/* - * Takes a vertex from a data stream. - */ -QDataStream& operator>>(QDataStream& in, Point3D& vertex) -{ - return in >> vertex.x >> vertex.y >> vertex.z; -} - -unsigned int qHash(const Point3D& key) -{ - return qHash(key.x) ^ utility::rotl10(qHash(key.y)) ^ utility::rotl20(qHash(key.z)); -} - -QString vertexToStringParens(const Point3D& vertex) -{ - return utility::format("(%1, %2, %3)", vertex.x, vertex.y, vertex.z); -}
--- a/src/vertex.h Sun Jan 26 01:06:27 2020 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +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 <functional> -#include <QVector3D> -#include "basics.h" -#include "maths.h" -#include "matrix.h" - -struct Point3D -{ - double x, y, z; - using CoordinateType = decltype(x); - void assign(Axis axis, CoordinateType value); - CoordinateType& get(Axis ax); - CoordinateType get(Axis ax) const; - operator QVariant() const; -}; - -constexpr Point3D origin = {0, 0, 0}; - -namespace math -{ - Point3D transform(const Point3D& point, const Matrix4x4& matrix); - qreal distance(const Point3D& one, const Point3D& other); -} - -Point3D& operator+=(Point3D &point, const QVector3D& other); -Point3D operator+(Point3D point, const QVector3D& other); -QVector3D operator-(const Point3D& point, const Point3D& other); -Point3D operator-(Point3D point, const QVector3D& vector); -Point3D& operator-=(Point3D &point, const QVector3D& vector); -Point3D& operator*=(Point3D &point, Point3D::CoordinateType scalar); -Point3D operator*(const Point3D &point, Point3D::CoordinateType scalar); -bool operator<(const Point3D &point, const Point3D& other); -bool operator==(const Point3D &point, const Point3D& other); -bool operator!=(const Point3D &point, const Point3D& other); - -inline Point3D operator*(qreal scalar, const Point3D& vertex) -{ - return vertex * scalar; -} - -Q_DECLARE_METATYPE(Point3D) -Point3D vertexFromVector(const QVector3D& vector); -QVector3D vertexToVector(const Point3D &vertex); -QString vertexToStringParens(const Point3D& vertex); -unsigned int qHash(const Point3D& key); -Point3D operator-(const Point3D& vertex); -QDataStream& operator<<(QDataStream& out, const Point3D& vertex); -QDataStream& operator>>(QDataStream& in, Point3D& vertex); - -/* - * Calls 'function' with the x, y and z coordinates of 'vertex'. - */ -template<typename Function> -inline auto xyz(Function&& function, const Point3D& vertex) -{ - return function(vertex.x, vertex.y, vertex.z); -}