I am trying to use the point clicking callback of PCLvisualizer. The code uses the QVTKwidget to show the PCLvisualizer in a qt GUI. The project below compiles fine and works but when I include this code to set up a callback:
// ERROR MESSAGE OCCURS HERE ! viewer->registerPointPickingCallback (PCLViewer::callback_Test,(void*)&viewer); then this error message shows:
error: C3867: 'PCLViewer::callback_Test': non-standard syntax; use '&' to create a pointer to member
Just to test the callback I made a public function callback_Test() that just prints to qDebug
void PCLViewer::callback_Test() { qDebug() << "callback_Test executed"; } What is wrong with my code?
This is my code:
#include "pclviewer.h" #include "../build/ui_pclviewer.h" PCLViewer::PCLViewer (QWidget *parent) : QMainWindow (parent), ui (new Ui::PCLViewer) { ui->setupUi (this); this->setWindowTitle ("PCL viewer"); // Setup the cloud pointer cloud.reset (new PointCloudT); // The number of points in the cloud cloud->points.resize (200); // The default color red = 128; green = 128; blue = 128; // Fill the cloud with some points for (size_t i = 0; i < cloud->points.size (); ++i) { cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].r = red; cloud->points[i].g = green; cloud->points[i].b = blue; } // Set up the QVTK window viewer.reset (new pcl::visualization::PCLVisualizer ("viewer", false)); ui->qvtkWidget->SetRenderWindow (viewer->getRenderWindow ()); viewer->setupInteractor (ui->qvtkWidget->GetInteractor (), ui->qvtkWidget->GetRenderWindow ()); ui->qvtkWidget->update (); viewer->addPointCloud (cloud, "cloud"); viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud"); viewer->resetCamera (); ui->qvtkWidget->update (); // ERROR MESSAGE OCCURS HERE ! viewer->registerPointPickingCallback (PCLViewer::callback_Test,(void*)&viewer); } PCLViewer::~PCLViewer () { delete ui; } void PCLViewer::callback_Test() { qDebug() << "callback_Test executed"; } This is my headerfile:
#ifndef PCLVIEWER_H #define PCLVIEWER_H #include <iostream> // Qt #include <QMainWindow> #include <QDebug> // Point Cloud Library #include <pcl/point_cloud.h> //#include <C:\Program Files\PCL 1.8.0\include\pcl-1.8\pcl\point_cloud.h> #include <pcl/point_types.h> //#include <C:\Program Files\PCL 1.8.0\include\pcl-1.8\pcl\point_types.h> #include <pcl/visualization/pcl_visualizer.h> //#include <C:\Program Files\PCL 1.8.0\include\pcl-1.8\pcl\visualization\pcl_visualizer.h> // Visualization Toolkit (VTK) #include <vtkRenderWindow.h> //#include <C:\Program Files\VTK\include\vtk-7.1\vtkRenderWindow.h> typedef pcl::PointXYZRGBA PointT; typedef pcl::PointCloud<PointT> PointCloudT; namespace Ui { class PCLViewer; } class PCLViewer : public QMainWindow { Q_OBJECT public: explicit PCLViewer (QWidget *parent = 0); ~PCLViewer (); void callback_Test(); public slots: protected: boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer; PointCloudT::Ptr cloud; unsigned int red; unsigned int green; unsigned int blue; private: Ui::PCLViewer *ui; }; #endif // PCLVIEWER_H 53 Answers
I found the problem thanks to @Some programmer dude 's comments:
Solution:
1) I declared the callback_Test outside the PCLViewer class
2) I used two arguments as expected by code calling the callback
Header file:
#ifndef PCLVIEWER_H #define PCLVIEWER_H #include <iostream> // Qt #include <QMainWindow> #include <QDebug> // Point Cloud Library #include <pcl/point_cloud.h> //#include <C:\Program Files\PCL 1.8.0\include\pcl-1.8\pcl\point_cloud.h> #include <pcl/point_types.h> //#include <C:\Program Files\PCL 1.8.0\include\pcl-1.8\pcl\point_types.h> #include <pcl/visualization/pcl_visualizer.h> //#include <C:\Program Files\PCL 1.8.0\include\pcl-1.8\pcl\visualization\pcl_visualizer.h> // included this as well -- however it seems to not be needed //#include <pcl/visualization/point_picking_event.h> // Visualization Toolkit (VTK) #include <vtkRenderWindow.h> //#include <C:\Program Files\VTK\include\vtk-7.1\vtkRenderWindow.h> typedef pcl::PointXYZRGBA PointT; typedef pcl::PointCloud<PointT> PointCloudT; namespace Ui { class PCLViewer; } class PCLViewer : public QMainWindow { Q_OBJECT public: explicit PCLViewer (QWidget *parent = 0); ~PCLViewer (); public slots: protected: boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer; PointCloudT::Ptr cloud; unsigned int red; unsigned int green; unsigned int blue; private: Ui::PCLViewer *ui; }; // ######################################################################################## // DECLARE OUTSIDE OF CLASS! WITH TWO ARGUMENTS void callback_Test(const pcl::visualization::PointPickingEvent& event, void* viewer_void); #endif // PCLVIEWER_H Then I called the registerPointPickingCallback without &;
// NOW ITS OK and no & is needed since callback_Test is outside the PCLViewer class viewer->registerPointPickingCallback (callback_Test,(void*)&viewer); The below code works.
.CPP file:
#include "pclviewer.h" #include "../build/ui_pclviewer.h" PCLViewer::PCLViewer (QWidget *parent) : QMainWindow (parent), ui (new Ui::PCLViewer) { ui->setupUi (this); this->setWindowTitle ("PCL viewer"); // Setup the cloud pointer cloud.reset (new PointCloudT); // The number of points in the cloud cloud->points.resize (200); // The default color red = 128; green = 128; blue = 128; // Fill the cloud with some points for (size_t i = 0; i < cloud->points.size (); ++i) { cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].r = red; cloud->points[i].g = green; cloud->points[i].b = blue; } // Set up the QVTK window viewer.reset (new pcl::visualization::PCLVisualizer ("viewer", false)); ui->qvtkWidget->SetRenderWindow (viewer->getRenderWindow ()); viewer->setupInteractor (ui->qvtkWidget->GetInteractor (), ui->qvtkWidget->GetRenderWindow ()); ui->qvtkWidget->update (); viewer->addPointCloud (cloud, "cloud"); viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud"); viewer->resetCamera (); ui->qvtkWidget->update (); // NOW ITS OK and no & is needed since callback_Test is outside the PCLViewer class viewer->registerPointPickingCallback (callback_Test,(void*)&viewer); } PCLViewer::~PCLViewer () { delete ui; } void callback_Test (const pcl::visualization::PointPickingEvent& event, void* viewer_void) { qDebug() << "callback_Test executed"; } The actual answer to your question is that you needed to include the & like the compiler told you
viewer->registerPointPickingCallback (&PCLViewer::callback_Test,(void*)&viewer) If anyone runs into this (and wants to use a member function). I solved it using the following. Just define your function as a member and use *this:
viewer->registerPointPickingCallback (&PCLViewer::callback_Test,*this)