diff --git a/BGL/doc/BGL/Doxyfile.in b/BGL/doc/BGL/Doxyfile.in index ffdeece5b0e..55054ac2947 100644 --- a/BGL/doc/BGL/Doxyfile.in +++ b/BGL/doc/BGL/Doxyfile.in @@ -11,7 +11,9 @@ INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Face_filtered_graph.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Dual.h \ ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h \ - ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Seam_mesh.h + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Seam_mesh.h \ + ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/io.h + EXAMPLE_PATH = ${CGAL_Surface_mesh_skeletonization_EXAMPLE_DIR} \ ${CGAL_Surface_mesh_segmentation_EXAMPLE_DIR} \ ${CGAL_Polygon_mesh_processing_EXAMPLE_DIR} \ diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 4b146db2289..e9c07b5543b 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -215,6 +215,9 @@ for conversion between models of different `FaceGraph` concepts, etc. Most functions are in the header file `` */ +/// \defgroup PkgBGLIOFct I/O Functions +/// \ingroup PkgBGL + /*! \addtogroup PkgBGLIterators @@ -412,12 +415,18 @@ user might encounter. - `CGAL::convert_nef_polyhedron_to_polygon_mesh()` - `CGAL::split_graph_into_polylines()` + ## Graph Adaptors ## - `CGAL::Dual` - `CGAL::Face_filtered_graph` - `CGAL::Graph_with_descriptor_with_graph` - `CGAL::Graph_with_descriptor_with_graph_property_map` - `CGAL::Seam_mesh` + +## I/O Functions ## +- `CGAL::read_off()` +- `CGAL::write_off()` + */ /*! diff --git a/BGL/examples/BGL_OpenMesh/TriMesh.cpp b/BGL/examples/BGL_OpenMesh/TriMesh.cpp index c28e11f7886..60a008218db 100644 --- a/BGL/examples/BGL_OpenMesh/TriMesh.cpp +++ b/BGL/examples/BGL_OpenMesh/TriMesh.cpp @@ -31,18 +31,13 @@ int main(int argc, char** argv ) Mesh mesh; std::vector V; - V.push_back(add_vertex(mesh)); - V.push_back(add_vertex(mesh)); - V.push_back(add_vertex(mesh)); - add_face(V.begin(), V.end(), mesh); - - // OpenMesh::IO::read_mesh(mesh, (argc>1)?argv[1]:"in.off"); - + std::ifstream in((argc>1)?argv[1]:"in.off"); + CGAL::read_off(in, mesh); BOOST_FOREACH(vertex_descriptor vd, vertices(mesh)){ BOOST_FOREACH(halfedge_descriptor hd, CGAL::halfedges_around_target(vd,mesh)){ if(! CGAL::is_border(edge(hd,mesh),mesh)){ CGAL::Euler::flip_edge(hd,mesh); - OpenMesh::IO::write_mesh(mesh, (argc>2)?argv[2]:"out.off"); + CGAL::write_off((argc>2)?argv[2]:"out.off", mesh); return 0; } } diff --git a/BGL/examples/BGL_OpenMesh/in.off b/BGL/examples/BGL_OpenMesh/in.off new file mode 100644 index 00000000000..21cfeb04fcd --- /dev/null +++ b/BGL/examples/BGL_OpenMesh/in.off @@ -0,0 +1,8 @@ +OFF +4 2 0 +0 0 0 +1 0 0 +1 1 0 +0 1 0 +3 0 1 2 +3 0 2 3 diff --git a/BGL/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h b/BGL/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h index cee9d776171..5eedbde37eb 100644 --- a/BGL/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h +++ b/BGL/include/CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h @@ -28,11 +28,14 @@ #include +#include + #include #include #include #include #include +#include #include #include @@ -208,6 +211,15 @@ degree(typename boost::graph_traits >::vertex return sm.valence(v); } + +template +typename boost::graph_traits >::degree_size_type +degree(typename boost::graph_traits >::face_descriptor f, + const OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return sm.valence(f); +} + template typename boost::graph_traits >::degree_size_type @@ -682,6 +694,20 @@ void clear(OpenMesh::PolyMesh_ArrayKernelT& sm) CGAL_postcondition(num_faces(sm) == 0); } + +template +bool read_off(std::istream& is, OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return OpenMesh::IO::read_mesh(sm, is, ".OFF"); +} + + +template +bool write_off(std::ostream& os, OpenMesh::PolyMesh_ArrayKernelT& sm) +{ + return OpenMesh::IO::write_mesh(sm, os, ".OFF"); +} + } #ifndef CGAL_NO_DEPRECATED_CODE #include diff --git a/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h b/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h index 657a93ea1ba..899734d5d56 100644 --- a/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h +++ b/BGL/include/CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h @@ -25,12 +25,15 @@ #include +#include + #include #include #include #include #include #include +#include #include #include @@ -136,6 +139,15 @@ degree(typename boost::graph_traits >::vertex_ return sm.valence(v); } + +template +typename boost::graph_traits >::degree_size_type +degree(typename boost::graph_traits >::face_descriptor, + const OpenMesh::TriMesh_ArrayKernelT& ) +{ + return 3; +} + template typename boost::graph_traits >::degree_size_type @@ -601,7 +613,40 @@ bool is_valid(OpenMesh::TriMesh_ArrayKernelT& sm, bool /* verbose */ = false) } // namespace OpenMesh +namespace CGAL { +// Overload CGAL::clear function. TriMesh_ArrayKernel behaves +// differently from other meshes. Calling clear does not affect the +// number of vertices, edges, or faces in the mesh. To get actual +// numbers it is necessary to first collect garbage. We add an +// overlaod to get consistent behavior. +template +void clear(OpenMesh::TriMesh_ArrayKernelT& sm) +{ + sm.clear(); + sm.garbage_collection(true, true, true); + CGAL_postcondition(num_edges(sm) == 0); + CGAL_postcondition(num_vertices(sm) == 0); + CGAL_postcondition(num_faces(sm) == 0); +} + + +template +bool read_off(std::istream& is, OpenMesh::TriMesh_ArrayKernelT& sm) +{ + OpenMesh::IO::Options ropt; + return OpenMesh::IO::read_mesh(sm, is, ".OFF", ropt, false); +} + + +template +bool write_off(std::ostream& os, OpenMesh::TriMesh_ArrayKernelT& sm) +{ + OpenMesh::IO::Options ropt; + return OpenMesh::IO::write_mesh(sm, os, ".OFF", ropt); +} + +} #ifndef CGAL_NO_DEPRECATED_CODE #include diff --git a/BGL/include/CGAL/boost/graph/io.h b/BGL/include/CGAL/boost/graph/io.h new file mode 100644 index 00000000000..4bf5a520912 --- /dev/null +++ b/BGL/include/CGAL/boost/graph/io.h @@ -0,0 +1,203 @@ +// Copyright (c) 2015 GeometryFactory (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 Lesser 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$ +// +// +// Author(s) : Andreas Fabri + +#ifndef CGAL_BOOST_GRAPH_IO_H +#define CGAL_BOOST_GRAPH_IO_H + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +namespace CGAL { +/*! + \ingroup PkgBGLIOFct + writes the graph `g` in the OFF format. + \sa Overloads of this function for specific models of the concept `FaceGraph`. + + */ +template +bool write_off(std::ostream& os, + const FaceGraph& g) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::vertices_size_type vertices_size_type; + typedef typename boost::graph_traits::faces_size_type faces_size_type; + + typename boost::property_map::const_type vpm = get(CGAL::vertex_point,g); + vertices_size_type nv = static_cast(std::distance(vertices(g).first, vertices(g).second)); + faces_size_type nf = static_cast(std::distance(faces(g).first, faces(g).second)); + + os << "OFF\n" << nv << " " << nf << " 0\n"; + boost::container::flat_map reindex; + int n = 0; + BOOST_FOREACH(vertex_descriptor v, vertices(g)){ + os << get(vpm,v) << '\n'; + reindex[v]=n++; + } + + BOOST_FOREACH(face_descriptor f, faces(g)){ + os << degree(f,g); + BOOST_FOREACH(vertex_descriptor v, vertices_around_face(halfedge(f,g),g)){ + os << " " << reindex[v]; + } + os << '\n'; + } + return os.good(); +} + + +/*! + \ingroup PkgBGLIOFct + writes the graph `g` in the OFF format into a file named `fname`. + \sa Overloads of this function for specific models of the concept `FaceGraph`. + + */ +template +bool write_off(const char* fname, + const FaceGraph& g) +{ + std::ofstream out(fname); + if(out.good()){ + return write_off(out,g); + } + return false; +} + + + namespace internal { namespace read_off_tools { + + bool is_whitespace(const std::string& s) + { + for(unsigned int i=0; i < s.size(); i++){ + if(s[i] != ' ' && s[i] != '\t'){ + return false; + } + } + return true; + } + +std::string next_non_comment(std::istream& is) +{ + std::string line; + do { + std::getline(is, line); + }while(line[0] == '#' || is_whitespace(line)); + return line; +} + + } + } // namespace internal + + +/*! + \ingroup PkgBGLIOFct + reads the graph `g` from data in the OFF format. Ignores comment lines which start with a hash, and lines with whitespace. + \sa Overloads of this function for specific models of the concept `FaceGraph`. + \pre The data must represent a 2-manifold + \attention The graph `g` is not cleared, and the data from the stream are added. + + */ +template +bool read_off(std::istream& is, + FaceGraph& g) +{ + using namespace internal::read_off_tools; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::vertices_size_type vertices_size_type; + typedef typename boost::graph_traits::faces_size_type faces_size_type; + + typedef typename boost::property_map::type Vpm; + typedef typename boost::property_traits::value_type Point_3; + Vpm vpm = get(CGAL::vertex_point,g); + vertices_size_type nv, nvf; + faces_size_type nf; + int ignore; + + std::string line = next_non_comment(is); + { + std::istringstream iss(line); + std::string off; + iss >> off; + CGAL_assertion( off == "OFF" || off == "COFF"); + } + line = next_non_comment(is); + { + std::istringstream iss(line); + iss >> nv >> nf >> ignore; + } + + std::vector vertices(nv); + Point_3 p; + for(vertices_size_type i=0; i < nv; i++){ + line = next_non_comment(is); + std::istringstream iss(line); + iss >> p; + vertices[i] = add_vertex(g); + put(vpm,vertices[i],p); + } + + for(faces_size_type i=0; i < nf; i++){ + line = next_non_comment(is); + std::istringstream iss(line); + iss >> nvf; + std::vector face(nvf); + for(vertices_size_type j = 0; j < nvf; j++){ + faces_size_type fvi; + iss >> fvi; + face[j] = vertices[fvi]; + } + Euler::add_face(face,g); + } + return true; +} + + +/*! + \ingroup PkgBGLIOFct + reads the graph `g` from data in the OFF format. Ignores comment lines which start with a hash, and lines with whitespace. + \sa Overloads of this function for specific models of the concept `FaceGraph`. + \pre The data must represent a 2-manifold + \attention The graph `g` is not cleared, and the data from the stream are added. + + */ +template +bool read_off(const char* fname, + FaceGraph& g) +{ + std::ifstream in(fname); + if(in.good()){ + return read_off(in, g); + } + return false; +} + + +} // namespace CGAL + +#endif // CGAL_BOOST_GRAPH_IO_H diff --git a/BGL/test/BGL/CMakeLists.txt b/BGL/test/BGL/CMakeLists.txt index e664cd8fa18..e15afcf3ac8 100644 --- a/BGL/test/BGL/CMakeLists.txt +++ b/BGL/test/BGL/CMakeLists.txt @@ -91,6 +91,8 @@ create_single_source_cgal_program( "test_Has_member_id.cpp" ) create_single_source_cgal_program( "test_cgal_bgl_named_params.cpp" ) +create_single_source_cgal_program( "test_bgl_read_write.cpp" ) + create_single_source_cgal_program( "graph_concept_Face_filtered_graph.cpp" ) create_single_source_cgal_program( "test_Face_filtered_graph.cpp" ) diff --git a/BGL/test/BGL/data/prim.off b/BGL/test/BGL/data/prim.off new file mode 100644 index 00000000000..da9ee71038c --- /dev/null +++ b/BGL/test/BGL/data/prim.off @@ -0,0 +1,24 @@ +OFF +11 7 0 +# vertices + -1 -1 1 + -1 1 1 + 1 1 1 + 1 -1 1 + -1 -1 -1 + -1 1 -1 + 1 1 -1 + 1 -1 -1 + 2 2 2 + 3 2 2 + 3 3 3 + +# facets + 3 3 2 1 + 3 3 1 0 + 4 0 1 5 4 + 4 6 5 1 2 + 4 3 7 6 2 + 4 4 7 3 0 + 4 4 5 6 7 + 3 8 9 10 diff --git a/BGL/test/BGL/test_bgl_read_write.cpp b/BGL/test/BGL/test_bgl_read_write.cpp new file mode 100644 index 00000000000..dcf1c257e4b --- /dev/null +++ b/BGL/test/BGL/test_bgl_read_write.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef CGAL::Surface_mesh Mesh; + + +int main(int argc, char* argv[]) +{ + Mesh sm; + std::ifstream in((argc>1)?argv[1]:"data/prim.off"); + + CGAL::read_off(in,sm); + + CGAL::write_off(std::cout, sm); + + return 0; +} diff --git a/Installation/changes.html b/Installation/changes.html index 899bfd84885..e0793139a9e 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -395,6 +395,8 @@ and src/ directories). a graph adaptor which allows to create virtual borders when marking edges as seam edges. +
  • Add the functions read_off() and write_off(). +
  • diff --git a/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h b/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h index d88c879e179..8e8848d6150 100644 --- a/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h +++ b/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h @@ -4,7 +4,7 @@ namespace CGAL { \relates Polyhedron_3 \ingroup PkgPolyhedronIOFunc -This operator reads a polyhedral surface in Object File Format, OFF, +This function reads a polyhedral surface in %Object File Format, OFF, with file extension .off, which is also understood by Geomview \cgalCite{cgal:p-gmgv16-96}, from the input stream `in` and appends it to the polyhedral surface \f$ P\f$. Only the point coordinates @@ -19,46 +19,65 @@ format automatically and can read both. \sa `CGAL::Polyhedron_3` \sa `CGAL::Polyhedron_incremental_builder_3` -\sa `operator<<(std::ostream&, CGAL::Polyhedron_3&)` +\sa \link PkgPolyhedronIOFunc `operator<<(std::ostream&, Polyhedron_3&)`\endlink +This function overloads the generic function \link PkgBGLIOFct `read_off(std::istream&,FaceGraph)`\endlink. \cgalHeading{Implementation} This operator is implemented using the modifier mechanism for -polyhedral surfaces and the `CGAL::Polyhedron_incremental_builder_3` +polyhedral surfaces and the `Polyhedron_incremental_builder_3` class, which allows the construction in a single, efficient scan pass of the input and handles also all the possible flexibility of the polyhedral surface. */ template -std::istream& operator>>( std::istream& in, CGAL::Polyhedron_3& P); +bool read_off( std::istream& in, Polyhedron_3& P); + +/*! +\relates Polyhedron_3 +\ingroup PkgPolyhedronIOFunc +calls \link read_off() `read_off(in, P)` \endlink. +*/ +template +std::istream& operator>>( std::istream& in, Polyhedron_3& P); /*! \relates Polyhedron_3 \ingroup PkgPolyhedronIOFunc -This operator writes the polyhedral surface \f$P\f$ to the output -stream out using the Object File Format, OFF, with file extension +This function writes the polyhedral surface \f$P\f$ to the output +stream `out` using the %Object File Format, OFF, with file extension .off, which is also understood by GeomView \cgalCite{cgal:p-gmgv16-96}. The output is in ASCII format. From the polyhedral surface, only the point coordinates and facets are written. Neither normal vectors nor color attributes are used. For OFF an ASCII and a binary format exist. The format can be selected -with the \cgal modifiers for streams, ::set_ascii_mode and -set_binary_mode respectively. The modifier ::set_pretty_mode can be used +with the \cgal modifiers for streams, `set_ascii_mode()` and +`set_binary_mode()` respectively. The modifier `set_pretty_mode()` can be used to allow for (a few) structuring comments in the output. Otherwise, the output would be free of comments. The default for writing is ASCII without comments. +This function overloads the generic function \link PkgBGLIOFct `write_off(std::istream&,FaceGraph)` \endlink. + \sa `CGAL::Polyhedron_3` \sa `CGAL::Polyhedron_incremental_builder_3` -\sa `operator>>(std::istream&, CGAL::Polyhedron_3&)` - +\sa \link PkgPolyhedronIOFunc `operator>>(std::istream& in, Polyhedron_3& P)` \endlink */ template -std::ostream& operator<<( std::ostream& out, CGAL::Polyhedron_3& P); +bool write_off( std::ostream& out, Polyhedron_3& P); + + +/*! +\relates Polyhedron_3 +\ingroup PkgPolyhedronIOFunc +calls \link write_off() `write_off(out, P)` \endlink. +*/ +template +std::ostream& operator<<( std::ostream& out, Polyhedron_3& P); } /* namespace CGAL */ diff --git a/Polyhedron/doc/Polyhedron/CGAL/Polyhedron_3.h b/Polyhedron/doc/Polyhedron/CGAL/Polyhedron_3.h index 14476abe9ea..7d7b22d075f 100644 --- a/Polyhedron/doc/Polyhedron/CGAL/Polyhedron_3.h +++ b/Polyhedron/doc/Polyhedron/CGAL/Polyhedron_3.h @@ -1594,7 +1594,11 @@ public: */ void delegate( CGAL::Modifier_base& m); + /// @} }; /* end Polyhedron_3 */ + + + } /* end namespace CGAL */ diff --git a/Polyhedron/doc/Polyhedron/PackageDescription.txt b/Polyhedron/doc/Polyhedron/PackageDescription.txt index 1b1acd2fd7f..aa9cf8ed001 100644 --- a/Polyhedron/doc/Polyhedron/PackageDescription.txt +++ b/Polyhedron/doc/Polyhedron/PackageDescription.txt @@ -60,6 +60,7 @@ surface can be used without knowing the halfedge data structure. ## Functions ## - \link PkgPolyhedronIOFunc `CGAL::operator<<()` \endlink - \link PkgPolyhedronIOFunc `CGAL::operator>>()` \endlink - +- \link PkgPolyhedronIOFunc `write_off()` \endlink +- \link PkgPolyhedronIOFunc `read_off()` \endlink */ diff --git a/Polyhedron/doc/Polyhedron/dependencies b/Polyhedron/doc/Polyhedron/dependencies index c0b5cba3cd2..b37e2f8debe 100644 --- a/Polyhedron/doc/Polyhedron/dependencies +++ b/Polyhedron/doc/Polyhedron/dependencies @@ -6,3 +6,4 @@ Circulator Stream_support HalfedgeDS Miscellany +BGL diff --git a/Polyhedron/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h b/Polyhedron/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h index 69cdfdc1f67..a064a5fb46f 100644 --- a/Polyhedron/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h +++ b/Polyhedron/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h @@ -100,6 +100,14 @@ in_degree(typename boost::graph_traits< CGAL::Polyhedron_3 const>::v return v->vertex_degree(); } +template +typename boost::graph_traits< CGAL::Polyhedron_3 const>::degree_size_type +degree(typename boost::graph_traits< CGAL::Polyhedron_3 const>::face_descriptor f + , const CGAL::Polyhedron_3&) +{ + return f->facet_degree(); +} + template typename boost::graph_traits< CGAL::Polyhedron_3 const>::vertex_descriptor source(typename boost::graph_traits< CGAL::Polyhedron_3 const>::edge_descriptor e diff --git a/Polyhedron_IO/include/CGAL/IO/Polyhedron_iostream.h b/Polyhedron_IO/include/CGAL/IO/Polyhedron_iostream.h index a4453978898..ec99c5c14cc 100644 --- a/Polyhedron_IO/include/CGAL/IO/Polyhedron_iostream.h +++ b/Polyhedron_IO/include/CGAL/IO/Polyhedron_iostream.h @@ -31,28 +31,55 @@ namespace CGAL { + +template < class Traits, + class Items, + template < class T, class I, class A> + class HDS, class Alloc> +bool +write_off( std::ostream& out, const Polyhedron_3& P){ + // writes P to `out' in PRETTY, ASCII or BINARY format + // as the stream indicates. + File_header_OFF header( is_binary( out), ! is_pretty( out), false); + CGAL::print_polyhedron_with_header_OFF( out, P, header); + return out.good(); +} + + +template < class Traits, + class Items, + template < class T, class I, class A> + class HDS, class Alloc> +bool +read_off(std::istream& in, + Polyhedron_3& P) { + // reads a polyhedron from `in' and appends it to P. + CGAL::scan_OFF( in, P); + return in.good(); +} + + template < class Traits, class Items, template < class T, class I, class A> class HDS, class Alloc> std::ostream& -operator<<( std::ostream& out, const Polyhedron_3& P) { - // writes P to `out' in PRETTY, ASCII or BINARY format - // as the stream indicates. - File_header_OFF header( is_binary( out), ! is_pretty( out), false); - CGAL::print_polyhedron_with_header_OFF( out, P, header); - return out; +operator<<( std::ostream& out, const Polyhedron_3& P) +{ + write_off(out,P); + return out; } + template < class Traits, class Items, template < class T, class I, class A> class HDS, class Alloc> std::istream& operator>>(std::istream& in, - Polyhedron_3& P) { - // reads a polyhedron from `in' and appends it to P. - CGAL::scan_OFF( in, P); - return in; + Polyhedron_3& P) +{ + read_off(in,P); + return in; } } //namespace CGAL diff --git a/Stream_support/doc/Stream_support/CGAL/IO/io.h b/Stream_support/doc/Stream_support/CGAL/IO/io.h index fbbea10fea4..549aeea9d8b 100644 --- a/Stream_support/doc/Stream_support/CGAL/IO/io.h +++ b/Stream_support/doc/Stream_support/CGAL/IO/io.h @@ -124,6 +124,7 @@ Returns the previous mode of `s`. */ IO::Mode set_pretty_mode(std::ios& s); + /*! \ingroup PkgIOstreams diff --git a/Stream_support/doc/Stream_support/IOstream.txt b/Stream_support/doc/Stream_support/IOstream.txt index 436c7c41691..f068650ad53 100644 --- a/Stream_support/doc/Stream_support/IOstream.txt +++ b/Stream_support/doc/Stream_support/IOstream.txt @@ -229,6 +229,8 @@ There are a 11 predefined `Color` constants available: `DEEPBLUE`, `BLUE`, `PURPLE`, `VIOLET`, `ORANGE`, and `YELLOW`. + + \section IOstreamStream Stream Support Three classes are provided by \cgal as adaptors to input and output stream diff --git a/Stream_support/doc/Stream_support/dependencies b/Stream_support/doc/Stream_support/dependencies index 1cc7062b2e9..b5b1f36e8f9 100644 --- a/Stream_support/doc/Stream_support/dependencies +++ b/Stream_support/doc/Stream_support/dependencies @@ -1,3 +1,5 @@ Manual STL_Extension Geomview +Surface_mesh +Polyhedron diff --git a/Stream_support/include/CGAL/IO/io.h b/Stream_support/include/CGAL/IO/io.h index f69c1473f72..b928d059b66 100644 --- a/Stream_support/include/CGAL/IO/io.h +++ b/Stream_support/include/CGAL/IO/io.h @@ -41,18 +41,27 @@ namespace CGAL { -class IO { + + +namespace IO { + +class Static { public: - static int get_static_mode() + static int get_mode() { static const int mode = std::ios::xalloc(); return mode; } - enum Mode {ASCII = 0, PRETTY, BINARY}; }; + enum Mode {ASCII = 0, PRETTY, BINARY}; + +} + + + template struct IO_rep_is_specialized_aux { diff --git a/Stream_support/include/CGAL/IO/io_impl.h b/Stream_support/include/CGAL/IO/io_impl.h index ee84373d5a4..d530abbcb6a 100644 --- a/Stream_support/include/CGAL/IO/io_impl.h +++ b/Stream_support/include/CGAL/IO/io_impl.h @@ -40,7 +40,7 @@ CGAL_INLINE_FUNCTION IO::Mode get_mode(std::ios& i) { - return static_cast(i.iword(IO::get_static_mode())); + return static_cast(i.iword(IO::Static::get_mode())); } CGAL_INLINE_FUNCTION @@ -48,7 +48,7 @@ IO::Mode set_ascii_mode(std::ios& i) { IO::Mode m = get_mode(i); - i.iword(IO::get_static_mode()) = IO::ASCII; + i.iword(IO::Static::get_mode()) = IO::ASCII; return m; } @@ -57,7 +57,7 @@ IO::Mode set_binary_mode(std::ios& i) { IO::Mode m = get_mode(i); - i.iword(IO::get_static_mode()) = IO::BINARY; + i.iword(IO::Static::get_mode()) = IO::BINARY; return m; } @@ -67,7 +67,7 @@ IO::Mode set_pretty_mode(std::ios& i) { IO::Mode m = get_mode(i); - i.iword(IO::get_static_mode()) = IO::PRETTY; + i.iword(IO::Static::get_mode()) = IO::PRETTY; return m; } @@ -76,7 +76,7 @@ IO::Mode set_mode(std::ios& i, IO::Mode m) { IO::Mode old = get_mode(i); - i.iword(IO::get_static_mode()) = m; + i.iword(IO::Static::get_mode()) = m; return old; } @@ -84,21 +84,21 @@ CGAL_INLINE_FUNCTION bool is_pretty(std::ios& i) { - return i.iword(IO::get_static_mode()) == IO::PRETTY; + return i.iword(IO::Static::get_mode()) == IO::PRETTY; } CGAL_INLINE_FUNCTION bool is_ascii(std::ios& i) { - return i.iword(IO::get_static_mode()) == IO::ASCII; + return i.iword(IO::Static::get_mode()) == IO::ASCII; } CGAL_INLINE_FUNCTION bool is_binary(std::ios& i) { - return i.iword(IO::get_static_mode()) == IO::BINARY; + return i.iword(IO::Static::get_mode()) == IO::BINARY; } CGAL_INLINE_FUNCTION diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index fa1fcd68d72..176fc819b73 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -42,9 +42,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -1958,13 +1958,14 @@ private: //------------------------------------------------------- private data return sm; } + /// \relates Surface_mesh /// Inserts the surface mesh in an output stream in Ascii OFF format. /// Only the \em point property is inserted in the stream. /// \pre `operator<<(std::ostream&,const P&)` must be defined. + template - std::ostream& operator<<(std::ostream& os, const Surface_mesh

    & sm) - { + bool write_off(std::ostream& os, const Surface_mesh

    & sm) { typedef Surface_mesh

    Mesh; typedef typename Mesh::Vertex_index Vertex_index; typedef typename Mesh::Face_index Face_index; @@ -2006,9 +2007,20 @@ private: //------------------------------------------------------- private data } os << '\n'; } + return os.good(); + } + + /// \relates Surface_mesh + /// + /// This operator calls `write_off(std::istream& , CGAL::Surface_mesh)`. + template + std::ostream& operator<<(std::ostream& os, const Surface_mesh

    & sm) + { + write_off(os, sm); return os; } + /// @cond CGAL_DOCUMENT_INTERNALS inline std::istream& sm_skip_comments( std::istream& in) { @@ -2022,18 +2034,20 @@ private: //------------------------------------------------------- private data in.putback(c); return in; } + + + /// @endcond - /// \relates Surface_mesh - - /// \relates Surface_mesh - /// Extracts the surface mesh from an input stream in Ascii OFF, COFF, NOFF, CNOFF format. + /// Extracts the surface mesh from an input stream in Ascii OFF, COFF, NOFF, CNOFF + /// format and appends it to the surface mesh `sm`. /// The operator reads the point property as well as "v:normal", "v:color", and "f:color". /// Vertex texture coordinates are ignored. /// \pre `operator>>(std::istream&,const P&)` must be defined. + template - std::istream& operator>>(std::istream& is, Surface_mesh

    & sm) + bool read_off(std::istream& is, Surface_mesh

    & sm) { typedef Surface_mesh

    Mesh; typedef typename Kernel_traits

    ::Kernel K; @@ -2041,7 +2055,6 @@ private: //------------------------------------------------------- private data typedef typename Mesh::Face_index Face_index; typedef typename Mesh::Vertex_index Vertex_index; typedef typename Mesh::size_type size_type; - sm.clear(); int n, f, e; std::string off; is >> sm_skip_comments; @@ -2050,7 +2063,8 @@ private: //------------------------------------------------------- private data is >> n >> f >> e; - sm.reserve(n,2*f,e); + sm.reserve(sm.num_vertices()+n, sm.num_faces()+2*f, sm.num_edges()+e); + std::vector vertexmap(n); P p; Vector_3 v; typename Mesh::template Property_map vcolor; @@ -2068,6 +2082,7 @@ private: //------------------------------------------------------- private data is >> sm_skip_comments; is >> p; Vertex_index vi= sm.add_vertex(p); + vertexmap[i] = vi; if(v_has_normals){ is >> v; vnormal[vi] = v; @@ -2092,9 +2107,8 @@ private: //------------------------------------------------------- private data } } } - std::vector vr; - std::size_t d; - + std::vector vr; + size_type d, vi; bool fcolored = false; typename Mesh::template Property_map fcolor; @@ -2103,14 +2117,15 @@ private: //------------------------------------------------------- private data is >> d; vr.resize(d); for(std::size_t j=0; j> vr[j]; + is >> vi; + vr[j] = vertexmap[vi]; } Face_index fi = sm.add_face(vr); if(fi == sm.null_face()) { std::cout<< "Warning: Facets don't seem to be oriented. Loading a Soup of polygons instead."< + std::istream& operator>>(std::istream& is, Surface_mesh

    & sm) + { + read_off(is, sm); return is; } - /*! @} */ template diff --git a/Surface_mesh/include/CGAL/boost/graph/graph_traits_Surface_mesh.h b/Surface_mesh/include/CGAL/boost/graph/graph_traits_Surface_mesh.h index ba3776014ad..ec443d377b5 100644 --- a/Surface_mesh/include/CGAL/boost/graph/graph_traits_Surface_mesh.h +++ b/Surface_mesh/include/CGAL/boost/graph/graph_traits_Surface_mesh.h @@ -127,6 +127,15 @@ degree(typename boost::graph_traits >::vertex_descriptor v return sm.degree(v); } + +template +typename boost::graph_traits >::degree_size_type +degree(typename boost::graph_traits >::face_descriptor f, + const CGAL::Surface_mesh

    & sm) +{ + return sm.degree(f); +} + template typename boost::graph_traits >::degree_size_type