Fri, 01 Jul 2022 16:46:43 +0300
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 | 1 | /* |
2 | * LDForge: LDraw parts authoring CAD | |
3 | * Copyright (C) 2013 - 2020 Teemu Piippo | |
4 | * | |
5 | * This program is free software: you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation, either version 3 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
47 | 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 | 192 | namespace { |
193 | struct Pens | |
194 | { | |
195 | const QBrush pointBrush; | |
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 | 198 | const QPen polygonPen; |
199 | const QPen badPolygonPen; | |
200 | const QBrush greenPolygonBrush; | |
201 | const QBrush redPolygonBrush; | |
202 | }; | |
203 | } | |
204 | ||
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 | 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 | 209 | .polygonPen = {QBrush{Qt::black}, 2.0, Qt::DashLine}, |
210 | .greenPolygonBrush = {QColor{64, 255, 128, 192}}, | |
211 | .redPolygonBrush = {QColor{255, 96, 96, 192}}, | |
212 | }; | |
213 | ||
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 | 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 | 218 | .polygonPen = {QBrush{Qt::white}, 2.0, Qt::DashLine}, |
219 | .greenPolygonBrush = {QColor{64, 255, 128, 192}}, | |
220 | .redPolygonBrush = {QColor{255, 96, 96, 192}}, | |
221 | }; | |
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 | 256 | void EditTools::renderPreview(QPainter* painter, const void* pensptr) |
257 | { | |
258 | const Pens& pens = *reinterpret_cast<const Pens*>(pensptr); | |
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 | 264 | } |
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 | 273 | } |
274 | } | |
275 | } | |
276 | painter->setBrush(pens.pointBrush); | |
277 | painter->setPen(pens.pointPen); | |
278 | for (const glm::vec3& point : this->polygon) { | |
279 | drawWorldPoint(painter, point, this->renderer); | |
280 | } | |
281 | } | |
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 | 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 | 462 | Colored<Triangle> tri = triangle( |
463 | this->polygon[indices[i]], | |
464 | this->polygon[indices[i + 1]], | |
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 | 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 | 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 | } |