// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkCellGridRangeQuery.h" #include "vtkBoundingBox.h" #include "vtkCellGrid.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include VTK_ABI_NAMESPACE_BEGIN vtkStandardNewMacro(vtkCellGridRangeQuery); vtkCxxSetObjectMacro(vtkCellGridRangeQuery, CellGrid, vtkCellGrid); vtkCellGridRangeQuery::~vtkCellGridRangeQuery() { this->SetCellAttribute(nullptr); this->SetCellGrid(nullptr); } void vtkCellGridRangeQuery::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "Component: " << this->Component << "\n"; os << indent << "FiniteRange: " << (this->FiniteRange ? "ON" : "OFF") << "\n"; os << indent << "CellGrid: " << this->CellGrid << "\n"; os << indent << "CellAttribute: " << this->CellAttribute << "\n"; os << indent << "Ranges:\n"; vtkIndent i2 = indent.GetNextIndent(); int cc = -2; for (const auto& range : this->Ranges) { os << i2; if (cc == -2) { os << "L₂-norm"; } else if (cc == -1) { os << "L₁-norm"; } else { os << "Component " << cc; } os << ": " << range[0] << " " << range[1] << "\n"; ++cc; } } bool vtkCellGridRangeQuery::Initialize() { bool ok = this->Superclass::Initialize(); if (!this->CellAttribute) { vtkErrorMacro("No attribute provided for range computation."); return false; } // Allocate space for all components plus L₁ and L₂ norms. this->Ranges.resize(this->CellAttribute->GetNumberOfComponents() + 2); // Invalidate the range each time we run. for (auto& range : this->Ranges) { range[0] = vtkMath::Inf(); range[1] = -vtkMath::Inf(); } return ok; } bool vtkCellGridRangeQuery::Finalize() { if (this->CellGrid && this->CellAttribute) { // Always overwrite the requested component: if (this->FiniteRange) { this->CellGrid->GetRangeCache()[this->CellAttribute][this->Component + 2].FiniteRange = this->Ranges[this->Component + 2]; this->CellGrid->GetRangeCache()[this->CellAttribute][this->Component + 2] .FiniteRangeTime.Modified(); } else { this->CellGrid->GetRangeCache()[this->CellAttribute][this->Component + 2].EntireRange = this->Ranges[this->Component + 2]; this->CellGrid->GetRangeCache()[this->CellAttribute][this->Component + 2] .EntireRangeTime.Modified(); } // If any other components have a valid range, copy them as well. // (Some range responders may choose to process all components of an array // at once instead of individually.) int cc = -2; for (auto& range : this->Ranges) { if (range[1] >= range[0]) { if (this->FiniteRange) { this->CellGrid->GetRangeCache()[this->CellAttribute][cc + 2].FiniteRange = range; this->CellGrid->GetRangeCache()[this->CellAttribute][cc + 2].FiniteRangeTime.Modified(); } else { this->CellGrid->GetRangeCache()[this->CellAttribute][cc + 2].EntireRange = range; this->CellGrid->GetRangeCache()[this->CellAttribute][cc + 2].EntireRangeTime.Modified(); } } ++cc; } } return true; } void vtkCellGridRangeQuery::GetRange(int component, double* bds) { if (!bds) { return; } if (component < -2 || component >= this->CellAttribute->GetNumberOfComponents()) { // Provide an invalid range. bds[0] = 1; bds[1] = 0; return; } std::copy(this->Ranges[component].begin(), this->Ranges[component].end(), bds); } const std::array& vtkCellGridRangeQuery::GetRange(int component) const { static const std::array invalid{ 1, 0 }; if (component < -2 || component >= this->CellAttribute->GetNumberOfComponents()) { return invalid; } return this->Ranges[component + 2]; } void vtkCellGridRangeQuery::AddRange(const std::array& range) { this->AddRange(this->Component, range); } void vtkCellGridRangeQuery::AddRange(int component, const std::array& range) { // Ignore invalid ranges: if (range[1] < range[0]) { return; } // Ignore invalid components: if (component < -2 || component >= this->CellAttribute->GetNumberOfComponents()) { return; } // If this->Range is invalid, just copy the \a range. if (this->Ranges[component + 2][1] < this->Ranges[component + 2][0]) { this->Ranges[component + 2] = range; return; } this->Ranges[component + 2][0] = std::min(this->Ranges[component + 2][0], range[0]); this->Ranges[component + 2][1] = std::max(this->Ranges[component + 2][1], range[1]); } VTK_ABI_NAMESPACE_END