环境为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();
}