1 /* |
|
2 * LDForge: LDraw parts authoring CAD |
|
3 * Copyright (C) 2013, 2014 Santeri 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 |
|
19 #pragma once |
|
20 #include <QString> |
|
21 #include <QObject> |
|
22 #include <QStringList> |
|
23 #include <QMetaType> |
|
24 #include "Macros.h" |
|
25 |
|
26 class LDObject; |
|
27 class QFile; |
|
28 class QTextStream; |
|
29 |
|
30 using int8 = qint8; |
|
31 using int16 = qint16; |
|
32 using int32 = qint32; |
|
33 using int64 = qint64; |
|
34 using uint8 = quint8; |
|
35 using uint16 = quint16; |
|
36 using uint32 = quint32; |
|
37 using uint64 = quint64; |
|
38 |
|
39 template<typename T, typename R> |
|
40 using Pair = std::pair<T, R>; |
|
41 |
|
42 enum Axis |
|
43 { |
|
44 X, |
|
45 Y, |
|
46 Z |
|
47 }; |
|
48 |
|
49 // ============================================================================= |
|
50 // |
|
51 class LDObject; |
|
52 using LDObjectList = QList<LDObject*>; |
|
53 |
|
54 //! |
|
55 //! \brief A mathematical 3 x 3 matrix |
|
56 //! |
|
57 class Matrix |
|
58 { |
|
59 public: |
|
60 //! Constructs a matrix with undetermined values. |
|
61 Matrix() {} |
|
62 |
|
63 //! Constructs a matrix with the given values. |
|
64 //! \note \c vals is expected to have exactly 9 elements. |
|
65 Matrix (const std::initializer_list<double>& vals); |
|
66 |
|
67 //! Constructs a matrix all 9 elements initialized to the same value. |
|
68 //! \param fillval the value to initialize the matrix coordinates as |
|
69 Matrix (double fillval); |
|
70 |
|
71 //! Constructs a matrix with a C-array. |
|
72 //! \note \c vals is expected to have exactly 9 elements. |
|
73 Matrix (double vals[]); |
|
74 |
|
75 //! Calculates the matrix's determinant. |
|
76 //! \returns the calculated determinant. |
|
77 double getDeterminant() const; |
|
78 |
|
79 //! Multiplies this matrix with \c other |
|
80 //! \param other the matrix to multiply with. |
|
81 //! \returns the resulting matrix |
|
82 //! \note a.mult(b) is not equivalent to b.mult(a)! |
|
83 Matrix mult (const Matrix& other) const; |
|
84 |
|
85 //! Prints the matrix to stdout. |
|
86 void dump() const; |
|
87 |
|
88 //! \returns a string representation of the matrix. |
|
89 QString toString() const; |
|
90 |
|
91 //! Zeroes the matrix out. |
|
92 void zero(); |
|
93 |
|
94 //! Assigns the matrix values to the values of \c other. |
|
95 //! \param other the matrix to assign this to. |
|
96 //! \returns a reference to self |
|
97 Matrix& operator= (const Matrix& other); |
|
98 |
|
99 //! \returns a mutable reference to a value by \c idx |
|
100 inline double& value (int idx) |
|
101 { |
|
102 return m_vals[idx]; |
|
103 } |
|
104 |
|
105 //! An overload of \c value() for const matrices. |
|
106 //! \returns a const reference to a value by \c idx |
|
107 inline const double& value (int idx) const |
|
108 { |
|
109 return m_vals[idx]; |
|
110 } |
|
111 |
|
112 //! An operator overload for \c mult(). |
|
113 //! \returns the multiplied matrix. |
|
114 inline Matrix operator* (const Matrix& other) const |
|
115 { |
|
116 return mult (other); |
|
117 } |
|
118 |
|
119 //! An operator overload for \c value(). |
|
120 //! \returns a mutable reference to a value by \c idx |
|
121 inline double& operator[] (int idx) |
|
122 { |
|
123 return value (idx); |
|
124 } |
|
125 |
|
126 //! An operator overload for \c value() const. |
|
127 //! \returns a const reference to a value by \c idx |
|
128 inline const double& operator[] (int idx) const |
|
129 { |
|
130 return value (idx); |
|
131 } |
|
132 |
|
133 //! \param other the matrix to check against |
|
134 //! \returns whether the two matrices have the same values. |
|
135 bool operator== (const Matrix& other) const; |
|
136 |
|
137 private: |
|
138 double m_vals[9]; |
|
139 }; |
|
140 |
|
141 //! |
|
142 //! \brief A vertex in 3D space |
|
143 //! |
|
144 //! Contains a single point in 3D space. Not to be confused with |
|
145 //! LDVertex, which is a vertex used in an LDraw part file. |
|
146 //! |
|
147 //! This also sees use as a position vector. |
|
148 //! |
|
149 class Vertex |
|
150 { |
|
151 public: |
|
152 //! Constructs a zero vertex |
|
153 Vertex() : |
|
154 m_coords{0, 0, 0} {} |
|
155 |
|
156 //! Constructs a vertex with the given \c x, \c y and \c z. |
|
157 Vertex (double x, double y, double z); |
|
158 |
|
159 //! \returns the distance from this vertex to \c other |
|
160 double distanceTo (const Vertex& other) const; |
|
161 |
|
162 //! \returns the vertex at the midpoint between this and \c other |
|
163 Vertex midpoint (const Vertex& other); |
|
164 |
|
165 //! Moves this vertex using \param other as a position vector. |
|
166 void move (const Vertex& other); |
|
167 |
|
168 //! Yields a string representation of the vertex. The string returned |
|
169 //! can possibly be mangled. |
|
170 //! - As mangled: {1.5, 2.8, 3.14} |
|
171 //! - Without mangling: 1.5 2.8 3.14 |
|
172 //! |
|
173 //! The mangled version is suitable for printing to the user, the |
|
174 //! non-mangled one is used when writing the vertex to LDraw files. |
|
175 //! |
|
176 //! \returns a string representation of this vertex |
|
177 //! \param mangled whether to return a mangled representation or not |
|
178 QString toString (bool mangled) const; |
|
179 |
|
180 //! Transforms this vertex with \c matr as transformation matrix |
|
181 //! and \c pos as the position column of the 4x4 matrix. |
|
182 void transform (const Matrix& matr, const Vertex& pos); |
|
183 |
|
184 //! An operator overload for \c move(). |
|
185 Vertex& operator+= (const Vertex& other); |
|
186 |
|
187 //! An operator overload for \c move(), using a temporary vertex. |
|
188 Vertex operator+ (const Vertex& other) const; |
|
189 |
|
190 //! Divides all values by \c d. |
|
191 Vertex operator/ (const double d) const; |
|
192 |
|
193 //! Divides all values by \c d. |
|
194 Vertex& operator/= (const double d); |
|
195 |
|
196 //! Checks whether this vertex has the same values as \c other. |
|
197 bool operator== (const Vertex& other) const; |
|
198 |
|
199 //! Checks whether this vertex has different values than \c other. |
|
200 bool operator!= (const Vertex& other) const; |
|
201 |
|
202 //! \returns a negated version the vertex |
|
203 Vertex operator-() const; |
|
204 |
|
205 //! \returns whether the vertex has lesser values than \c other. |
|
206 int operator< (const Vertex& other) const; |
|
207 |
|
208 //! An operator overload for \c getCoordinate(). |
|
209 inline double& operator[] (const Axis ax) |
|
210 { |
|
211 return getCoordinate ((int) ax); |
|
212 } |
|
213 |
|
214 //! An operator overload for \c getCoordinate() const. |
|
215 inline const double& operator[] (const Axis ax) const |
|
216 { |
|
217 return getCoordinate ((int) ax); |
|
218 } |
|
219 |
|
220 //! An operator overload for \c getCoordinate(). |
|
221 inline double& operator[] (const int ax) |
|
222 { |
|
223 return getCoordinate (ax); |
|
224 } |
|
225 |
|
226 //! An operator overload for \c getCoordinate() const. |
|
227 inline const double& operator[] (const int ax) const |
|
228 { |
|
229 return getCoordinate (ax); |
|
230 } |
|
231 |
|
232 //! \returns a mutable reference for the coordinate designated by \param n. |
|
233 inline double& getCoordinate (int n) |
|
234 { |
|
235 return m_coords[n]; |
|
236 } |
|
237 |
|
238 //! An overload of \c getCoordinate for const vertices. |
|
239 //! \returns a const reference for the coordinate designated by \param n. |
|
240 inline const double& getCoordinate (int n) const |
|
241 { |
|
242 return m_coords[n]; |
|
243 } |
|
244 |
|
245 //! \returns a mutable reference to X. |
|
246 inline double& x() |
|
247 { |
|
248 return m_coords[X]; |
|
249 } |
|
250 |
|
251 //! An overload of \c x() for const vertices. |
|
252 //! \returns a const reference to X. |
|
253 inline const double& x() const |
|
254 { |
|
255 return m_coords[X]; |
|
256 } |
|
257 |
|
258 //! \returns a mutable reference to Y. |
|
259 inline double& y() |
|
260 { |
|
261 return m_coords[Y]; |
|
262 } |
|
263 |
|
264 //! An overload of \c y() for const vertices. |
|
265 //! \returns a const reference to Y. |
|
266 inline const double& y() const |
|
267 { |
|
268 return m_coords[Y]; |
|
269 } |
|
270 |
|
271 //! \returns a mutable reference to Z. |
|
272 inline double& z() |
|
273 { |
|
274 return m_coords[Z]; |
|
275 } |
|
276 |
|
277 //! An overload of \c z() for const vertices. |
|
278 //! \returns a const reference to Z. |
|
279 inline const double& z() const |
|
280 { |
|
281 return m_coords[Z]; |
|
282 } |
|
283 |
|
284 private: |
|
285 double m_coords[3]; |
|
286 }; |
|
287 |
|
288 Q_DECLARE_METATYPE (Vertex) |
|
289 |
|
290 //! |
|
291 //! Defines a bounding box that encompasses a given set of objects. |
|
292 //! vertex0 is the minimum vertex, vertex1 is the maximum vertex. |
|
293 // |
|
294 class LDBoundingBox |
|
295 { |
|
296 PROPERTY (private, bool, isEmpty, setEmpty, STOCK_WRITE) |
|
297 PROPERTY (private, Vertex, vertex0, setVertex0, STOCK_WRITE) |
|
298 PROPERTY (private, Vertex, vertex1, setVertex1, STOCK_WRITE) |
|
299 |
|
300 public: |
|
301 //! Constructs an empty bounding box. |
|
302 LDBoundingBox(); |
|
303 |
|
304 //! Clears the bounding box |
|
305 void reset(); |
|
306 |
|
307 //! Calculates the bounding box's values from the objects in the current |
|
308 //! document. |
|
309 void calculateFromCurrentDocument(); |
|
310 |
|
311 //! \returns the length of the bounding box on the longest measure. |
|
312 double longestMeasurement() const; |
|
313 |
|
314 //! Calculates the given \c obj to the bounding box, adjusting |
|
315 //! extremas if necessary. |
|
316 void calcObject (LDObject* obj); |
|
317 |
|
318 //! Calculates the given \c vertex to the bounding box, adjusting |
|
319 //! extremas if necessary. |
|
320 void calcVertex (const Vertex& vertex); |
|
321 |
|
322 //! \returns the center of the bounding box. |
|
323 Vertex center() const; |
|
324 |
|
325 //! An operator overload for \c calcObject() |
|
326 LDBoundingBox& operator<< (LDObject* obj); |
|
327 |
|
328 //! An operator overload for \c calcVertex() |
|
329 LDBoundingBox& operator<< (const Vertex& v); |
|
330 }; |
|
331 |
|
332 extern const Vertex g_origin; // Vertex at (0, 0, 0) |
|
333 extern const Matrix g_identity; // Identity matrix |
|
334 |
|
335 static const double pi = 3.14159265358979323846; |
|