moab
|
00001 00017 #ifdef WIN32 00018 #ifdef _DEBUG 00019 // turn off warnings that say they debugging identifier has been truncated 00020 // this warning comes up when using some STL containers 00021 #pragma warning(disable : 4786) 00022 #endif 00023 #endif 00024 00025 #include "WriteGMV.hpp" 00026 00027 #include "moab/Interface.hpp" 00028 #include "Internals.hpp" 00029 #include "moab/Range.hpp" 00030 #include "moab/CN.hpp" 00031 #include "MBTagConventions.hpp" 00032 #include "moab/WriteUtilIface.hpp" 00033 #include <fstream> 00034 #include <assert.h> 00035 00036 namespace moab { 00037 00038 const char *WriteGMV::gmvTypeNames[] = { 00039 "", 00040 "line", 00041 "tri", 00042 "quad", 00043 "", 00044 "tet", 00045 "pyramid", 00046 "prism", 00047 "", 00048 "hex", 00049 "", 00050 "" 00051 }; 00052 00053 WriterIface* WriteGMV::factory( Interface* iface ) 00054 { return new WriteGMV( iface ); } 00055 00056 WriteGMV::WriteGMV(Interface *impl) 00057 : mbImpl(impl), mCurrentMeshHandle(0) 00058 { 00059 assert(impl != NULL); 00060 00061 impl->query_interface( mWriteIface ); 00062 00063 // initialize in case tag_get_handle fails below 00064 mMaterialSetTag = 0; 00065 mDirichletSetTag = 0; 00066 mNeumannSetTag = 0; 00067 mHasMidNodesTag = 0; 00068 mGeomDimensionTag= 0; 00069 mGlobalIdTag= 0; 00070 00072 // initialize in case tag_get_handle fails below 00074 int zero = 0, negone = -1; 00075 impl->tag_get_handle(MATERIAL_SET_TAG_NAME, 1, MB_TYPE_INTEGER, 00076 mMaterialSetTag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone); 00077 00078 impl->tag_get_handle(DIRICHLET_SET_TAG_NAME, 1, MB_TYPE_INTEGER, 00079 mDirichletSetTag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone); 00080 00081 impl->tag_get_handle(NEUMANN_SET_TAG_NAME, 1, MB_TYPE_INTEGER, 00082 mNeumannSetTag, MB_TAG_SPARSE|MB_TAG_CREAT, &negone); 00083 00084 impl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER, 00085 mGlobalIdTag, MB_TAG_SPARSE|MB_TAG_CREAT, &zero); 00086 00087 int dum_val_array[] = {-1, -1, -1, -1}; 00088 impl->tag_get_handle(HAS_MID_NODES_TAG_NAME, 4, MB_TYPE_INTEGER, 00089 mHasMidNodesTag, MB_TAG_SPARSE|MB_TAG_CREAT, dum_val_array); 00090 } 00091 00092 WriteGMV::~WriteGMV() 00093 { 00094 mbImpl->release_interface(mWriteIface); 00095 } 00096 00097 ErrorCode WriteGMV::write_file(const char *file_name, 00098 const EntityHandle output_set, 00099 const int user_dimension, 00100 const bool mesh, 00101 const bool poly_mesh) 00102 { 00103 // general function for writing a mesh 00104 00105 ErrorCode result = MB_SUCCESS; 00106 00107 // initialize file 00108 00109 if (mesh) { 00110 result = local_write_mesh(file_name, output_set, user_dimension, true, false); 00111 if (MB_SUCCESS != result) return result; 00112 } 00113 00114 if (poly_mesh) { 00115 result = local_write_mesh(file_name, output_set, user_dimension, false, true); 00116 if (MB_SUCCESS != result) return result; 00117 } 00118 00119 return result; 00120 } 00121 00122 ErrorCode WriteGMV::write_file( const char* filename, 00123 const bool , 00124 const FileOptions& /*opts*/, 00125 const EntityHandle* output_sets, 00126 const int num_output_sets, 00127 const std::vector<std::string>& , 00128 const Tag*, 00129 int, 00130 int dimension ) 00131 { 00132 EntityHandle output_set = 0; 00133 if (output_sets && num_output_sets > 0) 00134 { 00135 if (num_output_sets > 1) 00136 return MB_FAILURE; 00137 output_set = output_sets[0]; 00138 } 00139 00140 if (dimension == 0) 00141 { 00142 mbImpl->get_dimension( dimension ); 00143 } 00144 00145 return write_file( filename, output_set, dimension, true, true ); 00146 } 00147 00148 00149 ErrorCode WriteGMV::local_write_mesh(const char *file_name, 00150 const EntityHandle output_set, 00151 const int user_dimension, 00152 const bool mesh, 00153 const bool poly_mesh) 00154 { 00155 std::ofstream ofile; 00156 ErrorCode result; 00157 00158 if (mesh) { 00159 // need to insert ".gmv" 00160 std::string tmp_name(file_name); 00161 tmp_name += ".gmv"; 00162 ofile.open(tmp_name.c_str()); 00163 } 00164 else if (poly_mesh) { 00165 // need to insert ".poly.gmv" 00166 std::string tmp_name(file_name); 00167 tmp_name += ".poly.gmv"; 00168 ofile.open(tmp_name.c_str()); 00169 } 00170 00171 ofile << "gmvinput ascii" << std::endl; 00172 00173 // get elements to be output 00174 Range dum_range, elements, all_verts; 00175 EntityType otype; 00176 if (poly_mesh) { 00177 result = mbImpl->get_entities_by_type(output_set, MBPOLYGON, elements, true); 00178 if (MB_SUCCESS != result) return result; 00179 } 00180 else { 00181 for (otype = CN::TypeDimensionMap[user_dimension].first; 00182 otype <= CN::TypeDimensionMap[user_dimension].second; otype++) { 00183 if (otype == MBPOLYGON || otype == MBPOLYHEDRON) continue; 00184 dum_range.clear(); 00185 result = mbImpl->get_entities_by_type(output_set, otype, dum_range, true); 00186 if (MB_SUCCESS != result) return result; 00187 00188 std::copy(dum_range.begin(), dum_range.end(), range_inserter(elements)); 00189 } 00190 } 00191 00192 // gather the vertices in these elements 00193 result = mbImpl->get_adjacencies(elements, 0, false, all_verts, Interface::UNION); 00194 if (MB_SUCCESS != result) return result; 00195 00196 int num_verts = all_verts.size(); 00197 00198 // allocate coordinate arrays and put pointers to them in a list 00199 double *xcoord = new double[num_verts]; 00200 double *ycoord = new double[num_verts]; 00201 double *zcoord = new double[num_verts]; 00202 std::vector<double*> coord_arrays; 00203 coord_arrays.push_back(xcoord); 00204 coord_arrays.push_back(ycoord); 00205 coord_arrays.push_back(zcoord); 00206 00207 // fill them in, writing id tags at the same time 00208 result = mWriteIface->get_node_coords(3, num_verts, all_verts, mGlobalIdTag, 1, coord_arrays); 00209 if (MB_SUCCESS != result) return result; 00210 00211 int i, j; 00212 00213 //======================================== 00214 // WRITE COORDINATE DATA TO FILE HERE 00215 00216 ofile << "nodev " << num_verts << std::endl; 00217 for (i = 0; i < num_verts; i++) 00218 ofile << xcoord[i] << " " << ycoord[i] << " " << zcoord[i] << std::endl; 00219 00220 00221 //======================================== 00222 00223 delete [] xcoord; 00224 delete [] ycoord; 00225 delete [] zcoord; 00226 00227 // iterate over types in selected dimension 00228 00229 std::vector<int> connect; 00230 std::vector<EntityHandle> connecth; 00231 00232 if (mesh) { 00233 Range sub_range; 00234 00235 ofile << "cells " << elements.size() << std::endl; 00236 00237 for (otype = CN::TypeDimensionMap[user_dimension].first; 00238 otype <= CN::TypeDimensionMap[user_dimension].second; otype++) { 00239 00240 if (otype == MBPOLYGON || otype == MBPOLYHEDRON) continue; 00241 00242 // get the first element of this type in the range, and one past the last 00243 Range::iterator lower = 00244 Range::lower_bound(elements.begin(), 00245 elements.end(), 00246 CREATE_HANDLE(otype, MB_START_ID, i)); 00247 Range::iterator upper = 00248 Range::lower_bound(elements.begin(), 00249 elements.end(), 00250 CREATE_HANDLE(otype+1, MB_START_ID, i)); 00251 00252 if (lower == upper) continue; 00253 00254 // copy these elements into a subrange 00255 sub_range.clear(); 00256 std::copy(lower, upper, range_inserter(sub_range)); 00257 00258 // make sure the connectivity array is big enough 00259 int verts_per = CN::VerticesPerEntity(otype); 00260 if (connect.size() < verts_per*sub_range.size()) 00261 connect.reserve(verts_per*sub_range.size()); 00262 00263 // get the connectivity 00264 result = mWriteIface->get_element_connect(sub_range.size(), 00265 verts_per, 00266 mGlobalIdTag, sub_range, 00267 mGlobalIdTag, 1, &connect[0]); 00268 if (MB_SUCCESS != result) return result; 00269 00270 //======================================== 00271 // WRITE CONNECTIVITY DATA TO FILE HERE 00272 00273 for (i = 0; i < (int) sub_range.size(); i++) { 00274 ofile << gmvTypeNames[otype] << " " << verts_per << std::endl; 00275 for (j = i*verts_per; j < (int) (i+1)*verts_per; j++) 00276 ofile << connect[j] << " "; 00277 ofile << std::endl; 00278 } 00279 00280 //======================================== 00281 } 00282 } 00283 00284 else if (poly_mesh) { 00285 00286 // write polygons/hedra, if any 00287 Range polygons, polyhedra; 00288 result = mbImpl->get_entities_by_type(output_set, MBPOLYGON, polygons, true); 00289 if (MB_SUCCESS != result) return result; 00290 00291 result = mbImpl->get_entities_by_type(output_set, MBPOLYHEDRON, polyhedra, true); 00292 if (MB_SUCCESS != result) return result; 00293 00294 if (polygons.size() == 0) return result; 00295 00296 // mark polyhedra with global ids 00297 result = mWriteIface->assign_ids(polyhedra, mGlobalIdTag, 1); 00298 if (MB_SUCCESS != result) return result; 00299 00300 ofile << "faces " << polygons.size() << " " << polyhedra.size() << std::endl; 00301 00302 for (Range::iterator rit = polygons.begin(); rit != polygons.end(); rit++) { 00303 // get the vertices 00304 connecth.clear(); 00305 result = mbImpl->get_connectivity(&(*rit), 1, connecth, true); 00306 if (MB_SUCCESS != result) return result; 00307 00308 if (0 == connecth.size()) continue; 00309 00310 // get the polyhedra, if any 00311 if (user_dimension == 3) { 00312 polyhedra.clear(); 00313 result = mbImpl->get_adjacencies(Range(*rit, *rit), 3, false, polyhedra); 00314 if (MB_SUCCESS != result) return result; 00315 00316 // put them in the connect array 00317 connecth.push_back((polyhedra.size() > 0 ? *polyhedra.begin() : 0)); 00318 connecth.push_back((polyhedra.size() > 1 ? *polyhedra.rbegin() : 0)); 00319 } 00320 00321 // replace handles with ids 00322 connect.reserve(connecth.size()); 00323 00324 // pre-set polyhedra ids in case there aren't any 00325 connect[connecth.size()] = 0; 00326 connect[connecth.size()+1] = 0; 00327 result = mbImpl->tag_get_data(mGlobalIdTag, &connecth[0], 00328 connecth.size()-2+polyhedra.size(), 00329 &connect[0]); 00330 if (MB_SUCCESS != result) return result; 00331 00332 // write the data 00333 ofile << connecth.size()-2; 00334 00335 for (i = 0; i < (int)connecth.size(); i++) 00336 ofile << " " << connect[i]; 00337 00338 ofile << std::endl; 00339 } 00340 } 00341 00342 ofile << std::endl << "endgmv" << std::endl; 00343 00344 ofile.close(); 00345 00346 return MB_SUCCESS; 00347 } 00348 00349 } // namespace moab 00350