// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-FileCopyrightText: Copyright (c) Kitware, Inc. // SPDX-License-Identifier: BSD-3-Clause #include "vtkCleanUnstructuredGridCells.h" #include "vtkCell.h" #include "vtkCellData.h" #include "vtkCollection.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkIntArray.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkPoints.h" #include "vtkUnstructuredGrid.h" #include vtkStandardNewMacro(vtkCleanUnstructuredGridCells); //---------------------------------------------------------------------------- vtkCleanUnstructuredGridCells::vtkCleanUnstructuredGridCells() = default; //---------------------------------------------------------------------------- vtkCleanUnstructuredGridCells::~vtkCleanUnstructuredGridCells() = default; //---------------------------------------------------------------------------- void vtkCleanUnstructuredGridCells::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); } //---------------------------------------------------------------------------- int vtkCleanUnstructuredGridCells::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector) { vtkInformation* inInfo = inputVector[0]->GetInformationObject(0); vtkInformation* outInfo = outputVector->GetInformationObject(0); vtkUnstructuredGrid* input = vtkUnstructuredGrid::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT())); vtkUnstructuredGrid* output = vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); if (input->GetNumberOfCells() == 0) { // set up a ugrid with same data arrays as input, but // no points, cells or data. output->Allocate(1); output->GetPointData()->CopyAllocate(input->GetPointData(), VTK_CELL_SIZE); vtkPoints* pts = vtkPoints::New(); pts->SetDataTypeToDouble(); output->SetPoints(pts); pts->Delete(); return 1; } // Copy over the original points. Assume there are no degenerate points. output->SetPoints(input->GetPoints()); output->GetPointData()->ShallowCopy(input->GetPointData()); vtkCellData* outCD = output->GetCellData(); outCD->CopyGlobalIdsOn(); outCD->CopyAllocate(input->GetCellData()); // remove duplicate cells std::set> cellSet; std::set>::iterator cellIter; // Now copy the cells. vtkNew cellPoints; const vtkIdType numberOfCells = input->GetNumberOfCells(); vtkIdType progressStep = numberOfCells / 100; if (progressStep == 0) { progressStep = 1; } output->Allocate(numberOfCells); int ndeg = 0; int ndup = 0; for (vtkIdType id = 0; id < numberOfCells; id++) { if (id % progressStep == 0) { this->UpdateProgress(0.8 + 0.2 * (static_cast(id) / numberOfCells)); } // duplicate points do not make poly vertices or triangle // strips degenerate so don't remove them int cellType = input->GetCellType(id); if (cellType == VTK_POLY_VERTEX || cellType == VTK_TRIANGLE_STRIP) { input->GetCellPoints(id, cellPoints); vtkIdType newCellId = output->InsertNextCell(cellType, cellPoints); outCD->CopyData(input->GetCellData(), id, newCellId); continue; } input->GetCellPoints(id, cellPoints); std::set nn; for (int i = 0; i < cellPoints->GetNumberOfIds(); i++) { int cellPtId = cellPoints->GetId(i); nn.insert(cellPtId); } // this conditional may generate non-referenced nodes cellIter = cellSet.find(nn); // only copy a cell to the output if it is neither degenerate nor duplicate if (nn.size() == static_cast(cellPoints->GetNumberOfIds()) && cellIter == cellSet.end()) { vtkIdType newCellId = output->InsertNextCell(input->GetCellType(id), cellPoints); outCD->CopyData(input->GetCellData(), id, newCellId); cellSet.insert(nn); } else if (nn.size() != static_cast(cellPoints->GetNumberOfIds())) { ndeg++; // a node appeared more than once in a cell } else if (cellIter != cellSet.end()) { ndup++; // cell has duplicate(s) } } if (ndeg) { vtkDebugMacro(<< "vtkCleanUnstructuredGridCells : WARNING, " << ndeg << " degenerated cells (i.e. cells with coincident nodes) have been" << " removed, which may result in disconnected nodes. It is" << " recommended to clean the grid." << endl); } if (ndup) { vtkDebugMacro(<< "vtkCleanUnstructuredGridCells : " << ndup << " duplicate cells (multiple instances of a cell) have been" << " removed." << endl); output->Squeeze(); } return 1; } int vtkCleanUnstructuredGridCells::FillInputPortInformation( int vtkNotUsed(port), vtkInformation* info) { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkUnstructuredGrid"); return 1; }