|
Point Cloud Library (PCL)
1.6.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2012, 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: poisson.hpp 5444 2012-03-30 19:44:43Z aichim $ 00037 * 00038 */ 00039 00040 #ifndef PCL_SURFACE_IMPL_POISSON_H_ 00041 #define PCL_SURFACE_IMPL_POISSON_H_ 00042 00043 #include <pcl/surface/poisson.h> 00044 #include <pcl/common/common.h> 00045 #include <pcl/common/vector_average.h> 00046 #include <pcl/Vertices.h> 00047 00048 #include <pcl/surface/poisson/octree_poisson.h> 00049 #include <pcl/surface/poisson/sparse_matrix.h> 00050 #include <pcl/surface/poisson/function_data.h> 00051 #include <pcl/surface/poisson/ppolynomial.h> 00052 #include <pcl/surface/poisson/multi_grid_octree_data.h> 00053 00054 #define MEMORY_ALLOCATOR_BLOCK_SIZE 1<<12 00055 00056 #include <stdarg.h> 00057 #include <string> 00058 00059 using namespace pcl; 00060 00062 template <typename PointNT> 00063 pcl::Poisson<PointNT>::Poisson () 00064 : data_ (), 00065 no_reset_samples_ (false), 00066 no_clip_tree_ (false), 00067 confidence_ (false), 00068 manifold_ (false), 00069 output_polygons_ (false), 00070 depth_ (8), 00071 solver_divide_ (8), 00072 iso_divide_ (8), 00073 refine_ (3), 00074 kernel_depth_ (8), 00075 degree_ (2), 00076 samples_per_node_ (1.0), 00077 scale_ (1.25) 00078 { 00079 } 00080 00082 template <typename PointNT> 00083 pcl::Poisson<PointNT>::~Poisson () 00084 { 00085 } 00086 00088 template <typename PointNT> template <int Degree> void 00089 pcl::Poisson<PointNT>::execute (poisson::CoredMeshData &mesh, 00090 poisson::Point3D<float> ¢er, 00091 float &scale) 00092 { 00093 float isoValue = 0.0f; 00095 // Fix courtesy of David Gallup // 00096 poisson::TreeNodeData::UseIndex = 1; // 00098 poisson::Octree<Degree> tree; 00099 poisson::PPolynomial<Degree> ReconstructionFunction = poisson::PPolynomial<Degree>::GaussianApproximation (); 00100 00101 center.coords[0] = center.coords[1] = center.coords[2] = 0.0f; 00102 00103 poisson::TreeOctNode::SetAllocator (MEMORY_ALLOCATOR_BLOCK_SIZE); 00104 00105 kernel_depth_ = depth_ - 2; 00106 // if(KernelDepth.set){kernelDepth=KernelDepth.value;} 00107 00108 tree.setFunctionData (ReconstructionFunction, depth_, 0, poisson::Real (1.0f) / poisson::Real (1 << depth_)); 00109 // if (kernel_depth_>depth_) 00110 // { 00111 // fprintf(stderr,"KernelDepth can't be greater than Depth: %d <= %d\n",kernel_depth_,depth_); 00112 // return; 00113 // } 00114 00115 tree.setTree (input_, depth_, kernel_depth_, float (samples_per_node_), scale_, center, scale, !no_reset_samples_, confidence_); 00116 00117 printf ("scale after settree %f\n", scale); 00118 00119 if(!no_clip_tree_) 00120 { 00121 tree.ClipTree (); 00122 } 00123 00124 tree.finalize1 (refine_); 00125 00126 tree.maxMemoryUsage = 0; 00127 tree.SetLaplacianWeights (); 00128 00129 tree.finalize2 (refine_); 00130 00131 tree.maxMemoryUsage = 0; 00132 tree.LaplacianMatrixIteration (solver_divide_); 00133 00134 tree.maxMemoryUsage = 0; 00135 isoValue = tree.GetIsoValue (); 00136 00137 if (iso_divide_) 00138 tree.GetMCIsoTriangles (isoValue, iso_divide_, &mesh, 0, 1, manifold_, output_polygons_); 00139 else 00140 tree.GetMCIsoTriangles (isoValue, &mesh, 0, 1, manifold_, output_polygons_); 00141 } 00142 00143 00145 template <typename PointNT> void 00146 pcl::Poisson<PointNT>::performReconstruction (PolygonMesh &output) 00147 { 00148 poisson::CoredVectorMeshData mesh; 00149 poisson::Point3D<float> center; 00150 float scale = 1.0f; 00151 00152 switch (degree_) 00153 { 00154 case 1: 00155 { 00156 execute<1> (mesh, center, scale); 00157 break; 00158 } 00159 case 2: 00160 { 00161 execute<2> (mesh, center, scale); 00162 break; 00163 } 00164 case 3: 00165 { 00166 execute<3> (mesh, center, scale); 00167 break; 00168 } 00169 case 4: 00170 { 00171 execute<4> (mesh, center, scale); 00172 break; 00173 } 00174 case 5: 00175 { 00176 execute<5> (mesh, center, scale); 00177 break; 00178 } 00179 default: 00180 { 00181 PCL_ERROR (stderr, "Degree %d not supported\n", degree_); 00182 } 00183 } 00184 00186 // write vertices 00187 pcl::PointCloud<pcl::PointXYZ> cloud; 00188 cloud.points.resize (int (mesh.outOfCorePointCount () + mesh.inCorePoints.size ())); 00189 poisson::Point3D<float> p; 00190 for (int i = 0; i < int (mesh.inCorePoints.size ()); i++) 00191 { 00192 p = mesh.inCorePoints[i]; 00193 cloud.points[i].x = p.coords[0]*scale+center.coords[0]; 00194 cloud.points[i].y = p.coords[1]*scale+center.coords[1]; 00195 cloud.points[i].z = p.coords[2]*scale+center.coords[2]; 00196 } 00197 for (int i = int (mesh.inCorePoints.size ()); i < int (mesh.outOfCorePointCount () + mesh.inCorePoints.size ()); i++) 00198 { 00199 mesh.nextOutOfCorePoint (p); 00200 cloud.points[i].x = p.coords[0]*scale+center.coords[0]; 00201 cloud.points[i].y = p.coords[1]*scale+center.coords[1]; 00202 cloud.points[i].z = p.coords[2]*scale+center.coords[2]; 00203 } 00204 pcl::toROSMsg (cloud, output.cloud); 00205 output.polygons.resize (mesh.polygonCount ()); 00206 00207 // Write faces 00208 std::vector<poisson::CoredVertexIndex> polygon; 00209 for (int p_i = 0; p_i < mesh.polygonCount (); p_i++) 00210 { 00211 pcl::Vertices v; 00212 mesh.nextPolygon (polygon); 00213 v.vertices.resize (polygon.size ()); 00214 00215 for (int i = 0; i < static_cast<int> (polygon.size ()); ++i) 00216 if (polygon[i].inCore ) 00217 v.vertices[i] = polygon[i].idx; 00218 else 00219 v.vertices[i] = polygon[i].idx + int (mesh.inCorePoints.size ()); 00220 00221 output.polygons[p_i] = v; 00222 } 00223 } 00224 00226 template <typename PointNT> void 00227 pcl::Poisson<PointNT>::performReconstruction (pcl::PointCloud<PointNT> &points, 00228 std::vector<pcl::Vertices> &polygons) 00229 { 00230 poisson::CoredVectorMeshData mesh; 00231 poisson::Point3D<float> center; 00232 float scale = 1.0f; 00233 00234 switch (degree_) 00235 { 00236 case 1: 00237 { 00238 execute<1> (mesh, center, scale); 00239 break; 00240 } 00241 case 2: 00242 { 00243 execute<2> (mesh, center, scale); 00244 break; 00245 } 00246 case 3: 00247 { 00248 execute<3> (mesh, center, scale); 00249 break; 00250 } 00251 case 4: 00252 { 00253 execute<4> (mesh, center, scale); 00254 break; 00255 } 00256 case 5: 00257 { 00258 execute<5> (mesh, center, scale); 00259 break; 00260 } 00261 default: 00262 { 00263 PCL_ERROR (stderr, "Degree %d not supported\n", degree_); 00264 } 00265 } 00266 00267 // Write output PolygonMesh 00268 // Write vertices 00269 points.points.resize (int (mesh.outOfCorePointCount () + mesh.inCorePoints.size ())); 00270 poisson::Point3D<float> p; 00271 for (int i = 0; i < int(mesh.inCorePoints.size ()); i++) 00272 { 00273 p = mesh.inCorePoints[i]; 00274 points.points[i].x = p.coords[0]*scale+center.coords[0]; 00275 points.points[i].y = p.coords[1]*scale+center.coords[1]; 00276 points.points[i].z = p.coords[2]*scale+center.coords[2]; 00277 } 00278 for (int i = int(mesh.inCorePoints.size()); i < int (mesh.outOfCorePointCount() + mesh.inCorePoints.size ()); i++) 00279 { 00280 mesh.nextOutOfCorePoint (p); 00281 points.points[i].x = p.coords[0]*scale+center.coords[0]; 00282 points.points[i].y = p.coords[1]*scale+center.coords[1]; 00283 points.points[i].z = p.coords[2]*scale+center.coords[2]; 00284 } 00285 00286 00287 00288 polygons.resize (mesh.polygonCount ()); 00289 00290 // write faces 00291 std::vector<poisson::CoredVertexIndex> polygon; 00292 for (int p_i = 0; p_i < mesh.polygonCount (); p_i++) 00293 { 00294 pcl::Vertices v; 00295 mesh.nextPolygon (polygon); 00296 v.vertices.resize (polygon.size ()); 00297 00298 for (int i = 0; i < static_cast<int> (polygon.size ()); ++i) 00299 if (polygon[i].inCore ) 00300 v.vertices[i] = polygon[i].idx; 00301 else 00302 v.vertices[i] = polygon[i].idx + int (mesh.inCorePoints.size ()); 00303 00304 polygons[p_i] = v; 00305 } 00306 } 00307 00308 00309 #define PCL_INSTANTIATE_Poisson(T) template class PCL_EXPORTS pcl::Poisson<T>; 00310 00311 #endif // PCL_SURFACE_IMPL_POISSON_H_ 00312
1.7.6.1