1
votes

As I'm getting into Point Cloud Library (PCL) I'm encountering some confusion on when to declare point clouds with ::Ptr verses without this.

It seems to work either way, for example both of these programs compile, run, and product the expected results (writing a random 20 point cloud to file):

// WriteCloud.cpp

#include <iostream>

#include <pcl/common/common_headers.h>
#include <pcl/io/pcd_io.h>

int main(void)
{
  std::cout << "\n\n" << "starting program" << "\n\n";

  pcl::PointCloud<pcl::PointXYZ> cloud;    // !!! without ::Ptr !!!

  int numPoints = 20;

  for (int i = 0; i < numPoints; i++)
  {
    pcl::PointXYZ point;

    point.x = 1024 * rand() / (RAND_MAX + 1.0f);
    point.y = 1024 * rand() / (RAND_MAX + 1.0f);
    point.z = 1024 * rand() / (RAND_MAX + 1.0f);

    cloud.points.push_back(point);
  }

  // for simplicity, use an "unorganized" cloud, "width" = num points, "height" = 1
  cloud.width = (int)cloud.points.size();
  cloud.height = 1;

  pcl::io::savePCDFileASCII("my_cloud.pcd", cloud);

  std::cout << "\n\n" << "program complete" << "\n\n";

  return (0);
}

and

// WriteCloudPtr.cpp

#include <iostream>

#include <pcl/common/common_headers.h>
#include <pcl/io/pcd_io.h>

int main(void)
{
  std::cout << "\n\n" << "starting program" << "\n\n";

  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);      // !!! with ::Ptr !!!

  int numPoints = 20;

  for (int i = 0; i < numPoints; i++)
  {
    pcl::PointXYZ point;

    point.x = 1024 * rand() / (RAND_MAX + 1.0f);
    point.y = 1024 * rand() / (RAND_MAX + 1.0f);
    point.z = 1024 * rand() / (RAND_MAX + 1.0f);

    cloud->points.push_back(point);
  }

  // for simplicity, use an "unorganized" cloud, "width" = num points, "height" = 1
  cloud->width = (int)cloud->points.size();
  cloud->height = 1;

  pcl::io::savePCDFileASCII("my_cloud.pcd", *cloud);

  std::cout << "\n\n" << "program complete" << "\n\n";

  return (0);
}

Is there a rule of thumb as to which should be used? More specifically, here are some questions I have:

-In all of the PCL GitHub examples https://github.com/PointCloudLibrary/pcl/tree/master/examples the programs use ::Ptr, and on the website most (but not all) of the examples use ::Ptr. Also, for the most part, the examples I've found not using ::Ptr seem to be very old. Based on this more than anything I'm under the impression that ::Ptr is generally regarded as the current PCL standard, is this correct?

-The non-::Ptr way seems simpler, is there any disadvantage to the non-::Ptr way that is not apparent? Before somebody says "passing these into a function would make a copy of the cloud and therefore be inefficient" I would pass by reference so as to not make copies unnecessarily.

-Clearly ::Ptr is a typedef (essentially a renaming) of boost::shared_ptr. Still, it makes me uncomfortable to use pointers when not necessary as funny things can happen in odd situations. For example the accepted answer to this post Create a pcl::PointCloud::Ptr from a pcl::PointCloud mentions an odd conversion situation which could seem to cause a crash. Are there any risks with using the ::Ptr way in certain situations that PCL users should be aware of?

1

1 Answers

1
votes

IMHO, it's a design flaw in PCL to define function arguments for PointCloud as a PointCloud::Ptr since the functions don't care if the object is allocated on the stack or on the heap and neither do they make use of ownerships.

To your question, declare your objects as pointers when you know that your object will get very large, otherwise stick to non pointer version.