Reputation: 183
I've got a PCD point cloud and I want it to show progressively in a window inside a MFC application. In my dialog I have some code that opens this viewer, but for some reason, it seems that it isn't working. I am working with the PCL library.
Here's the code of the dialog
// ClavegueresDlg.cpp: archivo de implementación
//
#include "stdafx.h"
#include "Clavegueres.h"
#include "ClavegueresDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
//#define new DEBUG_NEW
#endif
// Cuadro de diálogo CAboutDlg utilizado para el comando Acerca de
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Datos del cuadro de diálogo
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // Compatibilidad con DDX/DDV
// Implementación
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// Cuadro de diálogo de CClavegueresDlg
CClavegueresDlg::CClavegueresDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CClavegueresDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CClavegueresDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CClavegueresDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON2, &CClavegueresDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON1, &CClavegueresDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
// Controladores de mensaje de CClavegueresDlg
BOOL CClavegueresDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Agregar el elemento de menú "Acerca de..." al menú del sistema.
// IDM_ABOUTBOX debe estar en el intervalo de comandos del sistema.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Establecer el icono para este cuadro de diálogo. El marco de trabajo realiza esta operación
// automáticamente cuando la ventana principal de la aplicación no es un cuadro de diálogo
SetIcon(m_hIcon, TRUE); // Establecer icono grande
SetIcon(m_hIcon, FALSE); // Establecer icono pequeño
// TODO: agregar aquí inicialización adicional
return TRUE; // Devuelve TRUE a menos que establezca el foco en un control
}
void CClavegueresDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// Si agrega un botón Minimizar al cuadro de diálogo, necesitará el siguiente código
// para dibujar el icono. Para aplicaciones MFC que utilicen el modelo de documentos y vistas,
// esta operación la realiza automáticamente el marco de trabajo.
void CClavegueresDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // Contexto de dispositivo para dibujo
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Centrar icono en el rectángulo de cliente
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Dibujar el icono
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// El sistema llama a esta función para obtener el cursor que se muestra mientras el usuario arrastra
// la ventana minimizada.
HCURSOR CClavegueresDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CClavegueresDlg::InitPCL()
{
if (io::loadPCDFile<PointXYZ>("C:\\Users\\avilarrubla\\Desktop\\Clavegueres\\configuracio\\InfSup.pcd", original_point_cloud) == -1) //* load the file
{
//error
}
else
{
Eigen::Matrix4f scale_trf = Eigen::Matrix4f::Identity();
float fl_scale = 3;
scale_trf(0, 0) = fl_scale; scale_trf(1, 1) = fl_scale; scale_trf(2, 2) = fl_scale;
transformPointCloud(original_point_cloud, point_cloud, scale_trf);
//color = PointCloud<PointXYZRGB>();
//copyPointCloud(point_cloud, color);
vamos_borrar = point_cloud.begin();
point_cloud_anadir = PointCloud<PointXYZ>::Ptr();
cuantos = point_cloud.points.size();
tenemos = 0;
viewer = visualization::PCLVisualizer("", false);
viewer.setBackgroundColor(0.94, 0.1, 0.1);
VisualiserRenderer = vtkRenderer::New();
InteractionVisualiserWindow = vtkRenderWindowInteractor::New();
VisualiserWindow = viewer.getRenderWindow();
/*
InteractionVisualiserWindow->RemoveObservers(vtkCommand::LeftButtonPressEvent);
InteractionVisualiserWindow->RemoveObservers(vtkCommand::RightButtonPressEvent);
InteractionVisualiserWindow->RemoveObservers(vtkCommand::MiddleButtonPressEvent);
InteractionVisualiserWindow->RemoveObservers(vtkCommand::MouseWheelBackwardEvent);
InteractionVisualiserWindow->RemoveObservers(vtkCommand::MouseWheelForwardEvent);
*/
LPRECT rect = new CRect;
CStatic *pclStatic = new CStatic();
pclStatic = (CStatic*)GetDlgItem(IDC_VISTA3D);
VisualiserWindow->SetParentId(pclStatic->m_hWnd);
//VisualiserWindow->SetSize(rect->right - rect->left, rect->bottom - rect->top);
VisualiserWindow->SetSize(0, 0);
//VisualiserWindow->SetPosition(10, 10);
InteractionVisualiserWindow->SetRenderWindow(VisualiserWindow);
VisualiserWindow->Render();
InteractionVisualiserWindow->Render();
//single_color = visualization::PointCloudColorHandlerCustom<PointXYZ>(point_cloud_anadir, 10, 255, 10);
SetTimer(1, 10, NULL);
}
}
void CClavegueresDlg::OnTimer(UINT_PTR nIDEvent)
{
viewer.removePointCloud("point_cloud_anadir");
viewer.removeAllShapes();
if (point_cloud_anadir->points.size() < cuantos){
point_cloud_anadir->points.resize(point_cloud_anadir->points.size() + 1);
point_cloud_anadir->points[tenemos].x = (*vamos_borrar).x;
point_cloud_anadir->points[tenemos].y = (*vamos_borrar).y;
point_cloud_anadir->points[tenemos].z = (*vamos_borrar).z;
++vamos_borrar;
++tenemos;
}
viewer.addPointCloud<PointXYZ>(point_cloud_anadir, "sample cloud");
viewer.setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");
CDialogEx::OnTimer(nIDEvent);
}
void CClavegueresDlg::OnBnClickedButton2()
{
// TODO: Agregue aquí su código de controlador de notificación de control
//visualization::PCLVisualizer viewer("", false);
KillTimer(1);
if (!viewer.wasStopped()){
viewer.~PCLVisualizer();
viewer.close();
}
}
void CClavegueresDlg::OnBnClickedButton1()
{
// TODO: Agregue aquí su código de controlador de notificación de control
InitPCL();
}
Button1 is a button that when clicked should begin to show the point cloud and Button2 should stop it. The important code is the InitPCL()
and the timer code. The first one initializes the viewer and the Timer inserts into the viewer a point every 10ms. Is there something wrong? How should I change this in order to work?
Upvotes: 0
Views: 261
Reputation: 50775
You should have written what exactly does not work, but I guess you simply forgot ON_WM_TIMER()
in the message map and therefore OnTimer
is never called.
BEGIN_MESSAGE_MAP(CClavegueresDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_TIMER() // <<<<<<<<<<<<<<< add this line
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON2, &CClavegueresDlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON1, &CClavegueresDlg::OnBnClickedButton1)
END_MESSAGE_MAP()
In the declaration of CClavegueresDlg
add this:
void OnTimer(UINT_PTR nIDEvent);
You could have found out this yourself by using the debugger.
There may be other issues related to the PCL.
Upvotes: 2