src/types.cpp

changeset 358
7885fa5b09c5
parent 322
5e701c3c3d8e
child 380
e442d9b7c251
equal deleted inserted replaced
357:9c954c222996 358:7885fa5b09c5
1 /* 1 /*
2 * LDForge: LDraw parts authoring CAD 2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 Santeri Piippo 3 * Copyright (C) 2013 Santeri Piippo
4 * 4 *
5 * This program is free software: you can redistribute it and/or modify 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 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 7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version. 8 * (at your option) any later version.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 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/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include <QObject> 19 #include <QObject>
25 #include "types.h" 25 #include "types.h"
26 #include "misc.h" 26 #include "misc.h"
27 27
28 const File nullfile; 28 const File nullfile;
29 29
30 str DoFormat (vector<StringFormatArg> args) { 30 str DoFormat( vector<StringFormatArg> args )
31 assert (args.size () >= 1); 31 {
32 str text = args[0].value (); 32 assert( args.size() >= 1 );
33 33 str text = args[0].value();
34 for (uchar i = 1; i < args.size (); ++i) 34
35 text = text.arg (args[i].value ()); 35 for( uchar i = 1; i < args.size(); ++i )
36 text = text.arg( args[i].value() );
36 37
37 return text; 38 return text;
38 } 39 }
39 40
40 vertex::vertex (double x, double y, double z) { 41 vertex::vertex( double x, double y, double z )
42 {
41 m_coords[X] = x; 43 m_coords[X] = x;
42 m_coords[Y] = y; 44 m_coords[Y] = y;
43 m_coords[Z] = z; 45 m_coords[Z] = z;
44 } 46 }
45 47
46 // ============================================================================= 48 // =============================================================================
47 void vertex::move (const vertex& other) { 49 void vertex::move( const vertex& other )
48 for (const Axis ax : g_Axes) 50 {
51 for( const Axis ax : g_Axes )
49 m_coords[ax] += other[ax]; 52 m_coords[ax] += other[ax];
50 } 53 }
51 54
52 // ============================================================================= 55 // =============================================================================
53 vertex vertex::midpoint (const vertex& other) { 56 vertex vertex::midpoint( const vertex& other )
57 {
54 vertex mid; 58 vertex mid;
55 59
56 for (const Axis ax : g_Axes) 60 for( const Axis ax : g_Axes )
57 mid[ax] = (m_coords[ax] + other[ax]) / 2; 61 mid[ax] = ( m_coords[ax] + other[ax] ) / 2;
58 62
59 return mid; 63 return mid;
60 } 64 }
61 65
62 // ============================================================================= 66 // =============================================================================
63 str vertex::stringRep (bool mangled) const { 67 str vertex::stringRep( bool mangled ) const
64 if (mangled) 68 {
65 return (str ("(") + 69 str fmtstr = "%1 %2 %3";
66 ftoa (coord (X)) + ", " + 70 if( mangled )
67 ftoa (coord (Y)) + ", " + 71 fmtstr = "(%1, %2, %3)";
68 ftoa (coord (Z)) + ")"); 72
69 73 return fmt( fmtstr, coord( X ), coord( Y ), coord( Z ));
70 return QStringList ({ftoa (coord (X)), ftoa (coord (Y)), 74 }
71 ftoa (coord (Z))}).join (" "); 75
72 } 76 // =============================================================================
73 77 void vertex::transform( matrix matr, vertex pos )
74 // ============================================================================= 78 {
75 void vertex::transform (matrix matr, vertex pos) { 79 double x2 = ( matr[0] * x()) + ( matr[1] * y()) + ( matr[2] * z()) + pos[X];
76 double x2 = (matr[0] * x ()) + (matr[1] * y ()) + (matr[2] * z ()) + pos[X]; 80 double y2 = ( matr[3] * x()) + ( matr[4] * y()) + ( matr[5] * z()) + pos[Y];
77 double y2 = (matr[3] * x ()) + (matr[4] * y ()) + (matr[5] * z ()) + pos[Y]; 81 double z2 = ( matr[6] * x()) + ( matr[7] * y()) + ( matr[8] * z()) + pos[Z];
78 double z2 = (matr[6] * x ()) + (matr[7] * y ()) + (matr[8] * z ()) + pos[Z]; 82
79 83 x() = x2;
80 x () = x2; 84 y() = y2;
81 y () = y2; 85 z() = z2;
82 z () = z2; 86 }
83 } 87
84 88 vertex vertex::operator-() const
85 vertex vertex::operator-() const { 89 {
86 return vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]); 90 return vertex( -m_coords[X], -m_coords[Y], -m_coords[Z] );
87 } 91 }
88 92
89 bool vertex::operator!= (const vertex& other) const { 93 bool vertex::operator!= ( const vertex& other ) const
90 return !operator== (other); 94 {
91 } 95 return !operator== ( other );
92 96 }
93 double& vertex::operator[] (const Axis ax) { 97
94 return coord ((ushort) ax); 98 double& vertex::operator[]( const Axis ax )
95 } 99 {
96 100 return coord( ( ushort ) ax );
97 const double& vertex::operator[] (const Axis ax) const { 101 }
98 return coord ((ushort) ax); 102
99 } 103 const double& vertex::operator[]( const Axis ax ) const
100 104 {
101 double& vertex::operator[] (const int ax) { 105 return coord( ( ushort ) ax );
102 return coord (ax); 106 }
103 } 107
104 108 double& vertex::operator[]( const int ax )
105 const double& vertex::operator[] (const int ax) const { 109 {
106 return coord (ax); 110 return coord( ax );
107 } 111 }
108 112
109 bool vertex::operator== (const vertex& other) const { 113 const double& vertex::operator[]( const int ax ) const
110 return coord (X) == other[X] && 114 {
111 coord (Y) == other[Y] && 115 return coord( ax );
112 coord (Z) == other[Z]; 116 }
113 } 117
114 118 bool vertex::operator== ( const vertex& other ) const
115 vertex& vertex::operator/= (const double d) { 119 {
116 for (const Axis ax : g_Axes) 120 return coord( X ) == other[X] &&
121 coord( Y ) == other[Y] &&
122 coord( Z ) == other[Z];
123 }
124
125 vertex& vertex::operator/= ( const double d )
126 {
127 for( const Axis ax : g_Axes )
117 m_coords[ax] /= d; 128 m_coords[ax] /= d;
118 129
119 return *this; 130 return *this;
120 } 131 }
121 132
122 vertex vertex::operator/ (const double d) const { 133 vertex vertex::operator/ ( const double d ) const
123 vertex other (*this); 134 {
135 vertex other( *this );
124 return other /= d; 136 return other /= d;
125 } 137 }
126 138
127 vertex& vertex::operator+= (const vertex& other) { 139 vertex& vertex::operator+= ( const vertex& other )
128 move (other); 140 {
141 move( other );
129 return *this; 142 return *this;
130 } 143 }
131 144
132 vertex vertex::operator+ (const vertex& other) const { 145 vertex vertex::operator+ ( const vertex& other ) const
133 vertex newvert (*this); 146 {
134 newvert.move (other); 147 vertex newvert( *this );
148 newvert.move( other );
135 return newvert; 149 return newvert;
136 } 150 }
137 151
138 int vertex::operator< (const vertex& other) const { 152 int vertex::operator< ( const vertex& other ) const
139 if (operator== (other)) 153 {
154 if( operator==( other ))
140 return false; 155 return false;
141 156
142 if (coord (X) < other[X]) 157 if( coord( X ) < other[X] )
143 return true; 158 return true;
144 159
145 if (coord (X) > other[X]) 160 if( coord( X ) > other[X] )
146 return false; 161 return false;
147 162
148 if (coord (Y) < other[Y]) 163 if( coord( Y ) < other[Y] )
149 return true; 164 return true;
150 165
151 if (coord (Y) > other[Y]) 166 if( coord( Y ) > other[Y] )
152 return false; 167 return false;
153 168
154 return coord (Z) < other[Z]; 169 return coord( Z ) < other[Z];
155 } 170 }
156 171
157 // ============================================================================= 172 // =============================================================================
158 matrix::matrix (double vals[]) { 173 matrix::matrix( double vals[] )
159 for (short i = 0; i < 9; ++i) 174 {
175 for( short i = 0; i < 9; ++i )
160 m_vals[i] = vals[i]; 176 m_vals[i] = vals[i];
161 } 177 }
162 178
163 matrix::matrix (double fillval) { 179 matrix::matrix( double fillval )
164 for (short i = 0; i < 9; ++i) 180 {
181 for( short i = 0; i < 9; ++i )
165 m_vals[i] = fillval; 182 m_vals[i] = fillval;
166 } 183 }
167 184
168 matrix::matrix (initlist<double> vals) { 185 matrix::matrix( initlist<double> vals )
169 assert (vals.size() == 9); 186 {
170 memcpy (&m_vals[0], &(*vals.begin ()), sizeof m_vals); 187 assert( vals.size() == 9 );
171 } 188 memcpy( &m_vals[0], &( *vals.begin() ), sizeof m_vals );
172 void matrix::puts () const { 189 }
173 for (short i = 0; i < 3; ++i) { 190
174 for (short j = 0; j < 3; ++j) 191 void matrix::puts() const
175 printf ("%*f\t", 10, m_vals[(i * 3) + j]); 192 {
193 for( short i = 0; i < 3; ++i )
194 {
195 for( short j = 0; j < 3; ++j )
196 print( "%1\t", m_vals[( i * 3 ) + j] );
176 197
177 printf ("\n"); 198 print( "\n" );
178 } 199 }
179 } 200 }
180 201
181 // ============================================================================= 202 // =============================================================================
182 str matrix::stringRep () const { 203 str matrix::stringRep() const
204 {
183 str val; 205 str val;
184 for (short i = 0; i < 9; ++i) { 206
185 if (i > 0) 207 for( short i = 0; i < 9; ++i )
208 {
209 if( i > 0 )
186 val += ' '; 210 val += ' ';
187 211
188 val += ftoa (m_vals[i]); 212 val += ftoa( m_vals[i] );
189 } 213 }
190 214
191 return val; 215 return val;
192 } 216 }
193 217
194 // ============================================================================= 218 // =============================================================================
195 void matrix::zero () { 219 void matrix::zero()
196 memset (&m_vals[0], 0, sizeof (double) * 9); 220 {
197 } 221 memset( &m_vals[0], 0, sizeof( double ) * 9 );
198 222 }
199 // ============================================================================= 223
200 matrix matrix::mult (matrix other) const { 224 // =============================================================================
225 matrix matrix::mult( matrix other ) const
226 {
201 matrix val; 227 matrix val;
202 val.zero (); 228 val.zero();
203 229
204 for (short i = 0; i < 3; ++i) 230 for( short i = 0; i < 3; ++i )
205 for (short j = 0; j < 3; ++j) 231 for( short j = 0; j < 3; ++j )
206 for (short k = 0; k < 3; ++k) 232 for( short k = 0; k < 3; ++k )
207 val[(i * 3) + j] += m_vals[(i * 3) + k] * other[(k * 3) + j]; 233 val[( i * 3 ) + j] += m_vals[( i * 3 ) + k] * other[( k * 3 ) + j];
208 234
209 return val; 235 return val;
210 } 236 }
211 237
212 // ============================================================================= 238 // =============================================================================
213 matrix& matrix::operator= (matrix other) { 239 matrix& matrix::operator= ( matrix other )
214 memcpy (&m_vals[0], &other.m_vals[0], sizeof (double) * 9); 240 {
215 return *this; 241 memcpy( &m_vals[0], &other.m_vals[0], sizeof( double ) * 9 );
216 } 242 return *this;
217 243 }
218 // ============================================================================= 244
219 double matrix::determinant () const { 245 // =============================================================================
220 return 246 double matrix::determinant() const
221 (val (0) * val (4) * val (8)) + 247 {
222 (val (1) * val (5) * val (6)) + 248 return ( val( 0 ) * val( 4 ) * val( 8 )) +
223 (val (2) * val (3) * val (7)) - 249 ( val( 1 ) * val( 5 ) * val( 6 )) +
224 (val (2) * val (4) * val (6)) - 250 ( val( 2 ) * val( 3 ) * val( 7 )) -
225 (val (1) * val (3) * val (8)) - 251 ( val( 2 ) * val( 4 ) * val( 6 )) -
226 (val (0) * val (5) * val (7)); 252 ( val( 1 ) * val( 3 ) * val( 8 )) -
227 } 253 ( val( 0 ) * val( 5 ) * val( 7 ));
228 254 }
229 // ============================================================================= 255
230 StringFormatArg::StringFormatArg (const str& v) { 256 // =============================================================================
257 StringFormatArg::StringFormatArg( const str& v )
258 {
231 m_val = v; 259 m_val = v;
232 } 260 }
233 261
234 StringFormatArg::StringFormatArg (const char& v) { 262 StringFormatArg::StringFormatArg( const char& v )
263 {
235 m_val = v; 264 m_val = v;
236 } 265 }
237 266
238 StringFormatArg::StringFormatArg (const uchar& v) { 267 StringFormatArg::StringFormatArg( const uchar& v )
268 {
239 m_val = v; 269 m_val = v;
240 } 270 }
241 271
242 StringFormatArg::StringFormatArg (const qchar& v) { 272 StringFormatArg::StringFormatArg( const qchar& v )
273 {
243 m_val = v; 274 m_val = v;
244 } 275 }
245 276
246 StringFormatArg::StringFormatArg (const float& v) { 277 StringFormatArg::StringFormatArg( const float& v )
247 m_val = ftoa (v); 278 {
248 } 279 m_val = ftoa( v );
249 280 }
250 StringFormatArg::StringFormatArg (const double& v) { 281
251 m_val = ftoa (v); 282 StringFormatArg::StringFormatArg( const double& v )
252 } 283 {
253 284 m_val = ftoa( v );
254 StringFormatArg::StringFormatArg (const vertex& v) { 285 }
255 m_val = v.stringRep (false); 286
256 } 287 StringFormatArg::StringFormatArg( const vertex& v )
257 288 {
258 StringFormatArg::StringFormatArg (const matrix& v) { 289 m_val = v.stringRep( false );
259 m_val = v.stringRep (); 290 }
260 } 291
261 292 StringFormatArg::StringFormatArg( const matrix& v )
262 StringFormatArg::StringFormatArg (const char* v) { 293 {
294 m_val = v.stringRep();
295 }
296
297 StringFormatArg::StringFormatArg( const char* v )
298 {
263 m_val = v; 299 m_val = v;
264 } 300 }
265 301
266 StringFormatArg::StringFormatArg (const strconfig& v) { 302 StringFormatArg::StringFormatArg( const strconfig& v )
303 {
267 m_val = v.value; 304 m_val = v.value;
268 } 305 }
269 306
270 StringFormatArg::StringFormatArg (const intconfig& v) { 307 StringFormatArg::StringFormatArg( const intconfig& v )
271 m_val.number (v.value); 308 {
272 } 309 m_val.number( v.value );
273 310 }
274 StringFormatArg::StringFormatArg (const floatconfig& v) { 311
275 m_val.number (v.value); 312 StringFormatArg::StringFormatArg( const floatconfig& v )
313 {
314 m_val.number( v.value );
276 } 315 }
277 316
278 StringFormatArg::StringFormatArg( const void* v ) 317 StringFormatArg::StringFormatArg( const void* v )
279 { 318 {
280 m_val.sprintf( "%p", v ); 319 m_val.sprintf( "%p", v );
281 } 320 }
282 321
283 // ============================================================================= 322 // =============================================================================
284 File::File () { 323 File::File()
324 {
285 // Make a null file 325 // Make a null file
286 m_file = null; 326 m_file = null;
287 m_textstream = null; 327 m_textstream = null;
288 } 328 }
289 329
290 File::File (str path, OpenType rtype) { 330 File::File( str path, OpenType rtype )
331 {
291 m_file = null; 332 m_file = null;
292 open (path, rtype); 333 open( path, rtype );
293 } 334 }
294 335
295 File::File (FILE* fp, OpenType rtype) { 336 File::File( FILE* fp, OpenType rtype )
337 {
296 m_file = null; 338 m_file = null;
297 open (fp, rtype); 339 open( fp, rtype );
298 } 340 }
299 341
300 File::~File () { 342 File::~File()
301 if (m_file) { 343 {
302 m_file->close (); 344 if( m_file )
345 {
346 m_file->close();
303 delete m_file; 347 delete m_file;
304 348
305 if (m_textstream) 349 if( m_textstream )
306 delete m_textstream; 350 delete m_textstream;
307 } 351 }
308 } 352 }
309 353
310 bool File::open (FILE* fp, OpenType rtype) { 354 bool File::open( FILE* fp, OpenType rtype )
311 return open ("", rtype, fp); 355 {
312 } 356 return open( "", rtype, fp );
313 357 }
314 bool File::open (str path, OpenType rtype, FILE* fp) { 358
315 close (); 359 bool File::open( str path, OpenType rtype, FILE* fp )
316 360 {
317 if (!m_file) 361 close();
362
363 if( !m_file )
318 m_file = new QFile; 364 m_file = new QFile;
319 365
320 m_file->setFileName (path); 366 m_file->setFileName( path );
321 367
322 bool result; 368 bool result;
323 369
324 QIODevice::OpenMode mode = 370 QIODevice::OpenMode mode =
325 (rtype == Read) ? QIODevice::ReadOnly : 371 ( rtype == Read ) ? QIODevice::ReadOnly :
326 (rtype == Write) ? QIODevice::WriteOnly : 372 ( rtype == Write ) ? QIODevice::WriteOnly : QIODevice::Append;
327 QIODevice::Append; 373
328 374 if( fp )
329 if (fp) 375 result = m_file->open( fp, mode );
330 result = m_file->open (fp, mode);
331 else 376 else
332 result = m_file->open (mode); 377 result = m_file->open( mode );
333 378
334 if (result) { 379 if( result )
335 m_textstream = new QTextStream (m_file); 380 {
381 m_textstream = new QTextStream( m_file );
336 return true; 382 return true;
337 } 383 }
338 384
339 delete m_file; 385 delete m_file;
340 m_file = null; 386 m_file = null;
341 return false; 387 return false;
342 } 388 }
343 389
344 File::iterator File::begin() { 390 File::iterator File::begin()
345 return iterator (this); 391 {
346 } 392 return iterator( this );
347 393 }
348 File::iterator& File::end () { 394
395 File::iterator& File::end()
396 {
349 return m_endIterator; 397 return m_endIterator;
350 } 398 }
351 399
352 void File::write (str msg) { 400 void File::write( str msg )
353 m_file->write (msg.toUtf8 (), msg.length ()); 401 {
354 } 402 m_file->write( msg.toUtf8(), msg.length() );
355 403 }
356 bool File::readLine (str& line) { 404
357 if (!m_textstream || m_textstream->atEnd ()) 405 bool File::readLine( str& line )
406 {
407 if( !m_textstream || m_textstream->atEnd() )
358 return false; 408 return false;
359 409
360 line = m_textstream->readLine (); 410 line = m_textstream->readLine();
361 return true; 411 return true;
362 } 412 }
363 413
364 bool File::atEnd () const { 414 bool File::atEnd() const
365 if (!m_textstream) 415 {
366 fatal ("cannot use atEnd on a null file"); 416 if( !m_textstream )
367 417 fatal( "cannot use atEnd on a null file" );
368 return m_textstream->atEnd (); 418
369 } 419 return m_textstream->atEnd();
370 420 }
371 bool File::isNull () const { 421
422 bool File::isNull() const
423 {
372 return m_file == null; 424 return m_file == null;
373 } 425 }
374 426
375 bool File::operator!() const { 427 bool File::operator!() const
376 return isNull (); 428 {
377 } 429 return isNull();
378 430 }
379 void File::close () { 431
380 if (!m_file) 432 void File::close()
433 {
434 if( !m_file )
381 return; 435 return;
382 436
383 delete m_file; 437 delete m_file;
384 m_file = null; 438 m_file = null;
385 439
386 if (m_textstream) { 440 if( m_textstream )
441 {
387 delete m_textstream; 442 delete m_textstream;
388 m_textstream = null; 443 m_textstream = null;
389 } 444 }
390 } 445 }
391 446
392 bool File::flush () { 447 bool File::flush()
393 return m_file->flush (); 448 {
394 } 449 return m_file->flush();
395 450 }
396 File::operator bool () const { 451
397 return !isNull (); 452 File::operator bool () const
398 } 453 {
399 454 return !isNull();
400 void File::rewind () { 455 }
401 m_file->seek (0); 456
402 } 457 void File::rewind()
403 458 {
404 File::iterator::iterator (File* f) : m_file (f) { 459 m_file->seek( 0 );
460 }
461
462 File::iterator::iterator( File* f ) : m_file( f )
463 {
405 operator++ (); 464 operator++ ();
406 } 465 }
407 466
408 void File::iterator::operator++ () { 467 void File::iterator::operator++ ()
409 m_gotdata = m_file->readLine (m_text); 468 {
410 } 469 m_gotdata = m_file->readLine( m_text );
411 470 }
412 str File::iterator::operator* () { 471
472 str File::iterator::operator* ()
473 {
413 return m_text; 474 return m_text;
414 } 475 }
415 476
416 // The prime contestant for the weirdest operator== 2013 award? 477 // The prime contestant for the weirdest operator== 2013 award?
417 bool File::iterator::operator== (File::iterator& other) { 478 bool File::iterator::operator== ( File::iterator& other )
418 return (other.m_file == null && !m_gotdata); 479 {
419 } 480 return ( other.m_file == null && !m_gotdata );
420 481 }
421 bool File::iterator::operator!= (File::iterator& other) { 482
422 return !operator== (other); 483 bool File::iterator::operator!= ( File::iterator& other )
423 } 484 {
485 return !operator== ( other );
486 }

mercurial