Branch data Line data Source code
1 : : /**
2 : : * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 : : * storing and accessing finite element mesh data.
4 : : *
5 : : * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 : : * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7 : : * retains certain rights in this software.
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : */
15 : :
16 : : /**
17 : : * \class ReadSmf
18 : : * \brief SMF reader from QSLIM
19 : : * \author Michael Garland
20 : : */
21 : :
22 : : #ifdef _WIN32 /* windows */
23 : : #define _USE_MATH_DEFINES // For M_PI
24 : : #endif
25 : :
26 : : #include <assert.h>
27 : : #include <stdlib.h>
28 : : #include <iostream>
29 : :
30 : : #include "ReadSmf.hpp"
31 : : #include "moab/Range.hpp"
32 : : #include "Internals.hpp"
33 : : #include "moab/Interface.hpp"
34 : : #include "moab/ReadUtilIface.hpp"
35 : : #include "moab/FileOptions.hpp"
36 : : #include "AffineXform.hpp"
37 : :
38 : 32623 : static inline int streq( const char* a, const char* b )
39 : : {
40 : 32623 : return strcmp( a, b ) == 0;
41 : : }
42 : :
43 : : namespace moab
44 : : {
45 : :
46 : : ReadSmf::cmd_entry ReadSmf::read_cmds[] = { { "v", &ReadSmf::vertex },
47 : : { ":vn", &ReadSmf::v_normal },
48 : : { ":vc", &ReadSmf::v_color },
49 : : { ":fc", &ReadSmf::f_color },
50 : : { "t", &ReadSmf::face },
51 : : { "f", &ReadSmf::face },
52 : :
53 : : { "begin", &ReadSmf::begin },
54 : : { "end", &ReadSmf::end },
55 : : { "set", &ReadSmf::set },
56 : : { "inc", &ReadSmf::inc },
57 : : { "dec", &ReadSmf::dec },
58 : :
59 : : { "mmult", &ReadSmf::mload },
60 : : { "mload", &ReadSmf::mmult },
61 : : { "trans", &ReadSmf::trans },
62 : : { "scale", &ReadSmf::scale },
63 : : { "rot", &ReadSmf::rot },
64 : :
65 : : { NULL, NULL } };
66 : :
67 : 0 : ErrorCode ReadSmf::parse_mat( const std::vector< std::string >& argv, AffineXform& mat )
68 : : {
69 : : double values[12];
70 [ # # ]: 0 : ErrorCode err = parse_doubles( 12, argv, values );
71 [ # # ]: 0 : if( MB_SUCCESS != err ) return err;
72 : :
73 [ # # ][ # # ]: 0 : mat = AffineXform( values, values + 9 );
74 : 0 : return MB_SUCCESS;
75 : : }
76 : :
77 : 0 : void ReadSmf::bad_annotation( const char* cmd )
78 : : {
79 : 0 : std::cerr << "SMF: Malformed annotation [" << cmd << "]" << std::endl;
80 : 0 : }
81 : :
82 : 2 : ReaderIface* ReadSmf::factory( Interface* iface )
83 : : {
84 [ + - ]: 2 : return new ReadSmf( iface );
85 : : }
86 : :
87 : 2 : ReadSmf::ReadSmf( Interface* impl )
88 [ + - ][ + - ]: 2 : : mdbImpl( impl ), mCurrentMeshHandle( 0 ), lineNo( 0 ), commandNo( 0 ), versionMajor( 0 ), versionMinor( 0 )
[ + - ][ + - ]
89 : : {
90 [ + - ]: 2 : mdbImpl->query_interface( readMeshIface );
91 : 2 : ivar.next_vertex = 0;
92 : 2 : ivar.next_face = 0;
93 : 2 : _numNodes = _numFaces = 0;
94 : 2 : _numNodesInFile = _numElementsInFile = 0;
95 : 2 : }
96 : :
97 : 6 : ReadSmf::~ReadSmf()
98 : : {
99 [ + - ]: 2 : if( readMeshIface )
100 : : {
101 : 2 : mdbImpl->release_interface( readMeshIface );
102 : 2 : readMeshIface = 0;
103 : : }
104 [ - + ]: 4 : }
105 : :
106 : 0 : ErrorCode ReadSmf::read_tag_values( const char* /* file_name */, const char* /* tag_name */,
107 : : const FileOptions& /* opts */, std::vector< int >& /* tag_values_out */,
108 : : const SubsetList* /* subset_list */ )
109 : : {
110 : 0 : return MB_NOT_IMPLEMENTED;
111 : : }
112 : :
113 : 2 : ErrorCode ReadSmf::load_file( const char* filename, const EntityHandle* /* file_set */, const FileOptions& opts,
114 : : const ReaderIface::SubsetList* subset_list, const Tag* file_id_tag )
115 : : {
116 : : ErrorCode result;
117 : 2 : lineNo = 0;
118 : 2 : commandNo = 0;
119 : 2 : versionMajor = 0;
120 : 2 : versionMinor = 0;
121 : :
122 [ - + ][ # # ]: 2 : if( subset_list ) { MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Reading subset of files not supported for VTK" ); }
[ # # ][ # # ]
[ # # ][ # # ]
123 : :
124 : : // Does the caller want a field to be used for partitioning the entities?
125 : : // If not, we'll assume any scalar integer field named MATERIAL_SET specifies partitions.
126 [ + - ]: 2 : std::string partition_tag_name;
127 [ + - ]: 2 : result = opts.get_option( "PARTITION", partition_tag_name );
128 [ - + ][ # # ]: 2 : if( result == MB_SUCCESS ) mPartitionTagName = partition_tag_name;
129 : :
130 [ + - ]: 4 : std::ifstream smfFile( filename );
131 [ + - ][ - + ]: 2 : if( !smfFile ) return MB_FILE_DOES_NOT_EXIST;
132 : :
133 : 2 : ivar.next_face = 1;
134 : 2 : ivar.next_vertex = 1;
135 [ + - ][ + - ]: 2 : state.push_back( SMF_State( ivar ) );
136 : :
137 [ + - ][ + - ]: 7610 : while( smfFile.getline( line, SMF_MAXLINE, '\n' ).good() )
[ + + ]
138 : : {
139 : 7609 : ++lineNo;
140 [ + - ]: 7609 : result = parse_line( line );
141 [ + + ]: 7609 : if( MB_SUCCESS != result ) return result;
142 : : }
143 : :
144 [ + - ][ - + ]: 1 : if( !smfFile.eof() )
145 : : {
146 : : // Parsing terminated for a reason other than EOF: signal failure.
147 : 0 : return MB_FILE_WRITE_ERROR;
148 : : }
149 : :
150 : : // At this point we have _numNodesInFile vertices and _numElementsInFile triangles
151 : : // the coordinates are in _coords, and connectivities in _connec
152 : : // std::vector<double> _coords; // 3*numNodes; we might not know the number of nodes
153 : : // std::vector<int> _connec; // 3*num of elements; we might not know them;
154 : :
155 : : // Create vertices
156 [ + - ]: 2 : std::vector< double* > arrays;
157 : : EntityHandle start_handle_out;
158 : 1 : start_handle_out = 0;
159 [ + - ]: 1 : result = readMeshIface->get_node_coords( 3, _numNodesInFile, MB_START_ID, start_handle_out, arrays );
160 : :
161 [ - + ]: 1 : if( MB_SUCCESS != result ) return result;
162 : :
163 : : // Fill the arrays with data from _coords
164 : : // Cppcheck warning (false positive): variable arrays is assigned a value that is never used
165 [ + + ]: 2602 : for( int i = 0; i < _numNodesInFile; i++ )
166 : : {
167 : 2601 : int i3 = 3 * i;
168 [ + - ][ + - ]: 2601 : arrays[0][i] = _coords[i3];
169 [ + - ][ + - ]: 2601 : arrays[1][i] = _coords[i3 + 1];
170 [ + - ][ + - ]: 2601 : arrays[2][i] = _coords[i3 + 2];
171 : : }
172 : : // Elements
173 : :
174 : : EntityHandle start_handle_elem_out;
175 : 1 : start_handle_elem_out = 0;
176 : : EntityHandle* conn_array_out;
177 : : result = readMeshIface->get_element_connect( _numElementsInFile, 3,
178 : : MBTRI, // EntityType
179 [ + - ]: 1 : MB_START_ID, start_handle_elem_out, conn_array_out );
180 [ - + ]: 1 : if( MB_SUCCESS != result ) return result;
181 [ + + ]: 15001 : for( int j = 0; j < _numElementsInFile * 3; j++ )
182 [ + - ]: 15000 : conn_array_out[j] = _connec[j];
183 : :
184 : : // Notify MOAB of the new elements
185 [ + - ]: 1 : result = readMeshIface->update_adjacencies( start_handle_elem_out, _numElementsInFile, 3, conn_array_out );
186 : :
187 [ - + ]: 1 : if( MB_SUCCESS != result ) return result;
188 : :
189 [ - + ]: 1 : if( file_id_tag )
190 : : {
191 [ # # ]: 0 : Range nodes( start_handle_out, start_handle_out + _numNodesInFile - 1 );
192 [ # # ]: 0 : Range elems( start_handle_elem_out, start_handle_elem_out + _numElementsInFile - 1 );
193 [ # # ]: 0 : readMeshIface->assign_ids( *file_id_tag, nodes );
194 [ # # ]: 0 : readMeshIface->assign_ids( *file_id_tag, elems );
195 : : }
196 : :
197 : 3 : return MB_SUCCESS;
198 : : }
199 : :
200 : 3 : ErrorCode ReadSmf::annotation( char* cmd, std::vector< std::string >& argv )
201 : : {
202 : : // Skip over the '#$' prefix
203 : 3 : cmd += 2;
204 : :
205 [ + + ]: 3 : if( streq( cmd, "SMF" ) )
206 : : {
207 : : // If SMF version is specified, it must be the first
208 : : // thing specified in the file.
209 [ - + ][ # # ]: 1 : if( commandNo > 1 ) { MB_SET_ERR( MB_FILE_WRITE_ERROR, "SMF file version specified at line " << lineNo ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
210 : :
211 [ + - ]: 1 : if( 2 == sscanf( argv[0].c_str(), "%d.%d", &versionMajor, &versionMinor ) )
212 : : {
213 [ + - ][ - + ]: 1 : if( versionMajor != 1 || versionMinor != 0 )
214 : : {
215 [ # # ][ # # ]: 1 : MB_SET_ERR( MB_FILE_WRITE_ERROR,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
216 : : "Unsupported SMF file version: " << versionMajor << "." << versionMinor );
217 : : }
218 : : }
219 : : else
220 : : {
221 [ # # ][ # # ]: 1 : MB_SET_ERR( MB_FILE_WRITE_ERROR, "Invalid SMF version annotation" );
[ # # ][ # # ]
[ # # ]
222 : : }
223 : : }
224 [ + + ]: 2 : else if( streq( cmd, "vertices" ) )
225 : : {
226 [ + - ]: 1 : if( argv.size() == 1 )
227 : 1 : _numNodes = atoi( argv[0].c_str() );
228 : : else
229 : 1 : bad_annotation( cmd );
230 : : }
231 [ + - ]: 1 : else if( streq( cmd, "faces" ) )
232 : : {
233 [ + - ]: 1 : if( argv.size() == 1 )
234 : 1 : _numFaces = atoi( argv[0].c_str() );
235 : : else
236 : 1 : bad_annotation( cmd );
237 : : }
238 [ # # ]: 0 : else if( streq( cmd, "BBox" ) )
239 : : {
240 : : }
241 [ # # ]: 0 : else if( streq( cmd, "BSphere" ) )
242 : : {
243 : : }
244 [ # # ]: 0 : else if( streq( cmd, "PXform" ) )
245 : : {
246 [ # # ]: 0 : if( argv.size() == 16 )
247 : : {
248 : : // parse_mat(argv);
249 : : }
250 : : else
251 : 0 : bad_annotation( cmd );
252 : : }
253 [ # # ]: 0 : else if( streq( cmd, "MXform" ) )
254 : : {
255 [ # # ]: 0 : if( argv.size() == 16 )
256 : : {
257 : : // parse_mat(argv);
258 : : }
259 : : else
260 : 0 : bad_annotation( cmd );
261 : : }
262 : :
263 : 3 : return MB_SUCCESS;
264 : : }
265 : :
266 : 7609 : ErrorCode ReadSmf::parse_line( char* ln )
267 : : {
268 : : char *cmd, *s;
269 [ + - ]: 7609 : std::vector< std::string > argv;
270 : : ErrorCode err;
271 : :
272 [ + + ][ - + ]: 7610 : while( *ln == ' ' || *ln == '\t' )
273 : 1 : ln++; // Skip initial white space
274 : :
275 : : // Ignore empty lines
276 [ + - ][ + + ]: 7609 : if( ln[0] == '\n' || ln[0] == '\0' ) return MB_SUCCESS;
277 : :
278 : : // Ignore comments
279 [ + + ][ + + ]: 7608 : if( ln[0] == '#' && ln[1] != '$' ) return MB_SUCCESS;
280 : :
281 : : // First, split the line into tokens
282 : 7605 : cmd = strtok( ln, " \t\n" );
283 : :
284 [ + + ]: 30411 : while( ( s = strtok( NULL, " \t\n" ) ) )
285 : : {
286 [ + - ]: 22806 : std::string stg( s );
287 [ + - ]: 22806 : argv.push_back( stg );
288 : 22806 : }
289 : :
290 : : // Figure out what command it is and execute it
291 [ + + ][ + - ]: 7605 : if( cmd[0] == '#' && cmd[1] == '$' )
292 : : {
293 [ + - ]: 3 : err = annotation( cmd, argv );
294 [ - + ]: 3 : if( MB_SUCCESS != err ) return err;
295 : : }
296 : : else
297 : : {
298 : 7602 : cmd_entry* entry = &read_cmds[0];
299 : 7602 : bool handled = 0;
300 : :
301 [ + + ][ + + ]: 40219 : while( entry->name && !handled )
302 : : {
303 [ + + ]: 32617 : if( streq( entry->name, cmd ) )
304 : : {
305 [ + - ][ + - ]: 7601 : err = ( this->*( entry->cmd ) )( argv );
306 [ - + ]: 7601 : if( MB_SUCCESS != err ) return err;
307 : 7601 : handled = 1;
308 : 7601 : ++commandNo;
309 : : }
310 : : else
311 : 25016 : entry++;
312 : : }
313 : :
314 [ + + ]: 7602 : if( !handled )
315 : : {
316 : : // If the first command was invalid, this probably
317 : : // wasn't an Smf file. Fail silently in this case.
318 : : // If versionMajor is set, then we saw an initial #$SMF,
319 : : // in which case it must be a SMF file.
320 [ + - ][ + - ]: 1 : if( !versionMajor && !commandNo ) return MB_FILE_WRITE_ERROR;
321 : :
322 : : // Invalid command:
323 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_UNSUPPORTED_OPERATION, "Illegal SMF command at line " << lineNo << ": \"" << cmd << "\"" );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
324 : : }
325 : : }
326 : :
327 : 7609 : return MB_SUCCESS;
328 : : }
329 : :
330 : 7601 : ErrorCode ReadSmf::check_length( int count, const std::vector< std::string >& argv )
331 : : {
332 [ + - ][ - + ]: 7601 : if( ( argv.size() < (unsigned)count ) || ( argv.size() > (unsigned)count && argv[count][0] != '#' ) )
[ # # ][ - + ]
333 [ # # ][ # # ]: 0 : { MB_SET_ERR( MB_FILE_WRITE_ERROR, "Expect " << count << " arguments at line " << lineNo ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
334 : :
335 : 7601 : return MB_SUCCESS;
336 : : }
337 : :
338 : 2601 : ErrorCode ReadSmf::parse_doubles( int count, const std::vector< std::string >& argv, double results[] )
339 : : {
340 [ + - ]: 2601 : ErrorCode rval = check_length( count, argv );
341 [ - + ]: 2601 : if( MB_SUCCESS != rval ) return rval;
342 : :
343 : : char* endptr;
344 [ + + ]: 10404 : for( int i = 0; i < count; i++ )
345 : : {
346 [ + - ]: 7803 : results[i] = strtod( argv[i].c_str(), &endptr );
347 [ - + ][ # # ]: 7803 : if( *endptr ) { MB_SET_ERR( MB_FILE_WRITE_ERROR, "Invalid vertex coordinates at line " << lineNo ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
348 : : }
349 : :
350 : 2601 : return MB_SUCCESS;
351 : : }
352 : :
353 : 2601 : ErrorCode ReadSmf::vertex( std::vector< std::string >& argv )
354 : : {
355 : : double v[3];
356 [ + - ]: 2601 : ErrorCode err = parse_doubles( 3, argv, v );
357 [ - + ]: 2601 : if( MB_SUCCESS != err ) return err;
358 : :
359 [ + - ][ + - ]: 2601 : state.back().vertex( v );
360 : 2601 : ivar.next_vertex++;
361 : 2601 : _numNodesInFile++;
362 [ + + ]: 10404 : for( int j = 0; j < 3; j++ )
363 [ + - ]: 7803 : _coords.push_back( v[j] );
364 : : // model->in_Vertex(v);
365 : 2601 : return MB_SUCCESS;
366 : : }
367 : :
368 : 0 : ErrorCode ReadSmf::v_normal( std::vector< std::string >& /*argv*/ )
369 : : {
370 : 0 : return MB_SUCCESS;
371 : : }
372 : :
373 : 0 : ErrorCode ReadSmf::v_color( std::vector< std::string >& /*argv*/ )
374 : : {
375 : 0 : return MB_SUCCESS;
376 : : }
377 : :
378 : 0 : ErrorCode ReadSmf::f_color( std::vector< std::string >& /*argv*/ )
379 : : {
380 : 0 : return MB_SUCCESS;
381 : : }
382 : :
383 : 5000 : ErrorCode ReadSmf::face( std::vector< std::string >& argv )
384 : : {
385 [ + - ]: 5000 : ErrorCode err = check_length( 3, argv );
386 [ - + ]: 5000 : if( MB_SUCCESS != err ) return err;
387 : :
388 : 5000 : int vert[3] = {};
389 : : char* endptr;
390 [ + + ]: 20000 : for( unsigned int i = 0; i < argv.size(); i++ )
391 : : {
392 [ + - ]: 15000 : vert[i] = strtol( argv[i].c_str(), &endptr, 0 );
393 [ - + ][ # # ]: 15000 : if( *endptr ) { MB_SET_ERR( MB_FILE_WRITE_ERROR, "Invalid face spec at line " << lineNo ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
394 : : }
395 : :
396 [ + - ][ + - ]: 5000 : state.back().face( vert, ivar );
397 : 5000 : ivar.next_face++;
398 [ + + ]: 20000 : for( int j = 0; j < 3; j++ )
399 [ + - ]: 15000 : _connec.push_back( vert[j] );
400 : 5000 : _numElementsInFile++;
401 : :
402 : 5000 : return MB_SUCCESS;
403 : : }
404 : :
405 : 0 : ErrorCode ReadSmf::begin( std::vector< std::string >& /*argv*/ )
406 : : {
407 [ # # ]: 0 : state.push_back( SMF_State( ivar, &state.back() ) );
408 : :
409 : 0 : return MB_SUCCESS;
410 : : }
411 : :
412 : 0 : ErrorCode ReadSmf::end( std::vector< std::string >& /*argv*/ )
413 : : {
414 : : // There must always be at least one state on the stack.
415 : : // Don't let mismatched begin/end statements cause us
416 : : // to read from an empty vector.
417 [ # # ][ # # ]: 0 : if( state.size() == 1 ) { MB_SET_ERR( MB_FILE_WRITE_ERROR, "End w/out Begin at line " << lineNo ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
418 : :
419 : 0 : state.pop_back();
420 : :
421 : 0 : return MB_SUCCESS;
422 : : }
423 : :
424 : 0 : ErrorCode ReadSmf::set( std::vector< std::string >& argv )
425 : : {
426 [ # # ][ # # ]: 0 : if( argv.size() < 2 || argv[0] != "vertex_coorection" ) return MB_SUCCESS;
[ # # ][ # # ]
[ # # ]
427 : :
428 : : char* endptr;
429 [ # # ]: 0 : int val = strtol( argv[1].c_str(), &endptr, 0 );
430 [ # # ][ # # ]: 0 : if( *endptr ) { MB_SET_ERR( MB_FILE_WRITE_ERROR, "Invalid value at line " << lineNo ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
431 : :
432 [ # # ][ # # ]: 0 : state.back().set_vertex_correction( val );
433 : :
434 : 0 : return MB_SUCCESS;
435 : : }
436 : :
437 : 0 : ErrorCode ReadSmf::inc( std::vector< std::string >& /*argv*/ )
438 : : {
439 : : // std::cerr << "SMF: INC not yet implemented." << std::endl;
440 : 0 : return MB_SUCCESS;
441 : : }
442 : :
443 : 0 : ErrorCode ReadSmf::dec( std::vector< std::string >& )
444 : : {
445 : : // std::cerr << "SMF: DEC not yet implemented." << std::endl;
446 : 0 : return MB_SUCCESS;
447 : : }
448 : :
449 : 0 : ErrorCode ReadSmf::trans( std::vector< std::string >& argv )
450 : : {
451 : : double v3[3];
452 [ # # ]: 0 : ErrorCode err = parse_doubles( 3, argv, v3 );
453 [ # # ]: 0 : if( MB_SUCCESS != err ) return err;
454 : :
455 [ # # ]: 0 : AffineXform M = AffineXform::translation( v3 );
456 : : // Mat4 M = Mat4::trans(atof(argv(0)), atof(argv(1)), atof(argv(2)));
457 [ # # ][ # # ]: 0 : state.back().mmult( M );
458 : :
459 : 0 : return MB_SUCCESS;
460 : : }
461 : :
462 : 0 : ErrorCode ReadSmf::scale( std::vector< std::string >& argv )
463 : : {
464 : : double v3[3];
465 [ # # ]: 0 : ErrorCode err = parse_doubles( 3, argv, v3 );
466 [ # # ]: 0 : if( MB_SUCCESS != err ) return err;
467 : :
468 [ # # ]: 0 : AffineXform M = AffineXform::scale( v3 );
469 : : // Mat4 M = Mat4::scale(atof(argv(0)), atof(argv(1)), atof(argv(2)));
470 [ # # ][ # # ]: 0 : state.back().mmult( M );
471 : :
472 : 0 : return MB_SUCCESS;
473 : : }
474 : :
475 : 0 : ErrorCode ReadSmf::rot( std::vector< std::string >& argv )
476 : : {
477 [ # # ]: 0 : ErrorCode err = check_length( 2, argv );
478 [ # # ]: 0 : if( MB_SUCCESS != err ) return err;
479 : :
480 : 0 : double axis[3] = { 0., 0., 0. };
481 [ # # ][ # # ]: 0 : std::string axisname = argv.front();
482 [ # # ]: 0 : argv.erase( argv.begin() );
483 [ # # ][ # # ]: 0 : if( axisname.size() != 1 ) { MB_SET_ERR( MB_FILE_WRITE_ERROR, "Malformed rotation command at line " << lineNo ); }
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
484 [ # # ]: 0 : switch( axisname[0] )
[ # # # # ]
485 : : {
486 : : case 'x':
487 : 0 : axis[0] = 1.;
488 : 0 : break;
489 : : case 'y':
490 : 0 : axis[1] = 1.;
491 : 0 : break;
492 : : case 'z':
493 : 0 : axis[2] = 1.;
494 : 0 : break;
495 : : default:
496 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FILE_WRITE_ERROR, "Malformed rotation command at line " << lineNo );
[ # # ][ # # ]
[ # # ][ # # ]
497 : : }
498 : :
499 : : double angle;
500 [ # # ]: 0 : err = parse_doubles( 1, argv, &angle );
501 [ # # ]: 0 : if( MB_SUCCESS != err ) return err;
502 : 0 : angle *= M_PI / 180.0;
503 : :
504 [ # # ]: 0 : AffineXform M = AffineXform::rotation( angle, axis );
505 [ # # ][ # # ]: 0 : state.back().mmult( M );
506 : :
507 : 0 : return MB_SUCCESS;
508 : : }
509 : :
510 : 0 : ErrorCode ReadSmf::mmult( std::vector< std::string >& argv )
511 : : {
512 [ # # ]: 0 : AffineXform mat;
513 [ # # ]: 0 : ErrorCode rval = parse_mat( argv, mat );
514 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
515 : :
516 [ # # ][ # # ]: 0 : state.back().mmult( mat );
517 : :
518 : 0 : return MB_SUCCESS;
519 : : }
520 : :
521 : 0 : ErrorCode ReadSmf::mload( std::vector< std::string >& argv )
522 : : {
523 [ # # ]: 0 : AffineXform mat;
524 [ # # ]: 0 : ErrorCode rval = parse_mat( argv, mat );
525 [ # # ]: 0 : if( MB_SUCCESS != rval ) return rval;
526 : :
527 [ # # ][ # # ]: 0 : state.back().mload( mat );
528 : :
529 : 0 : return MB_SUCCESS;
530 : : }
531 : :
532 [ + - ][ + - ]: 228 : } // namespace moab
|