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
|
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
#include "vtkHyperTreeGridRemoveGhostCells.h"
#include "vtkBitArray.h"
#include "vtkCellData.h"
#include "vtkHyperTree.h"
#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridNonOrientedCursor.h"
#include "vtkInformation.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkUnsignedCharArray.h"
VTK_ABI_NAMESPACE_BEGIN
vtkStandardNewMacro(vtkHyperTreeGridRemoveGhostCells);
namespace
{
/**
* Recursively process the tree to mask ghost cells. Return true if the current cell has been
* masked (i.e. already masked in inMask, ghost in inGhost, or all children masked and/or ghost).
*/
bool RecursivelyMaskGhost(
vtkHyperTreeGridNonOrientedCursor* cursor, vtkBitArray* inMask, vtkUnsignedCharArray* inGhost)
{
vtkIdType currentId = cursor->GetGlobalNodeIndex();
cursor->SetMask(false);
if (inMask && inMask->GetValue(currentId))
{
cursor->SetMask(true);
return true;
}
if (inGhost->GetTuple1(currentId))
{
cursor->SetMask(true);
return true;
}
bool allGhostOrMasked = false;
if (!cursor->IsLeaf())
{
for (int child = 0; child < cursor->GetNumberOfChildren(); ++child)
{
cursor->ToChild(child);
// Coarse cell is masked if it contains only ghosts and/or masked children
allGhostOrMasked = allGhostOrMasked && RecursivelyMaskGhost(cursor, inMask, inGhost);
cursor->ToParent();
}
}
cursor->SetMask(allGhostOrMasked);
return allGhostOrMasked;
}
}
//------------------------------------------------------------------------------
vtkHyperTreeGridRemoveGhostCells::vtkHyperTreeGridRemoveGhostCells()
{
this->AppropriateOutput = true;
}
//------------------------------------------------------------------------------
void vtkHyperTreeGridRemoveGhostCells::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
//------------------------------------------------------------------------------
int vtkHyperTreeGridRemoveGhostCells::ProcessTrees(vtkHyperTreeGrid* input, vtkDataObject* outputDO)
{
// Downcast output data object to hyper tree grid
vtkHyperTreeGrid* output = vtkHyperTreeGrid::SafeDownCast(outputDO);
if (!output)
{
vtkErrorMacro("Incorrect type of output: " << outputDO->GetClassName());
return 0;
}
output->ShallowCopy(input);
// Retrieve ghost array
if (!input->HasAnyGhostCells())
{
vtkWarningMacro(<< "Input does not have a ghost array. Filter will do nothing.");
output->SetMask(input->GetMask());
return 1;
}
// Retrieve and copy input mask if it exists
vtkNew<vtkBitArray> outMask;
if (input->HasMask())
{
outMask->DeepCopy(input->GetMask());
}
else
{
outMask->SetNumberOfTuples(output->GetNumberOfCells());
}
output->SetMask(outMask);
// Iterate over output HTG and mask ghost cells
vtkIdType inIndex = 0;
vtkHyperTreeGrid::vtkHyperTreeGridIterator it;
output->InitializeTreeIterator(it);
vtkNew<vtkHyperTreeGridNonOrientedCursor> outCursor;
while (it.GetNextTree(inIndex))
{
if (this->CheckAbort())
{
break;
}
output->InitializeNonOrientedCursor(outCursor, inIndex, true);
::RecursivelyMaskGhost(outCursor, input->GetMask(), input->GetGhostCells());
}
// Remove ghost cells array
output->GetCellData()->RemoveArray(input->GetGhostCells()->GetName());
return 1;
}
VTK_ABI_NAMESPACE_END
|