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]];
97 vtkMultiBlockDataSet *input,
98 vtkMultiBlockDataSet *output,
101 int n_blocks = input->GetNumberOfBlocks();
102 std::vector<T> inputValues;
103 for(
int i = 0; i < n_blocks; i++) {
104 vtkDataSet *block = vtkDataSet::SafeDownCast(input->GetBlock(i));
105 vtkDataArray *inputScalarField = this->GetInputArrayToProcess(0, block);
106 int nValues = inputScalarField->GetNumberOfTuples();
107 const T *
const inputScalarFieldPtr
110 inputValues.end(), inputScalarFieldPtr, inputScalarFieldPtr + nValues);
113 TTK_PSORT(nThreads, inputValues.begin(), inputValues.end());
114 const auto last = std::unique(inputValues.begin(), inputValues.end());
115 inputValues.erase(last, inputValues.end());
116 std::vector<T> shuffledValues(inputValues.size());
118 std::iota(shuffledValues.begin(), shuffledValues.end(), T{});
120 std::copy(inputValues.begin(), inputValues.end(), shuffledValues.begin());
123 std::mt19937 random_engine{};
124 random_engine.seed(RandomSeed);
130 std::map<T, T> originalToShuffledValues{};
131 for(
size_t i = 0; i < inputValues.size(); ++i) {
132 originalToShuffledValues[inputValues[i]] = shuffledValues[i];
136#ifdef TTK_ENABLE_OPENMP
137#pragma omp parallel for num_threads(nThreads)
139 for(
int i = 0; i < n_blocks; ++i) {
140 vtkDataSet *block = vtkDataSet::SafeDownCast(input->GetBlock(i));
141 vtkDataArray *inputScalarField = this->GetInputArrayToProcess(0, block);
142 int nValues = inputScalarField->GetNumberOfTuples();
146 outputArray->SetName(inputScalarField->GetName());
147 outputArray->SetNumberOfComponents(1);
148 outputArray->SetNumberOfTuples(inputScalarField->GetNumberOfTuples());
149 T *
const inputArrayPtr
151 T *
const outputArrayPtr
153 for(
int j = 0; j < nValues; ++j) {
154 T newValue = originalToShuffledValues[inputArrayPtr[j]];
155 outputArrayPtr[j] = newValue;
158 vtkDataSet *outputBlock = vtkDataSet::SafeDownCast(output->GetBlock(i));
159 if(block->GetPointData()->GetArray(inputScalarField->GetName())) {
160 outputBlock->GetPointData()->AddArray(outputArray);
162 outputBlock->GetCellData()->AddArray(outputArray);
170 vtkInformationVector **inputVector,
171 vtkInformationVector *outputVector) {
176 = vtkDataSet::SafeDownCast(vtkDataSet::GetData(inputVector[0]));
178 vtkDataSet *output = vtkDataSet::GetData(outputVector);
179 output->ShallowCopy(input);
187 vtkDataArray *inputScalarField
188 = this->GetInputArrayToProcess(0, inputVector);
190 if(!inputScalarField) {
191 printErr(
"Could not retrieve mandatory input array :(");
195 bool isPointData =
false;
196 if(input->GetPointData()->GetArray(inputScalarField->GetName())
197 == inputScalarField) {
201 this->
printMsg(
"Shuffling " + std::string{isPointData ?
"vertex" :
"cell"}
202 +
" field `" + std::string{inputScalarField->GetName()}
208 outputArray->SetName(inputScalarField->GetName());
209 outputArray->SetNumberOfComponents(1);
210 outputArray->SetNumberOfTuples(inputScalarField->GetNumberOfTuples());
212 switch(outputArray->GetDataType()) {
216 outputArray->GetNumberOfTuples(), this->RandomSeed, this->CompactRange,
217 this->threadNumber_));
221 output->GetPointData()->AddArray(outputArray);
223 output->GetCellData()->AddArray(outputArray);
225 printMsg(
"Processed " + std::to_string(outputArray->GetNumberOfTuples())
226 + (isPointData ?
" vertices." :
" cells."),
232 vtkMultiBlockDataSet *input_mb = vtkMultiBlockDataSet::SafeDownCast(
233 vtkMultiBlockDataSet::GetData(inputVector[0]));
234 vtkMultiBlockDataSet *output_mb
235 = vtkMultiBlockDataSet::GetData(outputVector);
236 output_mb->ShallowCopy(input_mb);
240 int n_blocks = input_mb->GetNumberOfBlocks();
244 for(
int i = 0; i < n_blocks; i++) {
245 vtkDataSet *block = vtkDataSet::SafeDownCast(input_mb->GetBlock(i));
247 printMsg(
"Block " + std::to_string(i) +
" invalid.");
248 vtkDataArray *inputScalarField = this->GetInputArrayToProcess(0, block);
250 if(!inputScalarField) {
252 "Block " + std::to_string(i)
253 +
" does not have the required input scalar field as data array.");
258 currentType = inputScalarField->GetDataType();
261 if(currentType != inputScalarField->GetDataType()) {
262 printErr(
"All block's input scalar field must have the same type.");
267 switch(currentType) {
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)