Now builds again

Thu, 09 Jun 2022 19:11:27 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Thu, 09 Jun 2022 19:11:27 +0300
changeset 211
b27b90fb993f
parent 210
232e7634cc8a
child 212
27259810da6d

Now builds again

src/gl/compiler.cpp 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/compiler.cpp	Thu Jun 09 13:32:55 2022 +0300
+++ b/src/gl/compiler.cpp	Thu Jun 09 19:11:27 2022 +0300
@@ -125,6 +125,36 @@
 }
 )";
 
+template<typename Fn>
+constexpr void pointsToRender(const PolygonElement& element, Fn func)
+{
+	visitPolygon<void>(
+		[&func](const LineSegment& edge)
+		{
+			func(edge.p1, glm::vec3{});
+			func(edge.p2, glm::vec3{});
+		},
+		[&func](const Triangle& tri)
+		{
+			func(tri.p1, normalVector({tri.p3, tri.p1, tri.p2}));
+			func(tri.p2, normalVector({tri.p1, tri.p2, tri.p3}));
+			func(tri.p3, normalVector({tri.p2, tri.p3, tri.p1}));
+		},
+		[&func](const Quadrilateral& quad)
+		{
+			func(quad.p1, normalVector({quad.p4, quad.p1, quad.p2}));
+			func(quad.p2, normalVector({quad.p1, quad.p2, quad.p3}));
+			func(quad.p3, normalVector({quad.p2, quad.p3, quad.p4}));
+			func(quad.p4, normalVector({quad.p3, quad.p4, quad.p1}));
+		},
+		[&func](const ConditionalEdge& cedge)
+		{
+			func(cedge.p1, glm::vec3{});
+			func(cedge.p2, glm::vec3{});
+		},
+		element);
+}
+
 void gl::buildShaders(
 	QOpenGLShaderProgram* shaderProgram,
 	const char* vertexShaderSource,
@@ -165,10 +195,8 @@
 
 void gl::initializeModelShaders(gl::ModelShaders *modelShaders)
 {
-	if (not modelShaders->initialized)
-	{
-		for (auto& shader : modelShaders->shaderObjects)
-		{
+	if (not modelShaders->initialized) {
+		for (auto& shader : modelShaders->shaderObjects) {
 			shader.program = std::make_unique<QOpenGLShaderProgram>();
 			gl::buildShaders(shader.program.get(), ::vertexShaderSource, ::fragmentShaderSource);
 			shader.program->bind();
@@ -177,8 +205,7 @@
 			shader.buffer.setUsagePattern(QOpenGLBuffer::DynamicDraw);
 			shader.vertexArray.create();
 			shader.vertexArray.bind();
-			for (int k : {0, 1, 2, 3, 4})
-			{
+			for (int k : {0, 1, 2, 3, 4}) {
 				shader.program->enableAttributeArray(k);
 			}
 			using Vertex = ModelShaders::Vertex;
@@ -209,16 +236,11 @@
 template<typename Fn>
 void iterateModelPolygons(Model* model, DocumentManager* context, Fn&& fn)
 {
-	std::optional<ModelId> modelId = context->findIdForModel(model);
-	if (modelId.has_value())
-	{
-		PolygonCache* cache = context->getPolygonCacheForModel(modelId.value());
-		if (cache != nullptr)
-		{
-			for (const WithId<PolygonElement>& polygon : getCachedPolygons(cache, model, context))
-			{
-				fn(polygon);
-			}
+	PolygonCache* cache = findPolygonCacheForModel(model, context);
+	if (cache != nullptr) {
+		const PolygonCache::vector_type* polygons = getCachedPolygons(cache, model, context);
+		for (const WithId<PolygonElement>& polygon : *polygons) {
+			fn(polygon);
 		}
 	}
 }
@@ -255,9 +277,9 @@
 	BoundingBox result = emptyBoundingBox;
 	iterateModelPolygons(model, context, [&](const PolygonElement& polygon)
 	{
-		visitPoints(
-			[&result](const glm::vec3& p) { addPointToBox(result, p); },
-			polygon);
+		visitPoints([&result](const glm::vec3& p) {
+			addPointToBox(result, p);
+		}, polygon);
 	});
 	return result;
 }
@@ -275,24 +297,18 @@
 	for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects) {
 		shader.cachedData.clear();
 	}
-	iterateModelPolygons(model, context, [&](const PolygonElement& polygon)
+	iterateModelPolygons(model, context, [&](const WithId<PolygonElement>& polygon)
 	{
 		const int index = static_cast<int>(classifyPolygon(polygon));
 		std::vector<gl::ModelShaders::Vertex>& vertexBuffer = shaders->shaderObjects[index].cachedData;
-		auto vertexRing = iter::ring(polygon.vertices, polygon.numPolygonVertices());
-		reserveMore(vertexBuffer, polygon.numPolygonVertices());
 		const QColor color = getColorForPolygon(polygon, preferences, colorTable);
-		for (unsigned int i = 0; i < polygon.numPolygonVertices(); i += 1)
-		{
-			const glm::vec3& v1 = vertexRing[i - 1];
-			const glm::vec3& v2 = vertexRing[i];
-			const glm::vec3& v3 = vertexRing[i + 1];
+		pointsToRender(polygon, [&](const glm::vec3& point, const glm::vec3& normal){
 			gl::ModelShaders::Vertex& vertex = vertexBuffer.emplace_back();
-			vertex.position = polygon.vertices[i];
-			vertex.normal = glm::normalize(glm::cross(v1 - v2, v3 - v2));
+			vertex.position = point;
+			vertex.normal = normal;
 			vertex.color = glm::vec4{color.redF(), color.greenF(), color.blueF(), color.alphaF()};
 			vertex.id = polygon.id.value;
-		}
+		});
 	});
 	for (gl::ModelShaders::ShaderObject& shader : shaders->shaderObjects)
 	{
--- a/src/model.h	Thu Jun 09 13:32:55 2022 +0300
+++ b/src/model.h	Thu Jun 09 19:11:27 2022 +0300
@@ -60,6 +60,12 @@
 };
 
 template<typename T, typename R>
+struct transfer_reference<const T&, R>
+{
+	using type = const std::remove_reference_t<R>&;
+};
+
+template<typename T, typename R>
 struct transfer_reference<T&&, R>
 {
 	using type = std::remove_reference_t<R>&&;
@@ -88,7 +94,7 @@
 	ConditionalEdge>>;
 
 template<typename T>
-struct remove_color { using type = T; };
+struct remove_color {};
 
 template<typename T>
 struct remove_color<Colored<T>> { using type = T; };
@@ -97,30 +103,43 @@
 struct remove_color<Colored<T>&> { using type = T&; };
 
 template<typename T>
+struct remove_color<const Colored<T>&> { using type = const T&; };
+
+template<typename T>
 struct remove_color<Colored<T>&&> { using type = T&&; };
 
 template<typename T>
 using remove_color_t = typename remove_color<T>::type;
 
+static_assert(std::is_same_v<remove_color_t<Colored<Triangle>>, Triangle>);
+static_assert(std::is_same_v<remove_color_t<Colored<Triangle>&>, Triangle&>);
+static_assert(std::is_same_v<remove_color_t<const Colored<Triangle>&>, const Triangle&>);
+
 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)
+template<typename Ret, typename Fn1, typename Fn2, typename Fn3, typename Fn4, typename T>
+constexpr auto visitPolygon(Fn1&& f1, Fn2&& f2, Fn3&& f3, Fn4&& f4, T&& element)
 {
-	return std::visit(overloaded{f1, f2, f3, f4}, extract_colored(element));
+	if (std::holds_alternative<LineSegment>(element)) {
+		return f1(std::get<LineSegment>(element));
+	}
+	else if (std::holds_alternative<Triangle>(element)) {
+		return f2(std::get<Triangle>(element));
+	}
+	else if (std::holds_alternative<Quadrilateral>(element)) {
+		return f3(std::get<Quadrilateral>(element));
+	}
+	else {
+		return f4(std::get<ConditionalEdge>(element));
+	}
 }
 
 template<typename T, typename Fn>
-constexpr void visitPoints(T&& element, Fn func)
+constexpr void visitPoints(Fn&& func, T&& element)
 {
 	visitPolygon<void>(
 		[&func](transfer_reference_t<T&&, LineSegment> edge)
--- a/src/polygoncache.cpp	Thu Jun 09 13:32:55 2022 +0300
+++ b/src/polygoncache.cpp	Thu Jun 09 19:11:27 2022 +0300
@@ -11,12 +11,23 @@
 	PolygonElement element,
 	const glm::mat4& transform)
 {
-	visitPoints(element, [&transform](glm::vec3& p) {
+	visitPoints([&transform](glm::vec3& p) {
 		p = transform * glm::vec4{p, 1};
-	});
+	}, element);
 	return element;
 }
 
+PolygonCache* findPolygonCacheForModel(Model* model, DocumentManager* context)
+{
+	std::optional<ModelId> modelId = context->findIdForModel(model);
+	if (modelId.has_value()) {
+		return context->getPolygonCacheForModel(modelId.value());
+	}
+	else {
+		return nullptr;
+	}
+}
+
 static std::vector<WithId<PolygonElement>> getPolygonsAt(
 	const Model* model,
 	GetPolygonsContext* context)
@@ -39,24 +50,20 @@
 			[&](const Colored<ConditionalEdge>& cedge) {
 				result.push_back({{cedge, cedge.color}, id});
 			},
-			[&](const Colored<SubfileReference>& ref) {
+			[&result, &id, context](const Colored<SubfileReference>& ref) {
 				Model* dependency = context->documents->findDependencyByName(context->modelId, ref.name);
 				PolygonCache* cache = nullptr;
-				if (dependency != nullptr)
-				{
-					const auto dependencyModelId = context->documents->findIdForModel(dependency);
-					if (dependencyModelId.has_value()) {
-						cache = context->documents->getPolygonCacheForModel(dependencyModelId.value());
-					}
+				if (dependency != nullptr) {
+					cache = findPolygonCacheForModel(dependency, context->documents);
 				}
 				if (cache != nullptr) {
 					const bool needInverting = glm::determinant(ref.transformation) < 0;
-					const auto& modelPolygons = getCachedPolygons(
+					const PolygonCache::vector_type* modelPolygons = getCachedPolygons(
 						cache,
 						dependency,
 						context->documents);
-					result.reserve(result.size() + modelPolygons.size());
-					for (WithId<PolygonElement> polygon : modelPolygons) {
+					reserveMore(result, modelPolygons->size());
+					for (WithId<PolygonElement> polygon : *modelPolygons) {
 						polygon = {transformed(polygon, ref.transformation), polygon.id};
 						if (needInverting != ref.inverted) {
 							gl::invert(polygon);
@@ -81,7 +88,7 @@
  * @param documents Documents to use to resolve subfile references
  * @return vector of GL polygons
  */
-const std::vector<WithId<PolygonElement>> &getCachedPolygons(
+const PolygonCache::vector_type* getCachedPolygons(
 	PolygonCache *cache,
 	Model *model,
 	DocumentManager *documents)
@@ -97,5 +104,5 @@
 		}
 		cache->needRecache = false;
 	}
-	return cache->cachedPolygons;
+	return &cache->cachedPolygons;
 }
--- a/src/polygoncache.h	Thu Jun 09 13:32:55 2022 +0300
+++ b/src/polygoncache.h	Thu Jun 09 19:11:27 2022 +0300
@@ -17,11 +17,13 @@
 
 struct PolygonCache
 {
-	std::vector<WithId<PolygonElement>> cachedPolygons;
+	using vector_type = std::vector<WithId<PolygonElement>>;
+	vector_type cachedPolygons;
 	bool needRecache = true;
 };
 
-const std::vector<WithId<PolygonElement>>& getCachedPolygons(
+const PolygonCache::vector_type* getCachedPolygons(
 	PolygonCache* cache,
 	Model* model,
 	class DocumentManager* documents);
+PolygonCache* findPolygonCacheForModel(Model* model, DocumentManager* context);

mercurial