ViennaGrid - The Vienna Grid Library
2.1.0
|
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