// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-FileCopyrightText: Copyright (c) Kitware, Inc. // SPDX-License-Identifier: BSD-3-Clause #include "vtkTableToPolyData.h" #include "vtkCellArray.h" #include "vtkDoubleArray.h" #include "vtkInformation.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkPoints.h" #include "vtkPolyData.h" #include "vtkTable.h" VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkTableToPolyData); //------------------------------------------------------------------------------ vtkTableToPolyData::vtkTableToPolyData() { this->XColumn = nullptr; this->YColumn = nullptr; this->ZColumn = nullptr; this->XColumnIndex = -1; this->YColumnIndex = -1; this->ZColumnIndex = -1; this->XComponent = 0; this->YComponent = 0; this->ZComponent = 0; this->Create2DPoints = false; this->PreserveCoordinateColumnsAsDataArrays = false; } //------------------------------------------------------------------------------ vtkTableToPolyData::~vtkTableToPolyData() { this->SetXColumn(nullptr); this->SetYColumn(nullptr); this->SetZColumn(nullptr); } //------------------------------------------------------------------------------ int vtkTableToPolyData::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info) { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable"); return 1; } //------------------------------------------------------------------------------ int vtkTableToPolyData::RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector) { vtkTable* input = vtkTable::GetData(inputVector[0], 0); vtkPolyData* output = vtkPolyData::GetData(outputVector, 0); if (input->GetNumberOfRows() == 0) { // empty input. return 1; } vtkDataArray* xarray = nullptr; vtkDataArray* yarray = nullptr; vtkDataArray* zarray = nullptr; if (this->XColumn && this->YColumn) { xarray = vtkArrayDownCast(input->GetColumnByName(this->XColumn)); yarray = vtkArrayDownCast(input->GetColumnByName(this->YColumn)); zarray = vtkArrayDownCast(input->GetColumnByName(this->ZColumn)); } else if (this->XColumnIndex >= 0) { xarray = vtkArrayDownCast(input->GetColumn(this->XColumnIndex)); yarray = vtkArrayDownCast(input->GetColumn(this->YColumnIndex)); zarray = vtkArrayDownCast(input->GetColumn(this->ZColumnIndex)); } // zarray is optional if (this->Create2DPoints) { if (!xarray || !yarray) { vtkErrorMacro("Failed to locate the columns to use for the point" " coordinates"); return 0; } } else { if (!xarray || !yarray || !zarray) { vtkErrorMacro("Failed to locate the columns to use for the point" " coordinates"); return 0; } } vtkPoints* newPoints = vtkPoints::New(); if (xarray == yarray && yarray == zarray && this->XComponent == 0 && this->YComponent == 1 && this->ZComponent == 2 && xarray->GetNumberOfComponents() == 3) { newPoints->SetData(xarray); } else { // Ideally we determine the smallest data type that can contain the values // in all the 3 arrays. For now I am just going with doubles. vtkDoubleArray* newData = vtkDoubleArray::New(); newData->SetNumberOfComponents(3); newData->SetNumberOfTuples(input->GetNumberOfRows()); vtkIdType numtuples = newData->GetNumberOfTuples(); if (this->Create2DPoints) { for (vtkIdType cc = 0; cc < numtuples; cc++) { newData->SetComponent(cc, 0, xarray->GetComponent(cc, this->XComponent)); newData->SetComponent(cc, 1, yarray->GetComponent(cc, this->YComponent)); newData->SetComponent(cc, 2, 0.0); } } else { for (vtkIdType cc = 0; cc < numtuples; cc++) { newData->SetComponent(cc, 0, xarray->GetComponent(cc, this->XComponent)); newData->SetComponent(cc, 1, yarray->GetComponent(cc, this->YComponent)); newData->SetComponent(cc, 2, zarray->GetComponent(cc, this->ZComponent)); } } newPoints->SetData(newData); newData->Delete(); } output->SetPoints(newPoints); newPoints->Delete(); // Now create a poly-vertex cell will all the points. vtkIdType numPts = newPoints->GetNumberOfPoints(); vtkIdType* ptIds = new vtkIdType[numPts]; for (vtkIdType cc = 0; cc < numPts; cc++) { ptIds[cc] = cc; } output->AllocateEstimate(1, 1); output->InsertNextCell(VTK_POLY_VERTEX, numPts, ptIds); delete[] ptIds; // Add all other columns as point data. for (int cc = 0; cc < input->GetNumberOfColumns(); cc++) { if (this->CheckAbort()) { break; } vtkAbstractArray* arr = input->GetColumn(cc); if (this->PreserveCoordinateColumnsAsDataArrays) { output->GetPointData()->AddArray(arr); } else if (arr != xarray && arr != yarray && arr != zarray) { output->GetPointData()->AddArray(arr); } } return 1; } //------------------------------------------------------------------------------ void vtkTableToPolyData::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "XColumn: " << (this->XColumn ? this->XColumn : "(none)") << endl; os << indent << "XComponent: " << this->XComponent << endl; os << indent << "XColumnIndex: " << this->XColumnIndex << endl; os << indent << "YColumn: " << (this->YColumn ? this->YColumn : "(none)") << endl; os << indent << "YComponent: " << this->YComponent << endl; os << indent << "YColumnIndex: " << this->YColumnIndex << endl; os << indent << "ZColumn: " << (this->ZColumn ? this->ZColumn : "(none)") << endl; os << indent << "ZComponent: " << this->ZComponent << endl; os << indent << "ZColumnIndex: " << this->ZColumnIndex << endl; os << indent << "Create2DPoints: " << (this->Create2DPoints ? "true" : "false") << endl; os << indent << "PreserveCoordinateColumnsAsDataArrays: " << (this->PreserveCoordinateColumnsAsDataArrays ? "true" : "false") << endl; } VTK_ABI_NAMESPACE_END