/*========================================================================= Program: Visualization Toolkit Module: vtkCellTreeLocator.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkCellTreeLocator * @brief This class implements the data structures, construction * algorithms for fast cell location presented in "Fast, Memory-Efficient Cell * location in Unstructured Grids for Visualization" by Christop Garth and Kenneth * I. Joy in VisWeek, 2011. * * * Cell Tree is a bounding interval hierarchy based data structure, where child boxes * do not form an exact split of the parent boxes along a dimension. Therefore two axis- * aligned bounding planes (left max and right min) are stored for each node along a * dimension. This class implements the data structure (Cell Tree Node) and its build * and traversal algorithms described in the paper. * Some methods in building and traversing the cell tree in this class were derived * avtCellLocatorBIH class in the VisIT Visualization Tool * * * * @sa * vtkLocator vtkCellLocator vtkModifiedBSPTree */ #ifndef vtkCellTreeLocator_h #define vtkCellTreeLocator_h #include "vtkAbstractCellLocator.h" #include "vtkFiltersGeneralModule.h" // For export macro #include // Needed for internal class class vtkCellPointTraversal; class vtkIdTypeArray; class vtkCellArray; class VTKFILTERSGENERAL_EXPORT vtkCellTreeLocator : public vtkAbstractCellLocator { public: class vtkCellTree; class vtkCellTreeNode; vtkTypeMacro(vtkCellTreeLocator, vtkAbstractCellLocator); void PrintSelf(ostream& os, vtkIndent indent) override; /** * Constructor sets the maximum number of cells in a leaf to 8 * and number of buckets to 5. Buckets are used in building the cell tree as described in the * paper */ static vtkCellTreeLocator* New(); /** * Test a point to find if it is inside a cell. Returns the cellId if inside * or -1 if not. */ vtkIdType FindCell(double pos[3], double vtkNotUsed, vtkGenericCell* cell, double pcoords[3], double* weights) override; /** * Return intersection point (if any) AND the cell which was intersected by * the finite line. The cell is returned as a cell id and as a generic cell. */ int IntersectWithLine(const double a0[3], const double a1[3], double tol, double& t, double x[3], double pcoords[3], int& subId, vtkIdType& cellId, vtkGenericCell* cell) override; /** * Return a list of unique cell ids inside of a given bounding box. The * user must provide the vtkIdList to populate. This method returns data * only after the locator has been built. */ void FindCellsWithinBounds(double* bbox, vtkIdList* cells) override; /* if the borland compiler is ever removed, we can use these declarations instead of reimplementaing the calls in this subclass using vtkAbstractCellLocator::IntersectWithLine; using vtkAbstractCellLocator::FindClosestPoint; using vtkAbstractCellLocator::FindClosestPointWithinRadius; */ /** * reimplemented from vtkAbstractCellLocator to support bad compilers */ int IntersectWithLine(const double p1[3], const double p2[3], double tol, double& t, double x[3], double pcoords[3], int& subId) override { return this->Superclass::IntersectWithLine(p1, p2, tol, t, x, pcoords, subId); } /** * Return intersection point (if any) AND the cell which was intersected by * the finite line. The cell is returned as a cell id and as a generic cell. * This function is a modification from the vtkModifiedBSPTree class using the * data structures in the paper to find intersections. */ int IntersectWithLine(const double p1[3], const double p2[3], double tol, double& t, double x[3], double pcoords[3], int& subId, vtkIdType& cellId) override; /** * reimplemented from vtkAbstractCellLocator to support bad compilers */ int IntersectWithLine( const double p1[3], const double p2[3], vtkPoints* points, vtkIdList* cellIds) override { return this->Superclass::IntersectWithLine(p1, p2, points, cellIds); } /** * reimplemented from vtkAbstractCellLocator to support bad compilers */ vtkIdType FindCell(double x[3]) override { return this->Superclass::FindCell(x); } //@{ /** * Satisfy vtkLocator abstract interface. */ void FreeSearchStructure() override; void GenerateRepresentation(int level, vtkPolyData* pd) override; virtual void BuildLocatorInternal(); virtual void BuildLocatorIfNeeded(); virtual void ForceBuildLocator(); void BuildLocator() override; //@} //@{ /** * Internal classes made public to allow subclasses to create * customized some traversal algorithms */ class VTKFILTERSGENERAL_EXPORT vtkCellTree { public: std::vector Nodes; std::vector Leaves; friend class vtkCellPointTraversal; friend class vtkCellTreeNode; friend class vtkCellTreeBuilder; //@} public: float DataBBox[6]; // This store the bounding values of the dataset }; /** * This class is the basic building block of the cell tree. * Nodes consist of two split planes, LeftMax and RightMin, * one which holds all cells assigned to the left, one for the right. * The planes may overlap in the box, but cells are only assigned * to one side, so some searches must traverse both leaves until they have eliminated * candidates. * start is the location in the cell tree. e.g. for root node start is zero. * size is the number of the nodes under the (sub-)tree */ class VTKFILTERSGENERAL_EXPORT vtkCellTreeNode { public: protected: unsigned int Index; float LeftMax; // left max value float RightMin; // right min value unsigned int Sz; // size unsigned int St; // start friend class vtkCellTree; friend class vtkCellPointTraversal; friend class vtkCellTreeBuilder; public: void MakeNode(unsigned int left, unsigned int d, float b[2]); void SetChildren(unsigned int left); bool IsNode() const; unsigned int GetLeftChildIndex() const; unsigned int GetRightChildIndex() const; unsigned int GetDimension() const; const float& GetLeftMaxValue() const; const float& GetRightMinValue() const; void MakeLeaf(unsigned int start, unsigned int size); bool IsLeaf() const; unsigned int Start() const; unsigned int Size() const; }; protected: vtkCellTreeLocator(); ~vtkCellTreeLocator() override; // Test ray against node BBox : clip t values to extremes bool RayMinMaxT(const double origin[3], const double dir[3], double& rTmin, double& rTmax); bool RayMinMaxT(const double bounds[6], const double origin[3], const double dir[3], double& rTmin, double& rTmax); int getDominantAxis(const double dir[3]); // Order nodes as near/far relative to ray void Classify(const double origin[3], const double dir[3], double& rDist, vtkCellTreeNode*& near, vtkCellTreeNode*& mid, vtkCellTreeNode*& far, int& mustCheck); // From vtkModifiedBSPTRee // We provide a function which does the cell/ray test so that // it can be overridden by subclasses to perform special treatment // (Example : Particles stored in tree, have no dimension, so we must // override the cell test to return a value based on some particle size virtual int IntersectCellInternal(vtkIdType cell_ID, const double p1[3], const double p2[3], const double tol, double& t, double ipt[3], double pcoords[3], int& subId); int NumberOfBuckets; vtkCellTree* Tree; friend class vtkCellPointTraversal; friend class vtkCellTreeNode; friend class vtkCellTreeBuilder; private: vtkCellTreeLocator(const vtkCellTreeLocator&) = delete; void operator=(const vtkCellTreeLocator&) = delete; }; #endif