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 #ifndef LDFORGE_TYPES_H |
|
20 #define LDFORGE_TYPES_H |
|
21 |
|
22 #include <QString> |
|
23 #include <QObject> |
|
24 #include <QStringList> |
|
25 #include <QMetaType> |
|
26 #include "property.h" |
|
27 |
|
28 class LDObject; |
|
29 class QFile; |
|
30 class QTextStream; |
|
31 |
|
32 using int8 = qint8; |
|
33 using int16 = qint16; |
|
34 using int32 = qint32; |
|
35 using int64 = qint64; |
|
36 using uint8 = quint8; |
|
37 using uint16 = quint16; |
|
38 using uint32 = quint32; |
|
39 using uint64 = quint64; |
|
40 |
|
41 template<class T> |
|
42 using initlist = std::initializer_list<T>; |
|
43 |
|
44 template<class T, class R> |
|
45 using pair = std::pair<T, R>; |
|
46 |
|
47 enum Axis |
|
48 { |
|
49 X, |
|
50 Y, |
|
51 Z |
|
52 }; |
|
53 |
|
54 // ============================================================================= |
|
55 // |
|
56 class LDObject; |
|
57 using LDObjectList = QList<LDObject*>; |
|
58 |
|
59 // ============================================================================= |
|
60 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
61 // ============================================================================= |
|
62 // matrix |
|
63 // |
|
64 // A mathematical 3 x 3 matrix |
|
65 // ============================================================================= |
|
66 class Matrix |
|
67 { |
|
68 public: |
|
69 Matrix() {} |
|
70 Matrix (initlist<double> vals); |
|
71 Matrix (double fillval); |
|
72 Matrix (double vals[]); |
|
73 |
|
74 double getDeterminant() const; |
|
75 Matrix mult (const Matrix& other) const; |
|
76 void puts() const; |
|
77 QString toString() const; |
|
78 void zero(); |
|
79 Matrix& operator= (const Matrix& other); |
|
80 |
|
81 inline double& val (int idx) |
|
82 { |
|
83 return m_vals[idx]; |
|
84 } |
|
85 |
|
86 inline const double& val (int idx) const |
|
87 { |
|
88 return m_vals[idx]; |
|
89 } |
|
90 |
|
91 inline Matrix operator* (const Matrix& other) const |
|
92 { |
|
93 return mult (other); |
|
94 } |
|
95 |
|
96 inline double& operator[] (int idx) |
|
97 { |
|
98 return val (idx); |
|
99 } |
|
100 |
|
101 inline const double& operator[] (int idx) const |
|
102 { |
|
103 return val (idx); |
|
104 } |
|
105 |
|
106 bool operator== (const Matrix& other) const; |
|
107 |
|
108 private: |
|
109 double m_vals[9]; |
|
110 }; |
|
111 |
|
112 // ============================================================================= |
|
113 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
114 // ============================================================================= |
|
115 // Vertex |
|
116 // |
|
117 // Vertex class, contains a single point in 3D space. Not to be confused with |
|
118 // LDVertex, which is a vertex used in an LDraw part file. |
|
119 // ============================================================================= |
|
120 class Vertex |
|
121 { |
|
122 public: |
|
123 Vertex() {} |
|
124 Vertex (double x, double y, double z); |
|
125 |
|
126 double distanceTo (const Vertex& other) const; |
|
127 Vertex midpoint (const Vertex& other); |
|
128 void move (const Vertex& other); |
|
129 QString toString (bool mangled) const; |
|
130 void transform (const Matrix& matr, const Vertex& pos); |
|
131 |
|
132 Vertex& operator+= (const Vertex& other); |
|
133 Vertex operator+ (const Vertex& other) const; |
|
134 Vertex operator/ (const double d) const; |
|
135 Vertex& operator/= (const double d); |
|
136 bool operator== (const Vertex& other) const; |
|
137 bool operator!= (const Vertex& other) const; |
|
138 Vertex operator-() const; |
|
139 int operator< (const Vertex& other) const; |
|
140 |
|
141 inline double& operator[] (const Axis ax) |
|
142 { |
|
143 return getCoordinate ((int) ax); |
|
144 } |
|
145 |
|
146 inline const double& operator[] (const Axis ax) const |
|
147 { |
|
148 return getCoordinate ((int) ax); |
|
149 } |
|
150 |
|
151 inline double& operator[] (const int ax) |
|
152 { |
|
153 return getCoordinate (ax); |
|
154 } |
|
155 |
|
156 inline const double& operator[] (const int ax) const |
|
157 { |
|
158 return getCoordinate (ax); |
|
159 } |
|
160 |
|
161 inline double& getCoordinate (int n) |
|
162 { |
|
163 return m_coords[n]; |
|
164 } |
|
165 |
|
166 inline const double& getCoordinate (int n) const |
|
167 { |
|
168 return m_coords[n]; |
|
169 } |
|
170 |
|
171 inline double& x() |
|
172 { |
|
173 return m_coords[X]; |
|
174 } |
|
175 |
|
176 inline const double& x() const |
|
177 { |
|
178 return m_coords[X]; |
|
179 } |
|
180 |
|
181 inline double& y() |
|
182 { |
|
183 return m_coords[Y]; |
|
184 } |
|
185 |
|
186 inline const double& y() const |
|
187 { |
|
188 return m_coords[Y]; |
|
189 } |
|
190 |
|
191 inline double& z() |
|
192 { |
|
193 return m_coords[Z]; |
|
194 } |
|
195 |
|
196 inline const double& z() const |
|
197 { |
|
198 return m_coords[Z]; |
|
199 } |
|
200 |
|
201 private: |
|
202 double m_coords[3]; |
|
203 }; |
|
204 |
|
205 Q_DECLARE_METATYPE (Vertex) |
|
206 |
|
207 // ============================================================================= |
|
208 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
|
209 // ============================================================================= |
|
210 // StringFormatArg |
|
211 // |
|
212 // Converts a given value into a string that can be retrieved with ::value(). |
|
213 // Used as the argument type to the formatting functions, hence its name. |
|
214 // ============================================================================= |
|
215 class StringFormatArg |
|
216 { |
|
217 public: |
|
218 StringFormatArg (const QString& a) : m_val (a) {} |
|
219 StringFormatArg (const char& a) : m_val (a) {} |
|
220 StringFormatArg (const uchar& a) : m_val (a) {} |
|
221 StringFormatArg (const QChar& a) : m_val (a) {} |
|
222 StringFormatArg (int a) : m_val (QString::number (a)) {} |
|
223 StringFormatArg (const float& a) : m_val (QString::number (a)) {} |
|
224 StringFormatArg (const double& a) : m_val (QString::number (a)) {} |
|
225 StringFormatArg (const Vertex& a) : m_val (a.toString (false)) {} |
|
226 StringFormatArg (const Matrix& a) : m_val (a.toString()) {} |
|
227 StringFormatArg (const char* a) : m_val (a) {} |
|
228 |
|
229 StringFormatArg (const void* a) |
|
230 { |
|
231 m_val.sprintf ("%p", a); |
|
232 } |
|
233 |
|
234 template<class T> StringFormatArg (const QList<T>& a) |
|
235 { |
|
236 m_val = "{ "; |
|
237 |
|
238 for (const T& it : a) |
|
239 { |
|
240 if (&it != &a.first()) |
|
241 m_val += ", "; |
|
242 |
|
243 StringFormatArg arg (it); |
|
244 m_val += arg.value(); |
|
245 } |
|
246 |
|
247 if (!a.isEmpty()) |
|
248 m_val += " "; |
|
249 |
|
250 m_val += "}"; |
|
251 } |
|
252 |
|
253 inline QString value() const |
|
254 { |
|
255 return m_val; |
|
256 } |
|
257 |
|
258 private: |
|
259 QString m_val; |
|
260 }; |
|
261 |
|
262 // ============================================================================= |
|
263 // LDBoundingBox |
|
264 // |
|
265 // The bounding box is the box that encompasses a given set of objects. |
|
266 // v0 is the minimum vertex, v1 is the maximum vertex. |
|
267 // ============================================================================= |
|
268 class LDBoundingBox |
|
269 { |
|
270 PROPERTY (private, bool, Empty, BOOL_OPS, STOCK_WRITE) |
|
271 PROPERTY (private, Vertex, Vertex0, NO_OPS, STOCK_WRITE) |
|
272 PROPERTY (private, Vertex, Vertex1, NO_OPS, STOCK_WRITE) |
|
273 |
|
274 public: |
|
275 LDBoundingBox(); |
|
276 void reset(); |
|
277 void calculate(); |
|
278 double size() const; |
|
279 void calcObject (LDObject* obj); |
|
280 void calcVertex (const Vertex& v); |
|
281 Vertex center() const; |
|
282 |
|
283 LDBoundingBox& operator<< (LDObject* obj); |
|
284 LDBoundingBox& operator<< (const Vertex& v); |
|
285 }; |
|
286 |
|
287 // Formatter function |
|
288 QString DoFormat (QList<StringFormatArg> args); |
|
289 |
|
290 // printf replacement |
|
291 void doPrint (QFile& f, QList<StringFormatArg> args); |
|
292 void doPrint (FILE* fp, QList<StringFormatArg> args); |
|
293 |
|
294 // log() - universal access to the message log. Defined here so that I don't have |
|
295 // to include messagelog.h here and recompile everything every time that file changes. |
|
296 void DoLog (std::initializer_list<StringFormatArg> args); |
|
297 |
|
298 // Macros to access these functions |
|
299 # ifndef IN_IDE_PARSER |
|
300 #define fmt(...) DoFormat ({__VA_ARGS__}) |
|
301 # define fprint(F, ...) doPrint (F, {__VA_ARGS__}) |
|
302 # define log(...) DoLog({ __VA_ARGS__ }) |
|
303 #else |
|
304 QString fmt (const char* fmtstr, ...); |
|
305 void fprint (QFile& f, const char* fmtstr, ...); |
|
306 void fprint (FILE* fp, const char* fmtstr, ...); |
|
307 void log (const char* fmtstr, ...); |
|
308 #endif |
|
309 |
|
310 extern const Vertex g_origin; // Vertex at (0, 0, 0) |
|
311 extern const Matrix g_identity; // Identity matrix |
|
312 |
|
313 static const double pi = 3.14159265358979323846; |
|
314 |
|
315 #endif // LDFORGE_TYPES_H |
|