mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
177 lines
5.6 KiB
C++
177 lines
5.6 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkBoostSplitTableField.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.
|
|
|
|
=========================================================================*/
|
|
|
|
#include "vtkBoostSplitTableField.h"
|
|
|
|
#include "vtkAbstractArray.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkDataSetAttributes.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkStringArray.h"
|
|
#include "vtkTable.h"
|
|
#include "vtkVariantArray.h"
|
|
|
|
#include <boost/algorithm/string/trim.hpp>
|
|
#include <boost/tokenizer.hpp>
|
|
|
|
vtkStandardNewMacro(vtkBoostSplitTableField);
|
|
|
|
/// Ecapsulates private implementation details of vtkBoostSplitTableField
|
|
class vtkBoostSplitTableField::implementation
|
|
{
|
|
public:
|
|
typedef boost::char_separator<char> delimiter_t;
|
|
typedef boost::tokenizer<delimiter_t> tokenizer_t;
|
|
typedef std::vector<tokenizer_t*> tokenizers_t;
|
|
|
|
static void GenerateRows(const tokenizers_t& tokenizers, const unsigned int column_index, vtkVariantArray* input_row, vtkVariantArray* output_row, vtkTable* output_table)
|
|
{
|
|
if(column_index == tokenizers.size())
|
|
{
|
|
output_table->InsertNextRow(output_row);
|
|
return;
|
|
}
|
|
|
|
tokenizer_t* const tokenizer = tokenizers[column_index];
|
|
vtkVariant input_value = input_row->GetValue(column_index);
|
|
|
|
if(tokenizer && input_value.IsString())
|
|
{
|
|
const std::string value = input_value.ToString();
|
|
tokenizer->assign(value);
|
|
for(tokenizer_t::iterator token = tokenizer->begin(); token != tokenizer->end(); ++token)
|
|
{
|
|
output_row->SetValue(column_index, boost::trim_copy(*token).c_str());
|
|
GenerateRows(tokenizers, column_index + 1, input_row, output_row, output_table);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
output_row->SetValue(column_index, input_value);
|
|
GenerateRows(tokenizers, column_index + 1, input_row, output_row, output_table);
|
|
}
|
|
}
|
|
};
|
|
|
|
vtkBoostSplitTableField::vtkBoostSplitTableField() :
|
|
Fields(vtkStringArray::New()),
|
|
Delimiters(vtkStringArray::New())
|
|
{
|
|
}
|
|
|
|
vtkBoostSplitTableField::~vtkBoostSplitTableField()
|
|
{
|
|
this->Delimiters->Delete();
|
|
this->Fields->Delete();
|
|
}
|
|
|
|
void vtkBoostSplitTableField::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|
|
|
|
void vtkBoostSplitTableField::ClearFields()
|
|
{
|
|
this->Fields->Initialize();
|
|
this->Delimiters->Initialize();
|
|
this->Modified();
|
|
}
|
|
|
|
void vtkBoostSplitTableField::AddField(const char* field, const char* delimiters)
|
|
{
|
|
assert(field);
|
|
assert(delimiters);
|
|
|
|
this->Fields->InsertNextValue(field);
|
|
this->Delimiters->InsertNextValue(delimiters);
|
|
|
|
this->Modified();
|
|
}
|
|
|
|
int vtkBoostSplitTableField::RequestData(
|
|
vtkInformation*,
|
|
vtkInformationVector** inputVector,
|
|
vtkInformationVector* outputVector)
|
|
{
|
|
vtkTable* const input = vtkTable::GetData(inputVector[0]);
|
|
vtkTable* const output = vtkTable::GetData(outputVector);
|
|
|
|
// If the number of fields and delimiters don't match, we're done ...
|
|
if(this->Fields->GetNumberOfValues() != this->Delimiters->GetNumberOfValues())
|
|
{
|
|
vtkErrorMacro("The number of fields and the number of delimiters must match");
|
|
return 0;
|
|
}
|
|
|
|
// If no fields were specified, we don't do any splitting - just shallow copy ...
|
|
if(0 == this->Fields->GetNumberOfValues())
|
|
{
|
|
output->ShallowCopy(input);
|
|
return 1;
|
|
}
|
|
|
|
// Setup the columns for our output table ...
|
|
for(vtkIdType i = 0; i < input->GetNumberOfColumns(); ++i)
|
|
{
|
|
vtkAbstractArray* const column = input->GetColumn(i);
|
|
vtkAbstractArray* const new_column = vtkAbstractArray::CreateArray(column->GetDataType());
|
|
new_column->SetName(column->GetName());
|
|
new_column->SetNumberOfComponents(column->GetNumberOfComponents());
|
|
output->AddColumn(new_column);
|
|
if(input->GetRowData()->GetPedigreeIds() == column)
|
|
{
|
|
output->GetRowData()->SetPedigreeIds(new_column);
|
|
}
|
|
new_column->Delete();
|
|
}
|
|
|
|
// Setup a tokenizer for each column that will be split ...
|
|
implementation::tokenizers_t tokenizers;
|
|
for(vtkIdType column = 0; column < input->GetNumberOfColumns(); ++column)
|
|
{
|
|
tokenizers.push_back(static_cast<implementation::tokenizer_t*>(0));
|
|
|
|
for(vtkIdType field = 0; field < this->Fields->GetNumberOfValues(); ++field)
|
|
{
|
|
if(this->Fields->GetValue(field) == input->GetColumn(column)->GetName())
|
|
{
|
|
tokenizers[column] = new implementation::tokenizer_t(std::string(), implementation::delimiter_t(this->Delimiters->GetValue(field)));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Iterate over each row in the input table, generating one-to-many rows in the output table ...
|
|
vtkVariantArray* const output_row = vtkVariantArray::New();
|
|
output_row->SetNumberOfValues(input->GetNumberOfColumns());
|
|
|
|
for(vtkIdType i = 0; i < input->GetNumberOfRows(); ++i)
|
|
{
|
|
vtkVariantArray* const input_row = input->GetRow(i);
|
|
implementation::GenerateRows(tokenizers, 0, input_row, output_row, output);
|
|
|
|
double progress = static_cast<double>(i) / static_cast<double>(input->GetNumberOfRows());
|
|
this->InvokeEvent(vtkCommand::ProgressEvent, &progress);
|
|
}
|
|
|
|
output_row->Delete();
|
|
|
|
// Cleanup tokenizers ...
|
|
for(implementation::tokenizers_t::iterator tokenizer = tokenizers.begin(); tokenizer != tokenizers.end(); ++tokenizer)
|
|
delete *tokenizer;
|
|
|
|
return 1;
|
|
}
|