Wed, 08 Jun 2022 19:33:00 +0300
Concentrate model editing into one coroutine inside main()
3 | 1 | /* |
2 | * LDForge: LDraw parts authoring CAD | |
24 | 3 | * Copyright (C) 2013 - 2020 Teemu Piippo |
3 | 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 | ||
19 | #pragma once | |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
20 | #include <algorithm> |
3 | 21 | #include <cstdio> |
22 | #include <cstdlib> | |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
23 | #include <cstring> |
3 | 24 | #include <cmath> |
53 | 25 | #include <optional> |
96 | 26 | #include <type_traits> |
3 | 27 | #include <QMatrix4x4> |
28 | #include <QObject> | |
29 | #include <QPointF> | |
30 | #include <QSet> | |
31 | #include <QString> | |
32 | #include <QStringList> | |
33 | #include <QVariant> | |
34 | #include <QVector> | |
35 | #include <QVector3D> | |
33
4c41bfe2ec6e
replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
36 | #include <glm/glm.hpp> |
3 | 37 | |
38 | using GLRotationMatrix = QMatrix4x4; | |
39 | ||
40 | enum Axis | |
41 | { | |
21 | 42 | X = 0, |
43 | Y = 1, | |
44 | Z = 2 | |
3 | 45 | }; |
46 | ||
26 | 47 | enum Result |
48 | { | |
49 | Success = 0, | |
50 | PartialSuccess, | |
51 | Failure | |
52 | }; | |
53 | ||
54 | constexpr bool failed(Result r) | |
55 | { | |
56 | return r == Failure; | |
57 | } | |
58 | ||
3 | 59 | enum Winding |
60 | { | |
61 | NoWinding, | |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
7
diff
changeset
|
62 | Anticlockwise, |
3 | 63 | Clockwise, |
64 | }; | |
65 | ||
66 | /* | |
67 | * Special operator definition that implements the XOR operator for windings. | |
68 | * However, if either winding is NoWinding, then this function returns NoWinding. | |
69 | */ | |
70 | inline Winding operator^(Winding one, Winding other) | |
71 | { | |
72 | if (one == NoWinding or other == NoWinding) | |
73 | return NoWinding; | |
74 | else | |
75 | return static_cast<Winding>(static_cast<int>(one) ^ static_cast<int>(other)); | |
76 | } | |
77 | ||
78 | inline Winding& operator^=(Winding& one, Winding other) | |
79 | { | |
80 | one = one ^ other; | |
81 | return one; | |
82 | } | |
21 | 83 | |
84 | template<typename T, int N> | |
90
e234edb5e613
remove dependency on glut, fixes
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
85 | constexpr int countof(T const (&)[N]) |
21 | 86 | { |
87 | return N; | |
88 | } | |
33
4c41bfe2ec6e
replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
89 | |
51 | 90 | /** |
91 | * @brief casts @c x to a suitable unsigned integer | |
92 | */ | |
93 | template<typename T> | |
94 | constexpr auto unsigned_cast(T x) | |
95 | -> std::enable_if_t<std::is_integral_v<T>, std::make_unsigned_t<T>> | |
96 | { | |
97 | return static_cast<std::make_unsigned_t<T>>(x); | |
98 | } | |
99 | ||
100 | /** | |
101 | * @brief casts @c x to a suitable signed integer | |
102 | */ | |
103 | template<typename T> | |
104 | constexpr auto signed_cast(T x) | |
105 | -> std::enable_if_t<std::is_integral_v<T>, std::make_signed_t<T>> | |
106 | { | |
107 | return static_cast<std::make_signed_t<T>>(x); | |
108 | } | |
109 | ||
53 | 110 | |
111 | /** | |
55 | 112 | * @brief casts floating point values to float, converting non-floating point values causes an error |
113 | * @param[in] x floating point value to cast | |
53 | 114 | * @returns float |
115 | */ | |
116 | template<typename T> | |
55 | 117 | auto toFloat(T x) -> std::enable_if_t<std::is_floating_point_v<T>, float> |
53 | 118 | { |
119 | return static_cast<float>(x); | |
120 | } | |
121 | ||
122 | /** | |
55 | 123 | * @brief casts floating point values to double, converting non-floating point values causes an error |
124 | * @param[in] x floating point value to cast | |
53 | 125 | * @returns double |
126 | */ | |
127 | template<typename T> | |
55 | 128 | auto toDouble(T x) -> std::enable_if_t<std::is_floating_point_v<T>, double> |
53 | 129 | { |
130 | return static_cast<double>(x); | |
131 | } | |
55 | 132 | |
81
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
133 | /** |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
134 | * @brief casts floating point values to qreal, converting non-floating point values causes an error |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
135 | * @param[in] x floating point value to cast |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
136 | * @returns qreal |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
137 | */ |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
138 | template<typename T> |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
139 | auto toQreal(T x) -> std::enable_if_t<std::is_floating_point_v<T>, qreal> |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
140 | { |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
141 | return static_cast<qreal>(x); |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
142 | } |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
70
diff
changeset
|
143 | |
55 | 144 | template<int N, typename T, glm::qualifier Q> |
145 | inline QPoint toQPoint(const glm::vec<N, T, Q>& vec) | |
146 | { | |
147 | return {static_cast<int>(vec.x), static_cast<int>(vec.y)}; | |
148 | } | |
149 | ||
150 | template<int N, typename T, glm::qualifier Q> | |
151 | inline QPointF toQPointF(const glm::vec<N, T, Q>& vec) | |
152 | { | |
153 | return {toDouble(vec.x), toDouble(vec.y)}; | |
154 | } | |
155 | ||
156 | inline glm::vec2 toVec2(const QPoint& point) | |
157 | { | |
158 | return {point.x(), point.y()}; | |
159 | } | |
160 | ||
161 | inline glm::vec2 toVec2(const QPointF& point) | |
162 | { | |
163 | return {point.x(), point.y()}; | |
164 | } | |
165 | ||
96 | 166 | /* |
167 | * coalesce(arg1, arg2, ..., argn) | |
168 | * Returns the first of the given arguments that evaluates to true. | |
169 | */ | |
170 | template<typename T> | |
171 | T coalesce(T&& arg) | |
172 | { | |
173 | // recursion base: 1 argument | |
174 | return arg; | |
175 | } | |
176 | ||
177 | template<typename T, typename... Rest> | |
178 | std::common_type_t<T, Rest...> coalesce(T&& arg, Rest&&... rest) | |
179 | { | |
180 | // general case: n arguments | |
181 | return arg ? arg : coalesce(rest...); | |
182 | } | |
183 | ||
148 | 184 | /** |
185 | * @brief Finds an element in a map and possibly returns a reference to it if find | |
186 | * @param map | |
187 | * @param key | |
188 | * @returns the value or nullptr if not found | |
189 | */ | |
190 | template<typename T, typename R, typename K> | |
191 | const R* findInMap(const std::map<T, R>& map, K&& key) | |
192 | { | |
193 | auto pair = map.find(key); | |
194 | if (pair != map.end()) | |
195 | { | |
196 | return &pair->second; | |
197 | } | |
198 | else | |
199 | { | |
200 | return nullptr; | |
201 | } | |
202 | } | |
203 | ||
204 | /** | |
205 | * @brief Finds an element in a map and possibly returns a reference to it if find | |
206 | * @param map | |
207 | * @param key | |
208 | * @returns the value or no value if not found | |
209 | */ | |
210 | template<typename T, typename R, typename K> | |
211 | R* findInMap(std::map<T, R>& map, K&& key) | |
212 | { | |
213 | auto pair = map.find(key); | |
214 | if (pair != map.end()) | |
215 | { | |
216 | return &pair->second; | |
217 | } | |
218 | else | |
219 | { | |
220 | return nullptr; | |
221 | } | |
222 | } | |
223 | ||
191
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
224 | template<typename T = float> |
d355d4c52d51
made editing tools not a polymorphic class tree
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
225 | constexpr std::enable_if_t<std::is_floating_point_v<T>, T> pi = static_cast<T>(M_PIl); |
196 | 226 | constexpr double infinity = std::numeric_limits<double>::infinity(); |
227 | ||
70 | 228 | |
33
4c41bfe2ec6e
replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
229 | Q_DECLARE_METATYPE(glm::vec3) |
4c41bfe2ec6e
replaced matrix and vertex classes with glm
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
230 | Q_DECLARE_METATYPE(glm::mat4) |