diff -r 180072db4a83 -r a39f454a3d7f src/layers/edittools.cpp --- a/src/layers/edittools.cpp Sun Jul 03 15:59:22 2022 +0300 +++ b/src/layers/edittools.cpp Sun Jul 03 20:18:34 2022 +0300 @@ -88,54 +88,8 @@ // And finally transform it back to grid coordinates by transforming it with the // grid matrix. this->worldPosition = this->gridMatrix * glm::vec4{*this->worldPosition, 1}; - this->polygon.back() = *this->worldPosition; - this->numpoints = this->calcNumPoints(); - } -} - -static QVector convertWorldPointsToScreenPoints( - const std::vector &worldPoints, - const PartRenderer* renderer) -{ - QVector points2d; - points2d.reserve(static_cast(worldPoints.size())); - for (const glm::vec3& point : worldPoints) - { - points2d.push_back(renderer->modelToScreenCoordinates(point)); + this->inputPolygon.updateCurrentPoint(*this->worldPosition); } - return points2d; -} - -static Winding worldPolygonWinding( - const std::vector &points, - const PartRenderer* renderer) -{ - return winding(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)}); -} - -static void drawWorldPoint( - QPainter* painter, - const glm::vec3& worldPoint, - const PartRenderer* renderer) -{ - const QPointF center = renderer->modelToScreenCoordinates(worldPoint); - painter->drawEllipse(inscribe(CircleF{center, 5})); -} - -static void drawWorldPolyline( - QPainter *painter, - const std::vector &points, - const PartRenderer* renderer) -{ - painter->drawPolyline(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)}); -} - -static void drawWorldPolygon( - QPainter* painter, - const std::vector &points, - const PartRenderer* renderer) -{ - painter->drawPolygon(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)}); } //! \brief Conversion function from PlainPolygonElement to ModelElement @@ -183,7 +137,6 @@ const QPen pointPen; const QPen textPen; const QPen polygonPen; - const QPen badPolygonPen; const QBrush greenPolygonBrush; const QBrush redPolygonBrush; }; @@ -240,11 +193,6 @@ } } -constexpr QPointF vecToQPoint(const glm::vec2& a) -{ - return {a.x, a.y}; -} - void EditTools::renderPreview(QPainter* painter, const void* pensptr) { const Pens& pens = *reinterpret_cast(pensptr); @@ -267,11 +215,11 @@ } painter->setBrush(pens.pointBrush); painter->setPen(pens.pointPen); - for (const glm::vec3& point : this->polygon) { + for (const glm::vec3& point : this->inputPolygon) { drawWorldPoint(painter, point, this->renderer); } - if (this->mode == CircleMode and this->polygon.size() >= 2) { - const glm::vec3 circleOrigin = this->polygon[0]; + if (this->mode == CircleMode and this->inputPolygon.polygonSize() >= 2) { + const glm::vec3 circleOrigin = this->inputPolygon[0]; const QPointF originScreen = this->renderer->modelToScreenCoordinates(circleOrigin); const auto extremity = [this, &originScreen](const glm::vec3& p){ const QPointF s2 = this->renderer->modelToScreenCoordinates(p); @@ -287,25 +235,25 @@ }; const glm::vec3 zvec = this->gridMatrix[2]; { - const glm::vec2 p1 = extremity(this->polygon[0] + zvec); - const glm::vec2 p2 = extremity(this->polygon[0] - zvec); + const glm::vec2 p1 = extremity(this->inputPolygon[0] + zvec); + const glm::vec2 p2 = extremity(this->inputPolygon[0] - zvec); const glm::vec2 lateral = glm::normalize(glm::mat2{{0, 1}, {-1, 0}} * (p2 - p1)); painter->setPen(QPen{Qt::white, 3}); painter->drawLine(vecToQPoint(p1), vecToQPoint(p2)); constexpr float notchsize = 40.0f; for (int a = -30; a <= 30; ++a) { - const glm::vec3 notch = this->polygon[0] + static_cast(a) * zvec; + const glm::vec3 notch = this->inputPolygon[0] + static_cast(a) * zvec; const QPointF s_notchcenter = this->renderer->modelToScreenCoordinates(notch); const QPointF notch_s1 = s_notchcenter + notchsize * 0.5f * vecToQPoint(lateral); const QPointF notch_s2 = s_notchcenter - notchsize * 0.5f * vecToQPoint(lateral); painter->drawLine(notch_s1, notch_s2); } } - if (this->polygon.size() >= 3) { + if (this->inputPolygon.polygonSize() >= 3) { const opt height = this->cylinderHeight(); if (height.has_value()) { const glm::vec3 heightvec = height.value_or(0) * zvec; - const glm::vec3 p = this->polygon[1] + 0.5f * heightvec; + const glm::vec3 p = this->inputPolygon[1] + 0.5f * heightvec; QFont font{}; font.setBold(true); drawBorderedText(painter, this->renderer->modelToScreenCoordinates(p), font, QString::number(*height)); @@ -314,50 +262,20 @@ } } -void EditTools::removeLastPoint() -{ - if (this->polygon.size() > 1) { - this->polygon.erase(this->polygon.end() - 2); - this->numpoints = this->calcNumPoints(); - } -} - -bool EditTools::isCloseToExistingPoints() const -{ - if (this->worldPosition.has_value()) { - const glm::vec3& pos = *this->worldPosition; - return std::any_of(this->polygon.begin(), this->polygon.end() - 1, [&pos](const glm::vec3& p){ - return isclose(pos, p); - }); - } - else { - return false; - } -} - -std::size_t EditTools::calcNumPoints() const -{ - std::size_t result = this->polygon.size(); - if (this->isCloseToExistingPoints()) { - result -= 1; - } - return result; -} - opt EditTools::cylinderHeight() const { - if (this->polygon.size() < 3) { + if (this->inputPolygon.bufferSize() < 3) { return {}; } else { const Plane plane{ .normal = glm::normalize(this->renderer->cameraVector(this->localPosition)), - .anchor = this->polygon[0], + .anchor = this->inputPolygon[0], }; const opt p = this->renderer->screenToModelCoordinates(this->localPosition, plane); if (p.has_value()) { const glm::vec3 heightvec = glm::normalize(glm::vec3{gridMatrix[2]}); - return std::round(glm::dot(*p - polygon[0], heightvec)); + return std::round(glm::dot(*p - this->inputPolygon[0], heightvec)); } else { return {}; @@ -381,27 +299,27 @@ break; case DrawMode: if (event->button() == Qt::LeftButton and this->worldPosition.has_value()) { - if (isCloseToExistingPoints()) { + if (this->inputPolygon.currentPointOnExistingPoint()) { this->closeShape(); } else { - this->polygon.push_back(*this->worldPosition); + this->inputPolygon.finishCurrentPoint(); } } break; case CircleMode: if (event->button() == Qt::LeftButton) { - if (this->polygon.size() == 3) { + if (this->inputPolygon.bufferSize() == 3) { this->closeShape(); } else if (this->worldPosition.has_value()) { - this->polygon.push_back(*this->worldPosition); + this->inputPolygon.finishCurrentPoint(); } } break; } - if (event->button() == Qt::RightButton and this->polygon.size() > 1) { - this->removeLastPoint(); + if (event->button() == Qt::RightButton) { + this->inputPolygon.removeLastPoint(); } } @@ -409,14 +327,14 @@ const std::vector EditTools::circleModeActions() const { std::vector result; - if (this->numpoints >= 2) { - const glm::vec3 x = polygon[1] - polygon[0]; + if (this->inputPolygon.polygonSize() >= 2) { + const glm::vec3 x = this->inputPolygon[1] - this->inputPolygon[0]; const opt cyliheight = this->cylinderHeight().value_or(1); glm::mat4 transform{ glm::vec4{x, 0}, *cyliheight * this->gridMatrix[2], glm::vec4{glm::cross(glm::vec3{-this->gridMatrix[2]}, x), 0}, - glm::vec4{this->polygon[0], 1}, + glm::vec4{this->inputPolygon[0], 1}, }; Colored circ{ CircularPrimitive{ @@ -434,13 +352,13 @@ const std::vector EditTools::drawModeActions() const { std::vector result; - if (this->numpoints == 2) { - result.push_back(AppendToModel{edge(this->polygon[0], this->polygon[1])}); + if (this->inputPolygon.polygonSize() == 2) { + result.push_back(AppendToModel{edge(this->inputPolygon[0], this->inputPolygon[1])}); } - else if (this->numpoints > 2) { + else if (this->inputPolygon.polygonSize() > 2) { for (const PlainPolygonElement& poly : polygonize( - this->polygon.begin(), - this->polygon.begin() + static_cast(this->numpoints)) + this->inputPolygon.begin(), + this->inputPolygon.polygonEnd()) ) { result.push_back(AppendToModel{ .newElement = elementFromPolygonAndColor(poly, MAIN_COLOR), @@ -467,6 +385,5 @@ for (const ModelAction& action : this->modelActions()) { Q_EMIT this->modelAction(action); } - this->polygon.clear(); - this->polygon.push_back(this->worldPosition.value_or(glm::vec3{0, 0, 0})); + this->inputPolygon.clear(); }