mirror of https://github.com/CGAL/cgal
Re-organize and improve BGL IO
This commit is contained in:
parent
6a5972cc3b
commit
423ae6ec84
|
|
@ -0,0 +1,287 @@
|
||||||
|
// Copyright (c) 2015 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 <CGAL/boost/graph/IO/Generic_facegraph_builder.h>
|
||||||
|
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
#include <CGAL/boost/graph/iterator.h>
|
||||||
|
|
||||||
|
#include <boost/container/flat_map.hpp>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Read
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Use CRTP to gain access to the protected members without getters/setters.
|
||||||
|
template <typename FaceGraph, typename Point>
|
||||||
|
class GOCAD_builder
|
||||||
|
: public Generic_facegraph_builder<FaceGraph, Point, GOCAD_builder<FaceGraph, Point> >
|
||||||
|
{
|
||||||
|
typedef GOCAD_builder<FaceGraph, Point> Self;
|
||||||
|
typedef Generic_facegraph_builder<FaceGraph, Point, Self> 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_) { }
|
||||||
|
|
||||||
|
// Implementation of the two functions required by the generic builder
|
||||||
|
bool read(std::istream& input,
|
||||||
|
Point_container& points,
|
||||||
|
Face_container& faces)
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
char c;
|
||||||
|
std::string s, tface("TFACE");
|
||||||
|
int i,j,k;
|
||||||
|
Point p;
|
||||||
|
bool vertices_read = false;
|
||||||
|
|
||||||
|
while(input >> s)
|
||||||
|
{
|
||||||
|
if(s == tface)
|
||||||
|
break;
|
||||||
|
|
||||||
|
std::string::size_type idx;
|
||||||
|
if((idx = s.find("name")) != std::string::npos)
|
||||||
|
{
|
||||||
|
std::istringstream str(s.substr(idx + 5));
|
||||||
|
str >> this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((idx = s.find("color")) != std::string::npos)
|
||||||
|
{
|
||||||
|
std::istringstream str(s.substr(idx + 6));
|
||||||
|
str >> this->color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::getline(input, s);
|
||||||
|
|
||||||
|
while(input.get(c))
|
||||||
|
{
|
||||||
|
if((c == 'V') || (c == 'P'))
|
||||||
|
{
|
||||||
|
input >> s >> i >> p; // @fixme check for failure
|
||||||
|
if(!vertices_read)
|
||||||
|
{
|
||||||
|
vertices_read = true;
|
||||||
|
offset -= i; // Some files start with index 0 others with 1
|
||||||
|
}
|
||||||
|
|
||||||
|
points.push_back(p);
|
||||||
|
}
|
||||||
|
else if(vertices_read && (c == 'T'))
|
||||||
|
{
|
||||||
|
input >> c >> c >> c >> i >> j >> k;
|
||||||
|
typename Base::Face new_face(3);
|
||||||
|
new_face[0] = offset+i;
|
||||||
|
new_face[1] = offset+j;
|
||||||
|
new_face[2] = offset+k;
|
||||||
|
faces.push_back(new_face);
|
||||||
|
}
|
||||||
|
else if(c == 'E')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::getline(input, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
reads the graph `g` from data in the TS format.
|
||||||
|
`name` and `color` will be filled according to the values contained in the file.
|
||||||
|
|
||||||
|
\pre The data must represent a 2-manifold
|
||||||
|
|
||||||
|
\attention The graph `g` is not cleared, and the data from the stream are added.
|
||||||
|
|
||||||
|
\see \ref IOStreamGocad
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_GOCAD(std::istream& in,
|
||||||
|
std::string& name,
|
||||||
|
std::string& color,
|
||||||
|
FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, CGAL_BGL_NP_CLASS>::type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||||
|
|
||||||
|
IO::internal::GOCAD_builder<FaceGraph, Point> builder(in);
|
||||||
|
if(!builder(g, np))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
name = builder.name;
|
||||||
|
color = builder.color;
|
||||||
|
|
||||||
|
return g.is_valid(); // @fixme keep validity check?
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
reads the graph `g` from data in the TS format.
|
||||||
|
|
||||||
|
\sa Overloads of this function for specific models of the concept `FaceGraph`.
|
||||||
|
|
||||||
|
\pre The data must represent a 2-manifold
|
||||||
|
|
||||||
|
\see \ref IOStreamGOCAD
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_GOCAD(const char* fname, FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
std::ifstream in(fname);
|
||||||
|
std::string unused_name;
|
||||||
|
std::string unused_color;
|
||||||
|
|
||||||
|
return read_GOCAD(in, unused_name, unused_color, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_GOCAD(const std::string& fname, FaceGraph& g, CGAL_BGL_NP_CLASS np)
|
||||||
|
{
|
||||||
|
return read_GOCAD(fname.c_str(), g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_GOCAD(std::istream& is, FaceGraph& g) { return read_GOCAD(is, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_GOCAD(const char* fname, FaceGraph& g) { return read_GOCAD(fname, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_GOCAD(const std::string& fname, FaceGraph& g) { return read_GOCAD(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Write
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
writes the graph `g` in the TS format into `os`. `fname` is the
|
||||||
|
mandatory name that will be assigned to `g`in the file.
|
||||||
|
|
||||||
|
\see \ref IOStreamGocad
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_GOCAD(std::ostream& os,
|
||||||
|
const char* fname,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::halfedge_descriptor halfedge_descriptor;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::vertices_size_type vertices_size_type;
|
||||||
|
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
using parameters::get_parameter;
|
||||||
|
|
||||||
|
typename CGAL::GetVertexPointMap<FaceGraph, CGAL_BGL_NP_CLASS>::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;
|
||||||
|
|
||||||
|
os << "GOCAD TSurf 1\n"
|
||||||
|
"HEADER {\n"
|
||||||
|
"name:";
|
||||||
|
os << fname << std::endl;
|
||||||
|
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";
|
||||||
|
|
||||||
|
os.precision(16);
|
||||||
|
|
||||||
|
boost::container::flat_map<vertex_descriptor, vertices_size_type> 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 PkgBGLIOFct
|
||||||
|
|
||||||
|
writes the graph `g` in the TS format into a file named `fname`.
|
||||||
|
|
||||||
|
\sa Overloads of this function for specific models of the concept `FaceGraph`.
|
||||||
|
|
||||||
|
\see \ref IOStreamGOCAD
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_GOCAD(const char* fname,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
std::ofstream out(fname);
|
||||||
|
return write_GOCAD(out, fname, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_GOCAD(const std::string& fname, const FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
return write_GOCAD(fname.c_str(), g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_GOCAD(const char* fname, const FaceGraph& g) { return write_GOCAD(fname, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_GOCAD(const std::string& fname, const FaceGraph& g) { return write_GOCAD(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_BGL_IO_GOCAD_H
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
// Copyright (c) 2019 GeometryFactory
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org);
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Maxime Gimeno
|
||||||
|
|
||||||
|
#ifndef CGAL_BGL_IO_GENERIC_FACEGRAPH_BUILDER_H
|
||||||
|
#define CGAL_BGL_IO_GENERIC_FACEGRAPH_BUILDER_H
|
||||||
|
|
||||||
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace CGAL{
|
||||||
|
namespace IO {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <class FaceGraph, class Point, class Derived>
|
||||||
|
class Generic_facegraph_builder
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef std::vector<Point> Point_container;
|
||||||
|
typedef typename Point_container::size_type size_type;
|
||||||
|
typedef std::vector<std::size_t> Face;
|
||||||
|
typedef std::vector<Face> Face_container;
|
||||||
|
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Generic_facegraph_builder(std::istream& in_) : m_in(in_) { }
|
||||||
|
|
||||||
|
// must be implemented by the derived class
|
||||||
|
bool read()
|
||||||
|
{
|
||||||
|
if(!m_in.good())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return static_cast<Derived*>(this)->read(m_in, m_points, m_faces);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename NamedParameters>
|
||||||
|
bool construct(FaceGraph& g,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, NamedParameters>::type VPM;
|
||||||
|
VPM vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_property_map(CGAL::vertex_point, g));
|
||||||
|
|
||||||
|
std::vector<vertex_descriptor> vertices(m_points.size());
|
||||||
|
for(std::size_t id = 0, ps=m_points.size(); id<ps; ++id)
|
||||||
|
{
|
||||||
|
vertices[id] = add_vertex(g);
|
||||||
|
put(vpm, vertices[id], m_points[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_type i=0, fs=m_faces.size(); i<fs; ++i)
|
||||||
|
{
|
||||||
|
std::vector<vertex_descriptor> face(m_faces[i].size());
|
||||||
|
for(std::size_t j=0, fs=face.size(); j<fs; ++j)
|
||||||
|
face[j] = vertices[m_faces[i][j]];
|
||||||
|
|
||||||
|
face_descriptor f = CGAL::Euler::add_face(face, g);
|
||||||
|
if(f == boost::graph_traits<FaceGraph>::null_face())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_valid_polygon_mesh(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename NamedParameters>
|
||||||
|
bool operator()(FaceGraph& g, const NamedParameters& np)
|
||||||
|
{
|
||||||
|
if(!read())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return construct(g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name, color;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::istream& m_in;
|
||||||
|
|
||||||
|
Point_container m_points;
|
||||||
|
Face_container m_faces;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end internal
|
||||||
|
} // end IO
|
||||||
|
} // end CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_BGL_IO_GENERIC_FACEGRAPH_BUILDER_H
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
// Copyright (c) 2015 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_INP_H
|
||||||
|
#define CGAL_BGL_IO_INP_H
|
||||||
|
|
||||||
|
#include <CGAL/boost/graph/iterator.h>
|
||||||
|
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
#include <boost/container/flat_map.hpp>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_INP(std::ostream& os,
|
||||||
|
std::string name,
|
||||||
|
std::string type,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
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 CGAL::GetVertexPointMap<FaceGraph, CGAL_BGL_NP_CLASS>::const_type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::reference Point_ref;
|
||||||
|
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
using parameters::get_parameter;
|
||||||
|
|
||||||
|
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, g));
|
||||||
|
|
||||||
|
if(!os.good())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
os << "*Part, name=" << name << "\n*Node\n";
|
||||||
|
boost::container::flat_map<vertex_descriptor,vertices_size_type> reindex;
|
||||||
|
int n = 1;
|
||||||
|
for(const vertex_descriptor v : vertices(g))
|
||||||
|
{
|
||||||
|
Point_ref p = get(vpm,v);
|
||||||
|
os << n << ", " << p.x() << ", " << p.y() << ", " << p.z() << '\n';
|
||||||
|
reindex[v] = n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = 1;
|
||||||
|
os << "*Element, type=" << type << std::endl;
|
||||||
|
for(const face_descriptor f : faces(g))
|
||||||
|
{
|
||||||
|
os << n++;
|
||||||
|
for(const vertex_descriptor v : CGAL::vertices_around_face(halfedge(f, g), g))
|
||||||
|
os << ", " << reindex[v];
|
||||||
|
|
||||||
|
os << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "*End Part"<< std::endl;
|
||||||
|
|
||||||
|
return os.good();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_INP(const char* fname,
|
||||||
|
const std::string type,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
std::ofstream out(fname);
|
||||||
|
return write_INP(out, fname, type, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_INP(std::ostream& os, std::string name, std::string type, const FaceGraph& g)
|
||||||
|
{
|
||||||
|
return write_INP(os, name, type, g, parameters::all_default());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_INP(const char* fname, const std::string type, const FaceGraph& g)
|
||||||
|
{
|
||||||
|
return write_INP(fname, type, g, parameters::all_default());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_BGL_IO_INP_H
|
||||||
|
|
@ -0,0 +1,228 @@
|
||||||
|
// Copyright (c) 2015 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_OBJ_H
|
||||||
|
#define CGAL_BGL_IO_OBJ_H
|
||||||
|
|
||||||
|
#include <CGAL/boost/graph/IO/Generic_facegraph_builder.h>
|
||||||
|
#include <CGAL/IO/OBJ.h>
|
||||||
|
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
|
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Read
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Use CRTP to gain access to the protected members without getters/setters.
|
||||||
|
template <typename FaceGraph, typename Point>
|
||||||
|
class OBJ_builder
|
||||||
|
: public Generic_facegraph_builder<FaceGraph, Point, OBJ_builder<FaceGraph, Point> >
|
||||||
|
{
|
||||||
|
typedef OBJ_builder<FaceGraph, Point> Self;
|
||||||
|
typedef Generic_facegraph_builder<FaceGraph, Point, Self> Base;
|
||||||
|
|
||||||
|
typedef typename Base::Point_container Point_container;
|
||||||
|
typedef typename Base::Face Face;
|
||||||
|
typedef typename Base::Face_container Face_container;
|
||||||
|
|
||||||
|
public:
|
||||||
|
OBJ_builder(std::istream& is_) : Base(is_) { }
|
||||||
|
|
||||||
|
// Implementation of the two functions required by the generic builder
|
||||||
|
bool read(std::istream& input, Point_container& points, Face_container& faces)
|
||||||
|
{
|
||||||
|
return read_OBJ(input, points, faces);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
reads the graph `g` from the stream `in` in the OBJ format.
|
||||||
|
|
||||||
|
\returns `true` if the resulting mesh is valid.
|
||||||
|
|
||||||
|
\pre The data must represent a 2-manifold
|
||||||
|
|
||||||
|
\see \ref IOStreamOBJ
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_OBJ(std::istream& in,
|
||||||
|
FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, CGAL_BGL_NP_CLASS>::type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||||
|
|
||||||
|
IO::internal::OBJ_builder<FaceGraph, Point> builder(in);
|
||||||
|
return builder(g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\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.
|
||||||
|
|
||||||
|
\see \ref IOStreamOFF
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_OBJ(const char* fname,
|
||||||
|
FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
std::ifstream in(fname);
|
||||||
|
return read_OBJ(in, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_OBJ(const std::string& fname,
|
||||||
|
FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
return read_OBJ(fname.c_str(), g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_OBJ(std::istream& is, FaceGraph& g) { return read_OBJ(is, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_OBJ(const char* fname, FaceGraph& g) { return read_OBJ(fname, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_OBJ(const std::string& fname, FaceGraph& g) { return read_OBJ(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Write
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
writes the graph `g` in the OBJ format.
|
||||||
|
|
||||||
|
\returns `true` if writing was successful.
|
||||||
|
|
||||||
|
\see \ref IOStreamOBJ
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_OBJ(std::ostream& os,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
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>::face_descriptor face_descriptor;
|
||||||
|
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, CGAL_BGL_NP_CLASS>::const_type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::reference Point_ref;
|
||||||
|
|
||||||
|
VPM vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, g));
|
||||||
|
|
||||||
|
if(!os.good())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CGAL::File_writer_wavefront writer;
|
||||||
|
writer.write_header(os, num_vertices(g), num_halfedges(g), num_faces(g));
|
||||||
|
|
||||||
|
boost::container::flat_map<vertex_descriptor, vertices_size_type> index_map;
|
||||||
|
vertices_size_type id = 0;
|
||||||
|
|
||||||
|
for(vertex_descriptor v : vertices(g))
|
||||||
|
{
|
||||||
|
Point_ref p = get(vpm, v);
|
||||||
|
writer.write_vertex(::CGAL::to_double(p.x()),
|
||||||
|
::CGAL::to_double(p.y()),
|
||||||
|
::CGAL::to_double(p.z()));
|
||||||
|
index_map[v] = id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.write_facet_header();
|
||||||
|
for(face_descriptor f : faces(g))
|
||||||
|
{
|
||||||
|
CGAL::Halfedge_around_face_circulator<FaceGraph> hc(halfedge(f, g), g);
|
||||||
|
CGAL::Halfedge_around_face_circulator<FaceGraph> hc_end = hc;
|
||||||
|
|
||||||
|
const std::size_t n = circulator_size(hc);
|
||||||
|
CGAL_assertion(n >= 3);
|
||||||
|
|
||||||
|
writer.write_facet_begin(n);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
writer.write_facet_vertex_index(index_map[target(*hc, g)]);
|
||||||
|
++hc;
|
||||||
|
}
|
||||||
|
while(hc != hc_end);
|
||||||
|
|
||||||
|
writer.write_facet_end();
|
||||||
|
}
|
||||||
|
writer.write_footer();
|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|
\see \ref IOStreamOFF
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_OBJ(const char* fname,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
std::ofstream out(fname);
|
||||||
|
return write_OBJ(out, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_OBJ(const std::string& fname, const FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
return write_OBJ(fname.c_str(), g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_OBJ(std::ostream& os, const FaceGraph& g) { return write_OBJ(os, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_OBJ(const char* fname, const FaceGraph& g) { return write_OBJ(fname, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_OBJ(const std::string& fname, const FaceGraph& g) { return write_OBJ(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_BGL_IO_OBJ_H
|
||||||
|
|
@ -0,0 +1,289 @@
|
||||||
|
// Copyright (c) 2015 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
|
||||||
|
|
||||||
|
#ifndef CGAL_BGL_IO_OFF_H
|
||||||
|
#define CGAL_BGL_IO_OFF_H
|
||||||
|
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
|
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
#include <boost/container/flat_map.hpp>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// @todo reintroduce deprecated versions of the functions using lower case file formats
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Read
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
namespace internal {
|
||||||
|
namespace read_off_tools {
|
||||||
|
|
||||||
|
inline 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline 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 read_off_tools
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
reads the graph `g` from data in the OFF format. Ignores comment lines which start with a hash, and lines with whitespace.
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `g`.
|
||||||
|
If this parameter is omitted, an internal property map for
|
||||||
|
`CGAL::vertex_point_t` should be available in `FaceGraph`\cgalParamEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\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.
|
||||||
|
|
||||||
|
\see \ref IOStreamOFF
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_OFF(std::istream& is,
|
||||||
|
FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
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>::face_descriptor face_descriptor;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::faces_size_type faces_size_type;
|
||||||
|
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, CGAL_BGL_NP_CLASS>::type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||||
|
|
||||||
|
using namespace IO::internal::read_off_tools;
|
||||||
|
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
using parameters::get_parameter;
|
||||||
|
|
||||||
|
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_property_map(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 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];
|
||||||
|
}
|
||||||
|
|
||||||
|
face_descriptor f = CGAL::Euler::add_face(face, g);
|
||||||
|
if(f == boost::graph_traits<FaceGraph>::null_face())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
\see \ref IOStreamOFF
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_OFF(const char* fname,
|
||||||
|
FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
std::ifstream in(fname);
|
||||||
|
return read_OFF(in, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_OFF(const std::string& fname, FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
return read_OFF(fname.c_str(), g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_OFF(std::istream& is, FaceGraph& g) { return read_OFF(is, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_OFF(const char* fname, FaceGraph& g) { return read_OFF(fname, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_OFF(const std::string& fname, FaceGraph& g) { return read_OFF(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Write
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
writes the graph `g` in the OFF format.
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `g`.
|
||||||
|
If this parameter is omitted, an internal property map for
|
||||||
|
`CGAL::vertex_point_t` should be available in `FaceGraph`
|
||||||
|
\cgalParamEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\sa Overloads of this function for specific models of the concept `FaceGraph`.
|
||||||
|
|
||||||
|
\see \ref IOStreamOFF
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_OFF(std::ostream& os,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
using parameters::get_parameter;
|
||||||
|
|
||||||
|
typename CGAL::GetVertexPointMap<FaceGraph, CGAL_BGL_NP_CLASS>::const_type
|
||||||
|
vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(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));
|
||||||
|
|
||||||
|
if(!os.good())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
os << "OFF\n"
|
||||||
|
<< nv << " " << nf << " 0\n";
|
||||||
|
|
||||||
|
boost::container::flat_map<vertex_descriptor, vertices_size_type> reindex;
|
||||||
|
int n = 0;
|
||||||
|
for(vertex_descriptor v : vertices(g))
|
||||||
|
{
|
||||||
|
os << get(vpm, v) << '\n';
|
||||||
|
reindex[v] = n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(face_descriptor f : faces(g))
|
||||||
|
{
|
||||||
|
os << degree(f, g);
|
||||||
|
for(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`.
|
||||||
|
|
||||||
|
\see \ref IOStreamOFF
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_OFF(const char* fname,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
std::ofstream out(fname);
|
||||||
|
return write_OFF(out, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_OFF(const std::string& fname, const FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
return write_OFF(fname.c_str(), g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_OFF(std::ostream& os, const FaceGraph& g) { return write_OFF(os, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_OFF(const char* fname, const FaceGraph& g) { return write_OFF(fname, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_OFF(const std::string& fname, const FaceGraph& g) { return write_OFF(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_BGL_IO_OFF_H
|
||||||
|
|
@ -0,0 +1,218 @@
|
||||||
|
// Copyright (c) 2015 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_STL_H
|
||||||
|
#define CGAL_BGL_IO_STL_H
|
||||||
|
|
||||||
|
#include <CGAL/boost/graph/IO/Generic_facegraph_builder.h>
|
||||||
|
#include <CGAL/IO/STL.h>
|
||||||
|
|
||||||
|
#include <CGAL/assertions.h>
|
||||||
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Read
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// Use CRTP to gain access to the protected members without getters/setters.
|
||||||
|
template <typename FaceGraph, typename Point>
|
||||||
|
class STL_builder
|
||||||
|
: public Generic_facegraph_builder<FaceGraph, Point, STL_builder<FaceGraph, Point> >
|
||||||
|
{
|
||||||
|
typedef STL_builder<FaceGraph, Point> Self;
|
||||||
|
typedef Generic_facegraph_builder<FaceGraph, Point, Self> Base;
|
||||||
|
|
||||||
|
typedef typename Base::Point_container Point_container;
|
||||||
|
typedef typename Base::Face Face;
|
||||||
|
typedef typename Base::Face_container Face_container;
|
||||||
|
|
||||||
|
public:
|
||||||
|
STL_builder(std::istream& is_) : Base(is_) { }
|
||||||
|
|
||||||
|
bool read(std::istream& input, Point_container& points, Face_container& faces)
|
||||||
|
{
|
||||||
|
return read_STL(input, points, faces);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_STL(std::istream& in,
|
||||||
|
FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, CGAL_BGL_NP_CLASS>::type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||||
|
|
||||||
|
IO::internal::STL_builder<FaceGraph, Point> builder(in);
|
||||||
|
return builder(g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
reads the graph `g` from data in the STL format.
|
||||||
|
|
||||||
|
\sa Overloads of this function for specific models of the concept `FaceGraph`.
|
||||||
|
|
||||||
|
\pre The data must represent a 2-manifold
|
||||||
|
|
||||||
|
\see \ref IOStreamSTL
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_STL(const char* fname, FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
std::ifstream in(fname);
|
||||||
|
return read_STL(in, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_STL(const std::string& fname, FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
return read_STL(fname.c_str(), g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_STL(std::istream& is, FaceGraph& g) { return read_STL(is, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_STL(const char* fname, FaceGraph& g) { return read_STL(fname, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool read_STL(const std::string& fname, FaceGraph& g) { return read_STL(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Write
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
writes the graph `g` in the stream `out` in the STL format.
|
||||||
|
|
||||||
|
\pre The graph must contain only triangle faces.
|
||||||
|
|
||||||
|
\see \ref IOStreamSTL
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_STL(std::ostream& out,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::halfedge_descriptor halfedge_descriptor;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
|
||||||
|
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, CGAL_BGL_NP_CLASS>::const_type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::reference Point_ref;
|
||||||
|
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||||
|
typedef typename Kernel_traits<Point>::Kernel::Vector_3 Vector;
|
||||||
|
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
using parameters::get_parameter;
|
||||||
|
|
||||||
|
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, g));
|
||||||
|
|
||||||
|
if(!out.good())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(get_mode(out) == IO::BINARY)
|
||||||
|
{
|
||||||
|
out << "FileType: Binary ";
|
||||||
|
const boost::uint32_t N32 = static_cast<boost::uint32_t>(faces(g).size());
|
||||||
|
out.write(reinterpret_cast<const char *>(&N32), sizeof(N32));
|
||||||
|
|
||||||
|
for(const face_descriptor f : faces(g))
|
||||||
|
{
|
||||||
|
const halfedge_descriptor h = halfedge(f, g);
|
||||||
|
Point_ref p = get(vpm, target(h, g));
|
||||||
|
Point_ref q = get(vpm, target(next(h, g), g));
|
||||||
|
Point_ref r = get(vpm, source(h, g));
|
||||||
|
|
||||||
|
Vector n = collinear(p, q, r) ? Vector(1, 0, 0) : unit_normal(p, q, r);
|
||||||
|
|
||||||
|
const float coords[12] =
|
||||||
|
{
|
||||||
|
static_cast<float>(n.x()), static_cast<float>(n.y()), static_cast<float>(n.z()),
|
||||||
|
static_cast<float>(p.x()), static_cast<float>(p.y()), static_cast<float>(p.z()),
|
||||||
|
static_cast<float>(q.x()), static_cast<float>(q.y()), static_cast<float>(q.z()),
|
||||||
|
static_cast<float>(r.x()), static_cast<float>(r.y()), static_cast<float>(r.z()) };
|
||||||
|
|
||||||
|
for(int i=0; i<12; ++i)
|
||||||
|
out.write(reinterpret_cast<const char *>(&coords[i]), sizeof(coords[i]));
|
||||||
|
out << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out << "solid\n";
|
||||||
|
for(const face_descriptor f : faces(g))
|
||||||
|
{
|
||||||
|
halfedge_descriptor h = halfedge(f, g);
|
||||||
|
Point_ref p = get(vpm, target(h, g));
|
||||||
|
Point_ref q = get(vpm, target(next(h, g), g));
|
||||||
|
Point_ref r = get(vpm, source(h, g));
|
||||||
|
Vector n = collinear(p, q, r) ? Vector(1, 0, 0) : unit_normal(p, q, r);
|
||||||
|
|
||||||
|
out << "facet normal " << n << "\nouter loop\n";
|
||||||
|
out << "vertex " << p << "\n";
|
||||||
|
out << "vertex " << q << "\n";
|
||||||
|
out << "vertex " << r << "\n";
|
||||||
|
out << "endloop\nendfacet\n";
|
||||||
|
}
|
||||||
|
out << "endsolid\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.good();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
writes the graph `g` in the STL format into a file named `fname`.
|
||||||
|
|
||||||
|
\sa Overloads of this function for specific models of the concept `FaceGraph`.
|
||||||
|
|
||||||
|
\see \ref IOStreamSTL
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_STL(const char* fname, const FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
std::ofstream out(fname);
|
||||||
|
return write_STL(out, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_STL(const std::string& fname, const FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
return write_STL(fname.c_str(), g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_STL(std::ostream& os, const FaceGraph& g) { return write_STL(os, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_STL(const char* fname, const FaceGraph& g) { return write_STL(fname, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_STL(const std::string& fname, const FaceGraph& g) { return write_STL(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_BGL_IO_STL_H
|
||||||
|
|
@ -0,0 +1,431 @@
|
||||||
|
// Copyright (c) 2015 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_VTK_H
|
||||||
|
#define CGAL_BGL_IO_VTK_H
|
||||||
|
|
||||||
|
#include <CGAL/IO/VTK.h>
|
||||||
|
|
||||||
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
|
#include <CGAL/boost/graph/iterator.h>
|
||||||
|
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
#include <vtkCell.h>
|
||||||
|
#include <vtkXMLPolyDataReader.h>
|
||||||
|
#include <vtkPointSet.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Read
|
||||||
|
|
||||||
|
#ifdef CGAL_USE_VTK
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename NamedParameters>
|
||||||
|
bool vtkPointSet_to_polygon_mesh(vtkPointSet* poly_data,
|
||||||
|
FaceGraph& g,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, NamedParameters>::type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
|
||||||
|
|
||||||
|
using parameters::get_parameter;
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
|
||||||
|
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, g));
|
||||||
|
|
||||||
|
vtkIdType nb_points = poly_data->GetNumberOfPoints();
|
||||||
|
vtkIdType nb_cells = poly_data->GetNumberOfCells();
|
||||||
|
|
||||||
|
// extract points
|
||||||
|
std::vector<vertex_descriptor> vertex_map(nb_points);
|
||||||
|
for(vtkIdType i=0; i<nb_points; ++i)
|
||||||
|
{
|
||||||
|
double coords[3];
|
||||||
|
poly_data->GetPoint(i, coords);
|
||||||
|
|
||||||
|
vertex_descriptor v = add_vertex(g);
|
||||||
|
put(vpm, v, Point(coords[0], coords[1], coords[2]));
|
||||||
|
vertex_map[i] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract cells
|
||||||
|
for(vtkIdType i=0; i<nb_cells; ++i)
|
||||||
|
{
|
||||||
|
int cell_type = poly_data->GetCellType(i);
|
||||||
|
if(cell_type != 5
|
||||||
|
&& cell_type != 7
|
||||||
|
&& cell_type != 9) // only supported cells are triangles, quads and polygons
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vtkCell* cell_ptr = poly_data->GetCell(i);
|
||||||
|
|
||||||
|
vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints();
|
||||||
|
if(nb_vertices < 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::vector<vertex_descriptor> vr(nb_vertices);
|
||||||
|
for(vtkIdType k=0; k<nb_vertices; ++k)
|
||||||
|
{
|
||||||
|
vtkIdType id = cell_ptr->GetPointId(k);
|
||||||
|
vr[k] = vertex_map[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
face_descriptor f = CGAL::Euler::add_face(vr, g);
|
||||||
|
if(f == boost::graph_traits<FaceGraph>::null_face())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
template<typename FaceGraph, typename NamedParameters>
|
||||||
|
bool read_VTP(const char* fname, FaceGraph& g, const NamedParameters& np)
|
||||||
|
{
|
||||||
|
vtkSmartPointer<vtkPointSet> data;
|
||||||
|
vtkSmartPointer<IO::internal::ErrorObserverVtk> obs =
|
||||||
|
vtkSmartPointer<IO::internal::ErrorObserverVtk>::New();
|
||||||
|
|
||||||
|
data = IO::internal::read_vtk_file<vtkXMLPolyDataReader>(fname, obs)->GetOutput();;
|
||||||
|
|
||||||
|
return IO::internal::vtkPointSet_to_polygon_mesh(data, g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FaceGraph>
|
||||||
|
bool read_VTP(const char* fname, FaceGraph& g) { return read_VTP(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
#endif // CGAL_USE_VTK
|
||||||
|
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
|
/*! \ingroup PkgBGLIOFct
|
||||||
|
* \brief reads a PolyData in the VTP format into a triangulated surface mesh.
|
||||||
|
*
|
||||||
|
* \tparam FaceGraph a model of `FaceListGraph`.
|
||||||
|
*
|
||||||
|
* \param fname the path to the file that will be read.
|
||||||
|
* \param g the output mesh.
|
||||||
|
*
|
||||||
|
* \pre \cgal needs to be configured with the VTK Libraries for this function to be available.
|
||||||
|
*/
|
||||||
|
template<typename FaceGraph, typename NamedParameters>
|
||||||
|
bool read_VTP(const char* fname, FaceGraph& g, const NamedParameters& np);
|
||||||
|
#endif // DOXYGEN_RUNNING
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Write
|
||||||
|
|
||||||
|
namespace IO {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// writes the polys appended data at the end of the .vtp file
|
||||||
|
template <typename FaceGraph, typename NamedParameters>
|
||||||
|
void write_polys(std::ostream& os,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
|
||||||
|
|
||||||
|
typedef typename CGAL::GetVertexIndexMap<FaceGraph, NamedParameters>::type VIM;
|
||||||
|
|
||||||
|
using parameters::get_parameter;
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
|
||||||
|
VIM V = choose_parameter(get_parameter(np, internal_np::vertex_index),
|
||||||
|
get_const_property_map(boost::vertex_index, g));
|
||||||
|
|
||||||
|
std::vector<std::size_t> connectivity_table;
|
||||||
|
std::vector<std::size_t> offsets;
|
||||||
|
std::vector<unsigned char> cell_type(num_faces(g), 5); // triangle == 5
|
||||||
|
|
||||||
|
std::size_t off = 0;
|
||||||
|
|
||||||
|
for(const face_descriptor f : faces(g))
|
||||||
|
{
|
||||||
|
off += 3;
|
||||||
|
offsets.push_back(off);
|
||||||
|
for(const vertex_descriptor v : vertices_around_face(halfedge(f, g), g))
|
||||||
|
connectivity_table.push_back(get(V, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
write_vector<std::size_t>(os, connectivity_table);
|
||||||
|
write_vector<std::size_t>(os, offsets);
|
||||||
|
write_vector<unsigned char>(os, cell_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo use named params for maps
|
||||||
|
template <typename FaceGraph, typename NamedParameters>
|
||||||
|
void write_polys_tag(std::ostream& os,
|
||||||
|
const FaceGraph& g,
|
||||||
|
bool binary,
|
||||||
|
std::size_t& offset,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::face_descriptor face_descriptor;
|
||||||
|
|
||||||
|
typedef typename CGAL::GetVertexIndexMap<FaceGraph, NamedParameters>::type VIM;
|
||||||
|
|
||||||
|
using parameters::get_parameter;
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
|
||||||
|
VIM V = choose_parameter(get_parameter(np, internal_np::vertex_index),
|
||||||
|
get_const_property_map(boost::vertex_index, g));
|
||||||
|
|
||||||
|
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 << " <Polys>\n"
|
||||||
|
<< " <DataArray Name=\"connectivity\""
|
||||||
|
<< formatattribute << typeattribute;
|
||||||
|
|
||||||
|
// if binary output, just write the xml tag
|
||||||
|
if(binary)
|
||||||
|
{
|
||||||
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
|
offset += (3 * num_faces(g)+ 1) * sizeof(std::size_t);
|
||||||
|
// 3 indices (size_t) per triangle + length of the encoded data (size_t)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << "\">\n";
|
||||||
|
|
||||||
|
for(face_descriptor f : faces(g))
|
||||||
|
{
|
||||||
|
for(vertex_descriptor v : vertices_around_face(halfedge(f, g), g))
|
||||||
|
os << get(V, v) << " ";
|
||||||
|
}
|
||||||
|
os << " </DataArray>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write offsets
|
||||||
|
os << " <DataArray Name=\"offsets\""
|
||||||
|
<< formatattribute << typeattribute;
|
||||||
|
|
||||||
|
if(binary) { // if binary output, just write the xml tag
|
||||||
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
|
offset += (num_faces(g) + 1) * sizeof(std::size_t);
|
||||||
|
// 1 offset (size_t) per triangle + length of the encoded data (size_t)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << "\">\n";
|
||||||
|
std::size_t polys_offset = 0;
|
||||||
|
|
||||||
|
for(face_descriptor f : faces(g))
|
||||||
|
{
|
||||||
|
polys_offset += 3;
|
||||||
|
os << polys_offset << " ";
|
||||||
|
}
|
||||||
|
os << " </DataArray>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write cell type (triangle == 5)
|
||||||
|
os << " <DataArray Name=\"types\""
|
||||||
|
<< formatattribute << " type=\"UInt8\"";
|
||||||
|
|
||||||
|
if(binary)
|
||||||
|
{
|
||||||
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
|
offset += num_faces(g) + sizeof(std::size_t);
|
||||||
|
// 1 unsigned char per cell + length of the encoded data (size_t)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << "\">\n";
|
||||||
|
for(std::size_t i = 0; i< num_faces(g); ++i)
|
||||||
|
os << "5 ";
|
||||||
|
os << " </DataArray>\n";
|
||||||
|
}
|
||||||
|
os << " </Polys>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo : use namedparams for points and ids
|
||||||
|
//overload for facegraph
|
||||||
|
template <typename FaceGraph, typename NamedParameters>
|
||||||
|
void write_points_tag(std::ostream& os,
|
||||||
|
const FaceGraph& g,
|
||||||
|
bool binary,
|
||||||
|
std::size_t& offset,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||||
|
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, NamedParameters>::const_type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||||
|
typedef typename CGAL::Kernel_traits<Point>::Kernel Gt;
|
||||||
|
typedef typename Gt::FT FT;
|
||||||
|
|
||||||
|
using parameters::get_parameter;
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
|
||||||
|
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, g));
|
||||||
|
|
||||||
|
std::string format = binary ? "appended" : "ascii";
|
||||||
|
std::string type = (sizeof(FT) == 8) ? "Float64" : "Float32";
|
||||||
|
|
||||||
|
os << " <Points>\n"
|
||||||
|
<< " <DataArray type =\"" << type << "\" NumberOfComponents=\"3\" format=\""
|
||||||
|
<< format;
|
||||||
|
|
||||||
|
if(binary)
|
||||||
|
{
|
||||||
|
os << "\" offset=\"" << offset << "\"/>\n";
|
||||||
|
offset += 3 * num_vertices(g) * sizeof(FT) + sizeof(std::size_t);
|
||||||
|
// 3 coords per points + length of the encoded data (size_t)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << "\">\n";
|
||||||
|
for(const vertex_descriptor v : vertices(g))
|
||||||
|
os << get(vpm, v).x() << " " << get(vpm, v).y() << " " << get(vpm, v).z() << " ";
|
||||||
|
os << " </DataArray>\n";
|
||||||
|
}
|
||||||
|
os << " </Points>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// writes the points appended data at the end of the .vtp file
|
||||||
|
template <typename FaceGraph, typename NamedParameters>
|
||||||
|
void write_polys_points(std::ostream& os,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
|
||||||
|
|
||||||
|
typedef typename CGAL::GetVertexPointMap<FaceGraph, NamedParameters>::const_type VPM;
|
||||||
|
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||||
|
typedef typename CGAL::Kernel_traits<Point>::Kernel Gt;
|
||||||
|
typedef typename Gt::FT FT;
|
||||||
|
|
||||||
|
using parameters::get_parameter;
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
|
||||||
|
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, g));
|
||||||
|
|
||||||
|
std::vector<FT> coordinates;
|
||||||
|
|
||||||
|
for(vertex_descriptor v : vertices(g))
|
||||||
|
{
|
||||||
|
coordinates.push_back(get(vpm, v).x());
|
||||||
|
coordinates.push_back(get(vpm, v).y());
|
||||||
|
coordinates.push_back(get(vpm, v).z());
|
||||||
|
}
|
||||||
|
|
||||||
|
write_vector<FT>(os, coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace IO
|
||||||
|
|
||||||
|
/*! \ingroup PkgBGLIOFct
|
||||||
|
*
|
||||||
|
* \brief writes a triangulated surface mesh in the `PolyData` XML format.
|
||||||
|
*
|
||||||
|
* \tparam FaceGraph a model of `FaceListGraph` with only triangle faces.
|
||||||
|
* \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters"
|
||||||
|
*
|
||||||
|
* \param os the stream used for writing.
|
||||||
|
* \param g the triangle mesh to be written.
|
||||||
|
* \param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the
|
||||||
|
* ones listed below
|
||||||
|
*
|
||||||
|
* \cgalNamedParamsBegin
|
||||||
|
* \cgalParamBegin{use_binary_mode} a Boolean indicating if the
|
||||||
|
* data should be written in binary (`true`, the default) or in ASCII (`false`).
|
||||||
|
* \cgalParamEnd
|
||||||
|
* \cgalParamBegin{vertex_point_map} the property map with the points associated to
|
||||||
|
* the vertices of `g`. If this parameter is omitted, an internal property map for
|
||||||
|
* `CGAL::vertex_Point` must be available in `FaceGraph`.
|
||||||
|
* \cgalParamEnd
|
||||||
|
* \cgalParamBegin{vertex_index_map} the property map with the indices associated to
|
||||||
|
* the vertices of `g`. If this parameter is omitted, an internal property map for
|
||||||
|
* `CGAL::vertex_index_t` must be available in `FaceGraph`.
|
||||||
|
* \cgalParamEnd
|
||||||
|
* \cgalNamedParamsEnd
|
||||||
|
* \see \ref IOStreamVTK
|
||||||
|
*/
|
||||||
|
template<typename FaceGraph, typename NamedParameters>
|
||||||
|
void write_VTP(std::ostream& os,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
using parameters::get_parameter;
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
|
||||||
|
os << "<?xml version=\"1.0\"?>\n"
|
||||||
|
<< "<VTKFile type=\"PolyData\" version=\"0.1\"";
|
||||||
|
|
||||||
|
#ifdef CGAL_LITTLE_ENDIAN
|
||||||
|
os << " byte_order=\"LittleEndian\"";
|
||||||
|
#else // CGAL_BIG_ENDIAN
|
||||||
|
os << " byte_order=\"BigEndian\"";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(sizeof(std::size_t))
|
||||||
|
{
|
||||||
|
case 4: os << " header_type=\"UInt32\""; break;
|
||||||
|
case 8: os << " header_type=\"UInt64\""; break;
|
||||||
|
default: CGAL_error_msg("Unknown size of std::size_t");
|
||||||
|
}
|
||||||
|
|
||||||
|
os << ">\n"
|
||||||
|
<< " <PolyData>" << "\n";
|
||||||
|
os << " <Piece NumberOfPoints=\"" << num_vertices(g)
|
||||||
|
<< "\" NumberOfPolys=\"" << num_faces(g) << "\">\n";
|
||||||
|
|
||||||
|
std::size_t offset = 0;
|
||||||
|
const bool binary = choose_parameter(get_parameter(np, internal_np::use_binary_mode), true);
|
||||||
|
|
||||||
|
IO::internal::write_points_tag(os, g, binary, offset, np);
|
||||||
|
IO::internal::write_polys_tag(os, g, binary, offset, np);
|
||||||
|
|
||||||
|
os << " </Piece>\n"
|
||||||
|
<< " </PolyData>\n";
|
||||||
|
if(binary)
|
||||||
|
{
|
||||||
|
os << "<AppendedData encoding=\"raw\">\n_";
|
||||||
|
IO::internal::write_polys_points(os, g, np);
|
||||||
|
IO::internal::write_polys(os, g, np);
|
||||||
|
}
|
||||||
|
os << "</VTKFile>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FaceGraph>
|
||||||
|
void write_VTP(std::ostream& os, const FaceGraph& g)
|
||||||
|
{
|
||||||
|
write_VTP(os, g, CGAL::parameters::all_default());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_BGL_IO_VTK_H
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
// Copyright (c) 2015 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_WRL_H
|
||||||
|
#define CGAL_BGL_IO_WRL_H
|
||||||
|
|
||||||
|
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||||
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
|
||||||
|
#include <boost/container/flat_map.hpp>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgBGLIOFct
|
||||||
|
|
||||||
|
writes the graph `g` in the wrl format (VRML 2.0).
|
||||||
|
|
||||||
|
\cgalNamedParamsBegin
|
||||||
|
\cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `g`.
|
||||||
|
If this parameter is omitted, an internal property map for
|
||||||
|
`CGAL::vertex_point_t` should be available in `FaceGraph`
|
||||||
|
\cgalParamEnd
|
||||||
|
\cgalNamedParamsEnd
|
||||||
|
|
||||||
|
\see \ref IOStreamWRL
|
||||||
|
*/
|
||||||
|
template <typename FaceGraph, typename NamedParameters>
|
||||||
|
bool write_WRL(std::ostream& os,
|
||||||
|
const FaceGraph& g,
|
||||||
|
const NamedParameters& np)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
using parameters::get_parameter;
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
|
||||||
|
typename CGAL::GetVertexPointMap<FaceGraph, NamedParameters>::const_type
|
||||||
|
vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, g));
|
||||||
|
|
||||||
|
boost::container::flat_map<vertex_descriptor,vertices_size_type> reindex;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
os << "#VRML V2.0 utf8\n"
|
||||||
|
"Group {\n"
|
||||||
|
"children [\n"
|
||||||
|
"Shape {\n"
|
||||||
|
"appearance DEF A1 Appearance {\n"
|
||||||
|
"material Material {\n"
|
||||||
|
"diffuseColor .6 .5 .9\n"
|
||||||
|
"}\n"
|
||||||
|
"}\n"
|
||||||
|
"appearance\n"
|
||||||
|
"Appearance {\n"
|
||||||
|
"material DEF Material Material {}\n"
|
||||||
|
"}\n"
|
||||||
|
"}\n"
|
||||||
|
"Group {\n"
|
||||||
|
"children [\n"
|
||||||
|
"Shape {\n"
|
||||||
|
"appearance Appearance { material USE Material }\n"
|
||||||
|
"geometry IndexedFaceSet {\n"
|
||||||
|
"convex FALSE\n"
|
||||||
|
"solid FALSE\n"
|
||||||
|
"coord Coordinate {\n"
|
||||||
|
"point [\n";
|
||||||
|
|
||||||
|
for(vertex_descriptor v : vertices(g))
|
||||||
|
{
|
||||||
|
os << get(vpm,v) << ",\n";
|
||||||
|
reindex[v] = n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "] #point\n"
|
||||||
|
"} #coord Coordinate\n"
|
||||||
|
"coordIndex [\n";
|
||||||
|
|
||||||
|
for(face_descriptor f : faces(g))
|
||||||
|
{
|
||||||
|
for(vertex_descriptor v : vertices_around_face(halfedge(f, g), g))
|
||||||
|
os << reindex[v] << ",";
|
||||||
|
os << "-1,\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "] #coordIndex\n"
|
||||||
|
"} #geometry\n"
|
||||||
|
"} #Shape\n"
|
||||||
|
"] #children\n"
|
||||||
|
"} #group\n"
|
||||||
|
"]\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
return os.good();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph, typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool write_WRL(const std::string& fname, const FaceGraph& g, const CGAL_BGL_NP_CLASS& np)
|
||||||
|
{
|
||||||
|
return write_WRL(fname.c_str(), g, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_WRL(std::ostream& os, const FaceGraph& g) { return write_WRL(os, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_WRL(const char* fname, const FaceGraph& g) { return write_WRL(fname, g, parameters::all_default()); }
|
||||||
|
template <typename FaceGraph>
|
||||||
|
bool write_WRL(const std::string& fname, const FaceGraph& g) { return write_WRL(fname, g, parameters::all_default()); }
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_BGL_IO_WRL_H
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -22,20 +22,20 @@ namespace CGAL {
|
||||||
//!
|
//!
|
||||||
/// reads the content of `input` into `points` and `faces`, using the `OBJ` format.
|
/// reads the content of `input` into `points` and `faces`, using the `OBJ` format.
|
||||||
///
|
///
|
||||||
/// \tparam Points_3 a `RandomAccessContainer` of `Point_3,
|
/// \tparam Points a `RandomAccessContainer` of `Point_3,
|
||||||
/// \tparam Faces a `RandomAccessContainer` of `RandomAccessContainer` of `std::size_t`
|
/// \tparam Faces a `RandomAccessContainer` of `RandomAccessContainer` of `std::size_t`
|
||||||
///
|
///
|
||||||
/// \see \ref IOStreamOBJ
|
/// \see \ref IOStreamOBJ
|
||||||
template <class Points_3, class Faces>
|
template <class Points, class Faces>
|
||||||
bool read_OBJ(std::istream& input,
|
bool read_OBJ(std::istream& input,
|
||||||
Points_3& points,
|
Points& points,
|
||||||
Faces& faces)
|
Faces& faces)
|
||||||
{
|
{
|
||||||
typedef typename Points_3::value_type Point_3;
|
typedef typename Points::value_type Point;
|
||||||
|
|
||||||
int mini(1),
|
int mini(1),
|
||||||
maxi(-INT_MAX);
|
maxi(-INT_MAX);
|
||||||
Point_3 p;
|
Point p;
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
||||||
while(getline(input, line))
|
while(getline(input, line))
|
||||||
|
|
@ -46,6 +46,7 @@ bool read_OBJ(std::istream& input,
|
||||||
iss >> p;
|
iss >> p;
|
||||||
if(!iss)
|
if(!iss)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
points.push_back(p);
|
points.push_back(p);
|
||||||
}
|
}
|
||||||
else if(line[0] == 'f')
|
else if(line[0] == 'f')
|
||||||
|
|
@ -57,9 +58,9 @@ bool read_OBJ(std::istream& input,
|
||||||
{
|
{
|
||||||
if(i < 1)
|
if(i < 1)
|
||||||
{
|
{
|
||||||
faces.back().push_back(points.size()+i);//negative indices are relative references
|
faces.back().push_back(points.size()+i); // negative indices are relative references
|
||||||
if(i<mini)
|
if(i < mini)
|
||||||
mini=i;
|
mini = i;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -80,7 +81,7 @@ bool read_OBJ(std::istream& input,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(maxi > points.size() || mini < -static_cast<int>(points.size()))
|
if(maxi > static_cast<int>(points.size()) || mini < -static_cast<int>(points.size()))
|
||||||
{
|
{
|
||||||
std::cerr << "a face index is invalid " << std::endl;
|
std::cerr << "a face index is invalid " << std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,6 @@
|
||||||
#ifndef CGAL_IO_OBJ_FILE_WRITER_WAVEFRONT_H
|
#ifndef CGAL_IO_OBJ_FILE_WRITER_WAVEFRONT_H
|
||||||
#define CGAL_IO_OBJ_FILE_WRITER_WAVEFRONT_H
|
#define CGAL_IO_OBJ_FILE_WRITER_WAVEFRONT_H
|
||||||
|
|
||||||
#include <CGAL/IO/binary_file_io.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
class File_writer_wavefront
|
class File_writer_wavefront
|
||||||
|
|
@ -31,7 +26,8 @@ class File_writer_wavefront
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::ostream& out() const { return *m_out; }
|
std::ostream& out() const { return *m_out; }
|
||||||
void write_header(std::ostream& out,
|
|
||||||
|
void write_header(std::ostream& o,
|
||||||
std::size_t vertices,
|
std::size_t vertices,
|
||||||
std::size_t halfedges,
|
std::size_t halfedges,
|
||||||
std::size_t facets)
|
std::size_t facets)
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ bool read_STL(std::istream& input,
|
||||||
// If we have gone beyond 80 characters and have not read anything yet,
|
// If we have gone beyond 80 characters and have not read anything yet,
|
||||||
// then this must be an ASCII file.
|
// then this must be an ASCII file.
|
||||||
if(pos > 80)
|
if(pos > 80)
|
||||||
return parse_ASCII_STL(input, points, facets, verbose);
|
return IO::internal::parse_ASCII_STL(input, points, facets, verbose);
|
||||||
|
|
||||||
// We are within the first 80 characters, both ASCII and binary are possible
|
// We are within the first 80 characters, both ASCII and binary are possible
|
||||||
|
|
||||||
|
|
@ -81,7 +81,7 @@ bool read_STL(std::istream& input,
|
||||||
// If the first word is not 'solid', the file must be binary
|
// If the first word is not 'solid', the file must be binary
|
||||||
if(s != "solid" || (word[5] !='\n' && word[5] != ' '))
|
if(s != "solid" || (word[5] !='\n' && word[5] != ' '))
|
||||||
{
|
{
|
||||||
if(parse_binary_STL(input, points, facets, verbose))
|
if(IO::internal::parse_binary_STL(input, points, facets, verbose))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -91,14 +91,14 @@ bool read_STL(std::istream& input,
|
||||||
// The file does not start with 'solid' anyway, so it's fine to reset it.
|
// The file does not start with 'solid' anyway, so it's fine to reset it.
|
||||||
input.clear();
|
input.clear();
|
||||||
input.seekg(0, std::ios::beg);
|
input.seekg(0, std::ios::beg);
|
||||||
return parse_ASCII_STL(input, points, facets, verbose);
|
return IO::internal::parse_ASCII_STL(input, points, facets, verbose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, we have found the keyword "solid" which is supposed to indicate that the file is ASCII
|
// Now, we have found the keyword "solid" which is supposed to indicate that the file is ASCII
|
||||||
input.clear();
|
input.clear();
|
||||||
input.seekg(0, std::ios::beg); //the parser needs to read all "solid" to work correctly.
|
input.seekg(0, std::ios::beg); //the parser needs to read all "solid" to work correctly.
|
||||||
if(parse_ASCII_STL(input, points, facets, verbose))
|
if(IO::internal::parse_ASCII_STL(input, points, facets, verbose))
|
||||||
{
|
{
|
||||||
// correctly read the input as an ASCII file
|
// correctly read the input as an ASCII file
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -106,7 +106,7 @@ bool read_STL(std::istream& input,
|
||||||
else // Failed to read the ASCII file
|
else // Failed to read the ASCII file
|
||||||
{
|
{
|
||||||
// It might have actually have been a binary file... ?
|
// It might have actually have been a binary file... ?
|
||||||
return parse_binary_STL(input, points, facets, verbose);
|
return IO::internal::parse_binary_STL(input, points, facets, verbose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,9 +122,9 @@ bool read_STL(std::istream& input,
|
||||||
* \see \ref IOStreamSTL
|
* \see \ref IOStreamSTL
|
||||||
*/
|
*/
|
||||||
template <class PointRange, class TriangleRange>
|
template <class PointRange, class TriangleRange>
|
||||||
std::ostream& write_STL(const PointRange& points,
|
std::ostream& write_STL(std::ostream& out,
|
||||||
const TriangleRange& facets,
|
const PointRange& points,
|
||||||
std::ostream& out)
|
const TriangleRange& facets)
|
||||||
{
|
{
|
||||||
typedef typename PointRange::value_type Point;
|
typedef typename PointRange::value_type Point;
|
||||||
typedef typename CGAL::Kernel_traits<Point>::Kernel K;
|
typedef typename CGAL::Kernel_traits<Point>::Kernel K;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace Stream_support {
|
namespace IO {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <class PointRange, class TriangleRange, typename IndexMap>
|
template <class PointRange, class TriangleRange, typename IndexMap>
|
||||||
|
|
@ -285,7 +285,7 @@ bool parse_binary_STL(std::istream& input,
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace Stream_support
|
} // namespace IO
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_IO_STL_STL_READER_H
|
#endif // CGAL_IO_STL_STL_READER_H
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
#ifndef CGAL_IO_VTK_H
|
#ifndef CGAL_IO_VTK_H
|
||||||
#define CGAL_IO_VTK_H
|
#define CGAL_IO_VTK_H
|
||||||
|
|
||||||
#include <CGAL/IO/VTK/write_vtk.h>
|
#include <CGAL/IO/VTK/VTK_reader.h>
|
||||||
|
#include <CGAL/IO/VTK/VTK_writer.h>
|
||||||
|
|
||||||
#endif // CGAL_IO_VTK_H
|
#endif // CGAL_IO_VTK_H
|
||||||
|
|
|
||||||
|
|
@ -13,4 +13,77 @@
|
||||||
#ifndef CGAL_IO_VTK_READER_H
|
#ifndef CGAL_IO_VTK_READER_H
|
||||||
#define CGAL_IO_VTK_READER_H
|
#define CGAL_IO_VTK_READER_H
|
||||||
|
|
||||||
|
#include <vtkSmartPointer.h>
|
||||||
|
#include <vtkCommand.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace IO {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
class ErrorObserverVtk
|
||||||
|
: public vtkCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ErrorObserverVtk()
|
||||||
|
: Error(false), Warning(false), ErrorMessage(""), WarningMessage("")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
static ErrorObserverVtk *New() { return new ErrorObserverVtk; }
|
||||||
|
|
||||||
|
bool GetError() const { return this->Error; }
|
||||||
|
bool GetWarning() const { return this->Warning; }
|
||||||
|
std::string GetErrorMessage() { return ErrorMessage; }
|
||||||
|
std::string GetWarningMessage() { return WarningMessage; }
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
this->Error = false;
|
||||||
|
this->Warning = false;
|
||||||
|
this->ErrorMessage = "";
|
||||||
|
this->WarningMessage = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Execute(vtkObject *vtkNotUsed(caller),
|
||||||
|
unsigned long event,
|
||||||
|
void *calldata)
|
||||||
|
{
|
||||||
|
switch (event)
|
||||||
|
{
|
||||||
|
case vtkCommand::ErrorEvent:
|
||||||
|
ErrorMessage = static_cast<char *>(calldata);
|
||||||
|
this->Error = true;
|
||||||
|
break;
|
||||||
|
case vtkCommand::WarningEvent:
|
||||||
|
WarningMessage = static_cast<char *>(calldata);
|
||||||
|
this->Warning = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool Error;
|
||||||
|
bool Warning;
|
||||||
|
std::string ErrorMessage;
|
||||||
|
std::string WarningMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class vtkReader>
|
||||||
|
vtkSmartPointer<vtkReader> read_vtk_file(const std::string& input_filename,
|
||||||
|
vtkSmartPointer<ErrorObserverVtk> errorObserver)
|
||||||
|
{
|
||||||
|
vtkSmartPointer<vtkReader> reader = vtkSmartPointer<vtkReader>::New();
|
||||||
|
reader->AddObserver(vtkCommand::ErrorEvent, errorObserver);
|
||||||
|
reader->AddObserver(vtkCommand::WarningEvent, errorObserver);
|
||||||
|
reader->SetFileName(input_filename.data());
|
||||||
|
reader->Update();
|
||||||
|
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace IO
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_IO_VTK_READER_H
|
#endif // CGAL_IO_VTK_READER_H
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,12 @@
|
||||||
#ifndef CGAL_IO_VTK_WRITER_H
|
#ifndef CGAL_IO_VTK_WRITER_H
|
||||||
#define CGAL_IO_VTK_WRITER_H
|
#define CGAL_IO_VTK_WRITER_H
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace Stream_support {
|
namespace IO {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template <class FT>
|
template <class FT>
|
||||||
|
|
@ -28,68 +32,8 @@ void write_vector(std::ostream& os,
|
||||||
os.write(buffer, vect.size()*sizeof(FT)); // encoded data
|
os.write(buffer, vect.size()*sizeof(FT)); // encoded data
|
||||||
}
|
}
|
||||||
|
|
||||||
class ErrorObserverVtk
|
|
||||||
: public vtkCommand
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ErrorObserverVtk()
|
|
||||||
: Error(false), Warning(false), ErrorMessage(""), WarningMessage("")
|
|
||||||
{ }
|
|
||||||
|
|
||||||
static ErrorObserverVtk *New() { return new ErrorObserverVtk; }
|
|
||||||
|
|
||||||
bool GetError() const { return this->Error; }
|
|
||||||
bool GetWarning() const { return this->Warning; }
|
|
||||||
std::string GetErrorMessage() { return ErrorMessage; }
|
|
||||||
std::string GetWarningMessage() { return WarningMessage; }
|
|
||||||
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
this->Error = false;
|
|
||||||
this->Warning = false;
|
|
||||||
this->ErrorMessage = "";
|
|
||||||
this->WarningMessage = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Execute(vtkObject *vtkNotUsed(caller),
|
|
||||||
unsigned long event,
|
|
||||||
void *calldata)
|
|
||||||
{
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case vtkCommand::ErrorEvent:
|
|
||||||
ErrorMessage = static_cast<char *>(calldata);
|
|
||||||
this->Error = true;
|
|
||||||
break;
|
|
||||||
case vtkCommand::WarningEvent:
|
|
||||||
WarningMessage = static_cast<char *>(calldata);
|
|
||||||
this->Warning = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool Error;
|
|
||||||
bool Warning;
|
|
||||||
std::string ErrorMessage;
|
|
||||||
std::string WarningMessage;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class vtkReader>
|
|
||||||
vtkSmartPointer<vtkReader>
|
|
||||||
read_vtk_file(const std::string& input_filename,
|
|
||||||
vtkSmartPointer<CGAL::ErrorObserverVtk> errorObserver)
|
|
||||||
{
|
|
||||||
vtkSmartPointer<vtkReader> reader = vtkSmartPointer<vtkReader>::New();
|
|
||||||
reader->AddObserver(vtkCommand::ErrorEvent, errorObserver);
|
|
||||||
reader->AddObserver(vtkCommand::WarningEvent, errorObserver);
|
|
||||||
reader->SetFileName(input_filename.data());
|
|
||||||
reader->Update();
|
|
||||||
return reader;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace Stream_support
|
} // namespace IO
|
||||||
} // namespace CGAL
|
} // namespace CGAL
|
||||||
|
|
||||||
#endif // CGAL_IO_VTK_WRITER_H
|
#endif // CGAL_IO_VTK_WRITER_H
|
||||||
|
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
// Copyright (c) 2019 GeometryFactory
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org);
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
|
||||||
//
|
|
||||||
// Author(s) : Maxime Gimeno
|
|
||||||
|
|
||||||
#ifndef CGAL_INTERNAL_IO_GENERIC_FACEGRAPH_BUILDER_H
|
|
||||||
#define CGAL_INTERNAL_IO_GENERIC_FACEGRAPH_BUILDER_H
|
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <boost/tuple/tuple.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace CGAL{
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
namespace IO{
|
|
||||||
template <class Facegraph, class P, class Derived>
|
|
||||||
class Generic_facegraph_builder
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
typedef P Point_3;
|
|
||||||
typedef std::deque<Point_3> Points_3;
|
|
||||||
typedef std::vector<std::size_t> Facet;
|
|
||||||
typedef std::deque<Facet> Surface;
|
|
||||||
|
|
||||||
public:
|
|
||||||
std::string name, color;
|
|
||||||
Generic_facegraph_builder(std::istream& is_)
|
|
||||||
: is(is_), counter(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void do_construct(){} //specific to Facegraph (declared in BGL)
|
|
||||||
void
|
|
||||||
read(std::istream&, Points_3&, Surface&) {}
|
|
||||||
|
|
||||||
void operator()( Facegraph& graph)
|
|
||||||
{
|
|
||||||
static_cast<Derived*>(this)->read(this->is, this->meshPoints, this->mesh);
|
|
||||||
static_cast<Derived*>(this)->do_construct(graph);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::istream& is;
|
|
||||||
int counter;
|
|
||||||
Points_3 meshPoints;
|
|
||||||
Surface mesh;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} //end IO
|
|
||||||
}//end internal
|
|
||||||
}//end CGAL
|
|
||||||
#endif // CGAL_INTERNAL_IO_GENERIC_FACEGRAPH_BUILDER_H
|
|
||||||
Loading…
Reference in New Issue