|
Point Cloud Library (PCL)
1.5.1
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2011, Willow Garage, Inc. 00006 * 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 00013 * * Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * * Redistributions in binary form must reproduce the above 00016 * copyright notice, this list of conditions and the following 00017 * disclaimer in the documentation and/or other materials provided 00018 * with the distribution. 00019 * * Neither the name of Willow Garage, Inc. nor the names of its 00020 * contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00033 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 * POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 * $Id: gp3.h 4702 2012-02-23 09:39:33Z gedikli $ 00037 * 00038 */ 00039 00040 #ifndef PCL_GP3_H_ 00041 #define PCL_GP3_H_ 00042 00043 // PCL includes 00044 #include "pcl/surface/reconstruction.h" 00045 00046 #include "pcl/ros/conversions.h" 00047 #include "pcl/kdtree/kdtree.h" 00048 #include <pcl/kdtree/kdtree_flann.h> 00049 #include <pcl/PolygonMesh.h> 00050 #include <pcl/TextureMesh.h> 00051 #include <boost/function.hpp> 00052 00053 #include <fstream> 00054 #include <iostream> 00055 00056 // add by ktran to export update function 00057 #include <pcl/pcl_macros.h> 00058 #include <pcl/point_types.h> 00059 00060 00061 namespace pcl 00062 { 00063 // add by ktran for Kdtree_flaan search 00064 struct SearchPoint : public PointXYZ 00065 { 00066 SearchPoint(float x, float y, float z) {this->x=x; this->y=y; this->z=z;} 00067 }; 00068 00077 inline bool 00078 isVisible (const Eigen::Vector2f &X, const Eigen::Vector2f &S1, const Eigen::Vector2f &S2, 00079 const Eigen::Vector2f &R = Eigen::Vector2f::Zero ()) 00080 { 00081 double a0 = S1[1] - S2[1]; 00082 double b0 = S2[0] - S1[0]; 00083 double c0 = S1[0]*S2[1] - S2[0]*S1[1]; 00084 double a1 = -X[1]; 00085 double b1 = X[0]; 00086 double c1 = 0; 00087 if (R != Eigen::Vector2f::Zero()) 00088 { 00089 a1 += R[1]; 00090 b1 -= R[0]; 00091 c1 = R[0]*X[1] - X[0]*R[1]; 00092 } 00093 double div = a0*b1 - b0*a1; 00094 double x = (b0*c1 - b1*c0) / div; 00095 double y = (a1*c0 - a0*c1) / div; 00096 00097 bool intersection_outside_XR; 00098 if (R == Eigen::Vector2f::Zero()) 00099 { 00100 if (X[0] > 0) 00101 intersection_outside_XR = (x <= 0) || (x >= X[0]); 00102 else if (X[0] < 0) 00103 intersection_outside_XR = (x >= 0) || (x <= X[0]); 00104 else if (X[1] > 0) 00105 intersection_outside_XR = (y <= 0) || (y >= X[1]); 00106 else if (X[1] < 0) 00107 intersection_outside_XR = (y >= 0) || (y <= X[1]); 00108 else 00109 intersection_outside_XR = true; 00110 } 00111 else 00112 { 00113 if (X[0] > R[0]) 00114 intersection_outside_XR = (x <= R[0]) || (x >= X[0]); 00115 else if (X[0] < R[0]) 00116 intersection_outside_XR = (x >= R[0]) || (x <= X[0]); 00117 else if (X[1] > R[1]) 00118 intersection_outside_XR = (y <= R[1]) || (y >= X[1]); 00119 else if (X[1] < R[1]) 00120 intersection_outside_XR = (y >= R[1]) || (y <= X[1]); 00121 else 00122 intersection_outside_XR = true; 00123 } 00124 if (intersection_outside_XR) 00125 return true; 00126 else 00127 { 00128 if (S1[0] > S2[0]) 00129 return (x <= S2[0]) || (x >= S1[0]); 00130 else if (S1[0] < S2[0]) 00131 return (x >= S2[0]) || (x <= S1[0]); 00132 else if (S1[1] > S2[1]) 00133 return (y <= S2[1]) || (y >= S1[1]); 00134 else if (S1[1] < S2[1]) 00135 return (y >= S2[1]) || (y <= S1[1]); 00136 else 00137 return false; 00138 } 00139 } 00140 00147 template <typename PointInT> 00148 class GreedyProjectionTriangulation : public MeshConstruction<PointInT> 00149 { 00150 public: 00151 using MeshConstruction<PointInT>::tree_; 00152 using MeshConstruction<PointInT>::input_; 00153 using MeshConstruction<PointInT>::indices_; 00154 00155 typedef typename pcl::KdTree<PointInT> KdTree; 00156 typedef typename pcl::KdTree<PointInT>::Ptr KdTreePtr; 00157 00158 typedef pcl::PointCloud<PointInT> PointCloudIn; 00159 typedef typename PointCloudIn::Ptr PointCloudInPtr; 00160 typedef typename PointCloudIn::ConstPtr PointCloudInConstPtr; 00161 00162 // FIXME this enum should have a type. Not be anonymous. 00163 // Otherplaces where consts are used probably should be fixed. 00164 enum 00165 { 00166 NONE = -1, // not-defined 00167 FREE = 0, 00168 FRINGE = 1, 00169 BOUNDARY = 2, 00170 COMPLETED = 3 00171 }; 00172 00174 GreedyProjectionTriangulation () : mu_ (0), search_radius_ (0), // must be set by user 00175 nnn_ (100), 00176 minimum_angle_ (M_PI/18), // 10 degrees 00177 maximum_angle_ (2*M_PI/3), // 120 degrees 00178 eps_angle_(M_PI/4), //45 degrees, 00179 consistent_(false), consistent_ordering_ (false) 00180 {}; 00181 00186 inline void 00187 setMu (double mu) { mu_ = mu; } 00188 00190 inline double 00191 getMu () { return (mu_); } 00192 00196 inline void 00197 setMaximumNearestNeighbors (int nnn) { nnn_ = nnn; } 00198 00200 inline int 00201 getMaximumNearestNeighbors () { return (nnn_); } 00202 00207 inline void 00208 setSearchRadius (double radius) { search_radius_ = radius; } 00209 00211 inline double 00212 getSearchRadius () { return (search_radius_); } 00213 00218 inline void 00219 setMinimumAngle (double minimum_angle) { minimum_angle_ = minimum_angle; } 00220 00222 inline double 00223 getMinimumAngle () { return (minimum_angle_); } 00224 00229 inline void 00230 setMaximumAngle (double maximum_angle) { maximum_angle_ = maximum_angle; } 00231 00233 inline double 00234 getMaximumAngle () { return (maximum_angle_); } 00235 00241 inline void 00242 setMaximumSurfaceAngle (double eps_angle) { eps_angle_ = eps_angle; } 00243 00245 inline double 00246 getMaximumSurfaceAngle () { return (eps_angle_); } 00247 00251 inline void 00252 setNormalConsistency (bool consistent) { consistent_ = consistent; } 00253 00255 inline bool 00256 getNormalConsistency () { return (consistent_); } 00257 00262 inline void 00263 setConsistentVertexOrdering (bool consistent_ordering) { consistent_ordering_ = consistent_ordering; } 00264 00266 inline bool 00267 getConsistentVertexOrdering () { return (consistent_ordering_); } 00268 00272 inline std::vector<int> 00273 getPointStates () { return (state_); } 00274 00278 inline std::vector<int> 00279 getPartIDs () { return (part_); } 00280 00281 00283 inline std::vector<int> 00284 getSFN () { return (sfn_); } 00285 00287 inline std::vector<int> 00288 getFFN () { return (ffn_); } 00289 00294 void 00295 removeOverlapTriangles (pcl::PolygonMesh &mesh1, pcl::PolygonMesh &mesh2); 00296 00297 protected: 00299 double mu_; 00300 00302 double search_radius_; 00303 00305 int nnn_; 00306 00308 double minimum_angle_; 00309 00311 double maximum_angle_; 00312 00314 double eps_angle_; 00315 00317 bool consistent_; 00318 00320 bool consistent_ordering_; 00321 00322 private: 00324 struct nnAngle 00325 { 00326 double angle; 00327 int index; 00328 int nnIndex; 00329 bool visible; 00330 }; 00331 00333 struct doubleEdge 00334 { 00335 int index; 00336 Eigen::Vector2f first; 00337 Eigen::Vector2f second; 00338 }; 00339 00340 // Variables made global to decrease the number of parameters to helper functions 00341 00343 pcl::Vertices triangle_; 00345 std::vector<Eigen::Vector3f> coords_; 00346 00348 std::vector<nnAngle> angles_; 00350 int R_; 00352 std::vector<int> state_; 00354 std::vector<int> source_; 00356 std::vector<int> ffn_; 00358 std::vector<int> sfn_; 00360 std::vector<int> part_; 00362 std::vector<int> fringe_queue_; 00363 00365 bool is_current_free_; 00367 int current_index_; 00369 bool prev_is_ffn_; 00371 bool prev_is_sfn_; 00373 bool next_is_ffn_; 00375 bool next_is_sfn_; 00377 bool changed_1st_fn_; 00379 bool changed_2nd_fn_; 00381 int new2boundary_; 00382 00386 bool already_connected_; 00387 00389 Eigen::Vector3f proj_qp_; 00391 Eigen::Vector3f u_; 00393 Eigen::Vector3f v_; 00395 Eigen::Vector2f uvn_ffn_; 00397 Eigen::Vector2f uvn_sfn_; 00399 Eigen::Vector2f uvn_next_ffn_; 00401 Eigen::Vector2f uvn_next_sfn_; 00402 00404 Eigen::Vector3f tmp_; 00405 00409 void 00410 performReconstruction (pcl::PolygonMesh &output); 00411 00415 void 00416 performReconstruction (std::vector<pcl::Vertices> &polygons); 00417 00421 bool 00422 reconstructPolygons (std::vector<pcl::Vertices> &polygons); 00423 00425 std::string 00426 getClassName () const { return ("GreedyProjectionTriangulation"); } 00427 00438 void 00439 connectPoint (std::vector<pcl::Vertices> &polygons, 00440 const int prev_index, 00441 const int next_index, 00442 const int next_next_index, 00443 const Eigen::Vector2f &uvn_current, 00444 const Eigen::Vector2f &uvn_prev, 00445 const Eigen::Vector2f &uvn_next); 00446 00451 void 00452 closeTriangle (std::vector<pcl::Vertices> &polygons); 00453 00457 std::vector<std::vector<size_t> > 00458 getTriangleList (const pcl::PolygonMesh &input); 00459 00466 inline void 00467 addTriangle (int a, int b, int c, std::vector<pcl::Vertices> &polygons) 00468 { 00469 triangle_.vertices.resize (3); 00470 if (consistent_ordering_) 00471 { 00472 const PointInT p = input_->at (indices_->at (a)); 00473 const Eigen::Vector3f pv = p.getVector3fMap (); 00474 if (p.getNormalVector3fMap ().dot ( 00475 (pv - input_->at (indices_->at (b)).getVector3fMap ()).cross ( 00476 pv - input_->at (indices_->at (c)).getVector3fMap ()) ) > 0) 00477 { 00478 triangle_.vertices[0] = a; 00479 triangle_.vertices[1] = b; 00480 triangle_.vertices[2] = c; 00481 } 00482 else 00483 { 00484 triangle_.vertices[0] = a; 00485 triangle_.vertices[1] = c; 00486 triangle_.vertices[2] = b; 00487 } 00488 } 00489 else 00490 { 00491 triangle_.vertices[0] = a; 00492 triangle_.vertices[1] = b; 00493 triangle_.vertices[2] = c; 00494 } 00495 polygons.push_back (triangle_); 00496 } 00497 00502 inline void 00503 addFringePoint (int v, int s) 00504 { 00505 source_[v] = s; 00506 part_[v] = part_[s]; 00507 fringe_queue_.push_back(v); 00508 } 00509 00515 static inline bool 00516 nnAngleSortAsc (const nnAngle& a1, const nnAngle& a2) 00517 { 00518 if (a1.visible == a2.visible) 00519 return (a1.angle < a2.angle); 00520 else 00521 return a1.visible; 00522 } 00523 }; 00524 00525 } // namespace pcl 00526 00527 #endif //#ifndef PCL_GP3_H_ 00528
1.8.0