Point Cloud Library (PCL)  1.14.0-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 <boost/random/bernoulli_distribution.hpp>
50 #include <boost/random/uniform_int.hpp>
51 #include <boost/uuid/uuid_io.hpp>
52 
53 // PCL
54 #include <pcl/common/utils.h> // pcl::utils::ignore
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 = 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  pcl::utils::ignore(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 != nullptr);
209 
210  //seek the right length;
211  int seekret = _fseeki64 (f, idx * sizeof(PointT), SEEK_SET);
212  pcl::utils::ignore(seekret);
213  assert (seekret == 0);
214 
215  std::size_t readlen = fread (&temp, 1, sizeof(PointT), f);
216  pcl::utils::ignore(readlen);
217  assert (readlen == sizeof (PointT));
218 
219  int res = fclose (f);
220  pcl::utils::ignore(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  pcl::utils::ignore(res);
256  assert (res == 0);
257 
258  dst.insert(dst.end(), cloud->cbegin(), cloud->cend());
259 
260  }
261  ////////////////////////////////////////////////////////////////////////////////
262 
263  template<typename PointT> void
264  OutofcoreOctreeDiskContainer<PointT>::readRangeSubSample_bernoulli (const std::uint64_t start, const std::uint64_t count, const double percent, AlignedPointTVector& dst)
265  {
266  if (count == 0)
267  {
268  return;
269  }
270 
271  dst.clear ();
272 
273  std::uint64_t filestart = 0;
274  std::uint64_t filecount = 0;
275 
276  std::int64_t buffstart = -1;
277  std::int64_t buffcount = -1;
278 
279  if (start < filelen_)
280  {
281  filestart = start;
282  }
283 
284  if ((start + count) <= filelen_)
285  {
286  filecount = count;
287  }
288  else
289  {
290  filecount = filelen_ - start;
291 
292  buffstart = 0;
293  buffcount = count - filecount;
294  }
295 
296  if (buffcount > 0)
297  {
298  {
299  std::lock_guard<std::mutex> lock (rng_mutex_);
300  boost::bernoulli_distribution<double> buffdist (percent);
301  boost::variate_generator<boost::mt19937&, boost::bernoulli_distribution<double> > buffcoin (rand_gen_, buffdist);
302 
303  for (std::size_t i = buffstart; i < static_cast<std::uint64_t> (buffcount); i++)
304  {
305  if (buffcoin ())
306  {
307  dst.push_back (writebuff_[i]);
308  }
309  }
310  }
311  }
312 
313  if (filecount > 0)
314  {
315  //pregen and then sort the offsets to reduce the amount of seek
316  std::vector < std::uint64_t > offsets;
317  {
318  std::lock_guard<std::mutex> lock (rng_mutex_);
319 
320  boost::bernoulli_distribution<double> filedist (percent);
321  boost::variate_generator<boost::mt19937&, boost::bernoulli_distribution<double> > filecoin (rand_gen_, filedist);
322  for (std::uint64_t i = filestart; i < (filestart + filecount); i++)
323  {
324  if (filecoin ())
325  {
326  offsets.push_back (i);
327  }
328  }
329  }
330  std::sort (offsets.begin (), offsets.end ());
331 
332  FILE* f = fopen (disk_storage_filename_.c_str (), "rbe");
333  assert (f != nullptr);
334  PointT p;
335  char* loc = reinterpret_cast<char*> (&p);
336 
337  std::uint64_t filesamp = offsets.size ();
338  for (std::uint64_t i = 0; i < filesamp; i++)
339  {
340  int seekret = _fseeki64 (f, offsets[i] * static_cast<std::uint64_t> (sizeof(PointT)), SEEK_SET);
341  pcl::utils::ignore(seekret);
342  assert (seekret == 0);
343  std::size_t readlen = fread (loc, sizeof(PointT), 1, f);
344  pcl::utils::ignore(readlen);
345  assert (readlen == 1);
346 
347  dst.push_back (p);
348  }
349 
350  fclose (f);
351  }
352  }
353  ////////////////////////////////////////////////////////////////////////////////
354 
355 //change this to use a weighted coin flip, to allow sparse sampling of small clouds (eg the bernoulli above)
356  template<typename PointT> void
357  OutofcoreOctreeDiskContainer<PointT>::readRangeSubSample (const std::uint64_t start, const std::uint64_t count, const double percent, AlignedPointTVector& dst)
358  {
359  if (count == 0)
360  {
361  return;
362  }
363 
364  dst.clear ();
365 
366  std::uint64_t filestart = 0;
367  std::uint64_t filecount = 0;
368 
369  std::int64_t buffcount = -1;
370 
371  if (start < filelen_)
372  {
373  filestart = start;
374  }
375 
376  if ((start + count) <= filelen_)
377  {
378  filecount = count;
379  }
380  else
381  {
382  filecount = filelen_ - start;
383  buffcount = count - filecount;
384  }
385 
386  auto filesamp = static_cast<std::uint64_t> (percent * static_cast<double> (filecount));
387 
388  std::uint64_t buffsamp = (buffcount > 0) ? (static_cast<std::uint64_t > (percent * static_cast<double> (buffcount))) : 0;
389 
390  if ((filesamp == 0) && (buffsamp == 0) && (size () > 0))
391  {
392  //std::cerr << "would not add points to LOD, falling back to bernoulli";
393  readRangeSubSample_bernoulli (start, count, percent, dst);
394  return;
395  }
396 
397  if (buffcount > 0)
398  {
399  {
400  std::lock_guard<std::mutex> lock (rng_mutex_);
401 
402  boost::uniform_int < std::uint64_t > buffdist (0, buffcount - 1);
403  boost::variate_generator<boost::mt19937&, boost::uniform_int<std::uint64_t> > buffdie (rand_gen_, buffdist);
404 
405  for (std::uint64_t i = 0; i < buffsamp; i++)
406  {
407  std::uint64_t buffstart = buffdie ();
408  dst.push_back (writebuff_[buffstart]);
409  }
410  }
411  }
412 
413  if (filesamp > 0)
414  {
415  //pregen and then sort the offsets to reduce the amount of seek
416  std::vector < std::uint64_t > offsets;
417  {
418  std::lock_guard<std::mutex> lock (rng_mutex_);
419 
420  offsets.resize (filesamp);
421  boost::uniform_int < std::uint64_t > filedist (filestart, filestart + filecount - 1);
422  boost::variate_generator<boost::mt19937&, boost::uniform_int<std::uint64_t> > filedie (rand_gen_, filedist);
423  for (std::uint64_t i = 0; i < filesamp; i++)
424  {
425  std::uint64_t _filestart = filedie ();
426  offsets[i] = _filestart;
427  }
428  }
429  std::sort (offsets.begin (), offsets.end ());
430 
431  FILE* f = fopen (disk_storage_filename_.c_str (), "rbe");
432  assert (f != nullptr);
433  PointT p;
434  char* loc = reinterpret_cast<char*> (&p);
435  for (std::uint64_t i = 0; i < filesamp; i++)
436  {
437  int seekret = _fseeki64 (f, offsets[i] * static_cast<std::uint64_t> (sizeof(PointT)), SEEK_SET);
438  pcl::utils::ignore(seekret);
439  assert (seekret == 0);
440  std::size_t readlen = fread (loc, sizeof(PointT), 1, f);
441  pcl::utils::ignore(readlen);
442  assert (readlen == 1);
443 
444  dst.push_back (p);
445  }
446  int res = fclose (f);
447  pcl::utils::ignore(res);
448  assert (res == 0);
449  }
450  }
451  ////////////////////////////////////////////////////////////////////////////////
452 
453  template<typename PointT> void
455  {
456  writebuff_.push_back (p);
457  if (writebuff_.size () > WRITE_BUFF_MAX_)
458  {
459  flushWritebuff (false);
460  }
461  }
462  ////////////////////////////////////////////////////////////////////////////////
463 
464  template<typename PointT> void
466  {
467  const std::uint64_t count = src.size ();
468 
469  typename pcl::PointCloud<PointT>::Ptr tmp_cloud (new pcl::PointCloud<PointT> ());
470 
471  // If there's a pcd file with data
472  if (boost::filesystem::exists (disk_storage_filename_))
473  {
474  // Open the existing file
475  pcl::PCDReader reader;
476  int res = reader.read (disk_storage_filename_, *tmp_cloud);
477  pcl::utils::ignore(res);
478  assert (res == 0);
479  }
480  // Otherwise create the point cloud which will be saved to the pcd file for the first time
481  else
482  {
483  tmp_cloud->width = count + writebuff_.size ();
484  tmp_cloud->height = 1;
485  }
486 
487  for (std::size_t i = 0; i < src.size (); i++)
488  tmp_cloud->push_back (src[i]);
489 
490  // If there are any points in the write cache writebuff_, a different write cache than this one, concatenate
491  for (std::size_t i = 0; i < writebuff_.size (); i++)
492  {
493  tmp_cloud->push_back (writebuff_[i]);
494  }
495 
496  //assume unorganized point cloud
497  tmp_cloud->width = tmp_cloud->size ();
498 
499  //save and close
500  PCDWriter writer;
501 
502  int res = writer.writeBinaryCompressed (disk_storage_filename_, *tmp_cloud);
503  pcl::utils::ignore(res);
504  assert (res == 0);
505  }
506 
507  ////////////////////////////////////////////////////////////////////////////////
508 
509  template<typename PointT> void
511  {
513 
514  //if there's a pcd file with data associated with this node, read the data, concatenate, and resave
515  if (boost::filesystem::exists (disk_storage_filename_))
516  {
517  //open the existing file
518  pcl::PCDReader reader;
519  int res = reader.read (disk_storage_filename_, *tmp_cloud);
520  pcl::utils::ignore(res);
521  assert (res == 0);
522  pcl::PCDWriter writer;
523  PCL_DEBUG ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Concatenating point cloud from %s to new cloud\n", __FUNCTION__, disk_storage_filename_.c_str ());
524 
525  std::size_t previous_num_pts = tmp_cloud->width*tmp_cloud->height + input_cloud->width*input_cloud->height;
526  //Concatenate will fail if the fields in input_cloud do not match the fields in the PCD file.
527  pcl::concatenate (*tmp_cloud, *input_cloud, *tmp_cloud);
528  std::size_t res_pts = tmp_cloud->width*tmp_cloud->height;
529 
530  pcl::utils::ignore(previous_num_pts);
531  pcl::utils::ignore(res_pts);
532 
533  assert (previous_num_pts == res_pts);
534 
535  writer.writeBinaryCompressed (disk_storage_filename_, *tmp_cloud);
536 
537  }
538  else //otherwise create the point cloud which will be saved to the pcd file for the first time
539  {
540  pcl::PCDWriter writer;
541  int res = writer.writeBinaryCompressed (disk_storage_filename_, *input_cloud);
542  pcl::utils::ignore(res);
543  assert (res == 0);
544  }
545 
546  }
547 
548  ////////////////////////////////////////////////////////////////////////////////
549 
550  template<typename PointT> void
551  OutofcoreOctreeDiskContainer<PointT>::readRange (const std::uint64_t, const std::uint64_t, pcl::PCLPointCloud2::Ptr& dst)
552  {
553  pcl::PCDReader reader;
554 
555  Eigen::Vector4f origin;
556  Eigen::Quaternionf orientation;
557 
558  if (boost::filesystem::exists (disk_storage_filename_))
559  {
560 // PCL_INFO ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Reading points from disk from %s.\n", __FUNCTION__ , disk_storage_filename_->c_str ());
561  int pcd_version;
562  int res = reader.read (disk_storage_filename_, *dst, origin, orientation, pcd_version);
563  pcl::utils::ignore(res);
564  assert (res != -1);
565  }
566  else
567  {
568  PCL_ERROR ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] File %s does not exist in node.\n", __FUNCTION__, disk_storage_filename_.c_str ());
569  }
570  }
571 
572  ////////////////////////////////////////////////////////////////////////////////
573 
574  template<typename PointT> int
576  {
577  pcl::PCLPointCloud2::Ptr temp_output_cloud (new pcl::PCLPointCloud2 ());
578 
579  if (boost::filesystem::exists (disk_storage_filename_))
580  {
581 // PCL_INFO ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Reading points from disk from %s.\n", __FUNCTION__ , disk_storage_filename_->c_str ());
582  int res = pcl::io::loadPCDFile (disk_storage_filename_, *temp_output_cloud);
583  pcl::utils::ignore(res);
584  assert (res != -1);
585  if(res == -1)
586  return (-1);
587  }
588  else
589  {
590  PCL_ERROR ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] File %s does not exist in node.\n", __FUNCTION__, disk_storage_filename_.c_str ());
591  return (-1);
592  }
593 
594  if(output_cloud.get () != nullptr)
595  {
596  pcl::concatenate (*output_cloud, *temp_output_cloud, *output_cloud);
597  }
598  else
599  {
600  output_cloud = temp_output_cloud;
601  }
602  return (0);
603  }
604 
605  ////////////////////////////////////////////////////////////////////////////////
606 
607  template<typename PointT> void
608  OutofcoreOctreeDiskContainer<PointT>::insertRange (const PointT* const * start, const std::uint64_t count)
609  {
610 // PCL_THROW_EXCEPTION (PCLException, "[pcl::outofcore::OutofcoreOctreeDiskContainer] Deprecated\n");
611  //copy the handles to a continuous block
612  PointT* arr = new PointT[count];
613 
614  //copy from start of array, element by element
615  for (std::size_t i = 0; i < count; i++)
616  {
617  arr[i] = *(start[i]);
618  }
619 
620  insertRange (arr, count);
621  delete[] arr;
622  }
623 
624  ////////////////////////////////////////////////////////////////////////////////
625 
626  template<typename PointT> void
627  OutofcoreOctreeDiskContainer<PointT>::insertRange (const PointT* start, const std::uint64_t count)
628  {
629  typename pcl::PointCloud<PointT>::Ptr tmp_cloud (new pcl::PointCloud<PointT> ());
630 
631  // If there's a pcd file with data, read it in from disk for appending
632  if (boost::filesystem::exists (disk_storage_filename_))
633  {
634  pcl::PCDReader reader;
635  // Open it
636  int res = reader.read (disk_storage_filename_, *tmp_cloud);
637  pcl::utils::ignore(res);
638  assert (res == 0);
639  }
640  else //otherwise create the pcd file
641  {
642  tmp_cloud->width = count + writebuff_.size ();
643  tmp_cloud->height = 1;
644  }
645 
646  // Add any points in the cache
647  for (std::size_t i = 0; i < writebuff_.size (); i++)
648  {
649  tmp_cloud->push_back (writebuff_ [i]);
650  }
651 
652  //add the new points passed with this function
653  for (std::size_t i = 0; i < count; i++)
654  {
655  tmp_cloud->push_back (*(start + i));
656  }
657 
658  tmp_cloud->width = tmp_cloud->size ();
659  tmp_cloud->height = 1;
660 
661  //save and close
662  PCDWriter writer;
663 
664  int res = writer.writeBinaryCompressed (disk_storage_filename_, *tmp_cloud);
665  pcl::utils::ignore(res);
666  assert (res == 0);
667  }
668  ////////////////////////////////////////////////////////////////////////////////
669 
670  template<typename PointT> std::uint64_t
672  {
673  pcl::PCLPointCloud2 cloud_info;
674  Eigen::Vector4f origin;
675  Eigen::Quaternionf orientation;
676  int pcd_version;
677  int data_type;
678  unsigned int data_index;
679 
680  //read the header of the pcd file and get the number of points
681  PCDReader reader;
682  reader.readHeader (disk_storage_filename_, cloud_info, origin, orientation, pcd_version, data_type, data_index, 0);
683 
684  std::uint64_t total_points = cloud_info.width * cloud_info.height + writebuff_.size ();
685 
686  return (total_points);
687  }
688  ////////////////////////////////////////////////////////////////////////////////
689 
690  }//namespace outofcore
691 }//namespace pcl
692 
693 #endif //PCL_OUTOFCORE_OCTREE_DISK_CONTAINER_IMPL_H_
Point Cloud Data (PCD) file format reader.
Definition: pcd_io.h:55
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.
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.
Point Cloud Data (PCD) file format writer.
Definition: pcd_io.h:299
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.
A base class for all pcl exceptions which inherits from std::runtime_error.
Definition: exceptions.h:66
PointCloud represents the base class in PCL for storing collections of 3D points.
Definition: point_cloud.h:173
const_iterator cbegin() const noexcept
Definition: point_cloud.h:433
void push_back(const PointT &pt)
Insert a new point in the cloud, at the end of the container.
Definition: point_cloud.h:663
const_iterator cend() const noexcept
Definition: point_cloud.h:434
std::uint32_t width
The point cloud width (if organized as an image-structure).
Definition: point_cloud.h:398
std::uint32_t height
The point cloud height (if organized as an image-structure).
Definition: point_cloud.h:400
std::size_t size() const
Definition: point_cloud.h:443
shared_ptr< PointCloud< PointT > > Ptr
Definition: point_cloud.h:413
Class responsible for serialization and deserialization of out of core point data.
int read(pcl::PCLPointCloud2::Ptr &output_cloud)
Reads the entire point contents from disk into output_cloud.
OutofcoreOctreeDiskContainer()
Empty constructor creates disk container and sets filename from random uuid string.
static void getRandomUUIDString(std::string &s)
Generate a universally unique identifier (UUID)
void insertRange(const AlignedPointTVector &src)
Inserts a vector of points into the disk data structure.
void readRangeSubSample_bernoulli(const std::uint64_t start, const std::uint64_t count, const double percent, AlignedPointTVector &dst)
Use bernoulli trials to select 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.
std::uint64_t getDataSize() const
Returns the number of points in the PCD file by reading the PCD header.
std::string & path()
Returns this objects path name.
typename OutofcoreAbstractNodeContainer< PointT >::AlignedPointTVector AlignedPointTVector
void readRangeSubSample(const std::uint64_t start, const std::uint64_t count, const double percent, AlignedPointTVector &dst) override
grab percent*count random points.
void push_back(const PointT &p)
Adds a single point to the buffer to be written to disk when the buffer grows sufficiently large,...
PointT operator[](std::uint64_t idx) const override
provides random access to points based on a linear index
~OutofcoreOctreeDiskContainer() override
flushes write buffer, then frees memory
Defines all the PCL implemented PointT point type structures.
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 loadPCDFile(const std::string &file_name, pcl::PCLPointCloud2 &cloud)
Load a PCD v.6 file into a templated PointCloud type.
Definition: pcd_io.h:633
boost::uuids::basic_random_generator< boost::mt19937 > OutofcoreOctreeDiskContainer< PointT >::uuid_gen_ & rand_gen_
void ignore(const T &...)
Utility function to eliminate unused variable warnings.
Definition: utils.h:62
shared_ptr< ::pcl::PCLPointCloud2 > Ptr
A point structure representing Euclidean xyz coordinates, and the RGB color.