Tue, 24 May 2022 16:11:10 +0300
more work on circle tool + cleanup
103 | 1 | #include <QMessageBox> |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
2 | #include <document.h> |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
3 | #include "linetypes/edge.h" |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
4 | #include "linetypes/triangle.h" |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
5 | #include "linetypes/quadrilateral.h" |
96 | 6 | #include "drawtool.h" |
153
2f79053c2e9a
Renamed modeleditcontext.cpp -> modeleditor.cpp
Teemu Piippo <teemu@hecknology.net>
parents:
152
diff
changeset
|
7 | #include "modeleditor.h" |
96 | 8 | |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
9 | static const QBrush pointBrush = {Qt::white}; |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
10 | static const QPen polygonPen = {QBrush{Qt::black}, 2.0, Qt::DashLine}; |
168
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
11 | static const QPen badPolygonPen = {QBrush{Qt::red}, 2.0, Qt::DashLine}; |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
12 | static const QPen pointPen = {QBrush{Qt::black}, 2.0}; |
168
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
13 | static const QBrush greenPolygonBrush = {QColor{64, 255, 128, 192}}; |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
14 | static const QBrush redPolygonBrush = {QColor{255, 96, 96, 192}}; |
108 | 15 | |
185 | 16 | AbstractDrawTool::AbstractDrawTool(Document *document) : |
17 | BaseTool{document} | |
18 | { | |
19 | } | |
20 | ||
152 | 21 | DrawTool::DrawTool(Document* document) : |
185 | 22 | AbstractDrawTool{document} |
152 | 23 | { |
24 | } | |
96 | 25 | |
26 | QString DrawTool::name() const | |
27 | { | |
28 | static const QString result = tr("Draw"); | |
29 | return result; | |
30 | } | |
31 | ||
32 | QString DrawTool::toolTip() const | |
33 | { | |
34 | static const QString result = tr("Draw new elements into the model."); | |
35 | return result; | |
36 | } | |
103 | 37 | |
185 | 38 | bool AbstractDrawTool::mouseClick(Canvas* canvas, QMouseEvent* event) |
103 | 39 | { |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
40 | if (event->button() == Qt::LeftButton) |
106 | 41 | { |
185 | 42 | this->addCurrentPoint(canvas); |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
43 | return true; |
106 | 44 | } |
185 | 45 | else if (event->button() == Qt::RightButton) |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
46 | { |
185 | 47 | this->removeLastPoint(); |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
48 | return true; |
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
49 | } |
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
50 | else |
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
51 | { |
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
52 | return false; |
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
53 | } |
103 | 54 | } |
106 | 55 | |
185 | 56 | bool AbstractDrawTool::mouseMove(Document* document, Canvas* canvas, QMouseEvent *event) |
108 | 57 | { |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
58 | static_cast<void>(document); |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
59 | static_cast<void>(event); |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
60 | const auto& worldPosition = canvas->getWorldPosition(); |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
61 | if (worldPosition.has_value()) |
108 | 62 | { |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
63 | this->previewPoint = worldPosition.value(); |
185 | 64 | this->updatePreviewPolygon(); |
108 | 65 | } |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
66 | return false; |
108 | 67 | } |
68 | ||
185 | 69 | bool AbstractDrawTool::keyReleased(Document*, Canvas* canvas, QKeyEvent* event) |
124
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
70 | { |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
71 | if (event->key() == Qt::Key_Escape) |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
72 | { |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
73 | this->polygon.clear(); |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
74 | this->updatePreviewPolygon(); |
125
f127982d3412
Move tools under Document instead of MainWindow
Teemu Piippo <teemu@hecknology.net>
parents:
124
diff
changeset
|
75 | canvas->update(); |
124
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
76 | return true; |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
77 | } |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
78 | else |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
79 | { |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
80 | return false; |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
81 | } |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
82 | } |
f9f308c8e0c5
esc with draw mode now clears the polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
83 | |
185 | 84 | void AbstractDrawTool::addCurrentPoint(Canvas* canvas) |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
85 | { |
185 | 86 | const auto& worldPosition = canvas->getWorldPosition(); |
87 | if (worldPosition.has_value()) | |
88 | { | |
89 | const glm::vec3& pos = worldPosition.value(); | |
90 | if (this->isCloseToExistingPoints(pos)) | |
91 | { | |
92 | this->closeShape(); | |
93 | } | |
94 | else | |
95 | { | |
96 | this->addPoint(pos); | |
97 | } | |
98 | } | |
99 | } | |
100 | ||
101 | void AbstractDrawTool::updatePreviewPolygon() | |
102 | { | |
103 | this->previewPolygon = this->polygon; | |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
104 | this->previewPolygon.resize(this->polygon.size() + 1); |
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
105 | this->previewPolygon.back() = this->previewPoint; |
122
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
106 | if (this->previewPolygon.size() > 2) |
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
107 | { |
123 | 108 | this->isconcave = not geom::isConvex(this->previewPolygon); |
122
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
121
diff
changeset
|
109 | } |
121
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
110 | } |
000781318c36
added right click support for draw tool
Teemu Piippo <teemu@hecknology.net>
parents:
111
diff
changeset
|
111 | |
185 | 112 | void AbstractDrawTool::reset() |
106 | 113 | { |
114 | this->polygon.clear(); | |
115 | } | |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
116 | |
185 | 117 | void AbstractDrawTool::overpaint(Canvas* canvas, QPainter* painter) const |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
118 | { |
168
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
119 | painter->setPen(this->isconcave ? ::badPolygonPen : ::polygonPen); |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
120 | if (this->previewPolygon.size() > 2 and not this->isconcave) |
164
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
163
diff
changeset
|
121 | { |
168
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
122 | if (canvas->worldPolygonWinding(this->previewPolygon) == Winding::Clockwise) |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
123 | { |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
124 | painter->setBrush(::greenPolygonBrush); |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
125 | } |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
126 | else |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
127 | { |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
128 | painter->setBrush(::redPolygonBrush); |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
164
diff
changeset
|
129 | } |
164
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
163
diff
changeset
|
130 | canvas->drawWorldPolygon(painter, this->previewPolygon); |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
163
diff
changeset
|
131 | } |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
163
diff
changeset
|
132 | else |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
163
diff
changeset
|
133 | { |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
163
diff
changeset
|
134 | canvas->drawWorldPolyline(painter, this->previewPolygon); |
8305e2f968fb
Render draw tool preview as a line when we only have 2 points
Teemu Piippo <teemu@hecknology.net>
parents:
163
diff
changeset
|
135 | } |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
136 | painter->setBrush(::pointBrush); |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
137 | painter->setPen(::pointPen); |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
138 | for (const glm::vec3& point : this->polygon) |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
139 | { |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
140 | canvas->drawWorldPoint(painter, point); |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
141 | } |
185 | 142 | canvas->drawWorldPoint(painter, this->previewPoint); |
143 | } | |
144 | ||
145 | void AbstractDrawTool::addPoint(const glm::vec3 &pos) | |
146 | { | |
147 | this->polygon.push_back(pos); | |
148 | this->updatePreviewPolygon(); | |
149 | } | |
150 | ||
151 | void AbstractDrawTool::removeLastPoint() | |
152 | { | |
153 | if (this->polygon.size() > 0) | |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
154 | { |
185 | 155 | this->polygon.erase(this->polygon.end() - 1); |
156 | this->updatePreviewPolygon(); | |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
157 | } |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
158 | } |
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
159 | |
185 | 160 | void AbstractDrawTool::clearPoints() |
161 | { | |
162 | this->polygon.clear(); | |
163 | this->updatePreviewPolygon(); | |
164 | } | |
165 | ||
166 | bool AbstractDrawTool::isCloseToExistingPoints(const glm::vec3 &pos) const | |
167 | { | |
168 | const auto isCloseToPos = [&](const glm::vec3& x) | |
169 | { | |
170 | return geom::isclose(x, pos); | |
171 | }; | |
172 | return any(this->polygon, isCloseToPos); | |
173 | } | |
174 | ||
163 | 175 | QString DrawTool::iconName() const |
176 | { | |
177 | return ":/icons/pencil-outline.png"; | |
178 | } | |
179 | ||
185 | 180 | void DrawTool::addPoint(const glm::vec3 &pos) |
181 | { | |
182 | AbstractDrawTool::addPoint(pos); | |
183 | if (this->polygon.size() == 4) | |
184 | { | |
185 | this->closeShape(); | |
186 | } | |
187 | } | |
188 | ||
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
189 | template<std::size_t N, typename T> |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
190 | std::array<T, N> vectorToArray(const std::vector<T>& x) |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
191 | { |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
192 | std::array<T, N> result; |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
193 | for (std::size_t i = 0; i < x.size() and i < N; i += 1) |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
194 | { |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
195 | result[i] = x[i]; |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
196 | } |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
197 | return result; |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
198 | } |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
199 | |
185 | 200 | void DrawTool::closeShape() |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
201 | { |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
202 | if (this->polygon.size() >= 2 and this->polygon.size() <= 4) |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
203 | { |
185 | 204 | std::unique_ptr<ModelEditor> modelEditor = this->document->editModel(); |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
205 | switch (this->polygon.size()) |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
206 | { |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
207 | case 2: |
152 | 208 | modelEditor->append<ldraw::Edge>(vectorToArray<2>(this->polygon), ldraw::EDGE_COLOR); |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
209 | break; |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
210 | case 3: |
152 | 211 | modelEditor->append<ldraw::Triangle>(vectorToArray<3>(this->polygon), ldraw::MAIN_COLOR); |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
212 | break; |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
213 | case 4: |
152 | 214 | modelEditor->append<ldraw::Quadrilateral>(vectorToArray<4>(this->polygon), ldraw::MAIN_COLOR); |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
215 | break; |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
216 | } |
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
109
diff
changeset
|
217 | } |
185 | 218 | this->clearPoints(); |
109
40a1cf2f38f5
replaced preview layers in favor of overpainting callback
Teemu Piippo <teemu@hecknology.net>
parents:
108
diff
changeset
|
219 | } |