Point Cloud Library (PCL)  1.9.1
mesh_io.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2009-2012, Willow Garage, Inc.
6  * Copyright (c) 2012-, Open Perception, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of the copyright holder(s) nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * $Id$
38  *
39  */
40 
41 #ifndef PCL_GEOMETRY_MESH_IO_H
42 #define PCL_GEOMETRY_MESH_IO_H
43 
44 #include <fstream>
45 #include <string>
46 #include <sstream>
47 #include <iostream>
48 
49 namespace pcl
50 {
51  namespace geometry
52  {
53  /** \brief Read / write the half-edge mesh from / to a file.
54  * \tparam MeshT e.g. pcl::geometry::TriangleMesh or pcl::geometry::PolygonMesh
55  * \author Martin Saelzle
56  * \ingroup geometry
57  * \todo
58  * - Only writes the topology (not the mesh data).
59  * - Supports only ascii.
60  * - Does not consider the mesh traits (e.g. manifold or not)
61  */
62  template <class MeshT>
63  class MeshIO
64  {
65  public:
66 
67  typedef MeshT Mesh;
68 
69  typedef typename Mesh::Vertex Vertex;
70  typedef typename Mesh::HalfEdge HalfEdge;
71  typedef typename Mesh::Face Face;
72 
73  typedef typename Mesh::Vertices Vertices;
74  typedef typename Mesh::HalfEdges HalfEdges;
75  typedef typename Mesh::Faces Faces;
76 
77  typedef typename Mesh::VertexIndex VertexIndex;
78  typedef typename Mesh::HalfEdgeIndex HalfEdgeIndex;
79  typedef typename Mesh::FaceIndex FaceIndex;
80 
81  /** \brief Constructor. */
82  MeshIO ()
83  {
84  }
85 
86  /** \brief Read the mesh from a file with the given filename.
87  * \param[in] filename Path to the file.
88  * \param[out] mesh The loaded mesh.
89  * \return true if success.
90  */
91  bool
92  read (const std::string& filename, Mesh& mesh) const
93  {
94  std::ifstream file (filename.c_str ());
95 
96  if (!file.is_open ())
97  {
98  std::cerr << "Error in MeshIO::read: Could not open the file '" << filename << "'\n";
99  return (false);
100  }
101 
102  // Read the header
103  std::string line;
104  unsigned int line_number = 1;
105  int n_v = -1, n_he = -1, n_f = -1;
106 
107  if (!std::getline (file, line) || line.compare ("PCL half-edge mesh") != 0)
108  {
109  std::cerr << "Error loading '" << filename << "' (line " << line_number << "): Wrong file format.\n";
110  return (false);
111  }
112  ++line_number;
113 
114  if (!std::getline (file, line))
115  {
116  std::cerr << "Error loading '" << filename << "'' (line " << line_number << "): Number of vertices / half-edges / faces not found.\n";
117  return (false);
118  }
119  {
120  std::istringstream iss (line);
121  if (!(iss >> n_v >> n_he >> n_f) || iss.good ()) // Don't allow more than 3 en
122  {
123  std::cerr << "Error loading '" << filename << "'' (line " << line_number << "): Could not read the number of vertices / half-edges / faces.\n";
124  return (false);
125  }
126  }
127  if (n_v < 0 || n_he < 0 || n_f < 0)
128  {
129  std::cerr << "Error loading '" << filename << "'' (line " << line_number << "): Invalid number of vertices / half-edges / faces.\n";
130  return (false);
131  }
132  ++line_number;
133 
134  // Read the vertices.
135  {
136  mesh.vertices_.reserve (n_v);
137  HalfEdgeIndex idx_ohe; // Outgoing half-edge;
138 
139  for (int i=0; i<n_v; ++i, ++line_number)
140  {
141  if (!std::getline (file, line))
142  {
143  std::cerr << "Error loading '" << filename << "'' (line " << line_number << "): Could not read the line.\n";
144  return (false);
145  }
146 
147  std::istringstream iss (line);
148  if (!(iss >> idx_ohe) || iss.good ())
149  {
150  std::cerr << "Error loading '" << filename << "'' (line " << line_number << "): Could not read the vertex.\n";
151  return (false);
152  }
153  mesh.vertices_.push_back (Vertex (idx_ohe));
154  }
155  }
156 
157  // Read the half-edges.
158  {
159  mesh.half_edges_.reserve (n_he);
160  VertexIndex idx_tv; // Terminating vertex.
161  HalfEdgeIndex idx_nhe; // Next half-edge;
162  HalfEdgeIndex idx_phe; // Previous half-edge.
163  FaceIndex idx_f; // Face.
164 
165  for (int i=0; i<n_he; ++i, ++line_number)
166  {
167  if (!std::getline (file, line))
168  {
169  std::cerr << "Error loading '" << filename << "'' (line " << line_number << "): Could not read the line.\n";
170  return (false);
171  }
172 
173  std::istringstream iss (line);
174  if (!(iss >> idx_tv >> idx_nhe >> idx_phe >> idx_f) || iss.good ())
175  {
176  std::cerr << "Error loading '" << filename << "'' (line " << line_number << "): Could not read the half-edge.\n";
177  return (false);
178  }
179  mesh.half_edges_.push_back (HalfEdge (idx_tv, idx_nhe, idx_phe, idx_f));
180  }
181  }
182 
183  // Read the faces.
184  {
185  mesh.faces_.reserve (n_f);
186  HalfEdgeIndex idx_ihe; // Inner half-edge.
187 
188  for (int i=0; i<n_f; ++i, ++line_number)
189  {
190  if (!std::getline (file, line))
191  {
192  std::cerr << "Error loading '" << filename << "'' (line " << line_number << "): Could not read the line.\n";
193  return (false);
194  }
195 
196  std::istringstream iss (line);
197  if (!(iss >> idx_ihe) || iss.good ())
198  {
199  std::cerr << "Error loading '" << filename << "'' (line " << line_number << "): Could not read the face.\n";
200  return (false);
201  }
202  mesh.faces_.push_back (Face (idx_ihe));
203  }
204  }
205 
206  // Set the data
207  if (Mesh::HasVertexData::value) mesh.vertex_data_cloud_. resize (n_v);
208  if (Mesh::HasHalfEdgeData::value) mesh.half_edge_data_cloud_.resize (n_he);
209  if (Mesh::HasEdgeData::value) mesh.edge_data_cloud_. resize (n_he / 2);
210  if (Mesh::HasFaceData::value) mesh.face_data_cloud_. resize (n_f);
211 
212  return (true);
213  }
214 
215  /** \brief Write the mesh to a file with the given filename.
216  * \param[in] filename Path to the file.
217  * \param[in] mesh The saved mesh.
218  * \return true if success
219  */
220  bool
221  write (const std::string& filename, const Mesh& mesh) const
222  {
223  std::ofstream file (filename.c_str ());
224 
225  // Write the header
226  if (!file.is_open ())
227  {
228  std::cerr << "Error in MeshIO::write: Could not open the file '" << filename << "'\n";
229  return (false);
230  }
231 
232  file << "PCL half-edge mesh\n";
233  file << mesh.sizeVertices () << " "
234  << mesh.sizeHalfEdges () << " "
235  << mesh.sizeFaces () << "\n";
236 
237  // Write the vertices
238  for (typename Vertices::const_iterator it=mesh.vertices_.begin (); it!=mesh.vertices_.end (); ++it)
239  {
240  file << it->idx_outgoing_half_edge_ << "\n";
241  }
242 
243  // Write the half-edges
244  for (typename HalfEdges::const_iterator it=mesh.half_edges_.begin (); it!=mesh.half_edges_.end (); ++it)
245  {
246  file << it->idx_terminating_vertex_ << " "
247  << it->idx_next_half_edge_ << " "
248  << it->idx_prev_half_edge_ << " "
249  << it->idx_face_ << "\n";
250  }
251 
252  // Write the faces
253  for (typename Faces::const_iterator it=mesh.faces_.begin (); it!=mesh.faces_.end (); ++it)
254  {
255  file << it->idx_inner_half_edge_ << "\n";
256  }
257 
258  return (true);
259  }
260  };
261 
262  } // End namespace geometry
263 } // End namespace pcl
264 
265 #endif // PCL_GEOMETRY_MESH_IO_H
MeshIO()
Constructor.
Definition: mesh_io.h:82
Definition: surface.h:14
Mesh::Vertex Vertex
Definition: mesh_io.h:69
bool read(const std::string &filename, Mesh &mesh) const
Read the mesh from a file with the given filename.
Definition: mesh_io.h:92
Mesh::HalfEdges HalfEdges
Definition: mesh_io.h:74
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:45
Mesh::HalfEdge HalfEdge
Definition: mesh_io.h:70
Mesh::FaceIndex FaceIndex
Definition: mesh_io.h:79
Mesh::VertexIndex VertexIndex
Definition: mesh_io.h:77
Mesh::Faces Faces
Definition: mesh_io.h:75
bool write(const std::string &filename, const Mesh &mesh) const
Write the mesh to a file with the given filename.
Definition: mesh_io.h:221
Mesh::HalfEdgeIndex HalfEdgeIndex
Definition: mesh_io.h:78
Mesh::Face Face
Definition: mesh_io.h:71
Mesh::Vertices Vertices
Definition: mesh_io.h:73