--- 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;