需求:导入多个stl模型 ,并提供已知点,将点会知道模型上的对应位置
注意:
1,因为VTK中的点 在场景中是一个正方形,无法特和到模型表面,所以不能直接使用vtkPoint绘制,这里采用vtkRegularPolygonSource 这个类,并将点的法向量设置给他,这样就是一个比较贴合的点了。
2.由于模型是多个stl拼接成的,所以在计算之前先将模型拼接一个polydata这样速度可以提升很多。
3,因为 向量 可能不在一个方向因此绘制出来的点 可能看不见,因此需要 使用vtkLinearExtrusionFilter 进行两次计算。
//合并polydata
vtkAppendPolyData *apd = vtkAppendPolyData::New();
for(const auto &iter:areaActorMap){
vtkSmartPointer<vtkPolyData> stlPolyData = vtkPolyData::SafeDownCast(iter.second->GetMapper()->GetInputAsDataSet());
apd->AddInputData(stlPolyData);//读入合并polydata
}
apd->Update();
//求向量
vtkSmartPointer<vtkPolyDataNormals> normals = vtkSmartPointer<vtkPolyDataNormals>::New();
normals->SetInputData(apd->GetOutput());
normals->Update();
vtkDataArray* normalsArray = normals->GetOutput()->GetCellData()->GetNormals();
//定位到最近的点
vtkSmartPointer<vtkCellLocator> locator = vtkSmartPointer<vtkCellLocator>::New();
locator->SetDataSet(apd->GetOutput());
locator->BuildLocator();
auto assistCell = vtkSmartPointer<vtkGenericCell>::New();
for(int i=0;i<pointList.point_count;i++){
Point point = pointList.poins[i];
double testInside[3] = {point.x , point.y,point.z};
double closestPoint[3];//返回最近点的坐标
double closestPointDist2;//返回到最近点的平方距离
vtkIdType cellId; //返回最近点的cell id
int subId;
locator->FindClosestPoint(testInside, closestPoint, assistCell, cellId, subId, closestPointDist2);
if(closestPointDist2<1.5){
//计算法向量
double* normal = normalsArray->GetTuple(cellId);
vtkSmartPointer<vtkRegularPolygonSource> polySource = vtkSmartPointer<vtkRegularPolygonSource>::New();
polySource->SetNumberOfSides(10);
polySource->SetRadius(pointSize);
polySource->SetCenter(testInside);
polySource->SetNormal(normal);
// std::cout<<"noraml "<<normal[0]<<" "<<normal[1]<<" "<<normal[2]<<std::endl;
vtkSmartPointer<vtkLinearExtrusionFilter> extrusionFilter = vtkSmartPointer<vtkLinearExtrusionFilter>::New();
extrusionFilter->SetInputConnection(polySource->GetOutputPort());
extrusionFilter->SetExtrusionTypeToNormalExtrusion();
extrusionFilter->SetVector(-normal[0],-normal[1],-normal[2]); // Extrude along z-axis
extrusionFilter->SetScaleFactor(1); // Extrusion factor
vtkSmartPointer<vtkLinearExtrusionFilter> extrusionFilter2 = vtkSmartPointer<vtkLinearExtrusionFilter>::New();
extrusionFilter2->SetInputConnection(extrusionFilter->GetOutputPort());
extrusionFilter2->SetExtrusionTypeToNormalExtrusion();
extrusionFilter2->SetVector(normal[0],normal[1],normal[2]); // Extrude along z-axis
extrusionFilter2->SetScaleFactor(1); // Extrusion factor
vtkSmartPointer<vtkPolyDataMapper> planeMapper =vtkSmartPointer<vtkPolyDataMapper>::New();
planeMapper->SetInputConnection(extrusionFilter2->GetOutputPort());
vtkSmartPointer<vtkActor> planeActor = vtkSmartPointer<vtkActor>::New();
planeActor->SetMapper(planeMapper);
planeActor->GetProperty()->SetColor(pointColor.r/255.0,pointColor.g/255.0,pointColor.b/255.0);
Renderer->AddActor(planeActor);
pointsMap.emplace(planeActor,point);
}
}
100个点 大概1.48s