0

I have a point cloud defined as pcl::PointCloud<pcl::PointXYZI> cloud_xyzi_;. Sometime later, I read in data from a file and push it back into this point cloud; everything works fine. My task however requires me to filter the point cloud, and the filtering methods require pointers.

Can I simply replace my above declaration with something like this pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_xyzi_p;, initialise it in the constructor of the class and then have a pointer on its own, rather than creating a pointer just to pass it to a function? Of course change the . to -> when I use it otherwise. I ask this because I am getting unexpected behaviour when trying to implement this.

Here is my abridged class, with the current code which seems both redundant and not working great.

class P400toPointcloud {
public:
    P400toPointcloud():
    callback_counter_(0),
    sensor_model_created_(false)
    {
        // Setup pointers for later use
        cloud_xyzi_p = cloud_xyzi_.makeShared();
        cloud_xyzi_fp = cloud_xyzi_f.makeShared();
    }

    ~P400toPointcloud()
    {
    }


private:
    pcl::PointCloud<pcl::PointXYZI> cloud_xyzi_;
    pcl::PointCloud<pcl::PointXYZI> cloud_xyzi_f;
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_xyzi_p;
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_xyzi_fp;

    std::vector<unsigned int> value_idx_;

};

1 Answer 1

3

The code that you have in the constructor have a different effect from what you probably expect:

// Setup pointers for later use
cloud_xyzi_p = cloud_xyzi_.makeShared();
cloud_xyzi_fp = cloud_xyzi_f.makeShared();

The call to makeShared() allocates memory for a new point cloud, copies the contents of the old one inside, wraps the pointer to the new cloud into boost::shared_ptr and returns. Effectively, you get a completely independent copy that can be used in functions that accept pointers. Any modifications done to it will not affect the original cloud.

Since you know you will need to work with the point cloud via its pointer, you should just have a pcl::PointCloud<pcl::PointXYZI>::Ptr. But don't forget to allocate memory for it in the constructor:

class P400toPointcloud {
public:
    P400toPointcloud():
    callback_counter_(0),
    sensor_model_created_(false),
    cloud_xyzi_(new pcl::PointCloud<pcl::PointXYZI>),
    cloud_xyzi_f(new pcl::PointCloud<pcl::PointXYZI>)
    {
        // From now on you pass
        //   cloud_xyzi_ to functions that expect pointer to a point cloud
        //   *cloud_xyzi_ to functions that expect (raw) point cloud
    }

    ~P400toPointcloud()
    {
    }

private:
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_xyzi_;
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_xyzi_f;

    std::vector<unsigned int> value_idx_;

};
Sign up to request clarification or add additional context in comments.

3 Comments

thank you for the good explanation - when I was trying to make sense of the docs it said it made a deep copy somewhere. wish i could upvote that more than once.
To which specific doc are you referring? We may refine it to avoid confusion in future.
".. Note that deep copy is performed.." docs.pointclouds.org/1.7.1/classpcl_1_1_point_cloud.html.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.