721 lines
22 KiB
C++
721 lines
22 KiB
C++
// Copyright (c) 2018 GeometryFactory Sarl (France).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org).
|
|
//
|
|
// $URL: https://github.com/CGAL/cgal/blob/v5.1/Surface_mesh/include/CGAL/Surface_mesh/IO/PLY.h $
|
|
// $Id: PLY.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
|
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
|
//
|
|
//
|
|
// 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 CGAL::Surface_mesh<Point> Surface_mesh;
|
|
typedef typename Surface_mesh::size_type size_type;
|
|
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, size_type 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, size_type 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")
|
|
{
|
|
CGAL_assertion (dynamic_cast<PLY_read_typed_list<boost::int32_t>*>(property)
|
|
|| dynamic_cast<PLY_read_typed_list<boost::uint32_t>*>(property));
|
|
m_index_tag = name;
|
|
m_use_int32_t = dynamic_cast<PLY_read_typed_list<boost::int32_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
|