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