src/types.cc

changeset 667
31540c1f22ea
parent 622
622c49e60348
equal deleted inserted replaced
666:c595cfb4791c 667:31540c1f22ea
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 #include <QObject>
20 #include <QStringList>
21 #include <QTextStream>
22 #include <QFile>
23 #include <assert.h>
24 #include "main.h"
25 #include "types.h"
26 #include "misc.h"
27 #include "ldtypes.h"
28 #include "document.h"
29
30 // =============================================================================
31 // -----------------------------------------------------------------------------
32 QString DoFormat (QList<StringFormatArg> args)
33 {
34 assert (args.size() >= 1);
35 QString text = args[0].value();
36
37 for (uchar i = 1; i < args.size(); ++i)
38 text = text.arg (args[i].value());
39
40 return text;
41 }
42
43 // =============================================================================
44 // -----------------------------------------------------------------------------
45 Vertex::Vertex (double x, double y, double z)
46 {
47 m_coords[X] = x;
48 m_coords[Y] = y;
49 m_coords[Z] = z;
50 }
51
52 // =============================================================================
53 // -----------------------------------------------------------------------------
54 void Vertex::move (const Vertex& other)
55 {
56 for_axes (ax)
57 m_coords[ax] += other[ax];
58 }
59
60 // =============================================================================
61 // -----------------------------------------------------------------------------
62 double Vertex::distanceTo (const Vertex& other) const
63 {
64 double dx = abs (x() - other.x());
65 double dy = abs (y() - other.y());
66 double dz = abs (z() - other.z());
67 return sqrt ((dx * dx) + (dy * dy) + (dz * dz));
68 }
69
70 // =============================================================================
71 // -----------------------------------------------------------------------------
72 Vertex Vertex::midpoint (const Vertex& other)
73 {
74 Vertex mid;
75
76 for_axes (ax)
77 mid[ax] = (getCoordinate (ax) + other[ax]) / 2;
78
79 return mid;
80 }
81
82 // =============================================================================
83 // -----------------------------------------------------------------------------
84 QString Vertex::toString (bool mangled) const
85 {
86 QString fmtstr = "%1 %2 %3";
87
88 if (mangled)
89 fmtstr = "(%1, %2, %3)";
90
91 return fmt (fmtstr, x(), y(), z());
92 }
93
94 // =============================================================================
95 // -----------------------------------------------------------------------------
96 void Vertex::transform (const Matrix& matr, const Vertex& pos)
97 {
98 double x2 = (matr[0] * x()) + (matr[1] * y()) + (matr[2] * z()) + pos[X];
99 double y2 = (matr[3] * x()) + (matr[4] * y()) + (matr[5] * z()) + pos[Y];
100 double z2 = (matr[6] * x()) + (matr[7] * y()) + (matr[8] * z()) + pos[Z];
101
102 x() = x2;
103 y() = y2;
104 z() = z2;
105 }
106
107 // =============================================================================
108 // -----------------------------------------------------------------------------
109 Vertex Vertex::operator-() const
110 {
111 return Vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]);
112 }
113
114 // =============================================================================
115 // -----------------------------------------------------------------------------
116 bool Vertex::operator!= (const Vertex& other) const
117 {
118 return !operator== (other);
119 }
120
121 // =============================================================================
122 // -----------------------------------------------------------------------------
123 bool Vertex::operator== (const Vertex& other) const
124 {
125 return getCoordinate (X) == other[X] &&
126 getCoordinate (Y) == other[Y] &&
127 getCoordinate (Z) == other[Z];
128 }
129
130 // =============================================================================
131 // -----------------------------------------------------------------------------
132 Vertex& Vertex::operator/= (const double d)
133 {
134 for_axes (ax)
135 m_coords[ax] /= d;
136
137 return *this;
138 }
139
140 // =============================================================================
141 // -----------------------------------------------------------------------------
142 Vertex Vertex::operator/ (const double d) const
143 {
144 Vertex other (*this);
145 return other /= d;
146 }
147
148 // =============================================================================
149 // -----------------------------------------------------------------------------
150 Vertex& Vertex::operator+= (const Vertex& other)
151 {
152 move (other);
153 return *this;
154 }
155
156 // =============================================================================
157 // -----------------------------------------------------------------------------
158 Vertex Vertex::operator+ (const Vertex& other) const
159 {
160 Vertex newvert (*this);
161 newvert.move (other);
162 return newvert;
163 }
164
165 // =============================================================================
166 // -----------------------------------------------------------------------------
167 int Vertex::operator< (const Vertex& other) const
168 {
169 if (operator== (other))
170 return false;
171
172 if (getCoordinate (X) < other[X])
173 return true;
174
175 if (getCoordinate (X) > other[X])
176 return false;
177
178 if (getCoordinate (Y) < other[Y])
179 return true;
180
181 if (getCoordinate (Y) > other[Y])
182 return false;
183
184 return getCoordinate (Z) < other[Z];
185 }
186
187 // =============================================================================
188 // -----------------------------------------------------------------------------
189 Matrix::Matrix (double vals[])
190 {
191 for (int i = 0; i < 9; ++i)
192 m_vals[i] = vals[i];
193 }
194
195 // =============================================================================
196 // -----------------------------------------------------------------------------
197 Matrix::Matrix (double fillval)
198 {
199 for (int i = 0; i < 9; ++i)
200 m_vals[i] = fillval;
201 }
202
203 // =============================================================================
204 // -----------------------------------------------------------------------------
205 Matrix::Matrix (initlist<double> vals)
206 {
207 assert (vals.size() == 9);
208 memcpy (&m_vals[0], & (*vals.begin()), sizeof m_vals);
209 }
210
211 // =============================================================================
212 // -----------------------------------------------------------------------------
213 void Matrix::puts() const
214 {
215 for (int i = 0; i < 3; ++i)
216 {
217 for (int j = 0; j < 3; ++j)
218 log ("%1\t", m_vals[ (i * 3) + j]);
219
220 log ("\n");
221 }
222 }
223
224 // =============================================================================
225 // -----------------------------------------------------------------------------
226 QString Matrix::toString() const
227 {
228 QString val;
229
230 for (int i = 0; i < 9; ++i)
231 {
232 if (i > 0)
233 val += ' ';
234
235 val += QString::number (m_vals[i]);
236 }
237
238 return val;
239 }
240
241 // =============================================================================
242 // -----------------------------------------------------------------------------
243 void Matrix::zero()
244 {
245 memset (&m_vals[0], 0, sizeof m_vals);
246 }
247
248 // =============================================================================
249 // -----------------------------------------------------------------------------
250 Matrix Matrix::mult (const Matrix& other) const
251 {
252 Matrix val;
253 val.zero();
254
255 for (int i = 0; i < 3; ++i)
256 for (int j = 0; j < 3; ++j)
257 for (int k = 0; k < 3; ++k)
258 val[(i * 3) + j] += m_vals[(i * 3) + k] * other[(k * 3) + j];
259
260 return val;
261 }
262
263 // =============================================================================
264 // -----------------------------------------------------------------------------
265 Matrix& Matrix::operator= (const Matrix& other)
266 {
267 memcpy (&m_vals[0], &other.m_vals[0], sizeof m_vals);
268 return *this;
269 }
270
271 // =============================================================================
272 // -----------------------------------------------------------------------------
273 double Matrix::getDeterminant() const
274 {
275 return (val (0) * val (4) * val (8)) +
276 (val (1) * val (5) * val (6)) +
277 (val (2) * val (3) * val (7)) -
278 (val (2) * val (4) * val (6)) -
279 (val (1) * val (3) * val (8)) -
280 (val (0) * val (5) * val (7));
281 }
282
283 // =============================================================================
284 // -----------------------------------------------------------------------------
285 bool Matrix::operator== (const Matrix& other) const
286 {
287 for (int i = 0; i < 9; ++i)
288 if (val (i) != other[i])
289 return false;
290
291 return true;
292 }
293
294 // =============================================================================
295 // -----------------------------------------------------------------------------
296 LDBoundingBox::LDBoundingBox()
297 {
298 reset();
299 }
300
301 // =============================================================================
302 // -----------------------------------------------------------------------------
303 void LDBoundingBox::calculate()
304 {
305 reset();
306
307 if (!getCurrentDocument())
308 return;
309
310 for (LDObject* obj : getCurrentDocument()->getObjects())
311 calcObject (obj);
312 }
313
314 // =============================================================================
315 // -----------------------------------------------------------------------------
316 void LDBoundingBox::calcObject (LDObject* obj)
317 {
318 switch (obj->getType())
319 {
320 case LDObject::ELine:
321 case LDObject::ETriangle:
322 case LDObject::EQuad:
323 case LDObject::ECondLine:
324 {
325 for (int i = 0; i < obj->vertices(); ++i)
326 calcVertex (obj->getVertex (i));
327 } break;
328
329 case LDObject::ESubfile:
330 {
331 LDSubfile* ref = static_cast<LDSubfile*> (obj);
332 LDObjectList objs = ref->inlineContents (LDSubfile::DeepCacheInline);
333
334 for (LDObject * obj : objs)
335 {
336 calcObject (obj);
337 obj->deleteSelf();
338 }
339 }
340 break;
341
342 default:
343 break;
344 }
345 }
346
347 // =============================================================================
348 // -----------------------------------------------------------------------------
349 LDBoundingBox& LDBoundingBox::operator<< (const Vertex& v)
350 {
351 calcVertex (v);
352 return *this;
353 }
354
355 // =============================================================================
356 // -----------------------------------------------------------------------------
357 LDBoundingBox& LDBoundingBox::operator<< (LDObject* obj)
358 {
359 calcObject (obj);
360 return *this;
361 }
362
363 // =============================================================================
364 // -----------------------------------------------------------------------------
365 void LDBoundingBox::calcVertex (const Vertex& v)
366 {
367 for_axes (ax)
368 {
369 m_Vertex0[ax] = min (v[ax], m_Vertex0[ax]);
370 m_Vertex1[ax] = max (v[ax], m_Vertex1[ax]);
371 }
372
373 setEmpty (false);
374 }
375
376 // =============================================================================
377 // -----------------------------------------------------------------------------
378 void LDBoundingBox::reset()
379 {
380 m_Vertex0[X] = m_Vertex0[Y] = m_Vertex0[Z] = 10000.0;
381 m_Vertex1[X] = m_Vertex1[Y] = m_Vertex1[Z] = -10000.0;
382 setEmpty (true);
383 }
384
385 // =============================================================================
386 // -----------------------------------------------------------------------------
387 double LDBoundingBox::size() const
388 {
389 double xscale = (m_Vertex0[X] - m_Vertex1[X]);
390 double yscale = (m_Vertex0[Y] - m_Vertex1[Y]);
391 double zscale = (m_Vertex0[Z] - m_Vertex1[Z]);
392 double size = zscale;
393
394 if (xscale > yscale)
395 {
396 if (xscale > zscale)
397 size = xscale;
398 }
399 elif (yscale > zscale)
400 size = yscale;
401
402 if (abs (size) >= 2.0f)
403 return abs (size / 2);
404
405 return 1.0f;
406 }
407
408 // =============================================================================
409 // -----------------------------------------------------------------------------
410 Vertex LDBoundingBox::center() const
411 {
412 return Vertex (
413 (m_Vertex0[X] + m_Vertex1[X]) / 2,
414 (m_Vertex0[Y] + m_Vertex1[Y]) / 2,
415 (m_Vertex0[Z] + m_Vertex1[Z]) / 2);
416 }

mercurial