逐步显示点云

Show Point cloud progressively

我有一个 PCD 点云,我希望它在 MFC 应用程序内的 window 中逐渐显示。在我的对话框中,我有一些代码可以打开这个查看器,但由于某种原因,它似乎不起作用。我正在使用 PCL 库。

这是对话框的代码

// 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 是一个按钮,单击它时应该开始显示点云,Button2 应该停止它。重要的代码是 InitPCL() 和定时器代码。第一个初始化查看器,定时器每 10 毫秒向查看器插入一个点。有什么不对?我应该如何改变它才能工作?

你应该写下 究竟是什么 不起作用,但我猜你只是在消息映射中忘记了 ON_WM_TIMER() 因此 OnTimer 永远不会被调用.

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() 

CClavegueresDlg 的声明中添加:

void OnTimer(UINT_PTR nIDEvent);

您可以使用调试器自己发现这一点。

可能存在与 PCL 相关的其他问题。