5#include <vtkCellData.h>
6#include <vtkIdTypeArray.h>
7#include <vtkInformation.h>
8#include <vtkIntArray.h>
10#include <vtkPointData.h>
11#include <vtkPolyData.h>
12#include <vtkSignedCharArray.h>
13#include <vtkSmartPointer.h>
18 SetNumberOfInputPorts(1);
19 SetNumberOfOutputPorts(2);
23 vtkInformation *info) {
25 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),
"vtkDataSet");
32 vtkInformation *info) {
33 if(port == 0 || port == 1) {
34 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkPolyData");
40template <
typename scalarType,
typename triangulationType>
41int ttkDiscreteVectorField::fillCriticalPoints(
42 vtkPolyData *outputCriticalPoints,
const triangulationType &triangulation) {
47 std::vector<std::array<float, 3>> critPoints_coords;
48 std::vector<char> critPoints_cellDimensions;
49 std::vector<SimplexId> critPoints_cellIds;
50 std::vector<char> critPoints_isOnBoundary;
51 std::vector<SimplexId> critPoints_PLVertexIdentifiers;
54 critPoints_coords, critPoints_cellDimensions, critPoints_cellIds,
55 critPoints_isOnBoundary, critPoints_PLVertexIdentifiers, triangulation);
56 const auto nPoints = critPoints_coords.size();
58 vtkNew<vtkPoints> points{};
59 points->SetNumberOfPoints(nPoints);
61 vtkNew<vtkSignedCharArray> cellDimensions{};
62 cellDimensions->SetNumberOfComponents(1);
63 cellDimensions->SetName(
"CellDimension");
64 cellDimensions->SetNumberOfTuples(nPoints);
66 vtkNew<ttkSimplexIdTypeArray> cellIds{};
67 cellIds->SetNumberOfComponents(1);
68 cellIds->SetName(
"CellId");
69 cellIds->SetNumberOfTuples(nPoints);
71 vtkNew<vtkSignedCharArray> isOnBoundary{};
72 isOnBoundary->SetNumberOfComponents(1);
73 isOnBoundary->SetName(
"IsOnBoundary");
74 isOnBoundary->SetNumberOfTuples(nPoints);
76 vtkNew<ttkSimplexIdTypeArray> PLVertexIdentifiers{};
77 PLVertexIdentifiers->SetNumberOfComponents(1);
79 PLVertexIdentifiers->SetNumberOfTuples(nPoints);
81#ifdef TTK_ENABLE_OPENMP
82#pragma omp parallel for num_threads(this->threadNumber_)
84 for(
size_t i = 0; i < nPoints; ++i) {
85 points->SetPoint(i, critPoints_coords[i].data());
86 cellDimensions->SetTuple1(i, critPoints_cellDimensions[i]);
87 cellIds->SetTuple1(i, critPoints_cellIds[i]);
88 isOnBoundary->SetTuple1(i, critPoints_isOnBoundary[i]);
90 if(ttk::hasInitializedMPI()) {
91 PLVertexIdentifiers->SetTuple1(
92 i, triangulation.getVertexGlobalId(critPoints_PLVertexIdentifiers[i]));
94 PLVertexIdentifiers->SetTuple1(i, critPoints_PLVertexIdentifiers[i]);
97 PLVertexIdentifiers->SetTuple1(i, critPoints_PLVertexIdentifiers[i]);
103 vtkPointData *pointData = outputCriticalPoints->GetPointData();
104#ifndef TTK_ENABLE_KAMIKAZE
106 this->
printErr(
"outputCriticalPoints has no point data");
111 pointData->SetScalars(cellDimensions);
112 pointData->AddArray(cellIds);
114 pointData->AddArray(isOnBoundary);
115 pointData->AddArray(PLVertexIdentifiers);
118 "Extracted critical points", 1.0, tm.getElapsedTime(), this->threadNumber_);
123template <
typename triangulationType>
124int ttkDiscreteVectorField::fillVectorGlyphs(
125 vtkPolyData *
const outputVectorGlyphs,
126 const triangulationType &triangulation) {
130 std::vector<std::array<float, 3>> vectorGlyphs_points;
131 std::vector<char> vectorGlyphs_points_pairOrigins;
132 std::vector<char> vectorGlyphs_cells_pairTypes;
133 std::vector<SimplexId> vectorGlyphs_point_ids{};
134 std::vector<char> vectorGlyphs_point_dimensions{};
136 this->
setVectorGlyphs(vectorGlyphs_points, vectorGlyphs_points_pairOrigins,
137 vectorGlyphs_cells_pairTypes, vectorGlyphs_point_ids,
138 vectorGlyphs_point_dimensions, triangulation);
140 const auto nPoints = vectorGlyphs_points.size();
142 vtkNew<vtkPoints> points{};
143 points->SetNumberOfPoints(nPoints);
144 vtkNew<vtkSignedCharArray> pairOrigins{};
145 pairOrigins->SetNumberOfComponents(1);
146 pairOrigins->SetName(
"PairOrigin");
147 pairOrigins->SetNumberOfTuples(nPoints);
149#ifdef TTK_ENABLE_OPENMP
150#pragma omp parallel for num_threads(this->threadNumber_)
152 for(
size_t i = 0; i < nPoints; ++i) {
153 points->SetPoint(i, vectorGlyphs_points[i].data());
154 pairOrigins->SetTuple1(i, vectorGlyphs_points_pairOrigins[i]);
156 outputVectorGlyphs->SetPoints(points);
158 const auto nCells = vectorGlyphs_cells_pairTypes.size();
160 vtkNew<vtkIdTypeArray> offsets{}, connectivity{};
161 offsets->SetNumberOfComponents(1);
162 offsets->SetNumberOfTuples(nCells + 1);
163 connectivity->SetNumberOfComponents(1);
164 connectivity->SetNumberOfTuples(2 * nCells);
165 vtkNew<vtkSignedCharArray> pairTypes{};
166 pairTypes->SetNumberOfComponents(1);
167 pairTypes->SetName(
"PairType");
168 pairTypes->SetNumberOfTuples(nCells);
169 vtkNew<ttkSimplexIdTypeArray> cellIds{};
170 cellIds->SetNumberOfComponents(1);
171 cellIds->SetName(
"CellId");
172 cellIds->SetNumberOfTuples(2 * nCells);
173 vtkNew<vtkSignedCharArray> cellDimensions{};
174 cellDimensions->SetNumberOfComponents(1);
175 cellDimensions->SetName(
"CellDimension");
176 cellDimensions->SetNumberOfTuples(2 * nCells);
178#ifdef TTK_ENABLE_OPENMP
179#pragma omp parallel for num_threads(this->threadNumber_)
181 for(
size_t i = 0; i < nCells; ++i) {
182 offsets->SetTuple1(i, 2 * i);
184 connectivity->SetTuple1(2 * i, 2 * i);
185 connectivity->SetTuple1(2 * i + 1, 2 * i + 1);
186 pairTypes->SetTuple1(i, vectorGlyphs_cells_pairTypes[i]);
187 cellIds->SetTuple1(2 * i + 0, vectorGlyphs_point_ids[2 * i + 0]);
188 cellIds->SetTuple1(2 * i + 1, vectorGlyphs_point_ids[2 * i + 1]);
189 cellDimensions->SetTuple1(
190 2 * i + 0, vectorGlyphs_point_dimensions[2 * i + 0]);
191 cellDimensions->SetTuple1(
192 2 * i + 1, vectorGlyphs_point_dimensions[2 * i + 1]);
194 offsets->SetTuple1(nCells, connectivity->GetNumberOfTuples());
196 vtkNew<vtkCellArray> cells{};
197 cells->SetData(offsets, connectivity);
198 outputVectorGlyphs->SetLines(cells);
200 vtkPointData *pointData = outputVectorGlyphs->GetPointData();
201 vtkCellData *cellData = outputVectorGlyphs->GetCellData();
203#ifndef TTK_ENABLE_KAMIKAZE
204 if(pointData ==
nullptr || cellData ==
nullptr) {
205 this->
printErr(
"In outputVectorGlyphs point or cell data");
210 pointData->AddArray(pairOrigins);
211 pointData->AddArray(cellIds);
212 pointData->AddArray(cellDimensions);
213 cellData->SetScalars(pairTypes);
216 "Computed Vector Glyphs", 1.0, tm.getElapsedTime(), this->threadNumber_);
222 vtkInformationVector **inputVector,
223 vtkInformationVector *outputVector) {
225 auto input = vtkDataSet::GetData(inputVector[0]);
226 auto outputCriticalPoints = vtkPolyData::GetData(outputVector, 0);
227 auto outputVectorGlyphs = vtkPolyData::GetData(outputVector, 1);
235#ifndef TTK_ENABLE_KAMIKAZE
237 this->
printErr(
"Input pointer is NULL.");
240 if(!outputCriticalPoints or !outputVectorGlyphs) {
241 this->
printErr(
"Output pointer is NULL.");
244 if(!input->GetNumberOfPoints()) {
245 this->
printErr(
"Input has no point.");
252 const auto inputVectors = this->GetInputArrayToProcess(0, input);
254 if(inputVectors ==
nullptr) {
255 this->
printErr(
"Input vector array is NULL");
258 if(this->GetInputArrayAssociation(0, inputVector) != 0) {
259 this->
printErr(
"Input array needs to be a point data array.");
262 if(inputVectors->GetNumberOfComponents() != 3) {
263 this->
printErr(
"Input array needs to be a vector array(3D).");
272#ifdef TTK_ENABLE_MPI_TIME
277 (ret = this->buildField<VTK_TT, TTK_TT>(
278 *
static_cast<TTK_TT *
>(triangulation->getData()))));
279#ifdef TTK_ENABLE_MPI_TIME
283 +
" MPI processes lasted :" + std::to_string(elapsedTime));
287 this->
printErr(
"DiscreteVectorField.buildField() error code: "
288 + std::to_string(ret));
294 inputVectors->GetDataType(), triangulation->getType(),
295 (fillCriticalPoints<VTK_TT, TTK_TT>(
296 outputCriticalPoints, *
static_cast<TTK_TT *
>(triangulation->getData()))));
299 if(ComputeVectorGlyphs) {
301 triangulation->getType(),
302 (fillVectorGlyphs<TTK_TT>(
303 outputVectorGlyphs, *
static_cast<TTK_TT *
>(triangulation->getData()))));
#define ttkTemplateMacro(triangulationType, call)
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
int checkEmptyMPIInput(inputType *input)
This method tests whether the input is a nullptr. If the computation is being done on multiple proces...
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
TTK VTK-filter that wraps the discreteVectorField processing package.
int FillOutputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillInputPortInformation(int port, vtkInformation *info) override
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
static int CellVertexFromPoints(vtkDataSet *const dataSet, vtkPoints *const points)
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
int setCriticalPoints(const std::array< std::vector< SimplexId >, 4 > &criticalCellsByDim, std::vector< std::array< float, 3 > > &points, std::vector< char > &cellDimensions, std::vector< SimplexId > &cellIds, std::vector< char > &isOnBoundary, std::vector< SimplexId > &PLVertexIdentifiers, const triangulationType &triangulation) const
int setVectorGlyphs(std::vector< std::array< float, 3 > > &points, std::vector< char > &points_pairOrigins, std::vector< char > &cells_pairTypes, std::vector< SimplexId > &cellsIds, std::vector< char > &cellsDimensions, const triangulationType &triangulation) const
void preconditionTriangulation(AbstractTriangulation *const data)
void setInputVectorField(const void *const data, const size_t mTime)
COMMON_EXPORTS int MPIsize_
COMMON_EXPORTS int MPIrank_
const char VertexScalarFieldName[]
default name for vertex scalar field
vtkStandardNewMacro(ttkDiscreteVectorField)
#define ttkVtkTemplateMacro(dataType, triangulationType, call)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)