mirror of https://github.com/CGAL/cgal
IO: write_PLY() for Epeck (#7874)
## Summary of Changes As reported in #7868 the function `CGAL::IO::write_PLY()` used in binary mode does not correctly write the coordinates if the points are from a kernel with exact constructions. ~~This PR applies `to_double()" to the coordinates.~~ ~~After a discussion with @MaelRL we decided that the user is in charge to pass a `vertex_point_map` as named parameter that does the conversion. This is straightforward as we offer the [`Cartesian_converter_property_map`](https://doc.cgal.org/latest/Property_map/structCGAL_1_1Cartesian__converter__property__map.html).~~ Moving back to the previous proposal: hardcode some to_double and to_float casts such that we meet the requirements of the file format, whatever the input. As the problem is the same for the vertex normals we add a named parameter `vertex_normal_map`. ### Todo - [x] Fix the generic function `write_polygon_mesh()`. Currently it is fixed for `Surface_mesh` ## Release Management * Affected package(s): Stream_support * Issue(s) solved (if any): fix #7868 and fix https://github.com/CGAL/cgal/issues/7327 * License and copyright ownership: unchanged * upcoming integration, update #9072 and test it
This commit is contained in:
commit
dfc5fb5065
|
|
@ -18,6 +18,7 @@
|
||||||
#include <CGAL/boost/graph/IO/Generic_facegraph_builder.h>
|
#include <CGAL/boost/graph/IO/Generic_facegraph_builder.h>
|
||||||
#include <CGAL/Named_function_parameters.h>
|
#include <CGAL/Named_function_parameters.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -44,7 +45,7 @@ class PLY_builder
|
||||||
typedef typename Base::Face_container Face_container;
|
typedef typename Base::Face_container Face_container;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PLY_builder(std::istream& is) : Base(is) { }
|
PLY_builder(std::istream& is, std::string& comments) : Base(is), comments(comments) { }
|
||||||
|
|
||||||
template <typename NamedParameters>
|
template <typename NamedParameters>
|
||||||
bool read(std::istream& is,
|
bool read(std::istream& is,
|
||||||
|
|
@ -52,19 +53,22 @@ public:
|
||||||
Face_container& faces,
|
Face_container& faces,
|
||||||
const NamedParameters& np)
|
const NamedParameters& np)
|
||||||
{
|
{
|
||||||
return read_PLY(is, points, faces, np);
|
return read_PLY(is, points, faces, comments, np);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string& comments;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Graph, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
template <typename Graph, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
bool read_PLY_BGL(std::istream& is,
|
bool read_PLY_BGL(std::istream& is,
|
||||||
Graph& g,
|
Graph& g,
|
||||||
|
std::string& comments,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values())
|
const CGAL_NP_CLASS& np = parameters::default_values())
|
||||||
{
|
{
|
||||||
typedef typename CGAL::GetVertexPointMap<Graph, CGAL_NP_CLASS>::type VPM;
|
typedef typename CGAL::GetVertexPointMap<Graph, CGAL_NP_CLASS>::type VPM;
|
||||||
typedef typename boost::property_traits<VPM>::value_type Point;
|
typedef typename boost::property_traits<VPM>::value_type Point;
|
||||||
|
|
||||||
internal::PLY_builder<Graph, Point> builder(is);
|
internal::PLY_builder<Graph, Point> builder(is, comments);
|
||||||
return builder(g, np);
|
return builder(g, np);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,6 +88,7 @@ bool read_PLY_BGL(std::istream& is,
|
||||||
|
|
||||||
\param is the input stream
|
\param is the input stream
|
||||||
\param g the graph to be built from the input data
|
\param g the graph to be built from the input data
|
||||||
|
\param comments a string included line by line in the header of the PLY stream (each line will be precedeed by "comment ")
|
||||||
\param np optional \ref bgl_namedparameters "Named Parameters" described below
|
\param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
\cgalNamedParamsBegin
|
||||||
|
|
@ -132,15 +137,31 @@ template <typename Graph,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
bool read_PLY(std::istream& is,
|
bool read_PLY(std::istream& is,
|
||||||
Graph& g,
|
Graph& g,
|
||||||
|
std::string& comments,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
#ifndef DOXYGEN_RUNNING
|
#ifndef DOXYGEN_RUNNING
|
||||||
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return internal::read_PLY_BGL(is, g, np);
|
return internal::read_PLY_BGL(is, g, comments, np);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Graph,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_PLY(std::istream& is,
|
||||||
|
Graph& g,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::string unused_comments;
|
||||||
|
return internal::read_PLY_BGL(is, g, unused_comments, np);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgBGLIoFuncsPLY
|
\ingroup PkgBGLIoFuncsPLY
|
||||||
|
|
||||||
|
|
@ -153,6 +174,7 @@ bool read_PLY(std::istream& is,
|
||||||
|
|
||||||
\param fname the name of the input file
|
\param fname the name of the input file
|
||||||
\param g the graph to be built from the input data
|
\param g the graph to be built from the input data
|
||||||
|
\param comments a string included line by line in the header of the PLY stream (each line will be precedeed by "comment" )
|
||||||
\param np optional \ref bgl_namedparameters "Named Parameters" described below
|
\param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||||
|
|
||||||
\cgalNamedParamsBegin
|
\cgalNamedParamsBegin
|
||||||
|
|
@ -207,6 +229,7 @@ template <typename Graph,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
bool read_PLY(const std::string& fname,
|
bool read_PLY(const std::string& fname,
|
||||||
Graph& g,
|
Graph& g,
|
||||||
|
std::string& comments,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
#ifndef DOXYGEN_RUNNING
|
#ifndef DOXYGEN_RUNNING
|
||||||
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
||||||
|
|
@ -218,16 +241,29 @@ bool read_PLY(const std::string& fname,
|
||||||
{
|
{
|
||||||
std::ifstream is(fname, std::ios::binary);
|
std::ifstream is(fname, std::ios::binary);
|
||||||
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
|
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
|
||||||
return internal::read_PLY_BGL(is, g, np);
|
return read_PLY(is, g, comments, np);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::ifstream is(fname);
|
std::ifstream is(fname);
|
||||||
CGAL::IO::set_mode(is, CGAL::IO::ASCII);
|
CGAL::IO::set_mode(is, CGAL::IO::ASCII);
|
||||||
return internal::read_PLY_BGL(is, g, np);
|
return read_PLY(is, g, comments, np);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Graph,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_PLY(const std::string& fname,
|
||||||
|
Graph& g,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<!internal::is_Point_set_or_Range_or_Iterator<Graph>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::string unused_comment;
|
||||||
|
return read_PLY(fname, g, unused_comment, np);
|
||||||
|
}
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Write
|
// Write
|
||||||
|
|
@ -259,6 +295,15 @@ bool read_PLY(const std::string& fname,
|
||||||
must be available in `Graph`.}
|
must be available in `Graph`.}
|
||||||
\cgalParamNEnd
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{vertex_normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the vertices of `g`}
|
||||||
|
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||||
|
as key type and `%Vector_3` as value type}
|
||||||
|
\cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
|
||||||
|
\cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||||
|
must be available in `Graph`.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
\cgalParamNBegin{vertex_index_map}
|
\cgalParamNBegin{vertex_index_map}
|
||||||
\cgalParamDescription{a property map associating to each vertex of `graph` a unique index}
|
\cgalParamDescription{a property map associating to each vertex of `graph` a unique index}
|
||||||
\cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
\cgalParamType{a class model of `WritablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||||
|
|
@ -326,6 +371,8 @@ bool write_PLY(std::ostream& os,
|
||||||
|
|
||||||
bool has_vcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value;
|
bool has_vcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value;
|
||||||
bool has_fcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value;
|
bool has_fcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value;
|
||||||
|
constexpr bool has_vnormal = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value;
|
||||||
|
|
||||||
VIMap vim = CGAL::get_initialized_vertex_index_map(g, np);
|
VIMap vim = CGAL::get_initialized_vertex_index_map(g, np);
|
||||||
Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
get_const_property_map(boost::vertex_point, g));
|
get_const_property_map(boost::vertex_point, g));
|
||||||
|
|
@ -351,8 +398,20 @@ bool write_PLY(std::ostream& os,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
os << "element vertex " << vertices(g).size() << std::endl;
|
os << "element vertex " << vertices(g).size() << std::endl;
|
||||||
|
if constexpr (std::is_same<typename Kernel_traits<Point_3>::Kernel::FT, float>::value)
|
||||||
|
{
|
||||||
internal::output_property_header(os, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
|
internal::output_property_header(os, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typedef typename Kernel_traits<Point_3>::Kernel K;
|
||||||
|
typedef decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Point_3>())) Target_point;
|
||||||
|
auto fvpm = CGAL::make_cartesian_converter_property_map<Target_point>(vpm);
|
||||||
|
internal::output_property_header(os, make_ply_point_writer (fvpm));
|
||||||
|
}
|
||||||
|
|
||||||
//if vcm is not default add v:color property
|
//if vcm is not default add v:color property
|
||||||
if(has_vcolor)
|
if(has_vcolor)
|
||||||
{
|
{
|
||||||
|
|
@ -362,10 +421,30 @@ bool write_PLY(std::ostream& os,
|
||||||
<< "property uchar alpha" << std::endl;
|
<< "property uchar alpha" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if constexpr (has_vnormal)
|
||||||
|
{
|
||||||
|
auto vnm = get_parameter(np, internal_np::vertex_normal_map);
|
||||||
|
typedef decltype(vnm) Normal_map;
|
||||||
|
typedef typename Normal_map::value_type Vector_3;
|
||||||
|
typedef typename Kernel_traits<Vector_3>::Kernel K;
|
||||||
|
typedef typename K::FT FT;
|
||||||
|
if constexpr (std::is_same<FT, float>::value)
|
||||||
|
{
|
||||||
|
internal::output_property_header(os, make_ply_normal_writer (CGAL::Identity_property_map<Vector_3>()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typedef decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Vector_3>())) Target_vector;
|
||||||
|
auto fvnm = CGAL::make_cartesian_converter_property_map<Target_vector>(vnm);
|
||||||
|
internal::output_property_header(os, make_ply_normal_writer (fvnm));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
os << "element face " << faces(g).size() << std::endl;
|
os << "element face " << faces(g).size() << std::endl;
|
||||||
internal::output_property_header(
|
internal::output_property_header(
|
||||||
os, std::make_pair(CGAL::Identity_property_map<std::vector<std::size_t> >(),
|
os, std::make_pair(CGAL::Identity_property_map<std::vector<std::size_t> >(),
|
||||||
PLY_property<std::vector<int> >("vertex_indices")));
|
PLY_property<std::vector<int> >("vertex_indices")));
|
||||||
|
|
||||||
//if fcm is not default add f:color property
|
//if fcm is not default add f:color property
|
||||||
if(has_fcolor)
|
if(has_fcolor)
|
||||||
{
|
{
|
||||||
|
|
@ -378,8 +457,42 @@ bool write_PLY(std::ostream& os,
|
||||||
|
|
||||||
for(vertex_descriptor vd : vertices(g))
|
for(vertex_descriptor vd : vertices(g))
|
||||||
{
|
{
|
||||||
const Point_3& p = get(vpm, vd);
|
if constexpr (std::is_same<typename Kernel_traits<Point_3>::Kernel::FT, float>::value)
|
||||||
|
{
|
||||||
|
decltype(auto) p = get(vpm, vd);
|
||||||
internal::output_properties(os, &p, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
|
internal::output_properties(os, &p, make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typedef typename Kernel_traits<Point_3>::Kernel K;
|
||||||
|
typedef CGAL::cpp20::remove_cvref_t<decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Point_3>()))> Target_point;
|
||||||
|
CGAL::Cartesian_converter_property_map<Target_point, Vpm> fvpm = CGAL::make_cartesian_converter_property_map<Target_point>(vpm);
|
||||||
|
decltype(auto) fp = get(fvpm, vd);
|
||||||
|
internal::output_properties(os, &fp, make_ply_point_writer (CGAL::Identity_property_map<Target_point>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "using generic writer" << std::endl;
|
||||||
|
|
||||||
|
if constexpr (!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value)
|
||||||
|
{
|
||||||
|
auto vnm = get_parameter(np, internal_np::vertex_normal_map);
|
||||||
|
typedef decltype(vnm) Normal_map;
|
||||||
|
typedef typename Normal_map::value_type Vector_3;
|
||||||
|
|
||||||
|
if constexpr (std::is_same<typename Kernel_traits<Vector_3>::Kernel::FT, float>::value)
|
||||||
|
{
|
||||||
|
decltype(auto) vec = get(vnm,vd);
|
||||||
|
internal::output_properties(os, &vec, make_ply_normal_writer (CGAL::Identity_property_map<Vector_3>()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typedef typename Kernel_traits<Vector_3>::Kernel K;
|
||||||
|
typedef CGAL::cpp20::remove_cvref_t<decltype(std::declval<CGAL::Cartesian_converter<K, Epick> >().operator()(std::declval<Vector_3>()))> Target_vector;
|
||||||
|
auto fvnm = CGAL::make_cartesian_converter_property_map<Target_vector>(vnm);
|
||||||
|
decltype(auto) fvec = get(fvnm, vd);
|
||||||
|
internal::output_properties(os, &fvec, make_ply_normal_writer (CGAL::Identity_property_map<Target_vector>()));
|
||||||
|
}
|
||||||
|
}
|
||||||
if(has_vcolor)
|
if(has_vcolor)
|
||||||
{
|
{
|
||||||
const CGAL::IO::Color& c = get(vcm, vd);
|
const CGAL::IO::Color& c = get(vcm, vd);
|
||||||
|
|
@ -455,6 +568,15 @@ bool write_PLY(std::ostream& os, const Graph& g, const CGAL_NP_CLASS& np = param
|
||||||
must be available in `Graph`.}
|
must be available in `Graph`.}
|
||||||
\cgalParamNEnd
|
\cgalParamNEnd
|
||||||
|
|
||||||
|
\cgalParamNBegin{vertex_normal_map}
|
||||||
|
\cgalParamDescription{a property map associating normals to the vertices of `g`}
|
||||||
|
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||||
|
as key type and `%Vector_3` as value type}
|
||||||
|
\cgalParamDefault{`boost::get(CGAL::vertex_point, g)`}
|
||||||
|
\cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||||
|
must be available in `Graph`.}
|
||||||
|
\cgalParamNEnd
|
||||||
|
|
||||||
\cgalParamNBegin{vertex_index_map}
|
\cgalParamNBegin{vertex_index_map}
|
||||||
\cgalParamDescription{a property map associating to each vertex of `graph` a unique index between `0` and `num_vertices(graph) - 1`}
|
\cgalParamDescription{a property map associating to each vertex of `graph` a unique index between `0` and `num_vertices(graph) - 1`}
|
||||||
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
\cgalParamType{a class model of `ReadablePropertyMap` with `boost::graph_traits<Graph>::%vertex_descriptor`
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,19 @@
|
||||||
Algebraic_foundations
|
Algebraic_foundations
|
||||||
|
Arithmetic_kernel
|
||||||
BGL
|
BGL
|
||||||
Cartesian_kernel
|
Cartesian_kernel
|
||||||
Circulator
|
Circulator
|
||||||
Distance_2
|
Distance_2
|
||||||
Distance_3
|
Distance_3
|
||||||
|
Filtered_kernel
|
||||||
|
Homogeneous_kernel
|
||||||
Hash_map
|
Hash_map
|
||||||
Installation
|
Installation
|
||||||
|
Intersections_2
|
||||||
|
Intersections_3
|
||||||
Interval_support
|
Interval_support
|
||||||
Kernel_23
|
Kernel_23
|
||||||
|
Kernel_d
|
||||||
Modular_arithmetic
|
Modular_arithmetic
|
||||||
Number_types
|
Number_types
|
||||||
Profiling_tools
|
Profiling_tools
|
||||||
|
|
@ -15,3 +21,4 @@ Property_map
|
||||||
Random_numbers
|
Random_numbers
|
||||||
STL_Extension
|
STL_Extension
|
||||||
Stream_support
|
Stream_support
|
||||||
|
CGAL_Core
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include <CGAL/Three/CGAL_Lab_io_plugin_interface.h>
|
#include <CGAL/Three/CGAL_Lab_io_plugin_interface.h>
|
||||||
#include <CGAL/Surface_mesh/IO/PLY.h>
|
#include <CGAL/Surface_mesh/IO/PLY.h>
|
||||||
#include <CGAL/Three/Three.h>
|
#include <CGAL/Three/Three.h>
|
||||||
|
#include <CGAL/use.h>
|
||||||
|
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
|
@ -132,8 +133,9 @@ load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||||
std::vector<CGAL::IO::Color> fcolors;
|
std::vector<CGAL::IO::Color> fcolors;
|
||||||
std::vector<CGAL::IO::Color> vcolors;
|
std::vector<CGAL::IO::Color> vcolors;
|
||||||
|
|
||||||
if (!(CGAL::IO::read_PLY (in, points, polygons, fcolors, vcolors)))
|
if (!(CGAL::IO::read_PLY (in, points, polygons, comments, fcolors, vcolors)))
|
||||||
{
|
{
|
||||||
|
CGAL_USE(comments);
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
ok = false;
|
ok = false;
|
||||||
return QList<Scene_item*>();
|
return QList<Scene_item*>();
|
||||||
|
|
|
||||||
|
|
@ -708,7 +708,6 @@ struct Cartesian_converter_property_map
|
||||||
{
|
{
|
||||||
return CGAL::Cartesian_converter<K1, K2>()(get(pm.vpm, k));
|
return CGAL::Cartesian_converter<K1, K2>()(get(pm.vpm, k));
|
||||||
}
|
}
|
||||||
|
|
||||||
friend void put(Cartesian_converter_property_map<GeomObject, Vpm>& pm, const key_type& k, const value_type& v)
|
friend void put(Cartesian_converter_property_map<GeomObject, Vpm>& pm, const key_type& k, const value_type& v)
|
||||||
{
|
{
|
||||||
put(pm.vpm, k, CGAL::Cartesian_converter<K2, K1>()(v));
|
put(pm.vpm, k, CGAL::Cartesian_converter<K2, K1>()(v));
|
||||||
|
|
|
||||||
|
|
@ -94,25 +94,25 @@ bool is_pretty(std::ios& s);
|
||||||
\subsection IOstreamInput Input Operator
|
\subsection IOstreamInput Input Operator
|
||||||
|
|
||||||
\cgal defines input operators for classes that are derived
|
\cgal defines input operators for classes that are derived
|
||||||
from the class `istream`. This allows to read from istreams
|
from the class `std::istream`. This allows to read from istreams
|
||||||
as `std::cin`, as well as from `std::istringstream` and `std::ifstream`.
|
as `std::cin`, as well as from `std::istringstream` and `std::ifstream`.
|
||||||
The input operator is defined for all classes in the \cgal `Kernel`.
|
The input operator is defined for all classes in the \cgal `Kernel`.
|
||||||
Let `is` be an input stream.
|
Let `is` be an input stream.
|
||||||
|
|
||||||
\code{.cpp}
|
\code{.cpp}
|
||||||
// Extracts object `c` from the stream `is`. Returns `is`.
|
// Extracts object `c` from the stream `is`. Returns `is`.
|
||||||
istream& operator>>(istream& is, Class c);
|
istream& operator>>(istream& is, Class& c);
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\code{.cpp}
|
\code{.cpp}
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/Segment_2.h>
|
#include <CGAL/Segment_2.h>
|
||||||
|
|
||||||
typedef CGAL::Point_2< CGAL::Cartesian<double> > Point;
|
typedef CGAL::Point_2< CGAL::Simple_cartesian<double> > Point;
|
||||||
typedef CGAL::Segment_2< CGAL::Cartesian<double> > Segment;
|
typedef CGAL::Segment_2< CGAL::Simple_cartesian<double> > Segment;
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
|
|
@ -123,7 +123,7 @@ main()
|
||||||
CGAL::IO::set_ascii_mode(std::cin);
|
CGAL::IO::set_ascii_mode(std::cin);
|
||||||
std::cin >> p >> q;
|
std::cin >> p >> q;
|
||||||
|
|
||||||
std::ifstream f("data.txt");
|
std::ifstream f("data.txt", std::ios::binary);
|
||||||
CGAL::IO::set_binary_mode(f);
|
CGAL::IO::set_binary_mode(f);
|
||||||
f >> s >> p;
|
f >> s >> p;
|
||||||
|
|
||||||
|
|
@ -150,11 +150,11 @@ ostream& operator<<(ostream& os, Class c);
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include <CGAL/Cartesian.h>
|
#include <CGAL/Simple_cartesian.h>
|
||||||
#include <CGAL/Segment_2.h>
|
#include <CGAL/Segment_2.h>
|
||||||
|
|
||||||
typedef CGAL::Point_2< CGAL::Cartesian<double> > Point;
|
typedef CGAL::Point_2< CGAL::Simple_cartesian<double> > Point;
|
||||||
typedef CGAL::Segment_2< CGAL::Cartesian<double> > Segment;
|
typedef CGAL::Segment_2< CGAL::Simple_cartesian<double> > Segment;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ template <class PointRange, class PolygonRange, class ColorOutputIterator, class
|
||||||
bool read_PLY(std::istream& is,
|
bool read_PLY(std::istream& is,
|
||||||
PointRange& points,
|
PointRange& points,
|
||||||
PolygonRange& polygons,
|
PolygonRange& polygons,
|
||||||
|
std::string& comments,
|
||||||
HEdgesOutputIterator hedges_out,
|
HEdgesOutputIterator hedges_out,
|
||||||
ColorOutputIterator fc_out,
|
ColorOutputIterator fc_out,
|
||||||
ColorOutputIterator vc_out,
|
ColorOutputIterator vc_out,
|
||||||
|
|
@ -72,6 +73,8 @@ bool read_PLY(std::istream& is,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
comments = reader.comments();
|
||||||
|
|
||||||
for(std::size_t i=0; i<reader.number_of_elements(); ++i)
|
for(std::size_t i=0; i<reader.number_of_elements(); ++i)
|
||||||
{
|
{
|
||||||
internal::PLY_element& element = reader.element(i);
|
internal::PLY_element& element = reader.element(i);
|
||||||
|
|
@ -228,6 +231,7 @@ template <class PointRange, class PolygonRange, class ColorRange, class HEdgesRa
|
||||||
bool read_PLY(std::istream& is,
|
bool read_PLY(std::istream& is,
|
||||||
PointRange& points,
|
PointRange& points,
|
||||||
PolygonRange& polygons,
|
PolygonRange& polygons,
|
||||||
|
std::string& comments,
|
||||||
HEdgesRange& hedges,
|
HEdgesRange& hedges,
|
||||||
ColorRange& fcolors,
|
ColorRange& fcolors,
|
||||||
ColorRange& vcolors,
|
ColorRange& vcolors,
|
||||||
|
|
@ -235,7 +239,7 @@ bool read_PLY(std::istream& is,
|
||||||
const bool verbose = false,
|
const bool verbose = false,
|
||||||
std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr)
|
std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr)
|
||||||
{
|
{
|
||||||
return internal::read_PLY(is, points, polygons,
|
return internal::read_PLY(is, points, polygons, comments,
|
||||||
std::back_inserter(hedges),
|
std::back_inserter(hedges),
|
||||||
std::back_inserter(fcolors),
|
std::back_inserter(fcolors),
|
||||||
std::back_inserter(vcolors),
|
std::back_inserter(vcolors),
|
||||||
|
|
@ -247,6 +251,7 @@ template <class PointRange, class PolygonRange, class ColorRange>
|
||||||
bool read_PLY(std::istream& is,
|
bool read_PLY(std::istream& is,
|
||||||
PointRange& points,
|
PointRange& points,
|
||||||
PolygonRange& polygons,
|
PolygonRange& polygons,
|
||||||
|
std::string& comments,
|
||||||
ColorRange& fcolors,
|
ColorRange& fcolors,
|
||||||
ColorRange& vcolors,
|
ColorRange& vcolors,
|
||||||
const bool verbose = false)
|
const bool verbose = false)
|
||||||
|
|
@ -254,7 +259,7 @@ bool read_PLY(std::istream& is,
|
||||||
std::vector<std::pair<unsigned int, unsigned int> > dummy_pui;
|
std::vector<std::pair<unsigned int, unsigned int> > dummy_pui;
|
||||||
std::vector<std::pair<float, float> > dummy_pf;
|
std::vector<std::pair<float, float> > dummy_pf;
|
||||||
|
|
||||||
return internal::read_PLY(is, points, polygons,
|
return internal::read_PLY(is, points, polygons, comments,
|
||||||
std::back_inserter(dummy_pui),
|
std::back_inserter(dummy_pui),
|
||||||
std::back_inserter(fcolors),
|
std::back_inserter(fcolors),
|
||||||
std::back_inserter(vcolors),
|
std::back_inserter(vcolors),
|
||||||
|
|
@ -284,7 +289,8 @@ bool read_PLY(std::istream& is,
|
||||||
* \param is the input stream
|
* \param is the input stream
|
||||||
* \param points points of the soup of polygons
|
* \param points points of the soup of polygons
|
||||||
* \param polygons a range of polygons. Each element in it describes a polygon
|
* \param polygons a range of polygons. Each element in it describes a polygon
|
||||||
* using the indices of the points in `points`.
|
* using the indices of the points in `points`
|
||||||
|
* \param comments a string that will contain all the comments found in the PLY file
|
||||||
* \param np optional \ref bgl_namedparameters "Named Parameters" described below
|
* \param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||||
*
|
*
|
||||||
* \cgalNamedParamsBegin
|
* \cgalNamedParamsBegin
|
||||||
|
|
@ -307,6 +313,7 @@ template <class PointRange, class PolygonRange, typename CGAL_NP_TEMPLATE_PARAME
|
||||||
bool read_PLY(std::istream& is,
|
bool read_PLY(std::istream& is,
|
||||||
PointRange& points,
|
PointRange& points,
|
||||||
PolygonRange& polygons,
|
PolygonRange& polygons,
|
||||||
|
std::string& comments,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
#ifndef DOXYGEN_RUNNING
|
#ifndef DOXYGEN_RUNNING
|
||||||
, std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr
|
, std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr
|
||||||
|
|
@ -319,7 +326,7 @@ bool read_PLY(std::istream& is,
|
||||||
std::vector<std::pair<unsigned int, unsigned int> > dummy_pui;
|
std::vector<std::pair<unsigned int, unsigned int> > dummy_pui;
|
||||||
std::vector<std::pair<float, float> > dummy_pf;
|
std::vector<std::pair<float, float> > dummy_pf;
|
||||||
|
|
||||||
return internal::read_PLY(is, points, polygons, std::back_inserter(dummy_pui),
|
return internal::read_PLY(is, points, polygons, comments, std::back_inserter(dummy_pui),
|
||||||
choose_parameter(get_parameter(np, internal_np::face_color_output_iterator),
|
choose_parameter(get_parameter(np, internal_np::face_color_output_iterator),
|
||||||
CGAL::Emptyset_iterator()),
|
CGAL::Emptyset_iterator()),
|
||||||
choose_parameter(get_parameter(np, internal_np::vertex_color_output_iterator),
|
choose_parameter(get_parameter(np, internal_np::vertex_color_output_iterator),
|
||||||
|
|
@ -328,6 +335,20 @@ bool read_PLY(std::istream& is,
|
||||||
choose_parameter(get_parameter(np, internal_np::verbose), true));
|
choose_parameter(get_parameter(np, internal_np::verbose), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class PointRange, class PolygonRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_PLY(std::istream& is,
|
||||||
|
PointRange& points,
|
||||||
|
PolygonRange& polygons,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::string unused_comments;
|
||||||
|
return read_PLY(is, points, polygons, unused_comments, np);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \ingroup PkgStreamSupportIoFuncsPLY
|
* \ingroup PkgStreamSupportIoFuncsPLY
|
||||||
*
|
*
|
||||||
|
|
@ -344,7 +365,8 @@ bool read_PLY(std::istream& is,
|
||||||
* \param fname the path to the input file
|
* \param fname the path to the input file
|
||||||
* \param points points of the soup of polygons
|
* \param points points of the soup of polygons
|
||||||
* \param polygons a range of polygons. Each element in it describes a polygon
|
* \param polygons a range of polygons. Each element in it describes a polygon
|
||||||
* using the indices of the points in `points`.
|
* using the indices of the points in `points`
|
||||||
|
* \param comments a string that will contain all the comments found in the PLY file
|
||||||
* \param np optional \ref bgl_namedparameters "Named Parameters" described below
|
* \param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||||
*
|
*
|
||||||
* \cgalNamedParamsBegin
|
* \cgalNamedParamsBegin
|
||||||
|
|
@ -367,6 +389,7 @@ template <typename PointRange, typename PolygonRange, typename CGAL_NP_TEMPLATE_
|
||||||
bool read_PLY(const std::string& fname,
|
bool read_PLY(const std::string& fname,
|
||||||
PointRange& points,
|
PointRange& points,
|
||||||
PolygonRange& polygons,
|
PolygonRange& polygons,
|
||||||
|
std::string& comments,
|
||||||
const CGAL_NP_CLASS& np = parameters::default_values()
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
#ifndef DOXYGEN_RUNNING
|
#ifndef DOXYGEN_RUNNING
|
||||||
, std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr
|
, std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr
|
||||||
|
|
@ -378,16 +401,30 @@ bool read_PLY(const std::string& fname,
|
||||||
{
|
{
|
||||||
std::ifstream is(fname, std::ios::binary);
|
std::ifstream is(fname, std::ios::binary);
|
||||||
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
|
CGAL::IO::set_mode(is, CGAL::IO::BINARY);
|
||||||
return read_PLY(is, points, polygons, np);
|
return read_PLY(is, points, polygons, comments, np);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::ifstream is(fname);
|
std::ifstream is(fname);
|
||||||
CGAL::IO::set_mode(is, CGAL::IO::ASCII);
|
CGAL::IO::set_mode(is, CGAL::IO::ASCII);
|
||||||
return read_PLY(is, points, polygons, np);
|
return read_PLY(is, points, polygons, comments, np);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename PointRange, typename PolygonRange, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
bool read_PLY(const std::string& fname,
|
||||||
|
PointRange& points,
|
||||||
|
PolygonRange& polygons,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, std::enable_if_t<internal::is_Range<PolygonRange>::value>* = nullptr
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::string unused_comments;
|
||||||
|
return read_PLY(fname, points, polygons, unused_comments, np);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Write
|
// Write
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#define CGAL_IO_PLY_PLY_WRITER_H
|
#define CGAL_IO_PLY_PLY_WRITER_H
|
||||||
|
|
||||||
#include <CGAL/IO/io.h>
|
#include <CGAL/IO/io.h>
|
||||||
|
#include <CGAL/number_utils.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace IO {
|
namespace IO {
|
||||||
|
|
|
||||||
|
|
@ -317,7 +317,7 @@ bool write_STL(std::ostream& os,
|
||||||
const Point& q = get(point_map, points[face[1]]);
|
const Point& q = get(point_map, points[face[1]]);
|
||||||
const Point& r = get(point_map, points[face[2]]);
|
const Point& r = get(point_map, points[face[2]]);
|
||||||
|
|
||||||
const Vector_3 n = collinear(p,q,r) ? Vector_3(1,0,0) : unit_normal(p,q,r);
|
const Vector_3 n = internal::construct_normal_of_STL_face(p, q, r, k);
|
||||||
|
|
||||||
const float coords[12] = { static_cast<float>(n.x()), static_cast<float>(n.y()), static_cast<float>(n.z()),
|
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>(p.x()), static_cast<float>(p.y()), static_cast<float>(p.z()),
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ enum Mode {ASCII = 0, PRETTY, BINARY};
|
||||||
\brief Inserts object `c` in the stream `os`. Returns `os`.
|
\brief Inserts object `c` in the stream `os`. Returns `os`.
|
||||||
\cgal defines output operators for classes that are derived
|
\cgal defines output operators for classes that are derived
|
||||||
from the class `ostream`. This allows to write to ostreams
|
from the class `ostream`. This allows to write to ostreams
|
||||||
as `cout` or `cerr`, as well as to `std::ostringstream`
|
as `std::cout` or `std::cerr`, as well as to `std::ostringstream`
|
||||||
and `std::ofstream`.
|
and `std::ofstream`.
|
||||||
The output operator is defined for all classes in the \cgal `Kernel` and for the class `Color` as well.
|
The output operator is defined for all classes in the \cgal `Kernel` and for the class `Color` as well.
|
||||||
|
|
||||||
|
|
@ -233,8 +233,8 @@ public:
|
||||||
\relates Output_rep
|
\relates Output_rep
|
||||||
\brief stream output of the \c Output_rep calls its \c operator().
|
\brief stream output of the \c Output_rep calls its \c operator().
|
||||||
|
|
||||||
\cgal defines output operators for classes that are derived from the class `ostream`.
|
\cgal defines output operators for classes that are derived from the class `std::ostream`.
|
||||||
This enables to write to ostreams as `cout` or `cerr`, as well as to `std::ostringstream`
|
This enables to write to output streams as `std::cout` or `std::cerr`, as well as to `std::ostringstream`
|
||||||
and `std::ofstream`.
|
and `std::ofstream`.
|
||||||
The output operator is defined for all classes in the \cgal `Kernel` and for the class `Color` as well.
|
The output operator is defined for all classes in the \cgal `Kernel` and for the class `Color` as well.
|
||||||
*/
|
*/
|
||||||
|
|
@ -455,7 +455,7 @@ public:
|
||||||
\brief stream input to the \c Input_rep calls its \c operator().
|
\brief stream input to the \c Input_rep calls its \c operator().
|
||||||
|
|
||||||
\brief \cgal defines input operators for classes that are derived
|
\brief \cgal defines input operators for classes that are derived
|
||||||
from the class `istream`. This allows to read from istreams
|
from the class `std::istream`. This allows to read from input streams
|
||||||
as `std::cin`, as well as from `std::istringstream` and `std::ifstream`.
|
as `std::cin`, as well as from `std::istringstream` and `std::ifstream`.
|
||||||
The input operator is defined for all classes in the \cgal `Kernel`.
|
The input operator is defined for all classes in the \cgal `Kernel`.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,169 @@
|
||||||
|
#include <CGAL/Surface_mesh.h>
|
||||||
|
#include <CGAL/Polyhedron_3.h>
|
||||||
|
#include <CGAL/Exact_rational.h>
|
||||||
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
|
#include <CGAL/boost/graph/helpers.h>
|
||||||
|
#include <CGAL/boost/graph/IO/PLY.h>
|
||||||
|
#include <CGAL/boost/graph/IO/polygon_mesh_io.h>
|
||||||
|
#include <CGAL/Surface_mesh/IO/PLY.h>
|
||||||
|
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
|
||||||
|
#include <CGAL/boost/graph/generators.h>
|
||||||
|
|
||||||
|
// typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck;
|
||||||
|
typedef CGAL::Simple_cartesian<CGAL::Exact_rational> Epeck;
|
||||||
|
typedef CGAL::Surface_mesh<Epeck::Point_3> Surface_mesh;
|
||||||
|
typedef boost::graph_traits<Surface_mesh>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef CGAL::Polyhedron_3<Epeck> Polyhedron_3;
|
||||||
|
typedef boost::graph_traits<Polyhedron_3>::vertex_descriptor pvertex_descriptor;
|
||||||
|
typedef Epeck::Point_3 Point_3;
|
||||||
|
typedef Epeck::Vector_3 Vector_3;
|
||||||
|
typedef CGAL::Simple_cartesian<double> SC;
|
||||||
|
typedef Surface_mesh::template Property_map<vertex_descriptor, Vector_3> VNMap;
|
||||||
|
typedef CGAL::Cartesian_converter_property_map< SC::Vector_3, VNMap> ScSmVertexNormalMap;
|
||||||
|
|
||||||
|
typedef std::map<pvertex_descriptor,Vector_3> PolyhedronVN;
|
||||||
|
typedef boost::associative_property_map<PolyhedronVN> PolyhedronVNMap;
|
||||||
|
typedef CGAL::Cartesian_converter_property_map< SC::Vector_3, PolyhedronVNMap> ScPolyhedronVertexNormalMap;
|
||||||
|
|
||||||
|
typedef boost::property_map<Surface_mesh, CGAL::vertex_point_t >::type SmVertexPointMap;
|
||||||
|
typedef CGAL::Cartesian_converter_property_map< SC::Point_3, SmVertexPointMap> ScSmVertexPointMap;
|
||||||
|
|
||||||
|
typedef boost::property_map<Polyhedron_3, CGAL::vertex_point_t >::type PolyhedronVertexPointMap;
|
||||||
|
typedef CGAL::Cartesian_converter_property_map< SC::Point_3, PolyhedronVertexPointMap> ScPolyhedronVertexPointMap;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Point_3 p(0.3, 0.3454, 0), q(0.6694, 0,0), r(0,0,0);
|
||||||
|
Surface_mesh sm;
|
||||||
|
Polyhedron_3 po;
|
||||||
|
CGAL::make_triangle(p,q,r,sm);
|
||||||
|
CGAL::make_triangle(p,q,r,po);
|
||||||
|
|
||||||
|
VNMap smvnpm = sm.template add_property_map<vertex_descriptor, Vector_3>("v:normal", CGAL::NULL_VECTOR).first;
|
||||||
|
|
||||||
|
CGAL::Polygon_mesh_processing::compute_vertex_normals(sm, smvnpm);
|
||||||
|
|
||||||
|
ScSmVertexNormalMap scsmvnpm(smvnpm);
|
||||||
|
|
||||||
|
SmVertexPointMap smvpm = get(CGAL::vertex_point_t(), sm);
|
||||||
|
ScSmVertexPointMap scsmvpm(smvpm);
|
||||||
|
PolyhedronVertexPointMap povpm = get(CGAL::vertex_point_t(), po);
|
||||||
|
ScPolyhedronVertexPointMap scpovpm(povpm);
|
||||||
|
|
||||||
|
// from <CGAL/boost/graph/IO/polygon_mesh_io.h>
|
||||||
|
// https://doc.cgal.org/latest/BGL/group__PkgBGLIoFuncsPLY.html#ga959dcd88ca979d3b6b0806d883a0247f
|
||||||
|
CGAL::IO::write_polygon_mesh("write_polygon_mesh_sm.ply", sm,
|
||||||
|
CGAL::parameters::stream_precision(17).use_binary_mode(true).vertex_point_map(scsmvpm).vertex_normal_map(scsmvnpm) );
|
||||||
|
|
||||||
|
{
|
||||||
|
Surface_mesh osm;
|
||||||
|
|
||||||
|
if(!CGAL::IO::read_polygon_mesh("write_polygon_mesh_sm.ply", osm))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: failed to read 'write_polygon_mesh_sm.ply'" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}else{
|
||||||
|
for(const std::string& s : osm.properties<vertex_descriptor>()){
|
||||||
|
std::cout << s << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
PolyhedronVN vn;
|
||||||
|
PolyhedronVNMap povnpm(vn);
|
||||||
|
CGAL::Polygon_mesh_processing::compute_vertex_normals(po, povnpm);
|
||||||
|
|
||||||
|
CGAL::IO::write_polygon_mesh("write_polygon_mesh_po.ply", po,
|
||||||
|
CGAL::parameters::stream_precision(17).use_binary_mode(true).vertex_point_map(povpm).vertex_normal_map(povnpm)) ;
|
||||||
|
if (!CGAL::IO::read_polygon_mesh("write_polygon_mesh_po.ply", po))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: failed to read 'write_polygon_mesh_po.ply'" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScPolyhedronVertexNormalMap scpovnpm(povnpm);
|
||||||
|
CGAL::IO::write_polygon_mesh("write_polygon_mesh_po_sc.ply", po,
|
||||||
|
CGAL::parameters::stream_precision(17).use_binary_mode(true).vertex_point_map(scpovpm).vertex_normal_map(scpovnpm)) ;
|
||||||
|
if (!CGAL::IO::read_polygon_mesh("write_polygon_mesh_po_sc.ply", po))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: failed to read 'write_polygon_mesh_po_sc.ply'" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Surface_mesh osm;
|
||||||
|
|
||||||
|
if(!CGAL::IO::read_polygon_mesh("write_polygon_mesh_po.ply", osm))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: failed to read 'write_polygon_mesh_po.ply'" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}else{
|
||||||
|
for(const std::string& s : osm.properties<vertex_descriptor>()){
|
||||||
|
std::cout << s << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// OK
|
||||||
|
// from #include <CGAL/boost/graph/IO/PLY.h>
|
||||||
|
// https://doc.cgal.org/latest/BGL/group__PkgBGLIoFuncsPLY.html#ga959dcd88ca979d3b6b0806d883a0247f
|
||||||
|
CGAL::IO::write_PLY("generic_write_PLY_sm.ply", sm, "generic write_PLY(Surface_mesh)",
|
||||||
|
CGAL::parameters::stream_precision(17).use_binary_mode(true).vertex_point_map(scsmvpm).vertex_normal_map(scsmvnpm));
|
||||||
|
|
||||||
|
{
|
||||||
|
Surface_mesh osm;
|
||||||
|
|
||||||
|
if(!CGAL::IO::read_polygon_mesh("generic_write_PLY_sm.ply", osm))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: failed to read 'generic_write_PLY_sm.ply'" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}else{
|
||||||
|
for(const std::string& s : osm.properties<vertex_descriptor>()){
|
||||||
|
std::cout << s << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ERROR this produces an invalid plyfile
|
||||||
|
CGAL::IO::write_PLY("generic_write_PLY_po.ply", po, "generic write_PLY(Polyhedron)",
|
||||||
|
CGAL::parameters::stream_precision(17).use_binary_mode(true).vertex_point_map(povpm));
|
||||||
|
|
||||||
|
{
|
||||||
|
Surface_mesh osm;
|
||||||
|
|
||||||
|
if(!CGAL::IO::read_polygon_mesh("generic_write_PLY_po.ply", osm))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: failed to read 'generic_write_PLY_po.ply'" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}else{
|
||||||
|
for(const std::string& s : osm.properties<vertex_descriptor>()){
|
||||||
|
std::cout << s << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// OK
|
||||||
|
// from #include <CGAL/Surface_mesh/IO/PLY.h>
|
||||||
|
// https://doc.cgal.org/latest/Surface_mesh/group__PkgSurfaceMeshIOFuncPLY.html#ga50f0e9f2b293855d2c7f1a62939cbe8d
|
||||||
|
std::ofstream out("overloaded_write_PLY_sm.ply", std::ios::binary);
|
||||||
|
CGAL::IO::set_binary_mode(out);
|
||||||
|
CGAL::IO::write_PLY(out, sm, "overloaded_write_PLY(Surface_mesh)",CGAL::parameters::stream_precision(17).use_binary_mode(true)
|
||||||
|
.vertex_point_map(scsmvpm).vertex_normal_map(scsmvnpm) );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Surface_mesh osm;
|
||||||
|
|
||||||
|
if(!CGAL::IO::read_polygon_mesh("overloaded_write_PLY_sm.ply", osm))
|
||||||
|
{
|
||||||
|
std::cerr << "Error: failed to read 'overloaded_write_PLY_sm.ply'" << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}else{
|
||||||
|
for(const std::string& s : osm.properties<vertex_descriptor>()){
|
||||||
|
std::cout << s << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include <CGAL/boost/graph/iterator.h>
|
#include <CGAL/boost/graph/iterator.h>
|
||||||
#include <CGAL/Named_function_parameters.h>
|
#include <CGAL/Named_function_parameters.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
|
||||||
#include <CGAL/IO/PLY.h>
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
|
|
@ -420,44 +421,77 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Point>
|
template <typename Point, typename NamedParameter>
|
||||||
bool fill_simplex_specific_header(std::ostream& os,
|
bool fill_simplex_specific_header(std::ostream& os,
|
||||||
const Surface_mesh<Point>& sm,
|
const Surface_mesh<Point>& sm,
|
||||||
std::vector<Abstract_property_printer<
|
std::vector<Abstract_property_printer<
|
||||||
typename Surface_mesh<Point>::Vertex_index>*>& printers,
|
typename Surface_mesh<Point>::Vertex_index>*>& printers,
|
||||||
const std::string& prop)
|
const std::string& prop,
|
||||||
|
const NamedParameter& np)
|
||||||
{
|
{
|
||||||
|
using CGAL::parameters::choose_parameter;
|
||||||
|
using CGAL::parameters::get_parameter;
|
||||||
|
|
||||||
typedef Surface_mesh<Point> SMesh;
|
typedef Surface_mesh<Point> SMesh;
|
||||||
typedef typename SMesh::Vertex_index VIndex;
|
typedef typename SMesh::Vertex_index VIndex;
|
||||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||||
typedef typename Kernel::FT FT;
|
typedef typename Kernel::FT FT;
|
||||||
typedef typename Kernel::Vector_3 Vector;
|
typedef typename Kernel::Vector_3 Vector;
|
||||||
typedef typename SMesh::template Property_map<VIndex, Point> Point_map;
|
|
||||||
|
typedef typename GetVertexPointMap<SMesh, NamedParameter>::const_type Point_map;
|
||||||
typedef typename SMesh::template Property_map<VIndex, Vector> Vector_map;
|
typedef typename SMesh::template Property_map<VIndex, Vector> Vector_map;
|
||||||
typedef typename SMesh::template Property_map<VIndex, Color> Vcolor_map;
|
typedef typename SMesh::template Property_map<VIndex, Color> Vcolor_map;
|
||||||
|
|
||||||
|
Point_map vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
|
||||||
|
get_const_property_map(CGAL::vertex_point, sm));
|
||||||
if(prop == "v:connectivity" || prop == "v:removed")
|
if(prop == "v:connectivity" || prop == "v:removed")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(prop == "v:point")
|
if(prop == "v:point")
|
||||||
{
|
{
|
||||||
if(std::is_same<FT, float>::value)
|
if constexpr(std::is_same<FT, float>::value)
|
||||||
{
|
{
|
||||||
os << "property float x" << std::endl
|
os << "property float x" << std::endl
|
||||||
<< "property float y" << std::endl
|
<< "property float y" << std::endl
|
||||||
<< "property float z" << std::endl;
|
<< "property float z" << std::endl;
|
||||||
|
printers.push_back(new Property_printer<VIndex, Point_map>(vpm));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
os << "property double x" << std::endl
|
os << "property double x" << std::endl
|
||||||
<< "property double y" << std::endl
|
<< "property double y" << std::endl
|
||||||
<< "property double z" << std::endl;
|
<< "property double z" << std::endl;
|
||||||
|
auto fvpm = CGAL::make_cartesian_converter_property_map<Epick::Point_3>(vpm);
|
||||||
|
printers.push_back(new Property_printer<VIndex, decltype(fvpm)>(fvpm));
|
||||||
}
|
}
|
||||||
printers.push_back(new Property_printer<VIndex, Point_map>(sm.points()));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prop == "v:normal")
|
if constexpr (!parameters::is_default_parameter<NamedParameter, internal_np::vertex_normal_map_t>::value)
|
||||||
|
{
|
||||||
|
auto vnm = get_parameter(np, internal_np::vertex_normal_map);
|
||||||
|
typedef decltype(vnm) Normal_map;
|
||||||
|
typedef typename Kernel_traits<typename Normal_map::value_type>::Kernel::FT FloatDouble;
|
||||||
|
if constexpr (std::is_same<FloatDouble, float>::value)
|
||||||
|
{
|
||||||
|
os << "property float nx" << std::endl
|
||||||
|
<< "property float ny" << std::endl
|
||||||
|
<< "property float nz" << std::endl;
|
||||||
|
printers.push_back(new Property_printer<VIndex, Normal_map>(vnm));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << "property double nx" << std::endl
|
||||||
|
<< "property double ny" << std::endl
|
||||||
|
<< "property double nz" << std::endl;
|
||||||
|
auto fvnm = CGAL::make_cartesian_converter_property_map<Epick::Vector_3>(vnm);
|
||||||
|
printers.push_back(new Property_printer<VIndex, decltype(fvnm)>(fvnm));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(prop == "v:normal")
|
||||||
{
|
{
|
||||||
auto pmap = sm.template property_map<VIndex, Vector>(prop);
|
auto pmap = sm.template property_map<VIndex, Vector>(prop);
|
||||||
if(pmap.has_value())
|
if(pmap.has_value())
|
||||||
|
|
@ -467,14 +501,16 @@ bool fill_simplex_specific_header(std::ostream& os,
|
||||||
os << "property float nx" << std::endl
|
os << "property float nx" << std::endl
|
||||||
<< "property float ny" << std::endl
|
<< "property float ny" << std::endl
|
||||||
<< "property float nz" << std::endl;
|
<< "property float nz" << std::endl;
|
||||||
|
printers.push_back(new Property_printer<VIndex, Vector_map>(*pmap));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
os << "property double nx" << std::endl
|
os << "property double nx" << std::endl
|
||||||
<< "property double ny" << std::endl
|
<< "property double ny" << std::endl
|
||||||
<< "property double nz" << std::endl;
|
<< "property double nz" << std::endl;
|
||||||
|
auto fvnm = CGAL::make_cartesian_converter_property_map<Epick::Vector_3>(*pmap);
|
||||||
|
printers.push_back(new Property_printer<VIndex, decltype(fvnm)>(fvnm));
|
||||||
}
|
}
|
||||||
printers.push_back(new Property_printer<VIndex, Vector_map>(*pmap));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -497,12 +533,13 @@ bool fill_simplex_specific_header(std::ostream& os,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Point>
|
template <typename Point, typename NamedParameter>
|
||||||
bool fill_simplex_specific_header(std::ostream& os,
|
bool fill_simplex_specific_header(std::ostream& os,
|
||||||
const Surface_mesh<Point>& sm,
|
const Surface_mesh<Point>& sm,
|
||||||
std::vector<Abstract_property_printer<
|
std::vector<Abstract_property_printer<
|
||||||
typename Surface_mesh<Point>::Face_index>*>& printers,
|
typename Surface_mesh<Point>::Face_index>*>& printers,
|
||||||
const std::string& prop)
|
const std::string& prop,
|
||||||
|
const NamedParameter&)
|
||||||
{
|
{
|
||||||
typedef typename Surface_mesh<Point>::Face_index FIndex;
|
typedef typename Surface_mesh<Point>::Face_index FIndex;
|
||||||
typedef CGAL::IO::Color Color;
|
typedef CGAL::IO::Color Color;
|
||||||
|
|
@ -528,12 +565,13 @@ bool fill_simplex_specific_header(std::ostream& os,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Point>
|
template <typename Point, typename NamedParameter>
|
||||||
bool fill_simplex_specific_header(std::ostream&,
|
bool fill_simplex_specific_header(std::ostream&,
|
||||||
const Surface_mesh<Point>& ,
|
const Surface_mesh<Point>& ,
|
||||||
std::vector<Abstract_property_printer<
|
std::vector<Abstract_property_printer<
|
||||||
typename Surface_mesh<Point>::Edge_index>*>& ,
|
typename Surface_mesh<Point>::Edge_index>*>& ,
|
||||||
const std::string& prop)
|
const std::string& prop,
|
||||||
|
const NamedParameter&)
|
||||||
{
|
{
|
||||||
if(prop == "e:removed")
|
if(prop == "e:removed")
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -541,12 +579,13 @@ bool fill_simplex_specific_header(std::ostream&,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Point>
|
template <typename Point, typename NamedParameter>
|
||||||
bool fill_simplex_specific_header(std::ostream&,
|
bool fill_simplex_specific_header(std::ostream&,
|
||||||
const Surface_mesh<Point>& ,
|
const Surface_mesh<Point>& ,
|
||||||
std::vector<Abstract_property_printer<
|
std::vector<Abstract_property_printer<
|
||||||
typename Surface_mesh<Point>::Halfedge_index>*>& ,
|
typename Surface_mesh<Point>::Halfedge_index>*>& ,
|
||||||
const std::string& prop)
|
const std::string& prop,
|
||||||
|
const NamedParameter&)
|
||||||
{
|
{
|
||||||
if(prop == "h:connectivity")
|
if(prop == "h:connectivity")
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -733,7 +772,7 @@ void fill_header(std::ostream& os, const Surface_mesh<Point>& sm,
|
||||||
if (has_fcolor && prop[i] == "f:color")
|
if (has_fcolor && prop[i] == "f:color")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(fill_simplex_specific_header(os, sm, printers, prop[i]))
|
if(fill_simplex_specific_header(os, sm, printers, prop[i], np))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
fill_header_impl<std::tuple_size<Type_tuple>::value>(Type_tuple(), type_strings, sm, prop[i], os, printers);
|
fill_header_impl<std::tuple_size<Type_tuple>::value>(Type_tuple(), type_strings, sm, prop[i], os, printers);
|
||||||
|
|
@ -773,21 +812,37 @@ void fill_header(std::ostream& os, const Surface_mesh<Point>& sm,
|
||||||
/// \param comments a string used to store the potential comments found in the PLY header.
|
/// \param comments a string used to store the potential comments found in the PLY header.
|
||||||
/// Each line starting by "comment " in the header is appended to the `comments` string
|
/// Each line starting by "comment " in the header is appended to the `comments` string
|
||||||
/// (without the "comment " word).
|
/// (without the "comment " word).
|
||||||
/// \param verbose whether extra information is printed when an incident occurs during reading
|
/// \param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||||
|
///
|
||||||
|
/// \cgalNamedParamsBegin
|
||||||
|
/// \cgalParamNBegin{verbose}
|
||||||
|
/// \cgalParamDescription{whether extra information is printed when an incident occurs during reading}
|
||||||
|
/// \cgalParamType{Boolean}
|
||||||
|
/// \cgalParamDefault{`false`}
|
||||||
|
/// \cgalParamNEnd
|
||||||
|
/// \cgalNamedParamsEnd
|
||||||
///
|
///
|
||||||
/// \pre The data in the stream must represent a two-manifold. If this is not the case
|
/// \pre The data in the stream must represent a two-manifold. If this is not the case
|
||||||
/// the `failbit` of `is` is set and the mesh cleared.
|
/// the `failbit` of `is` is set and the mesh cleared.
|
||||||
///
|
///
|
||||||
/// \returns `true` if reading was successful, `false` otherwise.
|
/// \returns `true` if reading was successful, `false` otherwise.
|
||||||
///
|
///
|
||||||
template <typename P>
|
template <typename P, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
bool read_PLY(std::istream& is,
|
bool read_PLY(std::istream& is,
|
||||||
Surface_mesh<P>& sm,
|
Surface_mesh<P>& sm,
|
||||||
std::string& comments,
|
std::string& comments,
|
||||||
bool verbose = true)
|
const CGAL_NP_CLASS& np = parameters::default_values())
|
||||||
{
|
{
|
||||||
typedef typename Surface_mesh<P>::size_type size_type;
|
typedef typename Surface_mesh<P>::size_type size_type;
|
||||||
|
|
||||||
|
// not yet supported: this function only uses the Surface_mesh's internal pmaps
|
||||||
|
// to make it work, it'd be sufficient to modify Surface_mesh_filler's maps
|
||||||
|
// static_assert(CGAL::parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value);
|
||||||
|
// static_assert(CGAL::parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value);
|
||||||
|
// static_assert(CGAL::parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value);
|
||||||
|
|
||||||
|
const bool verbose = CGAL::parameters::choose_parameter(CGAL::parameters::get_parameter(np, internal_np::verbose), true);
|
||||||
|
|
||||||
if(!is.good())
|
if(!is.good())
|
||||||
{
|
{
|
||||||
if(verbose)
|
if(verbose)
|
||||||
|
|
@ -874,6 +929,18 @@ bool read_PLY(std::istream& is,
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
||||||
|
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||||
|
// for backward compatibility
|
||||||
|
template <typename P>
|
||||||
|
bool read_PLY(std::istream& is,
|
||||||
|
Surface_mesh<P>& sm,
|
||||||
|
std::string& comments,
|
||||||
|
bool verbose)
|
||||||
|
{
|
||||||
|
return read_PLY(is, sm, comments, CGAL::parameters::verbose(verbose));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename P>
|
template <typename P>
|
||||||
bool read_PLY(std::istream& is, Surface_mesh<P>& sm)
|
bool read_PLY(std::istream& is, Surface_mesh<P>& sm)
|
||||||
{
|
{
|
||||||
|
|
@ -927,6 +994,7 @@ namespace IO {
|
||||||
/// \cgalNamedParamsEnd
|
/// \cgalNamedParamsEnd
|
||||||
///
|
///
|
||||||
/// \returns `true` if writing was successful, `false` otherwise.
|
/// \returns `true` if writing was successful, `false` otherwise.
|
||||||
|
|
||||||
template <typename P,
|
template <typename P,
|
||||||
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
bool write_PLY(std::ostream& os,
|
bool write_PLY(std::ostream& os,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
#include <CGAL/Surface_mesh/Surface_mesh.h>
|
||||||
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
|
||||||
|
typedef Kernel::Point_3 Point;
|
||||||
|
|
||||||
|
typedef CGAL::Surface_mesh<Point> SMesh;
|
||||||
|
typedef boost::graph_traits<SMesh>::vertex_descriptor vertex_descriptor;
|
||||||
|
typedef boost::graph_traits<SMesh>::face_descriptor face_descriptor;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::ifstream in(CGAL::data_file_path("meshes/colored_tetra.ply"));
|
||||||
|
SMesh mesh;
|
||||||
|
CGAL::IO::read_PLY(in, mesh);
|
||||||
|
|
||||||
|
std::cerr << "Read mesh with " << mesh.number_of_vertices() << " vertices and "
|
||||||
|
<< mesh.number_of_faces() << " faces" << std::endl;
|
||||||
|
|
||||||
|
std::cerr << "Properties associated with vertices:" << std::endl;
|
||||||
|
std::vector<std::string> properties = mesh.properties<SMesh::Vertex_index>();
|
||||||
|
for(std::size_t i = 0; i < properties.size(); ++ i)
|
||||||
|
std::cerr << " * " << properties[i] << std::endl;
|
||||||
|
|
||||||
|
std::cerr << "Properties associated with faces:" << std::endl;
|
||||||
|
properties = mesh.properties<SMesh::Face_index>();
|
||||||
|
for(std::size_t i = 0; i < properties.size(); ++ i)
|
||||||
|
std::cerr << " * " << properties[i] << std::endl;
|
||||||
|
|
||||||
|
mesh.add_property_map<SMesh::Edge_index, short>("id", 42);
|
||||||
|
mesh.add_property_map<SMesh::Halfedge_index, float>("u", 13.f);
|
||||||
|
mesh.add_property_map<SMesh::Halfedge_index, float>("v", 37.f);
|
||||||
|
|
||||||
|
// Append second mesh
|
||||||
|
std::ifstream in2("epeck_tetra.ply");
|
||||||
|
CGAL::IO::read_PLY(in2, mesh);
|
||||||
|
|
||||||
|
std::ofstream out("epeck_out.ply");
|
||||||
|
// CGAL::IO::set_binary_mode(out);
|
||||||
|
CGAL::IO::write_PLY(out, mesh);
|
||||||
|
|
||||||
|
// extra test for read/write of properties
|
||||||
|
mesh = SMesh();
|
||||||
|
in.close();
|
||||||
|
in.open(CGAL::data_file_path("meshes/colored_tetra.ply"));
|
||||||
|
CGAL::IO::read_PLY(in, mesh);
|
||||||
|
float fvalue=1001;
|
||||||
|
auto v_uvmap = mesh.add_property_map<SMesh::Vertex_index, std::vector<float>>("v:uv").first;
|
||||||
|
auto v_umap = mesh.add_property_map<SMesh::Vertex_index, float>("v:u").first;
|
||||||
|
auto v_vmap = mesh.add_property_map<SMesh::Vertex_index, float>("v:v").first;
|
||||||
|
for (SMesh::Vertex_index v : vertices(mesh))
|
||||||
|
{
|
||||||
|
v_uvmap[v]={fvalue, -fvalue};
|
||||||
|
v_umap[v]=fvalue;
|
||||||
|
v_vmap[v]=-fvalue;
|
||||||
|
++fvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dvalue=2001;
|
||||||
|
auto f_uvmap = mesh.add_property_map<SMesh::Face_index, std::vector<double>>("f:uv").first;
|
||||||
|
auto f_umap = mesh.add_property_map<SMesh::Face_index, double>("f:u").first;
|
||||||
|
auto f_vmap = mesh.add_property_map<SMesh::Face_index, double>("f:v").first;
|
||||||
|
for (SMesh::Face_index f : faces(mesh))
|
||||||
|
{
|
||||||
|
f_uvmap[f]={dvalue, -dvalue};
|
||||||
|
f_umap[f]=dvalue;
|
||||||
|
f_vmap[f]=-dvalue;
|
||||||
|
++dvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.close();
|
||||||
|
out.open("epeck_out_ascii.ply");
|
||||||
|
CGAL::IO::write_PLY(out, mesh);
|
||||||
|
out.close();
|
||||||
|
out.open("epeck_out_binary.ply", std::ios::binary);
|
||||||
|
CGAL::IO::set_binary_mode(out);
|
||||||
|
CGAL::IO::write_PLY(out, mesh);
|
||||||
|
out.close();
|
||||||
|
mesh.clear();
|
||||||
|
|
||||||
|
const std::array<std::string,2> fnames = {"epeck_out_ascii.ply", "epeck_out_binary.ply"};
|
||||||
|
for (std::string fn : fnames)
|
||||||
|
{
|
||||||
|
std::cout << "Reading " << fn << "\n";
|
||||||
|
in.close();
|
||||||
|
in.open(fn, std::ios::binary);
|
||||||
|
SMesh mesh_bis;
|
||||||
|
CGAL::IO::read_PLY(in, mesh_bis);
|
||||||
|
|
||||||
|
v_uvmap = mesh_bis.property_map<SMesh::Vertex_index, std::vector<float>>("v:uv").value();
|
||||||
|
v_umap = mesh_bis.property_map<SMesh::Vertex_index, float>("v:u").value();
|
||||||
|
v_vmap = mesh_bis.property_map<SMesh::Vertex_index, float>("v:v").value();
|
||||||
|
|
||||||
|
fvalue=1001;
|
||||||
|
for (SMesh::Vertex_index v : vertices(mesh_bis))
|
||||||
|
{
|
||||||
|
assert(v_uvmap[v].size()==2);
|
||||||
|
assert(v_uvmap[v][0]==fvalue);
|
||||||
|
assert(v_uvmap[v][1]==-fvalue);
|
||||||
|
assert(v_umap[v]==fvalue);
|
||||||
|
assert(v_vmap[v]==-fvalue);
|
||||||
|
++fvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
f_uvmap = mesh_bis.property_map<SMesh::Face_index, std::vector<double>>("f:uv").value();
|
||||||
|
f_umap = mesh_bis.property_map<SMesh::Face_index, double>("f:u").value();
|
||||||
|
f_vmap = mesh_bis.property_map<SMesh::Face_index, double>("f:v").value();
|
||||||
|
|
||||||
|
dvalue=2001;
|
||||||
|
for (SMesh::Face_index f : faces(mesh_bis))
|
||||||
|
{
|
||||||
|
assert(f_uvmap[f].size()==2);
|
||||||
|
assert(f_uvmap[f][0]==dvalue);
|
||||||
|
assert(f_uvmap[f][1]==-dvalue);
|
||||||
|
assert(f_umap[f]==dvalue);
|
||||||
|
assert(f_vmap[f]==-dvalue);
|
||||||
|
++dvalue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -76,7 +76,7 @@ int main()
|
||||||
out.open("out_ascii.ply");
|
out.open("out_ascii.ply");
|
||||||
CGAL::IO::write_PLY(out, mesh);
|
CGAL::IO::write_PLY(out, mesh);
|
||||||
out.close();
|
out.close();
|
||||||
out.open("out_binary.ply");
|
out.open("out_binary.ply", std::ios::binary);
|
||||||
CGAL::IO::set_binary_mode(out);
|
CGAL::IO::set_binary_mode(out);
|
||||||
CGAL::IO::write_PLY(out, mesh);
|
CGAL::IO::write_PLY(out, mesh);
|
||||||
out.close();
|
out.close();
|
||||||
|
|
@ -87,7 +87,7 @@ int main()
|
||||||
{
|
{
|
||||||
std::cout << "Reading " << fn << "\n";
|
std::cout << "Reading " << fn << "\n";
|
||||||
in.close();
|
in.close();
|
||||||
in.open(fn);
|
in.open(fn, std::ios::binary);
|
||||||
SMesh mesh_bis;
|
SMesh mesh_bis;
|
||||||
CGAL::IO::read_PLY(in, mesh_bis);
|
CGAL::IO::read_PLY(in, mesh_bis);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue