src/polygoncache.cpp

changeset 333
07e65a4c6611
parent 318
216f02b50b0a
child 338
719b909a7d2b
--- a/src/polygoncache.cpp	Mon Jul 04 15:37:22 2022 +0300
+++ b/src/polygoncache.cpp	Mon Jul 04 19:53:13 2022 +0300
@@ -2,6 +2,7 @@
 #include "src/documentmanager.h"
 #include "src/invert.h"
 #include "src/polygoncache.h"
+#include "src/parser.h"
 
 Model* resolve(const QString& name, const ModelId callingModelId, DocumentManager* documents)
 {
@@ -40,16 +41,26 @@
 	return a xor n_xor(rest...);
 }
 
+namespace {
+struct GetPolygonsContext
+{
+	bool invertnext = false;
+	ModelId modelId;
+	class DocumentManager* documents;
+};
+}
+
 template<typename Fn, typename Fn2>
 static void inlineSubfileReference(
 	const PolygonCache::vector_type& polygons,
 	const Colored<SubfileReference>& ref,
+	GetPolygonsContext* context,
 	Fn&& add,
 	Fn2&& reserve)
 {
 	const bool needInverting = 0
 		^ (glm::determinant(ref.transformation) < 0)
-		^ (ref.inverted);
+		^ (context->invertnext);
 	reserve(polygons.size());
 	for (const PolygonElement& cacheElement : polygons) {
 		PolygonElement polygon = transformed(cacheElement, ref.transformation);
@@ -63,42 +74,60 @@
 	}
 }
 
-Model* findDependency(const SubfileReference& ref, GetPolygonsContext* context)
+static Model* findDependency(const SubfileReference& ref, GetPolygonsContext* context)
 {
 	return context->documents->findDependencyByName(context->modelId, ref.name);
 }
 
 template<typename Fn, typename Fn2>
 static void collectPolygons(
-	const ModelElement& element,
+	const ParsedLine& element,
 	Winding& winding,
 	GetPolygonsContext* context,
 	Fn&& add,
 	Fn2&& reserve)
 {
+	bool foundinvertnext = false;
 	std::visit<void>(overloaded{
-		[&](const Colored<LineSegment>& edge) {
-			add({edge, edge.color});
-		},
-		[&](const Colored<Triangle>& triangle) {
-			add({triangle, triangle.color});
+		[&](const LineType0& line0) {
+			const QString text = line0.value.text.simplified();
+			if (text == QStringLiteral("BFC INVERTNEXT")) {
+				context->invertnext = true;
+				foundinvertnext = true;
+			}
+			else if (text == QStringLiteral("BFC CERTIFY CW")) {
+				winding = Clockwise;
+			}
+			else if (text == QStringLiteral("BFC CERTIFY CCW")) {
+				winding = Anticlockwise;
+			}
+			else if (text == QStringLiteral("BFC NOCERTIFY")) {
+				winding = NoWinding;
+			}
 		},
-		[&](const Colored<Quadrilateral>& quad) {
-			add({quad, quad.color});
+		[&](const LineType2& line2) {
+			add({line2.value, line2.value.color});
+		},
+		[&](const LineType3& line3) {
+			add({line3.value, line3.value.color});
 		},
-		[&](const Colored<ConditionalEdge>& cedge) {
-			add({cedge, cedge.color});
+		[&](const LineType4& line4) {
+			add({line4.value, line4.value.color});
 		},
-		[&add, context, &reserve](const Colored<SubfileReference>& ref) {
-			Model* const dependency = findDependency(ref, context);
+		[&](const LineType5& line5) {
+			add({line5.value, line5.value.color});
+		},
+		[&add, context, &reserve](const LineType1& line1) {
+			Model* const dependency = findDependency(line1.value, context);
 			if (PolygonCache* cache = (dependency != nullptr)
 				? findPolygonCacheForModel(dependency, context->documents)
 				: nullptr
 			) {
 				recacheIfNeeded(cache, dependency, context->documents);
-				inlineSubfileReference(cache->polygons, ref, add, reserve);
+				inlineSubfileReference(cache->polygons, line1.value, context, add, reserve);
 			}
 		},
+	#if 0
 		[&add](const Colored<CircularPrimitive>& circ) {
 			rasterize(circ, [&](const PlainPolygonElement& polygon, ColorIndex color){
 				if (color == MAIN_COLOR) {
@@ -107,19 +136,11 @@
 				add(PolygonElement{polygon, color});
 			});
 		},
-		[&winding](const Comment& comment) {
-			if (comment.text == QStringLiteral("BFC CERTIFY CW")) {
-				winding = Clockwise;
-			} 
-			else if (comment.text == QStringLiteral("BFC CERTIFY CCW")) {
-				winding = Anticlockwise;
-			}
-			else if (comment.text == QStringLiteral("BFC NOCERTIFY")) {
-				winding = NoWinding;
-			}
-		},
-		[](const ModelElement&) {}
+	#endif
 	}, element);
+	if (not foundinvertnext) {
+		context->invertnext = false;
+	}
 }
 
 static std::vector<WithId<PolygonElement>> inlinePolygons(
@@ -128,19 +149,22 @@
 {
 	Winding winding = NoWinding;
 	std::vector<WithId<PolygonElement>> result;
-	for (std::size_t i = 0; i < model->size(); i += 1)
-	{
-		const ModelElement& element = (*model)[i];
-		const ElementId id = model->idAt(i);
-		collectPolygons(element, winding, context,
-			[&result, winding, id](const PolygonElement& poly){
-				result.push_back({poly, id});
-				if (winding == Winding::Clockwise) {
-					gl::invert(result.back());
-				}
-			}, [&result](std::size_t incomingsize){
-				reserveMore(result, incomingsize);
-			});
+	int i = 0;
+	const auto add = [&result, winding, i](const PolygonElement& poly){
+		result.push_back({poly, i});
+		if (winding == Winding::Clockwise) {
+			gl::invert(result.back());
+		}
+	};
+	const auto reserve = [&result](std::size_t incomingsize){
+		reserveMore(result, incomingsize);
+	};
+	for (const QString& line : model->toPlainText().split("\n")) {
+		const opt<ParsedLine> parsedline = parse(line);
+		if (parsedline.has_value()) {
+			collectPolygons(*parsedline, winding, context, add, reserve);
+		}
+		++i;
 	}
 	return result;
 }
@@ -153,7 +177,11 @@
 		const std::optional<ModelId> modelId = documents->findIdForModel(model);
 		if (modelId.has_value())
 		{
-			GetPolygonsContext context{modelId.value(), documents};
+			GetPolygonsContext context{
+				.invertnext = false,
+				.modelId = *modelId,
+				.documents = documents,
+			};
 			cache->polygons = inlinePolygons(model, &context);
 		}
 		cache->needRecache = false;

mercurial