天天看点

pcl+vtk 3d坐标轴+数据展示

环境为msvc2010 + qt 5.2 编译生成的vtk7.1.1。 pcl 1.8.0   qt5.2qvtkwidgets .貌似只有这个编译环境才能造出vtk7.1.1 。 vtk8.0 需要2015+ qt5.6以上, vtk6.0 使用的qt是4版本的. 路过的请注意. 
使用 vtkTransform 将原始数据的 vtkActor 与坐标轴 vtkCubeAxesActor叠加在一起.  
      
void  PCLViewer::showPointCloud(pcl::PointCloud<PointT>::Ptr pointCloud)
{
    if(pointCloud->points.size() == 0){
      //  warningWindow(STR_3D_IMAGE_ERROR_TITLE);
        return;
    }

    vtkSmartPointer<vtkRenderer> pRender  = vtkSmartPointer<vtkRenderer>::New();

    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();//key code
    vtkIdType size = pointCloud->points.size();

    int n = size;
    for(int i = 0; i < n ; i ++ )
    {
        double ptx = pointCloud->points[i].x;
        double pty = pointCloud->points[i].y;
        double ptz = pointCloud->points[i].z;

        points->InsertNextPoint(ptx,pty,ptz);
    }

    vtkSmartPointer<vtkPolyVertex> polyvertex = vtkSmartPointer<vtkPolyVertex>::New();
    polyvertex->GetPointIds()->SetNumberOfIds(n);  //必须设置Id个数,否则可以编译,不能运行
    int i=0;
    for(i=0;i<n;i++)//建立拓扑关系
    {
        polyvertex->GetPointIds()->SetId(i,i);//第一个参数是几何point的ID号,第2个参数是拓扑中的Id号
    }

    //属性数据
    vtkSmartPointer<vtkFloatArray>pointsScalars=vtkSmartPointer<vtkFloatArray>::New();
    pointsScalars->SetNumberOfTuples(n);//此行可有可无
    for(i=0;i<n;i++)//建立拓扑关系
    {
        pointsScalars->InsertValue(i,0);//第1个参数是points点的Id,第2个参数是该点的属性值
    }

    vtkSmartPointer<vtkUnstructuredGrid> grid=vtkSmartPointer<vtkUnstructuredGrid>::New();
    grid->Allocate(1,1);
    grid->SetPoints(points);
    //grid->GetPointData()->SetScalars(pointsScalars);
    grid->InsertNextCell(polyvertex->GetCellType(), polyvertex->GetPointIds());

    //设置映射器
    vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
    mapper->SetInputData(grid);
    mapper->ScalarVisibilityOn();
    mapper->SetScalarRange(0,1);

    vtkSmartPointer<vtkActor> anActor=vtkSmartPointer<vtkActor>::New();
   anActor->SetMapper(mapper);
   anActor->GetProperty()->SetRepresentationToPoints();
   anActor->GetProperty()->SetDiffuseColor(128,128,0);
   anActor->GetProperty()->SetPointSize(5);
   anActor->GetProperty()->SetColor(0,255, 0);

    double dBounds[6];
    points->GetBounds(dBounds);
    int  xaxismin = floor(dBounds[0]);
    int  xaxismax = ceil(dBounds[1]);
    int  yaxismin = floor(dBounds[2]);
    int  yaxismax = ceil(dBounds[3]);
    int  zaxismin = floor(dBounds[4]);
    int  zaxismax = ceil(dBounds[5]);

   //----------------transform---------使得原始数据与3d坐标轴能够叠加匹配-----
       vtkSmartPointer<vtkTransform> trans =
            vtkSmartPointer<vtkTransform>::New();

       trans->PostMultiply();

       anActor->SetPosition(-(xaxismax)/2,
                            -(yaxismax)/2,
                            -(zaxismax)/2);  //( 0-20)  (0,2000)


        float fdata[3];
        fdata[0] = 2.0/(float(xaxismax-xaxismin));
        fdata[1] = 2.0/(float(yaxismax-yaxismin));
        fdata[2] = 2.0/(float(zaxismax-zaxismin));

       trans->Scale(fdata);

    anActor->SetUserTransform(trans);
    pRender->AddActor(anActor);

    //-------------------xyz axis -------------
    m_cubeAxesActor = vtkSmartPointer<vtkCubeAxesActor>::New();
    m_cubeAxesActor->SetUseAxisOrigin(0);

   // double dBoundsNew[6] = {xaxismin,xaxismax,yaxismin,yaxismax,zaxismin,zaxismax};
   // m_cubeAxesActor->SetBounds(dBoundsNew); // 按照数据的外包围框 ,如果不用tranform, 使用这个setbounds 会有很多坑,比如 坐标标签显示不出来. 

    vtkSmartPointer<vtkCamera> camera = pRender->GetActiveCamera();
    m_cubeAxesActor->SetCamera(camera);
    //设置x、y、z轴的起始和终止值
   double xaxis[2] = {xaxismin,xaxismax};
   double yaxis[2] = {yaxismin,yaxismax};
   double zaxis[2] = {zaxismin,zaxismax};
     m_cubeAxesActor->SetXAxisRange(xaxis);
     m_cubeAxesActor->SetYAxisRange(yaxis);
     m_cubeAxesActor->SetZAxisRange(zaxis);
  //  m_cubeAxesActor->SetXTitle("X /mm");//设置X轴的标签
  //  m_cubeAxesActor->SetYTitle("Y /mm");
  //  m_cubeAxesActor->SetZTitle("Z /mm");
    m_cubeAxesActor->GetTitleTextProperty(0)->SetColor(1.0, 0.0, 1.0);//设置x轴的标题的颜色为
    m_cubeAxesActor->GetLabelTextProperty(0)->SetColor(1.0, 0.0, 1.0);//设置x轴的标签label颜色
    m_cubeAxesActor->GetTitleTextProperty(1)->SetColor(0.0, 1.0, 0.0);
    m_cubeAxesActor->GetLabelTextProperty(1)->SetColor(0.0, 1.0, 0.0);
    m_cubeAxesActor->GetTitleTextProperty(2)->SetColor(0.5, 0.5, 1.0);
    m_cubeAxesActor->GetLabelTextProperty(2)->SetColor(0.5, 0.5, 1.0);
     //设置坐标轴线的宽度
     m_cubeAxesActor->GetXAxesLinesProperty()->SetLineWidth(0.5);
     m_cubeAxesActor->GetYAxesLinesProperty()->SetLineWidth(0.5);
     m_cubeAxesActor->GetZAxesLinesProperty()->SetLineWidth(0.5);
     //设置标题和标签文本的屏幕大小。默认值为10.0。
     m_cubeAxesActor->SetScreenSize(10);
     //指定标签与轴之间的距离。默认值为20.0。
     m_cubeAxesActor->SetLabelOffset(0.1);
     m_cubeAxesActor->SetTitleOffset(0.1);
     //显示坐标轴
     m_cubeAxesActor->SetVisibility(true);

     //指定一种模式来控制轴的绘制方式
     m_cubeAxesActor->SetFlyMode(0);
     //设置惯性因子,该惯性因子控制轴切换位置的频率(从一个轴跳到另一个轴)
     //m_cubeAxesActor->SetInertia(1);

     //开启x、y、z轴的网格线绘制
     m_cubeAxesActor->DrawXGridlinesOn();
     m_cubeAxesActor->DrawYGridlinesOn();
     m_cubeAxesActor->DrawZGridlinesOn();
     //设置x、y、z轴的内部网格线不绘制
     m_cubeAxesActor->SetDrawXInnerGridlines(false);
     m_cubeAxesActor->SetDrawYInnerGridlines(false);
     m_cubeAxesActor->SetDrawZInnerGridlines(false);
     //设置x、y、z轴网格线的颜色
     m_cubeAxesActor->GetXAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
     m_cubeAxesActor->GetYAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
     m_cubeAxesActor->GetZAxesGridlinesProperty()->SetColor(0.5, 0.5, 0.5);
     //指定网格线呈现的样式
     m_cubeAxesActor->SetGridLineLocation(2);

     m_cubeAxesActor->XAxisMinorTickVisibilityOff();
     m_cubeAxesActor->YAxisMinorTickVisibilityOff();
     m_cubeAxesActor->ZAxisMinorTickVisibilityOff();
     //设置刻度标签的显示方式(参数1为false,刻度标签按0-200000显示;为true时,按0-200显示)
     m_cubeAxesActor->SetLabelScaling(true, 0, 0,0);
     //设置刻度线显示的位置(内部、外部、两侧)
     m_cubeAxesActor->SetTickLocation(2);
     pRender->AddActor(m_cubeAxesActor);
     pRender->ResetCamera();
     pRender->ResetCameraClippingRange(); //不加这一行可能会成像不完整。

     ui->qvtkWidget->GetRenderWindow()->AddRenderer(pRender);
     ui->qvtkWidget->GetRenderWindow()->Render();
}