![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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
00027 #include
00028 #include
00029 #include
00030 #include
00031 #include
00032 #include
00033 #include
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,
00066 const bool overwrite,
00067 const FileOptions& opts,
00068 const EntityHandle* output_list,
00069 const int num_sets,
00070 const std::vector< std::string >& /* qa_list */,
00071 const Tag* /* tag_list */,
00072 int /* num_tags */,
00073 int /* export_dimension */ )
00074 {
00075 ErrorCode rval;
00076
00077 // Get precision for node coordinates
00078 int precision;
00079 if( MB_SUCCESS != opts.get_int_option( "PRECISION", precision ) ) precision = DEFAULT_PRECISION;
00080
00081 // Honor overwrite flag
00082 if( !overwrite )
00083 {
00084 rval = writeTool->check_doesnt_exist( file_name );
00085 if( MB_SUCCESS != rval ) return rval;
00086 }
00087
00088 // Create file
00089 std::ofstream file( file_name );
00090 if( !file )
00091 {
00092 MB_SET_ERR( MB_FILE_WRITE_ERROR, "Could not open file: " << file_name );
00093 }
00094 file.precision( precision );
00095
00096 // Get entities to write
00097 Range triangles;
00098 if( !output_list || !num_sets )
00099 {
00100 rval = mbImpl->get_entities_by_type( 0, MBTRI, triangles, false );
00101 if( MB_SUCCESS != rval ) return rval;
00102
00103 // Somehow get all the nodes from this range, order them, uniquify, then use binary search
00104 }
00105 else
00106 {
00107 // Get all triangles from output sets
00108 for( int i = 0; i < num_sets; i++ )
00109 rval = mbImpl->get_entities_by_type( output_list[i], MBTRI, triangles, false );
00110 }
00111 // Use an array with all the connectivities in the triangles; it will be converted later to ints
00112 int numTriangles = triangles.size();
00113 int array_alloc = 3 * numTriangles; // Allocated size of 'array'
00114 EntityHandle* array = new EntityHandle[array_alloc]; // ptr to working array of result handles
00115 // Fill up array with node handles; reorder and uniquify
00116 if( !array ) return MB_MEMORY_ALLOCATION_FAILED;
00117 int fillA = 0;
00118 for( Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e )
00119 {
00120 const EntityHandle* conn;
00121 int conn_len;
00122 rval = mbImpl->get_connectivity( *e, conn, conn_len );
00123 if( MB_SUCCESS != rval )
00124 {
00125 delete[] array;
00126 return rval;
00127 }
00128 if( 3 != conn_len )
00129 {
00130 delete[] array;
00131 return MB_INVALID_SIZE;
00132 }
00133
00134 for( int i = 0; i < conn_len; ++i )
00135 array[fillA++] = conn[i];
00136 }
00137 if( fillA != array_alloc )
00138 {
00139 delete[] array;
00140 return MB_INVALID_SIZE;
00141 }
00142
00143 std::sort( array, array + array_alloc );
00144 int numNodes = std::unique( array, array + array_alloc ) - array;
00145
00146 file << "#$SMF 1.0\n";
00147 file << "#$vertices " << numNodes << std::endl;
00148 file << "#$faces " << numTriangles << std::endl;
00149 file << "# \n";
00150 file << "# output from MOAB \n";
00151 file << "# \n";
00152
00153 // Output first the nodes
00154 // num nodes??
00155 // Write the nodes
00156 double coord[3];
00157 for( int i = 0; i < numNodes; i++ )
00158 {
00159 EntityHandle node_handle = array[i];
00160
00161 rval = mbImpl->get_coords( &node_handle, 1, coord );
00162 if( rval != MB_SUCCESS )
00163 {
00164 delete[] array;
00165 return rval;
00166 }
00167
00168 file << "v " << coord[0] << " " << coord[1] << " " << coord[2] << std::endl;
00169 }
00170 // Write faces now
00171 // Leave a blank line for cosmetics
00172 file << " \n";
00173 for( Range::const_iterator e = triangles.begin(); e != triangles.end(); ++e )
00174 {
00175 const EntityHandle* conn;
00176 int conn_len;
00177 rval = mbImpl->get_connectivity( *e, conn, conn_len );
00178 if( MB_SUCCESS != rval )
00179 {
00180 delete[] array;
00181 return rval;
00182 }
00183 if( 3 != conn_len )
00184 {
00185 delete[] array;
00186 return MB_INVALID_SIZE;
00187 }
00188 file << "f ";
00189 for( int i = 0; i < conn_len; ++i )
00190 {
00191 int indexInArray = std::lower_bound( array, array + numNodes, conn[i] ) - array;
00192 file << indexInArray + 1 << " ";
00193 }
00194 file << std::endl;
00195 }
00196
00197 file.close();
00198 delete[] array;
00199 return MB_SUCCESS;
00200 }
00201
00202 } // namespace moab