MEPP2 Project
cgal_point_set_reader.hpp
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as
6 // published by the Free Software Foundation; either version 3 of
7 // the License, or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 #pragma once
12 
15 
17 
18 #include "FEVV/Tools/IO/FileUtilities.hpp" // for FileUtils::has_extension()
19 
20 #include <CGAL/Point_set_3/IO.h>
21 #include <CGAL/IO/read_ply_points.h>
22 #include <stdexcept> // for std::invalid_argument
23 #include <string> // for std::getline
24 
25 
26 namespace FEVV {
27 
28 // parse PLY header to detect normals and colors
29 inline
30 void
31 parse_ply_header(std::ifstream &in, bool &has_normal, bool &has_color,
32  bool &is_binary)
33 {
34  in.seekg(0); // rewind
35  has_normal = false;
36  has_color = false;
37  is_binary = false;
38 
39  std::string line, word;
40 
41  do
42  {
43  std::getline(in, line);
44  std::istringstream line_ss(line);
45 
46  // look for line "property ... nx" and "property ... r"
47  line_ss >> word;
48  if(word == "property")
49  {
50  line_ss >> word;
51  line_ss >> word;
52 
53  if(word == "nx")
54  {
55  has_normal = true;
56  }
57  else if(word == "red")
58  {
59  has_color = true;
60  }
61  }
62  // look for line "format ..."
63  else if(word == "format")
64  {
65  line_ss >> word;
66 
67  if(word == "binary_little_endian" || word == "binary_big_endian")
68  {
69  is_binary = true;
70  }
71  }
72  }
73  while(word != "end_header");
74 
75  in.seekg(0); // rewind
76 }
77 
78 
79 // Functor to be able to use CGALPointSetColor with
80 // CGAL::read_ply_points_with_properties()
82 {
83  FEVV::CGALPointSetColor operator()(const unsigned char &r,
84  const unsigned char &g,
85  const unsigned char &b)
86  {
87  return FEVV::CGALPointSetColor(r, g, b);
88  }
89 };
90 
91 } // namespace FEVV
92 
93 
94 namespace FEVV {
95 namespace Filters {
96 
97 
108 inline
109 void
111  const std::string &filename,
113  PMapsContainer &pmaps,
114  bool /*only_pts*/ = false)
115 {
116 #if 1
117  bool success = false;
118 
119  // open input file
120  std::ifstream in(filename);
121  if(! in)
122  {
123  throw std::invalid_argument("read_mesh() error: can not open file " +
124  filename + ".");
125  }
126 
127  // load point cloud
128  if(FEVV::FileUtils::has_extension(filename, ".xyz"))
129  {
130  // load geometry + normal
131  success = CGAL::read_xyz_point_set(in, g);
132 
133  if(g.has_normal_map())
134  put_property_map(FEVV::vertex_normal, g, pmaps, g.normal_map());
135  }
136  else if(FEVV::FileUtils::has_extension(filename, ".off"))
137  {
138  // load geometry + normal
139  success = CGAL::read_off_point_set(in, g);
140 
141  if(g.has_normal_map())
142  put_property_map(FEVV::vertex_normal, g, pmaps, g.normal_map());
143  }
144  else if(FEVV::FileUtils::has_extension(filename, ".ply"))
145  {
146  // parse ply header to detect normals and colors
147  bool has_normal;
148  bool has_color;
149  bool is_binary;
150  parse_ply_header(in, has_normal, has_color, is_binary);
151 
152  // re-open file in binary mode if needed
153  if(is_binary)
154  {
155  in.close();
156  in.open(filename, std::ios::binary);
157 
158  if(! in)
159  {
160  throw std::invalid_argument("read_mesh() error: can not open file " +
161  filename + " in binary mode.");
162  }
163  }
164 
165  // create needed property maps
166  using VertexNormalMap =
168  FEVV::CGALPointSet >::pmap_type;
169  using VertexColorMap =
171  FEVV::CGALPointSet >::pmap_type;
172  VertexNormalMap v_nm;
173  VertexColorMap v_cm;
174 
175  if(has_normal)
176  {
178  put_property_map(FEVV::vertex_normal, g, pmaps, v_nm);
179  }
180 
181  if(has_color)
182  {
184  put_property_map(FEVV::vertex_color, g, pmaps, v_cm);
185  }
186 
187  if(has_normal && has_color)
188  {
189  success = CGAL::read_ply_points_with_properties(
190  in,
191  g.index_back_inserter(),
192  CGAL::make_ply_point_reader(g.point_push_map()),
193  CGAL::make_ply_normal_reader(g.push_property_map(v_nm)),
194  std::make_tuple(g.push_property_map(v_cm),
196  CGAL::PLY_property< unsigned char >("red"),
197  CGAL::PLY_property< unsigned char >("green"),
198  CGAL::PLY_property< unsigned char >("blue")));
199  // see https://doc.cgal.org/latest/Point_set_processing_3/Point_set_processing_3_2read_ply_points_with_colors_example_8cpp-example.html#a7
200  }
201  else if(has_normal)
202  {
203  success = CGAL::read_ply_points_with_properties(
204  in,
205  g.index_back_inserter(),
206  CGAL::make_ply_point_reader(g.point_push_map()),
207  CGAL::make_ply_normal_reader(g.push_property_map(v_nm)));
208  }
209  else if(has_color)
210  {
211  success = CGAL::read_ply_points_with_properties(
212  in,
213  g.index_back_inserter(),
214  CGAL::make_ply_point_reader(g.point_push_map()),
215  std::make_tuple(g.push_property_map(v_cm),
217  CGAL::PLY_property< unsigned char >("red"),
218  CGAL::PLY_property< unsigned char >("green"),
219  CGAL::PLY_property< unsigned char >("blue")));
220  // see https://doc.cgal.org/latest/Point_set_processing_3/Point_set_processing_3_2read_ply_points_with_colors_example_8cpp-example.html#a7
221  }
222  else
223  {
224  success = CGAL::read_ply_points_with_properties(
225  in,
226  g.index_back_inserter(),
227  CGAL::make_ply_point_reader(g.point_push_map()));
228  }
229  }
230 
231  if(! success)
232  {
233  throw std::invalid_argument("read_mesh() error: can not read file " +
234  filename + ".");
235  }
236 #else
237  // DBG
238  g.push_back(FEVV::CGALPoint(-1, -1, 2));
239  g.push_back(FEVV::CGALPoint(-1, 1, 2));
240  g.push_back(FEVV::CGALPoint( 1, 1, 2));
241  g.push_back(FEVV::CGALPoint( 1, -1, 2));
242 #endif
243 }
244 
245 
246 } // namespace Filters
247 } // namespace FEVV
FEVV::put_property_map
void put_property_map(PropertyT p, const MeshT &, PMapsContainer &pmaps, const typename PMap_traits< PropertyT, MeshT >::pmap_type &pmap)
Definition: properties.h:664
Wrappings_cgal_point_set.h
FEVV::CGALPointSet
CGAL::Point_set_3< CGALPointSetPoint > CGALPointSet
Definition: DataStructures_cgal_point_set.h:71
DataStructures_cgal_point_set.h
FEVV::PMapsContainer
std::map< std::string, boost::any > PMapsContainer
Definition: properties.h:99
FEVV::vertex_normal_t
vertex_normal_t
Definition: properties.h:35
FEVV::vertex_color_t
vertex_color_t
Definition: properties.h:47
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::parse_ply_header
void parse_ply_header(std::ifstream &in, bool &has_normal, bool &has_color, bool &is_binary)
Definition: cgal_point_set_reader.hpp:31
FEVV::Filters::read_mesh
void read_mesh(const std::string &filename, FEVV::CGALPointSet &g, PMapsContainer &pmaps, bool=false)
Load mesh from file.
Definition: cgal_point_set_reader.hpp:110
FEVV::vertex_color
@ vertex_color
Definition: properties.h:47
FEVV::Construct_color::operator()
FEVV::CGALPointSetColor operator()(const unsigned char &r, const unsigned char &g, const unsigned char &b)
Definition: cgal_point_set_reader.hpp:83
FEVV::Construct_color
Definition: cgal_point_set_reader.hpp:82
FEVV::CGALPoint
CGALKernel::Point_3 CGALPoint
Definition: DataStructures_cgal_surface_mesh.h:21
FEVV::CGALPointSetColor
Definition: DataStructures_cgal_point_set.h:40
FEVV::FileUtils::has_extension
bool has_extension(const std::string &file_name)
Definition: FileUtilities.hpp:58
FEVV::_PMap_traits
Definition: properties.h:376
properties.h
FileUtilities.hpp
FEVV::vertex_normal
@ vertex_normal
Definition: properties.h:35
FEVV::make_property_map
PMap_traits< PropertyT, MeshT >::pmap_type make_property_map(PropertyT, const MeshT &m)
Definition: properties.h:630