Commit 3d1b6466 authored by Joachim Pouderoux's avatar Joachim Pouderoux Committed by Kitware Robot

Merge topic 'filter_dev'

7014b417 New feature for vtkPointDataToCellData and vtkCellDataToPointData
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Mathieu Westphal's avatarMathieu Westphal <mathieu.westphal@kitware.com>
Acked-by: Joachim Pouderoux's avatarJoachim Pouderoux <joachim.pouderoux@kitware.com>
Merge-request: !4707
parents 921d4ffd 7014b417
......@@ -29,6 +29,7 @@ vtk_add_test_cxx(vtkFiltersCoreCxxTests tests
TestImplicitPolyDataDistance.cxx
TestMaskPoints.cxx,NO_VALID
TestNamedComponents.cxx,NO_VALID
TestPointDataToCellData.cxx,NO_VALID
TestPolyDataConnectivityFilter.cxx,NO_VALID
TestProbeFilter.cxx,NO_VALID
TestProbeFilterImageInput.cxx
......
......@@ -18,6 +18,8 @@
#include <vtkCellData.h>
#include <vtkDataSet.h>
#include <vtkDataSetTriangleFilter.h>
#include <vtkDoubleArray.h>
#include <vtkImageData.h>
#include <vtkPointData.h>
#include <vtkPointDataToCellData.h>
#include <vtkRTAnalyticSource.h>
......@@ -26,13 +28,10 @@
#include <vtkThreshold.h>
#include <vtkTestUtilities.h>
#define vsp(type, name) \
vtkSmartPointer<vtk##type> name = vtkSmartPointer<vtk##type>::New()
int TestCellDataToPointData (int, char*[])
{
char const name [] = "RTData";
vsp(RTAnalyticSource, wavelet);
vtkNew<vtkRTAnalyticSource> wavelet;
wavelet->SetWholeExtent(-2, 2, -2, 2, -2, 2);
wavelet->SetCenter(0, 0, 0);
wavelet->SetMaximum(255);
......@@ -44,24 +43,67 @@ int TestCellDataToPointData (int, char*[])
wavelet->SetYMag(18);
wavelet->SetZMag(5);
wavelet->SetSubsampleRate(1);
wavelet->Update();
vtkNew<vtkDoubleArray> dist;
dist->SetNumberOfComponents(1);
dist->SetName("Dist");
vtkImageData *original = wavelet->GetOutput();
for (vtkIdType i = 0; i < original->GetNumberOfPoints(); ++i)
{
double p[3];
original->GetPoint(i, p);
dist->InsertNextValue(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]);
}
original->GetPointData()->AddArray(dist);
vsp(PointDataToCellData, p2c);
p2c->SetInputConnection(wavelet->GetOutputPort());
vtkNew<vtkPointDataToCellData> p2c;
p2c->SetInputData(original);
p2c->PassPointDataOff();
vsp(CellDataToPointData, sc2p);
vtkNew<vtkCellDataToPointData> selectiveC2P;
selectiveC2P->SetInputConnection(p2c->GetOutputPort());
selectiveC2P->SetProcessAllArrays(false);
selectiveC2P->AddCellDataArray(name);
selectiveC2P->Update();
vtkNew<vtkCellDataToPointData> sc2p;
sc2p->SetInputConnection(p2c->GetOutputPort());
sc2p->PassCellDataOff();
sc2p->Update();
vsp(DataSetTriangleFilter, c2g);
vtkNew<vtkDataSetTriangleFilter> c2g;
c2g->SetInputConnection(p2c->GetOutputPort());
vsp(CellDataToPointData, uc2p);
vtkNew<vtkCellDataToPointData> uc2p;
uc2p->SetInputConnection(c2g->GetOutputPort());
vtkDataArray* const x = sc2p->GetOutput()->GetPointData()->GetArray(name);
// test if selective CellDataToPointData operates on the correct
int outNumPArrays = selectiveC2P->GetOutput()->GetPointData()->GetNumberOfArrays(); // should be 1
int outNumCArrays = selectiveC2P->GetOutput()->GetCellData()->GetNumberOfArrays(); // should be 0
std::string pArrayName = selectiveC2P->GetOutput()->GetPointData()->GetArrayName(0); // should be RTData
if (outNumPArrays != 1)
{
std::cerr << "Wrong number of PointData arrays." << std::endl;
return EXIT_FAILURE;
}
if (outNumCArrays != 0)
{
std::cerr << "Wrong number of CellData arrays." << std::endl;
return EXIT_FAILURE;
}
if (pArrayName != name)
{
std::cerr << "Array name not matching original name." << std::endl;
return EXIT_FAILURE;
}
// iterate through the options for which cells contribute to the result
// for the cell data to point data filter. since all cells are 3D the
// result should be the same.
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestCellDataToPointData.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 <vtkDataArray.h>
#include <vtkCellData.h>
#include <vtkDataSet.h>
#include <vtkDataSetTriangleFilter.h>
#include <vtkDoubleArray.h>
#include <vtkImageData.h>
#include <vtkPointData.h>
#include <vtkPointDataToCellData.h>
#include <vtkRTAnalyticSource.h>
#include <vtkUnstructuredGrid.h>
#include <vtkThreshold.h>
#include <vtkTestUtilities.h>
int TestPointDataToCellData (int, char*[])
{
char const name [] = "RTData";
vtkNew<vtkRTAnalyticSource> wavelet;
wavelet->SetWholeExtent(-2, 2, -2, 2, -2, 2);
wavelet->SetCenter(0, 0, 0);
wavelet->SetMaximum(255);
wavelet->SetStandardDeviation(.5);
wavelet->SetXFreq(60);
wavelet->SetYFreq(30);
wavelet->SetZFreq(40);
wavelet->SetXMag(10);
wavelet->SetYMag(18);
wavelet->SetZMag(5);
wavelet->SetSubsampleRate(1);
wavelet->Update();
vtkNew<vtkDoubleArray> dist;
dist->SetNumberOfComponents(1);
dist->SetName("Dist");
vtkImageData *original = wavelet->GetOutput();
for (vtkIdType i = 0; i < original->GetNumberOfPoints(); ++i)
{
double p[3];
original->GetPoint(i, p);
dist->InsertNextValue(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]);
}
original->GetPointData()->AddArray(dist);
vtkNew<vtkPointDataToCellData> p2c;
p2c->SetInputData(original);
p2c->SetProcessAllArrays(false);
p2c->AddPointDataArray(name);
p2c->PassPointDataOff();
p2c->Update();
// test if selective CellDataToPointData operates on the correct
int outNumPArrays = p2c->GetOutput()->GetPointData()->GetNumberOfArrays(); // should be 0
int outNumCArrays = p2c->GetOutput()->GetCellData()->GetNumberOfArrays(); // should be 1
std::string cArrayName = p2c->GetOutput()->GetCellData()->GetArrayName(0); // should be RTData
if (outNumPArrays != 0)
{
std::cerr << "Wrong number of PointData arrays." << std::endl;
return EXIT_FAILURE;
}
if (outNumCArrays != 1)
{
std::cerr << "Wrong number of CellData arrays." << std::endl;
return EXIT_FAILURE;
}
if (cArrayName != name)
{
std::cerr << "Array name not matching original name." << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
This diff is collapsed.
......@@ -19,8 +19,10 @@
* vtkCellDataToPointData is a filter that transforms cell data (i.e., data
* specified per cell) into point data (i.e., data specified at cell
* points). The method of transformation is based on averaging the data
* values of all cells using a particular point. Optionally, the input cell
* data can be passed through to the output as well.
* values of all cells using a particular point. For large datasets with
* several cell data arrays, the filter optionally supports selective
* processing to speed up processing. Optionally, the input cell data can
* be passed through to the output as well.
* Unstructured grids and polydata can have cells of different dimensions.
* To handle different use cases in this situation, the user can specify
* which cells contribute to the computation. The options for this are
......@@ -66,9 +68,9 @@ public:
* on, then the input cell data is passed through to the output; otherwise,
* only generated point data is placed into the output.
*/
vtkSetMacro(PassCellData,vtkTypeBool);
vtkGetMacro(PassCellData,vtkTypeBool);
vtkBooleanMacro(PassCellData,vtkTypeBool);
vtkSetMacro(PassCellData,bool);
vtkGetMacro(PassCellData,bool);
vtkBooleanMacro(PassCellData,bool);
//@}
//@{
......@@ -80,9 +82,39 @@ public:
vtkGetMacro(ContributingCellOption, int);
//@}
//@{
/**
* Activate selective processing of arrays. If inactive, only arrays selected
* by the user will be considered by this filter. The default is true.
*/
vtkSetMacro(ProcessAllArrays, bool);
vtkGetMacro(ProcessAllArrays, bool);
vtkBooleanMacro(ProcessAllArrays, bool);
//@}
/**
* Adds an array to be processed. This only has an effect if the
* ProcessAllArrays option is turned off. If a name is already present,
* nothing happens.
*/
virtual void AddCellDataArray(const char *name);
/**
* Removes an array to be processed. This only has an effect if the
* ProcessAllArrays option is turned off. If the specified name is not
* present, nothing happens.
*/
virtual void RemoveCellDataArray(const char *name);
/**
* Removes all arrays to be processed from the list. This only has an effect
* if the ProcessAllArrays option is turned off.
*/
virtual void ClearCellDataArrays();
protected:
vtkCellDataToPointData();
~vtkCellDataToPointData() override {}
~vtkCellDataToPointData() override;
int RequestData(vtkInformation* request,
vtkInformationVector** inputVector,
......@@ -97,13 +129,13 @@ protected:
(vtkInformation*, vtkInformationVector**, vtkInformationVector*);
//@}
void InterpolatePointData(vtkDataSet *input, vtkDataSet *output);
int InterpolatePointData(vtkDataSet *input, vtkDataSet *output);
//@{
/**
* Option to pass cell data arrays through to the output. Default is 0/off.
*/
vtkTypeBool PassCellData;
bool PassCellData;
//@}
//@{
......@@ -114,6 +146,14 @@ protected:
int ContributingCellOption;
//@}
/**
* Option to activate selective processing of arrays.
*/
bool ProcessAllArrays;
class Internals;
Internals *Implementation;
private:
vtkCellDataToPointData(const vtkCellDataToPointData&) = delete;
void operator=(const vtkCellDataToPointData&) = delete;
......
......@@ -17,6 +17,7 @@
#include <algorithm>
#include <cassert>
#include <limits>
#include <set>
#include <vector>
#include "vtkCellData.h"
......@@ -150,6 +151,12 @@ vtkIdType Histogram::IndexOfLargestBin()
}
class vtkPointDataToCellData::Internals
{
public:
std::set<std::string> PointDataArrays;
};
vtkStandardNewMacro(vtkPointDataToCellData);
......@@ -159,6 +166,50 @@ vtkPointDataToCellData::vtkPointDataToCellData()
{
this->PassPointData = 0;
this->CategoricalData = 0;
this->ProcessAllArrays = true;
this->Implementation = new Internals();
}
//----------------------------------------------------------------------------
vtkPointDataToCellData::~vtkPointDataToCellData()
{
delete this->Implementation;
}
//----------------------------------------------------------------------------
void vtkPointDataToCellData::AddPointDataArray(const char *name)
{
if (!name)
{
vtkErrorMacro("name cannot be null.");
return;
}
this->Implementation->PointDataArrays.insert(std::string(name));
this->Modified();
}
//----------------------------------------------------------------------------
void vtkPointDataToCellData::RemovePointDataArray(const char *name)
{
if (!name)
{
vtkErrorMacro("name cannot be null.");
return;
}
this->Implementation->PointDataArrays.erase(name);
this->Modified();
}
//----------------------------------------------------------------------------
void vtkPointDataToCellData::ClearPointDataArrays()
{
if (!this->Implementation->PointDataArrays.empty())
{
this->Modified();
}
this->Implementation->PointDataArrays.clear();
}
//----------------------------------------------------------------------------
......@@ -177,13 +228,34 @@ int vtkPointDataToCellData::RequestData(
vtkIdType cellId, ptId, pointId;
vtkIdType numCells, numPts;
vtkPointData *inPD=input->GetPointData();
vtkPointData *inputInPD = input->GetPointData();
vtkPointData *inPD;
vtkCellData *outCD=output->GetCellData();
int maxCellSize=input->GetMaxCellSize();
vtkIdList *cellPts;
double weight;
double *weights;
if (!this->ProcessAllArrays)
{
inPD = vtkPointData::New();
for (const auto &name : this->Implementation->PointDataArrays)
{
vtkAbstractArray *arr = inputInPD->GetAbstractArray(name.c_str());
if (arr == nullptr)
{
vtkWarningMacro("point data array name not found.");
continue;
}
inPD->AddArray(arr);
}
}
else
{
inPD = inputInPD;
}
vtkDebugMacro(<<"Mapping point data to cell data");
// First, copy the input to the output as a starting point
......@@ -292,6 +364,11 @@ int vtkPointDataToCellData::RequestData(
cellPts->Delete();
delete [] weights;
if (!this->ProcessAllArrays)
{
inPD->Delete();
}
return 1;
}
......
......@@ -19,7 +19,9 @@
* vtkPointDataToCellData is a filter that transforms point data (i.e., data
* specified per point) into cell data (i.e., data specified per cell).
* The method of transformation is based on averaging the data
* values of all points defining a particular cell. Optionally, the input point
* values of all points defining a particular cell. For large datasets with
* several cell data arrays, the filter optionally supports selective
* processing to speed up processing. Optionally, the input point
* data can be passed through to the output as well.
*
* @warning
......@@ -51,9 +53,9 @@ public:
* on, then the input point data is passed through to the output; otherwise,
* only generated point data is placed into the output.
*/
vtkSetMacro(PassPointData,vtkTypeBool);
vtkGetMacro(PassPointData,vtkTypeBool);
vtkBooleanMacro(PassPointData,vtkTypeBool);
vtkSetMacro(PassPointData,bool);
vtkGetMacro(PassPointData,bool);
vtkBooleanMacro(PassPointData,bool);
//@}
//@{
......@@ -62,21 +64,56 @@ public:
* the data is categorical, then the resultant cell data will be determined by
* a "majority rules" vote, with ties going to the smaller value.
*/
vtkSetMacro(CategoricalData,vtkTypeBool);
vtkGetMacro(CategoricalData,vtkTypeBool);
vtkBooleanMacro(CategoricalData,vtkTypeBool);
vtkSetMacro(CategoricalData,bool);
vtkGetMacro(CategoricalData,bool);
vtkBooleanMacro(CategoricalData,bool);
//@}
//@{
/**
* Activate selective processing of arrays. If inactive, only arrays selected
* by the user will be considered by this filter. The default is true.
*/
vtkSetMacro(ProcessAllArrays, bool);
vtkGetMacro(ProcessAllArrays, bool);
vtkBooleanMacro(ProcessAllArrays, bool);
//@}
/**
* Adds an array to be processed. This only has an effect if the
* ProcessAllArrays option is turned off. If a name is already present,
* nothing happens.
*/
virtual void AddPointDataArray(const char *name);
/**
* Removes an array to be processed. This only has an effect if the
* ProcessAllArrays option is turned off. If the specified name is not
* present, nothing happens.
*/
virtual void RemovePointDataArray(const char *name);
/**
* Removes all arrays to be processed from the list. This only has an effect
* if the ProcessAllArrays option is turned off.
*/
virtual void ClearPointDataArrays();
protected:
vtkPointDataToCellData();
~vtkPointDataToCellData() override {}
~vtkPointDataToCellData() override;
int RequestData(vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector) override;
vtkTypeBool PassPointData;
vtkTypeBool CategoricalData;
bool PassPointData;
bool CategoricalData;
bool ProcessAllArrays;
class Internals;
Internals *Implementation;
private:
vtkPointDataToCellData(const vtkPointDataToCellData&) = delete;
void operator=(const vtkPointDataToCellData&) = delete;
......
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