4#include <vtkDataArray.h>
6#include <vtkDoubleArray.h>
7#include <vtkInformation.h>
8#include <vtkInformationVector.h>
9#include <vtkMultiBlockDataSet.h>
11#include <vtkObjectFactory.h>
12#include <vtkPointData.h>
20 SetNumberOfInputPorts(1);
21 SetNumberOfOutputPorts(1);
25 vtkInformation *info) {
27 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkMultiBlockDataSet");
34 vtkInformation *info) {
36 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkTable");
44 std::vector<std::vector<double>> &distanceMatrix,
45 const std::vector<vtkDataSet *> &inputData,
46 const size_t nPoints) {
48 std::vector<const T *> inputPtrs(inputData.size());
49 for(
size_t i = 0; i < inputData.size(); ++i) {
51 = ttkUtils::GetPointer<T>(this->GetInputArrayToProcess(0, inputData[i]));
53 return this->
execute(distanceMatrix, inputPtrs, nPoints);
57 vtkInformationVector **inputVector,
58 vtkInformationVector *outputVector) {
61 const auto blocks = vtkMultiBlockDataSet::GetData(inputVector[0], 0);
63 if(blocks ==
nullptr) {
67 const size_t nInputs{blocks->GetNumberOfBlocks()};
70 std::vector<vtkDataSet *> inputData(nInputs);
72 for(
size_t i = 0; i < nInputs; ++i) {
73 inputData[i] = vtkDataSet::SafeDownCast(blocks->GetBlock(i));
78 std::set<vtkIdType> sizes{};
79 for(
size_t i = 0; i < nInputs; ++i) {
80 if(inputData[i] ==
nullptr) {
81 this->
printErr(
"One input block is not a vtkDataSet");
84 sizes.emplace(inputData[i]->GetNumberOfPoints());
86 if(sizes.size() > 1) {
87 this->
printErr(
"Input blocks do not have the same number of points");
93 auto DistTable = vtkTable::GetData(outputVector);
95 std::vector<std::vector<double>> distMatrix{};
97 const auto firstField = this->GetInputArrayToProcess(0, inputData[0]);
98 const auto dataType = firstField->GetDataType();
99 const size_t nPoints = firstField->GetNumberOfTuples();
102 vtkTemplateMacro(this->dispatch<VTK_TT>(distMatrix, inputData, nPoints));
107 = [](std::string &colName,
const size_t numberCols,
const size_t colIdx) {
108 std::string max{std::to_string(numberCols - 1)};
109 std::string cur{std::to_string(colIdx)};
110 std::string zer(max.size() - cur.size(),
'0');
111 colName.append(zer).append(cur);
115 for(
size_t i = 0; i < nInputs; ++i) {
116 std::string name{
"Dataset"};
117 zeroPad(name, distMatrix.size(), i);
119 vtkNew<vtkDoubleArray> col{};
120 col->SetNumberOfTuples(nInputs);
121 col->SetName(name.c_str());
122 for(
size_t j = 0; j < nInputs; ++j) {
123 col->SetTuple1(j, distMatrix[i][j]);
125 DistTable->AddColumn(col);
129 vtkNew<vtkFieldData> fd{};
130 fd->CopyStructure(inputData[0]->GetFieldData());
131 fd->SetNumberOfTuples(inputData.size());
132 for(
size_t i = 0; i < inputData.size(); ++i) {
133 fd->SetTuple(i, 0, inputData[i]->GetFieldData());
137 for(
int i = 0; i < fd->GetNumberOfArrays(); ++i) {
138 DistTable->AddColumn(fd->GetAbstractArray(i));
141 this->
printMsg(
"Complete (#datasets: " + std::to_string(nInputs)
142 +
", #points: " + std::to_string(nPoints) +
")",
143 1.0, tm.getElapsedTime(), this->threadNumber_);
Computes a distance matrix using LDistance between several input datasets with the same number of poi...
int FillInputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int dispatch(std::vector< std::vector< double > > &distanceMatrix, const std::vector< vtkDataSet * > &inputData, const size_t nPoints)
int FillOutputPortInformation(int port, vtkInformation *info) override
int printMsg(const std::string &msg, const debug::Priority &priority=debug::Priority::INFO, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cout) const
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
int execute(std::vector< TOut * > &output, const std::vector< const TIn * > &inputs, const size_t nPoints) const
vtkStandardNewMacro(ttkLDistanceMatrix)