#include "point_tris_dist.h" #include "project_surface_points_on_poly.h" #include #include #include #include #include #include #include #include #include #include #include vtkStandardNewMacro(ProjectSurfacePointsOnPoly); ProjectSurfacePointsOnPoly::ProjectSurfacePointsOnPoly() { SetNumberOfInputPorts(2); } int ProjectSurfacePointsOnPoly::FillInputPortInformation(int port, vtkInformation *info) { if (port == 0) { vtkUnstructuredGridAlgorithm::FillInputPortInformation(port, info); } else if (port == 1) { vtkNew input2; input2->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData"); info->Append(input2); } return 1; } vtkTypeBool ProjectSurfacePointsOnPoly::RequestData( vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) { (void) request; vtkUnstructuredGrid* us = vtkUnstructuredGrid::GetData(inputVector[0]); vtkPolyData* pd = vtkPolyData::GetData(inputVector[1]); vtkUnstructuredGrid* output = vtkUnstructuredGrid::GetData(outputVector); output->CopyStructure(us); output->GetPointData()->PassData(us->GetPointData()); output->GetCellData()->PassData(us->GetCellData()); /* Generate cell links, these tell us which cell a point belongs to. */ vtkNew links; links->BuildLinks(pd); vtkNew kdTree; kdTree->BuildLocatorFromPoints(pd->GetPoints()); vtkIdTypeArray *externalPoints = vtkIdTypeArray::SafeDownCast(us->GetFieldData()->GetArray("external_points")); for (vtkIdType i = 0; i < externalPoints->GetNumberOfTuples(); i++) { double p[3]; us->GetPoint(externalPoints->GetTuple1(i), p); double dist2; vtkIdType closest = kdTree->FindClosestPoint(p, dist2); vtkIdType *cellIds = links->GetCells(closest); vtkIdType nCells = links->GetNcells(closest); double min_dist = std::numeric_limits::infinity(); double min_direction[3]; /* For each tri the closest point belongs to. */ for (vtkIdType j = 0; j < nCells; j++) { vtkIdType cellId = cellIds[j]; double direction[3]; double dist = pointTriangleDistance(p, pd->GetCell(cellId), direction); /* Find the closest one. */ if (dist < min_dist) { min_dist = dist; min_direction[0] = direction[0]; min_direction[1] = direction[1]; min_direction[2] = direction[2]; } } vtkMath::MultiplyScalar(min_direction, min_dist); vtkMath::Subtract(p, min_direction, p); us->GetPoints()->SetPoint(externalPoints->GetTuple1(i), p); us->Modified(); } return true; }