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 : : #include "moab/Core.hpp"
17 : :
18 : : #include "moab/ReaderWriterSet.hpp"
19 : : #include "moab/ReaderIface.hpp"
20 : : #include "moab/WriterIface.hpp"
21 : :
22 : : #include "ReadVtk.hpp"
23 : : #include "ReadSTL.hpp"
24 : : #include "ReadGmsh.hpp"
25 : : #include "ReadIDEAS.hpp"
26 : : #include "ReadMCNP5.hpp"
27 : : #include "ReadOBJ.hpp"
28 : : #include "ReadNASTRAN.hpp"
29 : : #include "ReadRTT.hpp"
30 : : #include "ReadABAQUS.hpp"
31 : : #include "ReadSms.hpp"
32 : : #include "Tqdcfr.hpp"
33 : : #include "ReadTetGen.hpp"
34 : : #include "ReadSmf.hpp"
35 : : #include "ReadTemplate.hpp"
36 : : #ifdef MOAB_HAVE_CGM
37 : : #include "ReadCGM.hpp"
38 : : #endif
39 : :
40 : : #include "WriteAns.hpp"
41 : : #include "WriteVtk.hpp"
42 : : #include "WriteGMV.hpp"
43 : : #include "WriteSTL.hpp"
44 : : #include "WriteGmsh.hpp"
45 : : #include "WriteSmf.hpp"
46 : : #include "WriteTemplate.hpp"
47 : :
48 : : #ifdef MOAB_HAVE_NETCDF
49 : : #include "ReadNCDF.hpp"
50 : : #include "WriteNCDF.hpp"
51 : : #include "WriteNC.hpp"
52 : : #include "WriteSLAC.hpp"
53 : : #include "ReadNC.hpp"
54 : : #endif
55 : :
56 : : // 2nd include of ReadNC in case we have pnetcdf and not netcdf
57 : : #if defined( MOAB_HAVE_PNETCDF ) && !defined( MOAB_HAVE_NETCDF )
58 : : #include "ReadNC.hpp"
59 : : #endif
60 : :
61 : : #ifdef MOAB_HAVE_CGNS
62 : : #include "ReadCGNS.hpp"
63 : : #include "WriteCGNS.hpp"
64 : : #endif
65 : :
66 : : #ifdef MOAB_HAVE_CCMIO
67 : : #include "ReadCCMIO.hpp"
68 : : #include "WriteCCMIO.hpp"
69 : : #endif
70 : :
71 : : #ifdef MOAB_HAVE_DAMSEL
72 : : #include "WriteDamsel.hpp"
73 : : #include "ReadDamsel.hpp"
74 : : #endif
75 : :
76 : : #ifdef MOAB_HAVE_HDF5
77 : : #include "ReadHDF5.hpp"
78 : : #ifdef MOAB_HAVE_HDF5_PARALLEL
79 : : #include "WriteHDF5Parallel.hpp"
80 : : #else
81 : : #include "WriteHDF5.hpp"
82 : : #endif
83 : : #endif
84 : :
85 : : #include <algorithm>
86 : :
87 : : namespace moab
88 : : {
89 : :
90 : 744 : ReaderWriterSet::ReaderWriterSet( Core* mdb ) : mbCore( mdb )
91 : : {
92 : : #ifdef MOAB_HAVE_HDF5
93 : 372 : const char* hdf5_sufxs[] = { "h5m", "mhdf", NULL };
94 : : #ifdef MOAB_HAVE_HDF5_PARALLEL
95 : : register_factory( ReadHDF5::factory, WriteHDF5Parallel::factory, "MOAB native (HDF5)", hdf5_sufxs, "MOAB" );
96 : : #else
97 [ + - ]: 372 : register_factory( ReadHDF5::factory, WriteHDF5::factory, "MOAB native (HDF5)", hdf5_sufxs, "MOAB" );
98 : : #endif
99 : : #endif
100 : :
101 : : #ifdef MOAB_HAVE_NETCDF
102 : 372 : const char* exo_sufxs[] = { "exo", "exoII", "exo2", "g", "gen", NULL };
103 [ + - ]: 372 : register_factory( ReadNCDF::factory, WriteNCDF::factory, "Exodus II", exo_sufxs, "EXODUS" );
104 [ + - ]: 372 : register_factory( ReadNC::factory, WriteNC::factory, "Climate NC", "nc", "NC" );
105 : : #endif
106 : :
107 : : #ifdef MOAB_HAVE_CGNS
108 : : const char* cgns_sufxs[] = { "cgns", NULL };
109 : : register_factory( ReadCGNS::factory, WriteCGNS::factory, "CGNS", cgns_sufxs, "CGNS" );
110 : : #endif
111 : :
112 [ + - ]: 372 : register_factory( ReadIDEAS::factory, NULL, "IDEAS format", "unv", "UNV" );
113 : :
114 [ + - ]: 372 : register_factory( ReadMCNP5::factory, NULL, "MCNP5 format", "meshtal", "MESHTAL" );
115 : :
116 : 372 : const char* nastran_sufxs[] = { "nas", "bdf", NULL };
117 [ + - ]: 372 : register_factory( ReadNASTRAN::factory, NULL, "NASTRAN format", nastran_sufxs, "NAS" );
118 : :
119 [ + - ]: 372 : register_factory( ReadABAQUS::factory, NULL, "ABAQUS INP mesh format", "abq", "Abaqus mesh" );
120 : :
121 [ + - ]: 372 : register_factory( ReadRTT::factory, NULL, "RTT Mesh Format", "rtt", "Atilla RTT Mesh" );
122 : :
123 [ + - ]: 372 : register_factory( ReadVtk::factory, WriteVtk::factory, "Kitware VTK", "vtk", "VTK" );
124 : :
125 [ + - ]: 372 : register_factory( ReadOBJ::factory, NULL, "OBJ mesh format", "obj", "OBJ mesh" );
126 : :
127 [ + - ]: 372 : register_factory( ReadSms::factory, NULL, "RPI SMS", "sms", "SMS" );
128 : :
129 [ + - ]: 372 : register_factory( Tqdcfr::factory, NULL, "Cubit", "cub", "CUBIT" );
130 : :
131 [ + - ]: 372 : register_factory( ReadSmf::factory, WriteSmf::factory, "QSlim format", "smf", "SMF" );
132 : : #ifdef MOAB_HAVE_CGM_FACET
133 : : const char* facet_sufxs[] = { "facet", NULL };
134 : : register_factory( ReadCGM::factory, NULL, "Facet Engine Solid Model", facet_sufxs, "facet" );
135 : : #endif
136 : : #ifdef MOAB_HAVE_CGM_OCC
137 : 372 : const char* occ_sufxs[] = { "brep", "occ", NULL };
138 : 372 : const char* step_sufxs[] = { "step", "stp", NULL };
139 : 372 : const char* iges_sufxs[] = { "iges", "igs", NULL };
140 [ + - ]: 372 : register_factory( ReadCGM::factory, NULL, "OpenCascade solid model", occ_sufxs, "OCC" );
141 [ + - ]: 372 : register_factory( ReadCGM::factory, NULL, "STEP B-Rep exchange", step_sufxs, "STEP" );
142 [ + - ]: 372 : register_factory( ReadCGM::factory, NULL, "IGES B-Rep exchange", iges_sufxs, "IGES" );
143 : : #endif
144 : :
145 : : #ifdef MOAB_HAVE_NETCDF
146 [ + - ]: 372 : register_factory( NULL, WriteSLAC::factory, "SLAC", "slac", "SLAC" );
147 : : #endif
148 : :
149 : : #ifdef MOAB_HAVE_CCMIO
150 : : const char* ccmio_sufxs[] = { "ccm", "ccmg", NULL };
151 : : register_factory( ReadCCMIO::factory, WriteCCMIO::factory, "CCMIO files", ccmio_sufxs, "CCMIO" );
152 : : #endif
153 : :
154 : : #ifdef MOAB_HAVE_DAMSEL
155 : : const char* damsel_sufxs[] = { "h5", NULL };
156 : : register_factory( ReadDamsel::factory, WriteDamsel::factory, "Damsel files", damsel_sufxs, "DAMSEL" );
157 : : #endif
158 : :
159 [ + - ]: 372 : register_factory( NULL, WriteGMV::factory, "GMV", "gmv", "GMV" );
160 : :
161 [ + - ]: 372 : register_factory( NULL, WriteAns::factory, "Ansys", "ans", "ANSYS" );
162 : :
163 : 372 : const char* gmsh_sufxs[] = { "msh", "gmsh", NULL };
164 [ + - ]: 372 : register_factory( ReadGmsh::factory, WriteGmsh::factory, "Gmsh mesh file", gmsh_sufxs, "GMSH" );
165 : :
166 [ + - ]: 372 : register_factory( ReadSTL::factory, WriteSTL::factory, "Stereo Lithography File (STL)", "stl", "STL" );
167 : :
168 : 372 : const char* tetgen_sufxs[] = { "node", "ele", "face", "edge", NULL };
169 [ + - ]: 372 : register_factory( ReadTetGen::factory, 0, "TetGen output files", tetgen_sufxs, "TETGEN" );
170 : :
171 : 372 : const char* template_sufxs[] = { NULL };
172 : : register_factory( ReadTemplate::factory, WriteTemplate::factory, "Template input files", template_sufxs,
173 [ + - ]: 372 : "TEMPLATE" );
174 : 372 : }
175 : :
176 : 738 : ReaderWriterSet::~ReaderWriterSet() {}
177 : :
178 : 8556 : ErrorCode ReaderWriterSet::register_factory( reader_factory_t reader, writer_factory_t writer, const char* description,
179 : : const char* const* extensions, const char* name )
180 : : {
181 [ + + ][ - + ]: 8556 : if( !reader && !writer ) return MB_FAILURE;
182 : :
183 : : // check for duplicate names
184 [ + - ]: 8556 : iterator h = handler_by_name( name );
185 [ + - ][ + - ]: 8556 : if( h != end() ) { MB_SET_ERR( MB_FAILURE, "Conflicting string name for file formats: \"" << name << "\"" ); }
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
186 : :
187 : : // count extensions and check for duplicates
188 : : const char* const* iter;
189 [ + + ]: 21576 : for( iter = extensions; *iter; ++iter )
190 : : {
191 [ + - ][ + - ]: 13020 : h = handler_from_extension( *iter );
192 [ + - ][ + - ]: 13020 : if( h != end() )
[ - + ]
193 : : {
194 [ # # ][ # # ]: 0 : if( NULL != reader && h->have_reader() )
[ # # ][ # # ]
[ # # ]
195 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Conflicting readers for file extension \""
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
196 : : << *iter << "\": \"" << h->description() << "\" and \"" << description
197 : : << "\"." );
198 [ # # ][ # # ]: 0 : else if( NULL != writer && h->have_writer() )
[ # # ][ # # ]
[ # # ]
199 [ # # ][ # # ]: 0 : MB_SET_ERR( MB_FAILURE, "Conflicting writers for file extension \""
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
200 : : << *iter << "\": \"" << h->description() << "\" and \"" << description
201 : : << "\"." );
202 : : }
203 : : }
204 [ + - ][ + - ]: 8556 : handlerList.push_back( Handler( reader, writer, name, description, extensions, iter - extensions ) );
205 : 8556 : return MB_SUCCESS;
206 : : }
207 : :
208 : 5208 : ErrorCode ReaderWriterSet::register_factory( reader_factory_t reader, writer_factory_t writer, const char* description,
209 : : const char* extension, const char* name )
210 : : {
211 : 5208 : const char* extensions[2] = { extension, NULL };
212 [ + - ]: 5208 : return register_factory( reader, writer, description, extensions, name );
213 : : }
214 : :
215 : 0 : ReaderIface* ReaderWriterSet::get_file_extension_reader( const std::string& filename ) const
216 : : {
217 [ # # ]: 0 : std::string ext = extension_from_filename( filename );
218 [ # # ]: 0 : iterator handler = handler_from_extension( ext, true, false );
219 [ # # ][ # # ]: 0 : return handler == end() ? NULL : handler->make_reader( mbCore );
[ # # ][ # # ]
[ # # ]
220 : : }
221 : :
222 : 0 : WriterIface* ReaderWriterSet::get_file_extension_writer( const std::string& filename ) const
223 : : {
224 [ # # ]: 0 : std::string ext = extension_from_filename( filename );
225 [ # # ]: 0 : iterator handler = handler_from_extension( ext, false, true );
226 [ # # ][ # # ]: 0 : return handler == end() ? NULL : handler->make_writer( mbCore );
[ # # ][ # # ]
[ # # ]
227 : : }
228 : :
229 : 171 : std::string ReaderWriterSet::extension_from_filename( const std::string& filename )
230 : : {
231 : 171 : std::string::size_type idx = filename.find_last_of( "." );
232 : 171 : std::string::size_type idirx = filename.find_last_of( "\\/" );
233 : :
234 [ + + ][ + - ]: 171 : if( idx == std::string::npos ) return std::string( "" );
235 [ + + ][ + + ]: 129 : if( ( idirx != std::string::npos ) && ( idirx > idx ) ) return std::string( "" );
[ + - ]
236 : 171 : return filename.substr( idx + 1 );
237 : : }
238 : :
239 : 8556 : ReaderWriterSet::Handler::Handler( reader_factory_t read_f, writer_factory_t write_f, const char* nm, const char* desc,
240 : : const char* const* ext, int num_ext )
241 [ + - ][ + - ]: 8556 : : mReader( read_f ), mWriter( write_f ), mName( nm ), mDescription( desc ), mExtensions( num_ext )
[ + - ]
242 : : {
243 [ + + ]: 21576 : for( int i = 0; i < num_ext; ++i )
244 [ + - ][ + - ]: 13020 : mExtensions[i] = ext[i];
245 : 8556 : }
246 : :
247 : : #ifdef WIN32
248 : : #define strcasecmp( A, B ) _stricmp( A, B )
249 : : #endif
250 : :
251 : 13020 : ReaderWriterSet::iterator ReaderWriterSet::handler_from_extension( const std::string& ext, bool with_reader,
252 : : bool with_writer ) const
253 : : {
254 [ + - ]: 13020 : iterator iter;
255 : 13020 : std::vector< std::string >::const_iterator siter;
256 : :
257 : : // try case-sensitive compare
258 [ + - ][ + - ]: 148428 : for( iter = begin(); iter != end(); ++iter )
[ + - ][ + - ]
[ + + ]
259 : : {
260 [ - + ][ # # ]: 135408 : if( ( with_reader && !iter->have_reader() ) || ( with_writer && !iter->have_writer() ) ) continue;
[ # # ][ # # ]
[ - + ][ # # ]
[ # # ][ # # ]
[ - + ]
261 : :
262 [ + - ][ + - ]: 348564 : for( siter = iter->mExtensions.begin(); siter != iter->mExtensions.end(); ++siter )
[ + - ][ + - ]
[ + + ]
263 [ + - ][ + - ]: 213156 : if( *siter == ext ) return iter;
[ - + ]
264 : : }
265 : :
266 : : // try case-insensitive compare
267 [ + - ][ + - ]: 148428 : for( iter = begin(); iter != end(); ++iter )
[ + - ][ + - ]
[ + + ]
268 : : {
269 [ - + ][ # # ]: 135408 : if( ( with_reader && !iter->have_reader() ) || ( with_writer && !iter->have_writer() ) ) continue;
[ # # ][ # # ]
[ - + ][ # # ]
[ # # ][ # # ]
[ - + ]
270 : :
271 [ + - ][ + - ]: 348564 : for( siter = iter->mExtensions.begin(); siter != iter->mExtensions.end(); ++siter )
[ + - ][ + - ]
[ + + ]
272 [ + - ][ - + ]: 213156 : if( 0 == strcasecmp( siter->c_str(), ext.c_str() ) ) return iter;
273 : : }
274 : :
275 [ + - ]: 13020 : return end();
276 : : }
277 : :
278 : 876 : bool ReaderWriterSet::Handler::reads_extension( const char* ext ) const
279 : : {
280 [ + - ][ + + ]: 876 : if( !have_reader() ) return false;
281 : :
282 : 804 : std::vector< std::string >::const_iterator siter;
283 [ + - ][ + - ]: 2049 : for( siter = mExtensions.begin(); siter != mExtensions.end(); ++siter )
[ + + ]
284 [ + - ][ + - ]: 1342 : if( !( *siter ).compare( ext ) )
[ + + ]
285 : 97 : return true;
286 [ + - ][ - + ]: 1245 : else if( 0 == strcasecmp( siter->c_str(), ext ) )
287 : 0 : return true;
288 : :
289 : 876 : return false;
290 : : }
291 : :
292 : 555 : bool ReaderWriterSet::Handler::writes_extension( const char* ext ) const
293 : : {
294 [ + - ][ + + ]: 555 : if( !have_writer() ) return false;
295 : :
296 : 283 : std::vector< std::string >::const_iterator siter;
297 [ + - ][ + - ]: 696 : for( siter = mExtensions.begin(); siter != mExtensions.end(); ++siter )
[ + + ]
298 [ + - ][ + - ]: 444 : if( !( *siter ).compare( ext ) )
[ + + ]
299 : 31 : return true;
300 [ + - ][ - + ]: 413 : else if( 0 == strcasecmp( siter->c_str(), ext ) )
301 : 0 : return true;
302 : :
303 : 555 : return false;
304 : : }
305 : :
306 : 8556 : ReaderWriterSet::iterator ReaderWriterSet::handler_by_name( const char* nm ) const
307 : : {
308 : 8556 : return std::find( begin(), end(), nm );
309 : : }
310 : :
311 : 94116 : bool ReaderWriterSet::Handler::operator==( const char* nm ) const
312 : : {
313 : : // do case-insensitive comparison
314 : 94116 : std::string::const_iterator siter = mName.begin();
315 [ + - ][ + - ]: 102300 : for( ; *nm; ++nm, ++siter )
316 [ + - ][ + - ]: 102300 : if( siter == mName.end() || tolower( *nm ) != tolower( *siter ) ) return false;
[ + - ][ + + ]
[ + - ][ + + ]
[ # # ]
317 : 94116 : return *nm == '\0';
318 : : }
319 : :
320 [ + - ][ + - ]: 228 : } // namespace moab
|