MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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