Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
organized_fast_mesh.h
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2011, Dirk Holz, University of Bonn.
6  * Copyright (c) 2010-2011, Willow Garage, 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 Willow Garage, Inc. 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: organized_fast_mesh.h 5036 2012-03-12 08:54:15Z rusu $
38  *
39  */
40 
41 #ifndef PCL_SURFACE_ORGANIZED_FAST_MESH_H_
42 #define PCL_SURFACE_ORGANIZED_FAST_MESH_H_
43 
44 #include <pcl/common/angles.h>
46 
47 namespace pcl
48 {
49 
57  template <typename PointInT>
58  class OrganizedFastMesh : public MeshConstruction<PointInT>
59  {
60  public:
63 
65 
66  typedef std::vector<pcl::Vertices> Polygons;
67 
69  {
70  TRIANGLE_RIGHT_CUT, // _always_ "cuts" a quad from top left to bottom right
71  TRIANGLE_LEFT_CUT, // _always_ "cuts" a quad from top right to bottom left
72  TRIANGLE_ADAPTIVE_CUT, // "cuts" where possible and prefers larger differences in 'z' direction
73  QUAD_MESH // create a simple quad mesh
74  };
75 
78  : max_edge_length_squared_ (0.025f)
79  , triangle_pixel_size_ (1)
80  , triangulation_type_ (QUAD_MESH)
81  , store_shadowed_faces_ (false)
82  , cos_angle_tolerance_ (fabsf (cosf (pcl::deg2rad (12.5f))))
83  {
84  check_tree_ = false;
85  };
86 
89 
93  inline void
94  setMaxEdgeLength (float max_edge_length)
95  {
96  max_edge_length_squared_ = max_edge_length * max_edge_length;
97  };
98 
103  inline void
104  setTrianglePixelSize (int triangle_size)
105  {
106  triangle_pixel_size_ = std::max (1, (triangle_size - 1));
107  }
108 
113  inline void
115  {
116  triangulation_type_ = type;
117  }
118 
122  inline void
123  storeShadowedFaces (bool enable)
124  {
125  store_shadowed_faces_ = enable;
126  }
127 
128  protected:
130  float max_edge_length_squared_;
131 
133  int triangle_pixel_size_;
134 
136  TriangulationType triangulation_type_;
137 
139  bool store_shadowed_faces_;
140 
141  float cos_angle_tolerance_;
142 
146  void
147  reconstructPolygons (std::vector<pcl::Vertices>& polygons);
148 
152  virtual void
153  performReconstruction (std::vector<pcl::Vertices> &polygons);
154 
162  void
163  performReconstruction (pcl::PolygonMesh &output);
164 
172  inline void
173  addTriangle (int a, int b, int c, int idx, std::vector<pcl::Vertices>& polygons)
174  {
175  assert (idx < static_cast<int> (polygons.size ()));
176  polygons[idx].vertices.resize (3);
177  polygons[idx].vertices[0] = a;
178  polygons[idx].vertices[1] = b;
179  polygons[idx].vertices[2] = c;
180  }
181 
190  inline void
191  addQuad (int a, int b, int c, int d, int idx, std::vector<pcl::Vertices>& polygons)
192  {
193  assert (idx < static_cast<int> (polygons.size ()));
194  polygons[idx].vertices.resize (4);
195  polygons[idx].vertices[0] = a;
196  polygons[idx].vertices[1] = b;
197  polygons[idx].vertices[2] = c;
198  polygons[idx].vertices[3] = d;
199  }
200 
209  inline void
210  resetPointData (const int &point_index, pcl::PolygonMesh &mesh, const float &value = 0.0f,
211  int field_x_idx = 0, int field_y_idx = 1, int field_z_idx = 2)
212  {
213  float new_value = value;
214  memcpy (&mesh.cloud.data[point_index * mesh.cloud.point_step + mesh.cloud.fields[field_x_idx].offset], &new_value, sizeof (float));
215  memcpy (&mesh.cloud.data[point_index * mesh.cloud.point_step + mesh.cloud.fields[field_y_idx].offset], &new_value, sizeof (float));
216  memcpy (&mesh.cloud.data[point_index * mesh.cloud.point_step + mesh.cloud.fields[field_z_idx].offset], &new_value, sizeof (float));
217  }
218 
223  inline bool
224  isShadowed (const PointInT& point_a, const PointInT& point_b)
225  {
226  Eigen::Vector3f viewpoint = Eigen::Vector3f::Zero (); // TODO: allow for passing viewpoint information
227  Eigen::Vector3f dir_a = viewpoint - point_a.getVector3fMap ();
228  Eigen::Vector3f dir_b = point_b.getVector3fMap () - point_a.getVector3fMap ();
229  float distance_to_points = dir_a.norm ();
230  float distance_between_points = dir_b.norm ();
231  float cos_angle = dir_a.dot (dir_b) / (distance_to_points*distance_between_points);
232  if (cos_angle != cos_angle)
233  cos_angle = 1.0f;
234  return (fabs (cos_angle) >= cos_angle_tolerance_);
235  // TODO: check for both: angle almost 0/180 _and_ distance between points larger than noise level
236  }
237 
243  inline bool
244  isValidTriangle (const int& a, const int& b, const int& c)
245  {
246  if (!pcl::isFinite (input_->points[a])) return (false);
247  if (!pcl::isFinite (input_->points[b])) return (false);
248  if (!pcl::isFinite (input_->points[c])) return (false);
249  return (true);
250  }
251 
257  inline bool
258  isShadowedTriangle (const int& a, const int& b, const int& c)
259  {
260  if (isShadowed (input_->points[a], input_->points[b])) return (true);
261  if (isShadowed (input_->points[b], input_->points[c])) return (true);
262  if (isShadowed (input_->points[c], input_->points[a])) return (true);
263  return (false);
264  }
265 
272  inline bool
273  isValidQuad (const int& a, const int& b, const int& c, const int& d)
274  {
275  if (!pcl::isFinite (input_->points[a])) return (false);
276  if (!pcl::isFinite (input_->points[b])) return (false);
277  if (!pcl::isFinite (input_->points[c])) return (false);
278  if (!pcl::isFinite (input_->points[d])) return (false);
279  return (true);
280  }
281 
288  inline bool
289  isShadowedQuad (const int& a, const int& b, const int& c, const int& d)
290  {
291  if (isShadowed (input_->points[a], input_->points[b])) return (true);
292  if (isShadowed (input_->points[b], input_->points[c])) return (true);
293  if (isShadowed (input_->points[c], input_->points[d])) return (true);
294  if (isShadowed (input_->points[d], input_->points[a])) return (true);
295  return (false);
296  }
297 
301  void
302  makeQuadMesh (std::vector<pcl::Vertices>& polygons);
303 
307  void
308  makeRightCutMesh (std::vector<pcl::Vertices>& polygons);
309 
313  void
314  makeLeftCutMesh (std::vector<pcl::Vertices>& polygons);
315 
319  void
320  makeAdaptiveCutMesh (std::vector<pcl::Vertices>& polygons);
321  };
322 }
323 
324 #endif // PCL_SURFACE_ORGANIZED_FAST_MESH_H_