mirror of https://github.com/CGAL/cgal
Merge remote-tracking branch 'mine/Surface_mesh-PLY_IO-GF' into Surface_mesh-PLY_IO-GF
This commit is contained in:
commit
717137e48f
|
|
@ -479,7 +479,7 @@ void xAlci_main_window::setup(int w, int h)
|
||||||
tab_widget->addTab(cad_tab,"cad");
|
tab_widget->addTab(cad_tab,"cad");
|
||||||
tab_widget->addTab(arr_tab,"arrangement");
|
tab_widget->addTab(arr_tab,"arrangement");
|
||||||
|
|
||||||
*widget << CGAL::LineWidth(2) << CGAL::BackgroundColor(CGAL::WHITE);
|
*widget << CGAL::LineWidth(2) << CGAL::BackgroundColor(CGAL::white());
|
||||||
resize(w,h);
|
resize(w,h);
|
||||||
double ratio = 1.0;//(double)h/w;
|
double ratio = 1.0;//(double)h/w;
|
||||||
widget->set_window(-1, 1, -ratio, ratio, true);
|
widget->set_window(-1, 1, -ratio, ratio, true);
|
||||||
|
|
|
||||||
|
|
@ -277,11 +277,11 @@ inline std::ostream & operator<<(std::ostream & os, const Arr::Vertex & vertex)
|
||||||
inline Window_stream & operator<<(Window_stream & ws, Arr & arr)
|
inline Window_stream & operator<<(Window_stream & ws, Arr & arr)
|
||||||
{
|
{
|
||||||
Arr::Edge_iterator ei;
|
Arr::Edge_iterator ei;
|
||||||
ws << CGAL::BLUE;
|
ws << CGAL::blue();
|
||||||
for (ei = arr.edges_begin(); ei != arr.edges_end(); ++ei)
|
for (ei = arr.edges_begin(); ei != arr.edges_end(); ++ei)
|
||||||
ws << (*ei).curve();
|
ws << (*ei).curve();
|
||||||
Arr::Vertex_iterator vi;
|
Arr::Vertex_iterator vi;
|
||||||
ws << CGAL::RED;
|
ws << CGAL::red();
|
||||||
for (vi = arr.vertices_begin(); vi != arr.vertices_end(); ++vi)
|
for (vi = arr.vertices_begin(); vi != arr.vertices_end(); ++vi)
|
||||||
ws << (*vi).point();
|
ws << (*vi).point();
|
||||||
return ws;
|
return ws;
|
||||||
|
|
@ -474,7 +474,7 @@ public:
|
||||||
m_window->flush();
|
m_window->flush();
|
||||||
#else
|
#else
|
||||||
m_window->lock();
|
m_window->lock();
|
||||||
*m_window << CGAL::BackgroundColor(CGAL::WHITE) << CGAL::RED;
|
*m_window << CGAL::BackgroundColor(CGAL::white()) << CGAL::red();
|
||||||
(*m_window) << arr;
|
(*m_window) << arr;
|
||||||
m_window->unlock();
|
m_window->unlock();
|
||||||
App->flush();
|
App->flush();
|
||||||
|
|
@ -490,9 +490,9 @@ public:
|
||||||
ps_stream.set_line_width(1);
|
ps_stream.set_line_width(1);
|
||||||
CGAL::Arr_drawer<Arr, CGAL::Postscript_file_stream> drawer(ps_stream);
|
CGAL::Arr_drawer<Arr, CGAL::Postscript_file_stream> drawer(ps_stream);
|
||||||
// drawer.draw_faces(arr.faces_begin(), arr.faces_end());
|
// drawer.draw_faces(arr.faces_begin(), arr.faces_end());
|
||||||
ps_stream << CGAL::BLUE;
|
ps_stream << CGAL::blue();
|
||||||
drawer.draw_halfedges(arr.halfedges_begin(), arr.halfedges_end());
|
drawer.draw_halfedges(arr.halfedges_begin(), arr.halfedges_end());
|
||||||
ps_stream << CGAL::RED;
|
ps_stream << CGAL::red();
|
||||||
drawer.draw_vertices(arr.vertices_begin(), arr.vertices_end());
|
drawer.draw_vertices(arr.vertices_begin(), arr.vertices_end());
|
||||||
|
|
||||||
// draw_arr(arr, drawer, ps_stream);
|
// draw_arr(arr, drawer, ps_stream);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <CGAL/Classification/Cluster.h>
|
#include <CGAL/Classification/Cluster.h>
|
||||||
#include <CGAL/Classification/Color.h>
|
|
||||||
#include <CGAL/Classification/Evaluation.h>
|
#include <CGAL/Classification/Evaluation.h>
|
||||||
#include <CGAL/Classification/Feature_base.h>
|
#include <CGAL/Classification/Feature_base.h>
|
||||||
#include <CGAL/Classification/Feature_set.h>
|
#include <CGAL/Classification/Feature_set.h>
|
||||||
|
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
// Copyright (c) 2017 GeometryFactory Sarl (France).
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org).
|
|
||||||
// You can redistribute it and/or modify it under the terms of the GNU
|
|
||||||
// General Public License as published by the Free Software Foundation,
|
|
||||||
// either version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
// SPDX-License-Identifier: GPL-3.0+
|
|
||||||
//
|
|
||||||
// Author(s) : Simon Giraudot
|
|
||||||
|
|
||||||
#ifndef CGAL_CLASSIFICATION_COLOR_H
|
|
||||||
#define CGAL_CLASSIFICATION_COLOR_H
|
|
||||||
|
|
||||||
#include <CGAL/license/Classification.h>
|
|
||||||
#include <CGAL/number_utils.h>
|
|
||||||
#include <CGAL/int.h>
|
|
||||||
#include <CGAL/array.h>
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
namespace Classification {
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationColor
|
|
||||||
|
|
||||||
%Color described in red/green/blue space. Each component is stored
|
|
||||||
as an unsigned char ranging from 0 (no color) to 255 (full color).
|
|
||||||
*/
|
|
||||||
typedef std::array<unsigned char, 3> RGB_Color;
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationColor
|
|
||||||
|
|
||||||
%Color described in hue/saturation/value space. Each component is stored
|
|
||||||
as a float:
|
|
||||||
|
|
||||||
- `hue` ranges from 0° to 360° (corresponding to the color tint)
|
|
||||||
- `saturation` ranges from 0.0 (gray) to 100.0 (full saturation)
|
|
||||||
- `value` ranges from 0.0 (black) to 100.0 (white)
|
|
||||||
*/
|
|
||||||
typedef std::array<float, 3> HSV_Color;
|
|
||||||
|
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
|
||||||
inline HSV_Color rgb_to_hsv (const RGB_Color& c)
|
|
||||||
{
|
|
||||||
double r = (double)(c[0]) / 255.;
|
|
||||||
double g = (double)(c[1]) / 255.;
|
|
||||||
double b = (double)(c[2]) / 255.;
|
|
||||||
double Cmax = (std::max) (r, (std::max) (g, b));
|
|
||||||
double Cmin = (std::min) (r, (std::min) (g, b));
|
|
||||||
double delta = Cmax - Cmin;
|
|
||||||
double H = 0.;
|
|
||||||
|
|
||||||
if (delta != 0.)
|
|
||||||
{
|
|
||||||
if (Cmax == r)
|
|
||||||
H = 60. * ((g - b) / delta);
|
|
||||||
else if (Cmax == g)
|
|
||||||
H = 60. * (((b - r) / delta) + 2.);
|
|
||||||
else
|
|
||||||
H = 60. * (((r - g) / delta) + 4.);
|
|
||||||
}
|
|
||||||
if (H < 0.) H += 360.;
|
|
||||||
double S = (Cmax == 0. ? 0. : 100. * (delta / Cmax));
|
|
||||||
double V = 100. * Cmax;
|
|
||||||
HSV_Color out = {{ float(H), float(S), float(V) }};
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline RGB_Color hsv_to_rgb (const HSV_Color& c)
|
|
||||||
{
|
|
||||||
double h = c[0];
|
|
||||||
double s = c[1];
|
|
||||||
double v = c[2];
|
|
||||||
|
|
||||||
s /= 100.;
|
|
||||||
v /= 100.;
|
|
||||||
double C = v*s;
|
|
||||||
int hh = (int)(h/60.);
|
|
||||||
double X = C * (1-CGAL::abs (hh % 2 - 1));
|
|
||||||
double r = 0, g = 0, b = 0;
|
|
||||||
|
|
||||||
if( hh>=0 && hh<1 )
|
|
||||||
{
|
|
||||||
r = C;
|
|
||||||
g = X;
|
|
||||||
}
|
|
||||||
else if( hh>=1 && hh<2 )
|
|
||||||
{
|
|
||||||
r = X;
|
|
||||||
g = C;
|
|
||||||
}
|
|
||||||
else if( hh>=2 && hh<3 )
|
|
||||||
{
|
|
||||||
g = C;
|
|
||||||
b = X;
|
|
||||||
}
|
|
||||||
else if( hh>=3 && hh<4 )
|
|
||||||
{
|
|
||||||
g = X;
|
|
||||||
b = C;
|
|
||||||
}
|
|
||||||
else if( hh>=4 && hh<5 )
|
|
||||||
{
|
|
||||||
r = X;
|
|
||||||
b = C;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r = C;
|
|
||||||
b = X;
|
|
||||||
}
|
|
||||||
double m = v-C;
|
|
||||||
r += m;
|
|
||||||
g += m;
|
|
||||||
b += m;
|
|
||||||
r *= 255.0;
|
|
||||||
g *= 255.0;
|
|
||||||
b *= 255.0;
|
|
||||||
|
|
||||||
RGB_Color out = {{ (unsigned char)r, (unsigned char)g, (unsigned char)b }};
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
} // namespace Classification
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CGAL_CLASSIFICATION_COLOR_H
|
|
||||||
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <CGAL/Classification/Color.h>
|
|
||||||
#include <CGAL/Classification/Feature_base.h>
|
#include <CGAL/Classification/Feature_base.h>
|
||||||
|
#include <CGAL/array.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -65,7 +65,7 @@ namespace Feature {
|
||||||
`ColorMap`.
|
`ColorMap`.
|
||||||
\tparam ColorMap model of `ReadablePropertyMap` whose key
|
\tparam ColorMap model of `ReadablePropertyMap` whose key
|
||||||
type is the value type of the iterator of `PointRange` and value type
|
type is the value type of the iterator of `PointRange` and value type
|
||||||
is `CGAL::Classification::RGB_Color`.
|
is `CGAL::Color`.
|
||||||
*/
|
*/
|
||||||
template <typename GeomTraits, typename PointRange, typename ColorMap>
|
template <typename GeomTraits, typename PointRange, typename ColorMap>
|
||||||
class Color_channel : public Feature_base
|
class Color_channel : public Feature_base
|
||||||
|
|
@ -82,9 +82,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef typename Classification::RGB_Color RGB_Color;
|
|
||||||
typedef typename Classification::HSV_Color HSV_Color;
|
|
||||||
|
|
||||||
const PointRange& input;
|
const PointRange& input;
|
||||||
ColorMap color_map;
|
ColorMap color_map;
|
||||||
Channel m_channel;
|
Channel m_channel;
|
||||||
|
|
@ -111,8 +108,8 @@ public:
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
virtual float value (std::size_t pt_index)
|
virtual float value (std::size_t pt_index)
|
||||||
{
|
{
|
||||||
HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+pt_index)));
|
cpp11::array<double, 3> c = get(color_map, *(input.begin()+pt_index)).to_hsv();
|
||||||
return c[std::size_t(m_channel)];
|
return float(c[std::size_t(m_channel)]);
|
||||||
}
|
}
|
||||||
/// \endcond
|
/// \endcond
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,431 +0,0 @@
|
||||||
// Copyright (c) 2017 GeometryFactory Sarl (France).
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org).
|
|
||||||
// You can redistribute it and/or modify it under the terms of the GNU
|
|
||||||
// General Public License as published by the Free Software Foundation,
|
|
||||||
// either version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
// SPDX-License-Identifier: GPL-3.0+
|
|
||||||
//
|
|
||||||
// Author(s) : Simon Giraudot
|
|
||||||
|
|
||||||
#ifndef CGAL_CLASSIFICATION_FEATURES_EIGEN_H
|
|
||||||
#define CGAL_CLASSIFICATION_FEATURES_EIGEN_H
|
|
||||||
|
|
||||||
#include <CGAL/license/Classification.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <CGAL/Classification/Feature_base.h>
|
|
||||||
#include <CGAL/Classification/Local_eigen_analysis.h>
|
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
|
||||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
namespace Classification {
|
|
||||||
|
|
||||||
namespace Feature {
|
|
||||||
|
|
||||||
class Eigen_feature : public Feature_base
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
|
||||||
std::vector<float> attrib;
|
|
||||||
#else
|
|
||||||
const Classification::Local_eigen_analysis& eigen;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
template <typename InputRange>
|
|
||||||
Eigen_feature (const InputRange&,
|
|
||||||
const Classification::Local_eigen_analysis& eigen)
|
|
||||||
#ifndef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
|
||||||
: eigen (eigen)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
|
||||||
virtual void init (std::size_t size, const Classification::Local_eigen_analysis& eigen)
|
|
||||||
{
|
|
||||||
attrib.reserve (size);
|
|
||||||
for (std::size_t i = 0; i < size; ++ i)
|
|
||||||
attrib.push_back (get_value (eigen, i));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
virtual void init (std::size_t, const Classification::Local_eigen_analysis&)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual float get_value (const Classification::Local_eigen_analysis& eigen, std::size_t i) = 0;
|
|
||||||
virtual float value (std::size_t pt_index)
|
|
||||||
{
|
|
||||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
|
||||||
return attrib[pt_index];
|
|
||||||
#else
|
|
||||||
return get_value(eigen, pt_index);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationFeatures
|
|
||||||
|
|
||||||
%Feature based on the eigenvalues of the covariance matrix of a
|
|
||||||
local neighborhood. Linearity is defined, for the 3 eigenvalues
|
|
||||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
|
||||||
|
|
||||||
\f[
|
|
||||||
\frac{\lambda_1 - \lambda_2}{\lambda_1}
|
|
||||||
\f]
|
|
||||||
|
|
||||||
Its default name is "linearity".
|
|
||||||
*/
|
|
||||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Linearity, please update your code with Eigenvalue instead")
|
|
||||||
class Linearity
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
: public Feature_base
|
|
||||||
#else
|
|
||||||
: public Eigen_feature
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
Constructs the feature.
|
|
||||||
|
|
||||||
\tparam Input model of `ConstRange`. Its iterator type
|
|
||||||
is `RandomAccessIterator`.
|
|
||||||
\param input point range.
|
|
||||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
|
||||||
*/
|
|
||||||
template <typename InputRange>
|
|
||||||
Linearity (const InputRange& input,
|
|
||||||
const Local_eigen_analysis& eigen) : Eigen_feature (input, eigen)
|
|
||||||
{
|
|
||||||
this->set_name("linearity");
|
|
||||||
this->init(input.size(), eigen);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
|
||||||
{
|
|
||||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
|
||||||
if (ev[2] < 1e-15)
|
|
||||||
return 0.;
|
|
||||||
else
|
|
||||||
return ((ev[2] - ev[1]) / ev[2]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationFeatures
|
|
||||||
|
|
||||||
%Feature based on the eigenvalues of the covariance matrix of a
|
|
||||||
local neighborhood. Planarity is defined, for the 3 eigenvalues
|
|
||||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
|
||||||
|
|
||||||
\f[
|
|
||||||
\frac{\lambda_2 - \lambda_3}{\lambda_1}
|
|
||||||
\f]
|
|
||||||
|
|
||||||
Its default name is "planarity".
|
|
||||||
*/
|
|
||||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Planarity, please update your code with Eigenvalue instead")
|
|
||||||
class Planarity
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
: public Feature_base
|
|
||||||
#else
|
|
||||||
: public Eigen_feature
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
Constructs the feature.
|
|
||||||
|
|
||||||
\param input point range.
|
|
||||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
|
||||||
*/
|
|
||||||
template <typename InputRange>
|
|
||||||
Planarity (const InputRange& input,
|
|
||||||
const Local_eigen_analysis& eigen)
|
|
||||||
: Eigen_feature(input, eigen)
|
|
||||||
{
|
|
||||||
this->set_name("planarity");
|
|
||||||
this->init(input.size(), eigen);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
|
||||||
{
|
|
||||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
|
||||||
if (ev[2] < 1e-15)
|
|
||||||
return 0.;
|
|
||||||
else
|
|
||||||
return ((ev[1] - ev[0]) / ev[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationFeatures
|
|
||||||
|
|
||||||
%Feature based on the eigenvalues of the covariance matrix of a
|
|
||||||
local neighborhood. Sphericity is defined, for the 3 eigenvalues
|
|
||||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
|
||||||
|
|
||||||
\f[
|
|
||||||
\frac{\lambda_3}{\lambda_1}
|
|
||||||
\f]
|
|
||||||
|
|
||||||
Its default name is "sphericity".
|
|
||||||
*/
|
|
||||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Sphericity, please update your code with Eigenvalue instead")
|
|
||||||
class Sphericity
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
: public Feature_base
|
|
||||||
#else
|
|
||||||
: public Eigen_feature
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
Constructs the feature.
|
|
||||||
|
|
||||||
\param input point range.
|
|
||||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
|
||||||
*/
|
|
||||||
template <typename InputRange>
|
|
||||||
Sphericity (const InputRange& input,
|
|
||||||
const Local_eigen_analysis& eigen)
|
|
||||||
: Eigen_feature(input, eigen)
|
|
||||||
{
|
|
||||||
this->set_name("sphericity");
|
|
||||||
this->init(input.size(), eigen);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
|
||||||
{
|
|
||||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
|
||||||
if (ev[2] < 1e-15)
|
|
||||||
return 0.;
|
|
||||||
else
|
|
||||||
return (ev[0] / ev[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationFeatures
|
|
||||||
|
|
||||||
%Feature based on the eigenvalues of the covariance matrix of a
|
|
||||||
local neighborhood. Omnivariance is defined, for the 3 eigenvalues
|
|
||||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
|
||||||
|
|
||||||
\f[
|
|
||||||
(\lambda_1 \times \lambda_2 \times \lambda_3)^{\frac{1}{3}}
|
|
||||||
\f]
|
|
||||||
|
|
||||||
Its default name is "omnivariance".
|
|
||||||
*/
|
|
||||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Omnivariance, please update your code with Eigenvalue instead")
|
|
||||||
class Omnivariance
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
: public Feature_base
|
|
||||||
#else
|
|
||||||
: public Eigen_feature
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
Constructs the feature.
|
|
||||||
|
|
||||||
\param input point range.
|
|
||||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
|
||||||
*/
|
|
||||||
template <typename InputRange>
|
|
||||||
Omnivariance (const InputRange& input,
|
|
||||||
const Local_eigen_analysis& eigen)
|
|
||||||
: Eigen_feature(input, eigen)
|
|
||||||
{
|
|
||||||
this->set_name("omnivariance");
|
|
||||||
this->init(input.size(), eigen);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
|
||||||
{
|
|
||||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
|
||||||
return (std::pow (CGAL::abs(ev[0] * ev[1] * ev[2]), 0.333333333f));
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationFeatures
|
|
||||||
|
|
||||||
%Feature based on the eigenvalues of the covariance matrix of a
|
|
||||||
local neighborhood. Anisotropy is defined, for the 3 eigenvalues
|
|
||||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
|
||||||
|
|
||||||
\f[
|
|
||||||
\frac{\lambda_1 - \lambda_3}{\lambda_1}
|
|
||||||
\f]
|
|
||||||
|
|
||||||
Its default name is "anisotropy".
|
|
||||||
*/
|
|
||||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Anisotropy, please update your code with Eigenvalue instead")
|
|
||||||
class Anisotropy
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
: public Feature_base
|
|
||||||
#else
|
|
||||||
: public Eigen_feature
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
Constructs the feature.
|
|
||||||
|
|
||||||
\param input point range.
|
|
||||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
|
||||||
*/
|
|
||||||
template <typename InputRange>
|
|
||||||
Anisotropy (const InputRange& input,
|
|
||||||
const Local_eigen_analysis& eigen)
|
|
||||||
: Eigen_feature(input, eigen)
|
|
||||||
{
|
|
||||||
this->set_name("anisotropy");
|
|
||||||
this->init(input.size(), eigen);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
|
||||||
{
|
|
||||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
|
||||||
if (ev[2] < 1e-15)
|
|
||||||
return 0.;
|
|
||||||
else
|
|
||||||
return ((ev[2] - ev[0]) / ev[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationFeatures
|
|
||||||
|
|
||||||
%Feature based on the eigenvalues of the covariance matrix of a
|
|
||||||
local neighborhood. Eigentropy is defined, for the 3 eigenvalues
|
|
||||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
|
||||||
|
|
||||||
\f[
|
|
||||||
- \sum_{i=1}^3 \lambda_i \times \log{\lambda_i}
|
|
||||||
\f]
|
|
||||||
|
|
||||||
Its default name is "eigentropy".
|
|
||||||
*/
|
|
||||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Eigentropy, please update your code with Eigenvalue instead")
|
|
||||||
class Eigentropy
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
: public Feature_base
|
|
||||||
#else
|
|
||||||
: public Eigen_feature
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
Constructs the feature.
|
|
||||||
|
|
||||||
\param input point range.
|
|
||||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
|
||||||
*/
|
|
||||||
template <typename InputRange>
|
|
||||||
Eigentropy (const InputRange& input,
|
|
||||||
const Local_eigen_analysis& eigen)
|
|
||||||
: Eigen_feature(input, eigen)
|
|
||||||
{
|
|
||||||
this->set_name("eigentropy");
|
|
||||||
this->init(input.size(), eigen);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
|
||||||
{
|
|
||||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
|
||||||
if (ev[0] < 1e-15
|
|
||||||
|| ev[1] < 1e-15
|
|
||||||
|| ev[2] < 1e-15)
|
|
||||||
return 0.;
|
|
||||||
else
|
|
||||||
return (- ev[0] * std::log(ev[0])
|
|
||||||
- ev[1] * std::log(ev[1])
|
|
||||||
- ev[2] * std::log(ev[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationFeatures
|
|
||||||
|
|
||||||
%Feature based on the eigenvalues of the covariance
|
|
||||||
matrix of a local neighborhood. Surface variation is defined, for
|
|
||||||
the 3 eigenvalues \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge
|
|
||||||
0\f$, as:
|
|
||||||
|
|
||||||
\f[
|
|
||||||
\frac{\lambda_3}{\lambda_1 + \lambda_2 + \lambda_3}
|
|
||||||
\f]
|
|
||||||
|
|
||||||
Its default name is "surface_variation".
|
|
||||||
*/
|
|
||||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Surface_variation, please update your code with Eigenvalue instead")
|
|
||||||
class Surface_variation
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
: public Feature_base
|
|
||||||
#else
|
|
||||||
: public Eigen_feature
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
Constructs the feature.
|
|
||||||
|
|
||||||
\param input point range.
|
|
||||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
|
||||||
*/
|
|
||||||
template <typename InputRange>
|
|
||||||
Surface_variation (const InputRange& input,
|
|
||||||
const Local_eigen_analysis& eigen)
|
|
||||||
: Eigen_feature(input, eigen)
|
|
||||||
{
|
|
||||||
this->set_name("surface_variation");
|
|
||||||
this->init(input.size(), eigen);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
|
||||||
{
|
|
||||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
|
||||||
if (ev[0] + ev[1] + ev[2] < 1e-15)
|
|
||||||
return 0.;
|
|
||||||
else
|
|
||||||
return (ev[0] / (ev[0] + ev[1] + ev[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Feature
|
|
||||||
|
|
||||||
} // namespace Classification
|
|
||||||
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
#endif // CGAL_CLASSIFICATION_FEATURES_EIGEN_H
|
|
||||||
|
|
@ -1,175 +0,0 @@
|
||||||
// Copyright (c) 2017 GeometryFactory Sarl (France).
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org).
|
|
||||||
// You can redistribute it and/or modify it under the terms of the GNU
|
|
||||||
// General Public License as published by the Free Software Foundation,
|
|
||||||
// either version 3 of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
// SPDX-License-Identifier: GPL-3.0+
|
|
||||||
//
|
|
||||||
// Author(s) : Simon Giraudot
|
|
||||||
|
|
||||||
#ifndef CGAL_CLASSIFICATION_FEATURE_HSV_H
|
|
||||||
#define CGAL_CLASSIFICATION_FEATURE_HSV_H
|
|
||||||
|
|
||||||
#include <CGAL/license/Classification.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <CGAL/Classification/Color.h>
|
|
||||||
#include <CGAL/Classification/Feature_base.h>
|
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
|
||||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
namespace Classification {
|
|
||||||
|
|
||||||
namespace Feature {
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgClassificationFeatures
|
|
||||||
|
|
||||||
%Feature based on HSV colorimetric information. If the input
|
|
||||||
point cloud has colorimetric information, it can be used for
|
|
||||||
classification purposes. This feature is based on a Gaussian
|
|
||||||
probabilistic model on one of the three HSV channels (hue,
|
|
||||||
saturation or value). It computes the probability of the color of
|
|
||||||
the input point to match this specific color channel defined by a
|
|
||||||
mean and a standard deviation.
|
|
||||||
|
|
||||||
The HSV channels are defined this way:
|
|
||||||
|
|
||||||
- Hue ranges from 0 to 360 and measures the general "tint" of the
|
|
||||||
color (green, blue, pink, etc.)
|
|
||||||
|
|
||||||
- Saturation ranges from 0 to 100 and measures the "strength" of the
|
|
||||||
color (0 is gray and 100 is the fully saturated color)
|
|
||||||
|
|
||||||
- Value ranges from 0 to 100 and measures the "brightness" of the
|
|
||||||
color (0 is black and 100 is the fully bright color)
|
|
||||||
|
|
||||||
For example, such an feature using the channel 0 (hue) with a
|
|
||||||
mean of 90 (which corresponds to a green hue) can help to identify
|
|
||||||
trees.
|
|
||||||
|
|
||||||
\image html trees.png
|
|
||||||
|
|
||||||
<center><em>Left: input point set with colors. Right: HSV feature on hue with
|
|
||||||
a mean of 90 (from low values in white to high values in dark
|
|
||||||
red).</em></center>
|
|
||||||
|
|
||||||
Its default name is the channel followed by the mean value (for
|
|
||||||
example: "hue_180", "saturation_20" or "value_98").
|
|
||||||
|
|
||||||
\note The user only needs to provide a map to standard (and more common)
|
|
||||||
RGB colors, the conversion to HSV is done internally.
|
|
||||||
|
|
||||||
\tparam GeomTraits model of \cgal Kernel.
|
|
||||||
\tparam PointRange model of `ConstRange`. Its iterator type
|
|
||||||
is `RandomAccessIterator` and its value type is the key type of
|
|
||||||
`ColorMap`.
|
|
||||||
\tparam ColorMap model of `ReadablePropertyMap` whose key
|
|
||||||
type is the value type of the iterator of `PointRange` and value type
|
|
||||||
is `CGAL::Classification::RGB_Color`.
|
|
||||||
*/
|
|
||||||
template <typename GeomTraits, typename PointRange, typename ColorMap>
|
|
||||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Hsv, please update your code with Color_channel instead")
|
|
||||||
class Hsv : public Feature_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// Selected channel.
|
|
||||||
enum Channel
|
|
||||||
{
|
|
||||||
HUE = 0, ///< 0
|
|
||||||
SATURATION = 1, ///< 1
|
|
||||||
VALUE = 2 ///< 2
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef typename Classification::RGB_Color RGB_Color;
|
|
||||||
typedef typename Classification::HSV_Color HSV_Color;
|
|
||||||
|
|
||||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
|
||||||
std::vector<float> color_feature;
|
|
||||||
#else
|
|
||||||
const PointRange& input;
|
|
||||||
ColorMap color_map;
|
|
||||||
Channel m_channel;
|
|
||||||
float m_mean;
|
|
||||||
float m_sd;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*!
|
|
||||||
|
|
||||||
\brief Constructs a feature based on the given color channel,
|
|
||||||
mean and standard deviation.
|
|
||||||
|
|
||||||
\param input point range.
|
|
||||||
\param color_map property map to access the colors of the input points.
|
|
||||||
\param channel chosen HSV channel.
|
|
||||||
\param mean mean value of the specified channel.
|
|
||||||
\param sd standard deviation of the specified channel.
|
|
||||||
*/
|
|
||||||
Hsv (const PointRange& input,
|
|
||||||
ColorMap color_map,
|
|
||||||
Channel channel,
|
|
||||||
float mean, float sd)
|
|
||||||
#ifndef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
|
||||||
: input(input), color_map(color_map), m_channel(channel), m_mean(mean), m_sd(sd)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
|
||||||
for(std::size_t i = 0; i < input.size();i++)
|
|
||||||
{
|
|
||||||
HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+i)));
|
|
||||||
color_feature.push_back (std::exp (-(c[std::size_t(channel)] - mean)
|
|
||||||
* (c[std::size_t(channel)] - mean) / (2. * sd * sd)));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
std::ostringstream oss;
|
|
||||||
if (channel == HUE) oss << "hue";
|
|
||||||
else if (channel == SATURATION) oss << "saturation";
|
|
||||||
else if (channel == VALUE) oss << "value";
|
|
||||||
oss << "_" << mean;
|
|
||||||
this->set_name (oss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual float value (std::size_t pt_index)
|
|
||||||
{
|
|
||||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
|
||||||
return color_feature[pt_index];
|
|
||||||
#else
|
|
||||||
HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+pt_index)));
|
|
||||||
return std::exp (-(c[std::size_t(m_channel)] - m_mean)
|
|
||||||
* (c[std::size_t(m_channel)] - m_mean) / (2.f * m_sd * m_sd));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Feature
|
|
||||||
|
|
||||||
} // namespace Classification
|
|
||||||
|
|
||||||
} // namespace CGAL
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
#endif // CGAL_CLASSIFICATION_FEATURE_HSV_H
|
|
||||||
|
|
@ -152,8 +152,6 @@ public:
|
||||||
typedef Classification::Feature::Verticality
|
typedef Classification::Feature::Verticality
|
||||||
<GeomTraits> Verticality;
|
<GeomTraits> Verticality;
|
||||||
typedef Classification::Feature::Eigenvalue Eigenvalue;
|
typedef Classification::Feature::Eigenvalue Eigenvalue;
|
||||||
|
|
||||||
typedef typename Classification::RGB_Color RGB_Color;
|
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -153,8 +153,6 @@ public:
|
||||||
typedef Classification::Feature::Gradient_of_feature
|
typedef Classification::Feature::Gradient_of_feature
|
||||||
<PointRange, PointMap, Neighbor_query> Gradient_of_feature;
|
<PointRange, PointMap, Neighbor_query> Gradient_of_feature;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef typename Classification::RGB_Color RGB_Color;
|
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -294,64 +292,6 @@ public:
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
||||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
|
||||||
// deprecated
|
|
||||||
template <typename VectorMap = Default,
|
|
||||||
typename ColorMap = Default,
|
|
||||||
typename EchoMap = Default>
|
|
||||||
CGAL_DEPRECATED_MSG("you are using a deprecated constructor of CGAL::Classification::Point_set_feature_generator, please update your code")
|
|
||||||
Point_set_feature_generator(Feature_set& features,
|
|
||||||
const PointRange& input,
|
|
||||||
PointMap point_map,
|
|
||||||
std::size_t nb_scales,
|
|
||||||
VectorMap normal_map = VectorMap(),
|
|
||||||
ColorMap color_map = ColorMap(),
|
|
||||||
EchoMap echo_map = EchoMap(),
|
|
||||||
float voxel_size = -1.f)
|
|
||||||
: m_input (input), m_point_map (point_map)
|
|
||||||
{
|
|
||||||
m_bbox = CGAL::bounding_box
|
|
||||||
(boost::make_transform_iterator (m_input.begin(), CGAL::Property_map_to_unary_function<PointMap>(m_point_map)),
|
|
||||||
boost::make_transform_iterator (m_input.end(), CGAL::Property_map_to_unary_function<PointMap>(m_point_map)));
|
|
||||||
|
|
||||||
CGAL::Real_timer t; t.start();
|
|
||||||
|
|
||||||
m_scales.reserve (nb_scales);
|
|
||||||
|
|
||||||
m_scales.push_back (new Scale (m_input, m_point_map, m_bbox, voxel_size));
|
|
||||||
|
|
||||||
if (voxel_size == -1.f)
|
|
||||||
voxel_size = m_scales[0]->grid_resolution();
|
|
||||||
|
|
||||||
for (std::size_t i = 1; i < nb_scales; ++ i)
|
|
||||||
{
|
|
||||||
voxel_size *= 2;
|
|
||||||
m_scales.push_back (new Scale (m_input, m_point_map, m_bbox, voxel_size, m_scales[i-1]->grid));
|
|
||||||
}
|
|
||||||
t.stop();
|
|
||||||
CGAL_CLASSIFICATION_CERR << "Scales computed in " << t.time() << " second(s)" << std::endl;
|
|
||||||
t.reset();
|
|
||||||
|
|
||||||
typedef typename Default::Get<VectorMap, typename GeomTraits::Vector_3 >::type
|
|
||||||
Vmap;
|
|
||||||
typedef typename Default::Get<ColorMap, RGB_Color >::type
|
|
||||||
Cmap;
|
|
||||||
typedef typename Default::Get<EchoMap, std::size_t >::type
|
|
||||||
Emap;
|
|
||||||
|
|
||||||
generate_point_based_features (features);
|
|
||||||
generate_normal_based_features (features, get_parameter<Vmap>(normal_map));
|
|
||||||
generate_color_based_features (features, get_parameter<Cmap>(color_map));
|
|
||||||
generate_echo_based_features (features, get_parameter<Emap>(echo_map));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions to remove when deprecated constructor is removed
|
|
||||||
void generate_normal_based_features(const CGAL::Constant_property_map<Iterator, typename GeomTraits::Vector_3>&) { }
|
|
||||||
void generate_color_based_features(const CGAL::Constant_property_map<Iterator, RGB_Color>&) { }
|
|
||||||
void generate_echo_based_features(const CGAL::Constant_property_map<Iterator, std::size_t>&) { }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual ~Point_set_feature_generator()
|
virtual ~Point_set_feature_generator()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
@ -434,7 +374,7 @@ public:
|
||||||
|
|
||||||
\tparam ColorMap model of `ReadablePropertyMap` whose key type is
|
\tparam ColorMap model of `ReadablePropertyMap` whose key type is
|
||||||
the value type of the iterator of `PointRange` and value type is
|
the value type of the iterator of `PointRange` and value type is
|
||||||
`CGAL::Classification::RGB_Color`.
|
`CGAL::Color`.
|
||||||
|
|
||||||
\param features the feature set where the features are instantiated.
|
\param features the feature set where the features are instantiated.
|
||||||
\param color_map property map to access the colors of the input points (if any).
|
\param color_map property map to access the colors of the input points (if any).
|
||||||
|
|
|
||||||
|
|
@ -89,14 +89,6 @@ if(TARGET test_classification_point_set)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
create_single_source_cgal_program( "deprecated_test_classification_point_set.cpp" CXX_FEATURES ${needed_cxx_features} )
|
|
||||||
if(TARGET deprecated_test_classification_point_set)
|
|
||||||
target_link_libraries(deprecated_test_classification_point_set PUBLIC ${classification_linked_libraries})
|
|
||||||
if (TBB_FOUND)
|
|
||||||
CGAL_target_use_TBB( deprecated_test_classification_point_set )
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
create_single_source_cgal_program( "test_classification_io.cpp" CXX_FEATURES ${needed_cxx_features} )
|
create_single_source_cgal_program( "test_classification_io.cpp" CXX_FEATURES ${needed_cxx_features} )
|
||||||
if(TARGET test_classification_io)
|
if(TARGET test_classification_io)
|
||||||
target_link_libraries(test_classification_io PUBLIC ${classification_linked_libraries})
|
target_link_libraries(test_classification_io PUBLIC ${classification_linked_libraries})
|
||||||
|
|
|
||||||
|
|
@ -1,136 +0,0 @@
|
||||||
#include <CGAL/internal/disable_deprecation_warnings_and_errors.h>
|
|
||||||
|
|
||||||
#if defined (_MSC_VER) && !defined (_WIN64)
|
|
||||||
#pragma warning(disable:4244) // boost::number_distance::distance()
|
|
||||||
// converts 64 to 32 bits integers
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <CGAL/Simple_cartesian.h>
|
|
||||||
#include <CGAL/Classification.h>
|
|
||||||
#include <CGAL/Point_set_3.h>
|
|
||||||
#include <CGAL/Random.h>
|
|
||||||
|
|
||||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
|
||||||
typedef Kernel::Point_3 Point;
|
|
||||||
typedef Kernel::Vector_3 Vector;
|
|
||||||
|
|
||||||
typedef CGAL::Point_set_3<Point> Point_set;
|
|
||||||
typedef Point_set::Point_map Point_map;
|
|
||||||
|
|
||||||
typedef Kernel::Iso_cuboid_3 Iso_cuboid_3;
|
|
||||||
|
|
||||||
namespace Classification = CGAL::Classification;
|
|
||||||
|
|
||||||
typedef Classification::Label_handle Label_handle;
|
|
||||||
typedef Classification::Feature_handle Feature_handle;
|
|
||||||
typedef Classification::Label_set Label_set;
|
|
||||||
typedef Classification::Feature_set Feature_set;
|
|
||||||
|
|
||||||
typedef Classification::Sum_of_weighted_features_classifier Classifier;
|
|
||||||
|
|
||||||
typedef Classification::Point_set_feature_generator<Kernel, Point_set, Point_map> Feature_generator;
|
|
||||||
|
|
||||||
typedef Point_set::Property_map<std::size_t> Size_t_map;
|
|
||||||
typedef Point_set::Property_map<Classification::RGB_Color> Color_map;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main (int, char**)
|
|
||||||
{
|
|
||||||
Point_set pts;
|
|
||||||
|
|
||||||
pts.add_normal_map();
|
|
||||||
|
|
||||||
bool map_added = false;
|
|
||||||
Size_t_map echo_map;
|
|
||||||
Color_map color_map;
|
|
||||||
|
|
||||||
boost::tie (echo_map, map_added) = pts.add_property_map<std::size_t> ("echo");
|
|
||||||
assert (map_added);
|
|
||||||
boost::tie (color_map, map_added) = pts.add_property_map<Classification::RGB_Color> ("color");
|
|
||||||
assert (map_added);
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < 1000; ++ i)
|
|
||||||
{
|
|
||||||
Point_set::iterator it
|
|
||||||
= pts.insert (Point (CGAL::get_default_random().get_double(),
|
|
||||||
CGAL::get_default_random().get_double(),
|
|
||||||
CGAL::get_default_random().get_double()),
|
|
||||||
Vector (CGAL::get_default_random().get_double(),
|
|
||||||
CGAL::get_default_random().get_double(),
|
|
||||||
CGAL::get_default_random().get_double()));
|
|
||||||
echo_map[*it] = std::size_t(CGAL::get_default_random().get_int(0, 4));
|
|
||||||
color_map[*it] = CGAL::make_array ((unsigned char)(CGAL::get_default_random().get_int(0, 255)),
|
|
||||||
(unsigned char)(CGAL::get_default_random().get_int(0, 255)),
|
|
||||||
(unsigned char)(CGAL::get_default_random().get_int(0, 255)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Feature_set features;
|
|
||||||
Feature_generator generator (features, pts, pts.point_map(),
|
|
||||||
5, // using 5 scales
|
|
||||||
pts.normal_map(),
|
|
||||||
color_map, echo_map);
|
|
||||||
|
|
||||||
assert (generator.number_of_scales() == 5);
|
|
||||||
assert (features.size() == 59);
|
|
||||||
|
|
||||||
Label_set labels;
|
|
||||||
|
|
||||||
std::vector<int> training_set (pts.size(), -1);
|
|
||||||
for (std::size_t i = 0; i < 20; ++ i)
|
|
||||||
{
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "label_" << i;
|
|
||||||
Label_handle lh = labels.add(oss.str().c_str());
|
|
||||||
|
|
||||||
for (std::size_t j = 0; j < 10; ++ j)
|
|
||||||
training_set[std::size_t(CGAL::get_default_random().get_int(0, int(training_set.size())))] = int(i);
|
|
||||||
}
|
|
||||||
assert (labels.size() == 20);
|
|
||||||
|
|
||||||
Classifier classifier (labels, features);
|
|
||||||
|
|
||||||
classifier.train<CGAL::Sequential_tag> (training_set, 800);
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
|
||||||
classifier.train<CGAL::Parallel_tag> (training_set, 800);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::vector<int> label_indices(pts.size(), -1);
|
|
||||||
|
|
||||||
Classification::classify<CGAL::Sequential_tag>
|
|
||||||
(pts, labels, classifier, label_indices);
|
|
||||||
|
|
||||||
Classification::classify_with_local_smoothing<CGAL::Sequential_tag>
|
|
||||||
(pts, pts.point_map(), labels, classifier,
|
|
||||||
generator.neighborhood().sphere_neighbor_query(0.01f),
|
|
||||||
label_indices);
|
|
||||||
|
|
||||||
Classification::classify_with_graphcut<CGAL::Sequential_tag>
|
|
||||||
(pts, pts.point_map(), labels, classifier,
|
|
||||||
generator.neighborhood().k_neighbor_query(12),
|
|
||||||
0.2f, 10, label_indices);
|
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
|
||||||
Classification::classify<CGAL::Sequential_tag>
|
|
||||||
(pts, labels, classifier, label_indices);
|
|
||||||
|
|
||||||
Classification::classify_with_local_smoothing<CGAL::Sequential_tag>
|
|
||||||
(pts, pts.point_map(), labels, classifier,
|
|
||||||
generator.neighborhood().sphere_neighbor_query(0.01f),
|
|
||||||
label_indices);
|
|
||||||
|
|
||||||
Classification::classify_with_graphcut<CGAL::Sequential_tag>
|
|
||||||
(pts, pts.point_map(), labels, classifier,
|
|
||||||
generator.neighborhood().k_neighbor_query(12),
|
|
||||||
0.2f, 10, label_indices);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Classification::Evaluation evaluation (labels, training_set, label_indices);
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
@ -37,7 +37,7 @@ typedef Classification::Point_set_feature_generator<Kernel, Point_set, Point_map
|
||||||
|
|
||||||
typedef Point_set::Vector_map Vector_map;
|
typedef Point_set::Vector_map Vector_map;
|
||||||
typedef Point_set::Property_map<std::size_t> Size_t_map;
|
typedef Point_set::Property_map<std::size_t> Size_t_map;
|
||||||
typedef Point_set::Property_map<Classification::RGB_Color> Color_map;
|
typedef Point_set::Property_map<CGAL::Color> Color_map;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ int main (int, char**)
|
||||||
normal_map = pts.normal_map();
|
normal_map = pts.normal_map();
|
||||||
boost::tie (echo_map, map_added) = pts.add_property_map<std::size_t> ("echo");
|
boost::tie (echo_map, map_added) = pts.add_property_map<std::size_t> ("echo");
|
||||||
assert (map_added);
|
assert (map_added);
|
||||||
boost::tie (color_map, map_added) = pts.add_property_map<Classification::RGB_Color> ("color");
|
boost::tie (color_map, map_added) = pts.add_property_map<CGAL::Color> ("color");
|
||||||
assert (map_added);
|
assert (map_added);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < 1000; ++ i)
|
for (std::size_t i = 0; i < 1000; ++ i)
|
||||||
|
|
@ -68,9 +68,9 @@ int main (int, char**)
|
||||||
CGAL::get_default_random().get_double(),
|
CGAL::get_default_random().get_double(),
|
||||||
CGAL::get_default_random().get_double()));
|
CGAL::get_default_random().get_double()));
|
||||||
echo_map[*it] = std::size_t(CGAL::get_default_random().get_int(0, 4));
|
echo_map[*it] = std::size_t(CGAL::get_default_random().get_int(0, 4));
|
||||||
color_map[*it] = CGAL::make_array ((unsigned char)(CGAL::get_default_random().get_int(0, 255)),
|
color_map[*it] = CGAL::Color ((unsigned char)(CGAL::get_default_random().get_int(0, 255)),
|
||||||
(unsigned char)(CGAL::get_default_random().get_int(0, 255)),
|
(unsigned char)(CGAL::get_default_random().get_int(0, 255)),
|
||||||
(unsigned char)(CGAL::get_default_random().get_int(0, 255)));
|
(unsigned char)(CGAL::get_default_random().get_int(0, 255)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Feature_set features;
|
Feature_set features;
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ void draw_points_and_hull(const std::vector<Point_3>& points,
|
||||||
std::vector<Point_3>::const_iterator p_it;
|
std::vector<Point_3>::const_iterator p_it;
|
||||||
|
|
||||||
CGAL::Geomview_stream geomview;
|
CGAL::Geomview_stream geomview;
|
||||||
geomview << CGAL::RED;
|
geomview << CGAL::red();
|
||||||
for (p_it = points.begin(); p_it != points.end(); p_it++)
|
for (p_it = points.begin(); p_it != points.end(); p_it++)
|
||||||
{
|
{
|
||||||
geomview << *p_it;
|
geomview << *p_it;
|
||||||
|
|
@ -78,7 +78,7 @@ void draw_points_and_hull(const std::vector<Point_3>& points,
|
||||||
Point_3 point;
|
Point_3 point;
|
||||||
Polyhedron_3 polyhedron;
|
Polyhedron_3 polyhedron;
|
||||||
|
|
||||||
geomview << CGAL::BLUE;
|
geomview << CGAL::blue();
|
||||||
if ( CGAL::assign(point, object) )
|
if ( CGAL::assign(point, object) )
|
||||||
geomview << point;
|
geomview << point;
|
||||||
else if ( CGAL::assign(segment, object) )
|
else if ( CGAL::assign(segment, object) )
|
||||||
|
|
|
||||||
|
|
@ -57,13 +57,13 @@ int main()
|
||||||
|
|
||||||
// use different colors, and put a few sleeps/clear.
|
// use different colors, and put a few sleeps/clear.
|
||||||
|
|
||||||
gv << CGAL::BLUE;
|
gv << CGAL::blue();
|
||||||
std::cout << "Drawing 2D Delaunay triangulation in wired mode.\n";
|
std::cout << "Drawing 2D Delaunay triangulation in wired mode.\n";
|
||||||
gv.set_wired(true);
|
gv.set_wired(true);
|
||||||
gv << D;
|
gv << D;
|
||||||
|
|
||||||
#if 1 // It's too slow ! Needs to use OFF for that.
|
#if 1 // It's too slow ! Needs to use OFF for that.
|
||||||
gv << CGAL::RED;
|
gv << CGAL::red();
|
||||||
std::cout << "Drawing its Voronoi diagram.\n";
|
std::cout << "Drawing its Voronoi diagram.\n";
|
||||||
gv.set_wired(true);
|
gv.set_wired(true);
|
||||||
D.draw_dual(gv);
|
D.draw_dual(gv);
|
||||||
|
|
|
||||||
|
|
@ -50,25 +50,25 @@ int main()
|
||||||
gv.clear(); // remove the pickplane.
|
gv.clear(); // remove the pickplane.
|
||||||
|
|
||||||
gv << K::Point_2 (200, 100);
|
gv << K::Point_2 (200, 100);
|
||||||
gv << CGAL::BLUE;
|
gv << CGAL::blue();
|
||||||
gv << K::Point_3 (200, 100, 100);
|
gv << K::Point_3 (200, 100, 100);
|
||||||
gv << CGAL::RED;
|
gv << CGAL::red();
|
||||||
gv << K::Segment_2 (K::Point_2(200, 100),
|
gv << K::Segment_2 (K::Point_2(200, 100),
|
||||||
K::Point_2(300, 100));
|
K::Point_2(300, 100));
|
||||||
gv << CGAL::GREEN;
|
gv << CGAL::green();
|
||||||
gv << K::Segment_3 (K::Point_3(200, 100, 100),
|
gv << K::Segment_3 (K::Point_3(200, 100, 100),
|
||||||
K::Point_3(300, 100, 200));
|
K::Point_3(300, 100, 200));
|
||||||
gv << CGAL::DEEPBLUE;
|
gv << CGAL::deep_blue();
|
||||||
gv << K::Sphere_3 (K::Point_3(100, 100, 100), 1000);
|
gv << K::Sphere_3 (K::Point_3(100, 100, 100), 1000);
|
||||||
gv << CGAL::VIOLET;
|
gv << CGAL::violet();
|
||||||
gv << K::Triangle_2 (K::Point_2(200, 200),
|
gv << K::Triangle_2 (K::Point_2(200, 200),
|
||||||
K::Point_2(220, 220),
|
K::Point_2(220, 220),
|
||||||
K::Point_2(180, 220));
|
K::Point_2(180, 220));
|
||||||
gv << CGAL::ORANGE;
|
gv << CGAL::orange();
|
||||||
gv << K::Triangle_3 (K::Point_3(200, 200, 50),
|
gv << K::Triangle_3 (K::Point_3(200, 200, 50),
|
||||||
K::Point_3(220, 220, 80),
|
K::Point_3(220, 220, 80),
|
||||||
K::Point_3(180, 220, 100));
|
K::Point_3(180, 220, 100));
|
||||||
gv << CGAL::PURPLE;
|
gv << CGAL::purple();
|
||||||
gv << K::Tetrahedron_3 (K::Point_3(100, 100, 180),
|
gv << K::Tetrahedron_3 (K::Point_3(100, 100, 180),
|
||||||
K::Point_3(120, 70, 220),
|
K::Point_3(120, 70, 220),
|
||||||
K::Point_3(100, 100, 220),
|
K::Point_3(100, 100, 220),
|
||||||
|
|
@ -76,7 +76,7 @@ int main()
|
||||||
gv << CGAL::Bbox_2(10, 10, 30, 30);
|
gv << CGAL::Bbox_2(10, 10, 30, 30);
|
||||||
gv << CGAL::Bbox_3(10, 10, 10, 30, 30, 30);
|
gv << CGAL::Bbox_3(10, 10, 10, 30, 30, 30);
|
||||||
|
|
||||||
gv << CGAL::RED;
|
gv << CGAL::red();
|
||||||
gv << K::Ray_2(K::Point_2(205,205), K::Point_2(500,500));
|
gv << K::Ray_2(K::Point_2(205,205), K::Point_2(500,500));
|
||||||
gv << K::Ray_3(K::Point_3(250,250,250), K::Point_3(500,500,500));
|
gv << K::Ray_3(K::Point_3(250,250,250), K::Point_3(500,500,500));
|
||||||
gv << K::Line_2(K::Point_2(195,195), K::Point_2(500,500));
|
gv << K::Line_2(K::Point_2(195,195), K::Point_2(500,500));
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ CGAL_INLINE_FUNCTION
|
||||||
Geomview_stream::Geomview_stream(const Bbox_3 &bbox,
|
Geomview_stream::Geomview_stream(const Bbox_3 &bbox,
|
||||||
const char *machine,
|
const char *machine,
|
||||||
const char *login)
|
const char *login)
|
||||||
: bb(bbox), vertex_color(BLACK), edge_color(BLACK), face_color(BLACK),
|
: bb(bbox), vertex_color(black()), edge_color(black()), face_color(black()),
|
||||||
wired_flag(false), echo_flag(true), raw_flag(false),
|
wired_flag(false), echo_flag(true), raw_flag(false),
|
||||||
trace_flag(false), binary_flag(false),
|
trace_flag(false), binary_flag(false),
|
||||||
line_width(1)
|
line_width(1)
|
||||||
|
|
|
||||||
|
|
@ -173,9 +173,9 @@ SegmentDelaunayGraphGraphicsItem<T>::drawAll(QPainter *painter, const QStyleOpti
|
||||||
vit != t->finite_vertices_end(); ++vit) {
|
vit != t->finite_vertices_end(); ++vit) {
|
||||||
typename T::Site_2 s = vit->site();
|
typename T::Site_2 s = vit->site();
|
||||||
if ( s.is_input() ) {
|
if ( s.is_input() ) {
|
||||||
//*widget << CGAL::RED;
|
//*widget << CGAL::red();
|
||||||
} else {
|
} else {
|
||||||
//*widget << CGAL::YELLOW;
|
//*widget << CGAL::yellow();
|
||||||
}
|
}
|
||||||
if ( s.is_point() ) {
|
if ( s.is_point() ) {
|
||||||
QPointF point = matrix.map(convert(s.point()));
|
QPointF point = matrix.map(convert(s.point()));
|
||||||
|
|
|
||||||
|
|
@ -208,9 +208,9 @@ SegmentDelaunayGraphLinfGraphicsItem<T>::drawAll(QPainter *painter, const QStyle
|
||||||
vit != t->finite_vertices_end(); ++vit) {
|
vit != t->finite_vertices_end(); ++vit) {
|
||||||
typename T::Site_2 s = vit->site();
|
typename T::Site_2 s = vit->site();
|
||||||
if ( s.is_input() ) {
|
if ( s.is_input() ) {
|
||||||
//*widget << CGAL::RED;
|
//*widget << CGAL::red();
|
||||||
} else {
|
} else {
|
||||||
//*widget << CGAL::YELLOW;
|
//*widget << CGAL::yellow();
|
||||||
}
|
}
|
||||||
if ( s.is_point() ) {
|
if ( s.is_point() ) {
|
||||||
QPointF point = matrix.map(convert(s.point()));
|
QPointF point = matrix.map(convert(s.point()));
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ typedef HDS::Face_handle Face_handle;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
HDS hds;
|
HDS hds;
|
||||||
Face_handle f = hds.faces_push_back( Face( CGAL::RED));
|
Face_handle f = hds.faces_push_back( Face( CGAL::red()));
|
||||||
f->color = CGAL::BLUE;
|
f->color = CGAL::blue();
|
||||||
CGAL_assertion( f->color == CGAL::BLUE);
|
CGAL_assertion( f->color == CGAL::blue());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
// Use something defined not in headers but in the CGAL library to test that is was indeed properly built and linked to,
|
// Use something defined not in headers but in the CGAL library to test that is was indeed properly built and linked to,
|
||||||
|
|
||||||
#include <CGAL/IO/Color.h>
|
#include <CGAL/Random.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
volatile const CGAL::Color* c = &CGAL::BLACK;
|
volatile const CGAL::Random* r = &CGAL::get_default_random();
|
||||||
|
return int(r != 0);
|
||||||
return (c != 0) ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -287,14 +287,14 @@ int main(int , char** )
|
||||||
|
|
||||||
std::cout << "The data points are displayed in blue in the geomview"
|
std::cout << "The data points are displayed in blue in the geomview"
|
||||||
<< " application." << std::endl;
|
<< " application." << std::endl;
|
||||||
gv << CGAL::BLUE;
|
gv << CGAL::blue();
|
||||||
visu_points(gv,sample_3);
|
visu_points(gv,sample_3);
|
||||||
|
|
||||||
//show the gradients
|
//show the gradients
|
||||||
if(method>0){
|
if(method>0){
|
||||||
std::cout << "The function gradients are displayed by red lines "
|
std::cout << "The function gradients are displayed by red lines "
|
||||||
<<" in the geomview application." << std::endl;
|
<<" in the geomview application." << std::endl;
|
||||||
gv <<CGAL::RED;
|
gv <<CGAL::red();
|
||||||
gv << Segment_3(Point_3(h/3,h/3,w),Point_3(h/3,h/3,w)+ Vector_3(-g,-g,0));
|
gv << Segment_3(Point_3(h/3,h/3,w),Point_3(h/3,h/3,w)+ Vector_3(-g,-g,0));
|
||||||
gv << Segment_3(Point_3(-h/3,h/3,w),Point_3(-h/3,h/3,w)+Vector_3(g,-g,0));
|
gv << Segment_3(Point_3(-h/3,h/3,w),Point_3(-h/3,h/3,w)+Vector_3(g,-g,0));
|
||||||
gv << Segment_3(Point_3(-h/3,-h/3,w),Point_3(-h/3,-h/3,w)+Vector_3(g,g,0));
|
gv << Segment_3(Point_3(-h/3,-h/3,w),Point_3(-h/3,-h/3,w)+Vector_3(g,g,0));
|
||||||
|
|
|
||||||
|
|
@ -217,21 +217,21 @@ int main()
|
||||||
}
|
}
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
gv << CGAL::VIOLET;
|
gv << CGAL::violet();
|
||||||
visu_points(gv,points);
|
visu_points(gv,points);
|
||||||
|
|
||||||
gv << CGAL::RED << Segment(p, p+ 0.3*normal);
|
gv << CGAL::red() << Segment(p, p+ 0.3*normal);
|
||||||
gv << CGAL::ORANGE <<p;
|
gv << CGAL::orange() <<p;
|
||||||
|
|
||||||
std::cout << "Visualizing the intersection of "
|
std::cout << "Visualizing the intersection of "
|
||||||
<< "3D Voronoi diagram with tangent plane at "
|
<< "3D Voronoi diagram with tangent plane at "
|
||||||
<< p << "." << std::endl;
|
<< p << "." << std::endl;
|
||||||
gv << CGAL::BLUE;
|
gv << CGAL::blue();
|
||||||
T.draw_dual(gv);
|
T.draw_dual(gv);
|
||||||
Face_iterator fit = T.finite_faces_begin(),
|
Face_iterator fit = T.finite_faces_begin(),
|
||||||
fend = T.finite_faces_end();
|
fend = T.finite_faces_end();
|
||||||
for(;fit != fend;fit++)
|
for(;fit != fend;fit++)
|
||||||
gv <<CGAL::BLACK<<T.dual(fit);
|
gv <<CGAL::black()<<T.dual(fit);
|
||||||
|
|
||||||
std::cout << "Enter any character to quit" << std::endl;
|
std::cout << "Enter any character to quit" << std::endl;
|
||||||
std::cin >> ch;
|
std::cin >> ch;
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ void output_distribution_to_png(std::vector<double>& elements,
|
||||||
|
|
||||||
const double scale = double_options["scale"];
|
const double scale = double_options["scale"];
|
||||||
|
|
||||||
*widget << CGAL::FillColor(CGAL::BLACK);
|
*widget << CGAL::FillColor(CGAL::black());
|
||||||
// *widget << Segment_2(Point_2(0., 0.), Point_2(1., 0.));
|
// *widget << Segment_2(Point_2(0., 0.), Point_2(1., 0.));
|
||||||
for(int k=0;k<number_of_classes;k++)
|
for(int k=0;k<number_of_classes;k++)
|
||||||
if(distribution[k]>0)
|
if(distribution[k]>0)
|
||||||
|
|
@ -184,12 +184,12 @@ void output_distribution_to_png(std::vector<double>& elements,
|
||||||
height = ( (distribution[k]+0.)/number_of_cells ) * scale;
|
height = ( (distribution[k]+0.)/number_of_cells ) * scale;
|
||||||
else
|
else
|
||||||
height = ( std::log(distribution[k]+0.)/std::log(number_of_cells) ) * (-scale);
|
height = ( std::log(distribution[k]+0.)/std::log(number_of_cells) ) * (-scale);
|
||||||
*widget << CGAL::BLACK
|
*widget << CGAL::black()
|
||||||
<< Rectangle_2(Point_2(k*width, 0),
|
<< Rectangle_2(Point_2(k*width, 0),
|
||||||
Point_2((k+1)*width, height));
|
Point_2((k+1)*width, height));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*widget << CGAL::RED << Segment_2(Point_2(k*width, 0),
|
*widget << CGAL::red() << Segment_2(Point_2(k*width, 0),
|
||||||
Point_2((k+1)*width, 0));
|
Point_2((k+1)*width, 0));
|
||||||
|
|
||||||
widget->unlock();
|
widget->unlock();
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,10 @@ void display_distribution(Distribution_displayer* display,
|
||||||
const double height = ( distribution[k]+0. ) * echelle;
|
const double height = ( distribution[k]+0. ) * echelle;
|
||||||
display->fill_rectangle(k * width, 0,
|
display->fill_rectangle(k * width, 0,
|
||||||
(k+1)* width, height,
|
(k+1)* width, height,
|
||||||
CGAL::BLACK);
|
CGAL::black());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
display->segment(k * width, 0.,
|
display->segment(k * width, 0.,
|
||||||
(k+1) * width, 0.,
|
(k+1) * width, 0.,
|
||||||
CGAL::RED);
|
CGAL::red());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ bool process_aux_2(const std::vector<Qualities>& qualities,
|
||||||
|
|
||||||
displays[i]->segment(x_position_of_length_bound, 0.0,
|
displays[i]->segment(x_position_of_length_bound, 0.0,
|
||||||
x_position_of_length_bound, -0.05,
|
x_position_of_length_bound, -0.05,
|
||||||
CGAL::BLUE);
|
CGAL::blue());
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_stream << "saving " << filename.c_str() << "...\n";
|
*out_stream << "saving " << filename.c_str() << "...\n";
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ void parse_argv(int argc, char** argv, int extra_args = 0)
|
||||||
//
|
//
|
||||||
// const double scale = double_options["scale"];
|
// const double scale = double_options["scale"];
|
||||||
//
|
//
|
||||||
//// *widget << CGAL::FillColor(CGAL::BLACK);
|
//// *widget << CGAL::FillColor(CGAL::black());
|
||||||
// // *widget << Segment_2(Point_2(0., 0.), Point_2(1., 0.));
|
// // *widget << Segment_2(Point_2(0., 0.), Point_2(1., 0.));
|
||||||
// for(int k=0;k<number_of_classes;k++)
|
// for(int k=0;k<number_of_classes;k++)
|
||||||
// if(distribution[k]>0)
|
// if(distribution[k]>0)
|
||||||
|
|
@ -190,12 +190,12 @@ void parse_argv(int argc, char** argv, int extra_args = 0)
|
||||||
// height = ( (distribution[k]+0.)/number_of_cells ) * scale;
|
// height = ( (distribution[k]+0.)/number_of_cells ) * scale;
|
||||||
// else
|
// else
|
||||||
// height = ( std::log(distribution[k]+0.)/std::log(number_of_cells) ) * (-scale);
|
// height = ( std::log(distribution[k]+0.)/std::log(number_of_cells) ) * (-scale);
|
||||||
//// *widget << CGAL::BLACK
|
//// *widget << CGAL::black()
|
||||||
//// << Rectangle_2(Point_2(k*width, 0),
|
//// << Rectangle_2(Point_2(k*width, 0),
|
||||||
//// Point_2((k+1)*width, height));
|
//// Point_2((k+1)*width, height));
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
//// *widget << CGAL::RED << Segment_2(Point_2(k*width, 0),
|
//// *widget << CGAL::red() << Segment_2(Point_2(k*width, 0),
|
||||||
//// Point_2((k+1)*width, 0));
|
//// Point_2((k+1)*width, 0));
|
||||||
//
|
//
|
||||||
// // widget->unlock();
|
// // widget->unlock();
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,11 @@ class SNC_SM_BooleColor
|
||||||
typedef typename Refs_::Mark Mark;
|
typedef typename Refs_::Mark Mark;
|
||||||
public:
|
public:
|
||||||
Color color(SVertex_const_handle, Mark m) const
|
Color color(SVertex_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SHalfedge_const_handle, Mark m) const
|
Color color(SHalfedge_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SHalfloop_const_handle, Mark m) const
|
Color color(SHalfloop_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SFace_const_handle, Mark m) const
|
Color color(SFace_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL_NEF3_DGREY : CGAL_NEF3_LGREY ); }
|
{ return ( m ? CGAL_NEF3_DGREY : CGAL_NEF3_LGREY ); }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,11 @@ class SNC_SM_BooleColor
|
||||||
typedef typename Map_::Mark Mark;
|
typedef typename Map_::Mark Mark;
|
||||||
public:
|
public:
|
||||||
Color color(SVertex_const_handle, Mark m) const
|
Color color(SVertex_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SHalfedge_const_handle, Mark m) const
|
Color color(SHalfedge_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SHalfloop_const_handle, Mark m) const
|
Color color(SHalfloop_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SFace_const_handle, Mark m) const
|
Color color(SFace_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); }
|
{ return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,11 @@ class SM_BooleColor
|
||||||
typedef typename Map_::Mark Mark;
|
typedef typename Map_::Mark Mark;
|
||||||
public:
|
public:
|
||||||
Color color(SVertex_const_handle, Mark m) const
|
Color color(SVertex_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SHalfedge_const_handle, Mark m) const
|
Color color(SHalfedge_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SHalfloop_const_handle, Mark m) const
|
Color color(SHalfloop_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SFace_const_handle, Mark m) const
|
Color color(SFace_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); }
|
{ return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ class Sphere_point : public VPoint, public Gen_object {
|
||||||
public:
|
public:
|
||||||
Sphere_point() {}
|
Sphere_point() {}
|
||||||
Sphere_point(const CGAL::Sphere_point<R>& p,
|
Sphere_point(const CGAL::Sphere_point<R>& p,
|
||||||
CGAL::Color c = CGAL::BLACK, unsigned w = 10) :
|
CGAL::Color c = CGAL::black(), unsigned w = 10) :
|
||||||
VPoint(Approximator<R>::approximate(p)), p_(p), c_(c), w_(w) {}
|
VPoint(Approximator<R>::approximate(p)), p_(p), c_(c), w_(w) {}
|
||||||
Sphere_point(const Sphere_point<R>& p) : VPoint(p), Gen_object()
|
Sphere_point(const Sphere_point<R>& p) : VPoint(p), Gen_object()
|
||||||
{ p_ = p.p_; c_ = p.c_; w_ = p.w_; }
|
{ p_ = p.p_; c_ = p.c_; w_ = p.w_; }
|
||||||
|
|
@ -297,7 +297,7 @@ class Sphere_segment : public VSegment, public Gen_object {
|
||||||
public:
|
public:
|
||||||
Sphere_segment() {}
|
Sphere_segment() {}
|
||||||
Sphere_segment(const CGAL::Sphere_segment<R>& s,
|
Sphere_segment(const CGAL::Sphere_segment<R>& s,
|
||||||
CGAL::Color c = CGAL::BLACK, unsigned w = 2)
|
CGAL::Color c = CGAL::black(), unsigned w = 2)
|
||||||
: VSegment(Approximator<R>::approximate(s)), s_(s), c_(c), w_(w) {}
|
: VSegment(Approximator<R>::approximate(s)), s_(s), c_(c), w_(w) {}
|
||||||
Sphere_segment(const Sphere_segment<R>& s) : VSegment(s), Gen_object()
|
Sphere_segment(const Sphere_segment<R>& s) : VSegment(s), Gen_object()
|
||||||
{ s_ = s.s_; c_ = s.c_; w_ = s.w_; }
|
{ s_ = s.s_; c_ = s.c_; w_ = s.w_; }
|
||||||
|
|
@ -350,7 +350,7 @@ class Sphere_circle : public VSegment, public Gen_object {
|
||||||
public:
|
public:
|
||||||
Sphere_circle() {}
|
Sphere_circle() {}
|
||||||
Sphere_circle(const CGAL::Sphere_circle<R>& s,
|
Sphere_circle(const CGAL::Sphere_circle<R>& s,
|
||||||
CGAL::Color c = CGAL::BLACK, unsigned w = 2)
|
CGAL::Color c = CGAL::black(), unsigned w = 2)
|
||||||
: VSegment(Approximator<R>::approximate(s)), s_(s), c_(c), w_(w) {}
|
: VSegment(Approximator<R>::approximate(s)), s_(s), c_(c), w_(w) {}
|
||||||
Sphere_circle(const Sphere_circle<R>& s) : VSegment(s), Gen_object()
|
Sphere_circle(const Sphere_circle<R>& s) : VSegment(s), Gen_object()
|
||||||
{ s_ = s.s_; c_ = s.c_; w_ = s.w_; }
|
{ s_ = s.s_; c_ = s.c_; w_ = s.w_; }
|
||||||
|
|
@ -539,27 +539,27 @@ Unit_sphere& operator=(const Unit_sphere& S)
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
void push_back(const CGAL::Sphere_point<R>& p,
|
void push_back(const CGAL::Sphere_point<R>& p,
|
||||||
CGAL::Color c = CGAL::YELLOW, unsigned w = 5)
|
CGAL::Color c = CGAL::yellow(), unsigned w = 5)
|
||||||
{ objects_.push_back(new Sphere_point<R>(p,c,w)); }
|
{ objects_.push_back(new Sphere_point<R>(p,c,w)); }
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
void push_back(const CGAL::Sphere_segment<R>& s,
|
void push_back(const CGAL::Sphere_segment<R>& s,
|
||||||
CGAL::Color c = CGAL::BLACK, unsigned w = 1)
|
CGAL::Color c = CGAL::black(), unsigned w = 1)
|
||||||
{ objects_.push_back(new Sphere_segment<R>(s,c,w)); }
|
{ objects_.push_back(new Sphere_segment<R>(s,c,w)); }
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
void push_back(const CGAL::Sphere_circle<R>& s,
|
void push_back(const CGAL::Sphere_circle<R>& s,
|
||||||
CGAL::Color c = CGAL::BLACK, unsigned w = 1)
|
CGAL::Color c = CGAL::black(), unsigned w = 1)
|
||||||
{ objects_.push_back(new Sphere_circle<R>(s,c,w)); }
|
{ objects_.push_back(new Sphere_circle<R>(s,c,w)); }
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
void push_back(const CGAL::Sphere_triangle<R>& t,
|
void push_back(const CGAL::Sphere_triangle<R>& t,
|
||||||
CGAL::Color c = CGAL::WHITE)
|
CGAL::Color c = CGAL::white())
|
||||||
{ triangles_.push_back(new Sphere_triangle<R>(t,c)); }
|
{ triangles_.push_back(new Sphere_triangle<R>(t,c)); }
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
void push_back_triangle_edge(const CGAL::Sphere_segment<R>& s,
|
void push_back_triangle_edge(const CGAL::Sphere_segment<R>& s,
|
||||||
CGAL::Color c = CGAL::BLUE, unsigned w = 1)
|
CGAL::Color c = CGAL::blue(), unsigned w = 1)
|
||||||
{ triangle_edges_.push_back(new Sphere_segment<R>(s,c,w)); }
|
{ triangle_edges_.push_back(new Sphere_segment<R>(s,c,w)); }
|
||||||
|
|
||||||
void set_style(int style) {
|
void set_style(int style) {
|
||||||
|
|
@ -718,11 +718,11 @@ class SM_BooleColor
|
||||||
typedef typename Map_::Mark Mark;
|
typedef typename Map_::Mark Mark;
|
||||||
public:
|
public:
|
||||||
Color color(SVertex_const_handle, Mark m) const
|
Color color(SVertex_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SHalfedge_const_handle, Mark m) const
|
Color color(SHalfedge_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SHalfloop_const_handle, Mark m) const
|
Color color(SHalfloop_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL::BLACK : CGAL::WHITE ); }
|
{ return ( m ? CGAL::black() : CGAL::white() ); }
|
||||||
Color color(SFace_const_handle, Mark m) const
|
Color color(SFace_const_handle, Mark m) const
|
||||||
{ return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); }
|
{ return ( m ? CGAL_NEF_DGREY : CGAL_NEF_LGREY ); }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ int main()
|
||||||
PDT::Vertex_iterator vit;
|
PDT::Vertex_iterator vit;
|
||||||
for (vit = T.vertices_begin(); vit != T.vertices_end(); ++vit)
|
for (vit = T.vertices_begin(); vit != T.vertices_end(); ++vit)
|
||||||
if (T.degree(vit) == 6)
|
if (T.degree(vit) == 6)
|
||||||
vit->info() = CGAL::RED;
|
vit->info() = CGAL::red();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ int main(int, char**)
|
||||||
P3DT3::Vertex_iterator vit;
|
P3DT3::Vertex_iterator vit;
|
||||||
for (vit = T.vertices_begin(); vit != T.vertices_end(); ++vit) {
|
for (vit = T.vertices_begin(); vit != T.vertices_end(); ++vit) {
|
||||||
if (T.degree(vit) == 16) {
|
if (T.degree(vit) == 16) {
|
||||||
vit->info() = CGAL::RED;
|
vit->info() = CGAL::red();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,87 +35,12 @@
|
||||||
#include <CGAL/IO/read_las_points.h>
|
#include <CGAL/IO/read_las_points.h>
|
||||||
#include <CGAL/IO/write_las_points.h>
|
#include <CGAL/IO/write_las_points.h>
|
||||||
#endif // LAS
|
#endif // LAS
|
||||||
#include <CGAL/IO/read_ply_points.h>
|
#include <CGAL/IO/PLY.h>
|
||||||
#include <CGAL/IO/write_ply_points.h>
|
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename Point, typename Vector>
|
|
||||||
class Abstract_property_printer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~Abstract_property_printer() { }
|
|
||||||
virtual void print (std::ostream& stream, const typename CGAL::Point_set_3<Point,Vector>::Index& index) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Point, typename Vector, typename Type>
|
|
||||||
class Property_printer : public Abstract_property_printer<Point, Vector>
|
|
||||||
{
|
|
||||||
typedef typename CGAL::Point_set_3<Point, Vector> Point_set;
|
|
||||||
typedef typename Point_set::template Property_map<Type> Pmap;
|
|
||||||
Pmap m_pmap;
|
|
||||||
public:
|
|
||||||
Property_printer (const Pmap& pmap) : m_pmap (pmap)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void print(std::ostream& stream, const typename CGAL::Point_set_3<Point,Vector>::Index& index)
|
|
||||||
{
|
|
||||||
stream << get(m_pmap, index);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Point, typename Vector, typename Type>
|
|
||||||
class Simple_property_printer : public Abstract_property_printer<Point, Vector>
|
|
||||||
{
|
|
||||||
typedef typename CGAL::Point_set_3<Point, Vector> Point_set;
|
|
||||||
typedef typename Point_set::template Property_map<Type> Pmap;
|
|
||||||
Pmap m_pmap;
|
|
||||||
public:
|
|
||||||
Simple_property_printer (const Pmap& pmap) : m_pmap (pmap)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void print(std::ostream& stream, const typename CGAL::Point_set_3<Point,Vector>::Index& index)
|
|
||||||
{
|
|
||||||
if (get_mode(stream) == IO::ASCII)
|
|
||||||
stream << get(m_pmap, index);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Type t = get (m_pmap, index);
|
|
||||||
stream.write (reinterpret_cast<char*>(&t), sizeof(t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Point, typename Vector, typename Type>
|
|
||||||
class Char_property_printer : public Abstract_property_printer<Point, Vector>
|
|
||||||
{
|
|
||||||
typedef typename CGAL::Point_set_3<Point, Vector> Point_set;
|
|
||||||
typedef typename Point_set::template Property_map<Type> Pmap;
|
|
||||||
Pmap m_pmap;
|
|
||||||
public:
|
|
||||||
Char_property_printer (const Pmap& pmap) : m_pmap (pmap)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void print(std::ostream& stream, const typename CGAL::Point_set_3<Point,Vector>::Index& index)
|
|
||||||
{
|
|
||||||
if (get_mode(stream) == IO::ASCII)
|
|
||||||
stream << int(get(m_pmap, index));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Type t = get (m_pmap, index);
|
|
||||||
stream.write (reinterpret_cast<char*>(&t), sizeof(t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace PLY
|
namespace PLY
|
||||||
{
|
{
|
||||||
|
|
@ -365,19 +290,42 @@ read_off_point_set(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
template <typename Point, typename Vector>
|
||||||
|
bool
|
||||||
|
read_ply_point_set(
|
||||||
|
std::istream& stream, ///< input stream.
|
||||||
|
CGAL::Point_set_3<Point, Vector>& point_set) ///< point set
|
||||||
|
{
|
||||||
|
std::string dummy;
|
||||||
|
return read_ply_point_set (stream, point_set, dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgPointSet3IO
|
\ingroup PkgPointSet3IO
|
||||||
|
|
||||||
|
Reads a point set with properties from an input stream in Ascii or
|
||||||
|
Binary PLY format.
|
||||||
|
|
||||||
|
- the operator reads the vertex `point` property;
|
||||||
|
- if three PLY properties `nx`, `ny` and `nz` with type `float`
|
||||||
|
or `double` are found, the normal map is added;
|
||||||
|
- if any other PLY property is found, a "[name]" property map is
|
||||||
|
added, where `[name]` is the name of the PLY property.
|
||||||
|
|
||||||
|
The `comments` parameter can be omitted. If provided, it will be
|
||||||
|
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 (without the "comment " word).
|
||||||
*/
|
*/
|
||||||
template <typename Point, typename Vector>
|
template <typename Point, typename Vector>
|
||||||
bool
|
bool
|
||||||
read_ply_point_set(
|
read_ply_point_set(
|
||||||
std::istream& stream, ///< input stream.
|
std::istream& stream, ///< input stream.
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
CGAL::Point_set_3<Point, Vector>& point_set) ///< point set
|
|
||||||
#else
|
|
||||||
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
|
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
|
||||||
std::string* comments = NULL) ///< recover PLY comments
|
std::string& comments) ///< PLY comments.
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
if(!stream)
|
if(!stream)
|
||||||
{
|
{
|
||||||
|
|
@ -394,14 +342,14 @@ read_ply_point_set(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comments != NULL)
|
comments = reader.comments();
|
||||||
*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::PLY_element& element = reader.element(i);
|
internal::PLY::PLY_element& element = reader.element(i);
|
||||||
|
|
||||||
if (element.name() == "vertex" || element.name() == "vertices")
|
bool is_vertex = (element.name() == "vertex" || element.name() == "vertices");
|
||||||
|
if (is_vertex)
|
||||||
{
|
{
|
||||||
point_set.reserve (element.number_of_items());
|
point_set.reserve (element.number_of_items());
|
||||||
filler.instantiate_properties (element);
|
filler.instantiate_properties (element);
|
||||||
|
|
@ -417,7 +365,7 @@ read_ply_point_set(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.name() == "vertex" || element.name() == "vertices")
|
if (is_vertex)
|
||||||
filler.process_line (element);
|
filler.process_line (element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -427,27 +375,46 @@ read_ply_point_set(
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgPointSet3IO
|
\ingroup PkgPointSet3IO
|
||||||
|
|
||||||
|
Writes a point set with properties in an output stream in PLY
|
||||||
|
format.
|
||||||
|
|
||||||
|
If found, the normal map is inserted to the stream. All other
|
||||||
|
properties with simple types are inserted in the stream.
|
||||||
|
|
||||||
|
If provided, the `comments` string is included line by line in
|
||||||
|
the header of the PLY stream (each line will be precedeed by
|
||||||
|
"comment ").
|
||||||
*/
|
*/
|
||||||
template <typename Point, typename Vector>
|
template <typename Point, typename Vector>
|
||||||
bool
|
bool
|
||||||
write_ply_point_set(
|
write_ply_point_set(
|
||||||
std::ostream& stream, ///< output stream.
|
std::ostream& stream, ///< output stream.
|
||||||
#ifdef DOXYGEN_RUNNING
|
const CGAL::Point_set_3<Point, Vector>& point_set, ///< point set.
|
||||||
const CGAL::Point_set_3<Point, Vector>& point_set) ///< point set
|
const std::string& comments = std::string()) ///< PLY comments.
|
||||||
#else
|
|
||||||
const CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
|
|
||||||
std::string* comments = NULL) ///< write PLY comments
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
typedef CGAL::Point_set_3<Point, Vector> Point_set;
|
typedef CGAL::Point_set_3<Point, Vector> Point_set;
|
||||||
|
typedef typename Point_set::Index Index;
|
||||||
|
typedef typename Point_set::Point_map Point_map;
|
||||||
|
typedef typename Point_set::Vector_map Vector_map;
|
||||||
|
typedef typename Point_set::template Property_map<boost::int8_t> Int8_map;
|
||||||
|
typedef typename Point_set::template Property_map<boost::uint8_t> Uint8_map;
|
||||||
|
typedef typename Point_set::template Property_map<boost::int16_t> Int16_map;
|
||||||
|
typedef typename Point_set::template Property_map<boost::uint16_t> Uint16_map;
|
||||||
|
typedef typename Point_set::template Property_map<boost::int32_t> Int32_map;
|
||||||
|
typedef typename Point_set::template Property_map<boost::uint32_t> Uint32_map;
|
||||||
|
typedef typename Point_set::template Property_map<boost::int64_t> Int64_map;
|
||||||
|
typedef typename Point_set::template Property_map<boost::uint64_t> Uint64_map;
|
||||||
|
typedef typename Point_set::template Property_map<float> Float_map;
|
||||||
|
typedef typename Point_set::template Property_map<double> Double_map;
|
||||||
|
|
||||||
stream << "ply" << std::endl
|
stream << "ply" << std::endl
|
||||||
<< ((get_mode(stream) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl
|
<< ((get_mode(stream) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl
|
||||||
<< "comment Generated by the CGAL library" << std::endl;
|
<< "comment Generated by the CGAL library" << std::endl;
|
||||||
|
|
||||||
if (comments != NULL)
|
if (comments != std::string())
|
||||||
{
|
{
|
||||||
std::istringstream iss (*comments);
|
std::istringstream iss (comments);
|
||||||
std::string line;
|
std::string line;
|
||||||
while (getline(iss, line))
|
while (getline(iss, line))
|
||||||
{
|
{
|
||||||
|
|
@ -459,7 +426,7 @@ write_ply_point_set(
|
||||||
stream << "element vertex " << point_set.number_of_points() << std::endl;
|
stream << "element vertex " << point_set.number_of_points() << std::endl;
|
||||||
|
|
||||||
std::vector<std::string> prop = point_set.base().properties();
|
std::vector<std::string> prop = point_set.base().properties();
|
||||||
std::vector<internal::Abstract_property_printer<Point, Vector>*> printers;
|
std::vector<internal::PLY::Abstract_property_printer<Index>*> printers;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < prop.size(); ++ i)
|
for (std::size_t i = 0; i < prop.size(); ++ i)
|
||||||
{
|
{
|
||||||
|
|
@ -468,7 +435,7 @@ write_ply_point_set(
|
||||||
|
|
||||||
if (prop[i] == "point")
|
if (prop[i] == "point")
|
||||||
{
|
{
|
||||||
if (boost::is_same<typename GetFTFromMap<typename Point_set::Point_map>::type, float>::value)
|
if (boost::is_same<typename Get_FT_from_map<typename Point_set::Point_map>::type, float>::value)
|
||||||
{
|
{
|
||||||
stream << "property float x" << std::endl
|
stream << "property float x" << std::endl
|
||||||
<< "property float y" << std::endl
|
<< "property float y" << std::endl
|
||||||
|
|
@ -480,86 +447,125 @@ write_ply_point_set(
|
||||||
<< "property double y" << std::endl
|
<< "property double y" << std::endl
|
||||||
<< "property double z" << std::endl;
|
<< "property double z" << std::endl;
|
||||||
}
|
}
|
||||||
printers.push_back (new internal::Property_printer<Point,Vector,Point>(point_set.point_map()));
|
printers.push_back (new internal::PLY::Property_printer<Index,Point_map>(point_set.point_map()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (prop[i] == "normal")
|
if (prop[i] == "normal")
|
||||||
{
|
{
|
||||||
stream << "property double nx" << std::endl
|
if (boost::is_same<typename Get_FT_from_map<typename Point_set::Vector_map>::type, float>::value)
|
||||||
<< "property double ny" << std::endl
|
{
|
||||||
<< "property double nz" << std::endl;
|
stream << "property float nx" << std::endl
|
||||||
printers.push_back (new internal::Property_printer<Point,Vector,Vector>(point_set.normal_map()));
|
<< "property float ny" << std::endl
|
||||||
|
<< "property float nz" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stream << "property double nx" << std::endl
|
||||||
|
<< "property double ny" << std::endl
|
||||||
|
<< "property double nz" << std::endl;
|
||||||
|
}
|
||||||
|
printers.push_back (new internal::PLY::Property_printer<Index,Vector_map>(point_set.normal_map()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool okay = false;
|
bool okay = false;
|
||||||
{
|
{
|
||||||
typename Point_set::template Property_map<boost::int8_t> pmap;
|
Int8_map pmap;
|
||||||
boost::tie (pmap, okay) = point_set.template property_map<boost::int8_t>(prop[i]);
|
boost::tie (pmap, okay) = point_set.template property_map<boost::int8_t>(prop[i]);
|
||||||
if (okay)
|
if (okay)
|
||||||
{
|
{
|
||||||
stream << "property char " << prop[i] << std::endl;
|
stream << "property char " << prop[i] << std::endl;
|
||||||
printers.push_back (new internal::Char_property_printer<Point,Vector,boost::int8_t>(pmap));
|
printers.push_back (new internal::PLY::Char_property_printer<Index,Int8_map>(pmap));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
typename Point_set::template Property_map<boost::uint8_t> pmap;
|
Uint8_map pmap;
|
||||||
boost::tie (pmap, okay) = point_set.template property_map<boost::uint8_t>(prop[i]);
|
boost::tie (pmap, okay) = point_set.template property_map<boost::uint8_t>(prop[i]);
|
||||||
if (okay)
|
if (okay)
|
||||||
{
|
{
|
||||||
stream << "property uchar " << prop[i] << std::endl;
|
stream << "property uchar " << prop[i] << std::endl;
|
||||||
printers.push_back (new internal::Char_property_printer<Point,Vector,boost::uint8_t>(pmap));
|
printers.push_back (new internal::PLY::Char_property_printer<Index,Uint8_map>(pmap));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
typename Point_set::template Property_map<boost::int16_t> pmap;
|
Int16_map pmap;
|
||||||
boost::tie (pmap, okay) = point_set.template property_map<boost::int16_t>(prop[i]);
|
boost::tie (pmap, okay) = point_set.template property_map<boost::int16_t>(prop[i]);
|
||||||
if (okay)
|
if (okay)
|
||||||
{
|
{
|
||||||
stream << "property short " << prop[i] << std::endl;
|
stream << "property short " << prop[i] << std::endl;
|
||||||
printers.push_back (new internal::Simple_property_printer<Point,Vector,boost::int16_t>(pmap));
|
printers.push_back (new internal::PLY::Simple_property_printer<Index,Int16_map>(pmap));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
typename Point_set::template Property_map<boost::uint16_t> pmap;
|
Uint16_map pmap;
|
||||||
boost::tie (pmap, okay) = point_set.template property_map<boost::uint16_t>(prop[i]);
|
boost::tie (pmap, okay) = point_set.template property_map<boost::uint16_t>(prop[i]);
|
||||||
if (okay)
|
if (okay)
|
||||||
{
|
{
|
||||||
stream << "property ushort " << prop[i] << std::endl;
|
stream << "property ushort " << prop[i] << std::endl;
|
||||||
printers.push_back (new internal::Simple_property_printer<Point,Vector,boost::uint16_t>(pmap));
|
printers.push_back (new internal::PLY::Simple_property_printer<Index,Uint16_map>(pmap));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
typename Point_set::template Property_map<boost::int32_t> pmap;
|
Int32_map pmap;
|
||||||
boost::tie (pmap, okay) = point_set.template property_map<boost::int32_t>(prop[i]);
|
boost::tie (pmap, okay) = point_set.template property_map<boost::int32_t>(prop[i]);
|
||||||
if (okay)
|
if (okay)
|
||||||
{
|
{
|
||||||
stream << "property int " << prop[i] << std::endl;
|
stream << "property int " << prop[i] << std::endl;
|
||||||
printers.push_back (new internal::Simple_property_printer<Point,Vector,boost::int32_t>(pmap));
|
printers.push_back (new internal::PLY::Simple_property_printer<Index,Int32_map>(pmap));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
typename Point_set::template Property_map<float> pmap;
|
Uint32_map pmap;
|
||||||
|
boost::tie (pmap, okay) = point_set.template property_map<boost::uint32_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
stream << "property uint " << prop[i] << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Index,Uint32_map>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Int64_map pmap;
|
||||||
|
boost::tie (pmap, okay) = point_set.template property_map<boost::int64_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
stream << "property int " << prop[i] << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Index,Int64_map,boost::int32_t>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Uint64_map pmap;
|
||||||
|
boost::tie (pmap, okay) = point_set.template property_map<boost::uint64_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
stream << "property uint " << prop[i] << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Index,Uint64_map,boost::uint32_t>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Float_map pmap;
|
||||||
boost::tie (pmap, okay) = point_set.template property_map<float>(prop[i]);
|
boost::tie (pmap, okay) = point_set.template property_map<float>(prop[i]);
|
||||||
if (okay)
|
if (okay)
|
||||||
{
|
{
|
||||||
stream << "property float " << prop[i] << std::endl;
|
stream << "property float " << prop[i] << std::endl;
|
||||||
printers.push_back (new internal::Simple_property_printer<Point,Vector,float>(pmap));
|
printers.push_back (new internal::PLY::Simple_property_printer<Index,Float_map>(pmap));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
typename Point_set::template Property_map<double> pmap;
|
Double_map pmap;
|
||||||
boost::tie (pmap, okay) = point_set.template property_map<double>(prop[i]);
|
boost::tie (pmap, okay) = point_set.template property_map<double>(prop[i]);
|
||||||
if (okay)
|
if (okay)
|
||||||
{
|
{
|
||||||
stream << "property double " << prop[i] << std::endl;
|
stream << "property double " << prop[i] << std::endl;
|
||||||
printers.push_back (new internal::Simple_property_printer<Point,Vector,double>(pmap));
|
printers.push_back (new internal::PLY::Simple_property_printer<Index,Double_map>(pmap));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
#include <CGAL/IO/PLY.h>
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/value_type_traits.h>
|
#include <CGAL/value_type_traits.h>
|
||||||
#include <CGAL/point_set_processing_assertions.h>
|
#include <CGAL/point_set_processing_assertions.h>
|
||||||
|
|
@ -43,36 +44,9 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define TRY_TO_GENERATE_PROPERTY(STD_TYPE, T_TYPE, TYPE) \
|
|
||||||
if (type == STD_TYPE || type == T_TYPE) \
|
|
||||||
m_elements.back().add_property (new PLY_read_typed_number< TYPE > (name, format))
|
|
||||||
|
|
||||||
#define TRY_TO_GENERATE_SIZED_LIST_PROPERTY(STD_SIZE_TYPE, T_SIZE_TYPE, SIZE_TYPE, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \
|
|
||||||
if ((size_type == STD_SIZE_TYPE || size_type == T_SIZE_TYPE) && \
|
|
||||||
(index_type == STD_INDEX_TYPE || index_type == T_INDEX_TYPE)) \
|
|
||||||
m_elements.back().add_property (new PLY_read_typed_list_with_typed_size< SIZE_TYPE , INDEX_TYPE > (name, format))
|
|
||||||
|
|
||||||
#define TRY_TO_GENERATE_LIST_PROPERTY(STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \
|
|
||||||
TRY_TO_GENERATE_SIZED_LIST_PROPERTY("uchar", "uint8", boost::uint8_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE); \
|
|
||||||
else TRY_TO_GENERATE_SIZED_LIST_PROPERTY("ushort", "uint16", boost::uint16_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE); \
|
|
||||||
else TRY_TO_GENERATE_SIZED_LIST_PROPERTY("uint", "uint32", boost::uint32_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE)
|
|
||||||
|
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
#ifdef DOXYGEN_RUNNING // Document some parts from Stream_support here for convenience
|
||||||
// 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
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
\ingroup PkgPointSetProcessing3IOPly
|
||||||
|
|
||||||
|
|
@ -88,23 +62,6 @@ namespace CGAL {
|
||||||
PLY_property (const char* name) : name (name) { }
|
PLY_property (const char* name) : name (name) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
|
||||||
|
|
||||||
// Use a double property for all kernels...
|
|
||||||
template <typename FT> struct Convert_FT { typedef double type; };
|
|
||||||
// ...except if kernel uses type float
|
|
||||||
template <> struct Convert_FT<float> { typedef float type; };
|
|
||||||
|
|
||||||
template <typename PointOrVectorMap>
|
|
||||||
struct GetFTFromMap
|
|
||||||
{
|
|
||||||
typedef typename Convert_FT
|
|
||||||
<typename Kernel_traits
|
|
||||||
<typename boost::property_traits
|
|
||||||
<PointOrVectorMap>::value_type>::Kernel::FT>::type type;
|
|
||||||
};
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
\ingroup PkgPointSetProcessing3IOPly
|
||||||
|
|
||||||
|
|
@ -118,24 +75,10 @@ namespace CGAL {
|
||||||
\tparam PointMap the property map used to store points.
|
\tparam PointMap the property map used to store points.
|
||||||
*/
|
*/
|
||||||
template <typename PointMap>
|
template <typename PointMap>
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
std::tuple<PointMap,
|
std::tuple<PointMap,
|
||||||
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
|
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
|
||||||
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
||||||
#else
|
make_ply_point_reader(PointMap point_map);
|
||||||
std::tuple<PointMap,
|
|
||||||
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>,
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>,
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type> >
|
|
||||||
#endif
|
|
||||||
make_ply_point_reader(PointMap point_map)
|
|
||||||
{
|
|
||||||
return std::make_tuple (point_map, typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3(),
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>("x"),
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>("y"),
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>("z"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
\ingroup PkgPointSetProcessing3IOPly
|
||||||
|
|
@ -151,573 +94,11 @@ namespace CGAL {
|
||||||
\tparam VectorMap the property map used to store vectors.
|
\tparam VectorMap the property map used to store vectors.
|
||||||
*/
|
*/
|
||||||
template <typename VectorMap>
|
template <typename VectorMap>
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
std::tuple<VectorMap,
|
std::tuple<VectorMap,
|
||||||
typename Kernel_traits<typename VectorMap::value_type>::Kernel::Construct_vector_3,
|
typename Kernel_traits<typename VectorMap::value_type>::Kernel::Construct_vector_3,
|
||||||
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
||||||
#else
|
make_ply_normal_reader(VectorMap normal_map);
|
||||||
std::tuple<VectorMap,
|
#endif // DOXYGEN_RUNNING
|
||||||
typename Kernel_traits<typename VectorMap::value_type>::Kernel::Construct_vector_3,
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>,
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>,
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type> >
|
|
||||||
#endif
|
|
||||||
make_ply_normal_reader(VectorMap normal_map)
|
|
||||||
{
|
|
||||||
return std::make_tuple (normal_map, typename Kernel_traits<typename VectorMap::value_type>::Kernel::Construct_vector_3(),
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>("nx"),
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>("ny"),
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>("nz"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
namespace PLY {
|
|
||||||
|
|
||||||
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 void get (std::istream& stream) const = 0;
|
|
||||||
|
|
||||||
// The two following functions prevent the stream to only extract
|
|
||||||
// ONE character (= what the types char imply) by requiring
|
|
||||||
// explicitely an integer object when reading the stream
|
|
||||||
void read_ascii (std::istream& stream, char& c) const
|
|
||||||
{
|
|
||||||
short s;
|
|
||||||
stream >> s;
|
|
||||||
c = static_cast<char>(s);
|
|
||||||
}
|
|
||||||
void read_ascii (std::istream& stream, signed char& c) const
|
|
||||||
{
|
|
||||||
short s;
|
|
||||||
stream >> s;
|
|
||||||
c = static_cast<signed char>(s);
|
|
||||||
}
|
|
||||||
void read_ascii (std::istream& stream, unsigned char& c) const
|
|
||||||
{
|
|
||||||
unsigned short s;
|
|
||||||
stream >> s;
|
|
||||||
c = static_cast<unsigned char>(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_ascii (std::istream& stream, float& t) const
|
|
||||||
{
|
|
||||||
stream >> iformat(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_ascii (std::istream& stream, double& t) const
|
|
||||||
{
|
|
||||||
stream >> iformat(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default template when Type is not a char type
|
|
||||||
template <typename Type>
|
|
||||||
void read_ascii (std::istream& stream, Type& t) const
|
|
||||||
{
|
|
||||||
stream >> t;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
Type read (std::istream& stream) const
|
|
||||||
{
|
|
||||||
if (m_format == 0) // Ascii
|
|
||||||
{
|
|
||||||
Type t;
|
|
||||||
read_ascii (stream, t);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
else // Binary (2 = little endian)
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
char uChar[sizeof (Type)];
|
|
||||||
Type type;
|
|
||||||
} buffer;
|
|
||||||
|
|
||||||
std::size_t size = sizeof (Type);
|
|
||||||
|
|
||||||
stream.read(buffer.uChar, size);
|
|
||||||
|
|
||||||
if (m_format == 2) // Big endian
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < size / 2; ++ i)
|
|
||||||
{
|
|
||||||
unsigned char tmp = buffer.uChar[i];
|
|
||||||
buffer.uChar[i] = buffer.uChar[size - 1 - i];
|
|
||||||
buffer.uChar[size - 1 - i] = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buffer.type;
|
|
||||||
}
|
|
||||||
return Type();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
class PLY_read_typed_number : public PLY_read_number
|
|
||||||
{
|
|
||||||
mutable Type m_buffer;
|
|
||||||
public:
|
|
||||||
PLY_read_typed_number (std::string name, std::size_t format)
|
|
||||||
: PLY_read_number (name, format)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void get (std::istream& stream) const
|
|
||||||
{
|
|
||||||
m_buffer = (this->read<Type> (stream));
|
|
||||||
}
|
|
||||||
const Type& buffer() const
|
|
||||||
{
|
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
class PLY_read_typed_list : public PLY_read_number
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
mutable std::vector<Type> m_buffer;
|
|
||||||
public:
|
|
||||||
PLY_read_typed_list (std::string name, std::size_t format)
|
|
||||||
: PLY_read_number (name, format)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
virtual void get (std::istream& stream) const = 0;
|
|
||||||
|
|
||||||
const std::vector<Type>& buffer() const
|
|
||||||
{
|
|
||||||
return m_buffer;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename SizeType, typename IndexType>
|
|
||||||
class PLY_read_typed_list_with_typed_size
|
|
||||||
: public PLY_read_typed_list<IndexType>
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
PLY_read_typed_list_with_typed_size (std::string name, std::size_t format)
|
|
||||||
: PLY_read_typed_list<IndexType> (name, format)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void get (std::istream& stream) const
|
|
||||||
{
|
|
||||||
std::size_t size = static_cast<std::size_t>(this->template read<SizeType>(stream));
|
|
||||||
this->m_buffer.resize (size);
|
|
||||||
for (std::size_t i = 0; i < size; ++ i)
|
|
||||||
this->m_buffer[i] = this->template read<IndexType> (stream);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class PLY_element
|
|
||||||
{
|
|
||||||
std::string m_name;
|
|
||||||
std::size_t m_number;
|
|
||||||
|
|
||||||
std::vector<PLY_read_number*> m_properties;
|
|
||||||
public:
|
|
||||||
|
|
||||||
PLY_element (const std::string& name, std::size_t number)
|
|
||||||
: m_name (name), m_number (number)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
PLY_element (const PLY_element& other)
|
|
||||||
: m_name (other.m_name), m_number (other.m_number), m_properties (other.m_properties)
|
|
||||||
{
|
|
||||||
const_cast<PLY_element&>(other).m_properties.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
PLY_element& operator= (const PLY_element& other)
|
|
||||||
{
|
|
||||||
m_name = other.m_name;
|
|
||||||
m_number = other.m_number;
|
|
||||||
m_properties = other.m_properties;
|
|
||||||
const_cast<PLY_element&>(other).m_properties.clear();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~PLY_element()
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < m_properties.size(); ++ i)
|
|
||||||
delete m_properties[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& name() const { return m_name; }
|
|
||||||
std::size_t number_of_items() const { return m_number; }
|
|
||||||
std::size_t number_of_properties() const { return m_properties.size(); }
|
|
||||||
|
|
||||||
PLY_read_number* property (std::size_t idx) { return m_properties[idx]; }
|
|
||||||
|
|
||||||
void add_property (PLY_read_number* read_number)
|
|
||||||
{
|
|
||||||
m_properties.push_back (read_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
bool has_property (const char* tag)
|
|
||||||
{
|
|
||||||
return has_property (tag, Type());
|
|
||||||
}
|
|
||||||
template <typename Type>
|
|
||||||
bool has_property (const char* tag, const std::vector<Type>&)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < number_of_properties(); ++ i)
|
|
||||||
if (m_properties[i]->name () == tag)
|
|
||||||
return (dynamic_cast<PLY_read_typed_list<Type>*>(m_properties[i]) != NULL);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
bool has_property (const char* tag, Type)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < number_of_properties(); ++ i)
|
|
||||||
if (m_properties[i]->name () == tag)
|
|
||||||
return (dynamic_cast<PLY_read_typed_number<Type>*>(m_properties[i]) != NULL);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool has_property (const char* tag, double)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < number_of_properties(); ++ i)
|
|
||||||
if (m_properties[i]->name () == tag)
|
|
||||||
return (dynamic_cast<PLY_read_typed_number<double>*>(m_properties[i]) != NULL
|
|
||||||
|| dynamic_cast<PLY_read_typed_number<float>*>(m_properties[i]) != NULL);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
void assign (Type& t, const char* tag)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < number_of_properties (); ++ i)
|
|
||||||
if (m_properties[i]->name () == tag)
|
|
||||||
{
|
|
||||||
PLY_read_typed_number<Type>*
|
|
||||||
property = dynamic_cast<PLY_read_typed_number<Type>*>(m_properties[i]);
|
|
||||||
CGAL_assertion (property != NULL);
|
|
||||||
t = property->buffer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
void assign (std::vector<Type>& t, const char* tag)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < number_of_properties (); ++ i)
|
|
||||||
if (m_properties[i]->name () == tag)
|
|
||||||
{
|
|
||||||
PLY_read_typed_list<Type>*
|
|
||||||
property = dynamic_cast<PLY_read_typed_list<Type>*>(m_properties[i]);
|
|
||||||
CGAL_assertion (property != NULL);
|
|
||||||
t = property->buffer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void assign (double& t, const char* tag)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < number_of_properties (); ++ i)
|
|
||||||
if (m_properties[i]->name () == tag)
|
|
||||||
{
|
|
||||||
PLY_read_typed_number<double>*
|
|
||||||
property_double = dynamic_cast<PLY_read_typed_number<double>*>(m_properties[i]);
|
|
||||||
if (property_double == NULL)
|
|
||||||
{
|
|
||||||
PLY_read_typed_number<float>*
|
|
||||||
property_float = dynamic_cast<PLY_read_typed_number<float>*>(m_properties[i]);
|
|
||||||
CGAL_assertion (property_float != NULL);
|
|
||||||
t = property_float->buffer();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
t = property_double->buffer();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class PLY_reader
|
|
||||||
{
|
|
||||||
std::vector<PLY_element> m_elements;
|
|
||||||
std::string m_comments;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PLY_reader () { }
|
|
||||||
|
|
||||||
std::size_t number_of_elements() const { return m_elements.size(); }
|
|
||||||
PLY_element& element (std::size_t idx)
|
|
||||||
{
|
|
||||||
return m_elements[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& comments() const { return m_comments; }
|
|
||||||
|
|
||||||
template <typename Stream>
|
|
||||||
bool init (Stream& stream)
|
|
||||||
{
|
|
||||||
std::size_t lineNumber = 0; // current line number
|
|
||||||
enum Format { ASCII = 0, BINARY_LITTLE_ENDIAN = 1, BINARY_BIG_ENDIAN = 2};
|
|
||||||
Format format = ASCII;
|
|
||||||
|
|
||||||
std::string line;
|
|
||||||
std::istringstream iss;
|
|
||||||
|
|
||||||
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 << "Error: 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 << "Error: 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")
|
|
||||||
{
|
|
||||||
std::string type, name;
|
|
||||||
if (!(iss >> type >> name))
|
|
||||||
{
|
|
||||||
std::cerr << "Error line " << lineNumber << " of file" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (type == "list") // Special case
|
|
||||||
{
|
|
||||||
std::string size_type = name;
|
|
||||||
std::string index_type;
|
|
||||||
name.clear();
|
|
||||||
if (!(iss >> index_type >> name))
|
|
||||||
{
|
|
||||||
std::cerr << "Error line " << lineNumber << " of file" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRY_TO_GENERATE_LIST_PROPERTY ("char", "int8", boost::int8_t);
|
|
||||||
else TRY_TO_GENERATE_LIST_PROPERTY ("uchar", "uint8", boost::uint8_t);
|
|
||||||
else TRY_TO_GENERATE_LIST_PROPERTY ("short", "int16", boost::int16_t);
|
|
||||||
else TRY_TO_GENERATE_LIST_PROPERTY ("ushort", "uint16", boost::uint16_t);
|
|
||||||
else TRY_TO_GENERATE_LIST_PROPERTY ("int", "int32", boost::int32_t);
|
|
||||||
else TRY_TO_GENERATE_LIST_PROPERTY ("uint", "uint32", boost::uint32_t);
|
|
||||||
else TRY_TO_GENERATE_LIST_PROPERTY ("float", "float32", float);
|
|
||||||
else TRY_TO_GENERATE_LIST_PROPERTY ("double", "float64", double);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRY_TO_GENERATE_PROPERTY ("char", "int8", boost::int8_t);
|
|
||||||
else TRY_TO_GENERATE_PROPERTY ("uchar", "uint8", boost::uint8_t);
|
|
||||||
else TRY_TO_GENERATE_PROPERTY ("short", "int16", boost::int16_t);
|
|
||||||
else TRY_TO_GENERATE_PROPERTY ("ushort", "uint16", boost::uint16_t);
|
|
||||||
else TRY_TO_GENERATE_PROPERTY ("int", "int32", boost::int32_t);
|
|
||||||
else TRY_TO_GENERATE_PROPERTY ("uint", "uint32", boost::uint32_t);
|
|
||||||
else TRY_TO_GENERATE_PROPERTY ("float", "float32", float);
|
|
||||||
else TRY_TO_GENERATE_PROPERTY ("double", "float64", double);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (keyword == "comment")
|
|
||||||
{
|
|
||||||
std::string str = iss.str();
|
|
||||||
if (str.size() > 8)
|
|
||||||
{
|
|
||||||
std::copy (str.begin() + 8, str.end(), std::back_inserter (m_comments));
|
|
||||||
m_comments += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_elements.push_back (PLY_element(type, number));
|
|
||||||
}
|
|
||||||
// When end_header is reached, stop loop and begin reading points
|
|
||||||
else if (keyword == "end_header")
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
~PLY_reader ()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Reader, class T>
|
|
||||||
void get_value(Reader& r, T& v, PLY_property<T>& wrapper)
|
|
||||||
{
|
|
||||||
return r.assign(v, wrapper.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <std::size_t N>
|
|
||||||
struct Filler
|
|
||||||
{
|
|
||||||
template <class Reader, class Value_tuple, class PLY_property_tuple>
|
|
||||||
static void fill(Reader& r, Value_tuple& values, PLY_property_tuple wrappers)
|
|
||||||
{
|
|
||||||
get_value(r, std::get<N>(values), std::get<N+2>(wrappers));
|
|
||||||
Filler<N-1>::fill(r, values, wrappers);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int ...>
|
|
||||||
struct seq { };
|
|
||||||
|
|
||||||
template<int N, int ...S>
|
|
||||||
struct gens : gens<N-1, N-1, S...> { };
|
|
||||||
|
|
||||||
template<int ...S>
|
|
||||||
struct gens<0, S...> {
|
|
||||||
typedef seq<S...> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class ValueType, class Functor, class Tuple, int ...S>
|
|
||||||
ValueType call_functor(Functor f, Tuple t, seq<S...>) {
|
|
||||||
return f(std::get<S>(t) ...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ValueType, class Functor, typename ... T>
|
|
||||||
ValueType call_functor(Functor f, std::tuple<T...>& t)
|
|
||||||
{
|
|
||||||
return call_functor<ValueType>(f, t, typename gens<sizeof...(T)>::type());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct Filler<0>
|
|
||||||
{
|
|
||||||
template <class Reader, class Value_tuple, class PLY_property_tuple>
|
|
||||||
static void fill(Reader& r, Value_tuple& values, PLY_property_tuple wrappers)
|
|
||||||
{
|
|
||||||
get_value(r, std::get<0>(values), std::get<2>(wrappers));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename OutputValueType,
|
|
||||||
typename PropertyMap,
|
|
||||||
typename Constructor,
|
|
||||||
typename ... T>
|
|
||||||
void process_properties (PLY_element& element, OutputValueType& new_element,
|
|
||||||
std::tuple<PropertyMap, Constructor, PLY_property<T>...>&& current)
|
|
||||||
{
|
|
||||||
typedef typename PropertyMap::value_type PmapValueType;
|
|
||||||
std::tuple<T...> values;
|
|
||||||
Filler<sizeof...(T)-1>::fill(element, values, current);
|
|
||||||
PmapValueType new_value = call_functor<PmapValueType>(std::get<1>(current), values);
|
|
||||||
put (std::get<0>(current), new_element, new_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputValueType,
|
|
||||||
typename PropertyMap,
|
|
||||||
typename Constructor,
|
|
||||||
typename ... T,
|
|
||||||
typename NextPropertyBinder,
|
|
||||||
typename ... PropertyMapBinders>
|
|
||||||
void process_properties (PLY_element& element, OutputValueType& new_element,
|
|
||||||
std::tuple<PropertyMap, Constructor, PLY_property<T>...>&& current,
|
|
||||||
NextPropertyBinder&& next,
|
|
||||||
PropertyMapBinders&& ... properties)
|
|
||||||
{
|
|
||||||
typedef typename PropertyMap::value_type PmapValueType;
|
|
||||||
std::tuple<T...> values;
|
|
||||||
Filler<sizeof...(T)-1>::fill(element, values, current);
|
|
||||||
PmapValueType new_value = call_functor<PmapValueType>(std::get<1>(current), values);
|
|
||||||
put (std::get<0>(current), new_element, new_value);
|
|
||||||
|
|
||||||
process_properties (element, new_element, std::forward<NextPropertyBinder>(next),
|
|
||||||
std::forward<PropertyMapBinders>(properties)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename OutputValueType, typename PropertyMap, typename T>
|
|
||||||
void process_properties (PLY_element& element, OutputValueType& new_element,
|
|
||||||
std::pair<PropertyMap, PLY_property<T> >&& current)
|
|
||||||
{
|
|
||||||
T new_value = T();
|
|
||||||
element.assign (new_value, current.second.name);
|
|
||||||
put (current.first, new_element, new_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OutputValueType, typename PropertyMap, typename T,
|
|
||||||
typename NextPropertyBinder, typename ... PropertyMapBinders>
|
|
||||||
void process_properties (PLY_element& element, OutputValueType& new_element,
|
|
||||||
std::pair<PropertyMap, PLY_property<T> >&& current,
|
|
||||||
NextPropertyBinder&& next,
|
|
||||||
PropertyMapBinders&& ... properties)
|
|
||||||
{
|
|
||||||
T new_value = T();
|
|
||||||
element.assign (new_value, current.second.name);
|
|
||||||
put (current.first, new_element, new_value);
|
|
||||||
process_properties (element, new_element, std::forward<NextPropertyBinder>(next),
|
|
||||||
std::forward<PropertyMapBinders>(properties)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace PLY
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
\ingroup PkgPointSetProcessing3IOPly
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
#include <CGAL/IO/PLY.h>
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
#include <CGAL/point_set_processing_assertions.h>
|
#include <CGAL/point_set_processing_assertions.h>
|
||||||
#include <CGAL/IO/read_ply_points.h>
|
|
||||||
#include <CGAL/Iterator_range.h>
|
#include <CGAL/Iterator_range.h>
|
||||||
|
|
||||||
#include <CGAL/boost/graph/named_function_params.h>
|
#include <CGAL/boost/graph/named_function_params.h>
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
#ifdef DOXYGEN_RUNNING // Document some parts from Stream_support here for convenience
|
||||||
/**
|
/**
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
\ingroup PkgPointSetProcessing3IOPly
|
||||||
|
|
||||||
|
|
@ -55,21 +56,8 @@ namespace CGAL {
|
||||||
\tparam PointMap the property map used to store points.
|
\tparam PointMap the property map used to store points.
|
||||||
*/
|
*/
|
||||||
template <typename PointMap>
|
template <typename PointMap>
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
std::tuple<PointMap, PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
std::tuple<PointMap, PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
||||||
#else
|
make_ply_point_writer(PointMap point_map);
|
||||||
std::tuple<PointMap,
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>,
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>,
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type> >
|
|
||||||
#endif
|
|
||||||
make_ply_point_writer(PointMap point_map)
|
|
||||||
{
|
|
||||||
return std::make_tuple (point_map,
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>("x"),
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>("y"),
|
|
||||||
PLY_property<typename GetFTFromMap<PointMap>::type>("z"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\ingroup PkgPointSetProcessing3IOPly
|
\ingroup PkgPointSetProcessing3IOPly
|
||||||
|
|
@ -84,21 +72,9 @@ namespace CGAL {
|
||||||
\tparam VectorMap the property map used to store vectors.
|
\tparam VectorMap the property map used to store vectors.
|
||||||
*/
|
*/
|
||||||
template <typename VectorMap>
|
template <typename VectorMap>
|
||||||
#ifdef DOXYGEN_RUNNING
|
|
||||||
std::tuple<VectorMap, PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
std::tuple<VectorMap, PLY_property<FT>, PLY_property<FT>, PLY_property<FT> >
|
||||||
#else
|
make_ply_normal_writer(VectorMap normal_map);
|
||||||
std::tuple<VectorMap,
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>,
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>,
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type> >
|
|
||||||
#endif
|
#endif
|
||||||
make_ply_normal_writer(VectorMap normal_map)
|
|
||||||
{
|
|
||||||
return std::make_tuple (normal_map,
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>("nx"),
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>("ny"),
|
|
||||||
PLY_property<typename GetFTFromMap<VectorMap>::type>("nz"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
||||||
|
|
@ -106,219 +82,6 @@ namespace internal {
|
||||||
|
|
||||||
namespace PLY {
|
namespace PLY {
|
||||||
|
|
||||||
template <typename T> void property_header_type (std::ostream& stream)
|
|
||||||
{
|
|
||||||
CGAL_assertion_msg (false, "Unknown PLY type");
|
|
||||||
stream << "undefined_type";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> void property_header_type<char> (std::ostream& stream) { stream << "char"; }
|
|
||||||
template <> void property_header_type<signed char> (std::ostream& stream) { stream << "char"; }
|
|
||||||
template <> void property_header_type<unsigned char> (std::ostream& stream) { stream << "uchar"; }
|
|
||||||
template <> void property_header_type<short> (std::ostream& stream) { stream << "short"; }
|
|
||||||
template <> void property_header_type<unsigned short> (std::ostream& stream) { stream << "ushort"; }
|
|
||||||
template <> void property_header_type<int> (std::ostream& stream) { stream << "int"; }
|
|
||||||
template <> void property_header_type<unsigned int> (std::ostream& stream) { stream << "uint"; }
|
|
||||||
template <> void property_header_type<float> (std::ostream& stream) { stream << "float"; }
|
|
||||||
template <> void property_header_type<double> (std::ostream& stream) { stream << "double"; }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void property_header (std::ostream& stream, const PLY_property<T>& prop)
|
|
||||||
{
|
|
||||||
stream << "property ";
|
|
||||||
property_header_type<T>(stream);
|
|
||||||
stream << " " << prop.name << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void property_header (std::ostream& stream, const PLY_property<std::vector<T> >& prop)
|
|
||||||
{
|
|
||||||
stream << "property list uchar ";
|
|
||||||
property_header_type<T>(stream);
|
|
||||||
stream << " " << prop.name << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <std::size_t N>
|
|
||||||
struct Properties_header
|
|
||||||
{
|
|
||||||
template <class PLY_property_tuple>
|
|
||||||
static void write(std::ostream& stream, PLY_property_tuple& wrappers)
|
|
||||||
{
|
|
||||||
Properties_header<N-1>::write(stream, wrappers);
|
|
||||||
property_header (stream, std::get<N+1>(wrappers));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template <>
|
|
||||||
struct Properties_header<0>
|
|
||||||
{
|
|
||||||
template <class PLY_property_tuple>
|
|
||||||
static void write(std::ostream& stream, PLY_property_tuple& wrappers)
|
|
||||||
{
|
|
||||||
property_header (stream, std::get<1>(wrappers));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename PropertyMap,
|
|
||||||
typename ... T>
|
|
||||||
void output_property_header (std::ostream& stream,
|
|
||||||
std::tuple<PropertyMap, PLY_property<T>... >&& current)
|
|
||||||
{
|
|
||||||
Properties_header<sizeof...(T)-1>::write(stream, current);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename PropertyMap,
|
|
||||||
typename T>
|
|
||||||
void output_property_header (std::ostream& stream,
|
|
||||||
std::pair<PropertyMap, PLY_property<T> >&& current)
|
|
||||||
{
|
|
||||||
property_header (stream, current.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PropertyMap,
|
|
||||||
typename T,
|
|
||||||
typename NextPropertyHandler,
|
|
||||||
typename ... PropertyHandler>
|
|
||||||
void output_property_header (std::ostream& stream,
|
|
||||||
std::pair<PropertyMap, PLY_property<T> >&& current,
|
|
||||||
NextPropertyHandler&& next,
|
|
||||||
PropertyHandler&& ... properties)
|
|
||||||
{
|
|
||||||
property_header (stream, current.second);
|
|
||||||
output_property_header (stream, std::forward<NextPropertyHandler>(next),
|
|
||||||
std::forward<PropertyHandler>(properties)...);
|
|
||||||
}
|
|
||||||
template <typename PropertyMap,
|
|
||||||
typename ... T,
|
|
||||||
typename NextPropertyHandler,
|
|
||||||
typename ... PropertyHandler>
|
|
||||||
void output_property_header (std::ostream& stream,
|
|
||||||
std::tuple<PropertyMap, PLY_property<T>... >&& current,
|
|
||||||
NextPropertyHandler&& next,
|
|
||||||
PropertyHandler&& ... properties)
|
|
||||||
{
|
|
||||||
Properties_header<sizeof...(T)-1>::write(stream, current);
|
|
||||||
output_property_header (stream, std::forward<NextPropertyHandler>(next),
|
|
||||||
std::forward<PropertyHandler>(properties)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
|
||||||
typename PropertyMap>
|
|
||||||
void property_write (std::ostream& stream, ForwardIterator it, PropertyMap map)
|
|
||||||
{
|
|
||||||
stream << CGAL::oformat(get (map, *it));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T no_char_character (const T& t) { return t; }
|
|
||||||
int no_char_character (const char& t) { return int(t); }
|
|
||||||
int no_char_character (const signed char& t) { return int(t); }
|
|
||||||
int no_char_character (const unsigned char& t) { return int(t); }
|
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
|
||||||
typename PropertyMap,
|
|
||||||
typename T>
|
|
||||||
void simple_property_write (std::ostream& stream, ForwardIterator it,
|
|
||||||
std::pair<PropertyMap, PLY_property<T> > map)
|
|
||||||
{
|
|
||||||
if (CGAL::get_mode(stream) == IO::ASCII)
|
|
||||||
stream << no_char_character(get (map.first, *it));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
typename PropertyMap::value_type value = get(map.first, *it);
|
|
||||||
stream.write (reinterpret_cast<char*>(&value), sizeof(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
|
||||||
typename PropertyMap,
|
|
||||||
typename T>
|
|
||||||
void simple_property_write (std::ostream& stream, ForwardIterator it,
|
|
||||||
std::pair<PropertyMap, PLY_property<std::vector<T> > > map)
|
|
||||||
{
|
|
||||||
const typename PropertyMap::reference value = get(map.first, *it);
|
|
||||||
|
|
||||||
if (CGAL::get_mode(stream) == IO::ASCII)
|
|
||||||
{
|
|
||||||
stream << value.size();
|
|
||||||
for (std::size_t i = 0; i < value.size(); ++ i)
|
|
||||||
stream << " " << no_char_character(value[i]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char size = static_cast<unsigned char>(value.size());
|
|
||||||
stream.write (reinterpret_cast<char*>(&size), sizeof(size));
|
|
||||||
for (std::size_t i = 0; i < value.size(); ++ i)
|
|
||||||
{
|
|
||||||
T t = T(value[i]);
|
|
||||||
stream.write (reinterpret_cast<char*>(&t), sizeof(t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
|
||||||
typename PropertyMap,
|
|
||||||
typename ... T>
|
|
||||||
void output_properties (std::ostream& stream,
|
|
||||||
ForwardIterator it,
|
|
||||||
std::tuple<PropertyMap, PLY_property<T>... >&& current)
|
|
||||||
{
|
|
||||||
property_write (stream, it, std::get<0>(current));
|
|
||||||
if (get_mode(stream) == IO::ASCII)
|
|
||||||
stream << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
|
||||||
typename PropertyMap,
|
|
||||||
typename T>
|
|
||||||
void output_properties (std::ostream& stream,
|
|
||||||
ForwardIterator it,
|
|
||||||
std::pair<PropertyMap, PLY_property<T> >&& current)
|
|
||||||
{
|
|
||||||
simple_property_write (stream, it, std::forward<std::pair<PropertyMap, PLY_property<T> > >(current));
|
|
||||||
if (get_mode(stream) == IO::ASCII)
|
|
||||||
stream << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
|
||||||
typename PropertyMap,
|
|
||||||
typename T,
|
|
||||||
typename NextPropertyHandler,
|
|
||||||
typename ... PropertyHandler>
|
|
||||||
void output_properties (std::ostream& stream,
|
|
||||||
ForwardIterator it,
|
|
||||||
std::pair<PropertyMap, PLY_property<T> >&& current,
|
|
||||||
NextPropertyHandler&& next,
|
|
||||||
PropertyHandler&& ... properties)
|
|
||||||
{
|
|
||||||
simple_property_write (stream, it, current);
|
|
||||||
if (get_mode(stream) == IO::ASCII)
|
|
||||||
stream << " ";
|
|
||||||
output_properties (stream, it, std::forward<NextPropertyHandler>(next),
|
|
||||||
std::forward<PropertyHandler>(properties)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ForwardIterator,
|
|
||||||
typename PropertyMap,
|
|
||||||
typename ... T,
|
|
||||||
typename NextPropertyHandler,
|
|
||||||
typename ... PropertyHandler>
|
|
||||||
void output_properties (std::ostream& stream,
|
|
||||||
ForwardIterator it,
|
|
||||||
std::tuple<PropertyMap, PLY_property<T>... >&& current,
|
|
||||||
NextPropertyHandler&& next,
|
|
||||||
PropertyHandler&& ... properties)
|
|
||||||
{
|
|
||||||
property_write (stream, it, std::get<0>(current));
|
|
||||||
if (get_mode(stream) == IO::ASCII)
|
|
||||||
stream << " ";
|
|
||||||
output_properties (stream, it, std::forward<NextPropertyHandler>(next),
|
|
||||||
std::forward<PropertyHandler>(properties)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace PLY
|
} // namespace PLY
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -396,12 +396,12 @@ void Cluster_classification::backup_existing_colors_and_add_new()
|
||||||
{
|
{
|
||||||
if (m_points->point_set()->has_colors())
|
if (m_points->point_set()->has_colors())
|
||||||
{
|
{
|
||||||
m_color = m_points->point_set()->add_property_map<Color>("real_color").first;
|
m_color = m_points->point_set()->add_property_map<CGAL::Color>("real_color").first;
|
||||||
for (Point_set::const_iterator it = m_points->point_set()->begin();
|
for (Point_set::const_iterator it = m_points->point_set()->begin();
|
||||||
it != m_points->point_set()->first_selected(); ++ it)
|
it != m_points->point_set()->first_selected(); ++ it)
|
||||||
m_color[*it] = {{ (unsigned char)(255 * m_points->point_set()->red(*it)),
|
m_color[*it] = CGAL::Color ((unsigned char)(255 * m_points->point_set()->red(*it)),
|
||||||
(unsigned char)(255 * m_points->point_set()->green(*it)),
|
(unsigned char)(255 * m_points->point_set()->green(*it)),
|
||||||
(unsigned char)(255 * m_points->point_set()->blue(*it)) }};
|
(unsigned char)(255 * m_points->point_set()->blue(*it)));
|
||||||
|
|
||||||
m_points->point_set()->remove_colors();
|
m_points->point_set()->remove_colors();
|
||||||
}
|
}
|
||||||
|
|
@ -411,7 +411,7 @@ void Cluster_classification::backup_existing_colors_and_add_new()
|
||||||
|
|
||||||
void Cluster_classification::reset_colors()
|
void Cluster_classification::reset_colors()
|
||||||
{
|
{
|
||||||
if (m_color == Point_set::Property_map<Color>())
|
if (m_color == Point_set::Property_map<CGAL::Color>())
|
||||||
m_points->point_set()->remove_colors();
|
m_points->point_set()->remove_colors();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -606,7 +606,7 @@ int Cluster_classification::real_index_color() const
|
||||||
{
|
{
|
||||||
int out = m_index_color;
|
int out = m_index_color;
|
||||||
|
|
||||||
if (out == 0 && m_color == Point_set::Property_map<Color>())
|
if (out == 0 && m_color == Point_set::Property_map<CGAL::Color>())
|
||||||
out = -1;
|
out = -1;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
@ -642,7 +642,7 @@ void Cluster_classification::compute_features (std::size_t nb_scales, float voxe
|
||||||
if (normals)
|
if (normals)
|
||||||
normal_map = m_points->point_set()->normal_map();
|
normal_map = m_points->point_set()->normal_map();
|
||||||
|
|
||||||
bool colors = (m_color != Point_set::Property_map<Color>());
|
bool colors = (m_color != Point_set::Property_map<CGAL::Color>());
|
||||||
|
|
||||||
Point_set::Property_map<boost::uint8_t> echo_map;
|
Point_set::Property_map<boost::uint8_t> echo_map;
|
||||||
bool echo;
|
bool echo;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ class Cluster_classification : public Item_classification_base
|
||||||
public:
|
public:
|
||||||
typedef Kernel::Point_3 Point_3;
|
typedef Kernel::Point_3 Point_3;
|
||||||
typedef Kernel::Vector_3 Vector_3;
|
typedef Kernel::Vector_3 Vector_3;
|
||||||
typedef CGAL::Classification::RGB_Color Color;
|
|
||||||
|
|
||||||
typedef Point_set::Point_map Point_map;
|
typedef Point_set::Point_map Point_map;
|
||||||
typedef Point_set::Vector_map Vector_map;
|
typedef Point_set::Vector_map Vector_map;
|
||||||
|
|
@ -382,7 +381,10 @@ class Cluster_classification : public Item_classification_base
|
||||||
|
|
||||||
std::vector<Cluster> m_clusters;
|
std::vector<Cluster> m_clusters;
|
||||||
|
|
||||||
Point_set::Property_map<Color> m_color;
|
Point_set::Property_map<unsigned char> m_red;
|
||||||
|
Point_set::Property_map<unsigned char> m_green;
|
||||||
|
Point_set::Property_map<unsigned char> m_blue;
|
||||||
|
Point_set::Property_map<CGAL::Color> m_color;
|
||||||
Point_set::Property_map<int> m_cluster_id;
|
Point_set::Property_map<int> m_cluster_id;
|
||||||
Point_set::Property_map<int> m_training;
|
Point_set::Property_map<int> m_training;
|
||||||
Point_set::Property_map<int> m_classif;
|
Point_set::Property_map<int> m_classif;
|
||||||
|
|
|
||||||
|
|
@ -327,12 +327,12 @@ void Point_set_item_classification::backup_existing_colors_and_add_new()
|
||||||
{
|
{
|
||||||
if (m_points->point_set()->has_colors())
|
if (m_points->point_set()->has_colors())
|
||||||
{
|
{
|
||||||
m_color = m_points->point_set()->add_property_map<Color>("real_color").first;
|
m_color = m_points->point_set()->add_property_map<CGAL::Color>("real_color").first;
|
||||||
for (Point_set::const_iterator it = m_points->point_set()->begin();
|
for (Point_set::const_iterator it = m_points->point_set()->begin();
|
||||||
it != m_points->point_set()->first_selected(); ++ it)
|
it != m_points->point_set()->first_selected(); ++ it)
|
||||||
m_color[*it] = {{ (unsigned char)(255 * m_points->point_set()->red(*it)),
|
m_color[*it] = CGAL::Color((unsigned char)(255 * m_points->point_set()->red(*it)),
|
||||||
(unsigned char)(255 * m_points->point_set()->green(*it)),
|
(unsigned char)(255 * m_points->point_set()->green(*it)),
|
||||||
(unsigned char)(255 * m_points->point_set()->blue(*it)) }};
|
(unsigned char)(255 * m_points->point_set()->blue(*it)));
|
||||||
|
|
||||||
m_points->point_set()->remove_colors();
|
m_points->point_set()->remove_colors();
|
||||||
}
|
}
|
||||||
|
|
@ -342,7 +342,7 @@ void Point_set_item_classification::backup_existing_colors_and_add_new()
|
||||||
|
|
||||||
void Point_set_item_classification::reset_colors()
|
void Point_set_item_classification::reset_colors()
|
||||||
{
|
{
|
||||||
if (m_color == Point_set::Property_map<Color>())
|
if (m_color == Point_set::Property_map<CGAL::Color>())
|
||||||
m_points->point_set()->remove_colors();
|
m_points->point_set()->remove_colors();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -493,7 +493,7 @@ int Point_set_item_classification::real_index_color() const
|
||||||
{
|
{
|
||||||
int out = m_index_color;
|
int out = m_index_color;
|
||||||
|
|
||||||
if (out == 0 && m_color == Point_set::Property_map<Color>())
|
if (out == 0 && m_color == Point_set::Property_map<CGAL::Color>())
|
||||||
out = -1;
|
out = -1;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
@ -532,7 +532,7 @@ void Point_set_item_classification::compute_features (std::size_t nb_scales, flo
|
||||||
if (normals)
|
if (normals)
|
||||||
normal_map = m_points->point_set()->normal_map();
|
normal_map = m_points->point_set()->normal_map();
|
||||||
|
|
||||||
bool colors = (m_color != Point_set::Property_map<Color>());
|
bool colors = (m_color != Point_set::Property_map<CGAL::Color>());
|
||||||
|
|
||||||
Point_set::Property_map<boost::uint8_t> echo_map;
|
Point_set::Property_map<boost::uint8_t> echo_map;
|
||||||
bool echo;
|
bool echo;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ class Point_set_item_classification : public Item_classification_base
|
||||||
public:
|
public:
|
||||||
typedef Kernel::Point_3 Point_3;
|
typedef Kernel::Point_3 Point_3;
|
||||||
typedef Kernel::Vector_3 Vector_3;
|
typedef Kernel::Vector_3 Vector_3;
|
||||||
typedef CGAL::Classification::RGB_Color Color;
|
|
||||||
|
|
||||||
typedef Point_set::Point_map Point_map;
|
typedef Point_set::Point_map Point_map;
|
||||||
typedef Point_set::Vector_map Vector_map;
|
typedef Point_set::Vector_map Vector_map;
|
||||||
|
|
@ -398,9 +397,12 @@ class Point_set_item_classification : public Item_classification_base
|
||||||
|
|
||||||
std::vector<Cluster> m_clusters;
|
std::vector<Cluster> m_clusters;
|
||||||
|
|
||||||
|
Point_set::Property_map<unsigned char> m_red;
|
||||||
|
Point_set::Property_map<unsigned char> m_green;
|
||||||
|
Point_set::Property_map<unsigned char> m_blue;
|
||||||
|
Point_set::Property_map<CGAL::Color> m_color;
|
||||||
std::vector<std::vector<float> > m_label_probabilities;
|
std::vector<std::vector<float> > m_label_probabilities;
|
||||||
|
|
||||||
Point_set::Property_map<Color> m_color;
|
|
||||||
Point_set::Property_map<int> m_training;
|
Point_set::Property_map<int> m_training;
|
||||||
Point_set::Property_map<int> m_classif;
|
Point_set::Property_map<int> m_classif;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,34 +36,6 @@ public:
|
||||||
bool canSave(const CGAL::Three::Scene_item*);
|
bool canSave(const CGAL::Three::Scene_item*);
|
||||||
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
bool save(const CGAL::Three::Scene_item*, QFileInfo fileinfo);
|
||||||
|
|
||||||
private:
|
|
||||||
void set_vcolors(SMesh* smesh, const std::vector<CGAL::Color>& colors)
|
|
||||||
{
|
|
||||||
typedef SMesh SMesh;
|
|
||||||
typedef boost::graph_traits<SMesh>::vertex_descriptor vertex_descriptor;
|
|
||||||
SMesh::Property_map<vertex_descriptor, CGAL::Color> vcolors =
|
|
||||||
smesh->property_map<vertex_descriptor, CGAL::Color >("v:color").first;
|
|
||||||
bool created;
|
|
||||||
boost::tie(vcolors, created) = smesh->add_property_map<SMesh::Vertex_index,CGAL::Color>("v:color",CGAL::Color(0,0,0));
|
|
||||||
assert(colors.size()==smesh->number_of_vertices());
|
|
||||||
int color_id = 0;
|
|
||||||
for(vertex_descriptor vd : vertices(*smesh))
|
|
||||||
vcolors[vd] = colors[color_id++];
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_fcolors(SMesh* smesh, const std::vector<CGAL::Color>& colors)
|
|
||||||
{
|
|
||||||
typedef SMesh SMesh;
|
|
||||||
typedef boost::graph_traits<SMesh>::face_descriptor face_descriptor;
|
|
||||||
SMesh::Property_map<face_descriptor, CGAL::Color> fcolors =
|
|
||||||
smesh->property_map<face_descriptor, CGAL::Color >("f:color").first;
|
|
||||||
bool created;
|
|
||||||
boost::tie(fcolors, created) = smesh->add_property_map<SMesh::Face_index,CGAL::Color>("f:color",CGAL::Color(0,0,0));
|
|
||||||
assert(colors.size()==smesh->number_of_faces());
|
|
||||||
int color_id = 0;
|
|
||||||
for(face_descriptor fd : faces(*smesh))
|
|
||||||
fcolors[fd] = colors[color_id++];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Polyhedron_demo_ply_plugin::canLoad() const {
|
bool Polyhedron_demo_ply_plugin::canLoad() const {
|
||||||
|
|
@ -116,6 +88,23 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
||||||
|
|
||||||
if (input_is_mesh) // Open mesh or polygon soup
|
if (input_is_mesh) // Open mesh or polygon soup
|
||||||
{
|
{
|
||||||
|
// First try mesh
|
||||||
|
SMesh *surface_mesh = new SMesh();
|
||||||
|
std::string comments;
|
||||||
|
|
||||||
|
if (CGAL::read_ply (in, *surface_mesh, comments))
|
||||||
|
{
|
||||||
|
Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(surface_mesh);
|
||||||
|
sm_item->setName(fileinfo.completeBaseName());
|
||||||
|
sm_item->comments() = comments;
|
||||||
|
QApplication::restoreOverrideCursor();
|
||||||
|
return sm_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
in.clear();
|
||||||
|
in.seekg(0);
|
||||||
|
|
||||||
|
// else try polygon soup
|
||||||
std::vector<Kernel::Point_3> points;
|
std::vector<Kernel::Point_3> points;
|
||||||
std::vector<std::vector<std::size_t> > polygons;
|
std::vector<std::vector<std::size_t> > polygons;
|
||||||
std::vector<CGAL::Color> fcolors;
|
std::vector<CGAL::Color> fcolors;
|
||||||
|
|
@ -127,29 +116,11 @@ Polyhedron_demo_ply_plugin::load(QFileInfo fileinfo) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CGAL::Polygon_mesh_processing::is_polygon_soup_a_polygon_mesh (polygons))
|
Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item;
|
||||||
{
|
soup_item->setName(fileinfo.completeBaseName());
|
||||||
SMesh *surface_mesh = new SMesh();
|
soup_item->load (points, polygons, fcolors, vcolors);
|
||||||
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh (points, polygons,
|
QApplication::restoreOverrideCursor();
|
||||||
*surface_mesh);
|
return soup_item;
|
||||||
if(!(vcolors.empty()))
|
|
||||||
set_vcolors(surface_mesh, vcolors);
|
|
||||||
if(!(fcolors.empty()))
|
|
||||||
set_fcolors(surface_mesh, fcolors);
|
|
||||||
|
|
||||||
Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(surface_mesh);
|
|
||||||
sm_item->setName(fileinfo.completeBaseName());
|
|
||||||
QApplication::restoreOverrideCursor();
|
|
||||||
return sm_item;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Scene_polygon_soup_item* soup_item = new Scene_polygon_soup_item;
|
|
||||||
soup_item->setName(fileinfo.completeBaseName());
|
|
||||||
soup_item->load (points, polygons, fcolors, vcolors);
|
|
||||||
QApplication::restoreOverrideCursor();
|
|
||||||
return soup_item;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else // Open point set
|
else // Open point set
|
||||||
{
|
{
|
||||||
|
|
@ -212,10 +183,11 @@ bool Polyhedron_demo_ply_plugin::save(const CGAL::Three::Scene_item* item, QFile
|
||||||
return CGAL::write_PLY (out, soup_item->points(), soup_item->polygons());
|
return CGAL::write_PLY (out, soup_item->points(), soup_item->polygons());
|
||||||
|
|
||||||
// This plugin supports surface meshes
|
// This plugin supports surface meshes
|
||||||
const Scene_surface_mesh_item* sm_item =
|
Scene_surface_mesh_item* sm_item =
|
||||||
qobject_cast<const Scene_surface_mesh_item*>(item);
|
const_cast<Scene_surface_mesh_item*>(qobject_cast<const Scene_surface_mesh_item*>(item));
|
||||||
if (sm_item)
|
if (sm_item)
|
||||||
return CGAL::write_PLY (out, *(sm_item->polyhedron()));
|
return CGAL::write_ply (out, *(sm_item->polyhedron()), sm_item->comments());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -619,7 +619,7 @@ bool Scene_points_with_normal_item::read_ply_point_set(std::istream& stream)
|
||||||
d->m_points->clear();
|
d->m_points->clear();
|
||||||
|
|
||||||
bool ok = stream &&
|
bool ok = stream &&
|
||||||
CGAL::read_ply_point_set (stream, *(d->m_points), &(d->m_comments)) &&
|
CGAL::read_ply_point_set (stream, *(d->m_points), d->m_comments) &&
|
||||||
!isEmpty();
|
!isEmpty();
|
||||||
d->point_Slider->setValue(CGAL::Three::Three::getDefaultPointSize());
|
d->point_Slider->setValue(CGAL::Three::Three::getDefaultPointSize());
|
||||||
std::cerr << d->m_points->info();
|
std::cerr << d->m_points->info();
|
||||||
|
|
@ -653,7 +653,7 @@ bool Scene_points_with_normal_item::write_ply_point_set(std::ostream& stream, bo
|
||||||
if (binary)
|
if (binary)
|
||||||
CGAL::set_binary_mode (stream);
|
CGAL::set_binary_mode (stream);
|
||||||
|
|
||||||
CGAL::write_ply_point_set (stream, *(d->m_points), &(d->m_comments));
|
CGAL::write_ply_point_set (stream, *(d->m_points), d->m_comments);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,8 @@ struct Scene_surface_mesh_item_priv{
|
||||||
mutable QList<double> text_ids;
|
mutable QList<double> text_ids;
|
||||||
mutable std::vector<TextItem*> targeted_id;
|
mutable std::vector<TextItem*> targeted_id;
|
||||||
|
|
||||||
|
std::string comments;
|
||||||
|
|
||||||
mutable bool has_fpatch_id;
|
mutable bool has_fpatch_id;
|
||||||
mutable bool has_feature_edges;
|
mutable bool has_feature_edges;
|
||||||
mutable bool floated;
|
mutable bool floated;
|
||||||
|
|
@ -1050,6 +1052,9 @@ Scene_surface_mesh_item::~Scene_surface_mesh_item()
|
||||||
SMesh* Scene_surface_mesh_item::polyhedron() { return d->smesh_; }
|
SMesh* Scene_surface_mesh_item::polyhedron() { return d->smesh_; }
|
||||||
const SMesh* Scene_surface_mesh_item::polyhedron() const { return d->smesh_; }
|
const SMesh* Scene_surface_mesh_item::polyhedron() const { return d->smesh_; }
|
||||||
|
|
||||||
|
std::string& Scene_surface_mesh_item::comments() { return d->comments; }
|
||||||
|
const std::string& Scene_surface_mesh_item::comments() const { return d->comments; }
|
||||||
|
|
||||||
void Scene_surface_mesh_item::compute_bbox()const
|
void Scene_surface_mesh_item::compute_bbox()const
|
||||||
{
|
{
|
||||||
SMesh::Property_map<vertex_descriptor, Point_3> pprop = d->smesh_->points();
|
SMesh::Property_map<vertex_descriptor, Point_3> pprop = d->smesh_->points();
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,10 @@ public:
|
||||||
Face_graph* face_graph() { return polyhedron(); }
|
Face_graph* face_graph() { return polyhedron(); }
|
||||||
const Face_graph* face_graph() const { return polyhedron(); }
|
const Face_graph* face_graph() const { return polyhedron(); }
|
||||||
|
|
||||||
|
// Gets PLY comments (empty if mesh not originated from PLY input)
|
||||||
|
std::string& comments();
|
||||||
|
const std::string& comments() const;
|
||||||
|
|
||||||
void invalidate_aabb_tree();
|
void invalidate_aabb_tree();
|
||||||
void invalidateOpenGLBuffers()Q_DECL_OVERRIDE;
|
void invalidateOpenGLBuffers()Q_DECL_OVERRIDE;
|
||||||
void invalidate(Gl_data_names name);
|
void invalidate(Gl_data_names name);
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,6 @@ typedef Polyhedron::Halfedge_handle Halfedge_handle;
|
||||||
int main() {
|
int main() {
|
||||||
Polyhedron P;
|
Polyhedron P;
|
||||||
Halfedge_handle h = P.make_tetrahedron();
|
Halfedge_handle h = P.make_tetrahedron();
|
||||||
h->facet()->color = CGAL::RED;
|
h->facet()->color = CGAL::red();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,6 @@ typedef Polyhedron::Halfedge_handle Halfedge_handle;
|
||||||
int main() {
|
int main() {
|
||||||
Polyhedron P;
|
Polyhedron P;
|
||||||
Halfedge_handle h = P.make_tetrahedron();
|
Halfedge_handle h = P.make_tetrahedron();
|
||||||
h->vertex()->color = CGAL::RED;
|
h->vertex()->color = CGAL::red();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ int main() {
|
||||||
Polyhedron P;
|
Polyhedron P;
|
||||||
P.make_tetrahedron( p,q,r,s);
|
P.make_tetrahedron( p,q,r,s);
|
||||||
CGAL::Geomview_stream geo;
|
CGAL::Geomview_stream geo;
|
||||||
geo << CGAL::GREEN << P;
|
geo << CGAL::green() << P;
|
||||||
|
|
||||||
// wait for a mouse click.
|
// wait for a mouse click.
|
||||||
Point click;
|
Point click;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef CGAL_IO_PLY_READER_H
|
#ifndef CGAL_IO_PLY_READER_H
|
||||||
#define CGAL_IO_PLY_READER_H
|
#define CGAL_IO_PLY_READER_H
|
||||||
|
|
||||||
#include <CGAL/IO/read_ply_points.h>
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
namespace CGAL{
|
namespace CGAL{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
#ifndef CGAL_IO_PLY_WRITER_H
|
#ifndef CGAL_IO_PLY_WRITER_H
|
||||||
#define CGAL_IO_PLY_WRITER_H
|
#define CGAL_IO_PLY_WRITER_H
|
||||||
|
|
||||||
#include <CGAL/IO/write_ply_points.h>
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
namespace CGAL{
|
namespace CGAL{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ public:
|
||||||
mWriter (out)
|
mWriter (out)
|
||||||
,mDefaultDxfColor (255)
|
,mDefaultDxfColor (255)
|
||||||
,mDxfColor (255)
|
,mDxfColor (255)
|
||||||
,mCgalColor (WHITE)
|
,mCgalColor (white())
|
||||||
,mLayer ("0")
|
,mLayer ("0")
|
||||||
{
|
{
|
||||||
setup_initial_color_table();
|
setup_initial_color_table();
|
||||||
|
|
@ -305,15 +305,15 @@ protected:
|
||||||
|
|
||||||
void setup_initial_color_table()
|
void setup_initial_color_table()
|
||||||
{
|
{
|
||||||
define_color(BLACK,0);
|
define_color(black(),0);
|
||||||
define_color(RED,1);
|
define_color(red(),1);
|
||||||
define_color(YELLOW,2);
|
define_color(yellow(),2);
|
||||||
define_color(GREEN,3);
|
define_color(green(),3);
|
||||||
define_color(PURPLE,4);
|
define_color(purple(),4);
|
||||||
define_color(BLUE,5);
|
define_color(blue(),5);
|
||||||
define_color(VIOLET,6);
|
define_color(violet(),6);
|
||||||
define_color(WHITE,7);
|
define_color(white(),7);
|
||||||
define_color(GRAY,8);
|
define_color(gray(),8);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -547,25 +547,25 @@ void dump_to_dxf ( TestCase const& aCase )
|
||||||
{
|
{
|
||||||
if ( sVerbose )
|
if ( sVerbose )
|
||||||
cout << " Dumping input region. " << endl ;
|
cout << " Dumping input region. " << endl ;
|
||||||
dump_region_to_dxf(*aCase.Inner.Input,BLUE,"Input",lDxf);
|
dump_region_to_dxf(*aCase.Inner.Input,blue(),"Input",lDxf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( aCase.Inner.PartialSkeleton )
|
if ( aCase.Inner.PartialSkeleton )
|
||||||
{
|
{
|
||||||
if ( sVerbose )
|
if ( sVerbose )
|
||||||
cout << " Dumping inner skeleton." << endl ;
|
cout << " Dumping inner skeleton." << endl ;
|
||||||
dump_skeleton_to_dxf(*aCase.Inner.PartialSkeleton,YELLOW,GREEN,PURPLE,GRAY,"InnerSkeleton",lDxf);
|
dump_skeleton_to_dxf(*aCase.Inner.PartialSkeleton,yellow(),green(),purple(),gray(),"InnerSkeleton",lDxf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( aCase.Outer.PartialSkeleton )
|
if ( aCase.Outer.PartialSkeleton )
|
||||||
{
|
{
|
||||||
if ( sVerbose )
|
if ( sVerbose )
|
||||||
cout << " Dumping outer skeleton." << endl ;
|
cout << " Dumping outer skeleton." << endl ;
|
||||||
dump_skeleton_to_dxf(*aCase.Outer.PartialSkeleton,YELLOW,GREEN,PURPLE,GRAY,"OuterSkeleton",lDxf);
|
dump_skeleton_to_dxf(*aCase.Outer.PartialSkeleton,yellow(),green(),purple(),gray(),"OuterSkeleton",lDxf);
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_region_to_dxf(aCase.Inner.Contours,GRAY,"InnerOffset",lDxf);
|
dump_region_to_dxf(aCase.Inner.Contours,gray(),"InnerOffset",lDxf);
|
||||||
dump_region_to_dxf(aCase.Outer.Contours,GRAY,"OuterOffset",lDxf);
|
dump_region_to_dxf(aCase.Outer.Contours,gray(),"OuterOffset",lDxf);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,107 +0,0 @@
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\ingroup PkgStreamSupportRef
|
|
||||||
|
|
||||||
An object of the class `Color` is a color available
|
|
||||||
for drawing operations in many \cgal output streams.
|
|
||||||
Each color is defined by a triple of unsigned chars `(r,g,b)` with
|
|
||||||
0 \f$\le\f$ r,g,b \f$ \le \f$ 255, the so-called <I>rgb-value</I> of the color.
|
|
||||||
|
|
||||||
\sa `CGAL::Geomview_stream`
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Color {
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// \name Creation
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
/*!
|
|
||||||
creates a color with rgb-value `(0,0,0)`, i.e.\ black.
|
|
||||||
*/
|
|
||||||
Color();
|
|
||||||
|
|
||||||
/*!
|
|
||||||
creates a color with rgb-value `(red,green,blue)`.
|
|
||||||
*/
|
|
||||||
Color(unsigned char red, unsigned char green, unsigned char blue);
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/// \name Operations
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Test for equality: Two colors are equal, iff their
|
|
||||||
rgb-values are equal.
|
|
||||||
*/
|
|
||||||
bool operator==(const Color &q) const;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Test for inequality.
|
|
||||||
*/
|
|
||||||
bool operator!=(const Color &q) const;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
returns the red component of `c`.
|
|
||||||
*/
|
|
||||||
unsigned char red() const;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
returns the green component of `c`.
|
|
||||||
*/
|
|
||||||
unsigned char green() const;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
returns the blue component of `c`.
|
|
||||||
*/
|
|
||||||
unsigned char blue() const;
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/// \name Constants
|
|
||||||
/// The following constants are predefined:
|
|
||||||
/// @{
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Black.
|
|
||||||
*/
|
|
||||||
const Color BLACK = Color(0, 0, 0);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
White.
|
|
||||||
*/
|
|
||||||
const Color WHITE = Color(255, 255, 255);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Red.
|
|
||||||
*/
|
|
||||||
const Color RED = Color(255, 0, 0);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Green.
|
|
||||||
*/
|
|
||||||
const Color GREEN = Color(0, 255, 0);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Blue.
|
|
||||||
*/
|
|
||||||
const Color BLUE = Color(0, 0, 255);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Violet.
|
|
||||||
*/
|
|
||||||
const Color VIOLET = Color(255, 0, 255);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Orange.
|
|
||||||
*/
|
|
||||||
const Color ORANGE = Color(255, 170, 0);
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
}; /* end Color */
|
|
||||||
} /* end namespace CGAL */
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
|
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
|
||||||
|
|
||||||
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - IO Streams"
|
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - IO Streams"
|
||||||
|
INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/IO/Color.h
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,74 +23,327 @@
|
||||||
//
|
//
|
||||||
// Author(s) : Andreas Fabri
|
// Author(s) : Andreas Fabri
|
||||||
|
|
||||||
#include <CGAL/config.h>
|
|
||||||
|
|
||||||
#ifndef CGAL_COLOR_H
|
#ifndef CGAL_COLOR_H
|
||||||
#define CGAL_COLOR_H
|
#define CGAL_COLOR_H
|
||||||
|
|
||||||
|
#include <CGAL/config.h>
|
||||||
|
#include <CGAL/array.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
class Color {
|
|
||||||
public:
|
|
||||||
Color(): _red(120), _green(120), _blue(120), _alpha(120) {}
|
|
||||||
Color(unsigned char red,
|
|
||||||
unsigned char green,
|
|
||||||
unsigned char blue,
|
|
||||||
unsigned char alpha = 120)
|
|
||||||
: _red(red), _green(green), _blue(blue), _alpha(alpha)
|
|
||||||
{}
|
|
||||||
|
|
||||||
unsigned char r() const {return _red;}
|
/*!
|
||||||
unsigned char g() const {return _green;}
|
\ingroup PkgStreamSupportRef
|
||||||
unsigned char b() const {return _blue;}
|
|
||||||
|
|
||||||
unsigned char red() const {return _red;}
|
An object of the class `Color` is a color available for drawing
|
||||||
unsigned char green() const {return _green;}
|
operations in many \cgal output streams. Each color is defined by a
|
||||||
unsigned char blue() const {return _blue;}
|
4 unsigned chars `(r,g,b,a)` with 0 \f$\le\f$ r,g,b,a \f$ \le \f$
|
||||||
unsigned char alpha() const {return _alpha;}
|
255, the so-called <I>rgba-value</I> of the color.
|
||||||
void set_alpha(unsigned char a) {_alpha=a;}
|
|
||||||
bool operator==(const Color &c) const
|
|
||||||
{
|
|
||||||
return ( (red() == c.red()) &&
|
|
||||||
(green() == c.green()) &&
|
|
||||||
(blue() == c.blue()) );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const Color &c) const
|
The alpha parameter (representing transparency) is often ignored and
|
||||||
{
|
left to its default value (255 = no transparency), which is why we
|
||||||
return !( (*this) == c);
|
often refer to the <I>rgb-value</I> of the color.
|
||||||
}
|
|
||||||
|
|
||||||
|
\sa `CGAL::Geomview_stream`
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Color
|
||||||
|
{
|
||||||
private:
|
private:
|
||||||
unsigned char _red;
|
|
||||||
unsigned char _green;
|
cpp11::array<unsigned char, 4> m_data;
|
||||||
unsigned char _blue;
|
|
||||||
unsigned char _alpha;
|
public:
|
||||||
|
|
||||||
|
/// \name Creation
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
creates a color with rgba-value `(0,0,0,255)`, i.e.\ black.
|
||||||
|
*/
|
||||||
|
Color()
|
||||||
|
{
|
||||||
|
set_rgb (0, 0, 0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
creates a color with rgba-value `(red,green,blue,alpha)`.
|
||||||
|
*/
|
||||||
|
Color(unsigned char red,
|
||||||
|
unsigned char green,
|
||||||
|
unsigned char blue,
|
||||||
|
unsigned char alpha = 255)
|
||||||
|
{
|
||||||
|
set_rgb (red, green, blue, alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// \name Component Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns the red component.
|
||||||
|
*/
|
||||||
|
unsigned char red() const { return m_data[0]; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns a reference on the red component.
|
||||||
|
*/
|
||||||
|
unsigned char& red() { return m_data[0]; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns the green component.
|
||||||
|
*/
|
||||||
|
unsigned char green() const { return m_data[1]; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns a reference on the green component.
|
||||||
|
*/
|
||||||
|
unsigned char& green() { return m_data[1]; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns the blue component.
|
||||||
|
*/
|
||||||
|
unsigned char blue() const { return m_data[2]; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns a reference on the blue component.
|
||||||
|
*/
|
||||||
|
unsigned char& blue() { return m_data[2]; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns the alpha component.
|
||||||
|
*/
|
||||||
|
unsigned char alpha() const { return m_data[3]; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns a reference on the alpha component.
|
||||||
|
*/
|
||||||
|
unsigned char& alpha() { return m_data[3]; }
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
unsigned char r() const { return red(); }
|
||||||
|
unsigned char g() const { return green(); }
|
||||||
|
unsigned char b() const { return blue(); }
|
||||||
|
unsigned char a() const { return alpha(); }
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// \name Array Access
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns the \f$i^{th}\f$ component of the rgb color (the
|
||||||
|
\f$0^{th}\f$ is red, the \f$1^{st}\f$ is blue, etc.).
|
||||||
|
*/
|
||||||
|
unsigned char operator[] (std::size_t i) const { return m_data[i]; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns a reference on the \f$i^{th}\f$ component of `c` (the
|
||||||
|
\f$0^{th}\f$ is red, the \f$1^{st}\f$ is blue, etc.).
|
||||||
|
*/
|
||||||
|
unsigned char& operator[] (std::size_t i) { return m_data[i]; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns the array with rgba values.
|
||||||
|
*/
|
||||||
|
const cpp11::array<unsigned char, 4>& to_rgba() const { return m_data; }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
returns the array with rgb values.
|
||||||
|
*/
|
||||||
|
const cpp11::array<unsigned char, 3>& to_rgb() const
|
||||||
|
{
|
||||||
|
return reinterpret_cast<const cpp11::array<unsigned char, 3>&>(m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
computes the hsv (hue, saturation, value) values and returns an
|
||||||
|
array representing them as float values between 0 and 1.
|
||||||
|
*/
|
||||||
|
cpp11::array<double, 3> to_hsv() const
|
||||||
|
{
|
||||||
|
double r = (double)(m_data[0]) / 255.;
|
||||||
|
double g = (double)(m_data[1]) / 255.;
|
||||||
|
double b = (double)(m_data[2]) / 255.;
|
||||||
|
double Cmax = (std::max) (r, (std::max) (g, b));
|
||||||
|
double Cmin = (std::min) (r, (std::min) (g, b));
|
||||||
|
double delta = Cmax - Cmin;
|
||||||
|
double H = 0.;
|
||||||
|
|
||||||
|
if (delta != 0.)
|
||||||
|
{
|
||||||
|
if (Cmax == r)
|
||||||
|
H = 60. * ((g - b) / delta);
|
||||||
|
else if (Cmax == g)
|
||||||
|
H = 60. * (((b - r) / delta) + 2.);
|
||||||
|
else
|
||||||
|
H = 60. * (((r - g) / delta) + 4.);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (H < 0.) H += 360.;
|
||||||
|
|
||||||
|
double S = (Cmax == 0. ? 0. : 100. * (delta / Cmax));
|
||||||
|
double V = 100. * Cmax;
|
||||||
|
|
||||||
|
return make_array(H,S,V);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \name Modification
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
replaces the rgb values of the colors by the one given as parameters.
|
||||||
|
*/
|
||||||
|
void set_rgb (unsigned char red,
|
||||||
|
unsigned char green,
|
||||||
|
unsigned char blue,
|
||||||
|
unsigned char alpha = 255)
|
||||||
|
{
|
||||||
|
m_data[0] = red;
|
||||||
|
m_data[1] = green;
|
||||||
|
m_data[2] = blue;
|
||||||
|
m_data[3] = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
replaces the rgb values of the colors by the conversion to rgb of
|
||||||
|
the hsv values given as parameters.
|
||||||
|
|
||||||
|
Double values given as parameters should take range between 0 and 1.
|
||||||
|
*/
|
||||||
|
void set_hsv (double hue,
|
||||||
|
double saturation,
|
||||||
|
double value,
|
||||||
|
unsigned char alpha = 255)
|
||||||
|
{
|
||||||
|
saturation /= 100.;
|
||||||
|
value /= 100.;
|
||||||
|
double C = value*saturation;
|
||||||
|
int hh = (int)(hue/60.);
|
||||||
|
double X = C * (1-std::abs (hh % 2 - 1));
|
||||||
|
double r = 0, g = 0, b = 0;
|
||||||
|
|
||||||
|
if( hh>=0 && hh<1 )
|
||||||
|
{
|
||||||
|
r = C;
|
||||||
|
g = X;
|
||||||
|
}
|
||||||
|
else if( hh>=1 && hh<2 )
|
||||||
|
{
|
||||||
|
r = X;
|
||||||
|
g = C;
|
||||||
|
}
|
||||||
|
else if( hh>=2 && hh<3 )
|
||||||
|
{
|
||||||
|
g = C;
|
||||||
|
b = X;
|
||||||
|
}
|
||||||
|
else if( hh>=3 && hh<4 )
|
||||||
|
{
|
||||||
|
g = X;
|
||||||
|
b = C;
|
||||||
|
}
|
||||||
|
else if( hh>=4 && hh<5 )
|
||||||
|
{
|
||||||
|
r = X;
|
||||||
|
b = C;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = C;
|
||||||
|
b = X;
|
||||||
|
}
|
||||||
|
double m = value-C;
|
||||||
|
r += m;
|
||||||
|
g += m;
|
||||||
|
b += m;
|
||||||
|
r *= 255.0;
|
||||||
|
g *= 255.0;
|
||||||
|
b *= 255.0;
|
||||||
|
|
||||||
|
m_data[0] = (unsigned char)r;
|
||||||
|
m_data[1] = (unsigned char)g;
|
||||||
|
m_data[2] = (unsigned char)b;
|
||||||
|
m_data[3] = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifndef CGAL_HEADER_ONLY
|
/*!
|
||||||
|
|
||||||
CGAL_EXPORT extern const Color BLACK ;
|
Constructs Color(0,0,0).
|
||||||
CGAL_EXPORT extern const Color WHITE ;
|
\relates Color
|
||||||
CGAL_EXPORT extern const Color GRAY ;
|
*/
|
||||||
|
inline Color black() { return Color(0,0,0); }
|
||||||
|
|
||||||
CGAL_EXPORT extern const Color RED ;
|
/*!
|
||||||
CGAL_EXPORT extern const Color GREEN ;
|
Constructs Color(0,0,255).
|
||||||
|
\relates Color
|
||||||
|
*/
|
||||||
|
inline Color blue() { return Color(0,0,255); }
|
||||||
|
|
||||||
CGAL_EXPORT extern const Color DEEPBLUE;
|
/*!
|
||||||
CGAL_EXPORT extern const Color BLUE ;
|
Constructs Color(10,0,100).
|
||||||
CGAL_EXPORT extern const Color PURPLE ;
|
\relates Color
|
||||||
CGAL_EXPORT extern const Color VIOLET ;
|
*/
|
||||||
|
inline Color deep_blue() { return Color(10,0,100); }
|
||||||
|
|
||||||
CGAL_EXPORT extern const Color ORANGE ;
|
/*!
|
||||||
CGAL_EXPORT extern const Color YELLOW ;
|
Constructs Color(100,100,100).
|
||||||
|
\relates Color
|
||||||
|
*/
|
||||||
|
inline Color gray() { return Color(100,100,100); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs Color(0,255,0).
|
||||||
|
\relates Color
|
||||||
|
*/
|
||||||
|
inline Color green() { return Color(0,255,0); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs Color(235,150,0).
|
||||||
|
\relates Color
|
||||||
|
*/
|
||||||
|
inline Color orange() { return Color(235,150,0); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs Color(100,0,70).
|
||||||
|
\relates Color
|
||||||
|
*/
|
||||||
|
inline Color purple() { return Color(100,0,70); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs Color(255,0,0).
|
||||||
|
\relates Color
|
||||||
|
*/
|
||||||
|
inline Color red() { return Color(255,0,0); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs Color(255,0,255).
|
||||||
|
\relates Color
|
||||||
|
*/
|
||||||
|
inline Color violet() { return Color(255,0,255); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs Color(255,255,255).
|
||||||
|
\relates Color
|
||||||
|
*/
|
||||||
|
inline Color white() { return Color(255,255,255); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs Color(255,255,0).
|
||||||
|
\relates Color
|
||||||
|
*/
|
||||||
|
inline Color yellow() { return Color(255,255,0); }
|
||||||
|
|
||||||
#endif // CGAL_HEADER_ONLY
|
|
||||||
|
|
||||||
} //namespace CGAL
|
} //namespace CGAL
|
||||||
|
|
||||||
#ifdef CGAL_HEADER_ONLY
|
|
||||||
#include <CGAL/IO/Color_impl.h>
|
|
||||||
#endif // CGAL_HEADER_ONLY
|
|
||||||
|
|
||||||
#endif // CGAL_COLOR_H
|
#endif // CGAL_COLOR_H
|
||||||
|
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
// Copyright (c) 1997
|
|
||||||
// Utrecht University (The Netherlands),
|
|
||||||
// ETH Zurich (Switzerland),
|
|
||||||
// INRIA Sophia-Antipolis (France),
|
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU Lesser General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 3 of the License,
|
|
||||||
// or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
// SPDX-License-Identifier: LGPL-3.0+
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Andreas Fabri, Hervé Brönnimann
|
|
||||||
|
|
||||||
namespace CGAL {
|
|
||||||
|
|
||||||
const Color BLACK = Color(0, 0, 0);
|
|
||||||
const Color WHITE = Color(255, 255, 255);
|
|
||||||
const Color GRAY = Color(100,100,100);
|
|
||||||
|
|
||||||
const Color GREEN = Color(0, 255, 0);
|
|
||||||
|
|
||||||
const Color DEEPBLUE = Color(10, 0, 100);
|
|
||||||
const Color BLUE = Color(0, 0, 255);
|
|
||||||
const Color VIOLET = Color(255, 0, 255);
|
|
||||||
const Color PURPLE = Color(100, 0, 70);
|
|
||||||
|
|
||||||
const Color RED = Color(255, 0, 0);
|
|
||||||
const Color ORANGE = Color(235, 150, 0);
|
|
||||||
const Color YELLOW = Color(255, 255, 0);
|
|
||||||
|
|
||||||
} //namespace CGAL
|
|
||||||
|
|
@ -0,0 +1,973 @@
|
||||||
|
// Copyright (c) 2015 Geometry Factory
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: GPL-3.0+
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_IO_PLY_H
|
||||||
|
#define CGAL_IO_PLY_H
|
||||||
|
|
||||||
|
#include <CGAL/Kernel_traits.h>
|
||||||
|
#include <CGAL/IO/io.h>
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define TRY_TO_GENERATE_PROPERTY(STD_TYPE, T_TYPE, TYPE) \
|
||||||
|
if (type == STD_TYPE || type == T_TYPE) \
|
||||||
|
m_elements.back().add_property (new PLY_read_typed_number< TYPE > (name, format))
|
||||||
|
|
||||||
|
#define TRY_TO_GENERATE_SIZED_LIST_PROPERTY(STD_SIZE_TYPE, T_SIZE_TYPE, SIZE_TYPE, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \
|
||||||
|
if ((size_type == STD_SIZE_TYPE || size_type == T_SIZE_TYPE) && \
|
||||||
|
(index_type == STD_INDEX_TYPE || index_type == T_INDEX_TYPE)) \
|
||||||
|
m_elements.back().add_property (new PLY_read_typed_list_with_typed_size< SIZE_TYPE , INDEX_TYPE > (name, format))
|
||||||
|
|
||||||
|
#define TRY_TO_GENERATE_LIST_PROPERTY(STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE) \
|
||||||
|
TRY_TO_GENERATE_SIZED_LIST_PROPERTY("uchar", "uint8", boost::uint8_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE); \
|
||||||
|
else TRY_TO_GENERATE_SIZED_LIST_PROPERTY("ushort", "uint16", boost::uint16_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE); \
|
||||||
|
else TRY_TO_GENERATE_SIZED_LIST_PROPERTY("uint", "uint32", boost::uint32_t, STD_INDEX_TYPE, T_INDEX_TYPE, INDEX_TYPE)
|
||||||
|
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct PLY_property
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
const char* name;
|
||||||
|
PLY_property (const char* name) : name (name) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use a double property for all kernels...
|
||||||
|
template <typename FT> struct Convert_FT { typedef double type; };
|
||||||
|
// ...except if kernel uses type float
|
||||||
|
template <> struct Convert_FT<float> { typedef float type; };
|
||||||
|
|
||||||
|
template <typename PointOrVectorMap>
|
||||||
|
struct Get_FT_from_map
|
||||||
|
{
|
||||||
|
typedef typename Convert_FT
|
||||||
|
<typename Kernel_traits
|
||||||
|
<typename boost::property_traits
|
||||||
|
<PointOrVectorMap>::value_type>::Kernel::FT>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename PointMap>
|
||||||
|
std::tuple<PointMap,
|
||||||
|
typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3,
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>,
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>,
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type> >
|
||||||
|
make_ply_point_reader(PointMap point_map)
|
||||||
|
{
|
||||||
|
return std::make_tuple (point_map, typename Kernel_traits<typename PointMap::value_type>::Kernel::Construct_point_3(),
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>("x"),
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>("y"),
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>("z"));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VectorMap>
|
||||||
|
std::tuple<VectorMap,
|
||||||
|
typename Kernel_traits<typename VectorMap::value_type>::Kernel::Construct_vector_3,
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>,
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>,
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type> >
|
||||||
|
make_ply_normal_reader(VectorMap normal_map)
|
||||||
|
{
|
||||||
|
return std::make_tuple (normal_map, typename Kernel_traits<typename VectorMap::value_type>::Kernel::Construct_vector_3(),
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>("nx"),
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>("ny"),
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>("nz"));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PointMap>
|
||||||
|
std::tuple<PointMap,
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>,
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>,
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type> >
|
||||||
|
make_ply_point_writer(PointMap point_map)
|
||||||
|
{
|
||||||
|
return std::make_tuple (point_map,
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>("x"),
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>("y"),
|
||||||
|
PLY_property<typename Get_FT_from_map<PointMap>::type>("z"));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VectorMap>
|
||||||
|
std::tuple<VectorMap,
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>,
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>,
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type> >
|
||||||
|
make_ply_normal_writer(VectorMap normal_map)
|
||||||
|
{
|
||||||
|
return std::make_tuple (normal_map,
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>("nx"),
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>("ny"),
|
||||||
|
PLY_property<typename Get_FT_from_map<VectorMap>::type>("nz"));
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
namespace PLY {
|
||||||
|
|
||||||
|
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 void get (std::istream& stream) const = 0;
|
||||||
|
|
||||||
|
// The two following functions prevent the stream to only extract
|
||||||
|
// ONE character (= what the types char imply) by requiring
|
||||||
|
// explicitely an integer object when reading the stream
|
||||||
|
void read_ascii (std::istream& stream, char& c) const
|
||||||
|
{
|
||||||
|
short s;
|
||||||
|
stream >> s;
|
||||||
|
c = static_cast<char>(s);
|
||||||
|
}
|
||||||
|
void read_ascii (std::istream& stream, signed char& c) const
|
||||||
|
{
|
||||||
|
short s;
|
||||||
|
stream >> s;
|
||||||
|
c = static_cast<signed char>(s);
|
||||||
|
}
|
||||||
|
void read_ascii (std::istream& stream, unsigned char& c) const
|
||||||
|
{
|
||||||
|
unsigned short s;
|
||||||
|
stream >> s;
|
||||||
|
c = static_cast<unsigned char>(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_ascii (std::istream& stream, float& t) const
|
||||||
|
{
|
||||||
|
stream >> iformat(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_ascii (std::istream& stream, double& t) const
|
||||||
|
{
|
||||||
|
stream >> iformat(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default template when Type is not a char type
|
||||||
|
template <typename Type>
|
||||||
|
void read_ascii (std::istream& stream, Type& t) const
|
||||||
|
{
|
||||||
|
stream >> t;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
Type read (std::istream& stream) const
|
||||||
|
{
|
||||||
|
if (m_format == 0) // Ascii
|
||||||
|
{
|
||||||
|
Type t;
|
||||||
|
read_ascii (stream, t);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
else // Binary (2 = little endian)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
char uChar[sizeof (Type)];
|
||||||
|
Type type;
|
||||||
|
} buffer;
|
||||||
|
|
||||||
|
std::size_t size = sizeof (Type);
|
||||||
|
|
||||||
|
stream.read(buffer.uChar, size);
|
||||||
|
|
||||||
|
if (m_format == 2) // Big endian
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < size / 2; ++ i)
|
||||||
|
{
|
||||||
|
unsigned char tmp = buffer.uChar[i];
|
||||||
|
buffer.uChar[i] = buffer.uChar[size - 1 - i];
|
||||||
|
buffer.uChar[size - 1 - i] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer.type;
|
||||||
|
}
|
||||||
|
return Type();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class PLY_read_typed_number : public PLY_read_number
|
||||||
|
{
|
||||||
|
mutable Type m_buffer;
|
||||||
|
public:
|
||||||
|
PLY_read_typed_number (std::string name, std::size_t format)
|
||||||
|
: PLY_read_number (name, format)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void get (std::istream& stream) const
|
||||||
|
{
|
||||||
|
m_buffer = (this->read<Type> (stream));
|
||||||
|
}
|
||||||
|
const Type& buffer() const
|
||||||
|
{
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
class PLY_read_typed_list : public PLY_read_number
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
mutable std::vector<Type> m_buffer;
|
||||||
|
public:
|
||||||
|
PLY_read_typed_list (std::string name, std::size_t format)
|
||||||
|
: PLY_read_number (name, format)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void get (std::istream& stream) const = 0;
|
||||||
|
|
||||||
|
const std::vector<Type>& buffer() const
|
||||||
|
{
|
||||||
|
return m_buffer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename SizeType, typename IndexType>
|
||||||
|
class PLY_read_typed_list_with_typed_size
|
||||||
|
: public PLY_read_typed_list<IndexType>
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
PLY_read_typed_list_with_typed_size (std::string name, std::size_t format)
|
||||||
|
: PLY_read_typed_list<IndexType> (name, format)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void get (std::istream& stream) const
|
||||||
|
{
|
||||||
|
std::size_t size = static_cast<std::size_t>(this->template read<SizeType>(stream));
|
||||||
|
this->m_buffer.resize (size);
|
||||||
|
for (std::size_t i = 0; i < size; ++ i)
|
||||||
|
this->m_buffer[i] = this->template read<IndexType> (stream);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PLY_element
|
||||||
|
{
|
||||||
|
std::string m_name;
|
||||||
|
std::size_t m_number;
|
||||||
|
|
||||||
|
std::vector<PLY_read_number*> m_properties;
|
||||||
|
public:
|
||||||
|
|
||||||
|
PLY_element (const std::string& name, std::size_t number)
|
||||||
|
: m_name (name), m_number (number)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
PLY_element (const PLY_element& other)
|
||||||
|
: m_name (other.m_name), m_number (other.m_number), m_properties (other.m_properties)
|
||||||
|
{
|
||||||
|
const_cast<PLY_element&>(other).m_properties.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
PLY_element& operator= (const PLY_element& other)
|
||||||
|
{
|
||||||
|
m_name = other.m_name;
|
||||||
|
m_number = other.m_number;
|
||||||
|
m_properties = other.m_properties;
|
||||||
|
const_cast<PLY_element&>(other).m_properties.clear();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~PLY_element()
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < m_properties.size(); ++ i)
|
||||||
|
delete m_properties[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& name() const { return m_name; }
|
||||||
|
std::size_t number_of_items() const { return m_number; }
|
||||||
|
std::size_t number_of_properties() const { return m_properties.size(); }
|
||||||
|
|
||||||
|
PLY_read_number* property (std::size_t idx) { return m_properties[idx]; }
|
||||||
|
|
||||||
|
void add_property (PLY_read_number* read_number)
|
||||||
|
{
|
||||||
|
m_properties.push_back (read_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
bool has_property (const char* tag)
|
||||||
|
{
|
||||||
|
return has_property (tag, Type());
|
||||||
|
}
|
||||||
|
template <typename Type>
|
||||||
|
bool has_property (const char* tag, const std::vector<Type>&)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < number_of_properties(); ++ i)
|
||||||
|
if (m_properties[i]->name () == tag)
|
||||||
|
return (dynamic_cast<PLY_read_typed_list<Type>*>(m_properties[i]) != NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
bool has_property (const char* tag, Type)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < number_of_properties(); ++ i)
|
||||||
|
if (m_properties[i]->name () == tag)
|
||||||
|
return (dynamic_cast<PLY_read_typed_number<Type>*>(m_properties[i]) != NULL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool has_property (const char* tag, double)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < number_of_properties(); ++ i)
|
||||||
|
if (m_properties[i]->name () == tag)
|
||||||
|
return (dynamic_cast<PLY_read_typed_number<double>*>(m_properties[i]) != NULL
|
||||||
|
|| dynamic_cast<PLY_read_typed_number<float>*>(m_properties[i]) != NULL);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
void assign (Type& t, const char* tag)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < number_of_properties (); ++ i)
|
||||||
|
if (m_properties[i]->name () == tag)
|
||||||
|
{
|
||||||
|
PLY_read_typed_number<Type>*
|
||||||
|
property = dynamic_cast<PLY_read_typed_number<Type>*>(m_properties[i]);
|
||||||
|
CGAL_assertion (property != NULL);
|
||||||
|
t = property->buffer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
void assign (std::vector<Type>& t, const char* tag)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < number_of_properties (); ++ i)
|
||||||
|
if (m_properties[i]->name () == tag)
|
||||||
|
{
|
||||||
|
PLY_read_typed_list<Type>*
|
||||||
|
property = dynamic_cast<PLY_read_typed_list<Type>*>(m_properties[i]);
|
||||||
|
CGAL_assertion (property != NULL);
|
||||||
|
t = property->buffer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assign (double& t, const char* tag)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < number_of_properties (); ++ i)
|
||||||
|
if (m_properties[i]->name () == tag)
|
||||||
|
{
|
||||||
|
PLY_read_typed_number<double>*
|
||||||
|
property_double = dynamic_cast<PLY_read_typed_number<double>*>(m_properties[i]);
|
||||||
|
if (property_double == NULL)
|
||||||
|
{
|
||||||
|
PLY_read_typed_number<float>*
|
||||||
|
property_float = dynamic_cast<PLY_read_typed_number<float>*>(m_properties[i]);
|
||||||
|
CGAL_assertion (property_float != NULL);
|
||||||
|
t = property_float->buffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
t = property_double->buffer();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class PLY_reader
|
||||||
|
{
|
||||||
|
std::vector<PLY_element> m_elements;
|
||||||
|
std::string m_comments;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PLY_reader () { }
|
||||||
|
|
||||||
|
std::size_t number_of_elements() const { return m_elements.size(); }
|
||||||
|
PLY_element& element (std::size_t idx)
|
||||||
|
{
|
||||||
|
return m_elements[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& comments() const { return m_comments; }
|
||||||
|
|
||||||
|
template <typename Stream>
|
||||||
|
bool init (Stream& stream)
|
||||||
|
{
|
||||||
|
std::size_t lineNumber = 0; // current line number
|
||||||
|
enum Format { ASCII = 0, BINARY_LITTLE_ENDIAN = 1, BINARY_BIG_ENDIAN = 2};
|
||||||
|
Format format = ASCII;
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
std::istringstream iss;
|
||||||
|
|
||||||
|
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 << "Error: 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 << "Error: 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")
|
||||||
|
{
|
||||||
|
std::string type, name;
|
||||||
|
if (!(iss >> type >> name))
|
||||||
|
{
|
||||||
|
std::cerr << "Error line " << lineNumber << " of file" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (type == "list") // Special case
|
||||||
|
{
|
||||||
|
std::string size_type = name;
|
||||||
|
std::string index_type;
|
||||||
|
name.clear();
|
||||||
|
if (!(iss >> index_type >> name))
|
||||||
|
{
|
||||||
|
std::cerr << "Error line " << lineNumber << " of file" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRY_TO_GENERATE_LIST_PROPERTY ("char", "int8", boost::int8_t);
|
||||||
|
else TRY_TO_GENERATE_LIST_PROPERTY ("uchar", "uint8", boost::uint8_t);
|
||||||
|
else TRY_TO_GENERATE_LIST_PROPERTY ("short", "int16", boost::int16_t);
|
||||||
|
else TRY_TO_GENERATE_LIST_PROPERTY ("ushort", "uint16", boost::uint16_t);
|
||||||
|
else TRY_TO_GENERATE_LIST_PROPERTY ("int", "int32", boost::int32_t);
|
||||||
|
else TRY_TO_GENERATE_LIST_PROPERTY ("uint", "uint32", boost::uint32_t);
|
||||||
|
else TRY_TO_GENERATE_LIST_PROPERTY ("float", "float32", float);
|
||||||
|
else TRY_TO_GENERATE_LIST_PROPERTY ("double", "float64", double);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRY_TO_GENERATE_PROPERTY ("char", "int8", boost::int8_t);
|
||||||
|
else TRY_TO_GENERATE_PROPERTY ("uchar", "uint8", boost::uint8_t);
|
||||||
|
else TRY_TO_GENERATE_PROPERTY ("short", "int16", boost::int16_t);
|
||||||
|
else TRY_TO_GENERATE_PROPERTY ("ushort", "uint16", boost::uint16_t);
|
||||||
|
else TRY_TO_GENERATE_PROPERTY ("int", "int32", boost::int32_t);
|
||||||
|
else TRY_TO_GENERATE_PROPERTY ("uint", "uint32", boost::uint32_t);
|
||||||
|
else TRY_TO_GENERATE_PROPERTY ("float", "float32", float);
|
||||||
|
else TRY_TO_GENERATE_PROPERTY ("double", "float64", double);
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (keyword == "comment")
|
||||||
|
{
|
||||||
|
std::string str = iss.str();
|
||||||
|
if (str.size() > 8)
|
||||||
|
{
|
||||||
|
std::copy (str.begin() + 8, str.end(), std::back_inserter (m_comments));
|
||||||
|
m_comments += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_elements.push_back (PLY_element(type, number));
|
||||||
|
}
|
||||||
|
// When end_header is reached, stop loop and begin reading points
|
||||||
|
else if (keyword == "end_header")
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~PLY_reader ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class Reader, class T>
|
||||||
|
void get_value(Reader& r, T& v, PLY_property<T>& wrapper)
|
||||||
|
{
|
||||||
|
return r.assign(v, wrapper.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <std::size_t N>
|
||||||
|
struct Filler
|
||||||
|
{
|
||||||
|
template <class Reader, class Value_tuple, class PLY_property_tuple>
|
||||||
|
static void fill(Reader& r, Value_tuple& values, PLY_property_tuple wrappers)
|
||||||
|
{
|
||||||
|
get_value(r, std::get<N>(values), std::get<N+2>(wrappers));
|
||||||
|
Filler<N-1>::fill(r, values, wrappers);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int ...>
|
||||||
|
struct seq { };
|
||||||
|
|
||||||
|
template<int N, int ...S>
|
||||||
|
struct gens : gens<N-1, N-1, S...> { };
|
||||||
|
|
||||||
|
template<int ...S>
|
||||||
|
struct gens<0, S...> {
|
||||||
|
typedef seq<S...> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class ValueType, class Functor, class Tuple, int ...S>
|
||||||
|
ValueType call_functor(Functor f, Tuple t, seq<S...>) {
|
||||||
|
return f(std::get<S>(t) ...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ValueType, class Functor, typename ... T>
|
||||||
|
ValueType call_functor(Functor f, std::tuple<T...>& t)
|
||||||
|
{
|
||||||
|
return call_functor<ValueType>(f, t, typename gens<sizeof...(T)>::type());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Filler<0>
|
||||||
|
{
|
||||||
|
template <class Reader, class Value_tuple, class PLY_property_tuple>
|
||||||
|
static void fill(Reader& r, Value_tuple& values, PLY_property_tuple wrappers)
|
||||||
|
{
|
||||||
|
get_value(r, std::get<0>(values), std::get<2>(wrappers));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename OutputValueType,
|
||||||
|
typename PropertyMap,
|
||||||
|
typename Constructor,
|
||||||
|
typename ... T>
|
||||||
|
void process_properties (PLY_element& element, OutputValueType& new_element,
|
||||||
|
std::tuple<PropertyMap, Constructor, PLY_property<T>...>&& current)
|
||||||
|
{
|
||||||
|
typedef typename PropertyMap::value_type PmapValueType;
|
||||||
|
std::tuple<T...> values;
|
||||||
|
Filler<sizeof...(T)-1>::fill(element, values, current);
|
||||||
|
PmapValueType new_value = call_functor<PmapValueType>(std::get<1>(current), values);
|
||||||
|
put (std::get<0>(current), new_element, new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputValueType,
|
||||||
|
typename PropertyMap,
|
||||||
|
typename Constructor,
|
||||||
|
typename ... T,
|
||||||
|
typename NextPropertyBinder,
|
||||||
|
typename ... PropertyMapBinders>
|
||||||
|
void process_properties (PLY_element& element, OutputValueType& new_element,
|
||||||
|
std::tuple<PropertyMap, Constructor, PLY_property<T>...>&& current,
|
||||||
|
NextPropertyBinder&& next,
|
||||||
|
PropertyMapBinders&& ... properties)
|
||||||
|
{
|
||||||
|
typedef typename PropertyMap::value_type PmapValueType;
|
||||||
|
std::tuple<T...> values;
|
||||||
|
Filler<sizeof...(T)-1>::fill(element, values, current);
|
||||||
|
PmapValueType new_value = call_functor<PmapValueType>(std::get<1>(current), values);
|
||||||
|
put (std::get<0>(current), new_element, new_value);
|
||||||
|
|
||||||
|
process_properties (element, new_element, std::forward<NextPropertyBinder>(next),
|
||||||
|
std::forward<PropertyMapBinders>(properties)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename OutputValueType, typename PropertyMap, typename T>
|
||||||
|
void process_properties (PLY_element& element, OutputValueType& new_element,
|
||||||
|
std::pair<PropertyMap, PLY_property<T> >&& current)
|
||||||
|
{
|
||||||
|
T new_value = T();
|
||||||
|
element.assign (new_value, current.second.name);
|
||||||
|
put (current.first, new_element, new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename OutputValueType, typename PropertyMap, typename T,
|
||||||
|
typename NextPropertyBinder, typename ... PropertyMapBinders>
|
||||||
|
void process_properties (PLY_element& element, OutputValueType& new_element,
|
||||||
|
std::pair<PropertyMap, PLY_property<T> >&& current,
|
||||||
|
NextPropertyBinder&& next,
|
||||||
|
PropertyMapBinders&& ... properties)
|
||||||
|
{
|
||||||
|
T new_value = T();
|
||||||
|
element.assign (new_value, current.second.name);
|
||||||
|
put (current.first, new_element, new_value);
|
||||||
|
process_properties (element, new_element, std::forward<NextPropertyBinder>(next),
|
||||||
|
std::forward<PropertyMapBinders>(properties)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline void property_header_type (std::ostream& stream)
|
||||||
|
{
|
||||||
|
CGAL_assertion_msg (false, "Unknown PLY type");
|
||||||
|
stream << "undefined_type";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline void property_header_type<char> (std::ostream& stream) { stream << "char"; }
|
||||||
|
template <> inline void property_header_type<signed char> (std::ostream& stream) { stream << "char"; }
|
||||||
|
template <> inline void property_header_type<unsigned char> (std::ostream& stream) { stream << "uchar"; }
|
||||||
|
template <> inline void property_header_type<short> (std::ostream& stream) { stream << "short"; }
|
||||||
|
template <> inline void property_header_type<unsigned short> (std::ostream& stream) { stream << "ushort"; }
|
||||||
|
template <> inline void property_header_type<int> (std::ostream& stream) { stream << "int"; }
|
||||||
|
template <> inline void property_header_type<unsigned int> (std::ostream& stream) { stream << "uint"; }
|
||||||
|
template <> inline void property_header_type<float> (std::ostream& stream) { stream << "float"; }
|
||||||
|
template <> inline void property_header_type<double> (std::ostream& stream) { stream << "double"; }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void property_header (std::ostream& stream, const PLY_property<T>& prop)
|
||||||
|
{
|
||||||
|
stream << "property ";
|
||||||
|
property_header_type<T>(stream);
|
||||||
|
stream << " " << prop.name << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void property_header (std::ostream& stream, const PLY_property<std::vector<T> >& prop)
|
||||||
|
{
|
||||||
|
stream << "property list uchar ";
|
||||||
|
property_header_type<T>(stream);
|
||||||
|
stream << " " << prop.name << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <std::size_t N>
|
||||||
|
struct Properties_header
|
||||||
|
{
|
||||||
|
template <class PLY_property_tuple>
|
||||||
|
static void write(std::ostream& stream, PLY_property_tuple& wrappers)
|
||||||
|
{
|
||||||
|
Properties_header<N-1>::write(stream, wrappers);
|
||||||
|
property_header (stream, std::get<N+1>(wrappers));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template <>
|
||||||
|
struct Properties_header<0>
|
||||||
|
{
|
||||||
|
template <class PLY_property_tuple>
|
||||||
|
static void write(std::ostream& stream, PLY_property_tuple& wrappers)
|
||||||
|
{
|
||||||
|
property_header (stream, std::get<1>(wrappers));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename PropertyMap,
|
||||||
|
typename ... T>
|
||||||
|
void output_property_header (std::ostream& stream,
|
||||||
|
std::tuple<PropertyMap, PLY_property<T>... >&& current)
|
||||||
|
{
|
||||||
|
Properties_header<sizeof...(T)-1>::write(stream, current);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename PropertyMap,
|
||||||
|
typename T>
|
||||||
|
void output_property_header (std::ostream& stream,
|
||||||
|
std::pair<PropertyMap, PLY_property<T> >&& current)
|
||||||
|
{
|
||||||
|
property_header (stream, current.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PropertyMap,
|
||||||
|
typename T,
|
||||||
|
typename NextPropertyHandler,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
void output_property_header (std::ostream& stream,
|
||||||
|
std::pair<PropertyMap, PLY_property<T> >&& current,
|
||||||
|
NextPropertyHandler&& next,
|
||||||
|
PropertyHandler&& ... properties)
|
||||||
|
{
|
||||||
|
property_header (stream, current.second);
|
||||||
|
output_property_header (stream, std::forward<NextPropertyHandler>(next),
|
||||||
|
std::forward<PropertyHandler>(properties)...);
|
||||||
|
}
|
||||||
|
template <typename PropertyMap,
|
||||||
|
typename ... T,
|
||||||
|
typename NextPropertyHandler,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
void output_property_header (std::ostream& stream,
|
||||||
|
std::tuple<PropertyMap, PLY_property<T>... >&& current,
|
||||||
|
NextPropertyHandler&& next,
|
||||||
|
PropertyHandler&& ... properties)
|
||||||
|
{
|
||||||
|
Properties_header<sizeof...(T)-1>::write(stream, current);
|
||||||
|
output_property_header (stream, std::forward<NextPropertyHandler>(next),
|
||||||
|
std::forward<PropertyHandler>(properties)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
typename PropertyMap>
|
||||||
|
void property_write (std::ostream& stream, ForwardIterator it, PropertyMap map)
|
||||||
|
{
|
||||||
|
stream << CGAL::oformat(get (map, *it));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T no_char_character (const T& t) { return t; }
|
||||||
|
inline int no_char_character (const char& t) { return int(t); }
|
||||||
|
inline int no_char_character (const signed char& t) { return int(t); }
|
||||||
|
inline int no_char_character (const unsigned char& t) { return int(t); }
|
||||||
|
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
typename PropertyMap,
|
||||||
|
typename T>
|
||||||
|
void simple_property_write (std::ostream& stream, ForwardIterator it,
|
||||||
|
std::pair<PropertyMap, PLY_property<T> > map)
|
||||||
|
{
|
||||||
|
if (CGAL::get_mode(stream) == IO::ASCII)
|
||||||
|
stream << no_char_character(get (map.first, *it));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typename PropertyMap::value_type value = get(map.first, *it);
|
||||||
|
stream.write (reinterpret_cast<char*>(&value), sizeof(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
typename PropertyMap,
|
||||||
|
typename T>
|
||||||
|
void simple_property_write (std::ostream& stream, ForwardIterator it,
|
||||||
|
std::pair<PropertyMap, PLY_property<std::vector<T> > > map)
|
||||||
|
{
|
||||||
|
const typename PropertyMap::reference value = get(map.first, *it);
|
||||||
|
|
||||||
|
if (CGAL::get_mode(stream) == IO::ASCII)
|
||||||
|
{
|
||||||
|
stream << value.size();
|
||||||
|
for (std::size_t i = 0; i < value.size(); ++ i)
|
||||||
|
stream << " " << no_char_character(value[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char size = static_cast<unsigned char>(value.size());
|
||||||
|
stream.write (reinterpret_cast<char*>(&size), sizeof(size));
|
||||||
|
for (std::size_t i = 0; i < value.size(); ++ i)
|
||||||
|
{
|
||||||
|
T t = T(value[i]);
|
||||||
|
stream.write (reinterpret_cast<char*>(&t), sizeof(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
typename PropertyMap,
|
||||||
|
typename ... T>
|
||||||
|
void output_properties (std::ostream& stream,
|
||||||
|
ForwardIterator it,
|
||||||
|
std::tuple<PropertyMap, PLY_property<T>... >&& current)
|
||||||
|
{
|
||||||
|
property_write (stream, it, std::get<0>(current));
|
||||||
|
if (get_mode(stream) == IO::ASCII)
|
||||||
|
stream << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
typename PropertyMap,
|
||||||
|
typename T>
|
||||||
|
void output_properties (std::ostream& stream,
|
||||||
|
ForwardIterator it,
|
||||||
|
std::pair<PropertyMap, PLY_property<T> >&& current)
|
||||||
|
{
|
||||||
|
simple_property_write (stream, it, std::forward<std::pair<PropertyMap, PLY_property<T> > >(current));
|
||||||
|
if (get_mode(stream) == IO::ASCII)
|
||||||
|
stream << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
typename PropertyMap,
|
||||||
|
typename T,
|
||||||
|
typename NextPropertyHandler,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
void output_properties (std::ostream& stream,
|
||||||
|
ForwardIterator it,
|
||||||
|
std::pair<PropertyMap, PLY_property<T> >&& current,
|
||||||
|
NextPropertyHandler&& next,
|
||||||
|
PropertyHandler&& ... properties)
|
||||||
|
{
|
||||||
|
simple_property_write (stream, it, current);
|
||||||
|
if (get_mode(stream) == IO::ASCII)
|
||||||
|
stream << " ";
|
||||||
|
output_properties (stream, it, std::forward<NextPropertyHandler>(next),
|
||||||
|
std::forward<PropertyHandler>(properties)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ForwardIterator,
|
||||||
|
typename PropertyMap,
|
||||||
|
typename ... T,
|
||||||
|
typename NextPropertyHandler,
|
||||||
|
typename ... PropertyHandler>
|
||||||
|
void output_properties (std::ostream& stream,
|
||||||
|
ForwardIterator it,
|
||||||
|
std::tuple<PropertyMap, PLY_property<T>... >&& current,
|
||||||
|
NextPropertyHandler&& next,
|
||||||
|
PropertyHandler&& ... properties)
|
||||||
|
{
|
||||||
|
property_write (stream, it, std::get<0>(current));
|
||||||
|
if (get_mode(stream) == IO::ASCII)
|
||||||
|
stream << " ";
|
||||||
|
output_properties (stream, it, std::forward<NextPropertyHandler>(next),
|
||||||
|
std::forward<PropertyHandler>(properties)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Printer classes used by Point_set_3 and Surface_mesh (translate a
|
||||||
|
// property map to a PLY property)
|
||||||
|
|
||||||
|
template <typename Index>
|
||||||
|
class Abstract_property_printer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Abstract_property_printer() { }
|
||||||
|
virtual void print (std::ostream& stream, const Index& index) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Index, typename PropertyMap>
|
||||||
|
class Property_printer : public Abstract_property_printer<Index>
|
||||||
|
{
|
||||||
|
PropertyMap m_pmap;
|
||||||
|
public:
|
||||||
|
Property_printer (const PropertyMap& pmap) : m_pmap (pmap)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(std::ostream& stream, const Index& index)
|
||||||
|
{
|
||||||
|
stream << get(m_pmap, index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Index, typename PropertyMap,
|
||||||
|
typename Type = typename PropertyMap::value_type>
|
||||||
|
class Simple_property_printer : public Abstract_property_printer<Index>
|
||||||
|
{
|
||||||
|
PropertyMap m_pmap;
|
||||||
|
public:
|
||||||
|
Simple_property_printer (const PropertyMap& pmap) : m_pmap (pmap)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(std::ostream& stream, const Index& index)
|
||||||
|
{
|
||||||
|
if (get_mode(stream) == IO::ASCII)
|
||||||
|
stream << get(m_pmap, index);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Type t = Type(get (m_pmap, index));
|
||||||
|
stream.write (reinterpret_cast<char*>(&t), sizeof(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Index, typename PropertyMap>
|
||||||
|
class Char_property_printer : public Abstract_property_printer<Index>
|
||||||
|
{
|
||||||
|
typedef typename PropertyMap::value_type Type;
|
||||||
|
PropertyMap m_pmap;
|
||||||
|
public:
|
||||||
|
Char_property_printer (const PropertyMap& pmap) : m_pmap (pmap)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(std::ostream& stream, const Index& index)
|
||||||
|
{
|
||||||
|
if (get_mode(stream) == IO::ASCII)
|
||||||
|
stream << int(get(m_pmap, index));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Type t = get (m_pmap, index);
|
||||||
|
stream.write (reinterpret_cast<char*>(&t), sizeof(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace PLY
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CGAL_IO_PLY_H
|
||||||
|
|
@ -393,39 +393,45 @@ std::ostream& operator<<( std::ostream& out, const Color& col)
|
||||||
switch(get_mode(out)) {
|
switch(get_mode(out)) {
|
||||||
case IO::ASCII :
|
case IO::ASCII :
|
||||||
return out << static_cast<int>(col.red()) << ' '
|
return out << static_cast<int>(col.red()) << ' '
|
||||||
<< static_cast<int>(col.green()) << ' '
|
<< static_cast<int>(col.green()) << ' '
|
||||||
<< static_cast<int>(col.blue());
|
<< static_cast<int>(col.blue()) << ' '
|
||||||
|
<< static_cast<int>(col.alpha());
|
||||||
case IO::BINARY :
|
case IO::BINARY :
|
||||||
write(out, static_cast<int>(col.red()));
|
out.write(reinterpret_cast<const char*>(col.to_rgba().data()), 4);
|
||||||
write(out, static_cast<int>(col.green()));
|
|
||||||
write(out, static_cast<int>(col.blue()));
|
|
||||||
return out;
|
return out;
|
||||||
default:
|
default:
|
||||||
return out << "Color(" << static_cast<int>(col.red()) << ", "
|
return out << "Color(" << static_cast<int>(col.red()) << ", "
|
||||||
<< static_cast<int>(col.green()) << ", "
|
<< static_cast<int>(col.green()) << ", "
|
||||||
<< static_cast<int>(col.blue()) << ')';
|
<< static_cast<int>(col.blue()) << ", "
|
||||||
|
<< static_cast<int>(col.alpha()) << ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
std::istream &operator>>(std::istream &is, Color& col)
|
std::istream &operator>>(std::istream &is, Color& col)
|
||||||
{
|
{
|
||||||
int r = 0, g = 0, b = 0;
|
unsigned char r = 0, g = 0, b = 0, a = 0;
|
||||||
|
int ir = 0, ig = 0, ib = 0, ia = 0;
|
||||||
switch(get_mode(is)) {
|
switch(get_mode(is)) {
|
||||||
case IO::ASCII :
|
case IO::ASCII :
|
||||||
is >> r >> g >> b;
|
is >> ir >> ig >> ib >> ia;
|
||||||
|
r = (unsigned char)ir;
|
||||||
|
g = (unsigned char)ig;
|
||||||
|
b = (unsigned char)ib;
|
||||||
|
a = (unsigned char)ia;
|
||||||
break;
|
break;
|
||||||
case IO::BINARY :
|
case IO::BINARY :
|
||||||
read(is, r);
|
read(is, r);
|
||||||
read(is, g);
|
read(is, g);
|
||||||
read(is, b);
|
read(is, b);
|
||||||
|
read(is, a);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "" << std::endl;
|
std::cerr << "" << std::endl;
|
||||||
std::cerr << "Stream must be in ascii or binary mode" << std::endl;
|
std::cerr << "Stream must be in ascii or binary mode" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
col = Color((unsigned char)r,(unsigned char)g,(unsigned char)b);
|
col = Color(r,g,b,a);
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,5 @@
|
||||||
#ifndef CGAL_HEADER_ONLY
|
#ifndef CGAL_HEADER_ONLY
|
||||||
|
|
||||||
#include <CGAL/IO/Color.h>
|
#include <CGAL/IO/Color.h>
|
||||||
#include <CGAL/IO/Color_impl.h>
|
|
||||||
|
|
||||||
#endif // CGAL_HEADER_ONLY
|
#endif // CGAL_HEADER_ONLY
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,727 @@
|
||||||
|
// Copyright (c) 2018 GeometryFactory Sarl (France).
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
// You can redistribute it and/or modify it under the terms of the GNU
|
||||||
|
// General Public License as published by the Free Software Foundation,
|
||||||
|
// either version 3 of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Licensees holding a valid commercial license may use this file in
|
||||||
|
// accordance with the commercial license agreement provided with the software.
|
||||||
|
//
|
||||||
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||||
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: GPL-3.0+
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Author(s) : Simon Giraudot
|
||||||
|
|
||||||
|
#ifndef CGAL_SURFACE_MESH_IO_PLY
|
||||||
|
#define CGAL_SURFACE_MESH_IO_PLY
|
||||||
|
|
||||||
|
#include <CGAL/IO/PLY.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
#if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES)
|
||||||
|
namespace PLY {
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
class Surface_mesh_filler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||||
|
typedef typename Kernel::Vector_3 Vector;
|
||||||
|
typedef Surface_mesh<Point> Surface_mesh;
|
||||||
|
typedef typename Surface_mesh::Vertex_index Vertex_index;
|
||||||
|
typedef typename Surface_mesh::Face_index Face_index;
|
||||||
|
typedef typename Surface_mesh::Edge_index Edge_index;
|
||||||
|
typedef typename Surface_mesh::Halfedge_index Halfedge_index;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct Abstract_ply_property_to_surface_mesh_property
|
||||||
|
{
|
||||||
|
virtual ~Abstract_ply_property_to_surface_mesh_property() { }
|
||||||
|
virtual void assign (PLY_element& element, std::size_t index) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Simplex, typename Type>
|
||||||
|
class PLY_property_to_surface_mesh_property : public Abstract_ply_property_to_surface_mesh_property
|
||||||
|
{
|
||||||
|
typedef typename Surface_mesh::template Property_map<Simplex, Type> Map;
|
||||||
|
Map m_map;
|
||||||
|
std::string m_name;
|
||||||
|
public:
|
||||||
|
PLY_property_to_surface_mesh_property (Surface_mesh& sm, const std::string& name)
|
||||||
|
: m_name (name)
|
||||||
|
{
|
||||||
|
m_map = sm.template add_property_map<Simplex, Type>(prefix(Simplex()) + name).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void assign (PLY_element& element, std::size_t index)
|
||||||
|
{
|
||||||
|
Type t{};
|
||||||
|
element.assign (t, m_name.c_str());
|
||||||
|
put(m_map, Simplex(index), t);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string prefix(Vertex_index) const { return "v:"; }
|
||||||
|
std::string prefix(Face_index) const { return "f:"; }
|
||||||
|
std::string prefix(Edge_index) const { return "e:"; }
|
||||||
|
std::string prefix(Halfedge_index) const { return "h:"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
Surface_mesh& m_mesh;
|
||||||
|
std::vector<Vertex_index> m_map_v2v;
|
||||||
|
bool m_use_floats;
|
||||||
|
int m_normals;
|
||||||
|
typename Surface_mesh::template Property_map<Vertex_index, Vector> m_normal_map;
|
||||||
|
int m_vcolors;
|
||||||
|
typename Surface_mesh::template Property_map<Vertex_index, CGAL::Color> m_vcolor_map;
|
||||||
|
int m_fcolors;
|
||||||
|
typename Surface_mesh::template Property_map<Face_index, CGAL::Color> m_fcolor_map;
|
||||||
|
bool m_use_int32_t;
|
||||||
|
std::string m_index_tag;
|
||||||
|
std::vector<Abstract_ply_property_to_surface_mesh_property*> m_vertex_properties;
|
||||||
|
std::vector<Abstract_ply_property_to_surface_mesh_property*> m_face_properties;
|
||||||
|
std::vector<Abstract_ply_property_to_surface_mesh_property*> m_edge_properties;
|
||||||
|
std::vector<Abstract_ply_property_to_surface_mesh_property*> m_halfedge_properties;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Surface_mesh_filler (Surface_mesh& mesh)
|
||||||
|
: m_mesh (mesh), m_use_floats (false), m_normals(0), m_vcolors(0), m_fcolors(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~Surface_mesh_filler()
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < m_vertex_properties.size(); ++ i)
|
||||||
|
delete m_vertex_properties[i];
|
||||||
|
for (std::size_t i = 0; i < m_face_properties.size(); ++ i)
|
||||||
|
delete m_face_properties[i];
|
||||||
|
for (std::size_t i = 0; i < m_edge_properties.size(); ++ i)
|
||||||
|
delete m_edge_properties[i];
|
||||||
|
for (std::size_t i = 0; i < m_halfedge_properties.size(); ++ i)
|
||||||
|
delete m_halfedge_properties[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_simplex_specific_property (internal::PLY::PLY_read_number* property, Vertex_index)
|
||||||
|
{
|
||||||
|
const std::string& name = property->name();
|
||||||
|
if (name == "x" ||
|
||||||
|
name == "y" ||
|
||||||
|
name == "z")
|
||||||
|
{
|
||||||
|
if (dynamic_cast<PLY_read_typed_number<float>*>(property))
|
||||||
|
m_use_floats = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (name == "nx" ||
|
||||||
|
name == "ny" ||
|
||||||
|
name == "nz")
|
||||||
|
{
|
||||||
|
++ m_normals;
|
||||||
|
if (m_normals == 3)
|
||||||
|
m_normal_map = m_mesh.template add_property_map<Vertex_index, Vector>("v:normal").first;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (name == "red" ||
|
||||||
|
name == "green" ||
|
||||||
|
name == "blue")
|
||||||
|
{
|
||||||
|
++ m_vcolors;
|
||||||
|
if (m_vcolors == 3)
|
||||||
|
m_vcolor_map = m_mesh.template add_property_map<Vertex_index, CGAL::Color>("v:color").first;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_simplex_specific_property (internal::PLY::PLY_read_number* property, Face_index)
|
||||||
|
{
|
||||||
|
const std::string& name = property->name();
|
||||||
|
if (name == "vertex_indices" || name == "vertex_index")
|
||||||
|
{
|
||||||
|
m_index_tag = name;
|
||||||
|
m_use_int32_t = dynamic_cast<PLY_read_typed_list<boost::int32_t>*>(property);
|
||||||
|
CGAL_assertion (dynamic_cast<PLY_read_typed_list<boost::uint32_t>*>(property));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (name == "red" ||
|
||||||
|
name == "green" ||
|
||||||
|
name == "blue")
|
||||||
|
{
|
||||||
|
++ m_fcolors;
|
||||||
|
if (m_fcolors == 3)
|
||||||
|
m_fcolor_map = m_mesh.template add_property_map<Face_index, CGAL::Color>("f:color").first;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_simplex_specific_property (internal::PLY::PLY_read_number* property, Edge_index)
|
||||||
|
{
|
||||||
|
const std::string& name = property->name();
|
||||||
|
if (name == "v0" || name == "v1")
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_simplex_specific_property (internal::PLY::PLY_read_number* property, Halfedge_index)
|
||||||
|
{
|
||||||
|
const std::string& name = property->name();
|
||||||
|
if (name == "source" || name == "target")
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void instantiate_vertex_properties (PLY_element& element)
|
||||||
|
{
|
||||||
|
m_map_v2v.reserve(element.number_of_items());
|
||||||
|
instantiate_properties<Vertex_index> (element, m_vertex_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
void instantiate_face_properties (PLY_element& element)
|
||||||
|
{
|
||||||
|
instantiate_properties<Face_index> (element, m_face_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
void instantiate_edge_properties (PLY_element& element)
|
||||||
|
{
|
||||||
|
instantiate_properties<Edge_index> (element, m_edge_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
void instantiate_halfedge_properties (PLY_element& element)
|
||||||
|
{
|
||||||
|
instantiate_properties<Halfedge_index> (element, m_halfedge_properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Simplex>
|
||||||
|
void instantiate_properties (PLY_element& element,
|
||||||
|
std::vector<Abstract_ply_property_to_surface_mesh_property*>& properties)
|
||||||
|
{
|
||||||
|
for (std::size_t j = 0; j < element.number_of_properties(); ++ j)
|
||||||
|
{
|
||||||
|
internal::PLY::PLY_read_number* property = element.property(j);
|
||||||
|
|
||||||
|
if (has_simplex_specific_property (property, Simplex()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const std::string& name = property->name();
|
||||||
|
|
||||||
|
if (dynamic_cast<PLY_read_typed_number<boost::int8_t>*>(property))
|
||||||
|
{
|
||||||
|
properties.push_back
|
||||||
|
(new PLY_property_to_surface_mesh_property<Simplex, boost::int8_t>(m_mesh,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
else if (dynamic_cast<PLY_read_typed_number<boost::uint8_t>*>(property))
|
||||||
|
{
|
||||||
|
properties.push_back
|
||||||
|
(new PLY_property_to_surface_mesh_property<Simplex, boost::uint8_t>(m_mesh,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
else if (dynamic_cast<PLY_read_typed_number<boost::int16_t>*>(property))
|
||||||
|
{
|
||||||
|
properties.push_back
|
||||||
|
(new PLY_property_to_surface_mesh_property<Simplex, boost::int16_t>(m_mesh,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
else if (dynamic_cast<PLY_read_typed_number<boost::uint16_t>*>(property))
|
||||||
|
{
|
||||||
|
properties.push_back
|
||||||
|
(new PLY_property_to_surface_mesh_property<Simplex, boost::uint16_t>(m_mesh,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
else if (dynamic_cast<PLY_read_typed_number<boost::int32_t>*>(property))
|
||||||
|
{
|
||||||
|
properties.push_back
|
||||||
|
(new PLY_property_to_surface_mesh_property<Simplex, boost::int32_t>(m_mesh,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
else if (dynamic_cast<PLY_read_typed_number<boost::uint32_t>*>(property))
|
||||||
|
{
|
||||||
|
properties.push_back
|
||||||
|
(new PLY_property_to_surface_mesh_property<Simplex, boost::uint32_t>(m_mesh,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
else if (dynamic_cast<PLY_read_typed_number<float>*>(property))
|
||||||
|
{
|
||||||
|
properties.push_back
|
||||||
|
(new PLY_property_to_surface_mesh_property<Simplex, float>(m_mesh,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
else if (dynamic_cast<PLY_read_typed_number<double>*>(property))
|
||||||
|
{
|
||||||
|
properties.push_back
|
||||||
|
(new PLY_property_to_surface_mesh_property<Simplex, double>(m_mesh,
|
||||||
|
name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_vertex_line (PLY_element& element)
|
||||||
|
{
|
||||||
|
Vertex_index vi;
|
||||||
|
|
||||||
|
if (m_use_floats)
|
||||||
|
process_line<float>(element, vi);
|
||||||
|
else
|
||||||
|
process_line<double>(element, vi);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < m_vertex_properties.size(); ++ i)
|
||||||
|
m_vertex_properties[i]->assign (element, vi);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename FT>
|
||||||
|
void process_line (PLY_element& element, Vertex_index& vi)
|
||||||
|
{
|
||||||
|
FT x = (FT)0.,y = (FT)0., z = (FT)0.,
|
||||||
|
nx = (FT)0., ny = (FT)0., nz = (FT)0.;
|
||||||
|
element.assign (x, "x");
|
||||||
|
element.assign (y, "y");
|
||||||
|
element.assign (z, "z");
|
||||||
|
Point point (x, y, z);
|
||||||
|
vi = m_mesh.add_vertex(point);
|
||||||
|
m_map_v2v.push_back(vi);
|
||||||
|
|
||||||
|
if (m_normals == 3)
|
||||||
|
{
|
||||||
|
element.assign (nx, "nx");
|
||||||
|
element.assign (ny, "ny");
|
||||||
|
element.assign (nz, "nz");
|
||||||
|
Vector normal (nx, ny, nz);
|
||||||
|
m_normal_map[vi] = normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_vcolors == 3)
|
||||||
|
{
|
||||||
|
unsigned char r, g, b;
|
||||||
|
element.assign (r, "red");
|
||||||
|
element.assign (g, "green");
|
||||||
|
element.assign (b, "blue");
|
||||||
|
m_vcolor_map[vi] = CGAL::Color (r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool process_face_line (PLY_element& element)
|
||||||
|
{
|
||||||
|
Face_index fi = m_mesh.null_face();
|
||||||
|
|
||||||
|
if (m_use_int32_t)
|
||||||
|
process_line<boost::int32_t>(element, fi);
|
||||||
|
else
|
||||||
|
process_line<boost::uint32_t>(element, fi);
|
||||||
|
|
||||||
|
if (fi == Surface_mesh::null_face())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < m_face_properties.size(); ++ i)
|
||||||
|
m_face_properties[i]->assign (element, fi);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename IntType>
|
||||||
|
void process_line (PLY_element& element, Face_index& fi)
|
||||||
|
{
|
||||||
|
std::vector<IntType> indices;
|
||||||
|
element.assign (indices, m_index_tag.c_str());
|
||||||
|
std::vector<Vertex_index> vertices;
|
||||||
|
vertices.reserve(indices.size());
|
||||||
|
for (std::size_t i = 0; i < indices.size(); ++ i)
|
||||||
|
vertices.push_back (m_map_v2v[std::size_t(indices[i])]);
|
||||||
|
|
||||||
|
fi = m_mesh.add_face(vertices);
|
||||||
|
if (fi == m_mesh.null_face())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_fcolors == 3)
|
||||||
|
{
|
||||||
|
unsigned char r, g, b;
|
||||||
|
element.assign (r, "red");
|
||||||
|
element.assign (g, "green");
|
||||||
|
element.assign (b, "blue");
|
||||||
|
m_fcolor_map[fi] = CGAL::Color (r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool process_edge_line (PLY_element& element)
|
||||||
|
{
|
||||||
|
Edge_index ei = m_mesh.null_edge();
|
||||||
|
|
||||||
|
if (m_use_int32_t)
|
||||||
|
process_line<boost::int32_t>(element, ei);
|
||||||
|
else
|
||||||
|
process_line<boost::uint32_t>(element, ei);
|
||||||
|
|
||||||
|
if (ei == Surface_mesh::null_edge())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < m_edge_properties.size(); ++ i)
|
||||||
|
m_edge_properties[i]->assign (element, ei);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename IntType>
|
||||||
|
void process_line (PLY_element& element, Edge_index& ei)
|
||||||
|
{
|
||||||
|
IntType v0, v1;
|
||||||
|
element.assign (v0, "v0");
|
||||||
|
element.assign (v1, "v1");
|
||||||
|
|
||||||
|
Halfedge_index hi = m_mesh.halfedge(m_map_v2v[std::size_t(v0)],
|
||||||
|
m_map_v2v[std::size_t(v1)]);
|
||||||
|
if (hi == m_mesh.null_halfedge())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ei = m_mesh.edge (hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool process_halfedge_line (PLY_element& element)
|
||||||
|
{
|
||||||
|
Halfedge_index hi = m_mesh.null_halfedge();
|
||||||
|
|
||||||
|
if (m_use_int32_t)
|
||||||
|
process_line<boost::int32_t>(element, hi);
|
||||||
|
else
|
||||||
|
process_line<boost::uint32_t>(element, hi);
|
||||||
|
|
||||||
|
if (hi == Surface_mesh::null_halfedge())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < m_halfedge_properties.size(); ++ i)
|
||||||
|
m_halfedge_properties[i]->assign (element, hi);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename IntType>
|
||||||
|
void process_line (PLY_element& element, Halfedge_index& hi)
|
||||||
|
{
|
||||||
|
IntType source, target;
|
||||||
|
element.assign (source, "source");
|
||||||
|
element.assign (target, "target");
|
||||||
|
hi = m_mesh.halfedge(m_map_v2v[std::size_t(source)], m_map_v2v[std::size_t(target)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
bool fill_simplex_specific_header
|
||||||
|
(std::ostream& os, const Surface_mesh<Point>& sm,
|
||||||
|
std::vector<Abstract_property_printer<typename Surface_mesh<Point>::Vertex_index>*>& printers,
|
||||||
|
const std::string& prop)
|
||||||
|
{
|
||||||
|
typedef Surface_mesh<Point> SMesh;
|
||||||
|
typedef typename SMesh::Vertex_index VIndex;
|
||||||
|
typedef typename Kernel_traits<Point>::Kernel Kernel;
|
||||||
|
typedef typename Kernel::FT FT;
|
||||||
|
typedef typename Kernel::Vector_3 Vector;
|
||||||
|
typedef typename SMesh::template Property_map<VIndex, Point> Point_map;
|
||||||
|
typedef typename SMesh::template Property_map<VIndex, Vector> Vector_map;
|
||||||
|
typedef typename SMesh::template Property_map<VIndex, Color> Vcolor_map;
|
||||||
|
|
||||||
|
if (prop == "v:connectivity" ||
|
||||||
|
prop == "v:removed")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (prop == "v:point")
|
||||||
|
{
|
||||||
|
if (boost::is_same<FT, float>::value)
|
||||||
|
{
|
||||||
|
os << "property float x" << std::endl
|
||||||
|
<< "property float y" << std::endl
|
||||||
|
<< "property float z" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << "property double x" << std::endl
|
||||||
|
<< "property double y" << std::endl
|
||||||
|
<< "property double z" << std::endl;
|
||||||
|
}
|
||||||
|
printers.push_back (new Property_printer<VIndex,Point_map>(sm.points()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool okay = false;
|
||||||
|
if (prop == "v:normal")
|
||||||
|
{
|
||||||
|
Vector_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<VIndex,Vector>(prop);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
if (boost::is_same<FT, float>::value)
|
||||||
|
{
|
||||||
|
os << "property float nx" << std::endl
|
||||||
|
<< "property float ny" << std::endl
|
||||||
|
<< "property float nz" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << "property double nx" << std::endl
|
||||||
|
<< "property double ny" << std::endl
|
||||||
|
<< "property double nz" << std::endl;
|
||||||
|
}
|
||||||
|
printers.push_back (new Property_printer<VIndex,Vector_map>(pmap));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prop == "v:color")
|
||||||
|
{
|
||||||
|
Vcolor_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<VIndex,Color>(prop);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property uchar red" << std::endl
|
||||||
|
<< "property uchar green" << std::endl
|
||||||
|
<< "property uchar blue" << std::endl
|
||||||
|
<< "property uchar alpha" << std::endl;
|
||||||
|
|
||||||
|
printers.push_back (new Property_printer<VIndex,Vcolor_map>(pmap));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
bool fill_simplex_specific_header
|
||||||
|
(std::ostream& os, const Surface_mesh<Point>& sm,
|
||||||
|
std::vector<Abstract_property_printer<typename Surface_mesh<Point>::Face_index>*>& printers,
|
||||||
|
const std::string& prop)
|
||||||
|
{
|
||||||
|
typedef Surface_mesh<Point> SMesh;
|
||||||
|
typedef typename SMesh::Face_index FIndex;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, Color> Fcolor_map;
|
||||||
|
|
||||||
|
if (prop == "f:connectivity" ||
|
||||||
|
prop == "f:removed")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool okay = false;
|
||||||
|
if (prop == "f:color")
|
||||||
|
{
|
||||||
|
Fcolor_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<FIndex,Color>(prop);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property uchar red" << std::endl
|
||||||
|
<< "property uchar green" << std::endl
|
||||||
|
<< "property uchar blue" << std::endl
|
||||||
|
<< "property uchar alpha" << std::endl;
|
||||||
|
|
||||||
|
printers.push_back (new Property_printer<FIndex,Fcolor_map>(pmap));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
bool fill_simplex_specific_header
|
||||||
|
(std::ostream& , const Surface_mesh<Point>& ,
|
||||||
|
std::vector<Abstract_property_printer<typename Surface_mesh<Point>::Edge_index>*>& ,
|
||||||
|
const std::string& prop)
|
||||||
|
{
|
||||||
|
if (prop == "e:removed")
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
bool fill_simplex_specific_header
|
||||||
|
(std::ostream& , const Surface_mesh<Point>& ,
|
||||||
|
std::vector<Abstract_property_printer<typename Surface_mesh<Point>::Halfedge_index>*>& ,
|
||||||
|
const std::string& prop)
|
||||||
|
{
|
||||||
|
if (prop == "h:connectivity")
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
std::string get_property_raw_name (const std::string& prop, typename Surface_mesh<Point>::Vertex_index)
|
||||||
|
{
|
||||||
|
std::string name = prop;
|
||||||
|
if (name.rfind("v:",0) == 0)
|
||||||
|
name = std::string (prop.begin() + 2, prop.end());
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
std::string get_property_raw_name (const std::string& prop, typename Surface_mesh<Point>::Face_index)
|
||||||
|
{
|
||||||
|
std::string name = prop;
|
||||||
|
if (name.rfind("f:",0) == 0)
|
||||||
|
name = std::string (prop.begin() + 2, prop.end());
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
std::string get_property_raw_name (const std::string& prop, typename Surface_mesh<Point>::Edge_index)
|
||||||
|
{
|
||||||
|
std::string name = prop;
|
||||||
|
if (name.rfind("e:",0) == 0)
|
||||||
|
name = std::string (prop.begin() + 2, prop.end());
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Point>
|
||||||
|
std::string get_property_raw_name (const std::string& prop, typename Surface_mesh<Point>::Halfedge_index)
|
||||||
|
{
|
||||||
|
std::string name = prop;
|
||||||
|
if (name.rfind("h:",0) == 0)
|
||||||
|
name = std::string (prop.begin() + 2, prop.end());
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Point, typename Simplex>
|
||||||
|
void fill_header (std::ostream& os, const Surface_mesh<Point>& sm,
|
||||||
|
std::vector<Abstract_property_printer<Simplex>*>& printers)
|
||||||
|
{
|
||||||
|
typedef Surface_mesh<Point> SMesh;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, boost::int8_t> Int8_map;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, boost::uint8_t> Uint8_map;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, boost::int16_t> Int16_map;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, boost::uint16_t> Uint16_map;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, boost::int32_t> Int32_map;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, boost::uint32_t> Uint32_map;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, boost::int64_t> Int64_map;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, boost::uint64_t> Uint64_map;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, float> Float_map;
|
||||||
|
typedef typename SMesh::template Property_map<Simplex, double> Double_map;
|
||||||
|
std::vector<std::string> prop = sm.template properties<Simplex>();
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < prop.size(); ++ i)
|
||||||
|
{
|
||||||
|
if (fill_simplex_specific_header(os, sm, printers, prop[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Cut the "v:" prefix
|
||||||
|
std::string name = get_property_raw_name<Point> (prop[i], Simplex());
|
||||||
|
|
||||||
|
bool okay = false;
|
||||||
|
{
|
||||||
|
Int8_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,boost::int8_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property char " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Char_property_printer<Simplex,Int8_map>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Uint8_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,boost::uint8_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property uchar " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Char_property_printer<Simplex,Uint8_map>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Int16_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,boost::int16_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property short " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Simplex,Int16_map>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Uint16_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,boost::uint16_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property ushort " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Simplex,Uint16_map>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Int32_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,boost::int32_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property int " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Simplex,Int32_map>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Uint32_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,boost::uint32_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property uint " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Simplex,Uint32_map>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Int64_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,boost::int64_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property int " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Simplex,Int64_map,boost::int32_t>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Uint64_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,boost::uint64_t>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property uint " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Simplex,Uint64_map,boost::uint32_t>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Float_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,float>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property float " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Simplex,Float_map>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Double_map pmap;
|
||||||
|
boost::tie (pmap, okay) = sm.template property_map<Simplex,double>(prop[i]);
|
||||||
|
if (okay)
|
||||||
|
{
|
||||||
|
os << "property double " << name << std::endl;
|
||||||
|
printers.push_back (new internal::PLY::Simple_property_printer<Simplex,Double_map>(pmap));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace PLY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CGAL_SURFACE_MESH_IO_PLY
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
#include <CGAL/boost/graph/iterator.h>
|
#include <CGAL/boost/graph/iterator.h>
|
||||||
#include <CGAL/boost/graph/Euler_operations.h>
|
#include <CGAL/boost/graph/Euler_operations.h>
|
||||||
#include <CGAL/IO/File_scanner_OFF.h>
|
#include <CGAL/IO/File_scanner_OFF.h>
|
||||||
|
#include <CGAL/Surface_mesh/IO/PLY.h>
|
||||||
#include <CGAL/Handle_hash_function.h>
|
#include <CGAL/Handle_hash_function.h>
|
||||||
#include <CGAL/boost/graph/named_params_helper.h>
|
#include <CGAL/boost/graph/named_params_helper.h>
|
||||||
#include <CGAL/boost/graph/named_function_params.h>
|
#include <CGAL/boost/graph/named_function_params.h>
|
||||||
|
|
@ -2160,6 +2161,204 @@ private: //------------------------------------------------------- private data
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
/// \relates Surface_mesh
|
||||||
|
/// Inserts the surface mesh in an output stream in PLY format.
|
||||||
|
/// If found, "v:normal", "v:color" and "f:color" are inserted in the stream.
|
||||||
|
/// All other vertex and face properties with simple types are inserted in the stream.
|
||||||
|
/// Edges are only inserted in the stream if they have at least one
|
||||||
|
/// property with simple type: if they do, all edge properties with
|
||||||
|
/// simple types are inserted in the stream. The halfedges follow
|
||||||
|
/// the same behavior.
|
||||||
|
///
|
||||||
|
/// If provided, the `comments` string is included line by line in
|
||||||
|
/// the header of the PLY stream (each line will be precedeed by
|
||||||
|
/// "comment ").
|
||||||
|
///
|
||||||
|
/// \relates Surface_mesh
|
||||||
|
template <typename P>
|
||||||
|
bool write_ply(std::ostream& os, const Surface_mesh<P>& sm, const std::string& comments = std::string())
|
||||||
|
{
|
||||||
|
typedef Surface_mesh<P> SMesh;
|
||||||
|
typedef typename Kernel_traits<P>::Kernel K;
|
||||||
|
typedef typename K::Vector_3 Vector;
|
||||||
|
typedef typename SMesh::Vertex_index VIndex;
|
||||||
|
typedef typename SMesh::Face_index FIndex;
|
||||||
|
typedef typename SMesh::Edge_index EIndex;
|
||||||
|
typedef typename SMesh::Halfedge_index HIndex;
|
||||||
|
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, Color> Fcolor_map;
|
||||||
|
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, boost::int8_t> Int8_map_f;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, boost::uint8_t> Uint8_map_f;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, boost::int16_t> Int16_map_f;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, boost::uint16_t> Uint16_map_f;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, boost::int32_t> Int32_map_f;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, boost::uint32_t> Uint32_map_f;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, boost::int64_t> Int64_map_f;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, boost::uint64_t> Uint64_map_f;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, float> Float_map_f;
|
||||||
|
typedef typename SMesh::template Property_map<FIndex, double> Double_map_f;
|
||||||
|
|
||||||
|
os << "ply" << std::endl
|
||||||
|
<< ((get_mode(os) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl
|
||||||
|
<< "comment Generated by the CGAL library" << std::endl;
|
||||||
|
|
||||||
|
if (comments != std::string())
|
||||||
|
{
|
||||||
|
std::istringstream iss (comments);
|
||||||
|
std::string line;
|
||||||
|
while (getline(iss, line))
|
||||||
|
{
|
||||||
|
if (line != "Generated by the CGAL library") // Avoid repeating the line if multiple savings
|
||||||
|
os << "comment " << line << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "element vertex " << sm.number_of_vertices() << std::endl;
|
||||||
|
|
||||||
|
std::vector<internal::PLY::Abstract_property_printer<VIndex>*> vprinters;
|
||||||
|
internal::PLY::fill_header (os, sm, vprinters);
|
||||||
|
|
||||||
|
os << "element face " << sm.number_of_faces() << std::endl;
|
||||||
|
os << "property list uchar int vertex_indices" << std::endl;
|
||||||
|
std::vector<internal::PLY::Abstract_property_printer<FIndex>*> fprinters;
|
||||||
|
internal::PLY::fill_header (os, sm, fprinters);
|
||||||
|
|
||||||
|
std::vector<internal::PLY::Abstract_property_printer<EIndex>*> eprinters;
|
||||||
|
if (sm.template properties<EIndex>().size() > 1)
|
||||||
|
{
|
||||||
|
os << "element edge " << sm.number_of_edges() << std::endl;
|
||||||
|
os << "property int v0" << std::endl;
|
||||||
|
os << "property int v1" << std::endl;
|
||||||
|
internal::PLY::fill_header (os, sm, eprinters);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<internal::PLY::Abstract_property_printer<HIndex>*> hprinters;
|
||||||
|
if (sm.template properties<HIndex>().size() > 1)
|
||||||
|
{
|
||||||
|
os << "element halfedge " << sm.number_of_halfedges() << std::endl;
|
||||||
|
os << "property int source" << std::endl;
|
||||||
|
os << "property int target" << std::endl;
|
||||||
|
internal::PLY::fill_header (os, sm, hprinters);
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "end_header" << std::endl;
|
||||||
|
|
||||||
|
BOOST_FOREACH(VIndex vi, sm.vertices())
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < vprinters.size(); ++ i)
|
||||||
|
{
|
||||||
|
vprinters[i]->print(os, vi);
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << " ";
|
||||||
|
}
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<VIndex> polygon;
|
||||||
|
|
||||||
|
BOOST_FOREACH(FIndex fi, sm.faces())
|
||||||
|
{
|
||||||
|
// Get list of vertex indices
|
||||||
|
polygon.clear();
|
||||||
|
BOOST_FOREACH(HIndex hi, halfedges_around_face(halfedge(fi, sm), sm))
|
||||||
|
polygon.push_back (sm.target(hi));
|
||||||
|
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
{
|
||||||
|
os << polygon.size() << " ";
|
||||||
|
for (std::size_t i = 0; i < polygon.size(); ++ i)
|
||||||
|
os << int(polygon[i]) << " ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char size = (unsigned char)(polygon.size());
|
||||||
|
os.write (reinterpret_cast<char*>(&size), sizeof(size));
|
||||||
|
for (std::size_t i = 0; i < polygon.size(); ++ i)
|
||||||
|
{
|
||||||
|
int idx = int(polygon[i]);
|
||||||
|
os.write (reinterpret_cast<char*>(&idx), sizeof(idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < fprinters.size(); ++ i)
|
||||||
|
{
|
||||||
|
fprinters[i]->print(os, fi);
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eprinters.empty())
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(EIndex ei, sm.edges())
|
||||||
|
{
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << int(sm.vertex(ei,0)) << " " << int(sm.vertex(ei,1)) << " ";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int v0 = int(sm.vertex(ei,0));
|
||||||
|
int v1 = int(sm.vertex(ei,1));
|
||||||
|
os.write (reinterpret_cast<char*>(&v0), sizeof(v0));
|
||||||
|
os.write (reinterpret_cast<char*>(&v1), sizeof(v1));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < eprinters.size(); ++ i)
|
||||||
|
{
|
||||||
|
eprinters[i]->print(os, ei);
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hprinters.empty())
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(HIndex hi, sm.halfedges())
|
||||||
|
{
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << int(sm.source(hi)) << " " << int(sm.target(hi)) << " ";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int source = int(sm.source(hi));
|
||||||
|
int target = int(sm.target(hi));
|
||||||
|
os.write (reinterpret_cast<char*>(&source), sizeof(source));
|
||||||
|
os.write (reinterpret_cast<char*>(&target), sizeof(target));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < hprinters.size(); ++ i)
|
||||||
|
{
|
||||||
|
hprinters[i]->print(os, hi);
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_mode (os) == IO::ASCII)
|
||||||
|
os << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < vprinters.size(); ++ i)
|
||||||
|
delete vprinters[i];
|
||||||
|
for (std::size_t i = 0; i < fprinters.size(); ++ i)
|
||||||
|
delete fprinters[i];
|
||||||
|
for (std::size_t i = 0; i < eprinters.size(); ++ i)
|
||||||
|
delete eprinters[i];
|
||||||
|
for (std::size_t i = 0; i < hprinters.size(); ++ i)
|
||||||
|
delete hprinters[i];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @cond CGAL_DOCUMENT_INTERNALS
|
/// @cond CGAL_DOCUMENT_INTERNALS
|
||||||
|
|
||||||
|
|
@ -2218,7 +2417,7 @@ private: //------------------------------------------------------- private data
|
||||||
if(!is){
|
if(!is){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sm.reserve(sm.num_vertices()+n, sm.num_faces()+2*f, sm.num_edges()+e);
|
sm.reserve(sm.num_vertices()+n, sm.num_edges()+e, sm.num_faces()+f);
|
||||||
std::vector<Vertex_index> vertexmap(n);
|
std::vector<Vertex_index> vertexmap(n);
|
||||||
P p;
|
P p;
|
||||||
Vector_3 v;
|
Vector_3 v;
|
||||||
|
|
@ -2320,6 +2519,131 @@ private: //------------------------------------------------------- private data
|
||||||
return read_off(is, sm, parameters::all_default());
|
return read_off(is, sm, parameters::all_default());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE) && !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
template <typename P>
|
||||||
|
bool read_ply(std::istream& is, Surface_mesh<P>& sm)
|
||||||
|
{
|
||||||
|
std::string dummy;
|
||||||
|
return read_ply (is, sm, dummy);
|
||||||
|
}
|
||||||
|
/// \endcond
|
||||||
|
|
||||||
|
/// Extracts the surface mesh from an input stream in Ascii or
|
||||||
|
/// Binary PLY format and appends it to the surface mesh `sm`.
|
||||||
|
///
|
||||||
|
/// - the operator reads the vertex `point` property and the face
|
||||||
|
/// `vertex_index` (or `vertex_indices`) property;
|
||||||
|
/// - if three PLY properties `nx`, `ny` and `nz` with type `float`
|
||||||
|
/// or `double` are found for vertices, a "v:normal" vertex
|
||||||
|
/// property map is added;
|
||||||
|
/// - if three PLY properties `red`, `green` and `blue` with type
|
||||||
|
/// `uchar` are found for vertices, a "v:color" vertex property
|
||||||
|
/// map is added;
|
||||||
|
/// - if three PLY properties `red`, `green` and `blue` with type
|
||||||
|
/// `uchar` are found for faces, a "f:color" face property map is
|
||||||
|
/// added;
|
||||||
|
/// - if any other PLY property is found, a "[s]:[name]" property map is
|
||||||
|
/// added, where `[s]` is `v` for vertex and `f` for face, and
|
||||||
|
/// `[name]` is the name of the PLY property.
|
||||||
|
///
|
||||||
|
/// The `comments` parameter can be omitted. If provided, it will be
|
||||||
|
/// 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 (without the "comment " word).
|
||||||
|
///
|
||||||
|
/// \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.
|
||||||
|
/// \relates Surface_mesh
|
||||||
|
|
||||||
|
template <typename P>
|
||||||
|
bool read_ply(std::istream& is, Surface_mesh<P>& sm, std::string& comments)
|
||||||
|
{
|
||||||
|
if(!is)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: cannot open file" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal::PLY::PLY_reader reader;
|
||||||
|
internal::PLY::Surface_mesh_filler<P> filler(sm);
|
||||||
|
|
||||||
|
if (!(reader.init (is)))
|
||||||
|
{
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
comments = reader.comments();
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < reader.number_of_elements(); ++ i)
|
||||||
|
{
|
||||||
|
internal::PLY::PLY_element& element = reader.element(i);
|
||||||
|
|
||||||
|
bool is_vertex = (element.name() == "vertex" || element.name() == "vertices");
|
||||||
|
bool is_face = false;
|
||||||
|
bool is_edge = false;
|
||||||
|
bool is_halfedge = false;
|
||||||
|
if (is_vertex)
|
||||||
|
{
|
||||||
|
sm.reserve(sm.number_of_vertices() + element.number_of_items(),
|
||||||
|
sm.number_of_edges(),
|
||||||
|
sm.number_of_faces());
|
||||||
|
filler.instantiate_vertex_properties (element);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
is_face = (element.name() == "face" || element.name() == "faces");
|
||||||
|
|
||||||
|
if (is_face)
|
||||||
|
{
|
||||||
|
sm.reserve(sm.number_of_vertices(),
|
||||||
|
sm.number_of_edges(),
|
||||||
|
sm.number_of_faces() + element.number_of_items());
|
||||||
|
filler.instantiate_face_properties (element);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
is_edge = (element.name() == "edge");
|
||||||
|
|
||||||
|
if (is_edge)
|
||||||
|
filler.instantiate_edge_properties (element);
|
||||||
|
else
|
||||||
|
is_halfedge = (element.name() == "halfedge");
|
||||||
|
|
||||||
|
if (is_halfedge)
|
||||||
|
filler.instantiate_halfedge_properties (element);
|
||||||
|
|
||||||
|
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 (is);
|
||||||
|
if (is.fail())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_vertex)
|
||||||
|
filler.process_vertex_line (element);
|
||||||
|
else if (is_face)
|
||||||
|
{
|
||||||
|
if (!filler.process_face_line (element))
|
||||||
|
{
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (is_edge)
|
||||||
|
filler.process_edge_line (element);
|
||||||
|
else if (is_halfedge)
|
||||||
|
filler.process_halfedge_line (element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \relates Surface_mesh
|
/// \relates Surface_mesh
|
||||||
/// This operator calls `read_off(std::istream& is, CGAL::Surface_mesh& sm)`.
|
/// This operator calls `read_off(std::istream& is, CGAL::Surface_mesh& sm)`.
|
||||||
/// \attention Up to %CGAL 4.10 this operator called `sm.clear()`.
|
/// \attention Up to %CGAL 4.10 this operator called `sm.clear()`.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
ply
|
||||||
|
format ascii 1.0
|
||||||
|
element vertex 4
|
||||||
|
property double x
|
||||||
|
property double y
|
||||||
|
property double z
|
||||||
|
property double nx
|
||||||
|
property double ny
|
||||||
|
property double nz
|
||||||
|
property uchar red
|
||||||
|
property uchar green
|
||||||
|
property uchar blue
|
||||||
|
property int id
|
||||||
|
element face 4
|
||||||
|
property list uchar int vertex_indices
|
||||||
|
property uchar red
|
||||||
|
property uchar green
|
||||||
|
property uchar blue
|
||||||
|
property int label
|
||||||
|
element edge 6
|
||||||
|
property int v0
|
||||||
|
property int v1
|
||||||
|
property float confidence
|
||||||
|
end_header
|
||||||
|
0 0 0 -0.5 -0.5 -0.5 255 255 0 0
|
||||||
|
0 0 1 -0.5 -0.5 0 0 255 255 1
|
||||||
|
0 1 0 -0.5 0 -0.5 128 0 255 2
|
||||||
|
1 0 0 0 -0.5 -0.5 255 128 0 3
|
||||||
|
3 0 1 2 255 0 0 -1
|
||||||
|
3 0 3 1 0 255 0 1
|
||||||
|
3 1 3 2 0 0 255 -1
|
||||||
|
3 0 2 3 255 0 255 0
|
||||||
|
0 1 0.1
|
||||||
|
0 2 0.2
|
||||||
|
0 3 0.3
|
||||||
|
1 2 0.4
|
||||||
|
1 3 0.5
|
||||||
|
2 3 0.6
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include <CGAL/Surface_mesh/Surface_mesh.h>
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
|
typedef Kernel::Point_3 Point;
|
||||||
|
typedef CGAL::Surface_mesh<Point> SMesh;
|
||||||
|
typedef boost::graph_traits<SMesh>::face_descriptor face_descriptor;
|
||||||
|
typedef boost::graph_traits<SMesh>::vertex_descriptor vertex_descriptor;
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::ifstream in ("colored_tetra.ply");
|
||||||
|
SMesh mesh;
|
||||||
|
CGAL::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 ("tetra.ply");
|
||||||
|
CGAL::read_ply (in2, mesh);
|
||||||
|
|
||||||
|
std::ofstream out ("out.ply");
|
||||||
|
// CGAL::set_binary_mode(out);
|
||||||
|
CGAL::write_ply (out, mesh);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
ply
|
||||||
|
format ascii 1.0
|
||||||
|
element vertex 3
|
||||||
|
property double x
|
||||||
|
property double y
|
||||||
|
property double z
|
||||||
|
property int blabla
|
||||||
|
element face 1
|
||||||
|
property list uchar int vertex_indices
|
||||||
|
end_header
|
||||||
|
0 0 2 1000
|
||||||
|
0 1 2 200
|
||||||
|
1 0 2 30
|
||||||
|
3 0 1 2
|
||||||
|
|
@ -22,11 +22,11 @@ int main() {
|
||||||
t.insert(Point(2,2));
|
t.insert(Point(2,2));
|
||||||
|
|
||||||
Finite_faces_iterator fc = t.finite_faces_begin();
|
Finite_faces_iterator fc = t.finite_faces_begin();
|
||||||
for( ; fc != t.finite_faces_end(); ++fc) fc->info() = CGAL::BLUE;
|
for( ; fc != t.finite_faces_end(); ++fc) fc->info() = CGAL::blue();
|
||||||
|
|
||||||
Point p(0.5,0.5);
|
Point p(0.5,0.5);
|
||||||
Face_handle fh = t.locate(p);
|
Face_handle fh = t.locate(p);
|
||||||
fh->info() = CGAL::RED;
|
fh->info() = CGAL::red();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ int main()
|
||||||
Delaunay::Finite_vertices_iterator vit;
|
Delaunay::Finite_vertices_iterator vit;
|
||||||
for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit)
|
for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit)
|
||||||
if (T.degree(vit) == 6)
|
if (T.degree(vit) == 6)
|
||||||
vit->info() = CGAL::RED;
|
vit->info() = CGAL::red();
|
||||||
|
|
||||||
std::cout << " Visualization of T" << std::endl;
|
std::cout << " Visualization of T" << std::endl;
|
||||||
gv.set_wired(true);
|
gv.set_wired(true);
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ int main()
|
||||||
|
|
||||||
std::cout <<" Locating point (1,1,1) :" << std::endl;
|
std::cout <<" Locating point (1,1,1) :" << std::endl;
|
||||||
Point p(1,1,1);
|
Point p(1,1,1);
|
||||||
gv.set_vertex_color(CGAL::ORANGE);
|
gv.set_vertex_color(CGAL::orange());
|
||||||
gv << p;
|
gv << p;
|
||||||
Locate_type lt;
|
Locate_type lt;
|
||||||
int li, lj;
|
int li, lj;
|
||||||
|
|
@ -144,7 +144,7 @@ int main()
|
||||||
|
|
||||||
sleep(3);
|
sleep(3);
|
||||||
|
|
||||||
gv << CGAL::VIOLET;
|
gv << CGAL::violet();
|
||||||
if ( lt == Triangulation::CELL ) {
|
if ( lt == Triangulation::CELL ) {
|
||||||
std::cout <<" CELL" << std::endl;
|
std::cout <<" CELL" << std::endl;
|
||||||
visu_cell(gv,T,c);
|
visu_cell(gv,T,c);
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ int main()
|
||||||
gv << T;
|
gv << T;
|
||||||
|
|
||||||
std::cout <<" Visualizing the Voronoi edges" << std::endl;
|
std::cout <<" Visualizing the Voronoi edges" << std::endl;
|
||||||
gv << CGAL::RED;
|
gv << CGAL::red();
|
||||||
T.draw_dual(gv);
|
T.draw_dual(gv);
|
||||||
|
|
||||||
char ch;
|
char ch;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ int main()
|
||||||
Delaunay::Finite_vertices_iterator vit;
|
Delaunay::Finite_vertices_iterator vit;
|
||||||
for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit)
|
for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit)
|
||||||
if (T.degree(vit) == 6)
|
if (T.degree(vit) == 6)
|
||||||
vit->info() = CGAL::RED;
|
vit->info() = CGAL::red();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue