From 388a7678e61ca8bc0d449d94a9ffaca43e81e4cb Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 17 May 2017 14:51:54 +0200 Subject: [PATCH] Add an undocumented manipulator which allows operator<< to dispatch OFF, PLY, etc --- .../Polyhedron/CGAL/IO/Polyhedron_iostream.h | 39 ++++++++++---- Polyhedron/doc/Polyhedron/CGAL/Polyhedron_3.h | 16 ------ .../doc/Polyhedron/PackageDescription.txt | 3 +- Polyhedron/doc/Polyhedron/dependencies | 1 + .../doc/Stream_support/CGAL/IO/io.h | 1 + .../doc/Stream_support/IOstream.txt | 7 +++ .../doc/Stream_support/dependencies | 2 + Stream_support/include/CGAL/IO/io.h | 53 +++++++++++++++++-- Stream_support/include/CGAL/IO/io_impl.h | 16 +++--- .../include/CGAL/Surface_mesh/Surface_mesh.h | 21 ++++---- 10 files changed, 110 insertions(+), 49 deletions(-) diff --git a/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h b/Polyhedron/doc/Polyhedron/CGAL/IO/Polyhedron_iostream.h index 533f52fc176..b0f7fdb95f6 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 \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 +This operator calls `read_off(std::istream& , Polyhedron_3)`. +*/ +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 `write_off(std::istream&,FaceGraph)`. + \sa `CGAL::Polyhedron_3` \sa `CGAL::Polyhedron_incremental_builder_3` -\sa `operator>>(std::istream&, CGAL::Polyhedron_3&)` +\sa `operator>>(std::istream&, Polyhedron_3&)` +*/template +bool write_off( std::ostream& out, Polyhedron_3& P); + + +/*! +\relates Polyhedron_3 +\ingroup PkgPolyhedronIOFunc +This operator calls `write_off(std::istream& , Polyhedron_3)`. */ template -std::ostream& operator<<( std::ostream& out, CGAL::Polyhedron_3& P); +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 16955bda7b0..7d7b22d075f 100644 --- a/Polyhedron/doc/Polyhedron/CGAL/Polyhedron_3.h +++ b/Polyhedron/doc/Polyhedron/CGAL/Polyhedron_3.h @@ -1600,21 +1600,5 @@ public: }; /* end Polyhedron_3 */ -/*! -\relates Polyhedron_3 -\ingroup PkgPolyhedronIOFunc - -*/ -template -bool read_off( std::istream& in, CGAL::Polyhedron_3& P); - -/*! -\relates Polyhedron_3 -\ingroup PkgPolyhedronIOFunc - -*/ -template -bool write_off( std::ostream& out, CGAL::Polyhedron_3& P); - } /* 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/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..ae74c0361be 100644 --- a/Stream_support/doc/Stream_support/IOstream.txt +++ b/Stream_support/doc/Stream_support/IOstream.txt @@ -229,6 +229,13 @@ There are a 11 predefined `Color` constants available: `DEEPBLUE`, `BLUE`, `PURPLE`, `VIOLET`, `ORANGE`, and `YELLOW`. +\section IOstreamManipulators Manipulators for IO of polyhedral surfaces. + +There exists plenty of file formats for polyhedral surfaces, which can be +stored in a `Polyhedron` or a `Surface_mesh`. For the insert and extract +operators \cgal provides manipulators such as `CGAL::IO::off`, `CGAL::IO:ply`. + + \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..310bdfa6818 100644 --- a/Stream_support/include/CGAL/IO/io.h +++ b/Stream_support/include/CGAL/IO/io.h @@ -41,18 +41,65 @@ 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}; + + static int get_file_format() + { + static const int file_format = std::ios::xalloc(); + return file_format; + } + }; + enum Mode {ASCII = 0, PRETTY, BINARY}; + + enum File_format {OFF = 0, COFF, PLY, OBJ, STL}; + +} + +std::ios& off(std::ios& os) +{ + os.iword(IO::Static::get_file_format()) = IO::OFF; + return os; +} + + +std::ios& ply(std::ios& os) +{ + os.iword(IO::Static::get_file_format()) = IO::PLY; + return os; +} + +std::ios& obj(std::ios& os) +{ + os.iword(IO::Static::get_file_format()) = IO::OBJ; + return os; +} + +std::ios& stl(std::ios& os) +{ + os.iword(IO::Static::get_file_format()) = IO::STL; + return os; +} + + IO::File_format file_format(std::ios& os) + { + return static_cast(os.iword(IO::Static::get_file_format())); + } + + 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..b3160cdf501 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(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(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(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(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(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(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(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(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 ef627ff6def..91d90a58d15 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -1989,16 +1989,17 @@ private: //------------------------------------------------------- private data return os.good(); } - /// \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. - + /// + /// 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); + if(file_format(os) == IO::OFF){ + write_off(os, sm); + } else { + std::cerr << "For Surface_mesh we only support the OFF file format" << std::endl; + } return os; } @@ -2022,7 +2023,8 @@ private: //------------------------------------------------------- private data /// @endcond /// \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. @@ -2134,10 +2136,7 @@ private: //------------------------------------------------------- private data /// \relates Surface_mesh - /// Extracts the surface mesh from an input stream in Ascii OFF, COFF, NOFF, CNOFF format. - /// 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. + /// This operator calls `read_off(std::istream& , CGAL::Surface_mesh)`. template std::istream& operator>>(std::istream& is, Surface_mesh

& sm) {