diff -r 3dbdc243f053 -r d355d4c52d51 src/tools/drawtool.cpp --- a/src/tools/drawtool.cpp Wed May 25 13:49:45 2022 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,219 +0,0 @@ -#include -#include -#include "linetypes/edge.h" -#include "linetypes/triangle.h" -#include "linetypes/quadrilateral.h" -#include "drawtool.h" -#include "modeleditor.h" - -static const QBrush pointBrush = {Qt::white}; -static const QPen polygonPen = {QBrush{Qt::black}, 2.0, Qt::DashLine}; -static const QPen badPolygonPen = {QBrush{Qt::red}, 2.0, Qt::DashLine}; -static const QPen pointPen = {QBrush{Qt::black}, 2.0}; -static const QBrush greenPolygonBrush = {QColor{64, 255, 128, 192}}; -static const QBrush redPolygonBrush = {QColor{255, 96, 96, 192}}; - -AbstractDrawTool::AbstractDrawTool(Document *document) : - BaseTool{document} -{ -} - -DrawTool::DrawTool(Document* document) : - AbstractDrawTool{document} -{ -} - -QString DrawTool::name() const -{ - static const QString result = tr("Draw"); - return result; -} - -QString DrawTool::toolTip() const -{ - static const QString result = tr("Draw new elements into the model."); - return result; -} - -bool AbstractDrawTool::mouseClick(Canvas* canvas, QMouseEvent* event) -{ - if (event->button() == Qt::LeftButton) - { - this->addCurrentPoint(canvas); - return true; - } - else if (event->button() == Qt::RightButton) - { - this->removeLastPoint(); - return true; - } - else - { - return false; - } -} - -bool AbstractDrawTool::mouseMove(Document* document, Canvas* canvas, QMouseEvent *event) -{ - static_cast(document); - static_cast(event); - const auto& worldPosition = canvas->getWorldPosition(); - if (worldPosition.has_value()) - { - this->previewPoint = worldPosition.value(); - this->updatePreviewPolygon(); - } - return false; -} - -bool AbstractDrawTool::keyReleased(Document*, Canvas* canvas, QKeyEvent* event) -{ - if (event->key() == Qt::Key_Escape) - { - this->polygon.clear(); - this->updatePreviewPolygon(); - canvas->update(); - return true; - } - else - { - return false; - } -} - -void AbstractDrawTool::addCurrentPoint(Canvas* canvas) -{ - const auto& worldPosition = canvas->getWorldPosition(); - if (worldPosition.has_value()) - { - const glm::vec3& pos = worldPosition.value(); - if (this->isCloseToExistingPoints(pos)) - { - this->closeShape(); - } - else - { - this->addPoint(pos); - } - } -} - -void AbstractDrawTool::updatePreviewPolygon() -{ - this->previewPolygon = this->polygon; - this->previewPolygon.resize(this->polygon.size() + 1); - this->previewPolygon.back() = this->previewPoint; - if (this->previewPolygon.size() > 2) - { - this->isconcave = not geom::isConvex(this->previewPolygon); - } -} - -void AbstractDrawTool::reset() -{ - this->polygon.clear(); -} - -void AbstractDrawTool::overpaint(Canvas* canvas, QPainter* painter) const -{ - painter->setPen(this->isconcave ? ::badPolygonPen : ::polygonPen); - if (this->previewPolygon.size() > 2 and not this->isconcave) - { - if (canvas->worldPolygonWinding(this->previewPolygon) == Winding::Clockwise) - { - painter->setBrush(::greenPolygonBrush); - } - else - { - painter->setBrush(::redPolygonBrush); - } - canvas->drawWorldPolygon(painter, this->previewPolygon); - } - else - { - canvas->drawWorldPolyline(painter, this->previewPolygon); - } - painter->setBrush(::pointBrush); - painter->setPen(::pointPen); - for (const glm::vec3& point : this->polygon) - { - canvas->drawWorldPoint(painter, point); - } - canvas->drawWorldPoint(painter, this->previewPoint); -} - -void AbstractDrawTool::addPoint(const glm::vec3 &pos) -{ - this->polygon.push_back(pos); - this->updatePreviewPolygon(); -} - -void AbstractDrawTool::removeLastPoint() -{ - if (this->polygon.size() > 0) - { - this->polygon.erase(this->polygon.end() - 1); - this->updatePreviewPolygon(); - } -} - -void AbstractDrawTool::clearPoints() -{ - this->polygon.clear(); - this->updatePreviewPolygon(); -} - -bool AbstractDrawTool::isCloseToExistingPoints(const glm::vec3 &pos) const -{ - const auto isCloseToPos = [&](const glm::vec3& x) - { - return geom::isclose(x, pos); - }; - return any(this->polygon, isCloseToPos); -} - -QString DrawTool::iconName() const -{ - return ":/icons/pencil-outline.png"; -} - -void DrawTool::addPoint(const glm::vec3 &pos) -{ - AbstractDrawTool::addPoint(pos); - if (this->polygon.size() == 4) - { - this->closeShape(); - } -} - -template -std::array vectorToArray(const std::vector& x) -{ - std::array result; - for (std::size_t i = 0; i < x.size() and i < N; i += 1) - { - result[i] = x[i]; - } - return result; -} - -void DrawTool::closeShape() -{ - if (this->polygon.size() >= 2 and this->polygon.size() <= 4) - { - std::unique_ptr modelEditor = this->document->editModel(); - switch (this->polygon.size()) - { - case 2: - modelEditor->append(vectorToArray<2>(this->polygon), ldraw::EDGE_COLOR); - break; - case 3: - modelEditor->append(vectorToArray<3>(this->polygon), ldraw::MAIN_COLOR); - break; - case 4: - modelEditor->append(vectorToArray<4>(this->polygon), ldraw::MAIN_COLOR); - break; - } - } - this->clearPoints(); -}