QT+VTK+PCL实现交互式点云平面切割
2017-03-17 09:24
1996 查看
PCL及QT配置请移步点击打开链接
前言
恭喜你已经入了qt和pcl的坑,这篇文章帮助你实现在qvtkWidget中点云平面切割以及保存切割数据。
前提是你已经能成功读取pcd文件,并且将qvtkWidget配置好(代码中省略读取pcd部分)
先放效果图,如果是你想要的就继续读下去。
ps:初学,so只是将功能实现而已,若代码风格以及完成功能方法不尽如人意请尽管提出建议~么么哒
class vtkIPWCallback : public vtkCommand
{
public:
static vtkIPWCallback *New()
{
return new vtkIPWCallback;
}
virtual void Execute(vtkObject *caller, unsigned long, void*)
{
vtkImplicitPlaneWidget2 *planeWidget =
reinterpret_cast<vtkImplicitPlaneWidget2*>(caller);
vtkImplicitPlaneRepresentation *rep =
reinterpret_cast<vtkImplicitPlaneRepresentation*>(planeWidget->GetRepresentation());
rep->GetPlane(this->Plane);
}
vtkIPWCallback() :Plane(0), Actor(0) {}
vtkPlane *Plane;
vtkActor *Actor;
};
//!!!!!!!!!!!!!!!!!!!!超重要的两句,设置viewer的(试了很久才出来的)
ui.qvtkWidget->SetRenderWindow(renderWindow);
viewer->setupInteractor(renderWindowInteractor, renderWindow);
void initial()
{
//添加cloud和viewer
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
//初始化
cloud.reset(new pcl::PointCloud<pcl::PointXYZ>);
viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
viewer->addPointCloud(cloud, "cloud");
//初始化vtk
ui.qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
viewer->setupInteractor(ui.qvtkWidget->GetInteractor(), ui.qvtkWidget->GetRenderWindow());
viewer->setCameraPosition(0, 0, -2, 0, -1, 0, 0);
ui.qvtkWidget->update();
}
pcl::PolygonMesh mesh;
vtkSmartPointer<vtkPolyData> poly = vtkSmartPointer<vtkPolyData>::New();
pcl::io::loadPolygonFilePLY("temp/mesh.ply", mesh);
pcl::io::mesh2vtk(mesh, poly);
pcl::io::vtkPolyDataToPointCloud(poly, *cloud);
viewer->updatePointCloud(cloud, "cloud");
ui.qvtkWidget->update();
//更新上一步剪切的数据为新的input
glyphFilter->SetInputData(poly);
glyphFilter->Update();return EXIT_SUCCESS;}
前言
恭喜你已经入了qt和pcl的坑,这篇文章帮助你实现在qvtkWidget中点云平面切割以及保存切割数据。
前提是你已经能成功读取pcd文件,并且将qvtkWidget配置好(代码中省略读取pcd部分)
先放效果图,如果是你想要的就继续读下去。
ps:初学,so只是将功能实现而已,若代码风格以及完成功能方法不尽如人意请尽管提出建议~么么哒
class vtkIPWCallback : public vtkCommand
{
public:
static vtkIPWCallback *New()
{
return new vtkIPWCallback;
}
virtual void Execute(vtkObject *caller, unsigned long, void*)
{
vtkImplicitPlaneWidget2 *planeWidget =
reinterpret_cast<vtkImplicitPlaneWidget2*>(caller);
vtkImplicitPlaneRepresentation *rep =
reinterpret_cast<vtkImplicitPlaneRepresentation*>(planeWidget->GetRepresentation());
rep->GetPlane(this->Plane);
}
vtkIPWCallback() :Plane(0), Actor(0) {}
vtkPlane *Plane;
vtkActor *Actor;
};
//!!!!!!!!!!!!!!!!!!!!超重要的两句,设置viewer的(试了很久才出来的)
ui.qvtkWidget->SetRenderWindow(renderWindow);
viewer->setupInteractor(renderWindowInteractor, renderWindow);
void initial()
{
//添加cloud和viewer
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
//初始化
cloud.reset(new pcl::PointCloud<pcl::PointXYZ>);
viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
viewer->addPointCloud(cloud, "cloud");
//初始化vtk
ui.qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
viewer->setupInteractor(ui.qvtkWidget->GetInteractor(), ui.qvtkWidget->GetRenderWindow());
viewer->setCameraPosition(0, 0, -2, 0, -1, 0, 0);
ui.qvtkWidget->update();
}
int planeCut() { //input data points = vtkSmartPointer<vtkPoints>::New();//添加点集 sourcePolyData = vtkSmartPointer<vtkPolyData>::New();//添加数据 glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New();//过滤器 plane = vtkSmartPointer<vtkPlane>::New();//切割平面 clipper = vtkSmartPointer<vtkClipPolyData>::New();// mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); //映射器,可以根据点、线、面构造图形 actor = vtkSmartPointer<vtkActor>::New();// backFaces = vtkSmartPointer<vtkProperty>::New(); renderer = vtkSmartPointer<vtkRenderer>::New();//绘制器,能够绘制物体 renderWindow = vtkSmartPointer<vtkRenderWindow>::New();//绘制窗,提供绘制的平面 renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();//交互器 //!!!!!!!!!!!!!!!!!!!!超重要的两句,设置viewer的 ui.qvtkWidget->SetRenderWindow(renderWindow); viewer->setupInteractor(renderWindowInteractor, renderWindow); //点云数据输入 for (size_t i = 0; i < cloud->points.size(); i++) { points->InsertNextPoint(cloud->points[i].x, cloud->points[i].y, cloud->points[i].z); } sourcePolyData->SetPoints(points); #if VTK_MAJOR_VERSION <= 5 glyphFilter->SetInputConnection(polyData->GetProducerPort()); #else glyphFilter->SetInputData(sourcePolyData); //完成点的传递 #endif glyphFilter->Update(); //裁剪设置 clipper->SetClipFunction(plane); clipper->InsideOutOn(); clipper->SetInputConnection(glyphFilter->GetOutputPort()); clipper->Update(); // 映射和动作 mapper->SetInputConnection(clipper->GetOutputPort()); actor->SetMapper(mapper); backFaces->SetDiffuseColor(0.8275, 0.8275, 0.8275); actor->SetBackfaceProperty(backFaces); // 绘制窗口 renderWindow->AddRenderer(renderer); renderer->AddActor(actor); //交互器 renderWindowInteractor->SetRenderWindow(renderWindow); renderWindow->Render(); // 回调 vtkSmartPointer<vtkIPWCallback> myCallback = vtkSmartPointer<vtkIPWCallback>::New(); myCallback->Plane = plane; myCallback->Actor = actor; //提前于planewidget设置 vtkSmartPointer<vtkImplicitPlaneRepresentation> rep = vtkSmartPointer<vtkImplicitPlaneRepresentation>::New(); rep->SetPlaceFactor(1.25); rep->PlaceWidget(actor->GetBounds()); rep->SetNormal(plane->GetNormal()); rep->SetOrigin(0, 0, 0); vtkSmartPointer<vtkImplicitPlaneWidget2> planeWidget = vtkSmartPointer<vtkImplicitPlaneWidget2>::New(); planeWidget->SetInteractor(renderWindowInteractor); planeWidget->SetRepresentation(rep); planeWidget->AddObserver(vtkCommand::InteractionEvent, myCallback); //对观察到的事件响应 // 绘制 renderWindowInteractor->Initialize(); renderWindow->Render(); planeWidget->On(); // 鼠标交互 renderWindowInteractor->Start(); //过滤被裁剪部分 //////////////////////////////////////// vtkSmartPointer<vtkIdFilter> cellIdFilter = vtkSmartPointer<vtkIdFilter>::New(); cellIdFilter->SetInputConnection(clipper->GetOutputPort()); cellIdFilter->SetCellIds(true); cellIdFilter->SetPointIds(false); cellIdFilter->SetIdsArrayName("CellIds"); cellIdFilter->Update(); //将过滤部分保存ply ////////////////////////////////////////////////////////////////// vtkSmartPointer<vtkPLYWriter> writer = vtkSmartPointer<vtkPLYWriter>::New(); std::string filename = "temp/mesh.ply"; #if VTK_MAJOR_VERSION <= 5 writer->SetInput(dataSet); #else writer->SetInputData(cellIdFilter->GetOutput()); #endif writer->SetFileName(filename.c_str()); writer->Write();
//格式转换,先将ply转为vtk,再转vtk为pcd
pcl::PolygonMesh mesh;
vtkSmartPointer<vtkPolyData> poly = vtkSmartPointer<vtkPolyData>::New();
pcl::io::loadPolygonFilePLY("temp/mesh.ply", mesh);
pcl::io::mesh2vtk(mesh, poly);
pcl::io::vtkPolyDataToPointCloud(poly, *cloud);
viewer->updatePointCloud(cloud, "cloud");
ui.qvtkWidget->update();
//更新上一步剪切的数据为新的input
glyphFilter->SetInputData(poly);
glyphFilter->Update();return EXIT_SUCCESS;}
相关文章推荐
- 使用VS2013_X68;PCL1.7.2;QT5;VTK6.2实现qt显示PCL
- VS2008、QT及VTK实现DICOM图像三维重建之二:VS2008下VTK的安装使用
- VTK实现面模型切割
- 基于qt,opencv交互式的graphcuts算法的实现
- PCL初探(零) :opencv3.4.0 + qt5.9.1+ pcl1.8.1 + vtk7.1.1的安装
- VTK实现面模型切割
- Qt 与 VTK 在实现 3D 效果上的优劣
- 用vtk+Qt实现离散数据的体绘制
- vtkPlaneWidget 实现实时切割
- 【vtk实例】平面切割
- 模拟物体(汽车)任意方向和速度移动平面动画__(使用Qt 实现)
- KinectV2 qt pcl 实现点云显示
- QT实现图片按钮(用qss切割图片,或者放三张图片)
- VS2008、QT及VTK实现DICOM图像三维重建之三:Win32工程配置
- 基于VTK的任意平面切割
- VTK:基于Qt的VTK右击菜单实现
- VS2015 + PCL1.8.0 + QT_5.62 + cmake3.82 编译VTK7.1,生成QVTKWidgetPlugin.dll
- 在PCL中如何实现平面模型分割
- vtk实现三点确定一个平面
- 基于VTK的任意平面切割