added missing files

Sat, 14 Dec 2019 22:36:06 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sat, 14 Dec 2019 22:36:06 +0200
changeset 19
ed9685f44ab3
parent 18
918b6c0f8b5b
child 20
cef43609a374

added missing files

src/gl/common.h file | annotate | diff | comparison | revisions
src/gl/compiler.cpp file | annotate | diff | comparison | revisions
src/gl/compiler.h file | annotate | diff | comparison | revisions
src/invert.cpp file | annotate | diff | comparison | revisions
src/invert.h file | annotate | diff | comparison | revisions
src/ring.h file | annotate | diff | comparison | revisions
src/types/boundingbox.cpp file | annotate | diff | comparison | revisions
src/types/boundingbox.h file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gl/common.h	Sat Dec 14 22:36:06 2019 +0200
@@ -0,0 +1,158 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 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 <QColor>
+#include <QOpenGLFunctions>
+#include <QGenericMatrix>
+#include "basics.h"
+#include "colors.h"
+#include "vertex.h"
+
+namespace gl
+{
+	// Transformation matrices for projection cameras.
+	static const QMatrix4x4 topCameraMatrix = {};
+	static const QMatrix4x4 frontCameraMatrix = {1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1};
+	static const QMatrix4x4 leftCameraMatrix = {0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 1};
+	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;
+}
+
+struct gl::Polygon
+{
+	enum Type : qint8
+	{
+		EdgeLine,
+		Triangle,
+		Quadrilateral,
+		ConditionalEdge
+	};
+	Type type;
+	Point3D vertices[4];
+	Color color;
+
+	/**
+	 * @return amount of vertices used for geometry
+	 */
+	inline int numPolygonVertices() const
+	{
+		if (type == Type::ConditionalEdge)
+			return 2;
+		else
+			return numVertices();
+	}
+
+	/**
+	 * @return amount of vertices
+	 */
+	inline int numVertices() const
+	{
+		switch (type)
+		{
+		case Type::EdgeLine:
+			return 2;
+		case Type::Triangle:
+			return 3;
+		case Type::ConditionalEdge:
+		case Type::Quadrilateral:
+			return 4;
+		default:
+			return 0;
+		}
+	}
+};
+
+Q_DECLARE_METATYPE(gl::Polygon)
+
+namespace gl
+{
+	inline Polygon edgeLine(const Point3D& v_1, const Point3D& v_2, Color color)
+	{
+		return {Polygon::EdgeLine, {v_1, v_2}, color};
+	}
+
+	inline Polygon triangle(const Point3D& v_1, const Point3D& v_2, const Point3D& v_3, Color color)
+	{
+		return {Polygon::Triangle, {v_1, v_2, v_3}, color};
+	}
+
+	inline Polygon quadrilateral(
+		const Point3D& v_1,
+		const Point3D& v_2,
+		const Point3D& v_3,
+		const Point3D& v_4,
+		Color color)
+	{
+		return {Polygon::Quadrilateral, {v_1, v_2, v_3, v_4}, color};
+	}
+
+	inline Polygon conditionalEdge(
+		const Point3D& v_1,
+		const Point3D& v_2,
+		const Point3D& control_1,
+		const Point3D& control_2,
+		Color color)
+	{
+		return {Polygon::ConditionalEdge, {v_1, v_2, control_1, control_2}, color};
+	}
+
+	// Vbo names
+	enum class VboClass
+	{
+		Lines,
+		Triangles,
+		Quads,
+		ConditionalLines
+	};
+	constexpr int numVboClasses = 4;
+
+	// Types of vbo per object
+	enum class VboSubclass
+	{
+		Surfaces,
+		RegularColors,
+		PickColors,
+		BfcFrontColors,
+		BfcBackColors,
+		RandomColors,
+		Normals,
+		InvertedNormals
+	};
+	constexpr int numVboSubclasses = 8;
+
+	// Amount of vbos overall
+	constexpr int numVbos = gl::numVboClasses * gl::numVboSubclasses;
+
+	enum class RenderStyle
+	{
+		Normal,
+		Wireframe,
+		BfcRedGreen,
+		RandomColors
+	};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gl/compiler.cpp	Sat Dec 14 22:36:06 2019 +0200
@@ -0,0 +1,30 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 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/>.
+ */
+
+#define GL_GLEXT_PROTOTYPES
+#include <GL/glu.h>
+#include <GL/glext.h>
+#include "gl/compiler.h"
+#include "documentmanager.h"
+#include "invert.h"
+#include "ring.h"
+
+gl::Compiler::~Compiler()
+{
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gl/compiler.h	Sat Dec 14 22:36:06 2019 +0200
@@ -0,0 +1,62 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 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 "main.h"
+#include "gl/partrenderer.h"
+#include "gl/common.h"
+#include "types/boundingbox.h"
+#include <QMap>
+#include <QSet>
+
+namespace gl
+{
+	class Compiler;
+	class Renderer;
+}
+
+/*
+ * Compiles LDObjects into polygons for the GLRenderer to draw.
+ */
+class gl::Compiler : public QObject, protected QOpenGLFunctions
+{
+	Q_OBJECT
+public:
+	Compiler(Renderer* renderer);
+	~Compiler();
+	void initialize();
+	Point3D modelCenter();
+	void prepareVBO (int vbonum);
+	GLuint vbo (int vbonum) const;
+	int vboSize (int vbonum) const;
+	static int vboNumber (VboClass surface, VboSubclass complement);
+private:
+	struct ObjectVboData
+	{
+		QVector<GLfloat> data[gl::numVbos];
+	};
+	QMap<QPersistentModelIndex, ObjectVboData> m_objectInfo;
+	QSet<QPersistentModelIndex> m_staged; // Objects that need to be compiled
+	GLuint m_vbo[gl::numVbos];
+	bool m_vboChanged[gl::numVbos] = {true};
+	bool needBoundingBoxRebuild = true;
+	int m_vboSizes[gl::numVbos] = {0};
+};
+
+#define CHECK_GL_ERROR() { checkGLError(__FILE__, __LINE__); }
+void checkGLError (QString file, int line);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/invert.cpp	Sat Dec 14 22:36:06 2019 +0200
@@ -0,0 +1,159 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 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 "model.h"
+#include "matrix.h"
+#include "gl/common.h"
+
+#if 0
+/*
+ * Returns whether or not the document is flat.
+ * If it is flat, the result is stored in *axis.
+ */
+bool isflat(Model* model, Axis* flatDimension)
+{
+	// The dimensions that this model is potentially flat in.
+	QVector<Axis> dimensions = {X, Y, Z};
+
+	// Iterate through everything in the subfile. If there is any vertex with a coordinate not at
+	// zero, the subfile is not flat in that dimension.
+	for (LDObject* subfileObject : model->objects())
+	{
+		for (int i = 0; i < subfileObject->numVertices(); ++i)
+		{
+			Vertex const& v_i = subfileObject->vertex(i);
+
+			if (not qFuzzyCompare(v_i.x, 0.0))
+				dimensions.removeOne(X);
+
+			if (not qFuzzyCompare(v_i.y, 0.0))
+				dimensions.removeOne(Y);
+
+			if (not qFuzzyCompare(v_i.z, 0.0))
+				dimensions.removeOne(Z);
+		}
+
+		// If there are no more dimensions left, we can exit the loop.
+		if (dimensions.isEmpty())
+			break;
+	}
+
+	if (dimensions.size() == 1)
+	{
+		// The model is flat in one dimension, return that.
+		// If the model is flat in two or three dimensions, it's not really a valid model.
+		*flatDimension = dimensions[0];
+		return true;
+	}
+	else
+	{
+		// The model is not flat.
+		return false;
+	}
+}
+#endif
+
+/*
+ * Returns a matrix that causes a flip on the given dimension.
+ */
+Matrix4x4 flipmatrix(Axis dimension)
+{
+	Matrix4x4 result = identity4x4;
+	switch (dimension)
+	{
+	case X:
+		result(0, 0) = -1;
+		break;
+	case Y:
+		result(1, 1) = -1;
+		break;
+	case Z:
+		result(2, 2) = -1;
+		break;
+	}
+	return result;
+}
+
+#if 0
+/*
+ * Inverts an LDObject so that its winding is changed.
+ */
+void invert(LDObject* obj, DocumentManager* context)
+{
+	if (obj->numPolygonVertices() > 0)
+	{
+		// Object is vertex based, so change the order of the vertices.
+		QVector<Vertex> vertices;
+		vertices.resize(obj->numPolygonVertices());
+
+		for (int i = 0; i < vertices.size(); i += 1)
+			vertices[vertices.size() - 1 - i] = obj->vertex(i);
+
+		for (int i = 0; i < vertices.size(); i += 1)
+			obj->setVertex(i, vertices[i]);
+	}
+	else if (obj->type() == LDObjectType::SubfileReference)
+	{
+		// Check whether subfile is flat. If it is, flip it on the axis on which it is flat.
+		Model model {context};
+		LDSubfileReference* reference = static_cast<LDSubfileReference*>(obj);
+		reference->fileInfo(context)->inlineContents(model, true, false);
+		Axis flatDimension;
+
+		if (::isflat(&model, &flatDimension))
+		{
+			reference->setTransformationMatrix(
+				reference->transformationMatrix() * ::flipmatrix(flatDimension)
+			);
+		}
+		else
+		{
+			// Subfile is not flat. Resort to invertnext.
+			reference->setInverted(not reference->isInverted());
+		}
+	}
+	else if (obj->type() == LDObjectType::CircularPrimitive)
+	{
+		auto primitive = static_cast<LDCircularPrimitive*>(obj);
+
+		if (primitive->isFlat())
+			primitive->setTransformationMatrix(primitive->transformationMatrix() * ::flipmatrix(Y));
+		else
+			primitive->setInverted(not primitive->isInverted());
+	}
+}
+#endif
+
+/*
+ * Inverts the winding of a polygon.
+ */
+void invertPolygon(gl::Polygon& polygon)
+{
+	switch (polygon.numPolygonVertices())
+	{
+	case 2:
+	case 3:
+		std::swap(polygon.vertices[0], polygon.vertices[1]);
+		break;
+
+	case 4:
+		std::swap(polygon.vertices[1], polygon.vertices[3]);
+		break;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/invert.h	Sat Dec 14 22:36:06 2019 +0200
@@ -0,0 +1,27 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 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 "main.h"
+#include "matrix.h"
+#include "gl/common.h"
+
+bool isflat(class Model* model, Axis* axis);
+QMatrix4x4 flipmatrix(Axis dimension);
+//void invert(LDObject* obj, class DocumentManager* context);
+void invertPolygon(gl::Polygon& polygon);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ring.h	Sat Dec 14 22:36:06 2019 +0200
@@ -0,0 +1,109 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 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
+
+namespace iter
+{
+	namespace _imp
+	{
+		template<typename T>
+		class RingAdapter;
+	}
+
+	template<typename T>
+	_imp::RingAdapter<T> ring(T& collection);
+
+	template<typename T>
+	_imp::RingAdapter<T> ring(T& collection, int count);
+}
+
+/*
+ * Implements a ring adapter over T. This class corrects indices given to the element-operator so that they're within bounds.
+ * The maximum amount can be specified manually.
+ *
+ * Example:
+ *
+ *   int A[] = {10,20,30,40};
+ *   ring(A)[0]  ==     A[0 % 4]    == A[0]
+ *   ring(A)[5]  ==     A[5 % 4]    == A[1]
+ *   ring(A)[-1] == ring(A)[-1 + 4] == A[3]
+ */
+template<typename T>
+class iter::_imp::RingAdapter
+{
+private:
+	// The private section must come first because _collection is used in decltype() below.
+	T& collection;
+	const int count;
+
+public:
+	RingAdapter(T& collection, int count) :
+		collection {collection},
+		count {count} {}
+
+	template<typename IndexType>
+	decltype(collection[IndexType()]) operator[](IndexType index)
+	{
+		if (count == 0)
+		{
+			// Argh! ...let the collection deal with this case.
+			return this->collection[index];
+		}
+		else
+		{
+			index %= this->count;
+
+			// Fix negative modulus...
+			if (index < 0)
+				index += this->count;
+
+			return this->collection[index];
+		}
+	}
+
+	int size() const
+	{
+		return this->count;
+	}
+};
+
+/*
+ * Convenience function for RingAdapter so that the template parameter does not have to be provided. The ring amount is assumed
+ * to be the amount of elements in the collection.
+ */
+template<typename T>
+iter::_imp::RingAdapter<T> iter::ring(T& collection)
+{
+	return {collection, countof(collection)};
+}
+
+/*
+ * Version of ring() that allows manual specification of the count.
+ */
+template<typename T>
+iter::_imp::RingAdapter<T> iter::ring(T& collection, int count)
+{
+	return {collection, count};
+}
+
+template<typename T>
+int countof(const iter::_imp::RingAdapter<T>& ring)
+{
+	return ring.size();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/types/boundingbox.cpp	Sat Dec 14 22:36:06 2019 +0200
@@ -0,0 +1,68 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2019 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 "boundingbox.h"
+
+BoundingBox& BoundingBox::operator<<(const Point3D& vertex)
+{
+	this->consider(vertex);
+	return *this;
+}
+
+void BoundingBox::consider(const Point3D& vertex)
+{
+	this->minimum.x = std::min(vertex.x, this->minimum.x);
+	this->minimum.y = std::min(vertex.y, this->minimum.y);
+	this->minimum.z = std::min(vertex.z, this->minimum.z);
+	this->maximum.x = std::max(vertex.x, this->maximum.x);
+	this->maximum.y = std::max(vertex.y, this->maximum.y);
+	this->maximum.z = std::max(vertex.z, this->maximum.z);
+}
+
+/*
+ * Returns the length of the bounding box on the longest measure.
+ */
+double longestMeasure(const BoundingBox& box)
+{
+	double dx = box.minimum.x - box.maximum.x;
+	double dy = box.minimum.y - box.maximum.y;
+	double dz = box.minimum.z - box.maximum.z;
+	double size = std::max(std::max(dx, dy), dz);
+	return std::max(std::abs(size / 2.0), 1.0);
+}
+
+
+/*
+ * Yields the center of the bounding box.
+ */
+Point3D center(const BoundingBox& box)
+{
+	return {
+		(box.minimum.x + box.maximum.x) / 2,
+		(box.minimum.y + box.maximum.y) / 2,
+		(box.minimum.z + box.maximum.z) / 2
+	};
+}
+
+/*
+ * Returns the length of the bounding box's space diagonal.
+ */
+double spaceDiagonal(const BoundingBox& box)
+{
+	return distance(box.minimum, box.maximum);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/types/boundingbox.h	Sat Dec 14 22:36:06 2019 +0200
@@ -0,0 +1,35 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2018 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 "vertex.h"
+#include "math.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);
+};
+
+static constexpr BoundingBox emptyBoundingBox = {};
+Point3D center(const BoundingBox& box);
+double longestMeasure(const BoundingBox& box);
+double spaceDiagonal(const BoundingBox& box);

mercurial