Point Cloud Library (PCL)  1.9.1-dev
octree_disk_container.hpp
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  * Copyright (c) 2012, Urban Robotics, Inc.
7  *
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * * Redistributions of source code must retain the above copyright
15  * notice, this list of conditions and the following disclaimer.
16  * * Redistributions in binary form must reproduce the above
17  * copyright notice, this list of conditions and the following
18  * disclaimer in the documentation and/or other materials provided
19  * with the distribution.
20  * * Neither the name of Willow Garage, Inc. nor the names of its
21  * contributors may be used to endorse or promote products derived
22  * from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * $Id: octree_disk_container.hpp 6927M 2012-08-24 17:01:57Z (local) $
38  */
39 
40 #ifndef PCL_OUTOFCORE_OCTREE_DISK_CONTAINER_IMPL_H_
41 #define PCL_OUTOFCORE_OCTREE_DISK_CONTAINER_IMPL_H_
42 
43 // C++
44 #include <sstream>
45 #include <cassert>
46 #include <ctime>
47 
48 // Boost
49 #include <pcl/outofcore/boost.h>
50 #include <boost/random/bernoulli_distribution.hpp>
51 #include <boost/random/uniform_int.hpp>
52 #include <boost/uuid/uuid_io.hpp>
53 
54 // PCL
55 #include <pcl/io/pcd_io.h>
56 #include <pcl/point_types.h>
57 #include <pcl/PCLPointCloud2.h>
58 
59 // PCL (Urban Robotics)
60 #include <pcl/outofcore/octree_disk_container.h>
61 
62 //allows operation on POSIX
63 #if !defined WIN32
64 #define _fseeki64 fseeko
65 #elif defined __MINGW32__
66 #define _fseeki64 fseeko64
67 #endif
68 
69 namespace pcl
70 {
71  namespace outofcore
72  {
73  template<typename PointT>
74  std::mutex OutofcoreOctreeDiskContainer<PointT>::rng_mutex_;
75 
76  template<typename PointT> boost::mt19937
77  OutofcoreOctreeDiskContainer<PointT>::rand_gen_ (static_cast<unsigned int> (std::time(nullptr)));
78 
79  template<typename PointT>
80  boost::uuids::basic_random_generator<boost::mt19937> OutofcoreOctreeDiskContainer<PointT>::uuid_gen_ (&rand_gen_);
81 
82  template<typename PointT>
83  const std::uint64_t OutofcoreOctreeDiskContainer<PointT>::READ_BLOCK_SIZE_ = static_cast<std::uint64_t> (2e12);
84  template<typename PointT>
85  const std::uint64_t OutofcoreOctreeDiskContainer<PointT>::WRITE_BUFF_MAX_ = static_cast<std::uint64_t> (2e12);
86 
87  template<typename PointT> void
89  {
90  boost::uuids::uuid u;
91  {
92  std::lock_guard<std::mutex> lock (rng_mutex_);
93  u = uuid_gen_ ();
94  }
95 
96  std::stringstream ss;
97  ss << u;
98  s = ss.str ();
99  }
100  ////////////////////////////////////////////////////////////////////////////////
101 
102  template<typename PointT>
104  : filelen_ (0)
105  , writebuff_ (0)
106  {
107  getRandomUUIDString (disk_storage_filename_);
108  filelen_ = 0;
109  }
110  ////////////////////////////////////////////////////////////////////////////////
111 
112  template<typename PointT>
114  : filelen_ (0)
115  , writebuff_ (0)
116  {
117  if (boost::filesystem::exists (path))
118  {
119  if (boost::filesystem::is_directory (path))
120  {
121  std::string uuid;
122  getRandomUUIDString (uuid);
123  boost::filesystem::path filename (uuid);
124  boost::filesystem::path file = path / filename;
125 
126  disk_storage_filename_ = file.string ();
127  }
128  else
129  {
130  std::uint64_t len = boost::filesystem::file_size (path);
131 
132  disk_storage_filename_ = path.string ();
133 
134  filelen_ = len / sizeof(PointT);
135 
136  pcl::PCLPointCloud2 cloud_info;
137  Eigen::Vector4f origin;
138  Eigen::Quaternionf orientation;
139  int pcd_version;
140  int data_type;
141  unsigned int data_index;
142 
143  //read the header of the pcd file and get the number of points
144  PCDReader reader;
145  reader.readHeader (disk_storage_filename_, cloud_info, origin, orientation, pcd_version, data_type, data_index, 0);
146 
147  filelen_ = cloud_info.width * cloud_info.height;
148  }
149  }
150  else //path doesn't exist
151  {
152  disk_storage_filename_ = path.string ();
153  filelen_ = 0;
154  }
155  }
156  ////////////////////////////////////////////////////////////////////////////////
157 
158  template<typename PointT>
160  {
161  flushWritebuff (true);
162  }
163  ////////////////////////////////////////////////////////////////////////////////
164 
165  template<typename PointT> void
166  OutofcoreOctreeDiskContainer<PointT>::flushWritebuff (const bool force_cache_dealloc)
167  {
168  if (!writebuff_.empty ())
169  {
170  //construct the point cloud for this node
172 
173  cloud->width = static_cast<std::uint32_t> (writebuff_.size ());
174  cloud->height = 1;
175 
176  cloud->points = writebuff_;
177 
178  //write data to a pcd file
179  pcl::PCDWriter writer;
180 
181 
182  PCL_WARN ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Flushing writebuffer in a dangerous way to file %s. This might overwrite data in destination file\n", __FUNCTION__, disk_storage_filename_.c_str ());
183 
184  // Write ascii for now to debug
185  int res = writer.writeBinaryCompressed (disk_storage_filename_, *cloud);
186  (void)res;
187  assert (res == 0);
188  if (force_cache_dealloc)
189  {
190  writebuff_.resize (0);
191  }
192  }
193  }
194  ////////////////////////////////////////////////////////////////////////////////
195 
196  template<typename PointT> PointT
198  {
199  PCL_THROW_EXCEPTION (PCLException, "[pcl::outofcore::OutofcoreOctreeDiskContainer] Not implemented for use with PCL library\n");
200 
201  //if the index is on disk
202  if (idx < filelen_)
203  {
204 
205  PointT temp;
206  //open our file
207  FILE* f = fopen (disk_storage_filename_.c_str (), "rbe");
208  assert (f != NULL);
209 
210  //seek the right length;
211  int seekret = _fseeki64 (f, idx * sizeof(PointT), SEEK_SET);
212  (void)seekret;
213  assert (seekret == 0);
214 
215  std::size_t readlen = fread (&temp, 1, sizeof(PointT), f);
216  (void)readlen;
217  assert (readlen == sizeof (PointT));
218 
219  int res = fclose (f);
220  (void)res;
221  assert (res == 0);
222 
223  return (temp);
224  }
225  //otherwise if the index is still in the write buffer
226  if (idx < (filelen_ + writebuff_.size ()))
227  {
228  idx -= filelen_;
229  return (writebuff_[idx]);
230  }
231 
232  //else, throw out of range exception
233  PCL_THROW_EXCEPTION (PCLException, "[pcl::outofcore:OutofcoreOctreeDiskContainer] Index is out of range");
234  }
235 
236  ////////////////////////////////////////////////////////////////////////////////
237  template<typename PointT> void
238  OutofcoreOctreeDiskContainer<PointT>::readRange (const std::uint64_t start, const std::uint64_t count, AlignedPointTVector& dst)
239  {
240  if (count == 0)
241  {
242  return;
243  }
244 
245  if ((start + count) > size ())
246  {
247  PCL_ERROR ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Indices out of range; start + count exceeds the size of the stored points\n", __FUNCTION__);
248  PCL_THROW_EXCEPTION (PCLException, "[pcl::outofcore::OutofcoreOctreeDiskContainer] Outofcore Octree Exception: Read indices exceed range");
249  }
250 
251  pcl::PCDReader reader;
253 
254  int res = reader.read (disk_storage_filename_, *cloud);
255  (void)res;
256  assert (res == 0);
257 
258  for (std::size_t i=0; i < cloud->points.size (); i++)
259  dst.push_back (cloud->points[i]);
260 
261  }
262  ////////////////////////////////////////////////////////////////////////////////
263 
264  template<typename PointT> void
265  OutofcoreOctreeDiskContainer<PointT>::readRangeSubSample_bernoulli (const std::uint64_t start, const std::uint64_t count, const double percent, AlignedPointTVector& dst)
266  {
267  if (count == 0)
268  {
269  return;
270  }
271 
272  dst.clear ();
273 
274  std::uint64_t filestart = 0;
275  std::uint64_t filecount = 0;
276 
277  std::int64_t buffstart = -1;
278  std::int64_t buffcount = -1;
279 
280  if (start < filelen_)
281  {
282  filestart = start;
283  }
284 
285  if ((start + count) <= filelen_)
286  {
287  filecount = count;
288  }
289  else
290  {
291  filecount = filelen_ - start;
292 
293  buffstart = 0;
294  buffcount = count - filecount;
295  }
296 
297  if (buffcount > 0)
298  {
299  {
300  std::lock_guard<std::mutex> lock (rng_mutex_);
301  boost::bernoulli_distribution<double> buffdist (percent);
302  boost::variate_generator<boost::mt19937&, boost::bernoulli_distribution<double> > buffcoin (rand_gen_, buffdist);
303 
304  for (std::size_t i = buffstart; i < static_cast<std::uint64_t> (buffcount); i++)
305  {
306  if (buffcoin ())
307  {
308  dst.push_back (writebuff_[i]);
309  }
310  }
311  }
312  }
313 
314  if (filecount > 0)
315  {
316  //pregen and then sort the offsets to reduce the amount of seek
317  std::vector < std::uint64_t > offsets;
318  {
319  std::lock_guard<std::mutex> lock (rng_mutex_);
320 
321  boost::bernoulli_distribution<double> filedist (percent);
322  boost::variate_generator<boost::mt19937&, boost::bernoulli_distribution<double> > filecoin (rand_gen_, filedist);
323  for (std::uint64_t i = filestart; i < (filestart + filecount); i++)
324  {
325  if (filecoin ())
326  {
327  offsets.push_back (i);
328  }
329  }
330  }
331  std::sort (offsets.begin (), offsets.end ());
332 
333  FILE* f = fopen (disk_storage_filename_.c_str (), "rbe");
334  assert (f != NULL);
335  PointT p;
336  char* loc = reinterpret_cast<char*> (&p);
337 
338  std::uint64_t filesamp = offsets.size ();
339  for (std::uint64_t i = 0; i < filesamp; i++)
340  {
341  int seekret = _fseeki64 (f, offsets[i] * static_cast<std::uint64_t> (sizeof(PointT)), SEEK_SET);
342  (void)seekret;
343  assert (seekret == 0);
344  std::size_t readlen = fread (loc, sizeof(PointT), 1, f);
345  (void)readlen;
346  assert (readlen == 1);
347 
348  dst.push_back (p);
349  }
350 
351  fclose (f);
352  }
353  }
354  ////////////////////////////////////////////////////////////////////////////////
355 
356 //change this to use a weighted coin flip, to allow sparse sampling of small clouds (eg the bernoulli above)
357  template<typename PointT> void
358  OutofcoreOctreeDiskContainer<PointT>::readRangeSubSample (const std::uint64_t start, const std::uint64_t count, const double percent, AlignedPointTVector& dst)
359  {
360  if (count == 0)
361  {
362  return;
363  }
364 
365  dst.clear ();
366 
367  std::uint64_t filestart = 0;
368  std::uint64_t filecount = 0;
369 
370  std::int64_t buffcount = -1;
371 
372  if (start < filelen_)
373  {
374  filestart = start;
375  }
376 
377  if ((start + count) <= filelen_)
378  {
379  filecount = count;
380  }
381  else
382  {
383  filecount = filelen_ - start;
384  buffcount = count - filecount;
385  }
386 
387  std::uint64_t filesamp = static_cast<std::uint64_t> (percent * static_cast<double> (filecount));
388 
389  std::uint64_t buffsamp = (buffcount > 0) ? (static_cast<std::uint64_t > (percent * static_cast<double> (buffcount))) : 0;
390 
391  if ((filesamp == 0) && (buffsamp == 0) && (size () > 0))
392  {
393  //std::cerr << "would not add points to LOD, falling back to bernoulli";
394  readRangeSubSample_bernoulli (start, count, percent, dst);
395  return;
396  }
397 
398  if (buffcount > 0)
399  {
400  {
401  std::lock_guard<std::mutex> lock (rng_mutex_);
402 
403  boost::uniform_int < std::uint64_t > buffdist (0, buffcount - 1);
404  boost::variate_generator<boost::mt19937&, boost::uniform_int<std::uint64_t> > buffdie (rand_gen_, buffdist);
405 
406  for (std::uint64_t i = 0; i < buffsamp; i++)
407  {
408  std::uint64_t buffstart = buffdie ();
409  dst.push_back (writebuff_[buffstart]);
410  }
411  }
412  }
413 
414  if (filesamp > 0)
415  {
416  //pregen and then sort the offsets to reduce the amount of seek
417  std::vector < std::uint64_t > offsets;
418  {
419  std::lock_guard<std::mutex> lock (rng_mutex_);
420 
421  offsets.resize (filesamp);
422  boost::uniform_int < std::uint64_t > filedist (filestart, filestart + filecount - 1);
423  boost::variate_generator<boost::mt19937&, boost::uniform_int<std::uint64_t> > filedie (rand_gen_, filedist);
424  for (std::uint64_t i = 0; i < filesamp; i++)
425  {
426  std::uint64_t _filestart = filedie ();
427  offsets[i] = _filestart;
428  }
429  }
430  std::sort (offsets.begin (), offsets.end ());
431 
432  FILE* f = fopen (disk_storage_filename_.c_str (), "rbe");
433  assert (f != NULL);
434  PointT p;
435  char* loc = reinterpret_cast<char*> (&p);
436  for (std::uint64_t i = 0; i < filesamp; i++)
437  {
438  int seekret = _fseeki64 (f, offsets[i] * static_cast<std::uint64_t> (sizeof(PointT)), SEEK_SET);
439  (void)seekret;
440  assert (seekret == 0);
441  std::size_t readlen = fread (loc, sizeof(PointT), 1, f);
442  (void)readlen;
443  assert (readlen == 1);
444 
445  dst.push_back (p);
446  }
447  int res = fclose (f);
448  (void)res;
449  assert (res == 0);
450  }
451  }
452  ////////////////////////////////////////////////////////////////////////////////
453 
454  template<typename PointT> void
456  {
457  writebuff_.push_back (p);
458  if (writebuff_.size () > WRITE_BUFF_MAX_)
459  {
460  flushWritebuff (false);
461  }
462  }
463  ////////////////////////////////////////////////////////////////////////////////
464 
465  template<typename PointT> void
467  {
468  const std::uint64_t count = src.size ();
469 
470  typename pcl::PointCloud<PointT>::Ptr tmp_cloud (new pcl::PointCloud<PointT> ());
471 
472  // If there's a pcd file with data
473  if (boost::filesystem::exists (disk_storage_filename_))
474  {
475  // Open the existing file
476  pcl::PCDReader reader;
477  int res = reader.read (disk_storage_filename_, *tmp_cloud);
478  (void)res;
479  assert (res == 0);
480  }
481  // Otherwise create the point cloud which will be saved to the pcd file for the first time
482  else
483  {
484  tmp_cloud->width = static_cast<std::uint32_t> (count + writebuff_.size ());
485  tmp_cloud->height = 1;
486  }
487 
488  for (std::size_t i = 0; i < src.size (); i++)
489  tmp_cloud->points.push_back (src[i]);
490 
491  // If there are any points in the write cache writebuff_, a different write cache than this one, concatenate
492  for (std::size_t i = 0; i < writebuff_.size (); i++)
493  {
494  tmp_cloud->points.push_back (writebuff_[i]);
495  }
496 
497  //assume unorganized point cloud
498  tmp_cloud->width = static_cast<std::uint32_t> (tmp_cloud->points.size ());
499 
500  //save and close
501  PCDWriter writer;
502 
503  int res = writer.writeBinaryCompressed (disk_storage_filename_, *tmp_cloud);
504  (void)res;
505  assert (res == 0);
506  }
507 
508  ////////////////////////////////////////////////////////////////////////////////
509 
510  template<typename PointT> void
512  {
514 
515  //if there's a pcd file with data associated with this node, read the data, concatenate, and resave
516  if (boost::filesystem::exists (disk_storage_filename_))
517  {
518  //open the existing file
519  pcl::PCDReader reader;
520  int res = reader.read (disk_storage_filename_, *tmp_cloud);
521  (void)res;
522  assert (res == 0);
523  pcl::PCDWriter writer;
524  PCL_DEBUG ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Concatenating point cloud from %s to new cloud\n", __FUNCTION__, disk_storage_filename_.c_str ());
525 
526  std::size_t previous_num_pts = tmp_cloud->width*tmp_cloud->height + input_cloud->width*input_cloud->height;
527  //Concatenate will fail if the fields in input_cloud do not match the fields in the PCD file.
528  pcl::concatenate (*tmp_cloud, *input_cloud, *tmp_cloud);
529  std::size_t res_pts = tmp_cloud->width*tmp_cloud->height;
530 
531  (void)previous_num_pts;
532  (void)res_pts;
533 
534  assert (previous_num_pts == res_pts);
535 
536  writer.writeBinaryCompressed (disk_storage_filename_, *tmp_cloud);
537 
538  }
539  else //otherwise create the point cloud which will be saved to the pcd file for the first time
540  {
541  pcl::PCDWriter writer;
542  int res = writer.writeBinaryCompressed (disk_storage_filename_, *input_cloud);
543  (void)res;
544  assert (res == 0);
545  }
546 
547  }
548 
549  ////////////////////////////////////////////////////////////////////////////////
550 
551  template<typename PointT> void
552  OutofcoreOctreeDiskContainer<PointT>::readRange (const std::uint64_t, const std::uint64_t, pcl::PCLPointCloud2::Ptr& dst)
553  {
554  pcl::PCDReader reader;
555 
556  Eigen::Vector4f origin;
557  Eigen::Quaternionf orientation;
558  int pcd_version;
559 
560  if (boost::filesystem::exists (disk_storage_filename_))
561  {
562 // PCL_INFO ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Reading points from disk from %s.\n", __FUNCTION__ , disk_storage_filename_->c_str ());
563  int res = reader.read (disk_storage_filename_, *dst, origin, orientation, pcd_version);
564  (void)res;
565  assert (res != -1);
566  }
567  else
568  {
569  PCL_ERROR ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] File %s does not exist in node.\n", __FUNCTION__, disk_storage_filename_.c_str ());
570  }
571  }
572 
573  ////////////////////////////////////////////////////////////////////////////////
574 
575  template<typename PointT> int
577  {
578  pcl::PCLPointCloud2::Ptr temp_output_cloud (new pcl::PCLPointCloud2 ());
579 
580  if (boost::filesystem::exists (disk_storage_filename_))
581  {
582 // PCL_INFO ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Reading points from disk from %s.\n", __FUNCTION__ , disk_storage_filename_->c_str ());
583  int res = pcl::io::loadPCDFile (disk_storage_filename_, *temp_output_cloud);
584  (void)res;
585  assert (res != -1);
586  if(res == -1)
587  return (-1);
588  }
589  else
590  {
591  PCL_ERROR ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] File %s does not exist in node.\n", __FUNCTION__, disk_storage_filename_.c_str ());
592  return (-1);
593  }
594 
595  if(output_cloud.get () != nullptr)
596  {
597  pcl::concatenate (*output_cloud, *temp_output_cloud, *output_cloud);
598  }
599  else
600  {
601  output_cloud = temp_output_cloud;
602  }
603  return (0);
604  }
605 
606  ////////////////////////////////////////////////////////////////////////////////
607 
608  template<typename PointT> void
609  OutofcoreOctreeDiskContainer<PointT>::insertRange (const PointT* const * start, const std::uint64_t count)
610  {
611 // PCL_THROW_EXCEPTION (PCLException, "[pcl::outofcore::OutofcoreOctreeDiskContainer] Deprecated\n");
612  //copy the handles to a continuous block
613  PointT* arr = new PointT[count];
614 
615  //copy from start of array, element by element
616  for (std::size_t i = 0; i < count; i++)
617  {
618  arr[i] = *(start[i]);
619  }
620 
621  insertRange (arr, count);
622  delete[] arr;
623  }
624 
625  ////////////////////////////////////////////////////////////////////////////////
626 
627  template<typename PointT> void
628  OutofcoreOctreeDiskContainer<PointT>::insertRange (const PointT* start, const std::uint64_t count)
629  {
630  typename pcl::PointCloud<PointT>::Ptr tmp_cloud (new pcl::PointCloud<PointT> ());
631 
632  // If there's a pcd file with data, read it in from disk for appending
633  if (boost::filesystem::exists (disk_storage_filename_))
634  {
635  pcl::PCDReader reader;
636  // Open it
637  int res = reader.read (disk_storage_filename_.c_str (), *tmp_cloud);
638  (void)res;
639  assert (res == 0);
640  }
641  else //otherwise create the pcd file
642  {
643  tmp_cloud->width = static_cast<std::uint32_t> (count) + static_cast<std::uint32_t> (writebuff_.size ());
644  tmp_cloud->height = 1;
645  }
646 
647  // Add any points in the cache
648  for (std::size_t i = 0; i < writebuff_.size (); i++)
649  {
650  tmp_cloud->points.push_back (writebuff_ [i]);
651  }
652 
653  //add the new points passed with this function
654  for (std::size_t i = 0; i < count; i++)
655  {
656  tmp_cloud->points.push_back (*(start + i));
657  }
658 
659  tmp_cloud->width = static_cast<std::uint32_t> (tmp_cloud->points.size ());
660  tmp_cloud->height = 1;
661 
662  //save and close
663  PCDWriter writer;
664 
665  int res = writer.writeBinaryCompressed (disk_storage_filename_, *tmp_cloud);
666  (void)res;
667  assert (res == 0);
668  }
669  ////////////////////////////////////////////////////////////////////////////////
670 
671  template<typename PointT> std::uint64_t
673  {
674  pcl::PCLPointCloud2 cloud_info;
675  Eigen::Vector4f origin;
676  Eigen::Quaternionf orientation;
677  int pcd_version;
678  int data_type;
679  unsigned int data_index;
680 
681  //read the header of the pcd file and get the number of points
682  PCDReader reader;
683  reader.readHeader (disk_storage_filename_, cloud_info, origin, orientation, pcd_version, data_type, data_index, 0);
684 
685  std::uint64_t total_points = cloud_info.width * cloud_info.height + writebuff_.size ();
686 
687  return (total_points);
688  }
689  ////////////////////////////////////////////////////////////////////////////////
690 
691  }//namespace outofcore
692 }//namespace pcl
693 
694 #endif //PCL_OUTOFCORE_OCTREE_DISK_CONTAINER_IMPL_H_
std::uint64_t getDataSize() const
Returns the number of points in the PCD file by reading the PCD header.
std::vector< PointT, Eigen::aligned_allocator< PointT > > points
The point data.
Definition: point_cloud.h:394
void readRangeSubSample(const std::uint64_t start, const std::uint64_t count, const double percent, AlignedPointTVector &dst) override
grab percent*count random points.
A base class for all pcl exceptions which inherits from std::runtime_error.
Definition: exceptions.h:64
int writeBinaryCompressed(const std::string &file_name, const pcl::PCLPointCloud2 &cloud, const Eigen::Vector4f &origin=Eigen::Vector4f::Zero(), const Eigen::Quaternionf &orientation=Eigen::Quaternionf::Identity())
Save point cloud data to a PCD file containing n-D points, in BINARY_COMPRESSED format.
void insertRange(const AlignedPointTVector &src)
Inserts a vector of points into the disk data structure.
This file defines compatibility wrappers for low level I/O functions.
Definition: convolution.h:45
static void getRandomUUIDString(std::string &s)
Generate a universally unique identifier (UUID)
std::string & path()
Returns this objects path name.
std::uint32_t height
Class responsible for serialization and deserialization of out of core point data.
std::uint32_t width
The point cloud width (if organized as an image-structure).
Definition: point_cloud.h:397
typename OutofcoreAbstractNodeContainer< PointT >::AlignedPointTVector AlignedPointTVector
~OutofcoreOctreeDiskContainer()
flushes write buffer, then frees memory
void readRangeSubSample_bernoulli(const std::uint64_t start, const std::uint64_t count, const double percent, AlignedPointTVector &dst)
Use bernoulli trials to select points.
Defines all the PCL implemented PointT point type structures.
boost::shared_ptr< ::pcl::PCLPointCloud2 > Ptr
PointT operator[](std::uint64_t idx) const override
provides random access to points based on a linear index
int readHeader(std::istream &binary_istream, pcl::PCLPointCloud2 &cloud, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &pcd_version, int &data_type, unsigned int &data_idx)
Read a point cloud data header from a PCD-formatted, binary istream.
void push_back(const PointT &p)
Adds a single point to the buffer to be written to disk when the buffer grows sufficiently large...
boost::shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:412
PCL_EXPORTS bool concatenate(const pcl::PointCloud< PointT > &cloud1, const pcl::PointCloud< PointT > &cloud2, pcl::PointCloud< PointT > &cloud_out)
Concatenate two pcl::PointCloud<PointT>
Definition: io.h:281
int read(const std::string &file_name, pcl::PCLPointCloud2 &cloud, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &pcd_version, const int offset=0) override
Read a point cloud data from a PCD file and store it into a pcl/PCLPointCloud2.
OutofcoreOctreeDiskContainer()
Empty constructor creates disk container and sets filename from random uuid string.
std::uint32_t height
The point cloud height (if organized as an image-structure).
Definition: point_cloud.h:399
PointCloud represents the base class in PCL for storing collections of 3D points. ...
void readRange(const std::uint64_t start, const std::uint64_t count, AlignedPointTVector &dst) override
Reads count points into memory from the disk container.
boost::uuids::basic_random_generator< boost::mt19937 > OutofcoreOctreeDiskContainer< PointT >::uuid_gen_ & rand_gen_
std::uint32_t width
int loadPCDFile(const std::string &file_name, pcl::PCLPointCloud2 &cloud)
Load a PCD v.6 file into a templated PointCloud type.
Definition: pcd_io.h:620
int read(pcl::PCLPointCloud2::Ptr &output_cloud)
Reads the entire point contents from disk into output_cloud.
Point Cloud Data (PCD) file format reader.
Definition: pcd_io.h:52
A point structure representing Euclidean xyz coordinates, and the RGB color.
std::uint64_t size() const override
Returns the total number of points for which this container is responsible, filelen_ + points in writ...
Point Cloud Data (PCD) file format writer.
Definition: pcd_io.h:295