mirror of https://github.com/CGAL/cgal
Merge branch 'Point_set_processing_3-IO_ply-GF-old' into Point_set_processing_3-IO_ply-GF
This commit is contained in:
commit
c2e38b72a6
|
|
@ -0,0 +1,573 @@
|
|||
#ifndef CGAL_READ_PLY_POINTS_H
|
||||
#define CGAL_READ_PLY_POINTS_H
|
||||
|
||||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/value_type_traits.h>
|
||||
#include <CGAL/point_set_processing_assertions.h>
|
||||
|
||||
#include <boost/version.hpp>
|
||||
#if BOOST_VERSION >= 104000
|
||||
#include <boost/property_map/property_map.hpp>
|
||||
#else
|
||||
#include <boost/property_map.hpp>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
||||
// PLY types:
|
||||
// name type number of bytes
|
||||
// ---------------------------------------
|
||||
// char character 1
|
||||
// uchar unsigned character 1
|
||||
// short short integer 2
|
||||
// ushort unsigned short integer 2
|
||||
// int integer 4
|
||||
// uint unsigned integer 4
|
||||
// float single-precision float 4
|
||||
// double double-precision float 8
|
||||
|
||||
namespace internal {
|
||||
|
||||
class Ply_read_number
|
||||
{
|
||||
protected:
|
||||
std::string m_name;
|
||||
std::size_t m_format;
|
||||
|
||||
public:
|
||||
Ply_read_number (std::string name, std::size_t format)
|
||||
: m_name (name), m_format (format) { }
|
||||
virtual ~Ply_read_number() { }
|
||||
|
||||
const std::string& name () const { return m_name; }
|
||||
|
||||
virtual double operator() (std::istream& stream) const = 0;
|
||||
|
||||
template <typename Type>
|
||||
Type read (std::istream& stream) const
|
||||
{
|
||||
if (m_format == 0) // Ascii
|
||||
{
|
||||
Type t;
|
||||
stream >> t;
|
||||
return t;
|
||||
}
|
||||
else // Binary (2 = little endian)
|
||||
{
|
||||
std::size_t size = sizeof (Type);
|
||||
unsigned int buffer[size];
|
||||
|
||||
stream.read(reinterpret_cast<char*>(buffer), size);
|
||||
|
||||
if (m_format == 2) // Big endian
|
||||
{
|
||||
for (std::size_t i = 0; i < size / 2; ++ i)
|
||||
{
|
||||
unsigned char tmp = buffer[i];
|
||||
buffer[i] = buffer[size - i];
|
||||
buffer[size - i] = tmp;
|
||||
}
|
||||
}
|
||||
return reinterpret_cast<Type&> (buffer);
|
||||
}
|
||||
return Type();
|
||||
}
|
||||
};
|
||||
|
||||
class Ply_read_char : public Ply_read_number
|
||||
{
|
||||
public:
|
||||
Ply_read_char (std::string name, std::size_t format) : Ply_read_number (name, format) { }
|
||||
double operator() (std::istream& stream) const
|
||||
{ return static_cast<double> (this->read<char> (stream)); }
|
||||
};
|
||||
class Ply_read_uchar : public Ply_read_number
|
||||
{
|
||||
public:
|
||||
Ply_read_uchar (std::string name, std::size_t format) : Ply_read_number (name, format) { }
|
||||
double operator() (std::istream& stream) const
|
||||
{ return static_cast<double> (this->read<unsigned char> (stream)); }
|
||||
};
|
||||
class Ply_read_short : public Ply_read_number
|
||||
{
|
||||
public:
|
||||
Ply_read_short (std::string name, std::size_t format) : Ply_read_number (name, format) { }
|
||||
double operator() (std::istream& stream) const
|
||||
{ return static_cast<double> (this->read<short> (stream)); }
|
||||
};
|
||||
class Ply_read_ushort : public Ply_read_number
|
||||
{
|
||||
public:
|
||||
Ply_read_ushort (std::string name, std::size_t format) : Ply_read_number (name, format) { }
|
||||
double operator() (std::istream& stream) const
|
||||
{ return static_cast<double> (this->read<unsigned short> (stream)); }
|
||||
};
|
||||
class Ply_read_int : public Ply_read_number
|
||||
{
|
||||
public:
|
||||
Ply_read_int (std::string name, std::size_t format) : Ply_read_number (name, format) { }
|
||||
double operator() (std::istream& stream) const
|
||||
{ return static_cast<double> (this->read<int> (stream)); }
|
||||
};
|
||||
class Ply_read_uint : public Ply_read_number
|
||||
{
|
||||
public:
|
||||
Ply_read_uint (std::string name, std::size_t format) : Ply_read_number (name, format) { }
|
||||
double operator() (std::istream& stream) const
|
||||
{ return static_cast<double> (this->read<unsigned int> (stream)); }
|
||||
};
|
||||
class Ply_read_float : public Ply_read_number
|
||||
{
|
||||
public:
|
||||
Ply_read_float (std::string name, std::size_t format) : Ply_read_number (name, format) { }
|
||||
double operator() (std::istream& stream) const
|
||||
{ return static_cast<double> (this->read<float> (stream)); }
|
||||
};
|
||||
class Ply_read_double : public Ply_read_number
|
||||
{
|
||||
public:
|
||||
Ply_read_double (std::string name, std::size_t format) : Ply_read_number (name, format) { }
|
||||
double operator() (std::istream& stream) const
|
||||
{ return this->read<float> (stream); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
//===================================================================================
|
||||
/// \ingroup PkgPointSetProcessing
|
||||
/// Reads points (positions + normals, if available) from a .ply stream.
|
||||
/// 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.
|
||||
/// @tparam PointPMap is a model of `WritablePropertyMap` with value type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `OutputIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam NormalPMap is a model of `WritablePropertyMap` with value type `Vector_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
///
|
||||
/// @return true on success.
|
||||
|
||||
// This variant requires all parameters.
|
||||
//-----------------------------------------------------------------------------------
|
||||
template < typename OutputIteratorValueType,
|
||||
typename OutputIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename Kernel >
|
||||
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
PointPMap point_pmap, ///< property map: value_type of OutputIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of OutputIterator -> Vector_3.
|
||||
const Kernel& /*kernel*/) ///< geometric traits.
|
||||
{
|
||||
// value_type_traits is a workaround as back_insert_iterator's value_type is void
|
||||
// typedef typename value_type_traits<OutputIterator>::type Enriched_point;
|
||||
typedef OutputIteratorValueType Enriched_point;
|
||||
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
typedef typename Kernel::Vector_3 Vector;
|
||||
typedef typename Kernel::FT FT;
|
||||
|
||||
if(!stream)
|
||||
{
|
||||
std::cerr << "Error: cannot open file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// scan points
|
||||
std::size_t pointsCount = 0, // number of items in file
|
||||
pointsRead = 0, // current number of points read
|
||||
lineNumber = 0; // current line number
|
||||
enum Format { ASCII = 0, BINARY_LITTLE_ENDIAN = 1, BINARY_BIG_ENDIAN = 2};
|
||||
Format format;
|
||||
|
||||
std::string line;
|
||||
std::istringstream iss;
|
||||
|
||||
// Check the order of the properties of the point set
|
||||
bool reading_properties = false;
|
||||
std::vector<internal::Ply_read_number*> readers;
|
||||
|
||||
while (getline (stream,line))
|
||||
{
|
||||
iss.clear();
|
||||
iss.str (line);
|
||||
++ lineNumber;
|
||||
|
||||
// Reads file signature on first line
|
||||
if (lineNumber == 1)
|
||||
{
|
||||
std::string signature;
|
||||
if (!(iss >> signature) || (signature != "ply"))
|
||||
{
|
||||
// if wrong file format
|
||||
std::cerr << "Incorrect file format line " << lineNumber << " of file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Reads format on 2nd line
|
||||
else if (lineNumber == 2)
|
||||
{
|
||||
std::string tag, format_string, version;
|
||||
if ( !(iss >> tag >> format_string >> version) )
|
||||
{
|
||||
std::cerr << "Error line " << lineNumber << " of file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (format_string == "ascii") format = ASCII;
|
||||
else if (format_string == "binary_little_endian") format = BINARY_LITTLE_ENDIAN;
|
||||
else if (format_string == "binary_big_endian") format = BINARY_BIG_ENDIAN;
|
||||
else
|
||||
{
|
||||
std::cerr << "Unknown file format \"" << format_string << "\" line " << lineNumber << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Comments and vertex properties
|
||||
else
|
||||
{
|
||||
std::string keyword;
|
||||
if (!(iss >> keyword))
|
||||
{
|
||||
std::cerr << "Error line " << lineNumber << " of file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (keyword == "property")
|
||||
{
|
||||
if (!reading_properties)
|
||||
continue;
|
||||
|
||||
std::string type, name;
|
||||
if (!(iss >> type >> name))
|
||||
{
|
||||
std::cerr << "Error line " << lineNumber << " of file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == "char")
|
||||
readers.push_back (new internal::Ply_read_char (name, format));
|
||||
else if (type == "uchar")
|
||||
readers.push_back (new internal::Ply_read_uchar (name, format));
|
||||
else if (type == "short")
|
||||
readers.push_back (new internal::Ply_read_short (name, format));
|
||||
else if (type == "ushort")
|
||||
readers.push_back (new internal::Ply_read_ushort (name, format));
|
||||
else if (type == "int")
|
||||
readers.push_back (new internal::Ply_read_int (name, format));
|
||||
else if (type == "uint")
|
||||
readers.push_back (new internal::Ply_read_uint (name, format));
|
||||
else if (type == "float")
|
||||
readers.push_back (new internal::Ply_read_float (name, format));
|
||||
else if (type == "double")
|
||||
readers.push_back (new internal::Ply_read_double (name, format));
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
reading_properties = false;
|
||||
|
||||
// ignore comments and properties (if not in element
|
||||
// vertex - cf below - properties are useless in our case)
|
||||
if (keyword == "comment" || keyword == "property")
|
||||
continue;
|
||||
|
||||
// When end_header is reached, stop loop and begin reading points
|
||||
if (keyword == "end_header")
|
||||
break;
|
||||
|
||||
if (keyword == "element")
|
||||
{
|
||||
std::string type;
|
||||
std::size_t number;
|
||||
if (!(iss >> type >> number))
|
||||
{
|
||||
std::cerr << "Error line " << lineNumber << " of file" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == "vertex")
|
||||
{
|
||||
pointsCount = number;
|
||||
reading_properties = true;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
while (!(stream.eof()) && pointsRead < pointsCount)
|
||||
{
|
||||
|
||||
FT x, y, z, nx, ny, nz;
|
||||
for (std::size_t i = 0; i < readers.size (); ++ i)
|
||||
{
|
||||
FT value = (*readers[i])(stream);
|
||||
if (readers[i]->name () == "x") x = value;
|
||||
else if (readers[i]->name () == "y") y = value;
|
||||
else if (readers[i]->name () == "z") z = value;
|
||||
else if (readers[i]->name () == "nx") nx = value;
|
||||
else if (readers[i]->name () == "ny") ny = value;
|
||||
else if (readers[i]->name () == "nz") nz = value;
|
||||
}
|
||||
Point point(x,y,z);
|
||||
Vector normal(nx,ny,nz);
|
||||
|
||||
Enriched_point pwn;
|
||||
|
||||
#ifdef CGAL_USE_PROPERTY_MAPS_API_V1
|
||||
put(point_pmap, &pwn, point); // point_pmap[&pwn] = point
|
||||
put(normal_pmap, &pwn, normal); // normal_pmap[&pwn] = normal
|
||||
#else
|
||||
put(point_pmap, pwn, point); // point_pmap[&pwn] = point
|
||||
put(normal_pmap, pwn, normal); // normal_pmap[&pwn] = normal
|
||||
#endif
|
||||
*output++ = pwn;
|
||||
pointsRead++;
|
||||
}
|
||||
// Skip remaining lines
|
||||
|
||||
for (std::size_t i = 0; i < readers.size (); ++ i)
|
||||
delete readers[i];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
template < typename OutputIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap,
|
||||
typename Kernel >
|
||||
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
PointPMap point_pmap, ///< property map: value_type of OutputIterator -> Point_3.
|
||||
NormalPMap normal_pmap, ///< property map: value_type of OutputIterator -> Vector_3.
|
||||
const Kernel& kernel) ///< geometric traits.
|
||||
{
|
||||
// just deduce value_type of OutputIterator
|
||||
return read_ply_points_and_normals
|
||||
<typename value_type_traits<OutputIterator>::type>(stream,
|
||||
output,
|
||||
point_pmap,
|
||||
normal_pmap,
|
||||
kernel);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
//-----------------------------------------------------------------------------------
|
||||
template < typename OutputIteratorValueType,
|
||||
typename OutputIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap >
|
||||
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
PointPMap point_pmap, ///< property map: value_type of OutputIterator -> Point_3.
|
||||
NormalPMap normal_pmap) ///< property map: value_type of OutputIterator -> Vector_3.
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return read_ply_points_and_normals
|
||||
<OutputIteratorValueType>(stream,
|
||||
output,
|
||||
point_pmap,
|
||||
normal_pmap,
|
||||
Kernel());
|
||||
}
|
||||
|
||||
template < typename OutputIterator,
|
||||
typename PointPMap,
|
||||
typename NormalPMap >
|
||||
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
PointPMap point_pmap, ///< property map: value_type of OutputIterator -> Point_3.
|
||||
NormalPMap normal_pmap) ///< property map: value_type of OutputIterator -> Vector_3.
|
||||
{
|
||||
// just deduce value_type of OutputIterator
|
||||
return read_ply_points_and_normals
|
||||
<typename value_type_traits<OutputIterator>::type>(stream,
|
||||
output,
|
||||
point_pmap,
|
||||
normal_pmap);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant creates a default point property map = Identity_property_map.
|
||||
//-----------------------------------------------------------------------------------
|
||||
template < typename OutputIteratorValueType,
|
||||
typename OutputIterator,
|
||||
typename NormalPMap >
|
||||
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
NormalPMap normal_pmap) ///< property map: value_type of OutputIterator -> Vector_3.
|
||||
{
|
||||
return read_ply_points_and_normals
|
||||
<OutputIteratorValueType>(stream,
|
||||
output,
|
||||
#ifdef CGAL_USE_PROPERTY_MAPS_API_V1
|
||||
make_dereference_property_map(output),
|
||||
#else
|
||||
make_identity_property_map(OutputIteratorValueType()),
|
||||
#endif
|
||||
normal_pmap);
|
||||
}
|
||||
|
||||
template < typename OutputIterator,
|
||||
typename NormalPMap >
|
||||
bool read_ply_points_and_normals(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
NormalPMap normal_pmap) ///< property map: value_type of OutputIterator -> Vector_3.
|
||||
{
|
||||
// just deduce value_type of OutputIterator
|
||||
return read_ply_points_and_normals
|
||||
<typename value_type_traits<OutputIterator>::type>(stream,
|
||||
output,
|
||||
normal_pmap);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
/// @endcond
|
||||
|
||||
|
||||
//===================================================================================
|
||||
/// \ingroup PkgPointSetProcessing
|
||||
/// Reads points (position only) from a .ply stream.
|
||||
/// If the position is followed by the nx ny nz normal, then the normal will be ignored.
|
||||
/// 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.
|
||||
/// @tparam PointPMap is a model of `WritablePropertyMap` with value_type `Point_3<Kernel>`.
|
||||
/// It can be omitted if the value type of `OutputIterator` is convertible to `Point_3<Kernel>`.
|
||||
/// @tparam Kernel Geometric traits class.
|
||||
/// It can be omitted and deduced automatically from the value type of `PointPMap`.
|
||||
///
|
||||
/// @return `true` on success.
|
||||
|
||||
// This variant requires all parameters.
|
||||
//-----------------------------------------------------------------------------------
|
||||
template < typename OutputIteratorValueType,
|
||||
typename OutputIterator,
|
||||
typename PointPMap,
|
||||
typename Kernel >
|
||||
bool read_ply_points(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
PointPMap point_pmap, ///< property map: value_type of OutputIterator -> Point_3.
|
||||
const Kernel& kernel) ///< geometric traits.
|
||||
{
|
||||
// Calls read_ply_points_and_normals() with a normal property map = boost::dummy_property_map
|
||||
return read_ply_points_and_normals
|
||||
<OutputIteratorValueType>(stream,
|
||||
output,
|
||||
point_pmap,
|
||||
boost::dummy_property_map(),
|
||||
kernel);
|
||||
}
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
template < typename OutputIterator,
|
||||
typename PointPMap,
|
||||
typename Kernel >
|
||||
bool read_ply_points(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
PointPMap point_pmap, ///< property map: value_type of OutputIterator -> Point_3.
|
||||
const Kernel& kernel) ///< geometric traits.
|
||||
{
|
||||
// just deduce value_type of OutputIterator
|
||||
return read_ply_points
|
||||
<typename value_type_traits<OutputIterator>::type>(stream,
|
||||
output,
|
||||
point_pmap,
|
||||
kernel);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant deduces the kernel from the point property map.
|
||||
//-----------------------------------------------------------------------------------
|
||||
template < typename OutputIteratorValueType,
|
||||
typename OutputIterator,
|
||||
typename PointPMap >
|
||||
bool read_ply_points(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
PointPMap point_pmap) ///< property map: value_type of OutputIterator -> Point_3.
|
||||
{
|
||||
typedef typename boost::property_traits<PointPMap>::value_type Point;
|
||||
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||
return read_ply_points
|
||||
<OutputIteratorValueType>(stream,
|
||||
output,
|
||||
point_pmap,
|
||||
Kernel());
|
||||
}
|
||||
|
||||
template < typename OutputIterator,
|
||||
typename PointPMap >
|
||||
bool read_ply_points(std::istream& stream, ///< input stream.
|
||||
OutputIterator output, ///< output iterator over points.
|
||||
PointPMap point_pmap) ///< property map: value_type of OutputIterator -> Point_3.
|
||||
{
|
||||
// just deduce value_type of OutputIterator
|
||||
return read_ply_points
|
||||
<typename value_type_traits<OutputIterator>::type>(stream,
|
||||
output,
|
||||
point_pmap);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
/// @endcond
|
||||
|
||||
/// @cond SKIP_IN_MANUAL
|
||||
// This variant creates a default point property map = Identity_property_map.
|
||||
//-----------------------------------------------------------------------------------
|
||||
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,
|
||||
#ifdef CGAL_USE_PROPERTY_MAPS_API_V1
|
||||
make_dereference_property_map(output)
|
||||
#else
|
||||
make_identity_property_map(OutputIteratorValueType())
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
template < typename OutputIterator>
|
||||
bool read_ply_points(std::istream& stream, ///< input stream.
|
||||
OutputIterator output) ///< output iterator over points.
|
||||
{
|
||||
// just deduce value_type of OutputIterator
|
||||
return read_ply_points
|
||||
<typename value_type_traits<OutputIterator>::type>(stream,
|
||||
output);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
/// @endcond
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_READ_PLY_POINTS_H
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
OFF
|
||||
NOFF
|
||||
3 0 0
|
||||
1 1 1 2 2 2
|
||||
3 3 3 4 4 4
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,16 @@
|
|||
ply
|
||||
format ascii 1.0
|
||||
comment VCGLIB generated
|
||||
element vertex 3
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
property float nx
|
||||
property float ny
|
||||
property float nz
|
||||
element face 0
|
||||
property list uchar int vertex_indices
|
||||
end_header
|
||||
1 1 1 2 2 2
|
||||
3 3 3 4 4 4
|
||||
5 5 5 6 6 6
|
||||
Binary file not shown.
|
|
@ -2,6 +2,7 @@
|
|||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/IO/read_off_points.h>
|
||||
#include <CGAL/IO/read_ply_points.h>
|
||||
#include <CGAL/IO/read_xyz_points.h>
|
||||
|
||||
#include <vector>
|
||||
|
|
@ -47,6 +48,17 @@ bool read_off(std::string s,
|
|||
CGAL::Second_of_pair_property_map<PointVectorPair>());
|
||||
}
|
||||
|
||||
bool read_ply (std::string s,
|
||||
std::vector<PointVectorPair>& pv_pairs)
|
||||
{
|
||||
std::ifstream fs(s.c_str());
|
||||
|
||||
return CGAL::read_ply_points_and_normals (fs,
|
||||
back_inserter(pv_pairs),
|
||||
CGAL::First_of_pair_property_map<PointVectorPair>(),
|
||||
CGAL::Second_of_pair_property_map<PointVectorPair>());
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
@ -78,6 +90,12 @@ int main()
|
|||
assert(pv_pairs[2] == std::make_pair(Point_3(4,5,6), Vector_3(0,0,0)));
|
||||
assert(pv_pairs[3] == std::make_pair(Point_3(7,8,9), Vector_3(0,0,0)));
|
||||
|
||||
pv_pairs.clear ();
|
||||
assert(read_ply("data/read_test/simple.ply", pv_pairs));
|
||||
pv_pairs.clear ();
|
||||
assert(read_ply("data/read_test/simple_ascii.ply", pv_pairs));
|
||||
pv_pairs.clear ();
|
||||
assert(read_ply("data/read_test/simple_with_flag.ply", pv_pairs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -319,6 +319,9 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
|
|||
polyhedron_demo_plugin(off_to_xyz_plugin Polyhedron_demo_off_to_xyz_plugin)
|
||||
target_link_libraries(off_to_xyz_plugin scene_points_with_normal_item)
|
||||
|
||||
polyhedron_demo_plugin(ply_to_xyz_plugin Polyhedron_demo_ply_to_xyz_plugin)
|
||||
target_link_libraries(ply_to_xyz_plugin scene_points_with_normal_item)
|
||||
|
||||
polyhedron_demo_plugin(convex_hull_plugin Polyhedron_demo_convex_hull_plugin)
|
||||
target_link_libraries(convex_hull_plugin scene_polyhedron_item scene_points_with_normal_item scene_polylines_item scene_polyhedron_selection_item)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
#include "Scene_points_with_normal_item.h"
|
||||
#include "Polyhedron_demo_io_plugin_interface.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
class Polyhedron_demo_ply_to_xyz_plugin :
|
||||
public QObject,
|
||||
public Polyhedron_demo_io_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(Polyhedron_demo_io_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.0")
|
||||
|
||||
public:
|
||||
QString name() const { return "ply_to_xyz_plugin"; }
|
||||
QString nameFilters() const { return "PLY files as Point set (*.ply)"; }
|
||||
bool canLoad() const;
|
||||
Scene_item* load(QFileInfo fileinfo);
|
||||
|
||||
bool canSave(const Scene_item*);
|
||||
bool save(const Scene_item*, QFileInfo fileinfo);
|
||||
};
|
||||
|
||||
bool Polyhedron_demo_ply_to_xyz_plugin::canLoad() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
Scene_item*
|
||||
Polyhedron_demo_ply_to_xyz_plugin::load(QFileInfo fileinfo) {
|
||||
std::ifstream in(fileinfo.filePath().toUtf8());
|
||||
|
||||
if(!in)
|
||||
std::cerr << "Error!\n";
|
||||
|
||||
Scene_points_with_normal_item* item;
|
||||
item = new Scene_points_with_normal_item();
|
||||
if(!item->read_ply_point_set(in))
|
||||
{
|
||||
delete item;
|
||||
return 0;
|
||||
}
|
||||
|
||||
item->setName(fileinfo.baseName());
|
||||
return item;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_ply_to_xyz_plugin::canSave(const Scene_item*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Polyhedron_demo_ply_to_xyz_plugin::save(const Scene_item*, QFileInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#include "Polyhedron_demo_ply_to_xyz_plugin.moc"
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
#include "Polyhedron_type.h"
|
||||
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
|
||||
|
||||
#include <CGAL/IO/read_ply_points.h>
|
||||
#include <CGAL/IO/read_off_points.h>
|
||||
#include <CGAL/IO/write_off_points.h>
|
||||
#include <CGAL/IO/read_xyz_points.h>
|
||||
|
|
@ -317,6 +318,21 @@ void Scene_points_with_normal_item::selectDuplicates()
|
|||
Q_EMIT itemChanged();
|
||||
}
|
||||
|
||||
// Loads point set from .PLY file
|
||||
bool Scene_points_with_normal_item::read_ply_point_set(std::istream& stream)
|
||||
{
|
||||
Q_ASSERT(m_points != NULL);
|
||||
|
||||
m_points->clear();
|
||||
bool ok = stream &&
|
||||
CGAL::read_ply_points_and_normals(stream,
|
||||
std::back_inserter(*m_points),
|
||||
CGAL::make_normal_of_point_with_normal_pmap(Point_set::value_type())) &&
|
||||
!isEmpty();
|
||||
invalidate_buffers();
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Loads point set from .OFF file
|
||||
bool Scene_points_with_normal_item::read_off_point_set(std::istream& stream)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public:
|
|||
QMenu* contextMenu();
|
||||
|
||||
// IO
|
||||
bool read_ply_point_set(std::istream& in);
|
||||
bool read_off_point_set(std::istream& in);
|
||||
bool write_off_point_set(std::ostream& out) const;
|
||||
bool read_xyz_point_set(std::istream& in);
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ else
|
|||
orient_soup_plugin \
|
||||
parameterization_plugin \
|
||||
pca_plugin \
|
||||
ply_to_xyz_plugin \
|
||||
point_dialog \
|
||||
point_inside_polyhedron_plugin \
|
||||
point_set_average_spacing_plugin \
|
||||
|
|
|
|||
Loading…
Reference in New Issue