MOAB: Mesh Oriented datABase
(version 5.4.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 #include "moab/Core.hpp" 00017 00018 #include "moab/ReaderWriterSet.hpp" 00019 #include "moab/ReaderIface.hpp" 00020 #include "moab/WriterIface.hpp" 00021 00022 #include "ReadVtk.hpp" 00023 #include "ReadSTL.hpp" 00024 #include "ReadGmsh.hpp" 00025 #include "ReadIDEAS.hpp" 00026 #include "ReadMCNP5.hpp" 00027 #include "ReadOBJ.hpp" 00028 #include "ReadNASTRAN.hpp" 00029 #include "ReadRTT.hpp" 00030 #include "ReadABAQUS.hpp" 00031 #include "ReadSms.hpp" 00032 #include "Tqdcfr.hpp" 00033 #include "ReadTetGen.hpp" 00034 #include "ReadSmf.hpp" 00035 #include "ReadTemplate.hpp" 00036 #ifdef MOAB_HAVE_CGM 00037 #include "ReadCGM.hpp" 00038 #endif 00039 00040 #include "WriteAns.hpp" 00041 #include "WriteVtk.hpp" 00042 #include "WriteGMV.hpp" 00043 #include "WriteSTL.hpp" 00044 #include "WriteGmsh.hpp" 00045 #include "WriteSmf.hpp" 00046 #include "WriteTemplate.hpp" 00047 00048 #ifdef MOAB_HAVE_NETCDF 00049 #include "ReadNCDF.hpp" 00050 #include "WriteNCDF.hpp" 00051 #include "WriteNC.hpp" 00052 #include "WriteSLAC.hpp" 00053 #include "ReadNC.hpp" 00054 #endif 00055 00056 // 2nd include of ReadNC in case we have pnetcdf and not netcdf 00057 #if defined( MOAB_HAVE_PNETCDF ) && !defined( MOAB_HAVE_NETCDF ) 00058 #include "ReadNC.hpp" 00059 #endif 00060 00061 #ifdef MOAB_HAVE_CGNS 00062 #include "ReadCGNS.hpp" 00063 #include "WriteCGNS.hpp" 00064 #endif 00065 00066 #ifdef MOAB_HAVE_CCMIO 00067 #include "ReadCCMIO.hpp" 00068 #include "WriteCCMIO.hpp" 00069 #endif 00070 00071 #ifdef MOAB_HAVE_DAMSEL 00072 #include "WriteDamsel.hpp" 00073 #include "ReadDamsel.hpp" 00074 #endif 00075 00076 #ifdef MOAB_HAVE_HDF5 00077 #include "ReadHDF5.hpp" 00078 #ifdef MOAB_HAVE_HDF5_PARALLEL 00079 #include "WriteHDF5Parallel.hpp" 00080 #else 00081 #include "WriteHDF5.hpp" 00082 #endif 00083 #endif 00084 00085 #include <algorithm> 00086 00087 namespace moab 00088 { 00089 00090 ReaderWriterSet::ReaderWriterSet( Core* mdb ) : mbCore( mdb ) 00091 { 00092 #ifdef MOAB_HAVE_HDF5 00093 const char* hdf5_sufxs[] = { "h5m", "mhdf", NULL }; 00094 #ifdef MOAB_HAVE_HDF5_PARALLEL 00095 register_factory( ReadHDF5::factory, WriteHDF5Parallel::factory, "MOAB native (HDF5)", hdf5_sufxs, "MOAB" ); 00096 #else 00097 register_factory( ReadHDF5::factory, WriteHDF5::factory, "MOAB native (HDF5)", hdf5_sufxs, "MOAB" ); 00098 #endif 00099 #endif 00100 00101 #ifdef MOAB_HAVE_NETCDF 00102 const char* exo_sufxs[] = { "exo", "exoII", "exo2", "g", "gen", NULL }; 00103 register_factory( ReadNCDF::factory, WriteNCDF::factory, "Exodus II", exo_sufxs, "EXODUS" ); 00104 register_factory( ReadNC::factory, WriteNC::factory, "Climate NC", "nc", "NC" ); 00105 #endif 00106 00107 #ifdef MOAB_HAVE_CGNS 00108 const char* cgns_sufxs[] = { "cgns", NULL }; 00109 register_factory( ReadCGNS::factory, WriteCGNS::factory, "CGNS", cgns_sufxs, "CGNS" ); 00110 #endif 00111 00112 register_factory( ReadIDEAS::factory, NULL, "IDEAS format", "unv", "UNV" ); 00113 00114 register_factory( ReadMCNP5::factory, NULL, "MCNP5 format", "meshtal", "MESHTAL" ); 00115 00116 const char* nastran_sufxs[] = { "nas", "bdf", NULL }; 00117 register_factory( ReadNASTRAN::factory, NULL, "NASTRAN format", nastran_sufxs, "NAS" ); 00118 00119 register_factory( ReadABAQUS::factory, NULL, "ABAQUS INP mesh format", "abq", "Abaqus mesh" ); 00120 00121 register_factory( ReadRTT::factory, NULL, "RTT Mesh Format", "rtt", "Atilla RTT Mesh" ); 00122 00123 register_factory( ReadVtk::factory, WriteVtk::factory, "Kitware VTK", "vtk", "VTK" ); 00124 00125 register_factory( ReadOBJ::factory, NULL, "OBJ mesh format", "obj", "OBJ mesh" ); 00126 00127 register_factory( ReadSms::factory, NULL, "RPI SMS", "sms", "SMS" ); 00128 00129 register_factory( Tqdcfr::factory, NULL, "Cubit", "cub", "CUBIT" ); 00130 00131 register_factory( ReadSmf::factory, WriteSmf::factory, "QSlim format", "smf", "SMF" ); 00132 #ifdef MOAB_HAVE_CGM_FACET 00133 const char* facet_sufxs[] = { "facet", NULL }; 00134 register_factory( ReadCGM::factory, NULL, "Facet Engine Solid Model", facet_sufxs, "facet" ); 00135 #endif 00136 #ifdef MOAB_HAVE_CGM_OCC 00137 const char* occ_sufxs[] = { "brep", "occ", NULL }; 00138 const char* step_sufxs[] = { "step", "stp", NULL }; 00139 const char* iges_sufxs[] = { "iges", "igs", NULL }; 00140 register_factory( ReadCGM::factory, NULL, "OpenCascade solid model", occ_sufxs, "OCC" ); 00141 register_factory( ReadCGM::factory, NULL, "STEP B-Rep exchange", step_sufxs, "STEP" ); 00142 register_factory( ReadCGM::factory, NULL, "IGES B-Rep exchange", iges_sufxs, "IGES" ); 00143 #endif 00144 00145 #ifdef MOAB_HAVE_NETCDF 00146 register_factory( NULL, WriteSLAC::factory, "SLAC", "slac", "SLAC" ); 00147 #endif 00148 00149 #ifdef MOAB_HAVE_CCMIO 00150 const char* ccmio_sufxs[] = { "ccm", "ccmg", NULL }; 00151 register_factory( ReadCCMIO::factory, WriteCCMIO::factory, "CCMIO files", ccmio_sufxs, "CCMIO" ); 00152 #endif 00153 00154 #ifdef MOAB_HAVE_DAMSEL 00155 const char* damsel_sufxs[] = { "h5", NULL }; 00156 register_factory( ReadDamsel::factory, WriteDamsel::factory, "Damsel files", damsel_sufxs, "DAMSEL" ); 00157 #endif 00158 00159 register_factory( NULL, WriteGMV::factory, "GMV", "gmv", "GMV" ); 00160 00161 register_factory( NULL, WriteAns::factory, "Ansys", "ans", "ANSYS" ); 00162 00163 const char* gmsh_sufxs[] = { "msh", "gmsh", NULL }; 00164 register_factory( ReadGmsh::factory, WriteGmsh::factory, "Gmsh mesh file", gmsh_sufxs, "GMSH" ); 00165 00166 register_factory( ReadSTL::factory, WriteSTL::factory, "Stereo Lithography File (STL)", "stl", "STL" ); 00167 00168 const char* tetgen_sufxs[] = { "node", "ele", "face", "edge", NULL }; 00169 register_factory( ReadTetGen::factory, 0, "TetGen output files", tetgen_sufxs, "TETGEN" ); 00170 00171 const char* template_sufxs[] = { NULL }; 00172 register_factory( ReadTemplate::factory, WriteTemplate::factory, "Template input files", template_sufxs, 00173 "TEMPLATE" ); 00174 } 00175 00176 ReaderWriterSet::~ReaderWriterSet() {} 00177 00178 ErrorCode ReaderWriterSet::register_factory( reader_factory_t reader, 00179 writer_factory_t writer, 00180 const char* description, 00181 const char* const* extensions, 00182 const char* name ) 00183 { 00184 if( !reader && !writer ) return MB_FAILURE; 00185 00186 // check for duplicate names 00187 iterator h = handler_by_name( name ); 00188 if( h != end() ) 00189 { 00190 MB_SET_ERR( MB_FAILURE, "Conflicting string name for file formats: \"" << name << "\"" ); 00191 } 00192 00193 // count extensions and check for duplicates 00194 const char* const* iter; 00195 for( iter = extensions; *iter; ++iter ) 00196 { 00197 h = handler_from_extension( *iter ); 00198 if( h != end() ) 00199 { 00200 if( NULL != reader && h->have_reader() ) 00201 MB_SET_ERR( MB_FAILURE, "Conflicting readers for file extension \"" 00202 << *iter << "\": \"" << h->description() << "\" and \"" << description 00203 << "\"." ); 00204 else if( NULL != writer && h->have_writer() ) 00205 MB_SET_ERR( MB_FAILURE, "Conflicting writers for file extension \"" 00206 << *iter << "\": \"" << h->description() << "\" and \"" << description 00207 << "\"." ); 00208 } 00209 } 00210 handlerList.push_back( Handler( reader, writer, name, description, extensions, iter - extensions ) ); 00211 return MB_SUCCESS; 00212 } 00213 00214 ErrorCode ReaderWriterSet::register_factory( reader_factory_t reader, 00215 writer_factory_t writer, 00216 const char* description, 00217 const char* extension, 00218 const char* name ) 00219 { 00220 const char* extensions[2] = { extension, NULL }; 00221 return register_factory( reader, writer, description, extensions, name ); 00222 } 00223 00224 ReaderIface* ReaderWriterSet::get_file_extension_reader( const std::string& filename ) const 00225 { 00226 std::string ext = extension_from_filename( filename ); 00227 iterator handler = handler_from_extension( ext, true, false ); 00228 return handler == end() ? NULL : handler->make_reader( mbCore ); 00229 } 00230 00231 WriterIface* ReaderWriterSet::get_file_extension_writer( const std::string& filename ) const 00232 { 00233 std::string ext = extension_from_filename( filename ); 00234 iterator handler = handler_from_extension( ext, false, true ); 00235 return handler == end() ? NULL : handler->make_writer( mbCore ); 00236 } 00237 00238 std::string ReaderWriterSet::extension_from_filename( const std::string& filename ) 00239 { 00240 std::string::size_type idx = filename.find_last_of( "." ); 00241 std::string::size_type idirx = filename.find_last_of( "\\/" ); 00242 00243 if( idx == std::string::npos ) return std::string( "" ); 00244 if( ( idirx != std::string::npos ) && ( idirx > idx ) ) return std::string( "" ); 00245 return filename.substr( idx + 1 ); 00246 } 00247 00248 ReaderWriterSet::Handler::Handler( reader_factory_t read_f, 00249 writer_factory_t write_f, 00250 const char* nm, 00251 const char* desc, 00252 const char* const* ext, 00253 int num_ext ) 00254 : mReader( read_f ), mWriter( write_f ), mName( nm ), mDescription( desc ), mExtensions( num_ext ) 00255 { 00256 for( int i = 0; i < num_ext; ++i ) 00257 mExtensions[i] = ext[i]; 00258 } 00259 00260 #ifdef WIN32 00261 #define strcasecmp( A, B ) _stricmp( A, B ) 00262 #endif 00263 00264 ReaderWriterSet::iterator ReaderWriterSet::handler_from_extension( const std::string& ext, 00265 bool with_reader, 00266 bool with_writer ) const 00267 { 00268 iterator iter; 00269 std::vector< std::string >::const_iterator siter; 00270 00271 // try case-sensitive compare 00272 for( iter = begin(); iter != end(); ++iter ) 00273 { 00274 if( ( with_reader && !iter->have_reader() ) || ( with_writer && !iter->have_writer() ) ) continue; 00275 00276 for( siter = iter->mExtensions.begin(); siter != iter->mExtensions.end(); ++siter ) 00277 if( *siter == ext ) return iter; 00278 } 00279 00280 // try case-insensitive compare 00281 for( iter = begin(); iter != end(); ++iter ) 00282 { 00283 if( ( with_reader && !iter->have_reader() ) || ( with_writer && !iter->have_writer() ) ) continue; 00284 00285 for( siter = iter->mExtensions.begin(); siter != iter->mExtensions.end(); ++siter ) 00286 if( 0 == strcasecmp( siter->c_str(), ext.c_str() ) ) return iter; 00287 } 00288 00289 return end(); 00290 } 00291 00292 bool ReaderWriterSet::Handler::reads_extension( const char* ext ) const 00293 { 00294 if( !have_reader() ) return false; 00295 00296 std::vector< std::string >::const_iterator siter; 00297 for( siter = mExtensions.begin(); siter != mExtensions.end(); ++siter ) 00298 if( !( *siter ).compare( ext ) ) 00299 return true; 00300 else if( 0 == strcasecmp( siter->c_str(), ext ) ) 00301 return true; 00302 00303 return false; 00304 } 00305 00306 bool ReaderWriterSet::Handler::writes_extension( const char* ext ) const 00307 { 00308 if( !have_writer() ) return false; 00309 00310 std::vector< std::string >::const_iterator siter; 00311 for( siter = mExtensions.begin(); siter != mExtensions.end(); ++siter ) 00312 if( !( *siter ).compare( ext ) ) 00313 return true; 00314 else if( 0 == strcasecmp( siter->c_str(), ext ) ) 00315 return true; 00316 00317 return false; 00318 } 00319 00320 ReaderWriterSet::iterator ReaderWriterSet::handler_by_name( const char* nm ) const 00321 { 00322 return std::find( begin(), end(), nm ); 00323 } 00324 00325 bool ReaderWriterSet::Handler::operator==( const char* nm ) const 00326 { 00327 // do case-insensitive comparison 00328 std::string::const_iterator siter = mName.begin(); 00329 for( ; *nm; ++nm, ++siter ) 00330 if( siter == mName.end() || tolower( *nm ) != tolower( *siter ) ) return false; 00331 return *nm == '\0'; 00332 } 00333 00334 } // namespace moab