MOAB: Mesh Oriented datABase  (version 5.4.1)
ReadTemplate.cpp
Go to the documentation of this file.
00001 /**
00002  * \class ReadTemplate
00003  * \brief Template for writing a new reader in MOAB
00004  *
00005  */
00006 
00007 #include "ReadTemplate.hpp"
00008 #include "moab/Interface.hpp"
00009 #include "moab/ReadUtilIface.hpp"
00010 #include "moab/Range.hpp"
00011 #include "moab/FileOptions.hpp"
00012 
00013 #include <cstdio>
00014 #include <cassert>
00015 
00016 namespace moab
00017 {
00018 
00019 ReaderIface* ReadTemplate::factory( Interface* iface )
00020 {
00021     return new ReadTemplate( iface );
00022 }
00023 
00024 ReadTemplate::ReadTemplate( Interface* impl ) : mbImpl( impl ), fileName( NULL )
00025 {
00026     mbImpl->query_interface( readMeshIface );
00027 }
00028 
00029 ReadTemplate::~ReadTemplate()
00030 {
00031     if( readMeshIface )
00032     {
00033         mbImpl->release_interface( readMeshIface );
00034         readMeshIface = 0;
00035     }
00036 }
00037 
00038 ErrorCode ReadTemplate::read_tag_values( const char* /* file_name */,
00039                                          const char* /* tag_name */,
00040                                          const FileOptions& /* opts */,
00041                                          std::vector< int >& /* tag_values_out */,
00042                                          const SubsetList* /* subset_list */ )
00043 {
00044     return MB_NOT_IMPLEMENTED;
00045 }
00046 
00047 ErrorCode ReadTemplate::load_file( const char* filename,
00048                                    const EntityHandle* file_set,
00049                                    const FileOptions& opts,
00050                                    const ReaderIface::SubsetList* subset_list,
00051                                    const Tag* /*file_id_tag*/ )
00052 {
00053     if( subset_list )
00054     {
00055         // See src/moab/ReaderIface.hpp, definition of SubsetList struct; this basically specifies
00056         // an integer tag and tag values for sets to read on this proc, or a part number and total #
00057         // parts for reading a trivial partition of entities
00058     }
00059 
00060     // Save filename to member variable so we don't need to pass as an argument
00061     // to called functions
00062     fileName = filename;
00063 
00064     // Process options; see src/FileOptions.hpp for API for FileOptions class, and
00065     // doc/metadata_info.doc for a description of various options used by some of the readers in
00066     // MOAB
00067     ErrorCode result = process_options( opts );MB_CHK_SET_ERR( result, fileName << ": problem reading options" );
00068 
00069     // Open file; filePtr is member of ReadTemplate, change to whatever mechanism is used to
00070     // identify file
00071     FILE* filePtr = fopen( fileName, "r" );
00072     if( !filePtr )
00073     {
00074         MB_SET_ERR( MB_FILE_DOES_NOT_EXIST, fileName << ": fopen returned error" );
00075     }
00076 
00077     // Read number of verts, elements, sets
00078     long num_verts = 0, num_elems = 0, num_sets = 0;
00079 
00080     // read_ents keeps a running set of entities read from this file, including vertices, elements,
00081     // and sets; these will get added to file_set (if input) at the end of the read
00082     Range read_ents;
00083 
00084     // start_vertex is passed back so we know how to convert indices from the file into vertex
00085     // handles; most of the time this is done by adding start_vertex to the (0-based) index; if the
00086     // index is 1-based, you also need to subtract one; see read_elements for details
00087     EntityHandle start_vertex;
00088     result = read_vertices( num_verts, start_vertex, read_ents );
00089     if( MB_SUCCESS != result )
00090     {
00091         fclose( filePtr );
00092         return result;
00093     }
00094 
00095     // Create/read elements; this template assumes that all elements are the same type, so can be
00096     // read in a single call to read_elements, and kept track of with a single start_elem handle. If
00097     // there are more entity types, might have to keep these start handles in an array/vector.
00098     // start_elem is only really needed if you're reading sets later, and need to convert some
00099     // file-based index to an entity handle
00100     EntityHandle start_elem;
00101     result = read_elements( num_elems, start_vertex, start_elem, read_ents );
00102     if( MB_SUCCESS != result )
00103     {
00104         fclose( filePtr );
00105         return result;
00106     }
00107 
00108     // Read/create entity sets; typically these sets have some tag identifying what they're for, see
00109     // doc/metadata_info.doc for examples of different kinds of sets and how they're marked
00110     result = create_sets( num_sets, start_vertex, num_verts, start_elem, num_elems, read_ents );
00111     if( MB_SUCCESS != result )
00112     {
00113         fclose( filePtr );
00114         return result;
00115     }
00116 
00117     // Finally, add all read_ents into the file set, if one was input
00118     if( file_set && *file_set )
00119     {
00120         result = mbImpl->add_entities( *file_set, read_ents );
00121         if( MB_SUCCESS != result )
00122         {
00123             fclose( filePtr );
00124             return result;
00125         }
00126     }
00127 
00128     fclose( filePtr );
00129 
00130     return result;
00131 }
00132 
00133 ErrorCode ReadTemplate::read_vertices( int num_verts, EntityHandle& start_vertex, Range& read_ents )
00134 {
00135     // Allocate nodes; these are allocated in one shot, get contiguous handles starting with
00136     // start_handle, and the reader is passed back double*'s pointing to MOAB's native storage for
00137     // vertex coordinates for those verts
00138     std::vector< double* > coord_arrays;
00139     ErrorCode result = readMeshIface->get_node_coords( 3, num_verts, 1, start_vertex, coord_arrays );MB_CHK_SET_ERR( result, fileName << ": Trouble reading vertices" );
00140 
00141     // Fill in vertex coordinate arrays
00142     double *x = coord_arrays[0], *y = coord_arrays[1], *z = coord_arrays[2];
00143     for( long i = 0; i < num_verts; ++i )
00144     {
00145         // Read x/y/z; do something with them for now to avoid warning
00146         if( x || y || z )
00147         {
00148         }
00149     }
00150 
00151     if( num_verts ) read_ents.insert( start_vertex, start_vertex + num_verts - 1 );
00152 
00153     return result;
00154 }
00155 
00156 //! Read/create elements
00157 ErrorCode ReadTemplate::read_elements( int num_elems,
00158                                        EntityHandle start_vertex,
00159                                        EntityHandle& start_elem,
00160                                        Range& read_ents )
00161 {
00162     // Get the entity type being read
00163     EntityType ent_type = MBHEX;
00164 
00165     // Get the number of vertices per entity
00166     int verts_per_elem = 8;
00167 
00168     // Create the element sequence; passes back a pointer to the internal storage for connectivity
00169     // and the starting entity handle
00170     EntityHandle* conn_array;
00171     ErrorCode result =
00172         readMeshIface->get_element_connect( num_elems, verts_per_elem, ent_type, 1, start_elem, conn_array );MB_CHK_SET_ERR( result, fileName << ": Trouble reading elements" );
00173 
00174     // Read connectivity into conn_array directly
00175     for( long i = 0; i < num_elems; i++ )
00176     {
00177         // Read connectivity
00178     }
00179 
00180     // Convert file-based connectivity indices to vertex handles in-place; be careful, if indices
00181     // are smaller than handles, need to do from the end of the list so we don't overwrite data
00182     //
00183     // Here, we assume indices are smaller than handles, just for demonstration; create an
00184     // integer-type pointer to connectivity initialized to same start of connectivity array
00185     int* ind_array = reinterpret_cast< int* >( conn_array );
00186     // OFFSET is value of first vertex index in file; most files are 1-based, but some might be
00187     // 0-based
00188     int OFFSET = 1;
00189     for( long i = num_elems * verts_per_elem - 1; i >= 0; i-- )
00190     {
00191         conn_array[i] = ind_array[i] + start_vertex + OFFSET;
00192 
00193         // This assert assumes last handle in read_ents is highest vertex handle in this file
00194         assert( conn_array[i] >= start_vertex && conn_array[i] <= *read_ents.rbegin() );
00195     }
00196 
00197     // Notify MOAB of the new elements
00198     result = readMeshIface->update_adjacencies( start_elem, num_elems, verts_per_elem, conn_array );
00199     if( MB_SUCCESS != result ) return result;
00200 
00201     // Add elements to read_ents
00202     if( num_elems ) read_ents.insert( start_elem, start_elem + num_elems - 1 );
00203 
00204     return MB_SUCCESS;
00205 }
00206 
00207 //! Read/create sets
00208 ErrorCode ReadTemplate::create_sets( int num_sets,
00209                                      EntityHandle /*start_vertex*/,
00210                                      int /*num_verts*/,
00211                                      EntityHandle /*start_elem*/,
00212                                      int /*num_elems*/,
00213                                      Range& read_ents )
00214 {
00215     ErrorCode result = MB_SUCCESS;
00216     EntityHandle this_set;
00217 
00218     for( int i = 0; i < num_sets; i++ )
00219     {
00220         // Create set
00221         result = mbImpl->create_meshset( MESHSET_SET, this_set );MB_CHK_SET_ERR( result, fileName << ": Trouble creating set" );
00222 
00223         Range set_ents;
00224         // Read/compute what's in this set; REMEMBER TO CONVERT THESE TO MOAB HANDLES
00225 
00226         // Add them to the set
00227         result = mbImpl->add_entities( this_set, set_ents );MB_CHK_SET_ERR( result, fileName << ": Trouble putting entities in set" );
00228 
00229         // Add the new set to read_ents
00230         read_ents.insert( this_set );
00231     }
00232 
00233     return MB_SUCCESS;
00234 }
00235 
00236 ErrorCode ReadTemplate::process_options( const FileOptions& opts )
00237 {
00238     // Mark all options seen, to avoid compile warning on unused variable
00239     opts.mark_all_seen();
00240     return MB_SUCCESS;
00241 }
00242 
00243 }  // namespace moab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines