MOAB: Mesh Oriented datABase
(version 5.2.1)
|
00001 /** 00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating, 00003 * storing and accessing finite element mesh data. 00004 * 00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract 00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 00007 * retains certain rights in this software. 00008 * 00009 * This library is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 */ 00015 00016 #ifdef WIN32 00017 #ifdef _DEBUG 00018 // turn off warnings that say they debugging identifier has been truncated 00019 // this warning comes up when using some STL containers 00020 #pragma warning( disable : 4786 ) 00021 #endif 00022 #endif 00023 00024 #include "WriteSmf.hpp" 00025 00026 #include <fstream> 00027 #include <iostream> 00028 #include <stdio.h> 00029 #include <assert.h> 00030 #include <vector> 00031 #include <set> 00032 #include <iterator> 00033 #include <algorithm> 00034 00035 #include "moab/Interface.hpp" 00036 #include "moab/Range.hpp" 00037 #include "moab/CN.hpp" 00038 #include "MBTagConventions.hpp" 00039 #include "moab/WriteUtilIface.hpp" 00040 #include "Internals.hpp" 00041 #include "moab/FileOptions.hpp" 00042 00043 namespace moab 00044 { 00045 00046 const int DEFAULT_PRECISION = 10; 00047 // const bool DEFAULT_STRICT = true; 00048 00049 WriterIface* WriteSmf::factory( Interface* iface ) 00050 { 00051 return new WriteSmf( iface ); 00052 } 00053 00054 WriteSmf::WriteSmf( Interface* impl ) : mbImpl( impl ), writeTool( 0 ) 00055 { 00056 assert( impl != NULL ); 00057 impl->query_interface( writeTool ); 00058 } 00059 00060 WriteSmf::~WriteSmf() 00061 { 00062 mbImpl->release_interface( writeTool ); 00063 } 00064 00065 ErrorCode WriteSmf::write_file( const char* file_name, const bool overwrite, const FileOptions& opts, 00066 const EntityHandle* output_list, const int num_sets, 00067 const std::vector< std::string >& /* qa_list */, const Tag* /* tag_list */, 00068 int /* num_tags */, int /* export_dimension */ ) 00069 { 00070 ErrorCode rval; 00071 00072 // Get precision for node coordinates 00073 int precision; 00074 if( MB_SUCCESS != opts.get_int_option( "PRECISION", precision ) ) precision = DEFAULT_PRECISION; 00075 00076 // Honor overwrite flag 00077 if( !overwrite ) 00078 { 00079 rval = writeTool->check_doesnt_exist( file_name ); 00080 if( MB_SUCCESS != rval ) return rval; 00081 } 00082 00083 // Create file 00084 std::ofstream file( file_name ); 00085 if( !file ) { MB_SET_ERR( MB_FILE_WRITE_ERROR, "Could not open file: " << file_name ); } 00086 file.precision( precision ); 00087 00088 // Get entities to write 00089 Range triangles; 00090 if( !output_list || !num_sets ) 00091 { 00092 rval = mbImpl->get_entities_by_type( 0, MBTRI, triangles, false ); 00093 if( MB_SUCCESS != rval ) return rval; 00094 00095 // Somehow get all the nodes from this range, order them, uniquify, then use binary search 00096 } 00097 else 00098 { 00099 // Get all triangles from output sets 00100 for( int i = 0; i < num_sets; i++ ) 00101 rval = mbImpl->get_entities_by_type( output_list[i], MBTRI, triangles, false ); 00102 } 00103 // Use an array with all the connectivities in the triangles; it will be converted later to ints 00104 int numTriangles = triangles.size(); 00105 int array_alloc = 3 * numTriangles; // Allocated size of 'array' 00106 EntityHandle* array = new EntityHandle[array_alloc]; // ptr to working array of result handles 00107 // Fill up array with node handles; reorder and uniquify 00108 if( !array ) return MB_MEMORY_ALLOCATION_FAILED; 00109 int fillA = 0; 00110 for( Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e ) 00111 { 00112 const EntityHandle* conn; 00113 int conn_len; 00114 rval = mbImpl->get_connectivity( *e, conn, conn_len ); 00115 if( MB_SUCCESS != rval ) 00116 { 00117 delete[] array; 00118 return rval; 00119 } 00120 if( 3 != conn_len ) 00121 { 00122 delete[] array; 00123 return MB_INVALID_SIZE; 00124 } 00125 00126 for( int i = 0; i < conn_len; ++i ) 00127 array[fillA++] = conn[i]; 00128 } 00129 if( fillA != array_alloc ) 00130 { 00131 delete[] array; 00132 return MB_INVALID_SIZE; 00133 } 00134 00135 std::sort( array, array + array_alloc ); 00136 int numNodes = std::unique( array, array + array_alloc ) - array; 00137 00138 file << "#$SMF 1.0\n"; 00139 file << "#$vertices " << numNodes << std::endl; 00140 file << "#$faces " << numTriangles << std::endl; 00141 file << "# \n"; 00142 file << "# output from MOAB \n"; 00143 file << "# \n"; 00144 00145 // Output first the nodes 00146 // num nodes?? 00147 // Write the nodes 00148 double coord[3]; 00149 for( int i = 0; i < numNodes; i++ ) 00150 { 00151 EntityHandle node_handle = array[i]; 00152 00153 rval = mbImpl->get_coords( &node_handle, 1, coord ); 00154 if( rval != MB_SUCCESS ) 00155 { 00156 delete[] array; 00157 return rval; 00158 } 00159 00160 file << "v " << coord[0] << " " << coord[1] << " " << coord[2] << std::endl; 00161 } 00162 // Write faces now 00163 // Leave a blank line for cosmetics 00164 file << " \n"; 00165 for( Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e ) 00166 { 00167 const EntityHandle* conn; 00168 int conn_len; 00169 rval = mbImpl->get_connectivity( *e, conn, conn_len ); 00170 if( MB_SUCCESS != rval ) 00171 { 00172 delete[] array; 00173 return rval; 00174 } 00175 if( 3 != conn_len ) 00176 { 00177 delete[] array; 00178 return MB_INVALID_SIZE; 00179 } 00180 file << "f "; 00181 for( int i = 0; i < conn_len; ++i ) 00182 { 00183 int indexInArray = std::lower_bound( array, array + numNodes, conn[i] ) - array; 00184 file << indexInArray + 1 << " "; 00185 } 00186 file << std::endl; 00187 } 00188 00189 file.close(); 00190 delete[] array; 00191 return MB_SUCCESS; 00192 } 00193 00194 } // namespace moab