Point Cloud Library (PCL)  1.8.1-dev
gp3.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Willow Garage, Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  * $Id$
37  *
38  */
39 
40 #ifndef PCL_GP3_H_
41 #define PCL_GP3_H_
42 
43 // PCL includes
44 #include <pcl/surface/reconstruction.h>
45 #include <pcl/surface/boost.h>
46 
47 #include <pcl/conversions.h>
48 #include <pcl/kdtree/kdtree.h>
49 #include <pcl/kdtree/kdtree_flann.h>
50 #include <pcl/PolygonMesh.h>
51 
52 #include <fstream>
53 #include <iostream>
54 
55 
56 
57 namespace pcl
58 {
59  /** \brief Returns if a point X is visible from point R (or the origin)
60  * when taking into account the segment between the points S1 and S2
61  * \param X 2D coordinate of the point
62  * \param S1 2D coordinate of the segment's first point
63  * \param S2 2D coordinate of the segment's secont point
64  * \param R 2D coorddinate of the reference point (defaults to 0,0)
65  * \ingroup surface
66  */
67  inline bool
68  isVisible (const Eigen::Vector2f &X, const Eigen::Vector2f &S1, const Eigen::Vector2f &S2,
69  const Eigen::Vector2f &R = Eigen::Vector2f::Zero ())
70  {
71  double a0 = S1[1] - S2[1];
72  double b0 = S2[0] - S1[0];
73  double c0 = S1[0]*S2[1] - S2[0]*S1[1];
74  double a1 = -X[1];
75  double b1 = X[0];
76  double c1 = 0;
77  if (R != Eigen::Vector2f::Zero())
78  {
79  a1 += R[1];
80  b1 -= R[0];
81  c1 = R[0]*X[1] - X[0]*R[1];
82  }
83  double div = a0*b1 - b0*a1;
84  double x = (b0*c1 - b1*c0) / div;
85  double y = (a1*c0 - a0*c1) / div;
86 
87  bool intersection_outside_XR;
88  if (R == Eigen::Vector2f::Zero())
89  {
90  if (X[0] > 0)
91  intersection_outside_XR = (x <= 0) || (x >= X[0]);
92  else if (X[0] < 0)
93  intersection_outside_XR = (x >= 0) || (x <= X[0]);
94  else if (X[1] > 0)
95  intersection_outside_XR = (y <= 0) || (y >= X[1]);
96  else if (X[1] < 0)
97  intersection_outside_XR = (y >= 0) || (y <= X[1]);
98  else
99  intersection_outside_XR = true;
100  }
101  else
102  {
103  if (X[0] > R[0])
104  intersection_outside_XR = (x <= R[0]) || (x >= X[0]);
105  else if (X[0] < R[0])
106  intersection_outside_XR = (x >= R[0]) || (x <= X[0]);
107  else if (X[1] > R[1])
108  intersection_outside_XR = (y <= R[1]) || (y >= X[1]);
109  else if (X[1] < R[1])
110  intersection_outside_XR = (y >= R[1]) || (y <= X[1]);
111  else
112  intersection_outside_XR = true;
113  }
114  if (intersection_outside_XR)
115  return true;
116  else
117  {
118  if (S1[0] > S2[0])
119  return (x <= S2[0]) || (x >= S1[0]);
120  else if (S1[0] < S2[0])
121  return (x >= S2[0]) || (x <= S1[0]);
122  else if (S1[1] > S2[1])
123  return (y <= S2[1]) || (y >= S1[1]);
124  else if (S1[1] < S2[1])
125  return (y >= S2[1]) || (y <= S1[1]);
126  else
127  return false;
128  }
129  }
130 
131  /** \brief GreedyProjectionTriangulation is an implementation of a greedy triangulation algorithm for 3D points
132  * based on local 2D projections. It assumes locally smooth surfaces and relatively smooth transitions between
133  * areas with different point densities.
134  * \author Zoltan Csaba Marton
135  * \ingroup surface
136  */
137  template <typename PointInT>
139  {
140  public:
141  typedef boost::shared_ptr<GreedyProjectionTriangulation<PointInT> > Ptr;
142  typedef boost::shared_ptr<const GreedyProjectionTriangulation<PointInT> > ConstPtr;
143 
147 
148  typedef typename pcl::KdTree<PointInT> KdTree;
150 
154 
155  enum GP3Type
156  {
157  NONE = -1, // not-defined
158  FREE = 0,
159  FRINGE = 1,
160  BOUNDARY = 2,
162  };
163 
164  /** \brief Empty constructor. */
166  mu_ (0),
167  search_radius_ (0), // must be set by user
168  nnn_ (100),
169  minimum_angle_ (M_PI/18), // 10 degrees
170  maximum_angle_ (2*M_PI/3), // 120 degrees
171  eps_angle_(M_PI/4), //45 degrees,
172  consistent_(false),
173  consistent_ordering_ (false),
174  triangle_ (),
175  coords_ (),
176  angles_ (),
177  R_ (),
178  state_ (),
179  source_ (),
180  ffn_ (),
181  sfn_ (),
182  part_ (),
183  fringe_queue_ (),
184  is_current_free_ (false),
185  current_index_ (),
186  prev_is_ffn_ (false),
187  prev_is_sfn_ (false),
188  next_is_ffn_ (false),
189  next_is_sfn_ (false),
190  changed_1st_fn_ (false),
191  changed_2nd_fn_ (false),
192  new2boundary_ (),
193  already_connected_ (false),
194  proj_qp_ (),
195  u_ (),
196  v_ (),
197  uvn_ffn_ (),
198  uvn_sfn_ (),
199  uvn_next_ffn_ (),
200  uvn_next_sfn_ (),
201  tmp_ ()
202  {};
203 
204  /** \brief Set the multiplier of the nearest neighbor distance to obtain the final search radius for each point
205  * (this will make the algorithm adapt to different point densities in the cloud).
206  * \param[in] mu the multiplier
207  */
208  inline void
209  setMu (double mu) { mu_ = mu; }
210 
211  /** \brief Get the nearest neighbor distance multiplier. */
212  inline double
213  getMu () const { return (mu_); }
214 
215  /** \brief Set the maximum number of nearest neighbors to be searched for.
216  * \param[in] nnn the maximum number of nearest neighbors
217  */
218  inline void
219  setMaximumNearestNeighbors (int nnn) { nnn_ = nnn; }
220 
221  /** \brief Get the maximum number of nearest neighbors to be searched for. */
222  inline int
223  getMaximumNearestNeighbors () const { return (nnn_); }
224 
225  /** \brief Set the sphere radius that is to be used for determining the k-nearest neighbors used for triangulating.
226  * \param[in] radius the sphere radius that is to contain all k-nearest neighbors
227  * \note This distance limits the maximum edge length!
228  */
229  inline void
230  setSearchRadius (double radius) { search_radius_ = radius; }
231 
232  /** \brief Get the sphere radius used for determining the k-nearest neighbors. */
233  inline double
234  getSearchRadius () const { return (search_radius_); }
235 
236  /** \brief Set the minimum angle each triangle should have.
237  * \param[in] minimum_angle the minimum angle each triangle should have
238  * \note As this is a greedy approach, this will have to be violated from time to time
239  */
240  inline void
241  setMinimumAngle (double minimum_angle) { minimum_angle_ = minimum_angle; }
242 
243  /** \brief Get the parameter for distance based weighting of neighbors. */
244  inline double
245  getMinimumAngle () const { return (minimum_angle_); }
246 
247  /** \brief Set the maximum angle each triangle can have.
248  * \param[in] maximum_angle the maximum angle each triangle can have
249  * \note For best results, its value should be around 120 degrees
250  */
251  inline void
252  setMaximumAngle (double maximum_angle) { maximum_angle_ = maximum_angle; }
253 
254  /** \brief Get the parameter for distance based weighting of neighbors. */
255  inline double
256  getMaximumAngle () const { return (maximum_angle_); }
257 
258  /** \brief Don't consider points for triangulation if their normal deviates more than this value from the query point's normal.
259  * \param[in] eps_angle maximum surface angle
260  * \note As normal estimation methods usually give smooth transitions at sharp edges, this ensures correct triangulation
261  * by avoiding connecting points from one side to points from the other through forcing the use of the edge points.
262  */
263  inline void
264  setMaximumSurfaceAngle (double eps_angle) { eps_angle_ = eps_angle; }
265 
266  /** \brief Get the maximum surface angle. */
267  inline double
268  getMaximumSurfaceAngle () const { return (eps_angle_); }
269 
270  /** \brief Set the flag if the input normals are oriented consistently.
271  * \param[in] consistent set it to true if the normals are consistently oriented
272  */
273  inline void
274  setNormalConsistency (bool consistent) { consistent_ = consistent; }
275 
276  /** \brief Get the flag for consistently oriented normals. */
277  inline bool
278  getNormalConsistency () const { return (consistent_); }
279 
280  /** \brief Set the flag to order the resulting triangle vertices consistently (positive direction around normal).
281  * @note Assumes consistently oriented normals (towards the viewpoint) -- see setNormalConsistency ()
282  * \param[in] consistent_ordering set it to true if triangle vertices should be ordered consistently
283  */
284  inline void
285  setConsistentVertexOrdering (bool consistent_ordering) { consistent_ordering_ = consistent_ordering; }
286 
287  /** \brief Get the flag signaling consistently ordered triangle vertices. */
288  inline bool
290 
291  /** \brief Get the state of each point after reconstruction.
292  * \note Options are defined as constants: FREE, FRINGE, COMPLETED, BOUNDARY and NONE
293  */
294  inline std::vector<int>
295  getPointStates () const { return (state_); }
296 
297  /** \brief Get the ID of each point after reconstruction.
298  * \note parts are numbered from 0, a -1 denotes unconnected points
299  */
300  inline std::vector<int>
301  getPartIDs () const { return (part_); }
302 
303 
304  /** \brief Get the sfn list. */
305  inline std::vector<int>
306  getSFN () const { return (sfn_); }
307 
308  /** \brief Get the ffn list. */
309  inline std::vector<int>
310  getFFN () const { return (ffn_); }
311 
312  protected:
313  /** \brief The nearest neighbor distance multiplier to obtain the final search radius. */
314  double mu_;
315 
316  /** \brief The nearest neighbors search radius for each point and the maximum edge length. */
318 
319  /** \brief The maximum number of nearest neighbors accepted by searching. */
320  int nnn_;
321 
322  /** \brief The preferred minimum angle for the triangles. */
324 
325  /** \brief The maximum angle for the triangles. */
327 
328  /** \brief Maximum surface angle. */
329  double eps_angle_;
330 
331  /** \brief Set this to true if the normals of the input are consistently oriented. */
333 
334  /** \brief Set this to true if the output triangle vertices should be consistently oriented. */
336 
337  private:
338  /** \brief Struct for storing the angles to nearest neighbors **/
339  struct nnAngle
340  {
341  double angle;
342  int index;
343  int nnIndex;
344  bool visible;
345  };
346 
347  /** \brief Struct for storing the edges starting from a fringe point **/
348  struct doubleEdge
349  {
350  doubleEdge () : index (0), first (), second () {}
351  int index;
352  Eigen::Vector2f first;
353  Eigen::Vector2f second;
354  };
355 
356  // Variables made global to decrease the number of parameters to helper functions
357 
358  /** \brief Temporary variable to store a triangle (as a set of point indices) **/
359  pcl::Vertices triangle_;
360  /** \brief Temporary variable to store point coordinates **/
361  std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> > coords_;
362 
363  /** \brief A list of angles to neighbors **/
364  std::vector<nnAngle> angles_;
365  /** \brief Index of the current query point **/
366  int R_;
367  /** \brief List of point states **/
368  std::vector<int> state_;
369  /** \brief List of sources **/
370  std::vector<int> source_;
371  /** \brief List of fringe neighbors in one direction **/
372  std::vector<int> ffn_;
373  /** \brief List of fringe neighbors in other direction **/
374  std::vector<int> sfn_;
375  /** \brief Connected component labels for each point **/
376  std::vector<int> part_;
377  /** \brief Points on the outer edge from which the mesh has to be grown **/
378  std::vector<int> fringe_queue_;
379 
380  /** \brief Flag to set if the current point is free **/
381  bool is_current_free_;
382  /** \brief Current point's index **/
383  int current_index_;
384  /** \brief Flag to set if the previous point is the first fringe neighbor **/
385  bool prev_is_ffn_;
386  /** \brief Flag to set if the next point is the second fringe neighbor **/
387  bool prev_is_sfn_;
388  /** \brief Flag to set if the next point is the first fringe neighbor **/
389  bool next_is_ffn_;
390  /** \brief Flag to set if the next point is the second fringe neighbor **/
391  bool next_is_sfn_;
392  /** \brief Flag to set if the first fringe neighbor was changed **/
393  bool changed_1st_fn_;
394  /** \brief Flag to set if the second fringe neighbor was changed **/
395  bool changed_2nd_fn_;
396  /** \brief New boundary point **/
397  int new2boundary_;
398 
399  /** \brief Flag to set if the next neighbor was already connected in the previous step.
400  * To avoid inconsistency it should not be connected again.
401  */
402  bool already_connected_;
403 
404  /** \brief Point coordinates projected onto the plane defined by the point normal **/
405  Eigen::Vector3f proj_qp_;
406  /** \brief First coordinate vector of the 2D coordinate frame **/
407  Eigen::Vector3f u_;
408  /** \brief Second coordinate vector of the 2D coordinate frame **/
409  Eigen::Vector3f v_;
410  /** \brief 2D coordinates of the first fringe neighbor **/
411  Eigen::Vector2f uvn_ffn_;
412  /** \brief 2D coordinates of the second fringe neighbor **/
413  Eigen::Vector2f uvn_sfn_;
414  /** \brief 2D coordinates of the first fringe neighbor of the next point **/
415  Eigen::Vector2f uvn_next_ffn_;
416  /** \brief 2D coordinates of the second fringe neighbor of the next point **/
417  Eigen::Vector2f uvn_next_sfn_;
418 
419  /** \brief Temporary variable to store 3 coordiantes **/
420  Eigen::Vector3f tmp_;
421 
422  /** \brief The actual surface reconstruction method.
423  * \param[out] output the resultant polygonal mesh
424  */
425  void
426  performReconstruction (pcl::PolygonMesh &output);
427 
428  /** \brief The actual surface reconstruction method.
429  * \param[out] polygons the resultant polygons, as a set of vertices. The Vertices structure contains an array of point indices.
430  */
431  void
432  performReconstruction (std::vector<pcl::Vertices> &polygons);
433 
434  /** \brief The actual surface reconstruction method.
435  * \param[out] polygons the resultant polygons, as a set of vertices. The Vertices structure contains an array of point indices.
436  */
437  bool
438  reconstructPolygons (std::vector<pcl::Vertices> &polygons);
439 
440  /** \brief Class get name method. */
441  std::string
442  getClassName () const { return ("GreedyProjectionTriangulation"); }
443 
444  /** \brief Forms a new triangle by connecting the current neighbor to the query point
445  * and the previous neighbor
446  * \param[out] polygons the polygon mesh to be updated
447  * \param[in] prev_index index of the previous point
448  * \param[in] next_index index of the next point
449  * \param[in] next_next_index index of the point after the next one
450  * \param[in] uvn_current 2D coordinate of the current point
451  * \param[in] uvn_prev 2D coordinates of the previous point
452  * \param[in] uvn_next 2D coordinates of the next point
453  */
454  void
455  connectPoint (std::vector<pcl::Vertices> &polygons,
456  const int prev_index,
457  const int next_index,
458  const int next_next_index,
459  const Eigen::Vector2f &uvn_current,
460  const Eigen::Vector2f &uvn_prev,
461  const Eigen::Vector2f &uvn_next);
462 
463  /** \brief Whenever a query point is part of a boundary loop containing 3 points, that triangle is created
464  * (called if angle constraints make it possible)
465  * \param[out] polygons the polygon mesh to be updated
466  */
467  void
468  closeTriangle (std::vector<pcl::Vertices> &polygons);
469 
470  /** \brief Get the list of containing triangles for each vertex in a PolygonMesh
471  * \param[in] polygonMesh the input polygon mesh
472  */
473  std::vector<std::vector<size_t> >
474  getTriangleList (const pcl::PolygonMesh &input);
475 
476  /** \brief Add a new triangle to the current polygon mesh
477  * \param[in] a index of the first vertex
478  * \param[in] b index of the second vertex
479  * \param[in] c index of the third vertex
480  * \param[out] polygons the polygon mesh to be updated
481  */
482  inline void
483  addTriangle (int a, int b, int c, std::vector<pcl::Vertices> &polygons)
484  {
485  triangle_.vertices.resize (3);
487  {
488  const PointInT p = input_->at (indices_->at (a));
489  const Eigen::Vector3f pv = p.getVector3fMap ();
490  if (p.getNormalVector3fMap ().dot (
491  (pv - input_->at (indices_->at (b)).getVector3fMap ()).cross (
492  pv - input_->at (indices_->at (c)).getVector3fMap ()) ) > 0)
493  {
494  triangle_.vertices[0] = a;
495  triangle_.vertices[1] = b;
496  triangle_.vertices[2] = c;
497  }
498  else
499  {
500  triangle_.vertices[0] = a;
501  triangle_.vertices[1] = c;
502  triangle_.vertices[2] = b;
503  }
504  }
505  else
506  {
507  triangle_.vertices[0] = a;
508  triangle_.vertices[1] = b;
509  triangle_.vertices[2] = c;
510  }
511  polygons.push_back (triangle_);
512  }
513 
514  /** \brief Add a new vertex to the advancing edge front and set its source point
515  * \param[in] v index of the vertex that was connected
516  * \param[in] s index of the source point
517  */
518  inline void
519  addFringePoint (int v, int s)
520  {
521  source_[v] = s;
522  part_[v] = part_[s];
523  fringe_queue_.push_back(v);
524  }
525 
526  /** \brief Function for ascending sort of nnAngle, taking visibility into account
527  * (angles to visible neighbors will be first, to the invisible ones after).
528  * \param[in] a1 the first angle
529  * \param[in] a2 the second angle
530  */
531  static inline bool
532  nnAngleSortAsc (const nnAngle& a1, const nnAngle& a2)
533  {
534  if (a1.visible == a2.visible)
535  return (a1.angle < a2.angle);
536  else
537  return a1.visible;
538  }
539  };
540 
541 } // namespace pcl
542 
543 #ifdef PCL_NO_PRECOMPILE
544 #include <pcl/surface/impl/gp3.hpp>
545 #endif
546 
547 #endif //#ifndef PCL_GP3_H_
548 
double getMaximumAngle() const
Get the parameter for distance based weighting of neighbors.
Definition: gp3.h:256
boost::shared_ptr< const PointCloud< PointT > > ConstPtr
Definition: point_cloud.h:429
void setConsistentVertexOrdering(bool consistent_ordering)
Set the flag to order the resulting triangle vertices consistently (positive direction around normal)...
Definition: gp3.h:285
bool getConsistentVertexOrdering() const
Get the flag signaling consistently ordered triangle vertices.
Definition: gp3.h:289
boost::shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:428
std::vector< uint32_t > vertices
Definition: Vertices.h:19
double getMinimumAngle() const
Get the parameter for distance based weighting of neighbors.
Definition: gp3.h:245
void setMu(double mu)
Set the multiplier of the nearest neighbor distance to obtain the final search radius for each point ...
Definition: gp3.h:209
bool isVisible(const Eigen::Vector2f &X, const Eigen::Vector2f &S1, const Eigen::Vector2f &S2, const Eigen::Vector2f &R=Eigen::Vector2f::Zero())
Returns if a point X is visible from point R (or the origin) when taking into account the segment bet...
Definition: gp3.h:68
IndicesPtr indices_
A pointer to the vector of point indices to use.
Definition: pcl_base.h:153
pcl::PointCloud< PointInT > PointCloudIn
Definition: gp3.h:151
boost::shared_ptr< KdTree< PointT > > Ptr
Definition: kdtree.h:71
boost::shared_ptr< const GreedyProjectionTriangulation< PointInT > > ConstPtr
Definition: gp3.h:142
double getMaximumSurfaceAngle() const
Get the maximum surface angle.
Definition: gp3.h:268
std::vector< int > getSFN() const
Get the sfn list.
Definition: gp3.h:306
bool getNormalConsistency() const
Get the flag for consistently oriented normals.
Definition: gp3.h:278
Describes a set of vertices in a polygon mesh, by basically storing an array of indices.
Definition: Vertices.h:14
std::vector< int > getPartIDs() const
Get the ID of each point after reconstruction.
Definition: gp3.h:301
double getMu() const
Get the nearest neighbor distance multiplier.
Definition: gp3.h:213
double mu_
The nearest neighbor distance multiplier to obtain the final search radius.
Definition: gp3.h:314
double getSearchRadius() const
Get the sphere radius used for determining the k-nearest neighbors.
Definition: gp3.h:234
int nnn_
The maximum number of nearest neighbors accepted by searching.
Definition: gp3.h:320
void setMaximumNearestNeighbors(int nnn)
Set the maximum number of nearest neighbors to be searched for.
Definition: gp3.h:219
double minimum_angle_
The preferred minimum angle for the triangles.
Definition: gp3.h:323
pcl::KdTree< PointInT > KdTree
Definition: gp3.h:148
void setMinimumAngle(double minimum_angle)
Set the minimum angle each triangle should have.
Definition: gp3.h:241
GreedyProjectionTriangulation is an implementation of a greedy triangulation algorithm for 3D points ...
Definition: gp3.h:138
bool consistent_
Set this to true if the normals of the input are consistently oriented.
Definition: gp3.h:332
int getMaximumNearestNeighbors() const
Get the maximum number of nearest neighbors to be searched for.
Definition: gp3.h:223
GreedyProjectionTriangulation()
Empty constructor.
Definition: gp3.h:165
MeshConstruction represents a base surface reconstruction class.
void setMaximumSurfaceAngle(double eps_angle)
Don't consider points for triangulation if their normal deviates more than this value from the query ...
Definition: gp3.h:264
double eps_angle_
Maximum surface angle.
Definition: gp3.h:329
pcl::KdTree< PointInT >::Ptr KdTreePtr
Definition: gp3.h:149
std::vector< int > getFFN() const
Get the ffn list.
Definition: gp3.h:310
void setSearchRadius(double radius)
Set the sphere radius that is to be used for determining the k-nearest neighbors used for triangulati...
Definition: gp3.h:230
void setMaximumAngle(double maximum_angle)
Set the maximum angle each triangle can have.
Definition: gp3.h:252
void setNormalConsistency(bool consistent)
Set the flag if the input normals are oriented consistently.
Definition: gp3.h:274
double maximum_angle_
The maximum angle for the triangles.
Definition: gp3.h:326
PointCloudConstPtr input_
The input point cloud dataset.
Definition: pcl_base.h:150
bool consistent_ordering_
Set this to true if the output triangle vertices should be consistently oriented. ...
Definition: gp3.h:335
double search_radius_
The nearest neighbors search radius for each point and the maximum edge length.
Definition: gp3.h:317
std::vector< int > getPointStates() const
Get the state of each point after reconstruction.
Definition: gp3.h:295
PointCloudIn::Ptr PointCloudInPtr
Definition: gp3.h:152
KdTree represents the base spatial locator class for kd-tree implementations.
Definition: kdtree.h:56
PointCloudIn::ConstPtr PointCloudInConstPtr
Definition: gp3.h:153
boost::shared_ptr< GreedyProjectionTriangulation< PointInT > > Ptr
Definition: gp3.h:141