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>
17 SetNumberOfInputPorts(1);
18 SetNumberOfOutputPorts(2);
22 vtkInformation *info) {
24 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),
"vtkDataSet");
31 vtkInformation *info) {
32 if(port == 0 || port == 1) {
33 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkPolyData");
39template <
typename scalarType,
typename triangulationType>
40int ttkDiscreteGradient::fillCriticalPoints(
41 vtkPolyData *outputCriticalPoints,
42 vtkDataArray *
const inputScalars,
43 const triangulationType &triangulation) {
48 std::vector<std::array<float, 3>> critPoints_coords;
49 std::vector<char> critPoints_cellDimensions;
50 std::vector<SimplexId> critPoints_cellIds;
51 std::vector<char> critPoints_isOnBoundary;
52 std::vector<SimplexId> critPoints_PLVertexIdentifiers;
55 critPoints_cellIds, critPoints_isOnBoundary,
56 critPoints_PLVertexIdentifiers, triangulation);
57 const auto nPoints = critPoints_coords.size();
61 vtkNew<vtkPoints> points{};
62 points->SetNumberOfPoints(nPoints);
64 vtkNew<vtkSignedCharArray> cellDimensions{};
65 cellDimensions->SetNumberOfComponents(1);
66 cellDimensions->SetName(
"CellDimension");
67 cellDimensions->SetNumberOfTuples(nPoints);
69 vtkNew<ttkSimplexIdTypeArray> cellIds{};
70 cellIds->SetNumberOfComponents(1);
71 cellIds->SetName(
"CellId");
72 cellIds->SetNumberOfTuples(nPoints);
75#ifndef TTK_ENABLE_KAMIKAZE
77 this->
printErr(
"vtkDataArray allocation problem.");
81 cellScalars->SetNumberOfComponents(1);
82 cellScalars->SetName(inputScalars->GetName());
83 cellScalars->SetNumberOfTuples(nPoints);
85 vtkNew<vtkSignedCharArray> isOnBoundary{};
86 isOnBoundary->SetNumberOfComponents(1);
87 isOnBoundary->SetName(
"IsOnBoundary");
88 isOnBoundary->SetNumberOfTuples(nPoints);
90 vtkNew<ttkSimplexIdTypeArray> PLVertexIdentifiers{};
91 PLVertexIdentifiers->SetNumberOfComponents(1);
93 PLVertexIdentifiers->SetNumberOfTuples(nPoints);
95#ifdef TTK_ENABLE_OPENMP
96#pragma omp parallel for num_threads(this->threadNumber_)
98 for(
size_t i = 0; i < nPoints; ++i) {
99 points->SetPoint(i, critPoints_coords[i].data());
100 cellDimensions->SetTuple1(i, critPoints_cellDimensions[i]);
101 cellIds->SetTuple1(i, critPoints_cellIds[i]);
102 cellScalars->SetTuple1(i, scalars[critPoints_PLVertexIdentifiers[i]]);
103 isOnBoundary->SetTuple1(i, critPoints_isOnBoundary[i]);
105 if(ttk::hasInitializedMPI()) {
106 PLVertexIdentifiers->SetTuple1(
107 i, triangulation.getVertexGlobalId(critPoints_PLVertexIdentifiers[i]));
109 PLVertexIdentifiers->SetTuple1(i, critPoints_PLVertexIdentifiers[i]);
112 PLVertexIdentifiers->SetTuple1(i, critPoints_PLVertexIdentifiers[i]);
118 vtkPointData *pointData = outputCriticalPoints->GetPointData();
119#ifndef TTK_ENABLE_KAMIKAZE
121 this->
printErr(
"outputCriticalPoints has no point data");
126 pointData->SetScalars(cellDimensions);
127 pointData->AddArray(cellIds);
128 pointData->AddArray(cellScalars);
129 pointData->AddArray(isOnBoundary);
130 pointData->AddArray(PLVertexIdentifiers);
133 "Extracted critical points", 1.0, tm.getElapsedTime(), this->threadNumber_);
138template <
typename triangulationType>
139int ttkDiscreteGradient::fillGradientGlyphs(
140 vtkPolyData *
const outputGradientGlyphs,
141 const triangulationType &triangulation) {
145 std::vector<std::array<float, 3>> gradientGlyphs_points;
146 std::vector<char> gradientGlyphs_points_pairOrigins;
147 std::vector<char> gradientGlyphs_cells_pairTypes;
148 std::vector<SimplexId> gradientGlyphs_point_ids{};
149 std::vector<char> gradientGlyphs_point_dimensions{};
152 gradientGlyphs_points, gradientGlyphs_points_pairOrigins,
153 gradientGlyphs_cells_pairTypes, gradientGlyphs_point_ids,
154 gradientGlyphs_point_dimensions, triangulation);
156 const auto nPoints = gradientGlyphs_points.size();
158 vtkNew<vtkPoints> points{};
159 points->SetNumberOfPoints(nPoints);
160 vtkNew<vtkSignedCharArray> pairOrigins{};
161 pairOrigins->SetNumberOfComponents(1);
162 pairOrigins->SetName(
"PairOrigin");
163 pairOrigins->SetNumberOfTuples(nPoints);
165#ifdef TTK_ENABLE_OPENMP
166#pragma omp parallel for num_threads(this->threadNumber_)
168 for(
size_t i = 0; i < nPoints; ++i) {
169 points->SetPoint(i, gradientGlyphs_points[i].data());
170 pairOrigins->SetTuple1(i, gradientGlyphs_points_pairOrigins[i]);
172 outputGradientGlyphs->SetPoints(points);
174 const auto nCells = gradientGlyphs_cells_pairTypes.size();
176 vtkNew<vtkIdTypeArray> offsets{}, connectivity{};
177 offsets->SetNumberOfComponents(1);
178 offsets->SetNumberOfTuples(nCells + 1);
179 connectivity->SetNumberOfComponents(1);
180 connectivity->SetNumberOfTuples(2 * nCells);
181 vtkNew<vtkSignedCharArray> pairTypes{};
182 pairTypes->SetNumberOfComponents(1);
183 pairTypes->SetName(
"PairType");
184 pairTypes->SetNumberOfTuples(nCells);
185 vtkNew<ttkSimplexIdTypeArray> cellIds{};
186 cellIds->SetNumberOfComponents(1);
187 cellIds->SetName(
"CellId");
188 cellIds->SetNumberOfTuples(2 * nCells);
189 vtkNew<vtkSignedCharArray> cellDimensions{};
190 cellDimensions->SetNumberOfComponents(1);
191 cellDimensions->SetName(
"CellDimension");
192 cellDimensions->SetNumberOfTuples(2 * nCells);
194#ifdef TTK_ENABLE_OPENMP
195#pragma omp parallel for num_threads(this->threadNumber_)
197 for(
size_t i = 0; i < nCells; ++i) {
198 offsets->SetTuple1(i, 2 * i);
200 connectivity->SetTuple1(2 * i, 2 * i);
201 connectivity->SetTuple1(2 * i + 1, 2 * i + 1);
202 pairTypes->SetTuple1(i, gradientGlyphs_cells_pairTypes[i]);
203 cellIds->SetTuple1(2 * i + 0, gradientGlyphs_point_ids[2 * i + 0]);
204 cellIds->SetTuple1(2 * i + 1, gradientGlyphs_point_ids[2 * i + 1]);
205 cellDimensions->SetTuple1(
206 2 * i + 0, gradientGlyphs_point_dimensions[2 * i + 0]);
207 cellDimensions->SetTuple1(
208 2 * i + 1, gradientGlyphs_point_dimensions[2 * i + 1]);
210 offsets->SetTuple1(nCells, connectivity->GetNumberOfTuples());
212 vtkNew<vtkCellArray> cells{};
213 cells->SetData(offsets, connectivity);
214 outputGradientGlyphs->SetLines(cells);
216 vtkPointData *pointData = outputGradientGlyphs->GetPointData();
217 vtkCellData *cellData = outputGradientGlyphs->GetCellData();
219#ifndef TTK_ENABLE_KAMIKAZE
220 if(pointData ==
nullptr || cellData ==
nullptr) {
221 this->
printErr(
"In outputGradientGlyphs point or cell data");
226 pointData->AddArray(pairOrigins);
227 pointData->AddArray(cellIds);
228 pointData->AddArray(cellDimensions);
229 cellData->SetScalars(pairTypes);
232 "Computed gradient glyphs", 1.0, tm.getElapsedTime(), this->threadNumber_);
238 vtkInformationVector **inputVector,
239 vtkInformationVector *outputVector) {
241 auto input = vtkDataSet::GetData(inputVector[0]);
242 auto outputCriticalPoints = vtkPolyData::GetData(outputVector, 0);
243 auto outputGradientGlyphs = vtkPolyData::GetData(outputVector, 1);
247 int const keepGoing = checkEmptyMPIInput<ttk::Triangulation>(triangulation);
251#ifndef TTK_ENABLE_KAMIKAZE
253 this->
printErr(
"Input pointer is NULL.");
256 if(!outputCriticalPoints or !outputGradientGlyphs) {
257 this->
printErr(
"Output pointer is NULL.");
260 if(!input->GetNumberOfPoints()) {
261 this->
printErr(
"Input has no point.");
268 const auto inputScalars = this->GetInputArrayToProcess(0, input);
270 input, 0, triangulation,
false, 1, this->ForceInputOffsetScalarField);
272 if(inputScalars ==
nullptr || inputOffsets ==
nullptr) {
273 this->
printErr(
"Input scalar arrays are NULL");
279#ifndef TTK_ENABLE_KAMIKAZE
280 if(inputOffsets->GetDataType() != VTK_INT
281 and inputOffsets->GetDataType() != VTK_ID_TYPE) {
282 this->
printErr(
"input offset field type not supported.");
292#ifdef TTK_ENABLE_MPI_TIME
297 (ret = this->buildGradient<TTK_TT>(
298 *
static_cast<TTK_TT *
>(triangulation->getData()),
true)));
299#ifdef TTK_ENABLE_MPI_TIME
303 +
" MPI processes lasted :" + std::to_string(elapsedTime));
307 this->
printErr(
"DiscreteGradient.buildGradient() error code: "
308 + std::to_string(ret));
314 (fillCriticalPoints<VTK_TT, TTK_TT>(
315 outputCriticalPoints, inputScalars,
316 *
static_cast<TTK_TT *
>(triangulation->getData()))));
319 if(ComputeGradientGlyphs) {
321 (fillGradientGlyphs<TTK_TT>(
322 outputGradientGlyphs,
323 *
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.
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
vtkDataArray * GetOrderArray(vtkDataSet *const inputData, const int scalarArrayIdx, ttk::Triangulation *triangulation, const bool getGlobalOrder=false, const int orderArrayIdx=0, const bool enforceOrderArrayIdx=false)
TTK VTK-filter that wraps the discreteGradient processing package.
int FillInputPortInformation(int port, vtkInformation *info) override
int FillOutputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) 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
void setInputOffsets(const SimplexId *const data)
int setGradientGlyphs(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 setInputScalarField(const void *const data, const size_t mTime)
void preconditionTriangulation(AbstractTriangulation *const data)
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
COMMON_EXPORTS int MPIsize_
COMMON_EXPORTS int MPIrank_
const char VertexScalarFieldName[]
default name for vertex scalar field
vtkStandardNewMacro(ttkDiscreteGradient)
#define ttkVtkTemplateMacro(dataType, triangulationType, call)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)