Skip to content
Snippets Groups Projects
Commit e6ae090e authored by Scott Wittenburg's avatar Scott Wittenburg
Browse files

Move vtkMergeArrays into VTK proper, to be used from within other filters.

Also separate out the parallel functionality and move it into a subclass,
vtkPMergeArrays.
parent 581650da
No related branches found
No related tags found
No related merge requests found
......@@ -59,6 +59,7 @@ set(classes
vtkLoopBooleanPolyDataFilter
vtkMarchingContourFilter
vtkMatricizeArray
vtkMergeArrays
vtkMergeCells
vtkMultiBlockDataGroupFilter
vtkMultiBlockFromTimeSeriesFilter
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkMergeArrays.cxx
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 "vtkMergeArrays.h"
#include "vtkCellData.h"
#include "vtkCompositeDataIterator.h"
#include "vtkCompositeDataSet.h"
#include "vtkDataArray.h"
#include "vtkDataSet.h"
#include "vtkFieldData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"
vtkStandardNewMacro(vtkMergeArrays);
//----------------------------------------------------------------------------
vtkMergeArrays::vtkMergeArrays() {}
//----------------------------------------------------------------------------
vtkMergeArrays::~vtkMergeArrays() {}
//----------------------------------------------------------------------------
bool vtkMergeArrays::GetOutputArrayName(
vtkFieldData* arrays, const char* arrayName, int inputIndex, std::string& outputArrayName)
{
if (arrays->GetAbstractArray(arrayName) == nullptr)
{
return false;
}
outputArrayName = std::string(arrayName) + "_input_" + std::to_string(inputIndex);
return true;
}
//----------------------------------------------------------------------------
void vtkMergeArrays::MergeArrays(int inputIndex, vtkFieldData* inputFD, vtkFieldData* outputFD)
{
if (inputFD == nullptr || outputFD == nullptr)
{
return;
}
std::string outputArrayName;
int numArrays = inputFD->GetNumberOfArrays();
for (int arrayIdx = 0; arrayIdx < numArrays; ++arrayIdx)
{
vtkAbstractArray* array = inputFD->GetAbstractArray(arrayIdx);
if (this->GetOutputArrayName(outputFD, array->GetName(), inputIndex, outputArrayName))
{
vtkAbstractArray* newArray = array->NewInstance();
if (vtkDataArray* newDataArray = vtkDataArray::SafeDownCast(newArray))
{
newDataArray->ShallowCopy(vtkDataArray::SafeDownCast(array));
}
else
{
newArray->DeepCopy(array);
}
newArray->SetName(outputArrayName.c_str());
outputFD->AddArray(newArray);
newArray->FastDelete();
}
else
{
outputFD->AddArray(array);
}
}
}
//----------------------------------------------------------------------------
int vtkMergeArrays::MergeDataObjectFields(vtkDataObject* input, int idx, vtkDataObject* output)
{
int checks[vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES];
for (int attr = 0; attr < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; attr++)
{
checks[attr] = output->GetNumberOfElements(attr) == input->GetNumberOfElements(attr) ? 0 : 1;
}
int globalChecks[vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES];
for (int i = 0; i < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; ++i)
{
globalChecks[i] = checks[i];
}
for (int attr = 0; attr < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; attr++)
{
if (globalChecks[attr] == 0)
{
// only merge arrays when the number of elements in the input and output are the same
this->MergeArrays(
idx, input->GetAttributesAsFieldData(attr), output->GetAttributesAsFieldData(attr));
}
}
return 1;
}
//----------------------------------------------------------------------------
int vtkMergeArrays::FillInputPortInformation(int vtkNotUsed(port), vtkInformation* info)
{
info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
return 1;
}
//----------------------------------------------------------------------------
int vtkMergeArrays::RequestData(vtkInformation* vtkNotUsed(request),
vtkInformationVector** inputVector, vtkInformationVector* outputVector)
{
int num = inputVector[0]->GetNumberOfInformationObjects();
if (num < 1)
{
return 0;
}
// get the output info object
vtkInformation* outInfo = outputVector->GetInformationObject(0);
vtkDataObject* output = outInfo->Get(vtkDataObject::DATA_OBJECT());
vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
vtkDataObject* input = inInfo->Get(vtkDataObject::DATA_OBJECT());
vtkCompositeDataSet* cOutput = vtkCompositeDataSet::SafeDownCast(output);
if (cOutput)
{
vtkCompositeDataSet* cInput = vtkCompositeDataSet::SafeDownCast(input);
cOutput->CopyStructure(cInput);
vtkSmartPointer<vtkCompositeDataIterator> iter;
iter.TakeReference(cInput->NewIterator());
iter->InitTraversal();
for (; !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
if (vtkDataSet* tmpIn = vtkDataSet::SafeDownCast(iter->GetCurrentDataObject()))
{
vtkDataSet* tmpOut = tmpIn->NewInstance();
tmpOut->ShallowCopy(tmpIn);
cOutput->SetDataSet(iter, tmpOut);
tmpOut->Delete();
}
}
}
else
{
output->ShallowCopy(input);
}
for (int idx = 1; idx < num; ++idx)
{
inInfo = inputVector[0]->GetInformationObject(idx);
input = inInfo->Get(vtkDataObject::DATA_OBJECT());
if (!this->MergeDataObjectFields(input, idx, output))
{
return 0;
}
vtkCompositeDataSet* cInput = vtkCompositeDataSet::SafeDownCast(input);
if (cOutput && cInput)
{
vtkSmartPointer<vtkCompositeDataIterator> iter;
iter.TakeReference(cInput->NewIterator());
iter->InitTraversal();
for (; !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
vtkDataObject* tmpIn = iter->GetCurrentDataObject();
vtkDataObject* tmpOut = cOutput->GetDataSet(iter);
if (!this->MergeDataObjectFields(tmpIn, idx, tmpOut))
{
return 0;
}
}
}
}
return 1;
}
//----------------------------------------------------------------------------
void vtkMergeArrays::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkMergeArrays.h
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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.
=========================================================================*/
/**
* @class vtkMergeArrays
* @brief Multiple inputs with one output.
*
* vtkMergeArrays tries to put all arrays from all inputs into one output.
* The output data object is the same as the first data input.
* The filter checks for a consistent number of points and cells with
* respect to the first input, but does not check any more. Any inputs
* which do not have the correct number of points or cells are ignored
* for that type of data set attribute. When adding new arrays, if there
* is an existing array of the same name and attribute type, the new array
* will have the name mangled to be the original array name plus
* `_input_<inputid>` where `<inputid>` is the id/index of the input filter
* that is providing that array.
*/
#ifndef vtkMergeArrays_h
#define vtkMergeArrays_h
#include "vtkFiltersGeneralModule.h" // For export macro
#include "vtkPassInputTypeAlgorithm.h"
#include <string> // Needed for protected method argument
class vtkDataSet;
class vtkFieldData;
class VTKFILTERSGENERAL_EXPORT vtkMergeArrays : public vtkPassInputTypeAlgorithm
{
public:
static vtkMergeArrays* New();
vtkTypeMacro(vtkMergeArrays, vtkPassInputTypeAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent) override;
protected:
vtkMergeArrays();
~vtkMergeArrays() override;
//@{
/**
* Given an existing set of output arrays and an array name and input data set
* index, return an appropriate name to use for the output array. Returns true
* if the name is a new name and false if not.
*/
virtual bool GetOutputArrayName(
vtkFieldData* arrays, const char* inArrayName, int inputIndex, std::string& outArrayName);
//@}
//@{
/**
* Add input field arrays to output, mangling output array names as needed
* based on inputIndex.
*/
void MergeArrays(int inputIndex, vtkFieldData* inputFD, vtkFieldData* outputFD);
//@{
/**
* For a given input and index, add data arrays to the output. Returns 1 for
* success and 0 for failure.
*/
virtual int MergeDataObjectFields(vtkDataObject* input, int inputIndex, vtkDataObject* output);
//@}
// see algorithm for more info
int FillInputPortInformation(int port, vtkInformation* info) override;
int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;
private:
vtkMergeArrays(const vtkMergeArrays&) = delete;
void operator=(const vtkMergeArrays&) = delete;
};
#endif
......@@ -21,6 +21,7 @@ set(classes
vtkPKdTree
vtkPLinearExtrusionFilter
vtkPMaskPoints
vtkPMergeArrays
vtkPOutlineCornerFilter
vtkPOutlineFilter
vtkPOutlineFilterInternals
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPMergeArrays.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 "vtkPMergeArrays.h"
#include "vtkDataObject.h"
#include "vtkMultiProcessController.h"
#include "vtkObjectFactory.h"
vtkStandardNewMacro(vtkPMergeArrays);
//----------------------------------------------------------------------------
vtkPMergeArrays::vtkPMergeArrays() {}
//----------------------------------------------------------------------------
void vtkPMergeArrays::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
//----------------------------------------------------------------------------
int vtkPMergeArrays::MergeDataObjectFields(vtkDataObject* input, int idx, vtkDataObject* output)
{
int checks[vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES];
for (int attr = 0; attr < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; attr++)
{
checks[attr] = output->GetNumberOfElements(attr) == input->GetNumberOfElements(attr) ? 0 : 1;
}
int globalChecks[vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES];
auto controller = vtkMultiProcessController::GetGlobalController();
if (controller == nullptr)
{
for (int i = 0; i < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; ++i)
{
globalChecks[i] = checks[i];
}
}
else
{
controller->AllReduce(
checks, globalChecks, vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES, vtkCommunicator::MAX_OP);
}
for (int attr = 0; attr < vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES; attr++)
{
if (globalChecks[attr] == 0)
{
// only merge arrays when the number of elements in the input and output are the same
this->MergeArrays(
idx, input->GetAttributesAsFieldData(attr), output->GetAttributesAsFieldData(attr));
}
}
return 1;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPMergeArrays.h
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.
=========================================================================*/
/**
* @class vtkPMergeArrays
* @brief Multiple inputs with one output, parallel version
*
* Like it's super class, this filter tries to combine all arrays from
* inputs into one output.
*
* @sa
* vtkMergeArrays
*/
#ifndef vtkPMergeArrays_h
#define vtkPMergeArrays_h
#include "vtkFiltersParallelModule.h" // For export macro
#include "vtkMergeArrays.h"
class VTKFILTERSPARALLEL_EXPORT vtkPMergeArrays : public vtkMergeArrays
{
public:
vtkTypeMacro(vtkPMergeArrays, vtkMergeArrays);
void PrintSelf(ostream& os, vtkIndent indent) override;
static vtkPMergeArrays* New();
protected:
vtkPMergeArrays();
~vtkPMergeArrays() override {}
int MergeDataObjectFields(vtkDataObject* input, int idx, vtkDataObject* output) override;
private:
vtkPMergeArrays(const vtkPMergeArrays&) = delete;
void operator=(const vtkPMergeArrays&) = delete;
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment