moab
ReadTemplate.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines