Point Cloud Library (PCL)  1.6.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
poisson.hpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2012, 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: poisson.hpp 5444 2012-03-30 19:44:43Z aichim $
37  *
38  */
39 
40 #ifndef PCL_SURFACE_IMPL_POISSON_H_
41 #define PCL_SURFACE_IMPL_POISSON_H_
42 
43 #include <pcl/surface/poisson.h>
44 #include <pcl/common/common.h>
46 #include <pcl/Vertices.h>
47 
48 #include <pcl/surface/poisson/octree_poisson.h>
49 #include <pcl/surface/poisson/sparse_matrix.h>
50 #include <pcl/surface/poisson/function_data.h>
51 #include <pcl/surface/poisson/ppolynomial.h>
52 #include <pcl/surface/poisson/multi_grid_octree_data.h>
53 
54 #define MEMORY_ALLOCATOR_BLOCK_SIZE 1<<12
55 
56 #include <stdarg.h>
57 #include <string>
58 
59 using namespace pcl;
60 
62 template <typename PointNT>
64 : data_ (),
65  no_reset_samples_ (false),
66  no_clip_tree_ (false),
67  confidence_ (false),
68  manifold_ (false),
69  output_polygons_ (false),
70  depth_ (8),
71  solver_divide_ (8),
72  iso_divide_ (8),
73  refine_ (3),
74  kernel_depth_ (8),
75  degree_ (2),
76  samples_per_node_ (1.0),
77  scale_ (1.25)
78 {
79 }
80 
82 template <typename PointNT>
84 {
85 }
86 
88 template <typename PointNT> template <int Degree> void
89 pcl::Poisson<PointNT>::execute (poisson::CoredMeshData &mesh,
90  poisson::Point3D<float> &center,
91  float &scale)
92 {
93  float isoValue = 0.0f;
95  // Fix courtesy of David Gallup //
96  poisson::TreeNodeData::UseIndex = 1; //
98  poisson::Octree<Degree> tree;
99  poisson::PPolynomial<Degree> ReconstructionFunction = poisson::PPolynomial<Degree>::GaussianApproximation ();
100 
101  center.coords[0] = center.coords[1] = center.coords[2] = 0.0f;
102 
103  poisson::TreeOctNode::SetAllocator (MEMORY_ALLOCATOR_BLOCK_SIZE);
104 
105  kernel_depth_ = depth_ - 2;
106 // if(KernelDepth.set){kernelDepth=KernelDepth.value;}
107 
108  tree.setFunctionData (ReconstructionFunction, depth_, 0, poisson::Real (1.0f) / poisson::Real (1 << depth_));
109 // if (kernel_depth_>depth_)
110 // {
111 // fprintf(stderr,"KernelDepth can't be greater than Depth: %d <= %d\n",kernel_depth_,depth_);
112 // return;
113 // }
114 
115  tree.setTree (input_, depth_, kernel_depth_, float (samples_per_node_), scale_, center, scale, !no_reset_samples_, confidence_);
116 
117  printf ("scale after settree %f\n", scale);
118 
119  if(!no_clip_tree_)
120  {
121  tree.ClipTree ();
122  }
123 
124  tree.finalize1 (refine_);
125 
126  tree.maxMemoryUsage = 0;
127  tree.SetLaplacianWeights ();
128 
129  tree.finalize2 (refine_);
130 
131  tree.maxMemoryUsage = 0;
132  tree.LaplacianMatrixIteration (solver_divide_);
133 
134  tree.maxMemoryUsage = 0;
135  isoValue = tree.GetIsoValue ();
136 
137  if (iso_divide_)
138  tree.GetMCIsoTriangles (isoValue, iso_divide_, &mesh, 0, 1, manifold_, output_polygons_);
139  else
140  tree.GetMCIsoTriangles (isoValue, &mesh, 0, 1, manifold_, output_polygons_);
141 }
142 
143 
145 template <typename PointNT> void
147 {
148  poisson::CoredVectorMeshData mesh;
149  poisson::Point3D<float> center;
150  float scale = 1.0f;
151 
152  switch (degree_)
153  {
154  case 1:
155  {
156  execute<1> (mesh, center, scale);
157  break;
158  }
159  case 2:
160  {
161  execute<2> (mesh, center, scale);
162  break;
163  }
164  case 3:
165  {
166  execute<3> (mesh, center, scale);
167  break;
168  }
169  case 4:
170  {
171  execute<4> (mesh, center, scale);
172  break;
173  }
174  case 5:
175  {
176  execute<5> (mesh, center, scale);
177  break;
178  }
179  default:
180  {
181  PCL_ERROR (stderr, "Degree %d not supported\n", degree_);
182  }
183  }
184 
186  // write vertices
188  cloud.points.resize (int (mesh.outOfCorePointCount () + mesh.inCorePoints.size ()));
189  poisson::Point3D<float> p;
190  for (int i = 0; i < int (mesh.inCorePoints.size ()); i++)
191  {
192  p = mesh.inCorePoints[i];
193  cloud.points[i].x = p.coords[0]*scale+center.coords[0];
194  cloud.points[i].y = p.coords[1]*scale+center.coords[1];
195  cloud.points[i].z = p.coords[2]*scale+center.coords[2];
196  }
197  for (int i = int (mesh.inCorePoints.size ()); i < int (mesh.outOfCorePointCount () + mesh.inCorePoints.size ()); i++)
198  {
199  mesh.nextOutOfCorePoint (p);
200  cloud.points[i].x = p.coords[0]*scale+center.coords[0];
201  cloud.points[i].y = p.coords[1]*scale+center.coords[1];
202  cloud.points[i].z = p.coords[2]*scale+center.coords[2];
203  }
204  pcl::toROSMsg (cloud, output.cloud);
205  output.polygons.resize (mesh.polygonCount ());
206 
207  // Write faces
208  std::vector<poisson::CoredVertexIndex> polygon;
209  for (int p_i = 0; p_i < mesh.polygonCount (); p_i++)
210  {
211  pcl::Vertices v;
212  mesh.nextPolygon (polygon);
213  v.vertices.resize (polygon.size ());
214 
215  for (int i = 0; i < static_cast<int> (polygon.size ()); ++i)
216  if (polygon[i].inCore )
217  v.vertices[i] = polygon[i].idx;
218  else
219  v.vertices[i] = polygon[i].idx + int (mesh.inCorePoints.size ());
220 
221  output.polygons[p_i] = v;
222  }
223 }
224 
226 template <typename PointNT> void
228  std::vector<pcl::Vertices> &polygons)
229 {
230  poisson::CoredVectorMeshData mesh;
231  poisson::Point3D<float> center;
232  float scale = 1.0f;
233 
234  switch (degree_)
235  {
236  case 1:
237  {
238  execute<1> (mesh, center, scale);
239  break;
240  }
241  case 2:
242  {
243  execute<2> (mesh, center, scale);
244  break;
245  }
246  case 3:
247  {
248  execute<3> (mesh, center, scale);
249  break;
250  }
251  case 4:
252  {
253  execute<4> (mesh, center, scale);
254  break;
255  }
256  case 5:
257  {
258  execute<5> (mesh, center, scale);
259  break;
260  }
261  default:
262  {
263  PCL_ERROR (stderr, "Degree %d not supported\n", degree_);
264  }
265  }
266 
267  // Write output PolygonMesh
268  // Write vertices
269  points.points.resize (int (mesh.outOfCorePointCount () + mesh.inCorePoints.size ()));
270  poisson::Point3D<float> p;
271  for (int i = 0; i < int(mesh.inCorePoints.size ()); i++)
272  {
273  p = mesh.inCorePoints[i];
274  points.points[i].x = p.coords[0]*scale+center.coords[0];
275  points.points[i].y = p.coords[1]*scale+center.coords[1];
276  points.points[i].z = p.coords[2]*scale+center.coords[2];
277  }
278  for (int i = int(mesh.inCorePoints.size()); i < int (mesh.outOfCorePointCount() + mesh.inCorePoints.size ()); i++)
279  {
280  mesh.nextOutOfCorePoint (p);
281  points.points[i].x = p.coords[0]*scale+center.coords[0];
282  points.points[i].y = p.coords[1]*scale+center.coords[1];
283  points.points[i].z = p.coords[2]*scale+center.coords[2];
284  }
285 
286 
287 
288  polygons.resize (mesh.polygonCount ());
289 
290  // write faces
291  std::vector<poisson::CoredVertexIndex> polygon;
292  for (int p_i = 0; p_i < mesh.polygonCount (); p_i++)
293  {
294  pcl::Vertices v;
295  mesh.nextPolygon (polygon);
296  v.vertices.resize (polygon.size ());
297 
298  for (int i = 0; i < static_cast<int> (polygon.size ()); ++i)
299  if (polygon[i].inCore )
300  v.vertices[i] = polygon[i].idx;
301  else
302  v.vertices[i] = polygon[i].idx + int (mesh.inCorePoints.size ());
303 
304  polygons[p_i] = v;
305  }
306 }
307 
308 
309 #define PCL_INSTANTIATE_Poisson(T) template class PCL_EXPORTS pcl::Poisson<T>;
310 
311 #endif // PCL_SURFACE_IMPL_POISSON_H_
312