ViennaGrid - The Vienna Grid Library  2.1.0
viennagrid/io/vtk_writer.hpp
Go to the documentation of this file.
00001 #ifndef VIENNAGRID_IO_VTK_WRITER_HPP
00002 #define VIENNAGRID_IO_VTK_WRITER_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 <sstream>
00019 #include <iostream>
00020 
00021 #include "viennagrid/forwards.hpp"
00022 #include "viennagrid/mesh/segmentation.hpp"
00023 #include "viennagrid/mesh/mesh.hpp"
00024 #include "viennagrid/io/helper.hpp"
00025 #include "viennagrid/io/vtk_common.hpp"
00026 
00031 namespace viennagrid
00032 {
00033   namespace io
00034   {
00035 
00036     template<typename ElementType>
00037     struct ValueTypeInformation;
00038 
00039     template<>
00040     struct ValueTypeInformation<double>
00041     {
00042       typedef double value_type;
00043 
00044       static std::string type_name() { return "Float32"; }
00045       static int num_components() { return 1; }
00046       static void write( std::ostream & os, value_type value ) { os << value; }
00047     };
00048 
00049     template<>
00050     struct ValueTypeInformation< std::vector<double> >
00051     {
00052       typedef std::vector<double> value_type;
00053 
00054       static std::string type_name() { return "Float32"; }
00055       static int num_components() { return 3; }
00056       static void write( std::ostream & os, value_type const & value )
00057       {
00058         os << value[0] << " " << value[1] << " " << value[2];
00059 //         for (int i = 0; i < std::min(value.size(), std::size_t(3)); ++i)
00060 //           os << value[i] << " ";
00061 //
00062 //         for (int i = std::min(value.size(), std::size_t(3)); i < 3; ++i)
00063 //           os << "0 ";
00064       }
00065     };
00066 
00067 
00069 
00070     //helper: translate element tags to VTK-element types
00071     // (see: http://www.vtk.org/VTK/img/file-formats.pdf, page 9)
00072 
00078     template < typename MeshType, typename SegmentationType = typename viennagrid::result_of::segmentation<MeshType>::type >
00079     class vtk_writer
00080     {
00081     protected:
00082 
00083       typedef typename SegmentationType::segment_id_type segment_id_type;
00084 
00085       typedef typename result_of::point<MeshType>::type   PointType;
00086       typedef typename result_of::coord<PointType>::type  CoordType;
00087 
00088       typedef typename result_of::cell_tag<MeshType>::type                   CellTag;
00089       typedef typename result_of::element<MeshType, CellTag>::type           CellType;
00090       typedef typename result_of::const_handle<MeshType, CellTag>::type      ConstCellHandleType;
00091       typedef typename result_of::id<CellType>::type                         CellIDType;
00092 
00093       typedef typename result_of::element<MeshType, vertex_tag>::type            VertexType;
00094       typedef typename result_of::handle<MeshType, vertex_tag>::type             VertexHandleType;
00095       typedef typename result_of::const_handle<MeshType, vertex_tag>::type       ConstVertexHandleType;
00096       typedef typename result_of::id<VertexType>::type                           VertexIDType;
00097 
00098       typedef typename SegmentationType::segment_handle_type SegmentHandleType;
00099 
00100 
00101       typedef std::vector<double> vector_data_type;
00102 
00103       typedef base_dynamic_field<const double, VertexType> VertexScalarBaseAccesor;
00104       typedef std::map< std::string, VertexScalarBaseAccesor * > VertexScalarOutputAccessorContainer;
00105 
00106       typedef base_dynamic_field<const vector_data_type, VertexType> VertexVectorBaseAccesor;
00107       typedef std::map< std::string, VertexVectorBaseAccesor * > VertexVectorOutputAccessorContainer;
00108 
00109       typedef base_dynamic_field<const double, CellType> CellScalarBaseAccesor;
00110       typedef std::map< std::string, CellScalarBaseAccesor * > CellScalarOutputAccessorContainer;
00111 
00112       typedef base_dynamic_field<const vector_data_type, CellType> CellVectorBaseAccesor;
00113       typedef std::map< std::string, CellVectorBaseAccesor * > CellVectorOutputAccessorContainer;
00114 
00115     protected:
00116 
00117 
00118       template<typename map_type>
00119       void clear_map( map_type & map )
00120       {
00121         for (typename map_type::iterator it = map.begin(); it != map.end(); ++it)
00122           delete it->second;
00123 
00124         map.clear();
00125       }
00126 
00127       void clear()
00128       {
00129         clear_map(vertex_scalar_data);
00130         clear_map(vertex_vector_data);
00131 
00132         clear_map(cell_scalar_data);
00133         clear_map(cell_vector_data);
00134 
00135 
00136         for (typename std::map< segment_id_type, VertexScalarOutputAccessorContainer>::iterator it = segment_vertex_scalar_data.begin(); it != segment_vertex_scalar_data.end(); ++it)
00137           clear_map(it->second);
00138 
00139         for (typename std::map< segment_id_type, VertexVectorOutputAccessorContainer>::iterator it = segment_vertex_vector_data.begin(); it != segment_vertex_vector_data.end(); ++it)
00140           clear_map(it->second);
00141 
00142 
00143         for (typename std::map< segment_id_type, CellScalarOutputAccessorContainer>::iterator it = segment_cell_scalar_data.begin(); it != segment_cell_scalar_data.end(); ++it)
00144           clear_map(it->second);
00145 
00146         for (typename std::map< segment_id_type, CellVectorOutputAccessorContainer>::iterator it = segment_cell_vector_data.begin(); it != segment_cell_vector_data.end(); ++it)
00147           clear_map(it->second);
00148 
00149 
00150         segment_vertex_scalar_data.clear();
00151         segment_vertex_vector_data.clear();
00152 
00153         segment_cell_scalar_data.clear();
00154         segment_cell_vector_data.clear();
00155 
00156 
00157         used_vertex_map.clear();
00158         vertex_to_index_map.clear();
00159         used_cell_map.clear();
00160       }
00161 
00163       void writeHeader(std::ofstream & writer)
00164       {
00165         writer << "<?xml version=\"1.0\"?>" << std::endl;
00166         writer << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl;
00167         writer << " <UnstructuredGrid>" << std::endl;
00168       }
00169 
00170 
00171       template<typename SegmentHandleT>
00172       std::size_t preparePoints(SegmentHandleT const & segment, segment_id_type seg_id)
00173       {
00174         typedef typename viennagrid::result_of::const_element_range<SegmentHandleT, CellTag>::type     CellRange;
00175         typedef typename viennagrid::result_of::iterator<CellRange>::type                                         CellIterator;
00176 
00177         typedef typename viennagrid::result_of::const_element_range<CellType, vertex_tag>::type      VertexOnCellRange;
00178         typedef typename viennagrid::result_of::iterator<VertexOnCellRange>::type         VertexOnCellIterator;
00179 
00180         std::map< VertexIDType, ConstVertexHandleType > & current_used_vertex_map = used_vertex_map[seg_id];
00181         std::map< ConstVertexHandleType, VertexIDType > & current_vertex_to_index_map = vertex_to_index_map[seg_id];
00182 
00183 
00184         CellRange cells(segment);
00185 
00186         for (CellIterator it = cells.begin(); it != cells.end(); ++it)
00187         {
00188           VertexOnCellRange vertices_on_cell(*it);
00189           for (VertexOnCellIterator jt = vertices_on_cell.begin(); jt != vertices_on_cell.end(); ++jt)
00190           {
00191               typename std::map< VertexIDType, ConstVertexHandleType >::iterator kt = current_used_vertex_map.find( jt->id() );
00192               if (kt == current_used_vertex_map.end())
00193                 current_used_vertex_map.insert( std::make_pair(jt->id(), jt.handle()) );
00194 
00195 
00196 //                   typename std::map< ConstVertexHandleType, VertexIDType >::iterator kt = current_vertex_to_index_map.find( jt.handle() );
00197 //                   if (kt == current_vertex_to_index_map.end())
00198 //                   {
00199 // //                       current_vertex_to_index_map.insert( std::make_pair( jt.handle(), jt->id() ) );
00200 //                       current_vertex_to_index_map.insert( std::make_pair( jt.handle(), index ) );
00201 // //                       current_used_vertex_map[ index ] = jt.handle();
00202 //                       current_used_vertex_map[ jt->id() ] = jt.handle();
00203 //                       index++;
00204 //                   }
00205           }
00206         }
00207 
00208         typename VertexIDType::base_id_type index = 0;
00209         for (typename std::map< VertexIDType, ConstVertexHandleType >::iterator it = current_used_vertex_map.begin(); it != current_used_vertex_map.end(); ++it)
00210           current_vertex_to_index_map.insert( std::make_pair( it->second, VertexIDType(index++) ) );
00211 
00212         return current_vertex_to_index_map.size();
00213       }
00214 
00215       template<typename MeshSegmentHandleT>
00216       std::size_t prepareCells(MeshSegmentHandleT const & domseg, segment_id_type seg_id)
00217       {
00218         typedef typename viennagrid::result_of::const_element_range<MeshSegmentHandleT, CellTag>::type     CellRange;
00219         typedef typename viennagrid::result_of::iterator<CellRange>::type                                         CellIterator;
00220 
00221         std::map< CellIDType, ConstCellHandleType > & current_used_cells_map = used_cell_map[seg_id];
00222 
00223         int index = 0;
00224         CellRange cells(domseg);
00225         for (CellIterator cit  = cells.begin();
00226                           cit != cells.end();
00227                         ++cit, ++index)
00228             {
00229               current_used_cells_map[ cit->id() ] = cit.handle();
00230             }
00231 
00232         return current_used_cells_map.size();
00233       }
00234 
00236       template <typename MeshSegmentHandleT>
00237       void writePoints(MeshSegmentHandleT const & domseg, std::ofstream & writer, segment_id_type seg_id)
00238       {
00239         std::map< VertexIDType, ConstVertexHandleType > & current_used_vertex_map = used_vertex_map[seg_id];
00240 
00241         writer << "   <Points>" << std::endl;
00242         writer << "    <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">" << std::endl;
00243 
00244         for (typename std::map< VertexIDType, ConstVertexHandleType >::iterator it = current_used_vertex_map.begin(); it != current_used_vertex_map.end(); ++it)
00245         {
00246           const int dim = result_of::static_size<PointType>::value;
00247           PointWriter<dim>::write(writer, viennagrid::point(domseg, it->second) );
00248 
00249           // add 0's for less than three dimensions
00250           for (int i = dim; i < 3; ++i)
00251             writer << " " << 0;
00252 
00253           writer << std::endl;
00254         }
00255         writer << std::endl;
00256         writer << "    </DataArray>" << std::endl;
00257         writer << "   </Points> " << std::endl;
00258       } //writePoints()
00259 
00261       template <typename MeshSegmentHandleT>
00262       void writeCells(MeshSegmentHandleT const & domseg, std::ofstream & writer, segment_id_type seg_id)
00263       {
00264         typedef typename viennagrid::result_of::const_element_range<CellType, vertex_tag>::type      VertexOnCellRange;
00265         typedef typename viennagrid::result_of::iterator<VertexOnCellRange>::type         VertexOnCellIterator;
00266 
00267         std::map< ConstVertexHandleType, VertexIDType > & current_vertex_to_index_map = vertex_to_index_map[seg_id];
00268 
00269         writer << "   <Cells> " << std::endl;
00270         writer << "    <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">" << std::endl;
00271 
00272         std::map< CellIDType, ConstCellHandleType > & current_used_cells_map = used_cell_map[seg_id];
00273         for (typename std::map< CellIDType, ConstCellHandleType >::iterator it = current_used_cells_map.begin(); it != current_used_cells_map.end(); ++it)
00274 
00275         {
00276           //step 1: Write vertex indices in ViennaGrid orientation to array:
00277           CellType const & cell = viennagrid::dereference_handle(domseg, it->second);
00278 //             CellType const & cell = *cit;
00279 
00280           std::vector<VertexIDType> viennagrid_vertices(viennagrid::boundary_elements<CellTag, vertex_tag>::num);
00281           VertexOnCellRange vertices_on_cell = viennagrid::elements<vertex_tag>(cell);
00282           std::size_t j = 0;
00283           for (VertexOnCellIterator vocit = vertices_on_cell.begin();
00284               vocit != vertices_on_cell.end();
00285               ++vocit, ++j)
00286           {
00287             viennagrid_vertices[j] = current_vertex_to_index_map[vocit.handle()];
00288           }
00289 
00290           //Step 2: Write the transformed connectivities:
00291           detail::viennagrid_to_vtk_orientations<CellTag> reorderer;
00292           for (std::size_t i=0; i<viennagrid_vertices.size(); ++i)
00293             writer << viennagrid_vertices[reorderer(i)] << " ";
00294 
00295           writer << std::endl;
00296         }
00297 
00298         writer << std::endl;
00299         writer << "    </DataArray>" << std::endl;
00300 
00301         writer << "    <DataArray type=\"Int32\" Name=\"offsets\" format=\"ascii\">" << std::endl;
00302         for (std::size_t offsets = 1;
00303               //offsets <= current_used_cells_map.size();
00304               offsets <= viennagrid::elements<CellTag>(domseg).size();
00305               ++offsets)
00306         {
00307           writer << ( offsets * viennagrid::boundary_elements<CellTag, vertex_tag>::num) << " ";
00308         }
00309         writer << std::endl;
00310         writer << "    </DataArray>" << std::endl;
00311 
00312         writer << "    <DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">" << std::endl;
00313         for (std::size_t offsets = 1;
00314               //offsets <= current_used_cells_map.size();
00315              offsets <= viennagrid::elements<CellTag>(domseg).size();
00316               ++offsets)
00317         {
00318           writer << detail::ELEMENT_TAG_TO_VTK_TYPE<CellTag>::value << " ";
00319         }
00320         writer << std::endl;
00321         writer << "    </DataArray>" << std::endl;
00322         writer << "   </Cells>" << std::endl;
00323       }
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00333       template <typename SegmentHandleT, typename IOAccessorType>
00334       void writePointData(SegmentHandleT const & segment, std::ofstream & writer, std::string const & name, IOAccessorType const & accessor, segment_id_type seg_id)
00335       {
00336         typedef typename IOAccessorType::value_type ValueType;
00337 
00338         writer << "    <DataArray type=\"" << ValueTypeInformation<ValueType>::type_name() << "\" Name=\"" << name <<
00339           "\" NumberOfComponents=\"" << ValueTypeInformation<ValueType>::num_components() << "\" format=\"ascii\">" << std::endl;
00340 
00341         std::map< VertexIDType, ConstVertexHandleType > & current_used_vertex_map = used_vertex_map[seg_id];
00342         for (typename std::map< VertexIDType, ConstVertexHandleType >::iterator it = current_used_vertex_map.begin(); it != current_used_vertex_map.end(); ++it)
00343         {
00344           ValueTypeInformation<ValueType>::write(writer, accessor( viennagrid::dereference_handle(segment, it->second) ));
00345           writer << " ";
00346         }
00347         writer << std::endl;
00348 
00349         writer << "    </DataArray>" << std::endl;
00350       } //writePointDataScalar
00351 
00352 
00354       template <typename SegmentHandleT, typename IOAccessorType>
00355       void writeCellData(SegmentHandleT const & segment, std::ofstream & writer, std::string const & name, IOAccessorType const & accessor, segment_id_type seg_id)
00356       {
00357         typedef typename IOAccessorType::value_type ValueType;
00358 
00359         writer << "    <DataArray type=\"" << ValueTypeInformation<ValueType>::type_name() << "\" Name=\"" << name <<
00360           "\" NumberOfComponents=\"" << ValueTypeInformation<ValueType>::num_components() << "\" format=\"ascii\">" << std::endl;
00361 
00362 
00363         std::map< CellIDType, ConstCellHandleType > & current_used_cells_map = used_cell_map[seg_id];
00364         for (typename std::map< CellIDType, ConstCellHandleType >::iterator it = current_used_cells_map.begin(); it != current_used_cells_map.end(); ++it)
00365 
00366         {
00367           //step 1: Write vertex indices in ViennaGrid orientation to array:
00368           CellType const & cell = viennagrid::dereference_handle(segment, it->second);
00369 //             CellType const & cell = *cit;
00370 
00371           ValueTypeInformation<ValueType>::write(writer, accessor(cell));
00372           writer << " ";
00373         }
00374         writer << std::endl;
00375 
00376         writer << "    </DataArray>" << std::endl;
00377       } //writePointDataScalar
00378 
00379 
00380 
00382       void writeFooter(std::ofstream & writer)
00383       {
00384         writer << " </UnstructuredGrid>" << std::endl;
00385         writer << "</VTKFile>" << std::endl;
00386       }
00387 
00388     public:
00389 
00390 
00391       ~vtk_writer() { clear(); }
00392 
00398       void operator()(MeshType const & mesh_obj, std::string const & filename)
00399       {
00400           std::stringstream ss;
00401           ss << filename << ".vtu";
00402           std::ofstream writer(ss.str().c_str());
00403 
00404           if (!writer)
00405             throw cannot_open_file_exception("* ViennaGrid: vtk_writer::operator(): File " + filename + ": Cannot open file!");
00406 
00407           writeHeader(writer);
00408 
00409           segment_id_type tmp_id = segment_id_type();
00410 
00411           std::size_t num_points = preparePoints(mesh_obj, tmp_id);
00412           prepareCells(mesh_obj, tmp_id);
00413 
00414           writer << "  <Piece NumberOfPoints=\""
00415                  << num_points
00416                  << "\" NumberOfCells=\""
00417                  << viennagrid::elements<CellTag>(mesh_obj).size()
00418                  << "\">" << std::endl;
00419 
00420           writePoints(mesh_obj, writer, tmp_id);
00421 
00422           if (vertex_scalar_data.size() > 0 || vertex_vector_data.size() > 0)
00423           {
00424             writer << "   <PointData>" << std::endl;
00425 
00426               for (typename VertexScalarOutputAccessorContainer::const_iterator it = vertex_scalar_data.begin(); it != vertex_scalar_data.end(); ++it)
00427                 writePointData( mesh_obj, writer, it->first, *(it->second), tmp_id );
00428               for (typename VertexVectorOutputAccessorContainer::const_iterator it = vertex_vector_data.begin(); it != vertex_vector_data.end(); ++it)
00429                 writePointData( mesh_obj, writer, it->first, *(it->second), tmp_id );
00430 
00431             writer << "   </PointData>" << std::endl;
00432           }
00433 
00434           writeCells(mesh_obj, writer, tmp_id);
00435           if (cell_scalar_data.size() > 0 || cell_vector_data.size() > 0)
00436           {
00437             writer << "   <CellData>" << std::endl;
00438 
00439               for (typename CellScalarOutputAccessorContainer::const_iterator it = cell_scalar_data.begin(); it != cell_scalar_data.end(); ++it)
00440                 writeCellData( mesh_obj, writer, it->first, *(it->second), tmp_id );
00441               for (typename CellVectorOutputAccessorContainer::const_iterator it = cell_vector_data.begin(); it != cell_vector_data.end(); ++it)
00442                 writeCellData( mesh_obj, writer, it->first, *(it->second), tmp_id );
00443 
00444             writer << "   </CellData>" << std::endl;
00445           }
00446 
00447           writer << "  </Piece>" << std::endl;
00448           writeFooter(writer);
00449 
00450         clear();
00451       }
00452 
00459       void operator()(MeshType const & mesh_obj, SegmentationType const & segmentation, std::string const & filename)
00460       {
00461           if (segmentation.size() <= 1) return (*this)(mesh_obj, filename);
00462 
00463           //
00464           // Step 1: Write meta information
00465           //
00466           {
00467             std::stringstream ss;
00468             ss << filename << "_main.pvd";
00469             std::ofstream writer(ss.str().c_str());
00470 
00471             std::string short_filename = filename;
00472             std::string::size_type pos = filename.rfind("/");
00473             if (pos == std::string::npos)
00474               pos = filename.rfind("\\");   //A tribute to Windows
00475 
00476             if (pos != std::string::npos)
00477               short_filename = filename.substr(pos+1, filename.size());
00478 
00479             if (!writer){
00480               clear();
00481               throw cannot_open_file_exception("* ViennaGrid: vtk_writer::operator(): File " + filename + ": Cannot open file!");
00482             }
00483 
00484             writer << "<?xml version=\"1.0\"?>" << std::endl;
00485             writer << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">" << std::endl;
00486             writer << "<Collection>" << std::endl;
00487 
00488             for (typename SegmentationType::const_iterator it = segmentation.begin(); it != segmentation.end(); ++it)
00489             {
00490               SegmentHandleType const & seg = *it;
00491               writer << "    <DataSet part=\"" << seg.id() << "\" file=\"" << short_filename << "_" << seg.id() << ".vtu\" name=\"Segment_" << seg.id() << "\"/>" << std::endl;
00492             }
00493 
00494             writer << "  </Collection>" << std::endl;
00495             writer << "</VTKFile>" << std::endl;
00496             writer.close();
00497           }
00498 
00499           //
00500           // Step 2: Write segments to individual files
00501           //
00502 
00503           for (typename SegmentationType::const_iterator it = segmentation.begin(); it != segmentation.end(); ++it)
00504           {
00505             SegmentHandleType const & seg = *it;
00506 
00507             std::stringstream ss;
00508             ss << filename << "_" << seg.id() << ".vtu";
00509             std::ofstream writer(ss.str().c_str());
00510             writeHeader(writer);
00511 
00512             if (!writer)
00513             {
00514               clear();
00515               throw cannot_open_file_exception("* ViennaGrid: vtk_writer::operator(): File " + ss.str() + ": Cannot open file!");
00516             }
00517 
00518             std::size_t num_points = preparePoints(seg, seg.id());
00519             prepareCells(seg, seg.id());
00520 
00521             writer << "  <Piece NumberOfPoints=\""
00522                   << num_points
00523                   << "\" NumberOfCells=\""
00524                   << viennagrid::elements<CellTag>(seg).size()
00525                   << "\">" << std::endl;
00526 
00527             writePoints(seg, writer, seg.id());
00528 
00529 
00530             VertexScalarOutputAccessorContainer const & current_segment_vertex_scalar_data = segment_vertex_scalar_data[ seg.id() ];
00531             VertexVectorOutputAccessorContainer const & current_segment_vertex_vector_data = segment_vertex_vector_data[ seg.id() ];
00532 
00533             if (vertex_scalar_data.size() > 0 || vertex_vector_data.size() > 0 || current_segment_vertex_scalar_data.size() > 0 || current_segment_vertex_vector_data.size() > 0)
00534             {
00535               writer << "   <PointData>" << std::endl;
00536 
00537               for (typename VertexScalarOutputAccessorContainer::const_iterator data_it = vertex_scalar_data.begin(); data_it != vertex_scalar_data.end(); ++data_it)
00538                 writePointData( seg, writer, data_it->first, *(data_it->second), seg.id() );
00539               for (typename VertexVectorOutputAccessorContainer::const_iterator data_it = vertex_vector_data.begin(); data_it != vertex_vector_data.end(); ++data_it)
00540                 writePointData( seg, writer, data_it->first, *(data_it->second), seg.id() );
00541 
00542 
00543               for (typename VertexScalarOutputAccessorContainer::const_iterator data_it = current_segment_vertex_scalar_data.begin(); data_it != current_segment_vertex_scalar_data.end(); ++data_it)
00544                 writePointData( seg, writer, data_it->first, *(data_it->second), seg.id() );
00545 
00546               for (typename VertexVectorOutputAccessorContainer::const_iterator data_it = current_segment_vertex_vector_data.begin(); data_it != current_segment_vertex_vector_data.end(); ++data_it)
00547                 writePointData( seg, writer, data_it->first, *(data_it->second), seg.id() );
00548 
00549               writer << "   </PointData>" << std::endl;
00550             }
00551 
00552             writeCells(seg, writer, seg.id());
00553 
00554             CellScalarOutputAccessorContainer const & current_segment_cell_scalar_data = segment_cell_scalar_data[ seg.id() ];
00555             CellVectorOutputAccessorContainer const & current_segment_cell_vector_data = segment_cell_vector_data[ seg.id() ];
00556             if (cell_scalar_data.size() > 0 || cell_vector_data.size() > 0 || current_segment_cell_scalar_data.size() > 0 || current_segment_cell_vector_data.size() > 0)
00557             {
00558               writer << "   <CellData>" << std::endl;
00559 
00560               for (typename CellScalarOutputAccessorContainer::const_iterator data_it = cell_scalar_data.begin(); data_it != cell_scalar_data.end(); ++data_it)
00561                 writeCellData( seg, writer, data_it->first, *(data_it->second), seg.id() );
00562               for (typename CellVectorOutputAccessorContainer::const_iterator data_it = cell_vector_data.begin(); data_it != cell_vector_data.end(); ++data_it)
00563                 writeCellData( seg, writer, data_it->first, *(data_it->second), seg.id() );
00564 
00565 
00566               for (typename CellScalarOutputAccessorContainer::const_iterator data_it = current_segment_cell_scalar_data.begin(); data_it != current_segment_cell_scalar_data.end(); ++data_it)
00567                 writeCellData( seg, writer, data_it->first, *(data_it->second), seg.id() );
00568               for (typename CellVectorOutputAccessorContainer::const_iterator data_it = current_segment_cell_vector_data.begin(); data_it != current_segment_cell_vector_data.end(); ++data_it)
00569                 writeCellData( seg, writer, data_it->first, *(data_it->second), seg.id() );
00570 
00571               writer << "   </CellData>" << std::endl;
00572             }
00573 
00574             writer << "  </Piece>" << std::endl;
00575             writeFooter(writer);
00576             writer.close();
00577           }
00578 
00579         clear();
00580       }
00581 
00582 
00583 
00584   private:
00585 
00586 
00587     template<typename MapType, typename AccessorOrFieldType, typename AccessType>
00588     void add_to_container(MapType & map, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00589     {
00590         typename MapType::iterator it = map.find(quantity_name);
00591         if (it != map.end())
00592         {
00593           delete it->second;
00594           it->second = new dynamic_field_wrapper<const AccessorOrFieldType, AccessType>( accessor_or_field );
00595         }
00596         else
00597           map[quantity_name] = new dynamic_field_wrapper<const AccessorOrFieldType, AccessType>( accessor_or_field );
00598     }
00599 
00600     template<typename MapType, typename AccessorOrFieldType>
00601     void add_to_vertex_container(MapType & map, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00602     {
00603       add_to_container<MapType, AccessorOrFieldType, VertexType>(map, accessor_or_field, quantity_name);
00604     }
00605 
00606     template<typename MapType, typename AccessorOrFieldType>
00607     void add_to_cell_container(MapType & map, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00608     {
00609       add_to_container<MapType, AccessorOrFieldType, CellType>(map, accessor_or_field, quantity_name);
00610     }
00611 
00612   public:
00613 
00614 
00616       template <typename AccessorOrFieldType>
00617       void add_scalar_data_on_vertices(AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00618       { add_to_vertex_container(vertex_scalar_data, accessor_or_field, quantity_name); }
00619 
00621       template <typename AccessorOrFieldType>
00622       void add_scalar_data_on_vertices(segment_id_type seg_id, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00623       { add_to_vertex_container(segment_vertex_scalar_data[seg_id], accessor_or_field, quantity_name); }
00624 
00626       template <typename AccessorOrFieldType>
00627       void add_scalar_data_on_vertices(SegmentHandleType const & segment, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00628       { add_scalar_data_on_vertices(segment.id(), accessor_or_field, quantity_name); }
00629 
00630 
00632       template <typename AccessorOrFieldType>
00633       void add_vector_data_on_vertices(AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00634       { add_to_vertex_container(vertex_vector_data, accessor_or_field, quantity_name); }
00635 
00637       template <typename AccessorOrFieldType>
00638       void add_vector_data_on_vertices(segment_id_type seg_id, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00639       { add_to_vertex_container(segment_vertex_vector_data[seg_id], accessor_or_field, quantity_name); }
00640 
00642       template <typename AccessorOrFieldType>
00643       void add_vector_data_on_vertices(SegmentHandleType const & segment, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00644       { add_vector_data_on_vertices(segment.id(), accessor_or_field, quantity_name); }
00645 
00646 
00647 
00649       template <typename AccessorOrFieldType>
00650       void add_scalar_data_on_cells(AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00651       { add_to_cell_container(cell_scalar_data, accessor_or_field, quantity_name); }
00652 
00654       template <typename AccessorOrFieldType>
00655       void add_scalar_data_on_cells(segment_id_type seg_id, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00656       { add_to_cell_container(segment_cell_scalar_data[seg_id], accessor_or_field, quantity_name); }
00657 
00659       template <typename AccessorOrFieldType>
00660       void add_scalar_data_on_cells(SegmentHandleType const & segment, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00661       { add_scalar_data_on_cells(segment.id(), accessor_or_field, quantity_name); }
00662 
00663 
00665       template <typename AccessorOrFieldType>
00666       void add_vector_data_on_cells(AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00667       { add_to_cell_container(cell_vector_data, accessor_or_field, quantity_name); }
00668 
00670       template <typename AccessorOrFieldType>
00671       void add_vector_data_on_cells(segment_id_type seg_id, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00672       { add_to_cell_container(segment_cell_vector_data[seg_id], accessor_or_field, quantity_name); }
00673 
00675       template <typename AccessorOrFieldType>
00676       void add_vector_data_on_cells(SegmentHandleType const & segment, AccessorOrFieldType const accessor_or_field, std::string const & quantity_name)
00677       { add_vector_data_on_cells(segment.id(), accessor_or_field, quantity_name); }
00678 
00679 
00680     private:
00681 
00682       std::map< segment_id_type, std::map< ConstVertexHandleType, VertexIDType> >             vertex_to_index_map;
00683       std::map< segment_id_type, std::map< VertexIDType, ConstVertexHandleType> >             used_vertex_map;
00684       std::map< segment_id_type, std::map< CellIDType, ConstCellHandleType> >                 used_cell_map;
00685 
00686 
00687       VertexScalarOutputAccessorContainer          vertex_scalar_data;
00688       VertexVectorOutputAccessorContainer          vertex_vector_data;
00689 
00690       CellScalarOutputAccessorContainer          cell_scalar_data;
00691       CellVectorOutputAccessorContainer          cell_vector_data;
00692 
00693       std::map< segment_id_type, VertexScalarOutputAccessorContainer > segment_vertex_scalar_data;
00694       std::map< segment_id_type, VertexVectorOutputAccessorContainer > segment_vertex_vector_data;
00695 
00696       std::map< segment_id_type, CellScalarOutputAccessorContainer >   segment_cell_scalar_data;
00697       std::map< segment_id_type, CellVectorOutputAccessorContainer >   segment_cell_vector_data;
00698     };
00699 
00701     template < typename MeshType, typename SegmentationType >
00702     int export_vtk(MeshType const & mesh_obj, SegmentationType const & segmentation, std::string const & filename)
00703     {
00704       vtk_writer<MeshType> vtk_writer;
00705       return vtk_writer(mesh_obj, segmentation, filename);
00706     }
00707 
00709     template < typename MeshType >
00710     int export_vtk(MeshType const & mesh_obj, std::string const & filename)
00711     {
00712       vtk_writer<MeshType> vtk_writer;
00713       return vtk_writer(mesh_obj, filename);
00714     }
00715 
00716 
00726     template <typename MeshT, typename SegmentationT, typename AccessorOrFieldT>
00727     vtk_writer<MeshT, SegmentationT> & add_scalar_data_on_vertices(vtk_writer<MeshT, SegmentationT> & writer,
00728                                                                     AccessorOrFieldT const accessor_or_field,
00729                                                                     std::string const & quantity_name)
00730     {
00731       writer.add_scalar_data_on_vertices(accessor_or_field, quantity_name);
00732       return writer;
00733     }
00734 
00744     template <typename MeshT, typename SegmentationT, typename AccessorOrFieldT>
00745     vtk_writer<MeshT, SegmentationT> & add_vector_data_on_vertices(vtk_writer<MeshT, SegmentationT> & writer,
00746                                                                     AccessorOrFieldT const accessor_or_field,
00747                                                                     std::string const & quantity_name)
00748     {
00749       writer.add_vector_data_on_vertices(accessor_or_field, quantity_name);
00750       return writer;
00751     }
00752 
00763     template <typename MeshT, typename SegmentationT, typename AccessorOrFieldT>
00764     vtk_writer<MeshT, SegmentationT> & add_scalar_data_on_vertices(vtk_writer<MeshT, SegmentationT> & writer,
00765                                                                     segment_handle<SegmentationT> const & segment,
00766                                                                     AccessorOrFieldT const accessor_or_field,
00767                                                                     std::string const & quantity_name)
00768     {
00769       writer.add_scalar_data_on_vertices(segment, accessor_or_field, quantity_name);
00770       return writer;
00771     }
00772 
00783     template <typename MeshT, typename SegmentationT, typename AccessorOrFieldT>
00784     vtk_writer<MeshT, SegmentationT> & add_vector_data_on_vertices(vtk_writer<MeshT, SegmentationT> & writer,
00785                                                                     segment_handle<SegmentationT> const & segment,
00786                                                                     AccessorOrFieldT const accessor_or_field,
00787                                                                     std::string const & quantity_name)
00788     {
00789       writer.add_vector_data_on_vertices(segment, accessor_or_field, quantity_name);
00790       return writer;
00791     }
00792 
00793 
00794 
00795 
00796 
00806     template <typename MeshT, typename SegmentationT, typename AccessorOrFieldT>
00807     vtk_writer<MeshT, SegmentationT> & add_scalar_data_on_cells(vtk_writer<MeshT, SegmentationT> & writer,
00808                                                                     AccessorOrFieldT const accessor_or_field,
00809                                                                     std::string const & quantity_name)
00810     {
00811       writer.add_scalar_data_on_cells(accessor_or_field, quantity_name);
00812       return writer;
00813     }
00814 
00824     template <typename MeshT, typename SegmentationT, typename AccessorOrFieldT>
00825     vtk_writer<MeshT, SegmentationT> & add_vector_data_on_cells(vtk_writer<MeshT, SegmentationT> & writer,
00826                                                                     AccessorOrFieldT const accessor_or_field,
00827                                                                     std::string const & quantity_name)
00828     {
00829       writer.add_vector_data_on_cells(accessor_or_field, quantity_name);
00830       return writer;
00831     }
00832 
00843     template <typename MeshT, typename SegmentationT, typename AccessorOrFieldT>
00844     vtk_writer<MeshT, SegmentationT> & add_scalar_data_on_cells(vtk_writer<MeshT, SegmentationT> & writer,
00845                                                                   segment_handle<SegmentationT> const & segment,
00846                                                                   AccessorOrFieldT const accessor_or_field,
00847                                                                   std::string const & quantity_name)
00848     {
00849       writer.add_scalar_data_on_cells(segment, accessor_or_field, quantity_name);
00850       return writer;
00851     }
00852 
00863     template <typename MeshT, typename SegmentationT, typename AccessorOrFieldT>
00864     vtk_writer<MeshT, SegmentationT> & add_vector_data_on_cells(vtk_writer<MeshT, SegmentationT> & writer,
00865                                                                   segment_handle<SegmentationT> const & segment,
00866                                                                   AccessorOrFieldT const accessor_or_field,
00867                                                                   std::string const & quantity_name)
00868     {
00869       writer.add_vector_data_on_cells(segment, accessor_or_field, quantity_name);
00870       return writer;
00871     }
00872 
00873 
00874   } //namespace io
00875 } //namespace viennagrid
00876 
00877 #endif