7#include <vtkCellData.h>
8#include <vtkDataArray.h>
9#include <vtkDataObject.h>
10#include <vtkDataSet.h>
11#include <vtkDoubleArray.h>
12#include <vtkInformation.h>
13#include <vtkObjectFactory.h>
14#include <vtkPointData.h>
15#include <vtkPointSet.h>
16#include <vtkUnstructuredGrid.h>
23 this->SetNumberOfInputPorts(2);
24 this->SetNumberOfOutputPorts(1);
31 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkDataSet");
33 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkPointSet");
39 vtkInformation *info) {
41 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkUnstructuredGrid");
46template <
typename triangulationType>
49 const triangulationType *triangulation,
54 const std::vector<ttk::SimplexId> &globalVertexId,
55 const std::vector<ttk::SimplexId> &globalCellId,
57 vtkUnstructuredGrid *output) {
58 if(input ==
nullptr || output ==
nullptr
59 || input->GetPointData() ==
nullptr) {
60 this->
printErr(
"Null pointers in getTrajectories parameters");
64 vtkNew<vtkUnstructuredGrid> ug{};
65 vtkNew<vtkPoints> pts{};
66 vtkNew<vtkDoubleArray> dist{};
67 vtkNew<vtkIdTypeArray> identifier{};
69 vtkNew<vtkIdTypeArray> vtkEdgeIdentifiers{};
70 vtkNew<vtkIdTypeArray> vtkVertexGlobalIdArray{};
71 vtkNew<vtkIntArray> vtkVertexRankArray{};
72 vtkNew<vtkIntArray> vtkEdgeRankArray{};
74 vtkNew<vtkIdTypeArray> vtkForkIdentifiers{};
75 vtkNew<vtkUnsignedCharArray> outputMaskField{};
77 outputMaskField->SetNumberOfComponents(1);
80 dist->SetNumberOfComponents(1);
81 dist->SetName(
"DistanceFromSeed");
82 identifier->SetNumberOfComponents(1);
83 identifier->SetName(
"SeedIdentifier");
84 vtkForkIdentifiers->SetNumberOfComponents(1);
85 vtkForkIdentifiers->SetName(
"ForkIdentifiers");
88 vtkVertexGlobalIdArray->SetNumberOfComponents(1);
89 vtkVertexGlobalIdArray->SetName(
"GlobalPointIds");
90 vtkEdgeIdentifiers->SetNumberOfComponents(1);
91 vtkEdgeIdentifiers->SetName(
"GlobalCellIds");
92 vtkEdgeRankArray->SetNumberOfComponents(1);
93 vtkEdgeRankArray->SetName(
"RankArray");
94 vtkVertexRankArray->SetNumberOfComponents(1);
95 vtkVertexRankArray->SetName(
"RankArray");
97 const auto numberOfArrays = input->GetPointData()->GetNumberOfArrays();
99 std::vector<vtkDataArray *> scalarArrays{};
100 scalarArrays.reserve(numberOfArrays);
101 for(
int k = 0; k < numberOfArrays; ++k) {
102 const auto a = input->GetPointData()->GetArray(k);
103 if(a->GetNumberOfComponents() == 1) {
105 scalarArrays.push_back(a);
109 std::vector<vtkSmartPointer<vtkDataArray>> inputScalars(scalarArrays.size());
110 for(
size_t k = 0; k < scalarArrays.size(); ++k) {
113 inputScalars[k]->SetNumberOfComponents(1);
114 inputScalars[k]->SetName(scalarArrays[k]->GetName());
116 std::array<float, 3> p;
117 std::array<vtkIdType, 2> ids;
123 auto integralLine = integralLines[thread].list_.begin();
124 while(integralLine != integralLines[thread].list_.end()) {
126 if(integralLine->at(i).trajectory.size() > 0) {
128 triangulation->getVertexPoint(vertex, p[0], p[1], p[2]);
129 ids[0] = pts->InsertNextPoint(p.data());
131 dist->InsertNextTuple1(integralLine->at(i).distanceFromSeed.at(0));
133 outputMaskField->InsertNextTuple1(0);
134 vtkVertexGlobalIdArray->InsertNextTuple1(
135 globalVertexId.at(vertexCounter));
137 vtkVertexRankArray->InsertNextTuple1(
138 triangulation->getVertexRank(vertex));
140 outputMaskField->InsertNextTuple1(0);
142 identifier->InsertNextTuple1(integralLine->at(i).seedIdentifier);
143 vtkForkIdentifiers->InsertNextTuple1(
144 integralLine->at(i).forkIdentifier);
146 for(
size_t k = 0; k < scalarArrays.size(); ++k) {
147 inputScalars[k]->InsertNextTuple1(
148 scalarArrays[k]->GetTuple1(vertex));
150 for(
size_t j = 1; j < integralLine->at(i).trajectory.size(); ++j) {
151 vertex = integralLine->at(i).trajectory.at(j);
153 vtkVertexGlobalIdArray->InsertNextTuple1(
154 globalVertexId.at(vertexCounter));
156 vtkEdgeIdentifiers->InsertNextTuple1(globalCellId.at(edgeCounter));
158 vtkEdgeRankArray->InsertNextTuple1(triangulation->getVertexRank(
159 integralLine->at(i).trajectory.at(j - 1)));
160 vtkVertexRankArray->InsertNextTuple1(
161 triangulation->getVertexRank(vertex));
163 outputMaskField->InsertNextTuple1(1);
164 vtkForkIdentifiers->InsertNextTuple1(
165 integralLine->at(i).forkIdentifier);
166 triangulation->getVertexPoint(vertex, p[0], p[1], p[2]);
167 ids[1] = pts->InsertNextPoint(p.data());
169 dist->InsertNextTuple1(integralLine->at(i).distanceFromSeed.at(j));
170 identifier->InsertNextTuple1(integralLine->at(i).seedIdentifier);
172 for(
unsigned int k = 0; k < scalarArrays.size(); ++k)
173 inputScalars[k]->InsertNextTuple1(
174 scalarArrays[k]->GetTuple1(vertex));
175 ug->InsertNextCell(VTK_LINE, 2, ids.data());
179 outputMaskField->SetTuple1(
180 outputMaskField->GetNumberOfTuples() - 1, 0);
190 ug->GetPointData()->AddArray(dist);
191 ug->GetPointData()->AddArray(identifier);
192 ug->GetPointData()->AddArray(vtkForkIdentifiers);
193 ug->GetPointData()->AddArray(outputMaskField);
195 for(
unsigned int k = 0; k < scalarArrays.size(); ++k) {
196 ug->GetPointData()->AddArray(inputScalars[k]);
199 ug->GetPointData()->AddArray(vtkVertexRankArray);
200 ug->GetCellData()->AddArray(vtkEdgeRankArray);
201 ug->GetCellData()->SetGlobalIds(vtkEdgeIdentifiers);
202 ug->GetPointData()->SetGlobalIds(vtkVertexGlobalIdArray);
204 output->ShallowCopy(ug);
210 vtkInformationVector **inputVector,
211 vtkInformationVector *outputVector) {
213 vtkDataSet *domain = vtkDataSet::GetData(inputVector[0], 0);
214 vtkPointSet *seeds = vtkPointSet::GetData(inputVector[1], 0);
215 vtkUnstructuredGrid *output = vtkUnstructuredGrid::GetData(outputVector, 0);
218 vtkDataArray *inputScalars = this->GetInputArrayToProcess(0, domain);
220 int keepGoing = checkEmptyMPIInput<ttk::Triangulation>(triangulation);
224 vtkDataArray *inputOffsets
225 = this->
GetOrderArray(domain, 0, 1, ForceInputOffsetScalarField);
227 const ttk::SimplexId numberOfPointsInDomain = domain->GetNumberOfPoints();
229 int numberOfPointsInSeeds = seeds->GetNumberOfPoints();
230#ifndef TTK_ENABLE_KAMIKAZE
238#ifdef TTK_ENABLE_MPI_TIME
244 std::vector<ttk::SimplexId> inputIdentifiers{};
246 MPI_Reduce(&numberOfPointsInSeeds, &totalSeeds, 1, MPI_INTEGER, MPI_SUM, 0,
251 isDistributed = numberOfPointsInSeeds != totalSeeds;
253 MPI_Bcast(&isDistributed, 1, MPI_INTEGER, 0, ttk::MPIcomm_);
254 MPI_Bcast(&totalSeeds, 1, MPI_INTEGER, 0, ttk::MPIcomm_);
257 this->setGlobalElementCounter(totalSeeds);
258 vtkDataArray *globalSeedsId;
260 globalSeedsId = seeds->GetPointData()->GetArray(
"GlobalPointIds");
262 globalSeedsId = vtkDataArray::CreateDataArray(VTK_ID_TYPE);
266 globalSeedsId->SetNumberOfComponents(1);
267 globalSeedsId->SetNumberOfTuples(totalSeeds);
270 MPI_Bcast(ttkUtils::GetPointer<ttk::LongSimplexId>(globalSeedsId),
271 totalSeeds, ttk::getMPIType(
id), 0, ttk::MPIcomm_);
273 for(
int i = 0; i < totalSeeds; i++) {
274 localId = triangulation->getVertexLocalId(globalSeedsId->GetTuple1(i));
278 inputIdentifiers.push_back(localId);
281 numberOfPointsInSeeds = inputIdentifiers.size();
283 std::vector<ttk::SimplexId> idSpareStorage{};
289 for(
int i = 0; i < numberOfPointsInSeeds; i++) {
290 localId = triangulation->getVertexLocalId(inputIdentifierGlobalId[i]);
292 inputIdentifiers.push_back(localId);
295 numberOfPointsInSeeds = inputIdentifiers.size();
296 MPI_Allreduce(&numberOfPointsInSeeds, &totalSeeds, 1, MPI_INTEGER,
297 MPI_SUM, ttk::MPIcomm_);
298 this->setGlobalElementCounter(totalSeeds);
301 this->setGlobalElementCounter(numberOfPointsInSeeds);
302 inputIdentifiers.resize(numberOfPointsInSeeds);
303 totalSeeds = numberOfPointsInSeeds;
304 std::vector<ttk::SimplexId> idSpareStorage{};
309 for(
int i = 0; i < numberOfPointsInSeeds; i++) {
310 inputIdentifiers.at(i)
311 = triangulation->getVertexLocalId(inputIdentifierGlobalId[i]);
315 std::vector<ttk::SimplexId> idSpareStorage{};
319 std::unordered_set<ttk::SimplexId> isSeed;
321 isSeed.insert(identifiers[k]);
323 std::vector<ttk::SimplexId> inputIdentifiers(isSeed.begin(), isSeed.end());
324#ifndef TTK_ENABLE_KAMIKAZE
325 totalSeeds = inputIdentifiers.size();
340 this->
setInputOffsets(ttkUtils::GetPointer<ttk::SimplexId>(inputOffsets));
345 std::max(std::max(std::min(1000, (
int)numberOfPointsInSeeds),
349 std::vector<std::vector<std::vector<ttk::intgl::ElementToBeSent>>> toSend(
351 this->setNeighbors(triangulation->getNeighborRanks());
353 toSend.resize(this->neighborNumber_);
354 for(
int i = 0; i < this->neighborNumber_; i++) {
357 toSend[i][j].reserve((
int)numberOfPointsInSeeds * 0.005
358 / this->threadNumber_);
362 this->setToSend(&toSend);
363 this->createMessageType();
365#ifdef TTK_ENABLE_MPI_TIME
369 +
" MPI processes lasted :" + std::to_string(elapsedTime));
372#ifndef TTK_ENABLE_KAMIKAZE
375 this->
printErr(
"wrong scalar field.");
379 if(inputOffsets->GetDataType() != VTK_INT
380 and inputOffsets->GetDataType() != VTK_ID_TYPE) {
381 this->
printErr(
"input offset field type not supported.");
386 if(numberOfPointsInDomain <= 0) {
387 this->
printErr(
"domain has no points.");
391 if(totalSeeds <= 0) {
392 this->
printErr(
"seeds have no points.");
396#ifdef TTK_ENABLE_MPI_TIME
401 (status = this->execute<TTK_TT>(
402 static_cast<TTK_TT *
>(triangulation->
getData()))));
404#ifndef TTK_ENABLE_KAMIKAZE
407 this->
printErr(
"IntegralLines.execute() error code : "
408 + std::to_string(status));
413 std::vector<ttk::SimplexId> globalVertexId;
414 std::vector<ttk::SimplexId> globalCellId;
416 (getGlobalIdentifiers<TTK_TT>(
417 globalVertexId, globalCellId, integralLines,
418 static_cast<TTK_TT *
>(triangulation->
getData()))));
419#ifdef TTK_ENABLE_MPI_TIME
423 +
" MPI processes lasted :" + std::to_string(elapsedTime));
430 (getTrajectories<TTK_TT>(
431 domain,
static_cast<TTK_TT *
>(triangulation->
getData()),
432 integralLines, globalVertexId, globalCellId, output)));
435 (getTrajectories<TTK_TT>(
436 domain,
static_cast<TTK_TT *
>(triangulation->
getData()),
437 integralLines, output)));
440 return (
int)(status == 0);
#define ttkTemplateMacro(triangulationType, call)
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
#define INTEGRAL_LINE_TABULAR_SIZE
ttk::SimplexId * GetIdentifierArrayPtr(const bool &enforceArrayIndex, const int &arrayIndex, const std::string &arrayName, vtkDataSet *const inputData, std::vector< ttk::SimplexId > &spareStorage, const int inputPort=0, const bool printErr=true)
vtkDataArray * GetOrderArray(vtkDataSet *const inputData, const int scalarArrayIdx, const int orderArrayIdx=0, const bool enforceOrderArrayIdx=false)
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
TTK VTK-filter for the computation of edge-based integral lines of the gradient of an input scalar fi...
int getTrajectories(vtkDataSet *input, const triangulationType *triangulation, const std::vector< ttk::ArrayLinkedList< ttk::intgl::IntegralLine, INTEGRAL_LINE_TABULAR_SIZE > > &integralLines, vtkUnstructuredGrid *output)
int FillOutputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillInputPortInformation(int port, vtkInformation *info) override
~ttkIntegralLines() override
This class describes a dynamic size data structure for thread safe computation. It is a linked list o...
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
void setInputOffsets(const SimplexId *const data)
void setDirection(int direction)
void setInputScalarField(void *data)
void setChunkSize(int size)
int preconditionTriangulation(ttk::AbstractTriangulation *triangulation)
void setVertexNumber(const SimplexId &vertexNumber)
void setOutputIntegralLines(std::vector< ttk::ArrayLinkedList< ttk::intgl::IntegralLine, INTEGRAL_LINE_TABULAR_SIZE > > *integralLines)
void setVertexIdentifierScalarField(std::vector< SimplexId > *const data)
void setSeedNumber(const SimplexId &seedNumber)
Triangulation is a class that provides time and memory efficient traversal methods on triangulations ...
AbstractTriangulation * getData()
Triangulation::Type getType() const
COMMON_EXPORTS int MPIsize_
COMMON_EXPORTS int MPIrank_
const char VertexScalarFieldName[]
default name for vertex scalar field
long long int LongSimplexId
Identifier type for simplices of any dimension.
const char MaskScalarFieldName[]
default name for mask scalar field
int SimplexId
Identifier type for simplices of any dimension.
Struct containing the data of an integral line. trajectories: vector of identifiers of each vertex th...
vtkStandardNewMacro(ttkIntegralLines)