Mesh Oriented datABase  (version 5.4.1)
Array-based unstructured mesh datastructure
ReaderWriterSet.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines