41 vtkPoints *inputPoints,
42 const std::vector<ttk::rpd::Generator1> &generators1,
45 const auto cd = vtu->GetCellData();
48 for(
auto const &g : generators1)
49 n_edges += g.first.size();
52 vtkNew<vtkIntArray> simplexId{};
53 simplexId->SetName(
"simplexIdentifier");
54 simplexId->SetNumberOfTuples(n_edges);
55 cd->AddArray(simplexId);
57 vtkNew<vtkIntArray> classId{};
58 classId->SetName(
"ClassIdentifier");
59 classId->SetNumberOfTuples(n_edges);
60 cd->AddArray(classId);
62 vtkNew<vtkDoubleArray> classBirth{};
63 classBirth->SetName(
"ClassBirth");
64 classBirth->SetNumberOfTuples(n_edges);
65 cd->AddArray(classBirth);
67 vtkNew<vtkDoubleArray> classDeath{};
68 classDeath->SetName(
"ClassDeath");
69 classDeath->SetNumberOfTuples(n_edges);
70 cd->AddArray(classDeath);
72 vtkNew<vtkDoubleArray> classPersistence{};
73 classPersistence->SetName(
"ClassPersistence");
74 classPersistence->SetNumberOfTuples(n_edges);
75 cd->AddArray(classPersistence);
77 vtkNew<vtkIntArray> classDimension{};
78 classDimension->SetName(
"ClassDimension");
79 classDimension->SetNumberOfTuples(n_edges);
80 cd->AddArray(classDimension);
82 vtkNew<vtkDoubleArray> generatorParametrization{};
83 generatorParametrization->SetName(
"GeneratorParametrization");
84 generatorParametrization->SetNumberOfTuples(n_edges);
85 cd->AddArray(generatorParametrization);
88 vtkNew<vtkIdTypeArray> offsets{}, connectivity{};
89 offsets->SetNumberOfComponents(1);
90 offsets->SetNumberOfTuples(n_edges + 1);
91 connectivity->SetNumberOfComponents(1);
92 connectivity->SetNumberOfTuples(2 * n_edges);
95 for(
unsigned j = 0; j < generators1.size(); ++j) {
99 ParametrizeGenerator(parametrization, g);
100 for(
auto const &e : g.first) {
101 const unsigned i0 = 2 * i, i1 = 2 * i + 1;
102 simplexId->SetTuple1(i, i);
103 classId->SetTuple1(i, j);
104 classBirth->SetTuple1(i, g.second.first);
105 classDeath->SetTuple1(i, g.second.second);
106 classPersistence->SetTuple1(i, g.second.second - g.second.first);
107 classDimension->SetTuple1(i, 1);
109 generatorParametrization->SetTuple1(i, parametrization[e]);
111 generatorParametrization->SetTuple1(i, 0.);
113 connectivity->SetTuple1(i0, e.first);
114 connectivity->SetTuple1(i1, e.second);
115 offsets->SetTuple1(i, 2 * i);
120 offsets->SetTuple1(n_edges, connectivity->GetNumberOfTuples());
122 vtkNew<vtkCellArray> cells{};
123 cells->SetData(offsets, connectivity);
124 vtu->SetPoints(inputPoints);
125 vtu->SetCells(VTK_LINE, cells);
156 vtkInformationVector **inputVector,
157 vtkInformationVector *outputVector) {
161 vtkTable *input = vtkTable::GetData(inputVector[0]);
162 vtkPointSet *pointSet = vtkPointSet::GetData(inputVector[1]);
163 vtkUnstructuredGrid *outputGenerators
164 = vtkUnstructuredGrid::GetData(outputVector, 0);
165 vtkUnstructuredGrid *outputPersistenceDiagram
166 = vtkUnstructuredGrid::GetData(outputVector, 1);
168 if(!input || !pointSet)
171 if(SelectFieldsWithRegexp) {
173 ScalarFields.clear();
174 const auto n = input->GetNumberOfColumns();
175 for(
int i = 0; i < n; ++i) {
176 const auto &name = input->GetColumnName(i);
177 if(std::regex_match(name, std::regex(RegexpString))) {
178 ScalarFields.emplace_back(name);
183 if(input->GetNumberOfRows() <= 0 || ScalarFields.size() <= 0) {
184 this->
printErr(
"Input matrix has invalid dimensions (rows: "
185 + std::to_string(input->GetNumberOfRows())
186 +
", columns: " + std::to_string(ScalarFields.size()) +
")");
188 }
else if(input->GetNumberOfRows() != pointSet->GetNumberOfPoints()) {
189 this->
printErr(
"Input and 3D representation have different");
190 this->
printErr(
"numbers of points: resp. "
191 + std::to_string(input->GetNumberOfRows()) +
" and "
192 + std::to_string(pointSet->GetNumberOfPoints()));
196 std::vector<vtkAbstractArray *> arrays;
197 arrays.reserve(ScalarFields.size());
198 for(
const auto &s : ScalarFields)
199 arrays.push_back(input->GetColumnByName(s.data()));
201 std::vector<std::vector<double>> points;
204 const int numberOfPoints = input->GetNumberOfRows();
205 const int dimension = ScalarFields.size();
206 points.resize(numberOfPoints);
207 for(
int i = 0; i < numberOfPoints; ++i) {
208 for(
int j = 0; j < dimension; ++j)
209 points[i].push_back(arrays[j]->GetVariantValue(i).ToDouble());
212 "Computing Rips pers. generators", 0.0, tm.getElapsedTime(), 1);
213 this->
printMsg(
"#dimensions: " + std::to_string(dimension)
214 +
", #points: " + std::to_string(numberOfPoints),
215 0.0, tm.getElapsedTime(), 1);
219 const unsigned n = input->GetNumberOfRows();
220 if(n != ScalarFields.size()) {
221 this->
printErr(
"Input distance matrix is not squared.");
222 this->
printErr(
"(rows: " + std::to_string(input->GetNumberOfRows())
223 +
", columns: " + std::to_string(ScalarFields.size())
228 points = {std::vector<double>(n * (n - 1) / 2)};
229 for(
unsigned i = 1; i < n; ++i) {
230 for(
unsigned j = 0; j < i; ++j)
231 points[0][i * (i - 1) / 2 + j]
232 = arrays[j]->GetVariantValue(i).ToDouble();
235 "Computing Rips pers. generators", 0.0, tm.getElapsedTime(), 1);
237 "(" + std::to_string(n) +
"x" + std::to_string(n) +
" distance matrix)",
238 0.0, tm.getElapsedTime(), 1);
241 std::vector<ttk::rpd::Diagram> diagram(0);
242 std::vector<ttk::rpd::Generator1> generators(0);
243 this->
execute(points, diagram, generators);
246 outputGenerators, pointSet->GetPoints(), generators, !
OutputCascade);
249 this->
printMsg(
"Complete", 1.0, tm.getElapsedTime(), 1);
252 outputPersistenceDiagram->GetFieldData()->ShallowCopy(input->GetFieldData());
int DiagramToVTU(vtkUnstructuredGrid *vtu, const ttk::DiagramType &diagram, vtkDataArray *const inputScalars, const ttk::Debug &dbg, const int dim, const bool embedInDomain)
Converts a Persistence Diagram in the ttk::DiagramType format to the VTK Unstructured Grid format (as...