1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
#include "vtkCellData.h"
#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridNonOrientedCursor.h"
#include "vtkHyperTreeGridRemoveGhostCells.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkTestUtilities.h"
#include "vtkUnsignedCharArray.h"
#include "vtkXMLHyperTreeGridReader.h"
#include "vtkLogger.h"
namespace
{
/**
* Recursively process the Hyper Tree, add ghost cell ids from the ghost array
* to the ghostIds vector, and add non-ghost cell ids to nonGhostIds
*/
void FillGhostIdsVectors(vtkHyperTreeGridNonOrientedCursor* cursor,
std::vector<vtkIdType>& ghostIds, std::vector<vtkIdType>& nonGhostIds,
vtkUnsignedCharArray* ghostArray)
{
vtkIdType currentId = cursor->GetGlobalNodeIndex();
if (cursor->IsMasked())
{
return;
}
if (ghostArray->GetTuple1(currentId))
{
ghostIds.emplace_back(currentId);
return;
}
else
{
nonGhostIds.emplace_back(currentId);
}
if (!cursor->IsLeaf())
{
for (int child = 0; child < cursor->GetNumberOfChildren(); ++child)
{
cursor->ToChild(child);
::FillGhostIdsVectors(cursor, ghostIds, nonGhostIds, ghostArray);
cursor->ToParent();
}
}
}
/**
* Recursively process the Hyper Tree and add the not hidden cell ids to a vector
*/
void FillUnmaskedIdsVector(
vtkHyperTreeGridNonOrientedCursor* cursor, std::vector<vtkIdType>& unmaskedIds)
{
vtkIdType currentId = cursor->GetGlobalNodeIndex();
if (!cursor->IsMasked())
{
unmaskedIds.emplace_back(currentId);
}
if (!cursor->IsLeaf() && !cursor->IsMasked())
{
for (int child = 0; child < cursor->GetNumberOfChildren(); ++child)
{
cursor->ToChild(child);
::FillUnmaskedIdsVector(cursor, unmaskedIds);
cursor->ToParent();
}
}
}
}
int TestHyperTreeGridRemoveGhostCells(int argc, char* argv[])
{
int ret = EXIT_SUCCESS;
// Read HTG file containing ghost cells
vtkNew<vtkXMLHyperTreeGridReader> reader;
char* ghostFile = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/HTG/ghost.htg");
reader->SetFileName(ghostFile);
delete[] ghostFile;
// Remove ghost cells from input HTG
vtkNew<vtkHyperTreeGridRemoveGhostCells> removeGhosts;
removeGhosts->SetInputConnection(reader->GetOutputPort());
removeGhosts->Update();
vtkHyperTreeGrid* inputHTG = vtkHyperTreeGrid::SafeDownCast(reader->GetOutput());
vtkHyperTreeGrid* outputHTG = removeGhosts->GetHyperTreeGridOutput();
// Go through the input HTG and collect leaf ghost cells and unmasked non-ghost cells.
std::vector<vtkIdType> inputGhostIds;
std::vector<vtkIdType> inputNonGhostIds;
inputGhostIds.reserve(inputHTG->GetNumberOfCells());
inputNonGhostIds.reserve(inputHTG->GetNumberOfCells());
vtkUnsignedCharArray* inputGhostArray = inputHTG->GetGhostCells();
vtkIdType inIndex = 0;
vtkHyperTreeGrid::vtkHyperTreeGridIterator it;
inputHTG->InitializeTreeIterator(it);
vtkNew<vtkHyperTreeGridNonOrientedCursor> cursor;
while (it.GetNextTree(inIndex))
{
inputHTG->InitializeNonOrientedCursor(cursor, inIndex, true);
::FillGhostIdsVectors(cursor, inputGhostIds, inputNonGhostIds, inputGhostArray);
}
// Go through the output and collect unmasked cells
std::vector<vtkIdType> outputUnmasked;
outputUnmasked.reserve(outputHTG->GetNumberOfCells());
outputHTG->InitializeTreeIterator(it);
while (it.GetNextTree(inIndex))
{
outputHTG->InitializeNonOrientedCursor(cursor, inIndex, true);
::FillUnmaskedIdsVector(cursor, outputUnmasked);
}
// All input ghost cells should be masked in the output
for (vtkIdType ghostId : inputGhostIds)
{
if (std::find(outputUnmasked.begin(), outputUnmasked.end(), ghostId) != outputUnmasked.end())
{
vtkErrorWithObjectMacro(
nullptr, << "Ghost cell " << ghostId << " remains unmasked in output HTG but should be.");
ret = EXIT_FAILURE;
}
}
// All input unmasked non-ghost cells should stay unmasked in the output
for (vtkIdType nonGhostId : inputNonGhostIds)
{
if (std::find(outputUnmasked.begin(), outputUnmasked.end(), nonGhostId) == outputUnmasked.end())
{
vtkErrorWithObjectMacro(
nullptr, << "Cell " << nonGhostId << " has been masked in output HTG but shouldn't.");
ret = EXIT_FAILURE;
}
}
// The extracted cells don't have a ghost cell array
if (outputHTG->GetGhostCells() != nullptr)
{
vtkErrorWithObjectMacro(
nullptr, << "Extracted ghost cells should not have a ghost array anymore.");
ret = EXIT_FAILURE;
}
return ret;
}
|