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