dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/IO/read_ply_points.h

409 lines
14 KiB
C++

// Copyright (c) 2015 Geometry Factory
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Point_set_processing_3/include/CGAL/IO/read_ply_points.h $
// $Id: read_ply_points.h c253679 2020-04-18T16:27:58+02:00 Sébastien Loriot
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Simon Giraudot
#ifndef CGAL_READ_PLY_POINTS_H
#define CGAL_READ_PLY_POINTS_H
#include <CGAL/license/Point_set_processing_3.h>
#include <CGAL/config.h>
#include <tuple>
#include <CGAL/IO/PLY.h>
#include <CGAL/property_map.h>
#include <CGAL/value_type_traits.h>
#include <CGAL/point_set_processing_assertions.h>
#include <CGAL/Kernel_traits.h>
#include <CGAL/IO/io.h>
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <boost/version.hpp>
#include <boost/cstdint.hpp>
#include <iostream>
#include <sstream>
#include <string>
namespace CGAL {
#ifdef DOXYGEN_RUNNING // Document some parts from Stream_support here for convenience
/**
\ingroup PkgPointSetProcessing3IOPly
Class used to identify a %PLY property as a type and a name.
\sa `read_ply_points_with_properties()`
*/
template <typename T>
struct PLY_property
{
typedef T type;
const char* name;
PLY_property (const char* name) : name (name) { }
};
/**
\ingroup PkgPointSetProcessing3IOPly
Generates a %PLY property handler to read 3D points. Points are
constructed from the input using 3 %PLY properties of type `FT`
and named `x`, `y` and `z`. `FT` is `float` if the points use
`CGAL::Simple_cartesian<float>` and `double` otherwise.
\sa `read_ply_points_with_properties()`
\tparam PointMap the property map used to store points.
*/
template <typename PointMap>
std::tuple<PointMap,
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
make_ply_point_reader(PointMap point_map);
/**
\ingroup PkgPointSetProcessing3IOPly
Generates a %PLY property handler to read 3D normal
vectors. Vectors are constructed from the input using 3 PLY
properties of type `FT` and named `nx`, `ny` and `nz`. `FT`
is `float` if the points use `CGAL::Simple_cartesian<float>` and
`double` otherwise.
\sa `read_ply_points_with_properties()`
\tparam VectorMap the property map used to store vectors.
*/
template <typename VectorMap>
std::tuple<VectorMap,
typename Kernel_traits<typename VectorMap::value_type>::Kernel::Construct_vector_3,
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
make_ply_normal_reader(VectorMap normal_map);
#endif // DOXYGEN_RUNNING
/**
\ingroup PkgPointSetProcessingIOPly
Reads user-selected points properties from a .ply stream (ASCII or
binary).
Potential additional point properties and faces are ignored.
Properties are handled through a variadic list of property
handlers. A `PropertyHandler` can either be:
- A `std::pair<PropertyMap, PLY_property<T> >` if the user wants
to read a %PLY property as a scalar value T (for example, storing
an `int` %PLY property into an `int` variable).
- A `std::tuple<PropertyMap, Constructor,
PLY_property<T>...>` if the user wants to use one or several PLY
properties to construct a complex object (for example, storing 3
`uchar` %PLY properties into a %Color object that can for example
be a `std::array<unsigned char, 3>`). In that case, the
second element of the tuple should be a functor that constructs
the value type of `PropertyMap` from N objects of types `T`.
\sa `make_ply_point_reader()`
\sa `make_ply_normal_reader()`
\cgalRequiresCPP11
\tparam OutputIteratorValueType type of objects that can be put in `OutputIterator`.
It is default to `value_type_traits<OutputIterator>::%type` and can be omitted when the default is fine.
\tparam OutputIterator iterator over output points.
\tparam PropertyHandler handlers to recover properties.
\return `true` on success.
*/
template <typename OutputIteratorValueType,
typename OutputIterator,
typename ... PropertyHandler>
bool read_ply_points_with_properties (std::istream& stream,
OutputIterator output,
PropertyHandler&& ... properties)
{
typedef typename value_type_traits<OutputIterator>::type OutputValueType;
if(!stream)
{
std::cerr << "Error: cannot open file" << std::endl;
return false;
}
internal::PLY::PLY_reader reader;
if (!(reader.init (stream)))
{
stream.setstate(std::ios::failbit);
return false;
}
for (std::size_t i = 0; i < reader.number_of_elements(); ++ i)
{
internal::PLY::PLY_element& element = reader.element(i);
for (std::size_t j = 0; j < element.number_of_items(); ++ j)
{
for (std::size_t k = 0; k < element.number_of_properties(); ++ k)
{
internal::PLY::PLY_read_number* property = element.property(k);
property->get (stream);
if (stream.fail())
return false;
}
if (element.name() == "vertex" || element.name() == "vertices")
{
OutputValueType new_element;
internal::PLY::process_properties (element, new_element, std::forward<PropertyHandler>(properties)...);
*(output ++) = new_element;
}
}
}
return true;
}
/// \cond SKIP_IN_MANUAL
template <typename OutputIterator,
typename ... PropertyHandler>
bool read_ply_points_with_properties (std::istream& stream,
OutputIterator output,
PropertyHandler&& ... properties)
{
typedef typename value_type_traits<OutputIterator>::type OutputValueType;
return read_ply_points_with_properties<OutputValueType>
(stream, output, std::forward<PropertyHandler>(properties)...);
}
/// \endcond
/**
\ingroup PkgPointSetProcessing3IOPly
Reads points (positions + normals, if available) from a .ply
stream (ASCII or binary).
Potential additional point properties and faces are ignored.
\tparam OutputIteratorValueType type of objects that can be put in `OutputIterator`.
It is default to `value_type_traits<OutputIterator>::%type` and can be omitted when the default is fine.
\tparam OutputIterator iterator over output points.
\param stream input stream.
\param output output iterator over points.
\param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
\cgalNamedParamsBegin
\cgalParamNBegin{point_map}
\cgalParamDescription{a property map associating points to the elements of the point range}
\cgalParamType{a model of `WritablePropertyMap` with value type `geom_traits::Point_3`}
\cgalParamDefault{`CGAL::Identity_property_map<geom_traits::Point_3>`}
\cgalParamNEnd
\cgalParamNBegin{normal_map}
\cgalParamDescription{a property map associating normals to the elements of the poing range}
\cgalParamType{a model of `ReadWritePropertyMap` with value type `geom_traits::Vector_3`}
\cgalParamDefault{If this parameter is omitted, normals in the input stream are ignored.}
\cgalParamNEnd
\cgalParamNBegin{geom_traits}
\cgalParamDescription{an instance of a geometric traits class}
\cgalParamType{a model of `Kernel`}
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
\cgalParamNEnd
\cgalNamedParamsEnd
\return true on success.
\cgalRequiresCPP11
*/
template < typename OutputIteratorValueType,
typename OutputIterator,
#ifdef DOXYGEN_RUNNING
typename NamedParameters
#else
typename CGAL_BGL_NP_TEMPLATE_PARAMETERS
#endif
>
bool read_ply_points(std::istream& stream,
OutputIterator output,
#ifdef DOXYGEN_RUNNING
const NamedParameters& np)
#else
const CGAL_BGL_NP_CLASS& np)
#endif
{
using parameters::choose_parameter;
using parameters::get_parameter;
typedef Point_set_processing_3::Fake_point_range<OutputIteratorValueType> PointRange;
// basic geometric types
typedef typename CGAL::GetPointMap<PointRange, CGAL_BGL_NP_CLASS>::type PointMap;
typedef typename Point_set_processing_3::GetNormalMap<PointRange, CGAL_BGL_NP_CLASS>::type NormalMap;
bool has_normals = !(boost::is_same<NormalMap,
typename Point_set_processing_3::GetNormalMap<PointRange, CGAL_BGL_NP_CLASS>::NoMap>::value);
PointMap point_map = choose_parameter<PointMap>(get_parameter(np, internal_np::point_map));
NormalMap normal_map = choose_parameter<NormalMap>(get_parameter(np, internal_np::normal_map));
if (has_normals)
return read_ply_points_with_properties (stream, output,
make_ply_point_reader (point_map),
make_ply_normal_reader (normal_map));
// else
return read_ply_points_with_properties (stream, output,
make_ply_point_reader (point_map));
}
/// \cond SKIP_IN_MANUAL
// variant with default NP
template <typename OutputIteratorValueType,
typename OutputIterator>
bool
read_ply_points(
std::istream& stream, ///< input stream.
OutputIterator output) ///< output iterator over points.
{
return read_ply_points<OutputIteratorValueType>
(stream, output, CGAL::parameters::all_default());
}
// variant with default output iterator value type
template <typename OutputIterator,
typename CGAL_BGL_NP_TEMPLATE_PARAMETERS>
bool
read_ply_points(
std::istream& stream, ///< input stream.
OutputIterator output,
const CGAL_BGL_NP_CLASS& np)
{
return read_ply_points<typename value_type_traits<OutputIterator>::type>
(stream, output, np);
}
// variant with default NP and output iterator value type
template <typename OutputIterator>
bool
read_ply_points(
std::istream& stream, ///< input stream.
OutputIterator output)
{
return read_ply_points<typename value_type_traits<OutputIterator>::type>
(stream, output, CGAL::parameters::all_default());
}
#ifndef CGAL_NO_DEPRECATED_CODE
// deprecated API
template < typename OutputIteratorValueType,
typename OutputIterator,
typename PointMap,
typename NormalMap >
CGAL_DEPRECATED_MSG("you are using the deprecated V1 API of CGAL::read_ply_points_and_normals(), please update your code")
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
OutputIterator output, ///< output iterator over points.
PointMap point_map, ///< property map: value_type of OutputIterator -> Point_3.
NormalMap normal_map) ///< property map: value_type of OutputIterator -> Vector_3.
{
return read_ply_points<OutputIteratorValueType>
(stream, output,
CGAL::parameters::point_map (point_map).
normal_map (normal_map));
}
// deprecated API
template < typename OutputIterator,
typename PointMap,
typename NormalMap >
CGAL_DEPRECATED_MSG("you are using the deprecated V1 API of CGAL::read_ply_points_and_normals(), please update your code")
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
OutputIterator output, ///< output iterator over points.
PointMap point_map, ///< property map: value_type of OutputIterator -> Point_3.
NormalMap normal_map) ///< property map: value_type of OutputIterator -> Vector_3.
{
return read_ply_points<typename value_type_traits<OutputIterator>::type>
(stream, output,
CGAL::parameters::point_map (point_map).
normal_map (normal_map));
}
// deprecated API
template < typename OutputIteratorValueType,
typename OutputIterator,
typename NormalMap >
CGAL_DEPRECATED_MSG("you are using the deprecated V1 API of CGAL::read_ply_points_and_normals(), please update your code")
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
OutputIterator output, ///< output iterator over points.
NormalMap normal_map) ///< property map: value_type of OutputIterator -> Vector_3.
{
return read_ply_points<OutputIteratorValueType>
(stream, output,
CGAL::parameters::normal_map (normal_map));
}
// deprecated API
template < typename OutputIterator,
typename NormalMap >
CGAL_DEPRECATED_MSG("you are using the deprecated V1 API of CGAL::read_ply_points_and_normals(), please update your code")
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
OutputIterator output, ///< output iterator over points.
NormalMap normal_map) ///< property map: value_type of OutputIterator -> Vector_3.
{
return read_ply_points<typename value_type_traits<OutputIterator>::type>
(stream, output,
CGAL::parameters::normal_map (normal_map));
}
// deprecated API
template <typename OutputIteratorValueType,
typename OutputIterator,
typename PointMap
>
CGAL_DEPRECATED_MSG("you are using the deprecated V1 API of CGAL::read_ply_points(), please update your code")
bool
read_ply_points(
std::istream& stream, ///< input stream.
OutputIterator output, ///< output iterator over points.
PointMap point_map) ///< property map: value_type of OutputIterator -> Point_3.
{
return read_ply_points<OutputIteratorValueType>
(stream, output,
CGAL::parameters::point_map (point_map));
}
// deprecated API
template < typename OutputIterator,
typename PointMap >
CGAL_DEPRECATED_MSG("you are using the deprecated V1 API of CGAL::read_ply_points(), please update your code")
bool read_ply_points(std::istream& stream, ///< input stream.
OutputIterator output, ///< output iterator over points.
PointMap point_map) ///< property map: value_type of OutputIterator -> Point_3.
{
return read_ply_points<typename value_type_traits<OutputIterator>::type>
(stream, output,
CGAL::parameters::point_map (point_map));
}
#endif // CGAL_NO_DEPRECATED_CODE
/// \endcond
} //namespace CGAL
#undef TRY_TO_GENERATE_POINT_PROPERTY
#undef TRY_TO_GENERATE_SIZED_FACE_PROPERTY
#undef TRY_TO_GENERATE_FACE_PROPERTY
#endif // CGAL_READ_PLY_POINTS_H