基于Qt在PCL中画圆环,VTK画圆环,pcl可视化viewer与vtk显示接合(终于解决)

一、问题

想在利用PCL在点云可视化界面达到下图效果,主要是如何画圆。

找了很多资料,pcl中有 pcl::visualization::PCLVisualizer::addCircle 画圆环,但是明显看到圆环不圆,线条不光滑,不好看,于是有了我的画圆的方法。

在PCL中画圆环,pcl可视化pcl::visualization::PCLVisualizer

但是这样利用线段画圆性能不好,画得越多越卡,那还有什么办法呢?

二、利用vtk的不规则图形vtkRegularPolygonSource画圆

pcl没有画圆的接口,那就只有用VTK了,vtk也没有直接的画圆方案,但是参考了很多资料,发现了vtkRegularPolygonSource,画一个多边形,边设置多一点就无限接近圆了,和用线段拼接一个道理,只是这样效果更好。

重点是vtk画的图形和pcl可视化pcl::visualization::PCLVisualizer的viewer同时显示,而不是独立的。话不多说,上代码。

三、源码

void mainwindow::on_action_showGrid_triggered(bool isChecked)
{
    if (isChecked)    //绘制圆环及网格
    {
        //画网格 
        for (int i = -100; i <= 100; i += 10) {
            viewer->addLine(pcl::PointXYZ(i, -100, 0), pcl::PointXYZ(i, 100, 0), QString("GridlineY%1").arg(i).toStdString(), 0);
            viewer->addLine(pcl::PointXYZ(-100, i, 0), pcl::PointXYZ(100, i, 0), QString("GridlineX%1").arg(i).toStdString(), 0);
            if(i > 0)
                viewer->addText3D(QString::number(i).append("m").toStdString(), pcl::PointXYZ(0, i, 0), 0.8, 0.5, 0.5, 0.5, QString("GridText%1").arg(i).toStdString(), 0);
            viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, 0.1, QString("GridlineY%1").arg(i).toStdString(), 0);
            viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH, 0.1, QString("GridlineX%1").arg(i).toStdString(), 0);
        }
            
        //画圆环
        QVector<pcl::PointXYZ> points;
        for (int j = 1; j <= 10; j++) {
            int r = 10 * j;
           
            vtkSmartPointer<vtkRegularPolygonSource>   source = vtkSmartPointer<vtkRegularPolygonSource>::New();
            vtkSmartPointer<vtkPolyDataMapper>         mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
            vtkSmartPointer<vtkActor>                  actor = vtkSmartPointer<vtkActor>::New();

            source->SetNumberOfSides(70);    //多边形边数
            source->SetRadius(r);            //半径
            source->SetCenter(0, 0, 0);      //圆心     
            mapper->SetInputConnection(source->GetOutputPort());            
            actor->SetMapper(mapper);
            actor->GetProperty()->SetColor(0.5, 0.5, 0.5);    //颜色
            actor->GetProperty()->SetOpacity(1);    //透明度
            actor->GetProperty()->SetRepresentationToWireframe();//图形不填充,只要边框

            ui.qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor);
        }        
    }
    else    //删除圆环及网格
    {
        //删除网格图形
        viewer->removeAllShapes();

        //删除圆环
        vtkActorCollection* actorCollection = ui.qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActors();
        int num = actorCollection->GetNumberOfItems();
        actorCollection->InitTraversal();
        for (int i = 0; i < num; ++i)
        {
            vtkActor* actor = actorCollection->GetNextActor();
            ui.qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->RemoveActor(actor);
        }
    }
    ui.qvtkWidget->update();
}

画网格是利用viewer直接画的线,画圆是利用vtk画的多边形,他们本不关联,但要显示在一个图里,就需要画在同一个renderer里,关键代码:

ui.qvtkWidget->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddActor(actor);

因为在初始化viewer时,我们都添加了这几行代码:

ui.qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
viewer->setupInteractor(ui.qvtkWidget->GetInteractor(), ui.qvtkWidget->GetRenderWindow());
ui.qvtkWidget->update();

四、最终效果

1.只保留圆环边框效果

actor->GetProperty()->SetColor(0.5, 0.5, 0.5);
actor->GetProperty()->SetOpacity(1);
actor->GetProperty()->SetRepresentationToWireframe();

2.圆环填充效果

actor->GetProperty()->SetColor(0.5, 0.5, 0.7);
actor->GetProperty()->SetOpacity(0.1);
//actor->GetProperty()->SetRepresentationToWireframe();

 五、总结

说实话,代码不多,也很简单,但是我找了很多资料也没找到,一直想要这个效果,已经很久了,去年就想画这个,但是没找到合适的资料。慢慢积累吧,我获取知识的途径还是太少了。今天分享给大家,希望对大家有所帮助,程序员何苦为难程序员。

六、参考文章

VTK笔记-图形相关-绘制凹多边形-多边形三角网格化-vtkTriangleFilter类

VTK 遍历render中的actor

  • 14
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

源客V

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值