ViennaGrid - The Vienna Grid Library
2.1.0
|
00001 #ifndef VIENNAGRID_IO_POLY_READER_HPP 00002 #define VIENNAGRID_IO_POLY_READER_HPP 00003 00004 /* ======================================================================= 00005 Copyright (c) 2011-2014, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 00009 ----------------- 00010 ViennaGrid - The Vienna Grid Library 00011 ----------------- 00012 00013 License: MIT (X11), see file LICENSE in the base directory 00014 ======================================================================= */ 00015 00016 00017 #include <fstream> 00018 #include <iostream> 00019 #include <assert.h> 00020 00021 #include "viennagrid/forwards.hpp" 00022 #include "viennagrid/io/helper.hpp" 00023 00024 #include "viennagrid/mesh/mesh.hpp" 00025 00032 namespace viennagrid 00033 { 00034 namespace io 00035 { 00036 00037 template<typename stream_type> 00038 bool get_valid_line( stream_type & stream, std::string & line, char comment_line = '#' ) 00039 { 00040 std::string tmp; 00041 00042 while (true) 00043 { 00044 if (!std::getline(stream, tmp)) 00045 return false; 00046 00047 std::size_t pos = tmp.find(comment_line); 00048 if (pos != std::string::npos) 00049 tmp = tmp.substr(0, pos); 00050 00051 for (std::size_t i = 0; i != tmp.size(); ++i) 00052 { 00053 if ( tmp[i] != ' ' ) 00054 { 00055 line = tmp.substr(i, std::string::npos); 00056 return true; 00057 } 00058 } 00059 } 00060 } 00061 00066 struct tetgen_poly_reader 00067 { 00073 template <typename MeshT> 00074 void operator()(MeshT & mesh_obj, std::string const & filename) const 00075 { 00076 std::vector< typename viennagrid::result_of::point<MeshT>::type > hole_points; 00077 std::vector< std::pair<typename viennagrid::result_of::point<MeshT>::type, int> > seed_points; 00078 00079 (*this)(mesh_obj, filename, hole_points, seed_points); 00080 } 00081 00088 template <typename MeshT> 00089 void operator()(MeshT & mesh_obj, std::string const & filename, 00090 std::vector< typename viennagrid::result_of::point<MeshT>::type > & hole_points) const 00091 { 00092 std::vector< std::pair<typename viennagrid::result_of::point<MeshT>::type, int> > seed_points; 00093 (*this)(mesh_obj, filename, hole_points, seed_points); 00094 } 00095 00102 template <typename MeshT> 00103 void operator()(MeshT & mesh_obj, std::string const & filename, 00104 std::vector< std::pair<typename viennagrid::result_of::point<MeshT>::type, int> > & seed_points) const 00105 { 00106 std::vector< typename viennagrid::result_of::point<MeshT>::type > hole_points; 00107 00108 (*this)(mesh_obj, filename, hole_points, seed_points); 00109 } 00110 00118 template <typename MeshT> 00119 void operator()(MeshT & mesh_obj, std::string const & filename, 00120 std::vector< typename viennagrid::result_of::point<MeshT>::type > & hole_points, 00121 std::vector< std::pair<typename viennagrid::result_of::point<MeshT>::type, int> > & seed_points) const 00122 { 00123 typedef typename viennagrid::result_of::point<MeshT>::type PointType; 00124 00125 static const std::size_t point_dim = viennagrid::result_of::static_size<PointType>::value; 00126 00127 typedef typename result_of::element<MeshT, vertex_tag>::type VertexType; 00128 typedef typename result_of::handle<MeshT, vertex_tag>::type VertexHandleType; 00129 typedef typename VertexType::id_type VertexIDType; 00130 00131 typedef typename result_of::handle<MeshT, line_tag>::type LineHandleType; 00132 00133 std::ifstream reader(filename.c_str()); 00134 00135 #if defined VIENNAGRID_DEBUG_STATUS || defined VIENNAGRID_DEBUG_IO 00136 std::cout << "* poly_reader::operator(): Reading file " << filename << std::endl; 00137 #endif 00138 00139 if (!reader) 00140 { 00141 throw cannot_open_file_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": Cannot open file!"); 00142 } 00143 00144 hole_points.clear(); 00145 seed_points.clear(); 00146 00147 std::string tmp; 00148 std::istringstream current_line; 00149 00150 long node_num = 0; 00151 std::size_t dim = 0; 00152 long attribute_num = 0; 00153 long boundary_marker_num = 0; 00154 00155 00156 if (!reader.good()) 00157 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": File is empty."); 00158 00159 // 00160 // Read vertices: 00161 // 00162 if (!get_valid_line(reader, tmp)) 00163 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": EOF encountered when reading information"); 00164 00165 current_line.str(tmp); current_line.clear(); 00166 current_line >> node_num >> dim >> attribute_num >> boundary_marker_num; 00167 00168 if (node_num < 0) 00169 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY file has less than 0 nodes"); 00170 if (dim != point_dim) 00171 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY point dimension missmatch"); 00172 if (attribute_num < 0) 00173 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY file has less than 0 attributes"); 00174 if ((boundary_marker_num < 0) || (boundary_marker_num > 1)) 00175 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY file has not 0 or 1 boundary marker"); 00176 00177 #if defined VIENNAGRID_DEBUG_STATUS || defined VIENNAGRID_DEBUG_IO 00178 std::cout << "* poly_reader::operator(): Reading " << node_num << " vertices... " << std::endl; 00179 #endif 00180 00181 for (int i=0; i<node_num; i++) 00182 { 00183 if (!get_valid_line(reader, tmp)) 00184 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": EOF encountered when reading information"); 00185 00186 typename VertexIDType::base_id_type id; 00187 00188 current_line.str(tmp); current_line.clear(); 00189 current_line >> id; 00190 00191 PointType p; 00192 00193 for (std::size_t j=0; j<point_dim; j++) 00194 current_line >> p[j]; 00195 00196 viennagrid::make_vertex_with_id( mesh_obj, VertexIDType(id), p ); 00197 } 00198 00199 if (!reader.good()) 00200 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": EOF encountered when reading number of cells."); 00201 00202 00203 // 00204 // Read facets: 00205 // 00206 long facet_num = 0; 00207 if (!get_valid_line(reader, tmp)) 00208 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": EOF encountered when reading information"); 00209 00210 00211 current_line.str(tmp); current_line.clear(); 00212 current_line >> facet_num >> boundary_marker_num; 00213 00214 if (facet_num < 0) 00215 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY file has less than 0 facets"); 00216 if ((boundary_marker_num < 0) || (boundary_marker_num > 1)) 00217 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY file has not 0 or 1 boundary marker"); 00218 00219 #if defined VIENNAGRID_DEBUG_STATUS || defined VIENNAGRID_DEBUG_IO 00220 std::cout << "* netgen_reader::operator(): Reading " << cell_num << " cells... " << std::endl; 00221 #endif 00222 00223 for (int i=0; i<facet_num; ++i) 00224 { 00225 long polygon_num; 00226 long hole_num; 00227 00228 if (!get_valid_line(reader, tmp)) 00229 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": EOF encountered when reading information"); 00230 00231 00232 current_line.str(tmp); current_line.clear(); 00233 current_line >> polygon_num >> hole_num; 00234 00235 if (polygon_num < 0) 00236 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY facet has less than 0 polygons"); 00237 if (hole_num < 0) 00238 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY facet has less than 0 holes"); 00239 00240 std::list<LineHandleType> lines; 00241 std::list<VertexHandleType> vertices; 00242 00243 for (int j = 0; j<polygon_num; ++j) 00244 { 00245 long vertex_num; 00246 00247 if (!get_valid_line(reader, tmp)) 00248 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": EOF encountered when reading information"); 00249 00250 00251 current_line.str(tmp); current_line.clear(); 00252 current_line >> vertex_num; 00253 00254 if (vertex_num < 0) 00255 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY polygon has less than 0 vertices"); 00256 00257 std::vector<VertexHandleType> vertex_handles(static_cast<std::size_t>(vertex_num)); 00258 00259 for (std::size_t k = 0; k<static_cast<std::size_t>(vertex_num); ++k) 00260 { 00261 typename VertexIDType::base_id_type id; 00262 current_line >> id; 00263 vertex_handles[k] = viennagrid::find( mesh_obj, VertexIDType(id) ).handle(); 00264 } 00265 00266 if (vertex_num == 1) 00267 { 00268 vertices.push_back( vertex_handles.front() ); 00269 } 00270 else if (vertex_num == 2) 00271 { 00272 lines.push_back( viennagrid::make_line(mesh_obj, vertex_handles[0], vertex_handles[1]) ); 00273 } 00274 else 00275 { 00276 typename std::vector<VertexHandleType>::iterator it1 = vertex_handles.begin(); 00277 typename std::vector<VertexHandleType>::iterator it2 = it1; ++it2; 00278 for (; it2 != vertex_handles.end(); ++it1, ++it2) 00279 lines.push_back( viennagrid::make_line(mesh_obj, *it1, *it2) ); 00280 lines.push_back( viennagrid::make_line(mesh_obj, vertex_handles.back(), vertex_handles.front()) ); 00281 } 00282 } 00283 00284 std::list<PointType> hole_points_read; 00285 00286 for (int j = 0; j<hole_num; ++j) 00287 { 00288 if (!get_valid_line(reader, tmp)) 00289 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": EOF encountered when reading information"); 00290 00291 long hole_id; 00292 00293 current_line.str(tmp); current_line.clear(); 00294 current_line >> hole_id; 00295 00296 PointType p; 00297 00298 for (std::size_t k=0; k<point_dim; k++) 00299 current_line >> p[k]; 00300 00301 hole_points_read.push_back(p); 00302 } 00303 00304 00305 00306 viennagrid::make_plc( 00307 mesh_obj, 00308 lines.begin(), lines.end(), 00309 vertices.begin(), vertices.end(), 00310 hole_points_read.begin(), hole_points_read.end() 00311 ); 00312 00313 } 00314 00315 00316 00317 long hole_num; 00318 00319 if (!get_valid_line(reader, tmp)) 00320 { 00321 // no holes -> Okay, SUCCESS xD 00322 return; 00323 } 00324 00325 current_line.str(tmp); current_line.clear(); 00326 current_line >> hole_num; 00327 00328 if (hole_num < 0) 00329 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY file has less than 0 holes"); 00330 00331 for (int i=0; i<hole_num; ++i) 00332 { 00333 if (!get_valid_line(reader, tmp)) 00334 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": EOF encountered when reading information"); 00335 00336 long hole_number; 00337 PointType hole_point; 00338 00339 current_line.str(tmp); current_line.clear(); 00340 current_line >> hole_number; 00341 00342 for (std::size_t j=0; j < point_dim; j++) 00343 current_line >> hole_point[j]; 00344 00345 hole_points.push_back( hole_point ); 00346 } 00347 00348 00349 00350 00351 long segment_num; 00352 00353 if (!get_valid_line(reader, tmp)) 00354 { 00355 // no region -> SUCCESS xD 00356 return; 00357 } 00358 00359 current_line.str(tmp); current_line.clear(); 00360 current_line >> segment_num; 00361 00362 if (segment_num < 0) 00363 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": POLY file has less than 0 segments"); 00364 00365 for (int i=0; i<segment_num; ++i) 00366 { 00367 if (!get_valid_line(reader, tmp)) 00368 throw bad_file_format_exception("* ViennaGrid: tetgen_poly_reader::operator(): File " + filename + ": EOF encountered when reading information"); 00369 00370 long segment_number; 00371 PointType seed_point; 00372 int segment_id; 00373 00374 current_line.str(tmp); current_line.clear(); 00375 current_line >> segment_number; 00376 00377 for (std::size_t j=0; j < point_dim; j++) 00378 current_line >> seed_point[j]; 00379 00380 current_line >> segment_id; 00381 00382 seed_points.push_back( std::make_pair(seed_point, segment_id) ); 00383 } 00384 } //operator() 00385 00386 }; //class tetgen_poly_reader 00387 00388 } //namespace io 00389 } //namespace viennagrid 00390 00391 #endif