// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkHyperTreeGridGeometryUnlimitedLevelEntry.h" #include "vtkBitArray.h" #include "vtkHyperTree.h" #include "vtkHyperTreeGrid.h" #include "vtkHyperTreeGridNonOrientedGeometryCursor.h" #include "vtkHyperTreeGridScales.h" #include #include VTK_ABI_NAMESPACE_BEGIN //------------------------------------------------------------------------------ void vtkHyperTreeGridGeometryUnlimitedLevelEntry::Initialize( vtkHyperTree* tree, unsigned int level, vtkIdType index, const double* origin) { this->Tree = tree; this->Level = level; this->Index = index; for (unsigned int d = 0; d < 3; ++d) { this->Origin[d] = origin[d]; } } //------------------------------------------------------------------------------ vtkHyperTree* vtkHyperTreeGridGeometryUnlimitedLevelEntry::Initialize( vtkHyperTreeGrid* grid, vtkIdType treeIndex, bool create) { this->Tree = grid->GetTree(treeIndex, create); grid->GetLevelZeroOriginFromIndex(treeIndex, this->Origin); return this->Tree; } //------------------------------------------------------------------------------ void vtkHyperTreeGridGeometryUnlimitedLevelEntry::PrintSelf(ostream& os, vtkIndent indent) { os << indent << "--vtkHyperTreeGridGeometryUnlimitedLevelEntry--" << endl; this->Tree->PrintSelf(os, indent); os << indent << "Level:" << this->Level << endl; os << indent << "Index:" << this->Index << endl; os << indent << "LastRealIndex:" << this->LastRealIndex << endl; os << indent << "LastRealLevel:" << this->LastRealLevel << endl; os << indent << "Origin:" << this->Origin[0] << ", " << this->Origin[1] << ", " << this->Origin[2] << endl; } //------------------------------------------------------------------------------ void vtkHyperTreeGridGeometryUnlimitedLevelEntry::Dump(ostream& os) { os << "Level:" << this->Level << endl; os << "Index:" << this->Index << endl; os << "LastRealIndex:" << this->LastRealIndex << endl; os << "LastRealLevel:" << this->LastRealLevel << endl; os << "Origin:" << this->Origin[0] << ", " << this->Origin[1] << ", " << this->Origin[2] << endl; } //------------------------------------------------------------------------------ vtkIdType vtkHyperTreeGridGeometryUnlimitedLevelEntry::GetGlobalNodeIndex() const { return this->Tree ? this->Tree->GetGlobalIndexFromLocal(this->LastRealIndex) : vtkHyperTreeGrid::InvalidIndex; } //------------------------------------------------------------------------------ void vtkHyperTreeGridGeometryUnlimitedLevelEntry::SetGlobalIndexStart(vtkIdType index) { assert("pre: not_tree" && this->Tree); this->Tree->SetGlobalIndexStart(index); } //------------------------------------------------------------------------------ void vtkHyperTreeGridGeometryUnlimitedLevelEntry::SetGlobalIndexFromLocal(vtkIdType index) { assert("pre: not_tree" && this->Tree); this->Tree->SetGlobalIndexFromLocal(this->Index, index); } //------------------------------------------------------------------------------ void vtkHyperTreeGridGeometryUnlimitedLevelEntry::SetMask(const vtkHyperTreeGrid* grid, bool value) { assert("pre: not_tree" && this->Tree); const_cast(grid)->GetMask()->InsertTuple1(this->GetGlobalNodeIndex(), value); } //------------------------------------------------------------------------------ bool vtkHyperTreeGridGeometryUnlimitedLevelEntry::IsMasked(const vtkHyperTreeGrid* grid) const { if (this->Tree && const_cast(grid)->HasMask()) { return const_cast(grid)->GetMask()->GetValue(this->GetGlobalNodeIndex()) != 0; } return false; } //------------------------------------------------------------------------------ bool vtkHyperTreeGridGeometryUnlimitedLevelEntry::IsLeaf(const vtkHyperTreeGrid* grid) const { if (this->Level >= const_cast(grid)->GetDepthLimiter()) { return true; } return false; } //------------------------------------------------------------------------------ bool vtkHyperTreeGridGeometryUnlimitedLevelEntry::IsRealLeaf(const vtkHyperTreeGrid* grid) const { if (this->Level == const_cast(grid)->GetDepthLimiter()) { return true; } return this->Index == this->LastRealIndex && this->Tree->IsLeaf(this->Index); } //------------------------------------------------------------------------------ bool vtkHyperTreeGridGeometryUnlimitedLevelEntry::IsVirtualLeaf(const vtkHyperTreeGrid* grid) const { if (this->Level > const_cast(grid)->GetDepthLimiter()) { return true; } return this->LastRealIndex != this->Index; } //------------------------------------------------------------------------------ bool vtkHyperTreeGridGeometryUnlimitedLevelEntry::IsTerminalNode(const vtkHyperTreeGrid* grid) const { if (this->Level + 1 == const_cast(grid)->GetDepthLimiter()) { return true; } return false; } //------------------------------------------------------------------------------ void vtkHyperTreeGridGeometryUnlimitedLevelEntry::ToChild( const vtkHyperTreeGrid* grid, unsigned char ichild) { assert("pre: not_tree" && this->Tree); assert( "pre: depth_limiter" && this->Level <= const_cast(grid)->GetDepthLimiter()); assert("pre: is_masked" && !this->IsMasked(grid)); const double* sizeChild = this->Tree->GetScales()->ComputeScale(this->Level + 1); size_t indexMax = 0; this->Tree->GetElderChildIndexArray(indexMax); if (this->Index >= 0 && this->Index < static_cast(indexMax)) { const vtkIdType elder = this->Tree->GetElderChildIndex(this->Index); if (elder != static_cast(std::numeric_limits::max())) { this->Index = elder + ichild; this->LastRealIndex = this->Index; this->LastRealLevel = this->Level + 1; } else { // first virtual cell this->Index = vtkHyperTreeGrid::InvalidIndex; } } else { // cell already virtual this->Index = vtkHyperTreeGrid::InvalidIndex; } // Divide cell size and translate origin per template parameter switch (this->Tree->GetNumberOfChildren()) { case 2: // dimension = 1, branch factor = 2 { unsigned int axis = grid->GetOrientation(); this->Origin[axis] += (ichild & 1) * sizeChild[axis]; break; } case 3: // dimension = 1, branch factor = 3 { unsigned int axis = grid->GetOrientation(); this->Origin[axis] += (ichild % 3) * sizeChild[axis]; break; } case 4: // dimension = 2, branch factor = 2 { unsigned int axis1 = 0; unsigned int axis2 = 1; switch (grid->GetOrientation()) { case 0: axis1 = 1; [[fallthrough]]; case 1: axis2 = 2; } this->Origin[axis1] += (ichild & 1) * sizeChild[axis1]; this->Origin[axis2] += ((ichild & 2) >> 1) * sizeChild[axis2]; break; } case 9: // dimension = 2, branch factor = 3 { unsigned int axis1 = 0; unsigned int axis2 = 1; switch (grid->GetOrientation()) { case 0: axis1 = 1; [[fallthrough]]; case 1: axis2 = 2; } this->Origin[axis1] += (ichild % 3) * sizeChild[axis1]; this->Origin[axis2] += ((ichild % 9) / 3) * sizeChild[axis2]; break; } case 8: // dimension = 3, branch factor = 2 { this->Origin[0] += (ichild & 1) * sizeChild[0]; this->Origin[1] += ((ichild & 2) >> 1) * sizeChild[1]; this->Origin[2] += ((ichild & 4) >> 2) * sizeChild[2]; break; } case 27: // dimension = 3, branch factor = 3 { this->Origin[0] += (ichild % 3) * sizeChild[0]; this->Origin[1] += ((ichild % 9) / 3) * sizeChild[1]; this->Origin[2] += (ichild / 9) * sizeChild[2]; break; } } this->Level++; } //------------------------------------------------------------------------------ void vtkHyperTreeGridGeometryUnlimitedLevelEntry::GetBounds(double bounds[6]) const { assert("pre: not_tree" && this->Tree); const double* sizeChild = this->Tree->GetScales()->ComputeScale(this->Level); // Compute bounds bounds[0] = this->Origin[0]; bounds[1] = this->Origin[0] + sizeChild[0]; bounds[2] = this->Origin[1]; bounds[3] = this->Origin[1] + sizeChild[1]; bounds[4] = this->Origin[2]; bounds[5] = this->Origin[2] + sizeChild[2]; } //------------------------------------------------------------------------------ void vtkHyperTreeGridGeometryUnlimitedLevelEntry::GetPoint(double point[3]) const { assert("pre: not_tree" && this->Tree); const double* sizeChild = this->Tree->GetScales()->ComputeScale(this->Level); // Compute center point coordinates point[0] = this->Origin[0] + sizeChild[0] / 2.; point[1] = this->Origin[1] + sizeChild[1] / 2.; point[2] = this->Origin[2] + sizeChild[2] / 2.; } VTK_ABI_NAMESPACE_END