mirror of https://github.com/CGAL/cgal
Merge pull request #2101 from afabri/BGL-read_write_off-GF
BGL: Add generic functions read_off() and write_off()
This commit is contained in:
commit
89acad2d14
|
|
@ -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} \
|
||||
|
|
|
|||
|
|
@ -215,6 +215,9 @@ for conversion between models of different `FaceGraph` concepts, etc.
|
|||
Most functions are in the header file `<CGAL/boost/graph/helpers.h>`
|
||||
*/
|
||||
|
||||
/// \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()`
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -31,18 +31,13 @@ int main(int argc, char** argv )
|
|||
Mesh mesh;
|
||||
|
||||
std::vector<vertex_descriptor> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -28,11 +28,14 @@
|
|||
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
|
||||
#include <CGAL/boost/graph/properties_PolyMesh_ArrayKernelT.h>
|
||||
#include <CGAL/boost/graph/internal/OM_iterator_from_circulator.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/boost/graph/io.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
|
||||
|
|
@ -208,6 +211,15 @@ degree(typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::vertex
|
|||
return sm.valence(v);
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::degree_size_type
|
||||
degree(typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::face_descriptor f,
|
||||
const OpenMesh::PolyMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return sm.valence(f);
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >::degree_size_type
|
||||
|
|
@ -682,6 +694,20 @@ void clear(OpenMesh::PolyMesh_ArrayKernelT<K>& sm)
|
|||
CGAL_postcondition(num_faces(sm) == 0);
|
||||
}
|
||||
|
||||
|
||||
template<typename K>
|
||||
bool read_off(std::istream& is, OpenMesh::PolyMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return OpenMesh::IO::read_mesh(sm, is, ".OFF");
|
||||
}
|
||||
|
||||
|
||||
template<typename K>
|
||||
bool write_off(std::ostream& os, OpenMesh::PolyMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
return OpenMesh::IO::write_mesh(sm, os, ".OFF");
|
||||
}
|
||||
|
||||
}
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
#include <CGAL/boost/graph/backward_compatibility_functions.h>
|
||||
|
|
|
|||
|
|
@ -25,12 +25,15 @@
|
|||
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
|
||||
#include <CGAL/boost/graph/properties_TriMesh_ArrayKernelT.h>
|
||||
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
|
||||
#include <CGAL/boost/graph/internal/OM_iterator_from_circulator.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/Iterator_range.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/boost/graph/io.h>
|
||||
#include <CGAL/assertions.h>
|
||||
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
|
|
@ -136,6 +139,15 @@ degree(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::vertex_
|
|||
return sm.valence(v);
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::degree_size_type
|
||||
degree(typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::face_descriptor,
|
||||
const OpenMesh::TriMesh_ArrayKernelT<K>& )
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
template <typename K>
|
||||
typename boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >::degree_size_type
|
||||
|
|
@ -601,7 +613,40 @@ bool is_valid(OpenMesh::TriMesh_ArrayKernelT<K>& 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<typename K>
|
||||
void clear(OpenMesh::TriMesh_ArrayKernelT<K>& 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<typename K>
|
||||
bool read_off(std::istream& is, OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
OpenMesh::IO::Options ropt;
|
||||
return OpenMesh::IO::read_mesh(sm, is, ".OFF", ropt, false);
|
||||
}
|
||||
|
||||
|
||||
template<typename K>
|
||||
bool write_off(std::ostream& os, OpenMesh::TriMesh_ArrayKernelT<K>& sm)
|
||||
{
|
||||
OpenMesh::IO::Options ropt;
|
||||
return OpenMesh::IO::write_mesh(sm, os, ".OFF", ropt);
|
||||
}
|
||||
|
||||
}
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
#include <CGAL/boost/graph/backward_compatibility_functions.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 <boost/container/flat_map.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
|
||||
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 <typename FaceGraph>
|
||||
bool write_off(std::ostream& os,
|
||||
const FaceGraph& g)
|
||||
{
|
||||
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
|
||||
typedef typename boost::graph_traits<FaceGraph>::vertices_size_type vertices_size_type;
|
||||
typedef typename boost::graph_traits<FaceGraph>::faces_size_type faces_size_type;
|
||||
|
||||
typename boost::property_map<FaceGraph, CGAL::vertex_point_t>::const_type vpm = get(CGAL::vertex_point,g);
|
||||
vertices_size_type nv = static_cast<vertices_size_type>(std::distance(vertices(g).first, vertices(g).second));
|
||||
faces_size_type nf = static_cast<faces_size_type>(std::distance(faces(g).first, faces(g).second));
|
||||
|
||||
os << "OFF\n" << nv << " " << nf << " 0\n";
|
||||
boost::container::flat_map<vertex_descriptor,vertices_size_type> 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 <typename FaceGraph>
|
||||
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 <typename FaceGraph>
|
||||
bool read_off(std::istream& is,
|
||||
FaceGraph& g)
|
||||
{
|
||||
using namespace internal::read_off_tools;
|
||||
|
||||
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<FaceGraph>::vertices_size_type vertices_size_type;
|
||||
typedef typename boost::graph_traits<FaceGraph>::faces_size_type faces_size_type;
|
||||
|
||||
typedef typename boost::property_map<FaceGraph, CGAL::vertex_point_t>::type Vpm;
|
||||
typedef typename boost::property_traits<Vpm>::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<vertex_descriptor> 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<vertex_descriptor> 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 <typename FaceGraph>
|
||||
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
|
||||
|
|
@ -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" )
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
#include <CGAL/boost/graph/io.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||
typedef Kernel::Point_3 Point;
|
||||
typedef CGAL::Surface_mesh<Point> 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;
|
||||
}
|
||||
|
|
@ -395,6 +395,8 @@ and <code>src/</code> directories).
|
|||
a graph adaptor which allows to create virtual borders when marking edges
|
||||
as seam edges.
|
||||
</li>
|
||||
<li>Add the functions <code>read_off()</code> and <code>write_off()</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<!-- Visualization -->
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <TT>.off</TT>, 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<Traits>`
|
||||
\sa `CGAL::Polyhedron_incremental_builder_3<HDS>`
|
||||
\sa `operator<<(std::ostream&, CGAL::Polyhedron_3<PolyhedronTraits_3>&)`
|
||||
\sa \link PkgPolyhedronIOFunc `operator<<(std::ostream&, Polyhedron_3<PolyhedronTraits_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 <class PolyhedronTraits_3>
|
||||
std::istream& operator>>( std::istream& in, CGAL::Polyhedron_3<PolyhedronTraits_3>& P);
|
||||
bool read_off( std::istream& in, Polyhedron_3<PolyhedronTraits_3>& P);
|
||||
|
||||
/*!
|
||||
\relates Polyhedron_3
|
||||
\ingroup PkgPolyhedronIOFunc
|
||||
calls \link read_off() `read_off(in, P)` \endlink.
|
||||
*/
|
||||
template <class PolyhedronTraits_3>
|
||||
std::istream& operator>>( std::istream& in, Polyhedron_3<PolyhedronTraits_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
|
||||
<TT>.off</TT>, 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<Traits>`
|
||||
\sa `CGAL::Polyhedron_incremental_builder_3<HDS>`
|
||||
\sa `operator>>(std::istream&, CGAL::Polyhedron_3<PolyhedronTraits_3>&)`
|
||||
|
||||
\sa \link PkgPolyhedronIOFunc `operator>>(std::istream& in, Polyhedron_3<PolyhedronTraits_3>& P)` \endlink
|
||||
*/
|
||||
template <class PolyhedronTraits_3>
|
||||
std::ostream& operator<<( std::ostream& out, CGAL::Polyhedron_3<PolyhedronTraits_3>& P);
|
||||
bool write_off( std::ostream& out, Polyhedron_3<PolyhedronTraits_3>& P);
|
||||
|
||||
|
||||
/*!
|
||||
\relates Polyhedron_3
|
||||
\ingroup PkgPolyhedronIOFunc
|
||||
calls \link write_off() `write_off(out, P)` \endlink.
|
||||
*/
|
||||
template <class PolyhedronTraits_3>
|
||||
std::ostream& operator<<( std::ostream& out, Polyhedron_3<PolyhedronTraits_3>& P);
|
||||
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
|
|||
|
|
@ -1594,7 +1594,11 @@ public:
|
|||
*/
|
||||
void delegate( CGAL::Modifier_base<HDS>& m);
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
}; /* end Polyhedron_3 */
|
||||
|
||||
|
||||
|
||||
} /* end namespace CGAL */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@ Circulator
|
|||
Stream_support
|
||||
HalfedgeDS
|
||||
Miscellany
|
||||
BGL
|
||||
|
|
|
|||
|
|
@ -100,6 +100,14 @@ in_degree(typename boost::graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::v
|
|||
return v->vertex_degree();
|
||||
}
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::degree_size_type
|
||||
degree(typename boost::graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::face_descriptor f
|
||||
, const CGAL::Polyhedron_3<Gt,I,HDS,A>&)
|
||||
{
|
||||
return f->facet_degree();
|
||||
}
|
||||
|
||||
template<class Gt, class I, CGAL_HDS_PARAM_, class A>
|
||||
typename boost::graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::vertex_descriptor
|
||||
source(typename boost::graph_traits< CGAL::Polyhedron_3<Gt,I,HDS,A> const>::edge_descriptor e
|
||||
|
|
|
|||
|
|
@ -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<Traits,Items,HDS,Alloc>& 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<Traits,Items,HDS,Alloc>& 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<Traits,Items,HDS,Alloc>& 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<Traits,Items,HDS,Alloc>& 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<Traits,Items,HDS,Alloc>& P) {
|
||||
// reads a polyhedron from `in' and appends it to P.
|
||||
CGAL::scan_OFF( in, P);
|
||||
return in;
|
||||
Polyhedron_3<Traits,Items,HDS,Alloc>& P)
|
||||
{
|
||||
read_off(in,P);
|
||||
return in;
|
||||
}
|
||||
|
||||
} //namespace CGAL
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ Returns the previous mode of `s`.
|
|||
*/
|
||||
IO::Mode set_pretty_mode(std::ios& s);
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgIOstreams
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
Manual
|
||||
STL_Extension
|
||||
Geomview
|
||||
Surface_mesh
|
||||
Polyhedron
|
||||
|
|
|
|||
|
|
@ -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 <typename Dummy>
|
||||
struct IO_rep_is_specialized_aux
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ CGAL_INLINE_FUNCTION
|
|||
IO::Mode
|
||||
get_mode(std::ios& i)
|
||||
{
|
||||
return static_cast<IO::Mode>(i.iword(IO::get_static_mode()));
|
||||
return static_cast<IO::Mode>(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
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@
|
|||
#include <CGAL/circulator.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/Surface_mesh/Surface_mesh_fwd.h>
|
||||
#include <CGAL/Surface_mesh/IO.h>
|
||||
#include <CGAL/Surface_mesh/Properties.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
|
||||
#include <CGAL/boost/graph/copy_face_graph.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#include <CGAL/IO/File_scanner_OFF.h>
|
||||
|
|
@ -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 <typename P>
|
||||
std::ostream& operator<<(std::ostream& os, const Surface_mesh<P>& sm)
|
||||
{
|
||||
bool write_off(std::ostream& os, const Surface_mesh<P>& sm) {
|
||||
typedef Surface_mesh<P> 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 <typename P>
|
||||
std::ostream& operator<<(std::ostream& os, const Surface_mesh<P>& 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 <typename P>
|
||||
std::istream& operator>>(std::istream& is, Surface_mesh<P>& sm)
|
||||
bool read_off(std::istream& is, Surface_mesh<P>& sm)
|
||||
{
|
||||
typedef Surface_mesh<P> Mesh;
|
||||
typedef typename Kernel_traits<P>::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<Vertex_index> vertexmap(n);
|
||||
P p;
|
||||
Vector_3 v;
|
||||
typename Mesh::template Property_map<Vertex_index,CGAL::Color> 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<size_type> vr;
|
||||
std::size_t d;
|
||||
|
||||
std::vector<Vertex_index> vr;
|
||||
size_type d, vi;
|
||||
bool fcolored = false;
|
||||
typename Mesh::template Property_map<Face_index,CGAL::Color> fcolor;
|
||||
|
||||
|
|
@ -2103,14 +2117,15 @@ private: //------------------------------------------------------- private data
|
|||
is >> d;
|
||||
vr.resize(d);
|
||||
for(std::size_t j=0; j<d; j++){
|
||||
is >> 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::endl;
|
||||
sm.clear();
|
||||
return is;
|
||||
return false;
|
||||
}
|
||||
|
||||
// the first face will tell us if faces have a color map
|
||||
|
|
@ -2132,10 +2147,20 @@ private: //------------------------------------------------------- private data
|
|||
}
|
||||
}
|
||||
}
|
||||
return is.good();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// \relates Surface_mesh
|
||||
/// This operator calls `read_off(std::istream& , CGAL::Surface_mesh)`.
|
||||
template <typename P>
|
||||
std::istream& operator>>(std::istream& is, Surface_mesh<P>& sm)
|
||||
{
|
||||
read_off(is, sm);
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
/*! @} */
|
||||
|
||||
template <typename P>
|
||||
|
|
|
|||
|
|
@ -127,6 +127,15 @@ degree(typename boost::graph_traits<CGAL::Surface_mesh<P> >::vertex_descriptor v
|
|||
return sm.degree(v);
|
||||
}
|
||||
|
||||
|
||||
template <typename P>
|
||||
typename boost::graph_traits<CGAL::Surface_mesh<P> >::degree_size_type
|
||||
degree(typename boost::graph_traits<CGAL::Surface_mesh<P> >::face_descriptor f,
|
||||
const CGAL::Surface_mesh<P>& sm)
|
||||
{
|
||||
return sm.degree(f);
|
||||
}
|
||||
|
||||
|
||||
template <typename P>
|
||||
typename boost::graph_traits<CGAL::Surface_mesh<P> >::degree_size_type
|
||||
|
|
|
|||
Loading…
Reference in New Issue