// Copyright (c) 2018 GeometryFactory (France). // Copyright (c) 2004-2006 INRIA Sophia-Antipolis (France). // Copyright (c) 2009 INRIA Sophia-Antipolis (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // You can redistribute it and/or modify it under the terms of the GNU // General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // // Author(s) : Laurent RINEAU, Stephane Tayeb, Maxime Gimeno #ifndef CGAL_VTK_IO_H #define CGAL_VTK_IO_H #include #include #include #include //todo try to factorize with functors namespace CGAL{ template void write_cells_tag(std::ostream& os, const C3T3 & c3t3, std::map & V, bool binary, std::size_t& offset) { typedef typename C3T3::Cells_in_complex_iterator Cell_iterator; std::string formatattribute = binary ? " format=\"appended\"" : " format=\"ascii\""; std::string typeattribute; switch(sizeof(std::size_t)) { case 8: typeattribute = " type=\"UInt64\""; break; case 4: typeattribute = " type=\"UInt32\""; break; default: CGAL_error_msg("Unknown size of std::size_t"); } // Write connectivity table os << " \n" << " \n"; offset += (4 * c3t3.number_of_cells() + 1) * sizeof(std::size_t); // 4 indices (size_t) per cell + length of the encoded data (size_t) } else { os << "\">\n"; for( Cell_iterator cit = c3t3.cells_in_complex_begin() ; cit != c3t3.cells_in_complex_end() ; ++cit ) { for (int i=0; i<4; i++) os << V[cit->vertex(i)] << " "; } os << " \n"; } // Write offsets os << " \n"; offset += (c3t3.number_of_cells() + 1) * sizeof(std::size_t); // 1 offset (size_t) per cell + length of the encoded data (size_t) } else { os << "\">\n"; std::size_t cells_offset = 0; for( Cell_iterator cit = c3t3.cells_in_complex_begin() ; cit != c3t3.cells_in_complex_end() ; ++cit ) { cells_offset += 4; os << cells_offset << " "; } os << " \n"; } // Write cell type (tetrahedra == 10) os << " \n"; offset += c3t3.number_of_cells() + sizeof(std::size_t); // 1 unsigned char per cell + length of the encoded data (size_t) } else { os << "\">\n"; for( Cell_iterator cit = c3t3.cells_in_complex_begin() ; cit != c3t3.cells_in_complex_end() ; ++cit ) os << "10 "; os << " \n"; } os << " \n"; } template void write_cells(std::ostream& os, const C3T3 & c3t3, std::map & V, std::vector& mids) { typedef typename C3T3::Cells_in_complex_iterator Cell_iterator; std::vector connectivity_table; std::vector offsets; std::vector cell_type(c3t3.number_of_cells(),10); // tetrahedra == 10 std::size_t off = 0; for( Cell_iterator cit = c3t3.cells_in_complex_begin() ; cit != c3t3.cells_in_complex_end() ; ++cit ) { off += 4; offsets.push_back(off); for (int i=0; i<4; i++) connectivity_table.push_back(V[cit->vertex(i)]); mids.push_back(cit->subdomain_index()); } write_vector(os,connectivity_table); write_vector(os,offsets); write_vector(os,cell_type); } template void write_points_tag(std::ostream& os, const Tr & tr, std::map & V, bool binary, std::size_t& offset) { std::size_t dim = 3; typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator; typedef typename Tr::Geom_traits Gt; typedef typename Gt::FT FT; std::size_t inum = 0; std::string format = binary ? "appended" : "ascii"; std::string type = (sizeof(FT) == 8) ? "Float64" : "Float32"; os << " \n" << " \n"; offset += 3 * tr.number_of_vertices() * sizeof(FT) + sizeof(std::size_t); // dim coords per points + length of the encoded data (size_t) } else { os << "\">\n"; for( Finite_vertices_iterator vit = tr.finite_vertices_begin(); vit != tr.finite_vertices_end(); ++vit) { V[vit] = inum++; os << vit->point()[0] << " "; os << vit->point()[1] << " "; if(dim == 3) os << vit->point()[2] << " "; else os << 0.0 << " "; } os << " \n"; } os << " \n"; } // writes the points appended data at the end of the .vtu file template void write_points(std::ostream& os, const Tr & tr, std::map & V) { std::size_t dim = 3; typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator; typedef typename Tr::Geom_traits Gt; typedef typename Gt::FT FT; std::size_t inum = 0; std::vector coordinates; for( Finite_vertices_iterator vit = tr.finite_vertices_begin(); vit != tr.finite_vertices_end(); ++vit) { V[vit] = inum++; // binary output => the map has not been filled yet coordinates.push_back(vit->point()[0]); coordinates.push_back(vit->point()[1]); coordinates.push_back(dim == 3 ? vit->point()[2] : 0.0); } write_vector(os,coordinates); } // writes the attribute tags before binary data is appended template void write_attribute_tag(std::ostream& os, const std::string& attr_name, const std::vector& attribute, bool binary, std::size_t& offset) { std::string format = binary ? "appended" : "ascii"; std::string type = (sizeof(T) == 8) ? "Float64" : "Float32"; os << " \n"; offset += attribute.size() * sizeof(T) + sizeof(std::size_t); } else { typedef typename std::vector::const_iterator Iterator; os << "\">\n"; for (Iterator it = attribute.begin(); it != attribute.end(); ++it ) os << *it << " "; os << " \n"; } } // writes the attributes appended data at the end of the .vtu file template void write_attributes(std::ostream& os, const std::vector& att) { write_vector(os,att); } //public API template void write_VTU(std::ostream& os, const C3T3& c3t3) { typedef typename C3T3::Triangulation Tr; typedef typename Tr::Vertex_handle Vertex_handle; const Tr& tr = c3t3.triangulation(); std::map V; //write header os << "\n" << "\n" << " " << "\n"; os << " \n"; bool binary = true; std::size_t offset = 0; write_points_tag(os,tr,V,binary,offset); write_cells_tag(os,c3t3,V,binary,offset); std::vector mids; os << " \n"; write_attribute_tag(os,"MeshDomain",mids,binary,offset); os << " \n"; os << " \n" << " \n"; if (binary) { os << "\n_"; write_points(os,tr,V); // write points before cells to fill the std::map V write_cells(os,c3t3,V, mids);//todo mids should be filled by write_attribute_tag write_attributes(os,mids); } os << "\n"; } } //end CGAL #endif // CGAL_VTK_IO_H