00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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
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
00107
00108 tree.setFunctionData (ReconstructionFunction, depth_, 0, poisson::Real (1.0f) / poisson::Real (1 << depth_));
00109
00110
00111
00112
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
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
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
00268
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
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