Point Cloud Library (PCL)  1.14.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 <boost/random/bernoulli_distribution.hpp>
50 #include <boost/random/uniform_int.hpp>
51 #include <boost/random/variate_generator.hpp> // for boost::variate_generator
52 #include <boost/uuid/uuid_io.hpp>
53 
54 // PCL
55 #include <pcl/common/utils.h> // pcl::utils::ignore
56 #include <pcl/io/pcd_io.h>
57 #include <pcl/point_types.h>
58 #include <pcl/PCLPointCloud2.h>
59 
60 // PCL (Urban Robotics)
61 #include <pcl/outofcore/octree_disk_container.h>
62 
63 //allows operation on POSIX
64 #if !defined _WIN32
65 #define _fseeki64 fseeko
66 #elif defined __MINGW32__
67 #define _fseeki64 fseeko64
68 #endif
69 
70 namespace pcl
71 {
72  namespace outofcore
73  {
74  template<typename PointT>
75  std::mutex OutofcoreOctreeDiskContainer<PointT>::rng_mutex_;
76 
77  template<typename PointT> boost::mt19937
78  OutofcoreOctreeDiskContainer<PointT>::rand_gen_ (static_cast<unsigned int> (std::time(nullptr)));
79 
80  template<typename PointT>
81  boost::uuids::basic_random_generator<boost::mt19937> OutofcoreOctreeDiskContainer<PointT>::uuid_gen_ (&rand_gen_);
82 
83  template<typename PointT>
84  const std::uint64_t OutofcoreOctreeDiskContainer<PointT>::READ_BLOCK_SIZE_ = static_cast<std::uint64_t> (2e12);
85  template<typename PointT>
86  const std::uint64_t OutofcoreOctreeDiskContainer<PointT>::WRITE_BUFF_MAX_ = static_cast<std::uint64_t> (2e12);
87 
88  template<typename PointT> void
90  {
91  boost::uuids::uuid u;
92  {
93  std::lock_guard<std::mutex> lock (rng_mutex_);
94  u = uuid_gen_ ();
95  }
96 
97  std::stringstream ss;
98  ss << u;
99  s = ss.str ();
100  }
101  ////////////////////////////////////////////////////////////////////////////////
102 
103  template<typename PointT>
105  : filelen_ (0)
106  , writebuff_ (0)
107  {
108  getRandomUUIDString (disk_storage_filename_);
109  filelen_ = 0;
110  }
111  ////////////////////////////////////////////////////////////////////////////////
112 
113  template<typename PointT>
115  : filelen_ (0)
116  , writebuff_ (0)
117  {
118  if (boost::filesystem::exists (path))
119  {
120  if (boost::filesystem::is_directory (path))
121  {
122  std::string uuid;
123  getRandomUUIDString (uuid);
124  boost::filesystem::path filename (uuid);
125  boost::filesystem::path file = path / filename;
126 
127  disk_storage_filename_ = file.string ();
128  }
129  else
130  {
131  std::uint64_t len = boost::filesystem::file_size (path);
132 
133  disk_storage_filename_ = path.string ();
134 
135  filelen_ = len / sizeof(PointT);
136 
137  pcl::PCLPointCloud2 cloud_info;
138  Eigen::Vector4f origin;
139  Eigen::Quaternionf orientation;
140  int pcd_version;
141  int data_type;
142  unsigned int data_index;
143 
144  //read the header of the pcd file and get the number of points
145  PCDReader reader;
146  reader.readHeader (disk_storage_filename_, cloud_info, origin, orientation, pcd_version, data_type, data_index, 0);
147 
148  filelen_ = cloud_info.width * cloud_info.height;
149  }
150  }
151  else //path doesn't exist
152  {
153  disk_storage_filename_ = path.string ();
154  filelen_ = 0;
155  }
156  }
157  ////////////////////////////////////////////////////////////////////////////////
158 
159  template<typename PointT>
161  {
162  flushWritebuff (true);
163  }
164  ////////////////////////////////////////////////////////////////////////////////
165 
166  template<typename PointT> void
167  OutofcoreOctreeDiskContainer<PointT>::flushWritebuff (const bool force_cache_dealloc)
168  {
169  if (!writebuff_.empty ())
170  {
171  //construct the point cloud for this node
173 
174  cloud->width = writebuff_.size ();
175  cloud->height = 1;
176 
177  cloud->points = writebuff_;
178 
179  //write data to a pcd file
180  pcl::PCDWriter writer;
181 
182 
183  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 ());
184 
185  // Write ascii for now to debug
186  int res = writer.writeBinaryCompressed (disk_storage_filename_, *cloud);
187  pcl::utils::ignore(res);
188  assert (res == 0);
189  if (force_cache_dealloc)
190  {
191  writebuff_.resize (0);
192  }
193  }
194  }
195  ////////////////////////////////////////////////////////////////////////////////
196 
197  template<typename PointT> PointT
199  {
200  PCL_THROW_EXCEPTION (PCLException, "[pcl::outofcore::OutofcoreOctreeDiskContainer] Not implemented for use with PCL library\n");
201 
202  //if the index is on disk
203  if (idx < filelen_)
204  {
205 
206  PointT temp;
207  //open our file
208  FILE* f = fopen (disk_storage_filename_.c_str (), "rbe");
209  assert (f != nullptr);
210 
211  //seek the right length;
212  int seekret = _fseeki64 (f, idx * sizeof(PointT), SEEK_SET);
213  pcl::utils::ignore(seekret);
214  assert (seekret == 0);
215 
216  std::size_t readlen = fread (&temp, 1, sizeof(PointT), f);
217  pcl::utils::ignore(readlen);
218  assert (readlen == sizeof (PointT));
219 
220  int res = fclose (f);
221  pcl::utils::ignore(res);
222  assert (res == 0);
223 
224  return (temp);
225  }
226  //otherwise if the index is still in the write buffer
227  if (idx < (filelen_ + writebuff_.size ()))
228  {
229  idx -= filelen_;
230  return (writebuff_[idx]);
231  }
232 
233  //else, throw out of range exception
234  PCL_THROW_EXCEPTION (PCLException, "[pcl::outofcore:OutofcoreOctreeDiskContainer] Index is out of range");
235  }
236 
237  ////////////////////////////////////////////////////////////////////////////////
238  template<typename PointT> void
239  OutofcoreOctreeDiskContainer<PointT>::readRange (const std::uint64_t start, const std::uint64_t count, AlignedPointTVector& dst)
240  {
241  if (count == 0)
242  {
243  return;
244  }
245 
246  if ((start + count) > size ())
247  {
248  PCL_ERROR ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Indices out of range; start + count exceeds the size of the stored points\n", __FUNCTION__);
249  PCL_THROW_EXCEPTION (PCLException, "[pcl::outofcore::OutofcoreOctreeDiskContainer] Outofcore Octree Exception: Read indices exceed range");
250  }
251 
252  pcl::PCDReader reader;
254 
255  int res = reader.read (disk_storage_filename_, *cloud);
256  pcl::utils::ignore(res);
257  assert (res == 0);
258 
259  dst.insert(dst.end(), cloud->cbegin(), cloud->cend());
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 != nullptr);
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  pcl::utils::ignore(seekret);
343  assert (seekret == 0);
344  std::size_t readlen = fread (loc, sizeof(PointT), 1, f);
345  pcl::utils::ignore(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  auto 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 != nullptr);
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  pcl::utils::ignore(seekret);
440  assert (seekret == 0);
441  std::size_t readlen = fread (loc, sizeof(PointT), 1, f);
442  pcl::utils::ignore(readlen);
443  assert (readlen == 1);
444 
445  dst.push_back (p);
446  }
447  int res = fclose (f);
448  pcl::utils::ignore(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  pcl::utils::ignore(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 = count + writebuff_.size ();
485  tmp_cloud->height = 1;
486  }
487 
488  for (std::size_t i = 0; i < src.size (); i++)
489  tmp_cloud->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->push_back (writebuff_[i]);
495  }
496 
497  //assume unorganized point cloud
498  tmp_cloud->width = tmp_cloud->size ();
499 
500  //save and close
501  PCDWriter writer;
502 
503  int res = writer.writeBinaryCompressed (disk_storage_filename_, *tmp_cloud);
504  pcl::utils::ignore(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  pcl::utils::ignore(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  pcl::utils::ignore(previous_num_pts);
532  pcl::utils::ignore(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  pcl::utils::ignore(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 
559  if (boost::filesystem::exists (disk_storage_filename_))
560  {
561 // PCL_INFO ("[pcl::outofcore::OutofcoreOctreeDiskContainer::%s] Reading points from disk from %s.\n", __FUNCTION__ , disk_storage_filename_->c_str ());
562  int pcd_version;
563  int res = reader.read (disk_storage_filename_, *dst, origin, orientation, pcd_version);
564  pcl::utils::ignore(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  pcl::utils::ignore(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_, *tmp_cloud);
638  pcl::utils::ignore(res);
639  assert (res == 0);
640  }
641  else //otherwise create the pcd file
642  {
643  tmp_cloud->width = count + 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->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->push_back (*(start + i));
657  }
658 
659  tmp_cloud->width = tmp_cloud->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  pcl::utils::ignore(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_
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:67
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.
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.