59 vtkInformationVector **inputVector,
60 vtkInformationVector *outputVector) {
62 const auto blocks = vtkMultiBlockDataSet::GetData(inputVector[0]);
63 const auto weightsVTK = vtkTable::GetData(inputVector[1]);
65 std::vector<vtkUnstructuredGrid *> inputDiagrams;
67 if(blocks !=
nullptr) {
68 int numInputs = blocks->GetNumberOfBlocks();
69 inputDiagrams.resize(numInputs);
70 for(
int i = 0; i < numInputs; ++i) {
71 inputDiagrams[i] = vtkUnstructuredGrid::SafeDownCast(blocks->GetBlock(i));
75 const size_t nDiags = inputDiagrams.size();
77 std::vector<ttk::DiagramType> dictDiagrams(nDiags);
78 for(
size_t i = 0; i < nDiags; ++i) {
79 vtkNew<vtkUnstructuredGrid> vtu;
80 vtu->DeepCopy(inputDiagrams[i]);
81 auto &atom = dictDiagrams[i];
84 this->
printWrn(
"Could not read Persistence Diagram");
89 for(
const auto vtu : inputDiagrams) {
91 this->
printErr(
"Input diagrams are not all vtkUnstructuredGrid");
97 = [](std::string &colName,
const size_t numberCols,
const size_t colIdx) {
98 std::string max{std::to_string(numberCols - 1)};
99 std::string cur{std::to_string(colIdx)};
100 std::string zer(max.size() - cur.size(),
'0');
101 colName.append(zer).append(cur);
104 vtkNew<vtkTable> temp;
105 temp->DeepCopy(weightsVTK);
106 std::vector<vtkDataArray *> inputWeights;
107 int numWeights = temp->GetNumberOfRows();
109 if(weightsVTK !=
nullptr) {
110 inputWeights.resize(nDiags);
111 for(
size_t i = 0; i < nDiags; ++i) {
112 std::string name{
"Atom"};
113 zeroPad(name, nDiags, i);
115 = vtkDataArray::SafeDownCast(temp->GetColumnByName(name.c_str()));
119 std::vector<std::vector<double>> vectorWeights(numWeights);
120 for(
int i = 0; i < numWeights; ++i) {
121 std::vector<double> &t1 = vectorWeights[i];
122 for(
size_t j = 0; j < nDiags; ++j) {
123 double weight = inputWeights[j]->GetTuple1(i);
124 t1.push_back(weight);
127 std::vector<ttk::DiagramType> Barycenters(numWeights);
130 this->
execute(dictDiagrams, vectorWeights, Barycenters);
133 auto outputDgm = vtkMultiBlockDataSet::GetData(outputVector, 0);
134 auto outputCoordinates = vtkTable::GetData(outputVector, 1);
135 outputDgm->SetNumberOfBlocks(numWeights);
136 outputCoordinates->SetNumberOfRows(numWeights);
139 weightsVTK, vectorWeights,
Spacing, 1);
155 vtkMultiBlockDataSet *output,
156 vtkTable *outputCoordinates,
157 const std::vector<ttk::DiagramType> &diags,
158 std::vector<ttk::DiagramType> &atoms,
159 vtkTable *weightsVTK,
160 const std::vector<std::vector<double>> &weights,
161 const double spacing,
162 const double maxPersistence)
const {
164 const auto nDiags = diags.size();
165 const auto nAtoms = atoms.size();
169 output->SetNumberOfBlocks(nDiags + n_existing_blocks);
170 std::vector<std::array<double, 3>> coords(nAtoms);
171 std::vector<std::array<double, 3>> trueCoords(nAtoms);
172 std::vector<double> xVector(nDiags);
173 std::vector<double> yVector(nDiags);
174 std::vector<double> zVector(nDiags, 0.);
175 vtkNew<vtkDoubleArray> dummy{};
178 zVector, spacing, nAtoms);
183 for(
size_t i = 0; i < nAtoms; ++i) {
184 double X = coords[i][0];
185 double Y = coords[i][1];
186 vtkNew<vtkUnstructuredGrid> vtu{};
189 output->SetBlock(i, vtu);
193 }
else if(nAtoms == 3) {
196 for(
size_t i = 0; i < nAtoms; ++i) {
197 double X = coords[i][0];
198 double Y = coords[i][1];
199 vtkNew<vtkUnstructuredGrid> vtu{};
202 output->SetBlock(i, vtu);
209 for(
size_t i = 0; i < nAtoms; ++i) {
211 = 2.0 *
M_PI *
static_cast<double>(i) /
static_cast<double>(nAtoms);
212 double X = spacing * maxPersistence * std::cos(angle);
213 double Y = spacing * maxPersistence * std::sin(angle);
214 vtkNew<vtkUnstructuredGrid> vtu{};
217 output->SetBlock(i, vtu);
222 int numDiags = diags.size();
224 for(
int i = 0; i < numDiags; ++i) {
225 vtkNew<vtkUnstructuredGrid> vtu{};
232 for(
size_t iAtom = 0; iAtom < nAtoms; ++iAtom) {
233 X += weights[i][iAtom] * coords[iAtom][0];
234 Y += weights[i][iAtom] * coords[iAtom][1];
238 output->SetBlock(i + n_existing_blocks, vtu);
241 for(
size_t i = 0; i < 3; ++i) {
242 vtkNew<vtkDoubleArray> col{};
243 col->SetNumberOfValues(nDiags);
253 col->SetName(name.c_str());
254 for(
size_t j = 0; j < nDiags; ++j) {
256 col->SetValue(j, xVector[j]);
258 col->SetValue(j, yVector[j]);
260 col->SetValue(j, zVector[j]);
264 outputCoordinates->AddColumn(col);
268 = [](std::string &colName,
const size_t numberCols,
const size_t colIdx) {
269 std::string max{std::to_string(numberCols - 1)};
270 std::string cur{std::to_string(colIdx)};
271 std::string zer(max.size() - cur.size(),
'0');
272 colName.append(zer).append(cur);
275 vtkNew<vtkTable> temp;
276 temp->DeepCopy(weightsVTK);
277 for(
int i = 0; i < temp->GetNumberOfColumns(); ++i) {
279 const auto array = temp->GetColumn(i);
281 for(
size_t j = 0; j < nDiags; ++j) {
282 std::string name{
"Atom"};
283 zeroPad(name, nDiags, j);
284 if(strcmp(name.c_str(), temp->GetColumnName(i)) == 0) {
291 outputCoordinates->AddColumn(array);
294 for(
size_t i = 0; i < nAtoms; ++i) {
295 vtkNew<vtkVariantArray> row{};
296 row->SetNumberOfValues(outputCoordinates->GetNumberOfColumns());
297 for(
int j = 0; j < outputCoordinates->GetNumberOfColumns(); ++j) {
298 if(strcmp(outputCoordinates->GetColumnName(j),
"X") == 0) {
299 row->SetValue(j, trueCoords[i][0]);
300 }
else if(strcmp(outputCoordinates->GetColumnName(j),
"Y") == 0) {
301 row->SetValue(j, trueCoords[i][1]);
302 }
else if(strcmp(outputCoordinates->GetColumnName(j),
"Z") == 0) {
303 row->SetValue(j, trueCoords[i][2]);
304 }
else if(strcmp(outputCoordinates->GetColumnName(j),
"ClusterID") == 0) {
305 row->SetValue(j, -1);
311 outputCoordinates->InsertNextRow(row);