ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/io/tetgen_poly_reader.hpp
Go to the documentation of this file.
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