// Copyright (c) 2015-2020 GeometryFactory (France). All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // Author(s) : Andreas Fabri // Mael Rouxel-Labbé #ifndef CGAL_BGL_IO_GOCAD_H #define CGAL_BGL_IO_GOCAD_H #include #include #include #include #include #include #include #include #include #include namespace CGAL { //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // Read namespace IO { namespace internal { // Use CRTP to gain access to the protected members without getters/setters. template class GOCAD_builder : public Generic_facegraph_builder > { typedef GOCAD_builder Self; typedef Generic_facegraph_builder Base; typedef typename Base::Point_container Point_container; typedef typename Base::Face Face; typedef typename Base::Face_container Face_container; public: GOCAD_builder(std::istream& is) : Base(is) { } template bool read(std::istream& is, Point_container& points, Face_container& faces, const NamedParameters& np) { std::pair name_and_color; bool res = read_GOCAD(is, name_and_color, points, faces, np); if(res) { name = name_and_color.first; color = name_and_color.second; } return res; } public: std::string name; std::string color; }; } // namespace internal /// \ingroup PkgBGLIoFuncsGOCAD /// /// \brief reads the graph `g` from the input stream, using the \ref IOStreamGocad. /// /// The data is expected to represent a 2-manifold (possibly with borders). /// /// \attention The graph `g` is not cleared, and the data from the stream are appended. /// /// \tparam Graph a model of `MutableFaceGraph` /// \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" /// /// \param is the input stream /// \param name_and_color name and color of the mesh /// \param g the graph to be built from the input data /// \param np optional \ref bgl_namedparameters "Named Parameters" described below /// /// \cgalNamedParamsBegin /// \cgalParamNBegin{vertex_point_map} /// \cgalParamDescription{a property map associating points to the vertices of `g`} /// \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%vertex_descriptor` /// as key type and `%Point_3` as value type} /// \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} /// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` /// must be available in `Graph`.} /// \cgalParamNEnd /// /// \cgalParamNBegin{verbose} /// \cgalParamDescription{whether extra information is printed when an incident occurs during reading} /// \cgalParamType{Boolean} /// \cgalParamDefault{`false`} /// \cgalParamNEnd /// \cgalNamedParamsEnd /// /// \returns `true` if reading was successful and the resulting mesh is valid, `false` otherwise. /// template bool read_GOCAD(std::istream& is, std::pair& name_and_color, Graph& g, const CGAL_NP_CLASS& np = parameters::default_values() #ifndef DOXYGEN_RUNNING , typename boost::disable_if >::type* = nullptr #endif ) { typedef typename CGAL::GetVertexPointMap::type VPM; typedef typename boost::property_traits::value_type Point; internal::GOCAD_builder builder(is); if(!builder(g, np)) return false; name_and_color.first = builder.name; name_and_color.second = builder.color; return true; } /// \cond SKIP_IN_MANUAL template bool read_GOCAD(std::istream& is, Graph& g, const CGAL_NP_CLASS& np = parameters::default_values(), typename boost::disable_if >::type* = nullptr) { std::pair dummy; return read_GOCAD(is, dummy, g, np); } /// \endcond /// \ingroup PkgBGLIoFuncsGOCAD /// /// \brief reads the graph `g` from the file `fname`, using the \ref IOStreamGocad. /// /// The data is expected to represent a 2-manifold (possibly with borders). /// /// \attention The graph `g` is not cleared, and the data from the file are appended. /// /// \tparam Graph a model of `MutableFaceGraph` /// \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" /// /// \param fname the name of the input file /// \param name_and_color name and color of the mesh /// \param g the graph to be built from the input data /// \param np optional \ref bgl_namedparameters "Named Parameters" described below /// /// \cgalNamedParamsBegin /// \cgalParamNBegin{vertex_point_map} /// \cgalParamDescription{a property map associating points to the vertices of `g`} /// \cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits::%vertex_descriptor` /// as key type and `%Point_3` as value type} /// \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} /// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` /// must be available in `Graph`.} /// \cgalParamNEnd /// /// \cgalParamNBegin{verbose} /// \cgalParamDescription{whether extra information is printed when an incident occurs during reading} /// \cgalParamType{Boolean} /// \cgalParamDefault{`false`} /// \cgalParamNEnd /// \cgalNamedParamsEnd /// /// \sa Overloads of this function for specific models of the concept `FaceGraph`. /// /// \returns `true` if reading was successful and the resulting mesh is valid, `false` otherwise. /// template bool read_GOCAD(const std::string& fname, std::pair& name_and_color, Graph& g, const CGAL_NP_CLASS& np = parameters::default_values() #ifndef DOXYGEN_RUNNING , typename boost::disable_if >::type* = nullptr #endif ) { std::ifstream is(fname); CGAL::IO::set_mode(is, CGAL::IO::ASCII); return read_GOCAD(is, name_and_color, g, np); } /// \cond SKIP_IN_MANUAL template bool read_GOCAD(const std::string& fname, Graph& g, const CGAL_NP_CLASS& np = parameters::default_values(), typename boost::disable_if >::type* = nullptr) { std::pair dummy; return read_GOCAD(fname, dummy, g, np); } /// \endcond //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // Write /// \ingroup PkgBGLIoFuncsGOCAD /// /// \brief writes the graph `g` into the output stream `os`, using the \ref IOStreamGocad. /// /// \tparam Graph a model of `FaceListGraph` /// \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" /// /// \param os the output stream /// \param name the name that will be assigned to `g` in the output file /// \param g the graph to be written /// \param np optional \ref bgl_namedparameters "Named Parameters" described below /// /// \cgalNamedParamsBegin /// \cgalParamNBegin{vertex_point_map} /// \cgalParamDescription{a property map associating points to the vertices of `g`} /// \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` /// as key type and `%Point_3` as value type} /// \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} /// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` /// must be available in `Graph`.} /// \cgalParamNEnd /// /// \cgalParamNBegin{stream_precision} /// \cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream} /// \cgalParamType{int} /// \cgalParamDefault{the precision of the stream `os`} /// \cgalParamNEnd /// \cgalNamedParamsEnd /// /// \returns `true` if writing was successful, `false` otherwise. /// template bool write_GOCAD(std::ostream& os, const char* name, const Graph& g, const CGAL_NP_CLASS& np = parameters::default_values() #ifndef DOXYGEN_RUNNING , typename boost::disable_if >::type* = nullptr #endif ) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef typename boost::graph_traits::vertices_size_type vertices_size_type; using parameters::choose_parameter; using parameters::get_parameter; typename CGAL::GetVertexPointMap::const_type vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), get_const_property_map(CGAL::vertex_point, g)); if(!os.good()) return false; set_stream_precision_from_NP(os, np); os << "GOCAD TSurf 1\n" "HEADER {\n" "name:"; os << name << "\n"; os << "*border:on\n" "*border*bstone:on\n" "}\n" "GOCAD_ORIGINAL_COORDINATE_SYSTEM\n" "NAME Default\n" "AXIS_NAME \"X\" \"Y\" \"Z\"\n" "AXIS_UNIT \"m\" \"m\" \"m\"\n" "ZPOSITIVE Elevation\n" "END_ORIGINAL_COORDINATE_SYSTEM\n" "TFACE\n"; boost::container::flat_map reindex; vertices_size_type i = 0; for(const vertex_descriptor v : vertices(g)) { os << "VRTX " << i << " " << get(vpm, v) << "\n"; reindex[v] = i++; } for(const face_descriptor f : faces(g)) { halfedge_descriptor h = halfedge(f, g); os << "TRGL " << reindex[target(prev(h, g), g)] << " " << reindex[target(h, g)] << " " << reindex[target(next(h, g), g)] << "\n"; } os << "END" << std::endl; return os.good(); } /// \ingroup PkgBGLIoFuncsGOCAD /// /// \brief writes the graph `g` in the \ref IOStreamGocad into `os`. /// /// The name assigned to `g`in the output is `anonymous`. /// /// \tparam Graph a model of `FaceListGraph` /// \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" /// /// \param os the output stream /// \param g the graph to be written /// \param np optional \ref bgl_namedparameters "Named Parameters" described below /// /// \cgalNamedParamsBegin /// \cgalParamNBegin{vertex_point_map} /// \cgalParamDescription{a property map associating points to the vertices of `g`} /// \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` /// as key type and `%Point_3` as value type} /// \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} /// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` /// must be available in `Graph`.} /// \cgalParamNEnd /// /// \cgalParamNBegin{stream_precision} /// \cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream} /// \cgalParamType{int} /// \cgalParamDefault{the precision of the stream `os`} /// \cgalParamNEnd /// \cgalNamedParamsEnd /// /// \returns `true` if writing was successful, `false` otherwise. /// template bool write_GOCAD(std::ostream& os, const Graph& g, const CGAL_NP_CLASS& np = parameters::default_values() #ifndef DOXYGEN_RUNNING , typename boost::disable_if >::type* = nullptr #endif ) { return write_GOCAD(os, "anonymous", g, np); } /// \ingroup PkgBGLIoFuncsGOCAD /// /// \brief writes the graph `g` into a file named `fname`, using the \ref IOStreamGocad. /// /// In this overload, `fname` is used as the name of the graph within the file. /// /// \tparam Graph a model of `FaceListGraph` /// \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters" /// /// \param fname the name of the output file /// \param g the graph to be written /// \param np optional \ref bgl_namedparameters "Named Parameters" described below /// /// \cgalNamedParamsBegin /// \cgalParamNBegin{vertex_point_map} /// \cgalParamDescription{a property map associating points to the vertices of `g`} /// \cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits::%vertex_descriptor` /// as key type and `%Point_3` as value type} /// \cgalParamDefault{`boost::get(CGAL::vertex_point, g)`} /// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` /// must be available in `Graph`.} /// \cgalParamNEnd /// /// \cgalParamNBegin{stream_precision} /// \cgalParamDescription{a parameter used to set the precision (i.e. how many digits are generated) of the output stream} /// \cgalParamType{int} /// \cgalParamDefault{`6`} /// \cgalParamNEnd /// \cgalNamedParamsEnd /// /// \sa Overloads of this function for specific models of the concept `FaceGraph`. /// template bool write_GOCAD(const std::string& fname, const Graph& g, const CGAL_NP_CLASS& np = parameters::default_values() #ifndef DOXYGEN_RUNNING , typename boost::disable_if >::type* = nullptr #endif ) { std::ofstream os(fname); CGAL::IO::set_mode(os, CGAL::IO::ASCII); return write_GOCAD(os, fname.c_str(), g, np); } }} // namespace CGAL::IO #endif // CGAL_BGL_IO_GOCAD_H