Commit f7e845a7 authored by Mathieu Westphal's avatar Mathieu Westphal Committed by Kitware Robot
Browse files

Merge topic 'periodicFilterFix'

a94c1c8e Fixing parallel periodic filter
e180b45d

 First bug fix fro periodic filter
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Mathieu Westphal's avatarMathieu Westphal <mathieu.westphal@kitware.com>
Reviewed-by: Mathieu Westphal's avatarMathieu Westphal <mathieu.westphal@kitware.com>
Merge-request: !398
parents 3d3f264c a94c1c8e
set(Module_SRCS
vtkAngularPeriodicFilter.cxx
vtkAnnotationLink.cxx
vtkAppendPoints.cxx
vtkApproximatingSubdivisionFilter.cxx
......@@ -47,7 +46,6 @@ set(Module_SRCS
vtkOBBDicer.cxx
vtkOBBTree.cxx
vtkPassThrough.cxx
vtkPeriodicFilter.cxx
vtkPolyDataStreamer.cxx
vtkPolyDataToReebGraphFilter.cxx
vtkProbePolyhedron.cxx
......
......@@ -15,7 +15,6 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
BoxClipTetrahedra.cxx
BoxClipTriangulateAndInterpolate.cxx
BoxClipTriangulate.cxx,NO_VALID
TestAngularPeriodicFilter.cxx
TestAppendPoints.cxx,NO_VALID
TestBooleanOperationPolyDataFilter2.cxx
TestBooleanOperationPolyDataFilter.cxx
......
set(Module_SRCS
vtkAngularPeriodicFilter.cxx
vtkCollectGraph.cxx
vtkCollectPolyData.cxx
vtkCollectTable.cxx
......@@ -10,6 +11,7 @@ set(Module_SRCS
vtkExtractUserDefinedPiece.cxx
vtkPCellDataToPointData.cxx
vtkPExtractArraysOverTime.cxx
vtkPeriodicFilter.cxx
vtkPKdTree.cxx
vtkPLinearExtrusionFilter.cxx
vtkPMaskPoints.cxx
......
include(vtkMPI)
vtk_add_test_cxx(${vtk-module}CxxTests testsStd
TestAngularPeriodicFilter.cxx
)
vtk_add_test_mpi(${vtk-module}CxxTests-MPI tests
TESTING_DATA
DistributedData.cxx
......@@ -18,3 +22,4 @@ set(all_tests
${no_data_tests}
)
vtk_test_mpi_executable(${vtk-module}CxxTests-MPI all_tests)
vtk_test_cxx_executable(${vtk-module}CxxTests testsStd)
......@@ -12,10 +12,12 @@ vtk_module(vtkFiltersParallel
vtkTestingCore
vtkTestingRendering
vtkInteractionStyle
vtkIOXML
vtkRendering${VTK_RENDERING_BACKEND}
vtkRenderingParallel
vtkFiltersParallelMPI
vtkFiltersParallelImaging
vtkFiltersFlowPaths
vtkIOLegacy
KIT
vtkParallel
......
......@@ -20,6 +20,7 @@
#include "vtkDoubleArray.h"
#include "vtkFieldData.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkMath.h"
#include "vtkMultiPieceDataSet.h"
#include "vtkNew.h"
......@@ -32,6 +33,8 @@
#include "vtkTransformFilter.h"
#include "vtkUnstructuredGrid.h"
#include <sstream>
vtkStandardNewMacro(vtkAngularPeriodicFilter);
//----------------------------------------------------------------------------
......@@ -101,16 +104,16 @@ void vtkAngularPeriodicFilter::SetRotationAxisToZ()
}
//----------------------------------------------------------------------------
void vtkAngularPeriodicFilter::CreatePeriodicDataSet(
vtkCompositeDataIterator* loc,
vtkCompositeDataSet* output,
vtkCompositeDataSet* input)
void vtkAngularPeriodicFilter::CreatePeriodicDataSet(
vtkCompositeDataIterator* loc,
vtkCompositeDataSet* output,
vtkCompositeDataSet* input)
{
vtkDataObject* inputNode = input->GetDataSet(loc);
if (inputNode == NULL)
{
return;
}
vtkNew<vtkMultiPieceDataSet> multiPiece;
// Number of periods
int periodsNb = 0;
// Rotation angle in degree
double angle = this->GetRotationAngle();
......@@ -120,15 +123,22 @@ void vtkAngularPeriodicFilter::SetRotationAxisToZ()
break;
case VTK_ROTATION_MODE_ARRAY_VALUE:
{
vtkDataArray* angleArray =
inputNode->GetFieldData()->GetArray(this->GetRotationArrayName());
if (!angleArray)
if (inputNode != NULL)
{
vtkDataArray* angleArray =
inputNode->GetFieldData()->GetArray(this->GetRotationArrayName());
if (!angleArray)
{
vtkErrorMacro(<< "Bad rotation mode.");
return;
}
double angleRad = angleArray->GetTuple1(0);
angle = vtkMath::DegreesFromRadians(angleRad);
}
else
{
vtkErrorMacro(<< "Bad rotation mode.");
return;
angle = 360;
}
double angleRad = angleArray->GetTuple1(0);
angle = vtkMath::DegreesFromRadians(angleRad);
break;
}
default:
......@@ -138,8 +148,6 @@ void vtkAngularPeriodicFilter::SetRotationAxisToZ()
}
}
// Number of iterations
vtkIdType periodsNb;
switch (this->GetIterationMode())
{
case VTK_ITERATION_MODE_DIRECT_NB:
......@@ -161,10 +169,8 @@ void vtkAngularPeriodicFilter::SetRotationAxisToZ()
}
}
vtkNew<vtkMultiPieceDataSet> multiPiece;
multiPiece->SetNumberOfPieces(periodsNb);
if (periodsNb > 0)
if (periodsNb > 0 && inputNode != NULL)
{
// Shallow copy the first piece, it is not transformed
vtkDataObject* firstDataSet = inputNode->NewInstance();
......@@ -172,15 +178,31 @@ void vtkAngularPeriodicFilter::SetRotationAxisToZ()
multiPiece->SetPiece(0, firstDataSet);
firstDataSet->Delete();
this->GeneratePieceName(input, loc, multiPiece.Get(), 0);
}
for (vtkIdType iPiece = 1; iPiece < periodsNb; iPiece++)
{
this->AppendPeriodicPiece(angle, iPiece, inputNode, multiPiece.Get());
this->GeneratePieceName(input, loc, multiPiece.Get(), iPiece);
for (vtkIdType iPiece = 1; iPiece < periodsNb; iPiece++)
{
this->AppendPeriodicPiece(angle, iPiece, inputNode, multiPiece.Get());
this->GeneratePieceName(input, loc, multiPiece.Get(), iPiece);
}
}
this->PeriodNumbers.push_back(periodsNb);
output->SetDataSet(loc, multiPiece.Get());
}
//----------------------------------------------------------------------------
void vtkAngularPeriodicFilter::SetPeriodNumber(vtkCompositeDataIterator* loc,
vtkCompositeDataSet* output,
int nbPeriod)
{
vtkMultiPieceDataSet* mp = vtkMultiPieceDataSet::SafeDownCast(output->GetDataSet(loc));
if (mp)
{
mp->SetNumberOfPieces(nbPeriod);
}
else
{
vtkErrorMacro(<< "Setting period on a non existent vtkMultiPieceDataSet");
}
}
//----------------------------------------------------------------------------
void vtkAngularPeriodicFilter::AppendPeriodicPiece(double angle,
......@@ -189,32 +211,14 @@ void vtkAngularPeriodicFilter::AppendPeriodicPiece(double angle,
vtkPointSet* dataset = vtkPointSet::SafeDownCast(inputNode);
vtkPointSet* transformedDataset = NULL;
// MappedData supported type are polydata and (un)structured grid
if (!dataset)
{
return;
}
switch (dataset->GetDataObjectType())
{
case(VTK_POLY_DATA):
transformedDataset = vtkPolyData::New();
break;
case(VTK_STRUCTURED_GRID):
transformedDataset = vtkStructuredGrid::New();
break;
case(VTK_UNSTRUCTURED_GRID):
transformedDataset = vtkUnstructuredGrid::New();
break;
default:
break;
}
int pieceAlterner = ((iPiece % 2) * 2 - 1) * ((iPiece + 1) / 2);
double pieceAngle = angle * pieceAlterner;
if (transformedDataset)
// MappedData supported type are pointset
if (dataset)
{
transformedDataset = dataset->NewInstance();
// Transform periodic points and cells
this->ComputePeriodicMesh(dataset, transformedDataset, pieceAngle);
multiPiece->SetPiece(iPiece, transformedDataset);
......@@ -356,3 +360,40 @@ void vtkAngularPeriodicFilter::ComputePeriodicMesh(vtkPointSet* dataset,
// Shallow copy field data
transformedDataset->GetFieldData()->ShallowCopy(dataset->GetFieldData());
}
//----------------------------------------------------------------------------
int vtkAngularPeriodicFilter::RequestData(vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
if (this->GetRotationMode() == VTK_ROTATION_MODE_ARRAY_VALUE &&
this->GetIterationMode() == VTK_ITERATION_MODE_MAX)
{
this->ReducePeriodNumbers = true;
}
return this->Superclass::RequestData(request, inputVector, outputVector);
}
//----------------------------------------------------------------------------
void vtkAngularPeriodicFilter::GeneratePieceName(vtkCompositeDataSet* input,
vtkCompositeDataIterator* inputLoc, vtkMultiPieceDataSet* output, vtkIdType outputId)
{
vtkDataObjectTree* inputTree = vtkDataObjectTree::SafeDownCast(input);
if (!inputTree)
{
return;
}
std::ostringstream ss;
const char* parentName =
inputTree->GetMetaData(inputLoc)->Get(vtkCompositeDataSet::NAME());
if (parentName)
{
ss << parentName;
}
else
{
ss << "Piece";
}
ss << "_period" << outputId;
output->GetMetaData(outputId)->Set(vtkCompositeDataSet::NAME(), ss.str().c_str());
}
......@@ -35,7 +35,7 @@
#ifndef vtkAngularPeriodicFilter_h
#define vtkAngularPeriodicFilter_h
#include "vtkFiltersGeneralModule.h" // For export macro
#include "vtkFiltersParallelModule.h" // For export macro
#include "vtkPeriodicFilter.h"
class vtkDataSetAttributes;
......@@ -45,7 +45,7 @@ class vtkPointSet;
#define VTK_ROTATION_MODE_DIRECT_ANGLE 0 // Use user-provided angle
#define VTK_ROTATION_MODE_ARRAY_VALUE 1 // Use array from input data as angle
class VTKFILTERSGENERAL_EXPORT vtkAngularPeriodicFilter : public vtkPeriodicFilter
class VTKFILTERSPARALLEL_EXPORT vtkAngularPeriodicFilter : public vtkPeriodicFilter
{
public:
static vtkAngularPeriodicFilter* New();
......@@ -94,6 +94,10 @@ protected:
vtkAngularPeriodicFilter();
~vtkAngularPeriodicFilter();
virtual int RequestData(vtkInformation *,
vtkInformationVector **,
vtkInformationVector *);
// Description:
// Create a transform copy of the provided data array
vtkDataArray* TransformDataArray(vtkDataArray* inputArray,
......@@ -107,6 +111,12 @@ protected:
vtkDataObject* inputNode,
vtkMultiPieceDataSet* multiPiece);
// Description:
// Manually set the number of period on a specific leaf
virtual void SetPeriodNumber(vtkCompositeDataIterator* loc,
vtkCompositeDataSet* output,
int nbPeriod);
// Description:
// Compute periodic pointset, rotating point, using provided angle
void ComputePeriodicMesh(vtkPointSet* dataset, vtkPointSet* rotatedDataset,
......@@ -124,6 +134,12 @@ protected:
vtkCompositeDataSet* output,
vtkCompositeDataSet* input);
// Description:
// Generate a name for a piece in the periodic dataset from the input dataset
virtual void GeneratePieceName(vtkCompositeDataSet* input,
vtkCompositeDataIterator* inputLoc,
vtkMultiPieceDataSet* output,
vtkIdType outputId);
private:
vtkAngularPeriodicFilter(const vtkAngularPeriodicFilter&); // Not implemented.
void operator=(const vtkAngularPeriodicFilter&); // Not implemented.
......
......@@ -16,17 +16,16 @@
#include "vtkPeriodicFilter.h"
#include "vtkDataObjectTreeIterator.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkMultiPieceDataSet.h"
#include "vtkMultiProcessController.h"
#include <sstream>
//----------------------------------------------------------------------------
vtkPeriodicFilter::vtkPeriodicFilter()
{
this->IterationMode = VTK_ITERATION_MODE_MAX;
this->NumberOfPeriods = 1;
this->ReducePeriodNumbers = false;
}
//----------------------------------------------------------------------------
......@@ -70,57 +69,6 @@ void vtkPeriodicFilter::RemoveAllIndices()
this->Modified();
}
//----------------------------------------------------------------------------
void vtkPeriodicFilter::CreatePeriodicSubTree(vtkDataObjectTreeIterator* loc,
vtkMultiBlockDataSet* output,
vtkMultiBlockDataSet* input)
{
vtkDataObject* inputNode = input->GetDataSet(loc);
if (!inputNode)
{
return;
}
if (!inputNode->IsA("vtkCompositeDataSet"))
{
// We are on a leaf, process it
this->CreatePeriodicDataSet(loc, output, input);
}
else
{
// Recursively process the composite tree
vtkCompositeDataSet* cinput = vtkCompositeDataSet::SafeDownCast(inputNode);
vtkCompositeDataSet* coutput =
vtkCompositeDataSet::SafeDownCast(output->GetDataSet(loc));
if (coutput == NULL)
{
return;
}
vtkCompositeDataIterator* iter = cinput->NewIterator();
vtkDataObjectTreeIterator* treeIter =
vtkDataObjectTreeIterator::SafeDownCast(iter);
if (treeIter)
{
treeIter->VisitOnlyLeavesOff();
}
for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
vtkDataObject* inputNode2 = cinput->GetDataSet(iter);
if (inputNode2 == NULL)
{
break;
}
if (!inputNode2->IsA("vtkCompositeDataSet"))
{
this->CreatePeriodicDataSet(iter, coutput, cinput);
}
this->ActiveIndices.erase(
loc->GetCurrentFlatIndex() + iter->GetCurrentFlatIndex());
}
iter->Delete();
}
}
//----------------------------------------------------------------------------
int vtkPeriodicFilter::RequestData(vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
......@@ -136,38 +84,25 @@ int vtkPeriodicFilter::RequestData(vtkInformation *vtkNotUsed(request),
return 1;
}
output->CopyStructure(input);
this->PeriodNumbers.clear();
this->ActiveIndices = this->Indices;
output->CopyStructure(input);
// Copy selected blocks over to the output.
vtkDataObjectTreeIterator* iter = input->NewTreeIterator();
iter->VisitOnlyLeavesOff();
// Generate leaf multipieces
iter->VisitOnlyLeavesOn();
iter->SkipEmptyNodesOff();
iter->InitTraversal();
while (!iter->IsDoneWithTraversal() && this->ActiveIndices.size() > 0)
while (!iter->IsDoneWithTraversal() && this->Indices.size() > 0)
{
const unsigned int index = iter->GetCurrentFlatIndex();
if (this->ActiveIndices.find(index) != this->ActiveIndices.end())
if (this->Indices.find(index) != this->Indices.end())
{
this->ActiveIndices.erase(index);
// This removed the visited indices from this->ActiveIndices.
this->CreatePeriodicSubTree(iter, output, input);
this->CreatePeriodicDataSet(iter, output, input);
}
iter->GoToNextItem();
}
iter->Delete();
// Now shallow copy leaves from the input that were not selected
// Note: this is OK to share iterator between input and output here
iter = output->NewTreeIterator();
iter->VisitOnlyLeavesOn();
iter->SkipEmptyNodesOff();
iter->InitTraversal();
while (!iter->IsDoneWithTraversal())
{
if (!output->GetDataSet(iter))
else
{
vtkDataObject* inputLeaf = input->GetDataSet(iter);
if (inputLeaf)
......@@ -180,33 +115,34 @@ int vtkPeriodicFilter::RequestData(vtkInformation *vtkNotUsed(request),
}
iter->GoToNextItem();
}
iter->Delete();
this->ActiveIndices.clear();
return 1;
}
//----------------------------------------------------------------------------
void vtkPeriodicFilter::GeneratePieceName(vtkCompositeDataSet* input,
vtkCompositeDataIterator* inputLoc, vtkMultiPieceDataSet* output, vtkIdType outputId)
{
vtkDataObjectTree* inputTree = vtkDataObjectTree::SafeDownCast(input);
if (!inputTree)
{
return;
}
std::ostringstream ss;
const char* parentName =
inputTree->GetMetaData(inputLoc)->Get(vtkCompositeDataSet::NAME());
if (parentName)
{
ss << parentName;
}
else
// Reduce period number in case of parrallelism, and update empty multipieces
if (this->ReducePeriodNumbers)
{
ss << "Piece";
int* reducedPeriodNumbers = new int[this->PeriodNumbers.size()];
vtkMultiProcessController *controller = vtkMultiProcessController::GetGlobalController();
if (controller)
{
controller->AllReduce(&this->PeriodNumbers.front(), reducedPeriodNumbers,
this->PeriodNumbers.size(), vtkCommunicator::MAX_OP);
int i = 0;
iter->InitTraversal();
while (!iter->IsDoneWithTraversal() && this->Indices.size() > 0)
{
if (reducedPeriodNumbers[i] > this->PeriodNumbers[i])
{
const unsigned int index = iter->GetCurrentFlatIndex();
if (this->Indices.find(index) != this->Indices.end())
{
this->SetPeriodNumber(iter, output, reducedPeriodNumbers[i]);
}
}
iter->GoToNextItem();
i++;
}
}
delete [] reducedPeriodNumbers;
}
ss << "_period" << outputId;
output->GetMetaData(outputId)->Set(vtkCompositeDataSet::NAME(), ss.str().c_str());
iter->Delete();
return 1;
}
......@@ -32,10 +32,11 @@
#ifndef vtkPeriodicFilter_h
#define vtkPeriodicFilter_h
#include "vtkFiltersGeneralModule.h" // For export macro
#include "vtkFiltersParallelModule.h" // For export macro
#include "vtkMultiBlockDataSetAlgorithm.h"
#include <set> // For block selection
#include <vector> // For pieces number
class vtkCompositeDataIterator;
class vtkCompositeDataSet;
......@@ -45,7 +46,7 @@ class vtkMultiPieceDataSet;
#define VTK_ITERATION_MODE_DIRECT_NB 0 // Generate a user-provided number of periods
#define VTK_ITERATION_MODE_MAX 1 // Generate a maximum of periods, i.e. a full period.
class VTKFILTERSGENERAL_EXPORT vtkPeriodicFilter : public vtkMultiBlockDataSetAlgorithm
class VTKFILTERSPARALLEL_EXPORT vtkPeriodicFilter : public vtkMultiBlockDataSetAlgorithm
{
public:
vtkTypeMacro(vtkPeriodicFilter, vtkMultiBlockDataSetAlgorithm);
......@@ -95,12 +96,6 @@ protected:
vtkInformationVector **,
vtkInformationVector *);
// Description:
// Create the periodic sub tree
virtual void CreatePeriodicSubTree(vtkDataObjectTreeIterator* loc,
vtkMultiBlockDataSet* output,
vtkMultiBlockDataSet* input);
// Description:
// Create a periodic data, leaf of the tree
virtual void CreatePeriodicDataSet(vtkCompositeDataIterator* loc,
......@@ -108,11 +103,13 @@ protected:
vtkCompositeDataSet* input) = 0;
// Description:
// Generate a name for a piece in the periodic dataset from the input dataset
virtual void GeneratePieceName(vtkCompositeDataSet* input,
vtkCompositeDataIterator* inputLoc,
vtkMultiPieceDataSet* output,
vtkIdType outputId);
// Manually set the number of period on a specific leaf
virtual void SetPeriodNumber(vtkCompositeDataIterator* loc,
vtkCompositeDataSet* output,
int nbPeriod) = 0;
std::vector<int> PeriodNumbers; // Periods numbers by leaf
bool ReducePeriodNumbers;
private:
vtkPeriodicFilter(const vtkPeriodicFilter&); // Not implemented.
......@@ -121,8 +118,7 @@ private:
int IterationMode;
int NumberOfPeriods; // User provided number of periods
std::set<vtkIdType> Indices; // All the tree indices
std::set<vtkIdType> ActiveIndices; // Selected indices only
std::set<vtkIdType> Indices; // Selected indices
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment