pfe/src/surface_points_filter.cc

85 lines
2.6 KiB
C++

#include "surface_points_filter.h"
#include <vtkIdList.h>
#include <vtkUnstructuredGrid.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkIdTypeArray.h>
#include <vtkCellIterator.h>
#include <vtkTriangle.h>
#include <vtkStaticCellLinks.h>
#include <vtkIntArray.h>
#include <set>
vtkStandardNewMacro(SurfacePointsFilter);
vtkTypeBool SurfacePointsFilter::RequestData(
vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector) {
(void) request;
vtkUnstructuredGrid* input =
vtkUnstructuredGrid::GetData(inputVector[0]);
vtkUnstructuredGrid* output =
vtkUnstructuredGrid::GetData(outputVector);
/* Copy point and cell data unmodified. */
output->CopyStructure(input);
output->GetPointData()->PassData(input->GetPointData());
output->GetCellData()->PassData(input->GetCellData());
/* Create an array to store the IDs of surface points. */
vtkNew<vtkIdTypeArray> surfacePoints;
surfacePoints->SetName("surfacePoints");
surfacePoints->SetNumberOfComponents(1);
vtkNew<vtkIntArray> isSurface;
isSurface->SetName("isSurface");
isSurface->SetNumberOfComponents(1);
isSurface->SetNumberOfTuples(input->GetNumberOfPoints());
isSurface->FillValue(0);
/* Generate cell links, these tell us which cell a point belongs to. */
vtkNew<vtkStaticCellLinks> links;
links->BuildLinks(input);
vtkNew<vtkIdList> neighborCells;
vtkNew<vtkIdList> facePoints;
std::set<vtkIdType> surfacePointsSet;
auto *it = input->NewCellIterator();
for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextCell()) {
vtkIdList *cellPointIds = it->GetPointIds();
for (vtkIdType faceId = 0; faceId < 4; faceId++) {
vtkIdType idA = cellPointIds->GetId((faceId + 0) % 4);
vtkIdType idB = cellPointIds->GetId((faceId + 1) % 4);
vtkIdType idC = cellPointIds->GetId((faceId + 2) % 4);
facePoints->InsertNextId(idA);
facePoints->InsertNextId(idB);
facePoints->InsertNextId(idC);
input->GetCellNeighbors(it->GetCellId(), facePoints,
neighborCells);
facePoints->Reset();
if (neighborCells->GetNumberOfIds() == 0) {
surfacePointsSet.insert(idA);
surfacePointsSet.insert(idB);
surfacePointsSet.insert(idC);
isSurface->SetValue(idA, 1);
isSurface->SetValue(idB, 1);
isSurface->SetValue(idC, 1);
}
}
}
it->Delete();
surfacePoints->Allocate(surfacePointsSet.size());
for (const vtkIdType &id : surfacePointsSet) {
surfacePoints->InsertNextValue(id);
}
output->GetPointData()->SetScalars(isSurface);
output->GetFieldData()->AddArray(surfacePoints);
return true;
}