src/layers/edittools.cpp

Fri, 01 Jul 2022 16:46:43 +0300

author
Teemu Piippo <teemu.s.piippo@gmail.com>
date
Fri, 01 Jul 2022 16:46:43 +0300
changeset 312
2637134bc37c
parent 311
fab454611f9b
child 314
4642ba1218e8
permissions
-rw-r--r--

Fix right click to delete not really working properly
Instead of removing the point that had been added, it would remove
the point that is being drawn, which would cause it to overwrite the
previous point using the new point, causing a bit of a delay

24
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
1 /*
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
2 * LDForge: LDraw parts authoring CAD
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
3 * Copyright (C) 2013 - 2020 Teemu Piippo
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
4 *
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
5 * This program is free software: you can redistribute it and/or modify
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
6 * it under the terms of the GNU General Public License as published by
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
7 * the Free Software Foundation, either version 3 of the License, or
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
8 * (at your option) any later version.
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
9 *
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
10 * This program is distributed in the hope that it will be useful,
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
13 * GNU General Public License for more details.
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
14 *
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
15 * You should have received a copy of the GNU General Public License
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
17 */
1a0faaaceb84 added license
Teemu Piippo <teemu@hecknology.net>
parents: 21
diff changeset
18
47
cd6704009eb9 picking works now
Teemu Piippo <teemu@hecknology.net>
parents: 39
diff changeset
19 #include <QMouseEvent>
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
20 #include <QPainter>
301
8ccd6fdb30dc Move earcut.h outside src/ directory
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 264
diff changeset
21 #include "thirdparty/earcut.h"
264
76a025db4948 Convert all includes to be relative to project root directory. Files that cannot be found in this manner use angle brackets.
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 263
diff changeset
22 #include "src/model.h"
76a025db4948 Convert all includes to be relative to project root directory. Files that cannot be found in this manner use angle brackets.
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 263
diff changeset
23 #include "src/ui/objecteditor.h"
76a025db4948 Convert all includes to be relative to project root directory. Files that cannot be found in this manner use angle brackets.
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 263
diff changeset
24 #include "src/gl/partrenderer.h"
76a025db4948 Convert all includes to be relative to project root directory. Files that cannot be found in this manner use angle brackets.
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 263
diff changeset
25 #include "src/circularprimitive.h"
76a025db4948 Convert all includes to be relative to project root directory. Files that cannot be found in this manner use angle brackets.
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 263
diff changeset
26 #include "src/layers/edittools.h"
306
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
27 #include "src/invert.h"
125
f127982d3412 Move tools under Document instead of MainWindow
Teemu Piippo <teemu@hecknology.net>
parents: 124
diff changeset
28
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
29 // Make mapbox::earcut work with glm::vec3
244
065db0753f05 a bit of refactor in mapbox::util::nth
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 232
diff changeset
30 template<> struct mapbox::util::nth<0, glm::vec3>
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
31 {
250
2837b549e616 I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 245
diff changeset
32 static constexpr float get(const glm::vec3& t) { return t.x; }
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
33 };
244
065db0753f05 a bit of refactor in mapbox::util::nth
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 232
diff changeset
34
065db0753f05 a bit of refactor in mapbox::util::nth
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 232
diff changeset
35 template<> struct mapbox::util::nth<1, glm::vec3>
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
36 {
250
2837b549e616 I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 245
diff changeset
37 static constexpr float get(const glm::vec3& t) { return t.y; }
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
38 };
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
39
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
40 EditTools::EditTools(QObject* parent) :
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 205
diff changeset
41 QObject{parent},
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
42 RenderLayer{}
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
43 {
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
44 }
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
45
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 205
diff changeset
46 EditTools::~EditTools()
8
44679e468ba9 major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
47 {
9
8b9780700b5e added saving of splitter state and recent files
Teemu Piippo <teemu@hecknology.net>
parents: 8
diff changeset
48 }
36
bbb901b97404 added render style storage
Teemu Piippo <teemu@hecknology.net>
parents: 35
diff changeset
49
250
2837b549e616 I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 245
diff changeset
50 void EditTools::setEditMode(EditingMode newMode)
125
f127982d3412 Move tools under Document instead of MainWindow
Teemu Piippo <teemu@hecknology.net>
parents: 124
diff changeset
51 {
250
2837b549e616 I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 245
diff changeset
52 this->mode = newMode;
311
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
53 switch (this->mode) {
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
54 case SelectMode:
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
55 Q_EMIT this->suggestCursor(Qt::ArrowCursor);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
56 break;
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
57 case DrawMode:
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
58 case CircleMode:
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
59 Q_EMIT this->suggestCursor(Qt::CrossCursor);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
60 break;
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
61 }
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
62 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
63
250
2837b549e616 I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 245
diff changeset
64 void EditTools::setGridMatrix(const glm::mat4& newGridMatrix)
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
65 {
250
2837b549e616 I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 245
diff changeset
66 this->gridMatrix = newGridMatrix;
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
67 this->gridPlane = planeFromTriangle({
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
68 this->gridMatrix * glm::vec4{0, 0, 0, 1},
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
69 this->gridMatrix * glm::vec4{1, 0, 0, 1},
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
70 this->gridMatrix * glm::vec4{0, 1, 0, 1},
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
71 });
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
72 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
73
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
74 void EditTools::setCircleToolOptions(const CircleToolOptions& options)
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
75 {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
76 this->circleToolOptions = options;
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
77 }
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
78
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
79 void EditTools::mvpMatrixChanged(const glm::mat4& matrix)
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
80 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
81 this->mvpMatrix = matrix;
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
82 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
83
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
84 void EditTools::mouseMoved(const QMouseEvent* event)
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
85 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
86 this->worldPosition = this->renderer->screenToModelCoordinates(event->pos(), this->gridPlane);
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
87 if (this->worldPosition.has_value())
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
88 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
89 // Snap the position to grid. This procedure is basically the "change of basis" and almost follows the
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
90 // A⁻¹ × M × A formula which is used to perform a transformation in some other coordinate system, except
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
91 // we actually use the inverted matrix first and the regular one last to perform the transformation of
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
92 // grid coordinates in our XY coordinate system. Also, we're rounding the coordinates which is obviously
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
93 // not a linear transformation, but fits the pattern anyway.
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
94 // First transform the coordinates to the XY plane...
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
95 this->worldPosition = glm::inverse(this->gridMatrix) * glm::vec4{*this->worldPosition, 1};
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
96 // Then round the coordinates to integer precision...
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
97 this->worldPosition = glm::round(*this->worldPosition);
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
98 // And finally transform it back to grid coordinates by transforming it with the
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
99 // grid matrix.
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
100 this->worldPosition = this->gridMatrix * glm::vec4{*this->worldPosition, 1};
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
101 this->polygon.back() = *this->worldPosition;
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
102 }
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
103 this->numpoints = this->polygon.size();
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
104 if (this->isCloseToExistingPoints()) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
105 this->numpoints -= 1;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
106 }
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
107 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
108
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
109 static QVector<QPointF> convertWorldPointsToScreenPoints(
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
110 const std::vector<glm::vec3> &worldPoints,
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
111 const PartRenderer* renderer)
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
112 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
113 QVector<QPointF> points2d;
250
2837b549e616 I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 245
diff changeset
114 points2d.reserve(static_cast<int>(worldPoints.size()));
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
115 for (const glm::vec3& point : worldPoints)
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
116 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
117 points2d.push_back(renderer->modelToScreenCoordinates(point));
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
118 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
119 return points2d;
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
120 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
121
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
122 static Winding worldPolygonWinding(
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
123 const std::vector<glm::vec3> &points,
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
124 const PartRenderer* renderer)
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
125 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
126 return winding(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)});
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
127 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
128
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
129 static void drawWorldPoint(
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
130 QPainter* painter,
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
131 const glm::vec3& worldPoint,
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
132 const PartRenderer* renderer)
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
133 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
134 const QPointF center = renderer->modelToScreenCoordinates(worldPoint);
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
135 painter->drawEllipse(inscribe(CircleF{center, 5}));
125
f127982d3412 Move tools under Document instead of MainWindow
Teemu Piippo <teemu@hecknology.net>
parents: 124
diff changeset
136 }
f127982d3412 Move tools under Document instead of MainWindow
Teemu Piippo <teemu@hecknology.net>
parents: 124
diff changeset
137
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
138 static void drawWorldPolyline(
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
139 QPainter *painter,
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
140 const std::vector<glm::vec3> &points,
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
141 const PartRenderer* renderer)
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
142 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
143 painter->drawPolyline(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)});
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
144 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
145
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
146 static void drawWorldPolygon(
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
147 QPainter* painter,
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
148 const std::vector<glm::vec3> &points,
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
149 const PartRenderer* renderer)
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
150 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
151 painter->drawPolygon(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)});
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
152 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
153
305
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
154 //! \brief Conversion function from PlainPolygonElement to ModelElement
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
155 ModelElement elementFromPolygonAndColor(const PlainPolygonElement& poly, ColorIndex color)
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
156 {
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
157 // use std::visit with a templated lambda to resolve the type of poly.
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
158 return std::visit([color](const auto& resolvedPoly) -> ModelElement {
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
159 // unlike with normal templates we need to pry out the type out manually
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
160 using PolygonType = std::decay_t<decltype(resolvedPoly)>;
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
161 // add color and return as a model element.
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
162 return Colored<PolygonType>{resolvedPoly, color};
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
163 }, poly);
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
164 }
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
165
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
166 static std::vector<std::vector<glm::vec3>> polygonsToBeInserted(const ModelAction& action)
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
167 {
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
168 std::vector<std::vector<glm::vec3>> result;
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
169 if (const AppendToModel* append = std::get_if<AppendToModel>(&action)) {
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
170 const ModelElement& newElement = append->newElement;
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
171 if (const LineSegment* seg = std::get_if<Colored<LineSegment>>(&newElement)) {
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
172 result.push_back({seg->p1, seg->p2});
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
173 }
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
174 else if (const Triangle* tri = std::get_if<Colored<Triangle>>(&newElement)) {
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
175 result.push_back({tri->p1, tri->p2, tri->p3});
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
176 }
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
177 else if (const Quadrilateral* quad = std::get_if<Colored<Quadrilateral>>(&newElement)) {
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
178 result.push_back({quad->p1, quad->p2, quad->p3, quad->p4});
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
179 }
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
180 else if (const CircularPrimitive* circ = std::get_if<Colored<CircularPrimitive>>(&newElement)) {
305
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
181 // rasterize the circle down to polygons, and append them to the result.
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
182 rasterize(*circ, [&](const PlainPolygonElement& poly, const ColorIndex color){
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
183 AppendToModel append{elementFromPolygonAndColor(poly, color)};
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
184 const auto& subpoints = polygonsToBeInserted(append);
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
185 std::copy(subpoints.begin(), subpoints.end(), std::back_inserter(result));
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
186 });
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
187 }
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
188 }
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
189 return result;
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
190 }
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
191
228
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
192 namespace {
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
193 struct Pens
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
194 {
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
195 const QBrush pointBrush;
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
196 const QPen pointPen;
245
a41ccc6924e3 improve text rendering
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 244
diff changeset
197 const QPen textPen;
228
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
198 const QPen polygonPen;
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
199 const QPen badPolygonPen;
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
200 const QBrush greenPolygonBrush;
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
201 const QBrush redPolygonBrush;
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
202 };
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
203 }
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
204
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
205 static const Pens brightPens{
245
a41ccc6924e3 improve text rendering
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 244
diff changeset
206 .pointBrush = {Qt::black},
228
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
207 .pointPen = {QBrush{Qt::black}, 2.0},
245
a41ccc6924e3 improve text rendering
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 244
diff changeset
208 .textPen = {Qt::black},
228
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
209 .polygonPen = {QBrush{Qt::black}, 2.0, Qt::DashLine},
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
210 .greenPolygonBrush = {QColor{64, 255, 128, 192}},
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
211 .redPolygonBrush = {QColor{255, 96, 96, 192}},
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
212 };
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
213
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
214 static const Pens darkPens{
245
a41ccc6924e3 improve text rendering
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 244
diff changeset
215 .pointBrush = {Qt::white},
228
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
216 .pointPen = {QBrush{Qt::white}, 2.0},
245
a41ccc6924e3 improve text rendering
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 244
diff changeset
217 .textPen = {Qt::white},
228
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
218 .polygonPen = {QBrush{Qt::white}, 2.0, Qt::DashLine},
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
219 .greenPolygonBrush = {QColor{64, 255, 128, 192}},
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
220 .redPolygonBrush = {QColor{255, 96, 96, 192}},
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
221 };
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
222
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
223 void EditTools::overpaint(QPainter* painter)
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
224 {
245
a41ccc6924e3 improve text rendering
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 244
diff changeset
225 painter->save();
311
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
226 if (this->usePolygon()) {
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
227 const Pens& pens = (this->renderer->isDark() ? darkPens : brightPens);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
228 this->renderPreview(painter, &pens);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
229 QFont font;
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
230 font.setBold(true);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
231 if (this->usePolygon() and this->worldPosition.has_value())
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
232 {
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
233 painter->setRenderHint(QPainter::Antialiasing);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
234 painter->setPen(pens.pointPen);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
235 painter->setBrush(pens.greenPolygonBrush);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
236 const QPointF pos = this->renderer->modelToScreenCoordinates(*this->worldPosition);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
237 painter->drawEllipse(pos, 5, 5);
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
238 drawBorderedText(painter, pos + QPointF{5, 5}, font, vectorToString(*this->worldPosition));
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
239 }
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
240 }
245
a41ccc6924e3 improve text rendering
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 244
diff changeset
241 painter->restore();
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
242 }
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
243
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
244 const std::vector<ModelAction> EditTools::modelActions() const
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
245 {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
246 switch(this->mode) {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
247 case SelectMode:
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
248 return {};
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
249 case DrawMode:
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
250 return drawModeActions();
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
251 case CircleMode:
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
252 return circleModeActions();
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
253 }
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
254 }
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
255
228
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
256 void EditTools::renderPreview(QPainter* painter, const void* pensptr)
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
257 {
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
258 const Pens& pens = *reinterpret_cast<const Pens*>(pensptr);
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
259 painter->setPen(pens.polygonPen);
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
260 for (const ModelAction& action : this->modelActions()) {
305
d891da20abca Add support for BFC CERTIFY statements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 301
diff changeset
261 for (const std::vector<glm::vec3>& points : polygonsToBeInserted(action)) {
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
262 if (points.size() == 2) {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
263 drawWorldPolyline(painter, points, renderer);
228
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
264 }
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
265 else {
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
266 if (worldPolygonWinding(points, this->renderer) == Winding::Clockwise) {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
267 painter->setBrush(pens.greenPolygonBrush);
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
268 }
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
269 else {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
270 painter->setBrush(pens.redPolygonBrush);
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
271 }
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
272 drawWorldPolygon(painter, points, this->renderer);
228
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
273 }
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
274 }
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
275 }
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
276 painter->setBrush(pens.pointBrush);
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
277 painter->setPen(pens.pointPen);
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
278 for (const glm::vec3& point : this->polygon) {
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
279 drawWorldPoint(painter, point, this->renderer);
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
280 }
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
281 }
948867719906 refactor
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 227
diff changeset
282
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
283 void EditTools::removeLastPoint()
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
284 {
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
285 if (this->polygon.size() > 1) {
312
2637134bc37c Fix right click to delete not really working properly
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 311
diff changeset
286 this->polygon.erase(this->polygon.end() - 2);
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
287 }
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
288 }
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
289
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
290 bool EditTools::isCloseToExistingPoints() const
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
291 {
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
292 if (this->worldPosition.has_value()) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
293 const glm::vec3& pos = *this->worldPosition;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
294 return std::any_of(this->polygon.begin(), this->polygon.end() - 1, [&pos](const glm::vec3& p){
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
295 return isclose(pos, p);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
296 });
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
297 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
298 else {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
299 return false;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
300 }
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
301 }
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
302
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
303 EditingMode EditTools::currentEditingMode() const
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
304 {
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
305 return this->mode;
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
306 }
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
307
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
308 void EditTools::mouseClick(const QMouseEvent* event)
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
309 {
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
310 switch(this->mode) {
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
311 case SelectMode:
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
312 if (event->button() == Qt::LeftButton) {
309
d862721d19a3 Fixed ModelId being used to identify both models and elements, added ElementId to identify elements
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 307
diff changeset
313 const ElementId highlighted = this->renderer->pick(event->pos());
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
314 Q_EMIT this->select({highlighted}, false);
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
315 }
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
316 break;
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
317 case DrawMode:
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
318 if (event->button() == Qt::LeftButton and this->worldPosition.has_value()) {
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
319 if (isCloseToExistingPoints()) {
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
320 this->closeShape();
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
321 }
214
8e1fe64ce4e3 begin refactor of gl side
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 205
diff changeset
322 else {
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
323 this->polygon.push_back(*this->worldPosition);
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
324 }
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
325 }
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
326 break;
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
327 case CircleMode:
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
328 if (event->button() == Qt::LeftButton and this->worldPosition.has_value()) {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
329 if (this->polygon.size() == 2) {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
330 this->closeShape();
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
331 }
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
332 else {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
333 this->polygon.push_back(*this->worldPosition);
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
334 }
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
335 }
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
336 break;
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
337 }
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
338 if (event->button() == Qt::RightButton and this->polygon.size() > 1) {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
339 this->removeLastPoint();
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
340 }
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
341 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
342
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
343 struct MergedTriangles
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
344 {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
345 std::vector<Quadrilateral> quadrilaterals;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
346 std::set<std::size_t> cutTriangles;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
347 };
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
348
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
349 static MergedTriangles mergeTriangles(
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
350 const std::vector<std::uint16_t>& indices,
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
351 const std::vector<glm::vec3>& polygon)
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
352 {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
353 MergedTriangles result;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
354 using indextype = std::uint16_t;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
355 using indexpair = std::pair<indextype, indextype>;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
356 struct boundaryinfo { indextype third; std::size_t triangleid; };
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
357 std::map<indexpair, boundaryinfo> boundaries;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
358 for (std::size_t i = 0; i < indices.size(); i += 3) {
250
2837b549e616 I felt that the compiler was too kind to me, so I enabled a big pile of warnings
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 245
diff changeset
359 const auto add = [&](const std::size_t o1, const std::size_t o2, const std::size_t o3){
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
360 const auto key = std::make_pair(indices[i + o1], indices[i + o2]);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
361 boundaries[key] = {indices[i + o3], i};
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
362 };
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
363 add(0, 1, 2);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
364 add(1, 2, 0);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
365 add(2, 0, 1);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
366 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
367 std::vector<std::array<indextype, 4>> quadindices;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
368 std::vector<Quadrilateral> quads;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
369 bool repeat = true;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
370 const auto iscut = [&result](const std::size_t i){
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
371 return result.cutTriangles.find(i) != result.cutTriangles.end();
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
372 };
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
373 while (repeat) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
374 repeat = false;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
375 // Go through triangle boundaries
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
376 for (const auto& it1 : boundaries) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
377 const indexpair& pair1 = it1.first;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
378 const boundaryinfo& boundary1 = it1.second;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
379 // .. the ones we haven't already merged anyway
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
380 if (not iscut(boundary1.triangleid)) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
381 // Look for its inverse boundary to find the touching triangle
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
382 const auto pair2 = std::make_pair(pair1.second, pair1.first);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
383 const auto it2 = boundaries.find(pair2);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
384 // Also if that hasn't been cut
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
385 if (it2 != boundaries.end() and not iscut(it2->second.triangleid)) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
386 const Quadrilateral quad{
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
387 polygon[pair1.first],
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
388 polygon[it2->second.third],
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
389 polygon[pair1.second],
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
390 polygon[boundary1.third],
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
391 };
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
392 if (isConvex(quad)) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
393 result.quadrilaterals.push_back(quad);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
394 result.cutTriangles.insert(boundary1.triangleid);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
395 result.cutTriangles.insert(it2->second.triangleid);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
396 repeat = true;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
397 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
398 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
399 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
400 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
401 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
402 return result;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
403 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
404
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
405
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
406 const std::vector<ModelAction> EditTools::circleModeActions() const
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
407 {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
408 std::vector<ModelAction> result;
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
409 if (this->numpoints == 2) {
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
410 const glm::vec3 x = polygon[1] - polygon[0];
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
411 glm::mat4 transform{
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
412 glm::vec4{x, 0},
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
413 this->gridMatrix[2],
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
414 glm::vec4{glm::cross(glm::vec3{-this->gridMatrix[2]}, x), 0},
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
415 glm::vec4{this->polygon[0], 1},
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
416 };
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
417 Colored<CircularPrimitive> circ{
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
418 CircularPrimitive{
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
419 .type = this->circleToolOptions.type,
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
420 .fraction = this->circleToolOptions.fraction,
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
421 .transformation = transform,
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
422 },
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
423 MAIN_COLOR
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
424 };
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
425 result.push_back(AppendToModel{.newElement = circ});
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
426 }
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
427 return result;
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
428 }
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
429
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
430 const std::vector<ModelAction> EditTools::drawModeActions() const
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
431 {
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
432 std::vector<ModelAction> result;
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
433 if (this->numpoints == 2) {
310
5d6639a9607f Simplify some code
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 309
diff changeset
434 result.push_back(AppendToModel{edge(this->polygon[0], this->polygon[1])});
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
435 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
436 else if (this->numpoints > 2) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
437 const glm::mat4 inverseGrid = glm::inverse(this->gridMatrix);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
438 std::vector<std::vector<glm::vec3>> polygons{1};
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
439 std::vector<glm::vec3>& polygon2d = polygons.back();
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
440 polygon2d.reserve(this->numpoints);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
441 for (std::size_t i = 0; i < this->numpoints; ++i) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
442 polygon2d.push_back(inverseGrid * glm::vec4{this->polygon[i], 1});
306
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
443 }
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
444 // mapbox::earcut will always produce a CCW polygon, so if we're drawing
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
445 // a CW polygon, we should invert the result afterwards
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
446 const float shouldInvert = glm::dot(
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
447 glm::vec3{inverseGrid[2]},
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
448 glm::cross(this->polygon[0] - this->polygon[1], this->polygon[2] - this->polygon[1]));
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
449 using indextype = std::uint16_t;
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
450 const std::vector<indextype> indices = mapbox::earcut<std::uint16_t>(polygons);
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
451 MergedTriangles mergedTriangles = mergeTriangles(indices, this->polygon);
306
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
452 for (Quadrilateral& quad : mergedTriangles.quadrilaterals) {
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
453 if (shouldInvert < 0) {
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
454 invert(quad);
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
455 }
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
456 result.push_back(AppendToModel{
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
457 .newElement = Colored<Quadrilateral>{quad, MAIN_COLOR},
204
52e10e8d88cc Concentrate model editing into one coroutine inside main()
Teemu Piippo <teemu@hecknology.net>
parents: 203
diff changeset
458 });
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
459 }
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
460 for (std::size_t i = 0; i < indices.size(); i += 3) {
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
461 if (mergedTriangles.cutTriangles.find(i) == mergedTriangles.cutTriangles.end()) {
307
4771720fe258 simplify a bit
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 306
diff changeset
462 Colored<Triangle> tri = triangle(
4771720fe258 simplify a bit
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 306
diff changeset
463 this->polygon[indices[i]],
4771720fe258 simplify a bit
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 306
diff changeset
464 this->polygon[indices[i + 1]],
4771720fe258 simplify a bit
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 306
diff changeset
465 this->polygon[indices[i + 2]]);
306
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
466 if (shouldInvert < 0) {
307
4771720fe258 simplify a bit
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 306
diff changeset
467 invert(tri);
306
6ad27b7d2697 Enable drawing clockwise shapes despite mapbox::earcut rewinding them
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 305
diff changeset
468 }
307
4771720fe258 simplify a bit
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 306
diff changeset
469 result.push_back(AppendToModel{tri});
223
ce81db996275 Use Mapbox's ear clipping algorithm to handle drawing any simple polygon
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 222
diff changeset
470 }
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
471 }
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
472 }
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
473 return result;
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
474 }
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
475
311
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
476 bool EditTools::usePolygon() const
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
477 {
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
478 switch (this->mode) {
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
479 case SelectMode:
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
480 return false;
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
481 case DrawMode:
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
482 case CircleMode:
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
483 return true;
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
484 }
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
485 return {};
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
486 }
fab454611f9b Use different cursors depending on edit mode
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 310
diff changeset
487
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
488 void EditTools::closeShape()
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
489 {
232
8efa3a33172e Add base code for circular primitives
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 228
diff changeset
490 for (const ModelAction& action : this->modelActions()) {
222
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
491 Q_EMIT this->modelAction(action);
72b456f2f3c2 Edit tools: get rid of the preview polygon and render the result-to-be
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 217
diff changeset
492 }
217
6d95c1a41e6e reimplement EditTools as a render layer
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 214
diff changeset
493 this->polygon.clear();
225
551c136b459e Fix crash involving polygon being too empty
Teemu Piippo <teemu.s.piippo@gmail.com>
parents: 223
diff changeset
494 this->polygon.push_back(this->worldPosition.value_or(glm::vec3{0, 0, 0}));
197
0e729e681a2c move drawState to Document
Teemu Piippo <teemu@hecknology.net>
parents: 191
diff changeset
495 }

mercurial