Handle edge/halfedge properties in PLY IO

This commit is contained in:
Simon Giraudot 2019-01-25 11:03:24 +01:00
parent ce125cf020
commit b206e04c58
4 changed files with 509 additions and 318 deletions

View File

@ -40,6 +40,8 @@ public:
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:
@ -71,6 +73,8 @@ private:
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;
@ -85,6 +89,8 @@ private:
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:
@ -98,6 +104,10 @@ public:
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)
@ -155,6 +165,22 @@ public:
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)
{
instantiate_properties<Vertex_index> (element, m_vertex_properties);
@ -165,6 +191,16 @@ public:
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)
@ -274,7 +310,7 @@ public:
bool process_face_line (PLY_element& element)
{
Face_index fi;
Face_index fi = m_mesh.null_face();
if (m_use_int32_t)
process_line<boost::int32_t>(element, fi);
@ -301,6 +337,8 @@ public:
vertices.push_back (Vertex_index (indices[i]));
fi = m_mesh.add_face(vertices);
if (fi == m_mesh.null_face())
return;
if (m_fcolors == 3)
{
@ -312,9 +350,368 @@ public:
}
}
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(Vertex_index(v0), Vertex_index(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(Vertex_index(source), Vertex_index(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

View File

@ -2163,6 +2163,10 @@ private: //------------------------------------------------------- private data
/// 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.
/// \relates Surface_mesh
template <typename P>
bool write_ply(std::ostream& os, const Surface_mesh<P>& sm, const std::string& comments = std::string())
@ -2172,23 +2176,9 @@ private: //------------------------------------------------------- private data
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<VIndex, P> Point_map;
typedef typename SMesh::template Property_map<VIndex, Vector> Vector_map;
typedef typename SMesh::template Property_map<VIndex, Color> Vcolor_map;
typedef typename SMesh::template Property_map<VIndex, boost::int8_t> Int8_map_v;
typedef typename SMesh::template Property_map<VIndex, boost::uint8_t> Uint8_map_v;
typedef typename SMesh::template Property_map<VIndex, boost::int16_t> Int16_map_v;
typedef typename SMesh::template Property_map<VIndex, boost::uint16_t> Uint16_map_v;
typedef typename SMesh::template Property_map<VIndex, boost::int32_t> Int32_map_v;
typedef typename SMesh::template Property_map<VIndex, boost::uint32_t> Uint32_map_v;
typedef typename SMesh::template Property_map<VIndex, boost::int64_t> Int64_map_v;
typedef typename SMesh::template Property_map<VIndex, boost::uint64_t> Uint64_map_v;
typedef typename SMesh::template Property_map<VIndex, float> Float_map_v;
typedef typename SMesh::template Property_map<VIndex, double> Double_map_v;
typedef typename SMesh::template Property_map<FIndex, Color> Fcolor_map;
typedef typename SMesh::template Property_map<FIndex, boost::int8_t> Int8_map_f;
@ -2218,314 +2208,33 @@ private: //------------------------------------------------------- private data
}
os << "element vertex " << sm.number_of_vertices() << std::endl;
std::vector<std::string> vprop = sm.template properties<VIndex>();
std::vector<internal::PLY::Abstract_property_printer<VIndex>*> vprinters;
for (std::size_t i = 0; i < vprop.size(); ++ i)
{
if (vprop[i] == "v:connectivity" ||
vprop[i] == "v:removed")
continue;
if (vprop[i] == "v:point")
{
if (boost::is_same<typename Get_FT_from_map<Point_map>::type, 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;
}
vprinters.push_back (new internal::PLY::Property_printer<VIndex,Point_map>(sm.points()));
continue;
}
bool okay = false;
if (vprop[i] == "v:normal")
{
Vector_map pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,Vector>(vprop[i]);
if (okay)
{
if (boost::is_same<typename Get_FT_from_map<Vector_map>::type, 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;
}
vprinters.push_back (new internal::PLY::Property_printer<VIndex,Vector_map>(pmap));
continue;
}
}
if (vprop[i] == "v:color")
{
Vcolor_map pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,Color>(vprop[i]);
if (okay)
{
os << "property uchar red" << std::endl
<< "property uchar green" << std::endl
<< "property uchar blue" << std::endl
<< "property uchar alpha" << std::endl;
vprinters.push_back (new internal::PLY::Property_printer<VIndex,Vcolor_map>(pmap));
continue;
}
}
// Cut the "v:" prefix
std::string name = vprop[i];
if (name.rfind("v:",0) == 0)
name = std::string (vprop[i].begin() + 2, vprop[i].end());
{
Int8_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,boost::int8_t>(vprop[i]);
if (okay)
{
os << "property char " << name << std::endl;
vprinters.push_back (new internal::PLY::Char_property_printer<VIndex,Int8_map_v>(pmap));
continue;
}
}
{
Uint8_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,boost::uint8_t>(vprop[i]);
if (okay)
{
os << "property uchar " << name << std::endl;
vprinters.push_back (new internal::PLY::Char_property_printer<VIndex,Uint8_map_v>(pmap));
continue;
}
}
{
Int16_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,boost::int16_t>(vprop[i]);
if (okay)
{
os << "property short " << name << std::endl;
vprinters.push_back (new internal::PLY::Simple_property_printer<VIndex,Int16_map_v>(pmap));
continue;
}
}
{
Uint16_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,boost::uint16_t>(vprop[i]);
if (okay)
{
os << "property ushort " << name << std::endl;
vprinters.push_back (new internal::PLY::Simple_property_printer<VIndex,Uint16_map_v>(pmap));
continue;
}
}
{
Int32_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,boost::int32_t>(vprop[i]);
if (okay)
{
os << "property int " << name << std::endl;
vprinters.push_back (new internal::PLY::Simple_property_printer<VIndex,Int32_map_v>(pmap));
continue;
}
}
{
Uint32_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,boost::uint32_t>(vprop[i]);
if (okay)
{
os << "property uint " << name << std::endl;
vprinters.push_back (new internal::PLY::Simple_property_printer<VIndex,Uint32_map_v>(pmap));
continue;
}
}
{
Int64_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,boost::int64_t>(vprop[i]);
if (okay)
{
os << "property int " << name << std::endl;
vprinters.push_back (new internal::PLY::Simple_property_printer<VIndex,Int64_map_v,boost::int32_t>(pmap));
continue;
}
}
{
Uint64_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,boost::uint64_t>(vprop[i]);
if (okay)
{
os << "property uint " << name << std::endl;
vprinters.push_back (new internal::PLY::Simple_property_printer<VIndex,Uint64_map_v,boost::uint32_t>(pmap));
continue;
}
}
{
Float_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,float>(vprop[i]);
if (okay)
{
os << "property float " << name << std::endl;
vprinters.push_back (new internal::PLY::Simple_property_printer<VIndex,Float_map_v>(pmap));
continue;
}
}
{
Double_map_v pmap;
boost::tie (pmap, okay) = sm.template property_map<VIndex,double>(vprop[i]);
if (okay)
{
os << "property double " << name << std::endl;
vprinters.push_back (new internal::PLY::Simple_property_printer<VIndex,Double_map_v>(pmap));
continue;
}
}
}
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<std::string> fprop = sm.template properties<FIndex>();
std::vector<internal::PLY::Abstract_property_printer<FIndex>*> fprinters;
for (std::size_t i = 0; i < fprop.size(); ++ i)
{
if (fprop[i] == "f:connectivity" ||
fprop[i] == "f:removed")
continue;
bool okay = false;
if (fprop[i] == "f:color")
{
Fcolor_map pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,Color>(fprop[i]);
if (okay)
{
os << "property uchar red" << std::endl
<< "property uchar green" << std::endl
<< "property uchar blue" << std::endl
<< "property uchar alpha" << std::endl;
internal::PLY::fill_header (os, sm, fprinters);
fprinters.push_back (new internal::PLY::Property_printer<FIndex,Fcolor_map>(pmap));
continue;
}
}
// Cut the "f:" prefix
std::string name = fprop[i];
if (name.rfind("f:",0) == 0)
name = std::string (fprop[i].begin() + 2, fprop[i].end());
{
Int8_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,boost::int8_t>(fprop[i]);
if (okay)
{
os << "property char " << name << std::endl;
fprinters.push_back (new internal::PLY::Char_property_printer<FIndex,Int8_map_f>(pmap));
continue;
}
}
{
Uint8_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,boost::uint8_t>(fprop[i]);
if (okay)
{
os << "property uchar " << name << std::endl;
fprinters.push_back (new internal::PLY::Char_property_printer<FIndex,Uint8_map_f>(pmap));
continue;
}
}
{
Int16_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,boost::int16_t>(fprop[i]);
if (okay)
{
os << "property short " << name << std::endl;
fprinters.push_back (new internal::PLY::Simple_property_printer<FIndex,Int16_map_f>(pmap));
continue;
}
}
{
Uint16_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,boost::uint16_t>(fprop[i]);
if (okay)
{
os << "property ushort " << name << std::endl;
fprinters.push_back (new internal::PLY::Simple_property_printer<FIndex,Uint16_map_f>(pmap));
continue;
}
}
{
Int32_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,boost::int32_t>(fprop[i]);
if (okay)
{
os << "property int " << name << std::endl;
fprinters.push_back (new internal::PLY::Simple_property_printer<FIndex,Int32_map_f>(pmap));
continue;
}
}
{
Uint32_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,boost::uint32_t>(fprop[i]);
if (okay)
{
os << "property uint " << name << std::endl;
fprinters.push_back (new internal::PLY::Simple_property_printer<FIndex,Uint32_map_f>(pmap));
continue;
}
}
{
Int64_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,boost::int64_t>(fprop[i]);
if (okay)
{
os << "property int " << name << std::endl;
fprinters.push_back (new internal::PLY::Simple_property_printer<FIndex,Int64_map_f,boost::int32_t>(pmap));
continue;
}
}
{
Uint64_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,boost::uint64_t>(fprop[i]);
if (okay)
{
os << "property uint " << name << std::endl;
fprinters.push_back (new internal::PLY::Simple_property_printer<FIndex,Uint64_map_f,boost::uint32_t>(pmap));
continue;
}
}
{
Float_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,float>(fprop[i]);
if (okay)
{
os << "property float " << name << std::endl;
fprinters.push_back (new internal::PLY::Simple_property_printer<FIndex,Float_map_f>(pmap));
continue;
}
}
{
Double_map_f pmap;
boost::tie (pmap, okay) = sm.template property_map<FIndex,double>(fprop[i]);
if (okay)
{
os << "property double " << name << std::endl;
fprinters.push_back (new internal::PLY::Simple_property_printer<FIndex,Double_map_f>(pmap));
continue;
}
}
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())
@ -2577,10 +2286,66 @@ private: //------------------------------------------------------- private data
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;
}
@ -2805,6 +2570,8 @@ private: //------------------------------------------------------- private data
bool is_vertex = (element.name() == "vertex" || element.name() == "vertices");
bool is_face = false;
bool is_edge = false;
bool is_halfedge = false;
if (is_vertex)
filler.instantiate_vertex_properties (element);
else
@ -2812,6 +2579,16 @@ private: //------------------------------------------------------- private data
if (is_face)
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)
{
@ -2833,6 +2610,10 @@ private: //------------------------------------------------------- private data
return false;
}
}
else if (is_edge)
filler.process_edge_line (element);
else if (is_halfedge)
filler.process_halfedge_line (element);
}
}

View File

@ -17,6 +17,10 @@ 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
@ -26,3 +30,9 @@ end_header
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

View File

@ -30,9 +30,12 @@ int main()
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);
std::ofstream out ("out.ply");
CGAL::set_binary_mode(out);
// CGAL::set_binary_mode(out);
CGAL::write_ply (out, mesh);
return 0;