more refactoring, dosn't build yet

Thu, 09 Jun 2022 13:32:55 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Thu, 09 Jun 2022 13:32:55 +0300
changeset 210
232e7634cc8a
parent 209
c93e4a1eaadb
child 211
b27b90fb993f

more refactoring, dosn't build yet

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/model.h file | annotate | diff | comparison | revisions
src/polygoncache.cpp file | annotate | diff | comparison | revisions
src/polygoncache.h file | annotate | diff | comparison | revisions
--- a/src/gl/common.h	Thu Jun 09 11:51:42 2022 +0300
+++ b/src/gl/common.h	Thu Jun 09 13:32:55 2022 +0300
@@ -31,7 +31,6 @@
 
 namespace gl
 {
-	struct Polygon;
 	class ShaderProgram;
 
 	void buildShaders(
@@ -67,121 +66,10 @@
 	}
 };
 
-struct gl::Polygon
-{
-	enum Type : qint8
-	{
-		EdgeLine,
-		Triangle,
-		Quadrilateral,
-		ConditionalEdge
-	} type;
-	glm::vec3 vertices[4];
-	ldraw::Color color;
-	ModelId id;
-
-	/**
-	 * @return amount of vertices used for geometry
-	 */
-	inline unsigned int numPolygonVertices() const
-	{
-		if (type == Type::ConditionalEdge)
-			return 2;
-		else
-			return numVertices();
-	}
-
-	/**
-	 * @return amount of vertices
-	 */
-	inline unsigned int numVertices() const
-	{
-		switch (type)
-		{
-		case Type::EdgeLine:
-			return 2;
-		case Type::Triangle:
-			return 3;
-		case Type::ConditionalEdge:
-		case Type::Quadrilateral:
-			return 4;
-		}
-		return 0;
-	}
-};
-
-Q_DECLARE_METATYPE(gl::Polygon)
 extern QOpenGLFunctions glfunc;
 
 namespace gl
 {
-	constexpr Polygon::Type POLYGON_TYPES[] =
-	{
-		Polygon::Type::EdgeLine,
-		Polygon::Type::Triangle,
-		Polygon::Type::Quadrilateral,
-		Polygon::Type::ConditionalEdge
-	};
-
-	constexpr int NUM_POLYGON_TYPES = countof(POLYGON_TYPES);
-
-	inline Polygon edgeLine(const Colored<LineSegment>& seg, ModelId id)
-	{
-		return Polygon{
-			.type = Polygon::EdgeLine,
-			.vertices = {seg.p1, seg.p2},
-			.color = seg.color,
-			.id = id,
-		};
-	}
-
-	inline Polygon triangle(const Colored<Triangle>& tri, ModelId id)
-	{
-		return Polygon{
-			.type = Polygon::Triangle,
-			.vertices = {tri.p1, tri.p2, tri.p3},
-			.color = tri.color,
-			.id = id,
-		};
-	}
-
-	inline Polygon quadrilateral(const Colored<Quadrilateral>& quad, ModelId id)
-	{
-		return Polygon{
-			.type = Polygon::Quadrilateral,
-			.vertices = {quad.p1, quad.p2, quad.p3, quad.p4},
-			.color = quad.color,
-			.id = id,
-		};
-	}
-
-	inline Polygon conditionalEdge(const Colored<ConditionalEdge>& cedge, ModelId id)
-	{
-		return Polygon{
-			.type = Polygon::ConditionalEdge,
-			.vertices = {cedge.p1, cedge.p2, cedge.c1, cedge.c2},
-			.color = cedge.color,
-			.id = id,
-		};
-	}
-
-	// Vbo names
-	enum class ArrayClass : std::uint8_t
-	{
-		Lines,
-		Triangles,
-		Quads,
-		ConditionalLines
-	};
-
-	constexpr ArrayClass ARRAY_CLASSES[] = {
-		ArrayClass::Lines,
-		ArrayClass::Triangles,
-		ArrayClass::Quads,
-		ArrayClass::ConditionalLines,
-	};
-	constexpr int NUM_ARRAY_CLASSES = countof(ARRAY_CLASSES);
-
 	// Different ways to render the scene
 	enum class RenderStyle
 	{
--- a/src/gl/compiler.cpp	Thu Jun 09 11:51:42 2022 +0300
+++ b/src/gl/compiler.cpp	Thu Jun 09 13:32:55 2022 +0300
@@ -196,20 +196,14 @@
 	}
 }
 
-static gl::ArrayClass classifyPolygon(const gl::Polygon& polygon)
+static constexpr gl::ArrayClass classifyPolygon(const PolygonElement& element)
 {
-	switch (polygon.type)
-	{
-	case gl::Polygon::EdgeLine:
-		return gl::ArrayClass::Lines;
-	case gl::Polygon::Triangle:
-		return gl::ArrayClass::Triangles;
-	case gl::Polygon::Quadrilateral:
-		return gl::ArrayClass::Quads;
-	case gl::Polygon::ConditionalEdge:
-		return gl::ArrayClass::ConditionalLines;
-	}
-	return gl::ArrayClass::Lines;
+	return visitPolygon<gl::ArrayClass>(
+		[](const LineSegment&) { return gl::ArrayClass::Lines; },
+		[](const Triangle&) { return gl::ArrayClass::Triangles; },
+		[](const Quadrilateral&) { return gl::ArrayClass::Quads; },
+		[](const ConditionalEdge&) { return gl::ArrayClass::ConditionalLines; },
+		element);
 }
 
 template<typename Fn>
@@ -221,7 +215,7 @@
 		PolygonCache* cache = context->getPolygonCacheForModel(modelId.value());
 		if (cache != nullptr)
 		{
-			for (const gl::Polygon& polygon : getCachedPolygons(cache, model, context))
+			for (const WithId<PolygonElement>& polygon : getCachedPolygons(cache, model, context))
 			{
 				fn(polygon);
 			}
@@ -230,7 +224,7 @@
 }
 
 static QColor getColorForPolygon(
-	const gl::Polygon& polygon,
+	const PolygonElement& polygon,
 	const gl::RenderPreferences& preferences,
 	const ColorTable& colorTable)
 {
@@ -259,12 +253,11 @@
 BoundingBox gl::boundingBoxForModel(Model* model, DocumentManager* context)
 {
 	BoundingBox result = emptyBoundingBox;
-	iterateModelPolygons(model, context, [&](const gl::Polygon& polygon)
+	iterateModelPolygons(model, context, [&](const PolygonElement& polygon)
 	{
-		for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
-		{
-			addPointToBox(result, polygon.vertices[i]);
-		}
+		visitPoints(
+			[&result](const glm::vec3& p) { addPointToBox(result, p); },
+			polygon);
 	});
 	return result;
 }
@@ -282,7 +275,7 @@
 	for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) {
 		shader.cachedData.clear();
 	}
-	iterateModelPolygons(model, context, [&](const Polygon& polygon)
+	iterateModelPolygons(model, context, [&](const PolygonElement& polygon)
 	{
 		const int index = static_cast<int>(classifyPolygon(polygon));
 		std::vector<gl::ModelShaders::Vertex>& vertexBuffer = shaders->shaderObjects[index].cachedData;
--- a/src/gl/compiler.h	Thu Jun 09 11:51:42 2022 +0300
+++ b/src/gl/compiler.h	Thu Jun 09 13:32:55 2022 +0300
@@ -32,6 +32,23 @@
 
 namespace gl
 {
+	// VAO names
+	enum class ArrayClass : std::uint8_t
+	{
+		Lines,
+		Triangles,
+		Quads,
+		ConditionalLines
+	};
+	
+	constexpr ArrayClass ARRAY_CLASSES[] = {
+		ArrayClass::Lines,
+		ArrayClass::Triangles,
+		ArrayClass::Quads,
+		ArrayClass::ConditionalLines,
+	};
+	constexpr int NUM_ARRAY_CLASSES = countof(ARRAY_CLASSES);
+
 	struct ModelShaders
 	{
 		struct Vertex
@@ -51,7 +68,7 @@
 			QOpenGLVertexArrayObject vertexArray;
 			std::vector<Vertex> cachedData;
 			std::size_t vertexCount;
-		} shaderObjects[gl::NUM_POLYGON_TYPES];
+		} shaderObjects[gl::NUM_ARRAY_CLASSES];
 	};
 
 	void build(
--- a/src/invert.cpp	Thu Jun 09 11:51:42 2022 +0300
+++ b/src/invert.cpp	Thu Jun 09 13:32:55 2022 +0300
@@ -36,19 +36,16 @@
 /*
  * Inverts the winding of a polygon.
  */
-void gl::invert(gl::Polygon& polygon)
+void gl::invert(PolygonElement& polygon)
 {
-	switch (polygon.numPolygonVertices())
-	{
-	case 2:
-	case 3:
-		// 0 1 => 1 0
-		// 0 1 2 => 1 0 2
-		std::swap(polygon.vertices[0], polygon.vertices[1]);
-		break;
-	case 4:
-		// 0 1 2 3 => 0 3 2 1
-		std::swap(polygon.vertices[1], polygon.vertices[3]);
-		break;
-	}
+	visitPolygon<void>(
+		[](LineSegment&) {},
+		[](Triangle& tri) {
+			std::swap(tri.p1, tri.p2);
+		},
+		[](Quadrilateral& quad) {
+			std::swap(quad.p1, quad.p3);
+		},
+		[](ConditionalEdge&) {},
+		polygon);
 }
--- a/src/invert.h	Thu Jun 09 11:51:42 2022 +0300
+++ b/src/invert.h	Thu Jun 09 13:32:55 2022 +0300
@@ -30,5 +30,5 @@
 
 namespace gl
 {
-	void invert(gl::Polygon& polygon);
+	void invert(PolygonElement &polygon);
 }
--- a/src/model.h	Thu Jun 09 11:51:42 2022 +0300
+++ b/src/model.h	Thu Jun 09 13:32:55 2022 +0300
@@ -47,6 +47,30 @@
 
 struct Empty {};
 
+template<typename T, typename R>
+struct transfer_reference
+{
+	using type = std::remove_reference_t<R>;
+};
+
+template<typename T, typename R>
+struct transfer_reference<T&, R>
+{
+	using type = std::remove_reference_t<R>&;
+};
+
+template<typename T, typename R>
+struct transfer_reference<T&&, R>
+{
+	using type = std::remove_reference_t<R>&&;
+};
+
+template<typename T, typename R>
+using transfer_reference_t = typename transfer_reference<T, R>::type;
+static_assert(std::is_same_v<transfer_reference_t<int, char>, char>);
+static_assert(std::is_same_v<transfer_reference_t<int&, char>, char&>);
+static_assert(std::is_same_v<transfer_reference_t<int&&, char>, char&&>);
+
 using ModelElement = std::variant<
 	Colored<SubfileReference>,
 	Colored<LineSegment>,
@@ -57,6 +81,76 @@
 	Empty,
 	ParseError>;
 
+using PolygonElement = Colored<std::variant<
+	LineSegment,
+	Triangle,
+	Quadrilateral,
+	ConditionalEdge>>;
+
+template<typename T>
+struct remove_color { using type = T; };
+
+template<typename T>
+struct remove_color<Colored<T>> { using type = T; };
+
+template<typename T>
+struct remove_color<Colored<T>&> { using type = T&; };
+
+template<typename T>
+struct remove_color<Colored<T>&&> { using type = T&&; };
+
+template<typename T>
+using remove_color_t = typename remove_color<T>::type;
+
+template<typename T>
+constexpr remove_color_t<T&&> extract_colored(T&& x)
+{
+	return static_cast<remove_color_t<T&&>>(x);
+}
+
+template<typename Ret, typename T>
+constexpr auto visitPolygon(
+	std::function<Ret(transfer_reference_t<T&&, LineSegment>)> f1,
+	std::function<Ret(transfer_reference_t<T&&, Triangle>)> f2,
+	std::function<Ret(transfer_reference_t<T&&, Quadrilateral>)> f3,
+	std::function<Ret(transfer_reference_t<T&&, ConditionalEdge>)> f4,
+	T&& element)
+{
+	return std::visit(overloaded{f1, f2, f3, f4}, extract_colored(element));
+}
+
+template<typename T, typename Fn>
+constexpr void visitPoints(T&& element, Fn func)
+{
+	visitPolygon<void>(
+		[&func](transfer_reference_t<T&&, LineSegment> edge)
+		{
+			func(edge.p1);
+			func(edge.p2);
+		},
+		[&func](transfer_reference_t<T&&, Triangle>& tri)
+		{
+			func(tri.p1);
+			func(tri.p2);
+			func(tri.p3);
+		},
+		[&func](transfer_reference_t<T&&, Quadrilateral>& quad)
+		{
+			func(quad.p1);
+			func(quad.p2);
+			func(quad.p3);
+			func(quad.p4);
+		},
+		[&func](transfer_reference_t<T&&, ConditionalEdge>& cedge)
+		{
+			func(cedge.p1);
+			func(cedge.p2);
+			func(cedge.c1);
+			func(cedge.c2);
+		},
+		element);
+}
+
 QString modelElementToString(const ModelElement& element);
 struct ModelId
 {
--- a/src/polygoncache.cpp	Thu Jun 09 11:51:42 2022 +0300
+++ b/src/polygoncache.cpp	Thu Jun 09 13:32:55 2022 +0300
@@ -7,31 +7,37 @@
 	return documents->findDependencyByName(callingModelId, name);
 }
 
-/**
- * @brief Gets the GL polygons of the object at the specified position in the model
- * @param index Index of object in the model
- * @param polygons_out Vector to add polygons into
- * @param context Context to use to resolve subfile references
- */
-static std::vector<gl::Polygon> getPolygonsAt(const Model* model, GetPolygonsContext* context)
+static PolygonElement transformed(
+	PolygonElement element,
+	const glm::mat4& transform)
 {
-	std::vector<gl::Polygon> result;
+	visitPoints(element, [&transform](glm::vec3& p) {
+		p = transform * glm::vec4{p, 1};
+	});
+	return element;
+}
+
+static std::vector<WithId<PolygonElement>> getPolygonsAt(
+	const Model* model,
+	GetPolygonsContext* context)
+{
+	std::vector<WithId<PolygonElement>> result;
 	for (int i = 0; i < model->size(); i += 1)
 	{
 		const ModelElement& element = (*model)[i];
 		const ModelId id = model->idAt(i);
 		std::visit<void>(overloaded{
 			[&](const Colored<LineSegment>& edge) {
-				result.push_back(gl::edgeLine(edge, id));
+				result.push_back({{edge, edge.color}, id});
 			},
 			[&](const Colored<Triangle>& triangle) {
-				result.push_back(gl::triangle(triangle, id));
+				result.push_back({{triangle, triangle.color}, id});
 			},
 			[&](const Colored<Quadrilateral>& quad) {
-				result.push_back(gl::quadrilateral(quad, id));
+				result.push_back({{quad, quad.color}, id});
 			},
 			[&](const Colored<ConditionalEdge>& cedge) {
-				result.push_back(gl::conditionalEdge(cedge, id));
+				result.push_back({{cedge, cedge.color}, id});
 			},
 			[&](const Colored<SubfileReference>& ref) {
 				Model* dependency = context->documents->findDependencyByName(context->modelId, ref.name);
@@ -45,24 +51,17 @@
 				}
 				if (cache != nullptr) {
 					const bool needInverting = glm::determinant(ref.transformation) < 0;
-					const std::vector<gl::Polygon>& modelPolygons = getCachedPolygons(
+					const auto& modelPolygons = getCachedPolygons(
 						cache,
 						dependency,
 						context->documents);
 					result.reserve(result.size() + modelPolygons.size());
-					for (gl::Polygon polygon : modelPolygons)
-					{
-						for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
-						{
-							const glm::vec4 homogenousVertex {polygon.vertices[i], 1};
-							polygon.vertices[i] = ref.transformation * homogenousVertex;
-						}
-						if (needInverting != ref.inverted)
-						{
+					for (WithId<PolygonElement> polygon : modelPolygons) {
+						polygon = {transformed(polygon, ref.transformation), polygon.id};
+						if (needInverting != ref.inverted) {
 							gl::invert(polygon);
 						}
-						if (polygon.color == MAIN_COLOR)
-						{
+						if (polygon.color == MAIN_COLOR) {
 							polygon.color = ref.color;
 						}
 						polygon.id = id;
@@ -82,7 +81,7 @@
  * @param documents Documents to use to resolve subfile references
  * @return vector of GL polygons
  */
-const std::vector<gl::Polygon> &getCachedPolygons(
+const std::vector<WithId<PolygonElement>> &getCachedPolygons(
 	PolygonCache *cache,
 	Model *model,
 	DocumentManager *documents)
--- a/src/polygoncache.h	Thu Jun 09 11:51:42 2022 +0300
+++ b/src/polygoncache.h	Thu Jun 09 13:32:55 2022 +0300
@@ -3,6 +3,12 @@
 #include "model.h"
 #include "gl/common.h"
 
+template<typename T>
+struct WithId : T
+{
+	ModelId id;
+};
+
 struct GetPolygonsContext
 {
 	ModelId modelId;
@@ -11,11 +17,11 @@
 
 struct PolygonCache
 {
-	std::vector<gl::Polygon> cachedPolygons;
+	std::vector<WithId<PolygonElement>> cachedPolygons;
 	bool needRecache = true;
 };
 
-const std::vector<gl::Polygon>& getCachedPolygons(
+const std::vector<WithId<PolygonElement>>& getCachedPolygons(
 	PolygonCache* cache,
 	Model* model,
 	class DocumentManager* documents);

mercurial