4#include <vtkCellData.h>
5#include <vtkDataArray.h>
7#include <vtkInformation.h>
8#include <vtkObjectFactory.h>
9#include <vtkPointData.h>
22 this->SetNumberOfInputPorts(1);
23 this->SetNumberOfOutputPorts(1);
29 vtkInformation *info) {
31 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),
"vtkDataSet");
38 vtkInformation *info) {
51 const bool compactRange,
52 const int nThreads = 1) {
55 std::vector<T> inputValues(inputField, inputField + nValues);
58 TTK_PSORT(nThreads, inputValues.begin(), inputValues.end());
59 const auto last = std::unique(inputValues.begin(), inputValues.end());
60 inputValues.erase(last, inputValues.end());
63 std::vector<T> shuffledValues(inputValues.size());
65 std::iota(shuffledValues.begin(), shuffledValues.end(), T{});
67 std::copy(inputValues.begin(), inputValues.end(), shuffledValues.begin());
71 std::mt19937 random_engine{};
72 random_engine.seed(seed);
78 std::map<T, T> originalToShuffledValues{};
79 for(
size_t i = 0; i < inputValues.size(); ++i) {
80 originalToShuffledValues[inputValues[i]] = shuffledValues[i];
84#ifdef TTK_ENABLE_OPENMP
85#pragma omp parallel for num_threads(nThreads)
87 for(
int i = 0; i < nValues; ++i) {
88 outputField[i] = originalToShuffledValues[inputField[i]];
96 vtkInformationVector **inputVector,
97 vtkInformationVector *outputVector) {
101 bool isPointData =
false;
103 vtkDataSet *input = vtkDataSet::GetData(inputVector[0]);
104 vtkDataSet *output = vtkDataSet::GetData(outputVector);
108 output->ShallowCopy(input);
114 vtkDataArray *inputScalarField = this->GetInputArrayToProcess(0, inputVector);
116 if(!inputScalarField) {
117 printErr(
"Could not retrieve mandatory input array :(");
121 if(input->GetPointData()->GetArray(inputScalarField->GetName())
122 == inputScalarField) {
126 this->
printMsg(
"Shuffling " + std::string{isPointData ?
"vertex" :
"cell"}
127 +
" field `" + std::string{inputScalarField->GetName()}
133 outputArray->SetName(inputScalarField->GetName());
134 outputArray->SetNumberOfComponents(1);
135 outputArray->SetNumberOfTuples(inputScalarField->GetNumberOfTuples());
137 switch(outputArray->GetDataType()) {
141 outputArray->GetNumberOfTuples(), this->RandomSeed, this->CompactRange,
142 this->threadNumber_));
146 output->GetPointData()->AddArray(outputArray);
148 output->GetCellData()->AddArray(outputArray);
150 printMsg(
"Processed " + std::to_string(outputArray->GetNumberOfTuples())
151 + (isPointData ?
" vertices." :
" cells."),
#define TTK_FORCE_USE(x)
Force the compiler to use the function/method parameter.
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
#define TTK_PSORT(NTHREADS,...)
Parallel sort macro.
static vtkInformationIntegerKey * SAME_DATA_TYPE_AS_INPUT_PORT()
TTK VTK-filter that randomly shuffles segmentation identifiers.
ttkIdentifierRandomizer()
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillInputPortInformation(int port, vtkInformation *info) override
int FillOutputPortInformation(int port, vtkInformation *info) override
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
void setDebugMsgPrefix(const std::string &prefix)
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
void shuffle(std::vector< T > &toShuffle, U &&rng)
Platform-independent alternative to std::shuffle implementing the Fisher-Yates shuffle algorithm.
vtkStandardNewMacro(ttkIdentifierRandomizer)
int shuffleScalarFieldValues(const T *const inputField, T *const outputField, const int nValues, const int seed, const bool compactRange, const int nThreads=1)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)