/*========================================================================= Program: Visualization Toolkit Module: TestTable.cxx 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. =========================================================================*/ /*------------------------------------------------------------------------- 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. -------------------------------------------------------------------------*/ #include "vtkDoubleArray.h" #include "vtkIntArray.h" #include "vtkMath.h" #include "vtkStringArray.h" #include "vtkTable.h" #include "vtkVariantArray.h" #include #include using namespace std; void CheckEqual(vtkTable* table, vector > & stdTable) { // Check sizes if (table->GetNumberOfRows() != static_cast(stdTable[0].size())) { cout << "Number of rows is incorrect (" << table->GetNumberOfRows() << " != " << stdTable.size() << ")" << endl; exit(1); } if (table->GetNumberOfColumns() != static_cast(stdTable.size())) { cout << "Number of columns is incorrect (" << table->GetNumberOfColumns() << " != " << stdTable.size() << ")" << endl; exit(1); } // Use GetValue() and GetValueByName() to check for (int i = 0; i < table->GetNumberOfRows(); i++) { for (int j = 0; j < table->GetNumberOfColumns(); j++) { double tableVal = table->GetValue(i, j).ToDouble(); double stdTableVal = stdTable[j][i]; if (stdTableVal && tableVal != stdTableVal) { cout << "Values not equal at row " << i << " column " << j << ": "; cout << "(" << tableVal << " != " << stdTableVal << ")" << endl; exit(1); } } } // Use GetColumn() and GetColumnByName() to check for (int j = 0; j < table->GetNumberOfColumns(); j++) { vtkAbstractArray* arr; if (vtkMath::Random() < 0.5) { arr = table->GetColumn(j); } else { arr = table->GetColumnByName(table->GetColumnName(j)); } for (int i = 0; i < table->GetNumberOfRows(); i++) { double val; if (arr->IsA("vtkVariantArray")) { val = vtkArrayDownCast(arr)->GetValue(i).ToDouble(); } else if (arr->IsA("vtkStringArray")) { vtkVariant v(vtkArrayDownCast(arr)->GetValue(i)); val = v.ToDouble(); } else if (arr->IsA("vtkDataArray")) { val = vtkArrayDownCast(arr)->GetTuple1(i); } else { cout << "Unknown array type" << endl; exit(1); } double stdTableVal = stdTable[j][i]; if (stdTableVal && val != stdTableVal) { cout << "Values not equal at row " << i << " column " << j << ": "; cout << "(" << val << " != " << stdTableVal << ")" << endl; exit(1); } } } // Use GetRow() to check for (int i = 0; i < table->GetNumberOfRows(); i++) { vtkVariantArray* arr = table->GetRow(i); for (int j = 0; j < table->GetNumberOfColumns(); j++) { double val = arr->GetValue(j).ToDouble(); double stdTableVal = stdTable[j][i]; if (stdTableVal && val != stdTableVal) { cout << "Values not equal at row " << i << " column " << j << ": "; cout << "(" << val << " != " << stdTableVal << ")" << endl; exit(1); } } } } int TestTable(int, char*[]) { cout << "CTEST_FULL_OUTPUT" << endl; long seed = time(nullptr); cout << "Seed: " << seed << endl; vtkMath::RandomSeed(seed); // Make a table and a parallel vector of vectors vtkTable* table = vtkTable::New(); vector > stdTable; int size = 100; double prob = 1.0 - 1.0 / size; double highProb = 1.0 - 1.0 / (size*size); cout << "Creating columns." << endl; vtkIdType columnId = 0; bool noColumns = true; while (noColumns || vtkMath::Random() < prob) { noColumns = false; stdTable.push_back(vector()); double r = vtkMath::Random(); vtkVariant name(columnId); vtkAbstractArray* arr; if (r < 0.25) { arr = vtkIntArray::New(); arr->SetName((name.ToString() + " (vtkIntArray)").c_str()); } else if (r < 0.5) { arr = vtkDoubleArray::New(); arr->SetName((name.ToString() + " (vtkDoubleArray)").c_str()); } else if (r < 0.75) { arr = vtkStringArray::New(); arr->SetName((name.ToString() + " (vtkStringArray)").c_str()); } else { arr = vtkVariantArray::New(); arr->SetName((name.ToString() + " (vtkVariantArray)").c_str()); } table->AddColumn(arr); arr->Delete(); columnId++; } cout << "Inserting empty rows." << endl; bool noRows = true; while (noRows || vtkMath::Random() < prob) { noRows = false; table->InsertNextBlankRow(); for (unsigned int i = 0; i < stdTable.size(); i++) { stdTable[i].push_back(0.0); } } cout << "Inserting full rows." << endl; while (vtkMath::Random() < prob) { vtkVariantArray* rowArray = vtkVariantArray::New(); for (vtkIdType j = 0; j < table->GetNumberOfColumns(); j++) { rowArray->InsertNextValue(vtkVariant(j)); stdTable[j].push_back(j); } table->InsertNextRow(rowArray); rowArray->Delete(); } cout << "Performing all kinds of inserts." << endl; int id = 0; while (vtkMath::Random() < highProb) { vtkIdType row = static_cast(vtkMath::Random(0, table->GetNumberOfRows())); vtkIdType col = static_cast(vtkMath::Random(0, table->GetNumberOfColumns())); vtkVariant v; if (vtkMath::Random() < 0.25) { vtkVariant temp(id); v = vtkVariant(temp.ToString()); } else if (vtkMath::Random() < 0.5) { v = vtkVariant(id); } else { v = vtkVariant(static_cast(id)); } if (vtkMath::Random() < 0.5) { table->SetValue(row, col, v); } else { table->SetValueByName(row, table->GetColumnName(col), v); } stdTable[col][row] = id; id++; } cout << "Removing half of the rows." << endl; int numRowsToRemove = table->GetNumberOfRows() / 2; for (int i = 0; i < numRowsToRemove; i++) { vtkIdType row = static_cast(vtkMath::Random(0, table->GetNumberOfRows())); cout << "Removing row " << row << " from vtkTable with " << table->GetNumberOfRows() << " rows" << endl; table->RemoveRow(row); cout << "Removing row " << row << " from vector< vector > with " << stdTable[0].size() << " rows " << endl; for (unsigned int j = 0; j < stdTable.size(); j++) { vector::iterator rowIt = stdTable[j].begin() + row; stdTable[j].erase(rowIt); } } cout << "Removing half of the columns." << endl; int numColsToRemove = table->GetNumberOfColumns() / 2; for (int i = 0; i < numColsToRemove; i++) { vtkIdType col = static_cast(vtkMath::Random(0, table->GetNumberOfColumns())); if (vtkMath::Random() < 0.5) { table->RemoveColumn(col); } else { table->RemoveColumnByName(table->GetColumnName(col)); } vector >::iterator colIt = stdTable.begin() + col; stdTable.erase(colIt); } cout << "vtkTable size: " << table->GetNumberOfRows() << "," << table->GetNumberOfColumns() << endl; cout << "vector > size: " << stdTable[0].size() << "," << stdTable.size() << endl; cout << "Checking that table matches expected table." << endl; CheckEqual(table, stdTable); table->Delete(); return 0; }