Wed, 29 Jun 2022 14:43:42 +0300
Enable drawing clockwise shapes despite mapbox::earcut rewinding them
src/invert.cpp | file | annotate | diff | comparison | revisions | |
src/invert.h | file | annotate | diff | comparison | revisions | |
src/layers/edittools.cpp | file | annotate | diff | comparison | revisions |
--- a/src/invert.cpp Wed Jun 29 14:11:58 2022 +0300 +++ b/src/invert.cpp Wed Jun 29 14:43:42 2022 +0300 @@ -41,10 +41,10 @@ visitPolygon<void>( [](LineSegment&) {}, [](Triangle& tri) { - std::swap(tri.p1, tri.p2); + invert(tri); }, [](Quadrilateral& quad) { - std::swap(quad.p1, quad.p3); + invert(quad); }, [](ConditionalEdge&) {}, polygon);
--- a/src/invert.h Wed Jun 29 14:11:58 2022 +0300 +++ b/src/invert.h Wed Jun 29 14:43:42 2022 +0300 @@ -26,9 +26,32 @@ { glm::mat4 flipmatrix(Axis dimension); } -//void invert(LDObject* obj, class DocumentManager* context); + +constexpr void invert(Quadrilateral& quad) +{ + std::swap(quad.p1, quad.p3); +} + +constexpr Quadrilateral inverted(Quadrilateral quad) +{ + invert(quad); + return quad; +} + +constexpr void invert(Triangle& tri) +{ + std::swap(tri.p1, tri.p2); +} + +constexpr Triangle inverted(Triangle tri) +{ + invert(tri); + return tri; +} namespace gl { void invert(PolygonElement &polygon); } + +using gl::invert;
--- a/src/layers/edittools.cpp Wed Jun 29 14:11:58 2022 +0300 +++ b/src/layers/edittools.cpp Wed Jun 29 14:43:42 2022 +0300 @@ -24,6 +24,7 @@ #include "src/gl/partrenderer.h" #include "src/circularprimitive.h" #include "src/layers/edittools.h" +#include "src/invert.h" // Make mapbox::earcut work with glm::vec3 template<> struct mapbox::util::nth<0, glm::vec3> @@ -436,24 +437,38 @@ polygon2d.reserve(this->numpoints); for (std::size_t i = 0; i < this->numpoints; ++i) { polygon2d.push_back(inverseGrid * glm::vec4{this->polygon[i], 1}); - } + } + // mapbox::earcut will always produce a CCW polygon, so if we're drawing + // a CW polygon, we should invert the result afterwards + const float shouldInvert = glm::dot( + glm::vec3{inverseGrid[2]}, + glm::cross(this->polygon[0] - this->polygon[1], this->polygon[2] - this->polygon[1])); using indextype = std::uint16_t; const std::vector<indextype> indices = mapbox::earcut<std::uint16_t>(polygons); MergedTriangles mergedTriangles = mergeTriangles(indices, this->polygon); - for (const Quadrilateral& quad : mergedTriangles.quadrilaterals) { + for (Quadrilateral& quad : mergedTriangles.quadrilaterals) { + if (shouldInvert < 0) { + invert(quad); + } result.push_back(AppendToModel{ .newElement = Colored<Quadrilateral>{quad, MAIN_COLOR}, }); } for (std::size_t i = 0; i < indices.size(); i += 3) { if (mergedTriangles.cutTriangles.find(i) == mergedTriangles.cutTriangles.end()) { + Triangle triangle{ + Triangle{ + .p1 = this->polygon[indices[i]], + .p2 = this->polygon[indices[i + 1]], + .p3 = this->polygon[indices[i + 2]], + } + }; + if (shouldInvert < 0) { + invert(triangle); + } result.push_back(AppendToModel{ .newElement = Colored<Triangle>{ - Triangle{ - .p1 = this->polygon[indices[i]], - .p2 = this->polygon[indices[i + 1]], - .p3 = this->polygon[indices[i + 2]], - }, + triangle, MAIN_COLOR, } });