avm_69
avm_69

Reputation: 183

Show Point cloud progressively

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

Answers (1)

Jabberwocky
Jabberwocky

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

Related Questions