/*========================================================================= Program: Visualization Toolkit Module: vtkTableToSparseArray.cxx ------------------------------------------------------------------------- Copyright 2008 Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. ------------------------------------------------------------------------- Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkTableToSparseArray.h" #include "vtkArrayData.h" #include "vtkDoubleArray.h" #include "vtkIdTypeArray.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkLongLongArray.h" #include "vtkObjectFactory.h" #include "vtkSmartPointer.h" #include "vtkSparseArray.h" #include "vtkStdString.h" #include "vtkStringArray.h" #include "vtkTable.h" #include class vtkTableToSparseArray::implementation { public: std::vector Coordinates; vtkStdString Values; vtkArrayExtents OutputExtents; bool ExplicitOutputExtents; }; //------------------------------------------------------------------------------ vtkStandardNewMacro(vtkTableToSparseArray); //------------------------------------------------------------------------------ vtkTableToSparseArray::vtkTableToSparseArray() : Implementation(new implementation()) { this->Implementation->ExplicitOutputExtents = false; this->SetNumberOfInputPorts(1); this->SetNumberOfOutputPorts(1); } //------------------------------------------------------------------------------ vtkTableToSparseArray::~vtkTableToSparseArray() { delete this->Implementation; } //------------------------------------------------------------------------------ void vtkTableToSparseArray::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); for (size_t i = 0; i != this->Implementation->Coordinates.size(); ++i) os << indent << "CoordinateColumn: " << this->Implementation->Coordinates[i] << endl; os << indent << "ValueColumn: " << this->Implementation->Values << endl; os << indent << "OutputExtents: "; if (this->Implementation->ExplicitOutputExtents) os << this->Implementation->OutputExtents << endl; else os << "" << endl; } void vtkTableToSparseArray::ClearCoordinateColumns() { this->Implementation->Coordinates.clear(); this->Modified(); } void vtkTableToSparseArray::AddCoordinateColumn(const char* name) { if (!name) { vtkErrorMacro(<< "cannot add coordinate column with nullptr name"); return; } this->Implementation->Coordinates.emplace_back(name); this->Modified(); } void vtkTableToSparseArray::SetValueColumn(const char* name) { if (!name) { vtkErrorMacro(<< "cannot set value column with nullptr name"); return; } this->Implementation->Values = name; this->Modified(); } const char* vtkTableToSparseArray::GetValueColumn() { return this->Implementation->Values.c_str(); } void vtkTableToSparseArray::ClearOutputExtents() { this->Implementation->ExplicitOutputExtents = false; this->Modified(); } void vtkTableToSparseArray::SetOutputExtents(const vtkArrayExtents& extents) { this->Implementation->ExplicitOutputExtents = true; this->Implementation->OutputExtents = extents; this->Modified(); } int vtkTableToSparseArray::FillInputPortInformation(int port, vtkInformation* info) { switch (port) { case 0: info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable"); return 1; } return 0; } //------------------------------------------------------------------------------ int vtkTableToSparseArray::RequestData( vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector* outputVector) { vtkTable* const table = vtkTable::GetData(inputVector[0]); std::vector coordinates(this->Implementation->Coordinates.size()); for (size_t i = 0; i != this->Implementation->Coordinates.size(); ++i) { coordinates[i] = table->GetColumnByName(this->Implementation->Coordinates[i].c_str()); if (!coordinates[i]) { vtkErrorMacro(<< "missing coordinate array: " << this->Implementation->Coordinates[i].c_str()); } } // See http://developers.sun.com/solaris/articles/cmp_stlport_libCstd.html // Language Feature: Partial Specializations // Workaround int n = 0; #ifdef _RWSTD_NO_CLASS_PARTIAL_SPEC std::count(coordinates.begin(), coordinates.end(), static_cast(0), n); #else n = std::count(coordinates.begin(), coordinates.end(), static_cast(nullptr)); #endif if (n != 0) { return 0; } vtkAbstractArray* const values = table->GetColumnByName(this->Implementation->Values.c_str()); if (!values) { vtkErrorMacro(<< "missing value array: " << this->Implementation->Values.c_str()); return 0; } vtkSparseArray* const array = vtkSparseArray::New(); array->Resize( vtkArrayExtents::Uniform(static_cast(coordinates.size()), 0)); for (size_t i = 0; i != coordinates.size(); ++i) { array->SetDimensionLabel(static_cast(i), coordinates[i]->GetName()); } vtkArrayCoordinates output_coordinates; output_coordinates.SetDimensions( static_cast(coordinates.size())); for (vtkIdType i = 0; i != table->GetNumberOfRows(); ++i) { for (size_t j = 0; j != coordinates.size(); ++j) { output_coordinates[static_cast(j)] = coordinates[j]->GetVariantValue(i).ToInt(); } array->AddValue(output_coordinates, values->GetVariantValue(i).ToDouble()); } if (this->Implementation->ExplicitOutputExtents) { array->SetExtents(this->Implementation->OutputExtents); } else { array->SetExtentsFromContents(); } vtkArrayData* const output = vtkArrayData::GetData(outputVector); output->ClearArrays(); output->AddArray(array); array->Delete(); return 1; }