MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 // This utility reads a MOAB HDF5 mesh file, and prints out 00002 // the list of all geometry entitysets and the parent and 00003 // child geometry entitysets of each such entityset. 00004 00005 #include <stdio.h> 00006 #include <stdlib.h> 00007 #include <hdf5.h> 00008 #include <vector> 00009 #include <map> 00010 #include <string> 00011 00012 // Open HDF5 file 00013 hid_t open_file( const char* name ) 00014 { 00015 hid_t handle = H5Fopen( name, H5F_ACC_RDONLY, H5P_DEFAULT ); 00016 if (handle < 0) { 00017 fprintf(stderr, "Cannot open file: \"%s\"\n", name ); 00018 exit (1); 00019 } 00020 return handle; 00021 } 00022 00023 // Read a scalar attribute value from an HDF5 file 00024 long read_scalar_attrib( hid_t file, const char* table, const char* attrib ) 00025 { 00026 hid_t table_id = H5Dopen( file, table ); 00027 if (table_id < 0) { 00028 fprintf(stderr, "Invalid file. Data not found: \"%s\"\n", table ); 00029 exit (1); 00030 } 00031 00032 hid_t attr_id = H5Aopen_name( table_id, attrib ); 00033 H5Dclose( table_id ); 00034 if (attr_id < 0) { 00035 fprintf(stderr, "Invalid file. No \"%s\" attrib on \"%s\"\n", attrib, table ); 00036 exit (1); 00037 } 00038 00039 long value; 00040 herr_t rval = H5Aread( attr_id, H5T_NATIVE_LONG, &value ); 00041 H5Aclose( attr_id ); 00042 if (rval < 0) { 00043 fprintf(stderr, "Failed to read \"%s\" attrib on \"%s\"\n", attrib, table ); 00044 exit (2); 00045 } 00046 00047 return value; 00048 } 00049 00050 00051 // Read a data table from an HDF5 file 00052 void read_data( hid_t file, const char* name, int expected_cols, std::vector<long>& data ) 00053 { 00054 hid_t handle = H5Dopen( file, name ); 00055 if (handle < 0) { 00056 fprintf(stderr, "Invalid file. Data not found: \"%s\"\n", name ); 00057 exit (1); 00058 } 00059 00060 hid_t space = H5Dget_space( handle ); 00061 if (space < 0) { 00062 fprintf(stderr, "Internal error accessing: \"%s\"\n", name ); 00063 exit (2); 00064 } 00065 00066 int ndims = H5Sget_simple_extent_ndims( space ); 00067 if (ndims < 0) { 00068 fprintf(stderr, "Internal error accessing: \"%s\"\n", name ); 00069 exit (2); 00070 } 00071 else if (ndims < 1 || ndims > 2) { 00072 fprintf(stderr, "\"%s\" is an %d-dimension table. Corrupt file?", name, ndims ); 00073 exit (2); 00074 } 00075 00076 hsize_t dims[2] = { 0, 1 }; 00077 H5Sget_simple_extent_dims( space, dims, 0 ); 00078 H5Sclose( space ); 00079 00080 if (dims[1] != expected_cols) { 00081 fprintf(stderr, "Error reading \"%s\": expected %d cols, has %d\n", name, expected_cols, (int)dims[1] ); 00082 exit (2); 00083 } 00084 00085 data.resize( dims[0] * dims[1] ); 00086 herr_t rval = H5Dread( handle, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, &data[0] ); 00087 if (rval < 0) { 00088 fprintf(stderr, "Error reading data from: \"%s\"\n", name ); 00089 exit (1); 00090 } 00091 00092 H5Dclose( handle ); 00093 } 00094 00095 // Given two vectors of the same length, create a map where the 00096 // key is taken from the first vectgor and the value is taken 00097 // from the second vector. 00098 void create_map( const std::vector<long>& ents, 00099 const std::vector<long>& vals, 00100 std::map<long,long>& map, 00101 const char* name ) 00102 { 00103 if (ents.size() != vals.size()) { 00104 fprintf(stderr, "Invalid data for tag \"%s\": mismatched table lengths.\n", name ); 00105 exit (1); 00106 } 00107 00108 std::vector<long>::const_iterator e_iter = ents.begin(), v_iter = vals.begin(); 00109 for (; e_iter != ents.end(); ++e_iter, ++v_iter) 00110 map[*e_iter] = *v_iter; 00111 } 00112 00113 // Construct a string designator for a geometry entity given 00114 // the handle of that geometry entity and maps from handle to 00115 // dimension and handle to global id. 00116 std::string ent_from_handle( const std::map<long,long>& dimmap, 00117 const std::map<long,long>& idmap, 00118 long handle ) 00119 { 00120 std::string result; 00121 std::map<long,long>::const_iterator d_iter, i_iter; 00122 d_iter = dimmap.find( handle ); 00123 i_iter = idmap.find( handle ); 00124 if (d_iter == dimmap.end() || i_iter == idmap.end()) 00125 return result; 00126 00127 switch (d_iter->second) { 00128 case 0: result += "v"; break; 00129 case 1: result += "c"; break; 00130 case 2: result += "s"; break; 00131 case 3: result += "V"; break; 00132 default: 00133 fprintf(stderr,"Invalid value in GEOM_DIMENSION tag data.\n"); 00134 exit (1); 00135 } 00136 00137 char buffer[128]; 00138 sprintf(buffer, "%ld", i_iter->second ); 00139 result += buffer; 00140 return result; 00141 } 00142 00143 // Construct a string designator for list of geometry entities given 00144 // a list of handles and maps from handle to 00145 // dimension and handle to global id. 00146 std::string ent_list_from_handles( const std::map<long,long>& dimmap, 00147 const std::map<long,long>& idmap, 00148 const std::vector<long>& vect, 00149 long start, 00150 long stop ) 00151 { 00152 std::string result; 00153 if (start >= (long)vect.size() || stop >= (long)vect.size() || stop < start) { 00154 fprintf(stderr, "Invalid set data. Corrupt file?\n"); 00155 exit(2); 00156 } 00157 std::vector<long>::const_iterator iter = vect.begin() + start+1, 00158 end = vect.begin() + stop+1; 00159 00160 for (; iter != end; ++iter) 00161 { 00162 std::string tmp = ent_from_handle( dimmap, idmap, *iter ); 00163 if (!tmp.empty()) { 00164 result += tmp; 00165 result += " "; 00166 } 00167 else 00168 result += "? "; 00169 } 00170 return result; 00171 } 00172 00173 int main( int argc, char* argv[] ) 00174 { 00175 // Need a file name to read 00176 if (argc != 2) { 00177 printf("Usage: %s <file>\n", argv[0] ); 00178 exit(1); 00179 } 00180 00181 // Read everything we need from the file 00182 std::vector<long> set_meta, set_child, set_parent, dim_ents, dim_vals, id_ents, id_vals; 00183 hid_t file = open_file( argv[1] ); 00184 read_data( file, "/tstt/sets/list", 4, set_meta ); 00185 read_data( file, "/tstt/sets/parents", 1, set_parent ); 00186 read_data( file, "/tstt/sets/children", 1, set_child ); 00187 read_data( file, "/tstt/tags/GEOM_DIMENSION/id_list", 1, dim_ents ); 00188 read_data( file, "/tstt/tags/GEOM_DIMENSION/values", 1, dim_vals ); 00189 read_data( file, "/tstt/tags/GLOBAL_ID/id_list", 1, id_ents ); 00190 read_data( file, "/tstt/tags/GLOBAL_ID/values", 1, id_vals ); 00191 const long startid = read_scalar_attrib( file, "/tstt/sets/list", "start_id" ); 00192 H5Fclose( file ); 00193 00194 // Construct handle->dimension and handle->global_id maps. 00195 std::map<long,long> dimmap, idmap; 00196 create_map( dim_ents, dim_vals, dimmap, "GEOM_DIMENSION" ); 00197 create_map( id_ents, id_vals, idmap, "GLOBAL_ID" ); 00198 00199 // For each entity set 00200 long parent_start = -1l, child_start = -1l; 00201 printf("handle ID Children Parents\n"); 00202 for (unsigned i = 0; i < set_meta.size(); i += 4) 00203 { 00204 // Get name 00205 long handle = startid + i/4; 00206 std::string name = ent_from_handle( dimmap, idmap, handle ); 00207 if (name.empty()) // not a geometry set 00208 continue; 00209 00210 // Get parents and children 00211 long child_end = set_meta[i+1]; 00212 long parent_end = set_meta[i+2]; 00213 std::string children = ent_list_from_handles( dimmap, idmap, set_child, child_start, child_end ); 00214 std::string parents = ent_list_from_handles( dimmap, idmap, set_parent, parent_start, parent_end ); 00215 child_start = child_end; 00216 parent_start = parent_end; 00217 00218 // Print 00219 printf( "%6ld %-6s %-20s %-20s\n", handle, name.c_str(), children.c_str(), parents.c_str() ); 00220 } 00221 00222 return 0; 00223 }