You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
635 lines
20 KiB
C
635 lines
20 KiB
C
|
3 weeks ago
|
/*=========================================================================
|
||
|
|
|
||
|
|
Program: Visualization Toolkit
|
||
|
|
Module: vtkHyperOctree.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 vtkHyperOctree
|
||
|
|
* @brief A dataset structured as a tree where each node has
|
||
|
|
* exactly 2^n children.
|
||
|
|
*
|
||
|
|
* An hyperoctree is a dataset where each node has either exactly 2^n children
|
||
|
|
* or no child at all if the node is a leaf. `n' is the dimension of the
|
||
|
|
* dataset (1 (binary tree), 2 (quadtree) or 3 (octree) ).
|
||
|
|
* The class name comes from the following paper:
|
||
|
|
*
|
||
|
|
* \verbatim
|
||
|
|
* @ARTICLE{yau-srihari-1983,
|
||
|
|
* author={Mann-May Yau and Sargur N. Srihari},
|
||
|
|
* title={A Hierarchical Data Structure for Multidimensional Digital Images},
|
||
|
|
* journal={Communications of the ACM},
|
||
|
|
* month={July},
|
||
|
|
* year={1983},
|
||
|
|
* volume={26},
|
||
|
|
* number={7},
|
||
|
|
* pages={504--515}
|
||
|
|
* }
|
||
|
|
* \endverbatim
|
||
|
|
*
|
||
|
|
* Each node is a cell. Attributes are associated with cells, not with points.
|
||
|
|
* The geometry is implicitly given by the size of the root node on each axis
|
||
|
|
* and position of the center and the orientation. (TODO: review center
|
||
|
|
* position and orientation). The geometry is then not limited to an hybercube
|
||
|
|
* but can have a rectangular shape.
|
||
|
|
* Attributes are associated with leaves. For LOD (Level-Of-Detail) purpose,
|
||
|
|
* attributes can be computed on none-leaf nodes by computing the average
|
||
|
|
* values from its children (which can be leaves or not).
|
||
|
|
*
|
||
|
|
* By construction, an hyperoctree is efficient in memory usage when the
|
||
|
|
* geometry is sparse. The LOD feature allows to cull quickly part of the
|
||
|
|
* dataset.
|
||
|
|
*
|
||
|
|
* A couple of filters can be applied on this dataset: contour, outline,
|
||
|
|
* geometry.
|
||
|
|
*
|
||
|
|
* * 3D case (octree)
|
||
|
|
* for each node, each child index (from 0 to 7) is encoded in the following
|
||
|
|
* orientation. It is easy to access each child as a cell of a grid.
|
||
|
|
* Note also that the binary representation is relevant, each bit code a
|
||
|
|
* side: bit 0 encodes -x side (0) or +x side (1)
|
||
|
|
* bit 1 encodes -y side (0) or +y side (1)
|
||
|
|
* bit 2 encodes -z side (0) or +z side (2)
|
||
|
|
* - the -z side first
|
||
|
|
* - 0: -y -x sides
|
||
|
|
* - 1: -y +x sides
|
||
|
|
* - 2: +y -x sides
|
||
|
|
* - 3: +y +x sides
|
||
|
|
* \verbatim
|
||
|
|
* +y
|
||
|
|
* +-+-+ ^
|
||
|
|
* |2|3| |
|
||
|
|
* +-+-+ O +z +-> +x
|
||
|
|
* |0|1|
|
||
|
|
* +-+-+
|
||
|
|
* \endverbatim
|
||
|
|
*
|
||
|
|
* - then the +z side, in counter-clockwise
|
||
|
|
* - 4: -y -x sides
|
||
|
|
* - 5: -y +x sides
|
||
|
|
* - 6: +y -x sides
|
||
|
|
* - 7: +y +x sides
|
||
|
|
* \verbatim
|
||
|
|
* +y
|
||
|
|
* +-+-+ ^
|
||
|
|
* |6|7| |
|
||
|
|
* +-+-+ O +z +-> +x
|
||
|
|
* |4|5|
|
||
|
|
* +-+-+
|
||
|
|
* \endverbatim
|
||
|
|
*
|
||
|
|
* The cases with fewer dimensions are consistent with the octree case:
|
||
|
|
*
|
||
|
|
* * Quadtree:
|
||
|
|
* in counter-clockwise
|
||
|
|
* - 0: -y -x edges
|
||
|
|
* - 1: -y +x edges
|
||
|
|
* - 2: +y -x edges
|
||
|
|
* - 3: +y +x edges
|
||
|
|
* \verbatim
|
||
|
|
* +y
|
||
|
|
* +-+-+ ^
|
||
|
|
* |2|3| |
|
||
|
|
* +-+-+ O+-> +x
|
||
|
|
* |0|1|
|
||
|
|
* +-+-+
|
||
|
|
* \endverbatim
|
||
|
|
*
|
||
|
|
* * Binary tree:
|
||
|
|
* \verbatim
|
||
|
|
* +0+1+ O+-> +x
|
||
|
|
* \endverbatim
|
||
|
|
*
|
||
|
|
* @warning
|
||
|
|
* It is not a spatial search object! If you looking for this kind of
|
||
|
|
* octree see vtkCellLocator instead.
|
||
|
|
*
|
||
|
|
* @sa
|
||
|
|
* vtkHyperOctreeAlgorithm
|
||
|
|
*/
|
||
|
|
|
||
|
|
#ifndef vtkHyperOctree_h
|
||
|
|
#define vtkHyperOctree_h
|
||
|
|
|
||
|
|
#include "vtkCommonDataModelModule.h" // For export macro
|
||
|
|
#include "vtkDataSet.h"
|
||
|
|
|
||
|
|
class vtkHyperOctreeLightWeightCursor;
|
||
|
|
class vtkHyperOctreeCursor;
|
||
|
|
class vtkHyperOctreeInternal;
|
||
|
|
class vtkHyperOctreePointsGrabber;
|
||
|
|
|
||
|
|
class vtkHyperOctreeIdSet; // Pimpl idiom
|
||
|
|
class vtkPolygon;
|
||
|
|
class vtkIdTypeArray;
|
||
|
|
class vtkPoints;
|
||
|
|
class vtkPointLocator;
|
||
|
|
class vtkOrderedTriangulator;
|
||
|
|
class vtkDataSetAttributes;
|
||
|
|
|
||
|
|
class vtkLine;
|
||
|
|
class vtkPixel;
|
||
|
|
class vtkVoxel;
|
||
|
|
class vtkCellLinks;
|
||
|
|
|
||
|
|
class VTKCOMMONDATAMODEL_EXPORT vtkHyperOctree : public vtkDataSet
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
static vtkInformationIntegerKey* LEVELS();
|
||
|
|
static vtkInformationIntegerKey* DIMENSION();
|
||
|
|
static vtkInformationDoubleVectorKey* SIZES();
|
||
|
|
static vtkHyperOctree *New();
|
||
|
|
|
||
|
|
vtkTypeMacro(vtkHyperOctree,vtkDataSet);
|
||
|
|
void PrintSelf(ostream& os, vtkIndent indent) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return what type of dataset this is.
|
||
|
|
*/
|
||
|
|
int GetDataObjectType() VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copy the geometric and topological structure of an input rectilinear grid
|
||
|
|
* object.
|
||
|
|
*/
|
||
|
|
void CopyStructure(vtkDataSet *ds) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
// Return the node describes by the path from the root.
|
||
|
|
// Path is a sequence of number between 0 and 7.
|
||
|
|
// \pre path_exists: path!=0
|
||
|
|
// \pre node_exists: IsANode(path)
|
||
|
|
// vtkOctree *GetNode(vtkPath *path);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the dimension of the tree (1D:binary tree(2 children), 2D:quadtree(4 children),
|
||
|
|
* 3D:octree (8 children))
|
||
|
|
* \post valid_result: result>=1 && result<=3
|
||
|
|
*/
|
||
|
|
int GetDimension();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Set the dimension of the tree with `dim'. See GetDimension() for details.
|
||
|
|
* \pre valid_dim: dim>=1 && dim<=3
|
||
|
|
* \post dimension_is_set: GetDimension()==dim
|
||
|
|
*/
|
||
|
|
void SetDimension(int dim);
|
||
|
|
|
||
|
|
// Return if the node for the given path exists or not.
|
||
|
|
// \pre path_exists: path!=0
|
||
|
|
// int IsANode(vtkPath *path);
|
||
|
|
|
||
|
|
// Return if the node for the given path is a leaf or not.
|
||
|
|
// \pre path_exists: path!=0
|
||
|
|
// \pre node_exists: IsANode(path)
|
||
|
|
// int IsALeaf(vtkPath *path);
|
||
|
|
|
||
|
|
// Measurement: topology
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the number of cells in the dual grid.
|
||
|
|
* \post positive_result: result>=0
|
||
|
|
*/
|
||
|
|
vtkIdType GetNumberOfCells() VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the number of leaves in the tree.
|
||
|
|
*/
|
||
|
|
vtkIdType GetNumberOfLeaves();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the number of points in the dual grid.
|
||
|
|
* \post positive_result: result>=0
|
||
|
|
*/
|
||
|
|
vtkIdType GetNumberOfPoints() VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the number of points corresponding to an hyperoctree starting at
|
||
|
|
* level `level' where all the leaves at at the last level. In this case, the
|
||
|
|
* hyperoctree is like a uniform grid. So this number is the number of points
|
||
|
|
* of the uniform grid.
|
||
|
|
* \pre positive_level: level>=0 && level<this->GetNumberOfLevels()
|
||
|
|
* \post definition: result==(2^(GetNumberOfLevels()-level-1)+1)^GetDimension()
|
||
|
|
*/
|
||
|
|
vtkIdType GetMaxNumberOfPoints(int level);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the number of points corresponding to the boundary of an
|
||
|
|
* hyperoctree starting at level `level' where all the leaves at at the last
|
||
|
|
* level. In this case, the hyperoctree is like a uniform grid. So this
|
||
|
|
* number is the number of points of on the boundary of the uniform grid.
|
||
|
|
* For an octree, the boundary are the faces. For a quadtree, the boundary
|
||
|
|
* are the edges.
|
||
|
|
* \pre 2d_or_3d: this->GetDimension()==2 || this->GetDimension()==3
|
||
|
|
* \pre positive_level: level>=0 && level<this->GetNumberOfLevels()
|
||
|
|
* \post min_result: result>=GetMaxNumberOfPoints(this->GetNumberOfLevels()-1)
|
||
|
|
* \post max_result: result<=GetMaxNumberOfPoints(level)
|
||
|
|
*/
|
||
|
|
vtkIdType GetMaxNumberOfPointsOnBoundary(int level);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the number of cells corresponding to the boundary of a cell
|
||
|
|
* of level `level' where all the leaves at at the last level.
|
||
|
|
* \pre positive_level: level>=0 && level<this->GetNumberOfLevels()
|
||
|
|
* \post positive_result: result>=0
|
||
|
|
*/
|
||
|
|
vtkIdType GetMaxNumberOfCellsOnBoundary(int level);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the number of levels.
|
||
|
|
* \post result_greater_or_equal_to_one: result>=1
|
||
|
|
*/
|
||
|
|
vtkIdType GetNumberOfLevels();
|
||
|
|
|
||
|
|
// Measurement: geometry
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Set the size on each axis.
|
||
|
|
*/
|
||
|
|
vtkSetVector3Macro(Size,double);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Return the size on each axis.
|
||
|
|
*/
|
||
|
|
vtkGetVector3Macro(Size,double);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Set the origin (position of corner (0,0,0) of the root.
|
||
|
|
*/
|
||
|
|
vtkSetVector3Macro(Origin,double);
|
||
|
|
// Return the origin (position of corner (0,0,0) ) of the root.
|
||
|
|
vtkGetVector3Macro(Origin,double);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new cursor: an object that can traverse
|
||
|
|
* the cell of an hyperoctree.
|
||
|
|
* \post result_exists: result!=0
|
||
|
|
*/
|
||
|
|
vtkHyperOctreeCursor *NewCellCursor();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Subdivide node pointed by cursor, only if its a leaf.
|
||
|
|
* At the end, cursor points on the node that used to be leaf.
|
||
|
|
* \pre leaf_exists: leaf!=0
|
||
|
|
* \pre is_a_leaf: leaf->CurrentIsLeaf()
|
||
|
|
*/
|
||
|
|
void SubdivideLeaf(vtkHyperOctreeCursor *leaf);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Collapse a node for which all children are leaves.
|
||
|
|
* At the end, cursor points on the leaf that used to be a node.
|
||
|
|
* \pre node_exists: node!=0
|
||
|
|
* \pre node_is_node: !node->CurrentIsLeaf()
|
||
|
|
* \pre children_are_leaves: node->CurrentIsTerminalNode()
|
||
|
|
*/
|
||
|
|
void CollapseTerminalNode(vtkHyperOctreeCursor *node);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get point coordinates with ptId such that: 0 <= ptId < NumberOfPoints.
|
||
|
|
* THIS METHOD IS NOT THREAD SAFE.
|
||
|
|
*/
|
||
|
|
double *GetPoint(vtkIdType ptId) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Copy point coordinates into user provided array x[3] for specified
|
||
|
|
* point id.
|
||
|
|
* THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND
|
||
|
|
* THE DATASET IS NOT MODIFIED
|
||
|
|
*/
|
||
|
|
void GetPoint(vtkIdType id, double x[3]) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get cell with cellId such that: 0 <= cellId < NumberOfCells.
|
||
|
|
* THIS METHOD IS NOT THREAD SAFE.
|
||
|
|
*/
|
||
|
|
vtkCell *GetCell(vtkIdType cellId) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get cell with cellId such that: 0 <= cellId < NumberOfCells.
|
||
|
|
* This is a thread-safe alternative to the previous GetCell()
|
||
|
|
* method.
|
||
|
|
* THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND
|
||
|
|
* THE DATASET IS NOT MODIFIED
|
||
|
|
*/
|
||
|
|
void GetCell(vtkIdType cellId, vtkGenericCell *cell) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get type of cell with cellId such that: 0 <= cellId < NumberOfCells.
|
||
|
|
* THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND
|
||
|
|
* THE DATASET IS NOT MODIFIED
|
||
|
|
*/
|
||
|
|
int GetCellType(vtkIdType cellId) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Topological inquiry to get points defining cell.
|
||
|
|
* THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND
|
||
|
|
* THE DATASET IS NOT MODIFIED
|
||
|
|
*/
|
||
|
|
void GetCellPoints(vtkIdType cellId, vtkIdList *ptIds) VTK_OVERRIDE;
|
||
|
|
virtual void GetCellPoints(vtkIdType cellId, vtkIdType& npts,
|
||
|
|
vtkIdType* &pts);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Topological inquiry to get cells using point.
|
||
|
|
* THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND
|
||
|
|
* THE DATASET IS NOT MODIFIED
|
||
|
|
*/
|
||
|
|
void GetPointCells(vtkIdType ptId, vtkIdList *cellIds) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Topological inquiry to get all cells using list of points exclusive of
|
||
|
|
* cell specified (e.g., cellId). Note that the list consists of only
|
||
|
|
* cells that use ALL the points provided.
|
||
|
|
* THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND
|
||
|
|
* THE DATASET IS NOT MODIFIED
|
||
|
|
*/
|
||
|
|
void GetCellNeighbors(vtkIdType cellId, vtkIdList *ptIds,
|
||
|
|
vtkIdList *cellIds) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
vtkIdType FindPoint(double x[3]) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Locate cell based on global coordinate x and tolerance
|
||
|
|
* squared. If cell and cellId is non-NULL, then search starts from
|
||
|
|
* this cell and looks at immediate neighbors. Returns cellId >= 0
|
||
|
|
* if inside, < 0 otherwise. The parametric coordinates are
|
||
|
|
* provided in pcoords[3]. The interpolation weights are returned in
|
||
|
|
* weights[]. (The number of weights is equal to the number of
|
||
|
|
* points in the found cell). Tolerance is used to control how close
|
||
|
|
* the point is to be considered "in" the cell.
|
||
|
|
* THIS METHOD IS NOT THREAD SAFE.
|
||
|
|
*/
|
||
|
|
vtkIdType FindCell(double x[3], vtkCell *cell, vtkIdType cellId,
|
||
|
|
double tol2, int& subId, double pcoords[3],
|
||
|
|
double *weights) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This is a version of the above method that can be used with
|
||
|
|
* multithreaded applications. A vtkGenericCell must be passed in
|
||
|
|
* to be used in internal calls that might be made to GetCell()
|
||
|
|
* THIS METHOD IS THREAD SAFE IF FIRST CALLED FROM A SINGLE THREAD AND
|
||
|
|
* THE DATASET IS NOT MODIFIED
|
||
|
|
*/
|
||
|
|
vtkIdType FindCell(double x[3], vtkCell *cell,
|
||
|
|
vtkGenericCell *gencell, vtkIdType cellId,
|
||
|
|
double tol2, int& subId, double pcoords[3],
|
||
|
|
double *weights) VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Restore data object to initial state,
|
||
|
|
* THIS METHOD IS NOT THREAD SAFE.
|
||
|
|
*/
|
||
|
|
void Initialize() VTK_OVERRIDE;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Convenience method returns largest cell size in dataset. This is generally
|
||
|
|
* used to allocate memory for supporting data structures.
|
||
|
|
* This is the number of points of a cell.
|
||
|
|
* THIS METHOD IS THREAD SAFE
|
||
|
|
*/
|
||
|
|
int GetMaxCellSize() VTK_OVERRIDE;
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Shallow and Deep copy.
|
||
|
|
*/
|
||
|
|
void ShallowCopy(vtkDataObject *src) VTK_OVERRIDE;
|
||
|
|
void DeepCopy(vtkDataObject *src) VTK_OVERRIDE;
|
||
|
|
//@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the points of node `sibling' on its face `face'.
|
||
|
|
* \pre sibling_exists: sibling!=0
|
||
|
|
* \pre sibling_not_leaf: !sibling->CurrentIsLeaf()
|
||
|
|
* \pre sibling_3d: sibling->GetDimension()==3
|
||
|
|
* \pre valid_face: face>=0 && face<6
|
||
|
|
* \pre valid_level_not_leaf: level>=0 level<(this->GetNumberOfLevels()-1)
|
||
|
|
*/
|
||
|
|
void GetPointsOnFace(vtkHyperOctreeCursor *sibling,
|
||
|
|
int face,
|
||
|
|
int level,
|
||
|
|
vtkHyperOctreePointsGrabber *grabber);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the points of the parent node of `cursor' on its faces `faces' at
|
||
|
|
* level `level' or deeper.
|
||
|
|
* \pre cursor_exists: cursor!=0
|
||
|
|
* \pre cursor_3d: cursor->GetDimension()==3
|
||
|
|
* \pre valid_level: level>=0
|
||
|
|
* \pre boolean_faces: (faces[0]==0 || faces[0]==1) && (faces[1]==0 || faces[1]==1) && (faces[2]==0 || faces[2]==1)
|
||
|
|
*/
|
||
|
|
void GetPointsOnParentFaces(int faces[3],
|
||
|
|
int level,
|
||
|
|
vtkHyperOctreeCursor *cursor,
|
||
|
|
vtkHyperOctreePointsGrabber *grabber);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the points of node `sibling' on its edge `axis','k','j'.
|
||
|
|
* If axis==0, the edge is X-aligned and k gives the z coordinate and j the
|
||
|
|
* y-coordinate. If axis==1, the edge is Y-aligned and k gives the x coordinate
|
||
|
|
* and j the z coordinate. If axis==2, the edge is Z-aligned and k gives the
|
||
|
|
* y coordinate and j the x coordinate.
|
||
|
|
* \pre sibling_exists: sibling!=0
|
||
|
|
* \pre sibling_3d: sibling->GetDimension()==3
|
||
|
|
* \pre sibling_not_leaf: !sibling->CurrentIsLeaf()
|
||
|
|
* \pre valid_axis: axis>=0 && axis<3
|
||
|
|
* \pre valid_k: k>=0 && k<=1
|
||
|
|
* \pre valid_j: j>=0 && j<=1
|
||
|
|
* \pre valid_level_not_leaf: level>=0 level<(this->Input->GetNumberOfLevels()-1)
|
||
|
|
*/
|
||
|
|
void GetPointsOnEdge(vtkHyperOctreeCursor *sibling,
|
||
|
|
int level,
|
||
|
|
int axis,
|
||
|
|
int k,
|
||
|
|
int j,
|
||
|
|
vtkHyperOctreePointsGrabber *grabber);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the points of the parent node of `cursor' on its edge `axis','k','j'
|
||
|
|
* at level `level' or deeper.
|
||
|
|
* If axis==0, the edge is X-aligned and k gives the z coordinate and j the
|
||
|
|
* y-coordinate. If axis==1, the edge is Y-aligned and k gives the x
|
||
|
|
* coordinate and j the z coordinate. If axis==2, the edge is Z-aligned and
|
||
|
|
* k gives the y coordinate and j the x coordinate.
|
||
|
|
* \pre cursor_exists: cursor!=0
|
||
|
|
* \pre cursor_3d: cursor->GetDimension()==3
|
||
|
|
* \pre valid_level: level>=0
|
||
|
|
* \pre valid_range_axis: axis>=0 && axis<3
|
||
|
|
* \pre valid_range_k: k>=0 && k<=1
|
||
|
|
* \pre valid_range_j: j>=0 && j<=1
|
||
|
|
*/
|
||
|
|
void GetPointsOnParentEdge(vtkHyperOctreeCursor *cursor,
|
||
|
|
int level,
|
||
|
|
int axis,
|
||
|
|
int k,
|
||
|
|
int j,
|
||
|
|
vtkHyperOctreePointsGrabber *grabber);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the points of node `sibling' on its edge `edge'.
|
||
|
|
* \pre sibling_exists: sibling!=0
|
||
|
|
* \pre sibling_not_leaf: !sibling->CurrentIsLeaf()
|
||
|
|
* \pre sibling_2d: sibling->GetDimension()==2
|
||
|
|
* \pre valid_edge: edge>=0 && edge<4
|
||
|
|
* \pre valid_level_not_leaf: level>=0 level<(this->Input->GetNumberOfLevels()-1)
|
||
|
|
*/
|
||
|
|
void GetPointsOnEdge2D(vtkHyperOctreeCursor *sibling,
|
||
|
|
int edge,
|
||
|
|
int level,
|
||
|
|
vtkHyperOctreePointsGrabber *grabber);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the points of the parent node of `cursor' on its edge `edge' at
|
||
|
|
* level `level' or deeper. (edge=0 for -X, 1 for +X, 2 for -Y, 3 for +Y)
|
||
|
|
* \pre cursor_exists: cursor!=0
|
||
|
|
* \pre cursor_2d: cursor->GetDimension()==2
|
||
|
|
* \pre valid_level: level>=0
|
||
|
|
* \pre valid_edge: edge>=0 && edge<4
|
||
|
|
*/
|
||
|
|
void GetPointsOnParentEdge2D(vtkHyperOctreeCursor *cursor,
|
||
|
|
int edge,
|
||
|
|
int level,
|
||
|
|
vtkHyperOctreePointsGrabber *grabber);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A generic way to set the leaf data attributes.
|
||
|
|
* This can be either point data for dual or cell data for normal grid.
|
||
|
|
*/
|
||
|
|
vtkDataSetAttributes* GetLeafData();
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Switch between returning leaves as cells, or the dual grid.
|
||
|
|
*/
|
||
|
|
void SetDualGridFlag(int flag);
|
||
|
|
vtkGetMacro(DualGridFlag,int);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return the actual size of the data in kibibytes (1024 bytes). This number
|
||
|
|
* is valid only after the pipeline has updated. The memory size
|
||
|
|
* returned is guaranteed to be greater than or equal to the
|
||
|
|
* memory required to represent the data (e.g., extra space in
|
||
|
|
* arrays, etc. are not included in the return value). THIS METHOD
|
||
|
|
* IS THREAD SAFE.
|
||
|
|
*/
|
||
|
|
unsigned long GetActualMemorySize() VTK_OVERRIDE;
|
||
|
|
|
||
|
|
//@{
|
||
|
|
/**
|
||
|
|
* Retrieve an instance of this class from an information object.
|
||
|
|
*/
|
||
|
|
static vtkHyperOctree* GetData(vtkInformation* info);
|
||
|
|
static vtkHyperOctree* GetData(vtkInformationVector* v, int i=0);
|
||
|
|
//@}
|
||
|
|
|
||
|
|
protected:
|
||
|
|
// Constructor with default bounds (0,1, 0,1, 0,1).
|
||
|
|
vtkHyperOctree();
|
||
|
|
~vtkHyperOctree() VTK_OVERRIDE;
|
||
|
|
|
||
|
|
void ComputeBounds() VTK_OVERRIDE;
|
||
|
|
|
||
|
|
int Dimension; // 1, 2 or 3.
|
||
|
|
|
||
|
|
double Size[3]; // size on each axis
|
||
|
|
double Origin[3]; // position of corner (0,0,0) of the root.
|
||
|
|
|
||
|
|
vtkHyperOctreeInternal *CellTree;
|
||
|
|
|
||
|
|
vtkHyperOctreeCursor *TmpChild; // to avoid allocation in the loop
|
||
|
|
|
||
|
|
friend class vtkHyperOctreeLightWeightCursor;
|
||
|
|
|
||
|
|
// Initialize the arrays if necessary, then return it.
|
||
|
|
void UpdateDualArrays();
|
||
|
|
vtkPoints* GetLeafCenters();
|
||
|
|
vtkIdTypeArray* GetCornerLeafIds();
|
||
|
|
vtkPoints *LeafCenters;
|
||
|
|
vtkIdTypeArray *CornerLeafIds;
|
||
|
|
|
||
|
|
void UpdateGridArrays();
|
||
|
|
vtkPoints* GetCornerPoints();
|
||
|
|
vtkIdTypeArray* GetLeafCornerIds();
|
||
|
|
vtkPoints* CornerPoints;
|
||
|
|
vtkIdTypeArray* LeafCornerIds;
|
||
|
|
|
||
|
|
void DeleteInternalArrays();
|
||
|
|
|
||
|
|
void TraverseDualRecursively(vtkHyperOctreeLightWeightCursor* neighborhood,
|
||
|
|
unsigned short *xyzIds, int level);
|
||
|
|
void TraverseGridRecursively(vtkHyperOctreeLightWeightCursor* neighborhood,
|
||
|
|
unsigned char* visited,
|
||
|
|
double* origin, double* size);
|
||
|
|
void EvaluateDualCorner(vtkHyperOctreeLightWeightCursor* neighborhood);
|
||
|
|
vtkIdType EvaluateGridCorner(int level,vtkHyperOctreeLightWeightCursor* neighborhood,
|
||
|
|
unsigned char* visited, int* cornerNeighborIds);
|
||
|
|
|
||
|
|
// This is a table for traversing a neighborhood down an octree.
|
||
|
|
// 8 children x 27 cursors
|
||
|
|
// First three bits encode the child, rest encode the cursor id.
|
||
|
|
// 8xCursorId + childId.
|
||
|
|
// This will be shorter when we get rid of the 3x3x3 neighborhood.
|
||
|
|
// I was using unsigned char, but VS60 optimized build had a problem.
|
||
|
|
int NeighborhoodTraversalTable[216];
|
||
|
|
void GenerateGridNeighborhoodTraversalTable();
|
||
|
|
void GenerateDualNeighborhoodTraversalTable();
|
||
|
|
|
||
|
|
// for the GetCell method
|
||
|
|
vtkLine *Line;
|
||
|
|
vtkPixel *Pixel;
|
||
|
|
vtkVoxel *Voxel;
|
||
|
|
|
||
|
|
vtkCellLinks* Links;
|
||
|
|
void BuildLinks();
|
||
|
|
|
||
|
|
vtkIdType RecursiveFindPoint(double x[3],
|
||
|
|
vtkHyperOctreeLightWeightCursor* cursor,
|
||
|
|
double *origin, double *size);
|
||
|
|
|
||
|
|
// This toggles the data set API between the leaf cells and
|
||
|
|
// the dual grid (leaves are points, corners are cells).
|
||
|
|
int DualGridFlag;
|
||
|
|
|
||
|
|
private:
|
||
|
|
vtkHyperOctree(const vtkHyperOctree&) VTK_DELETE_FUNCTION;
|
||
|
|
void operator=(const vtkHyperOctree&) VTK_DELETE_FUNCTION;
|
||
|
|
};
|
||
|
|
|
||
|
|
class VTKCOMMONDATAMODEL_EXPORT vtkHyperOctreeLightWeightCursor
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
vtkHyperOctreeLightWeightCursor();
|
||
|
|
void Initialize(vtkHyperOctree* tree);
|
||
|
|
void ToRoot();
|
||
|
|
void ToChild(int child);
|
||
|
|
unsigned short GetIsLeaf();
|
||
|
|
int GetLeafIndex() {return this->Index;} // Only valid for leaves.
|
||
|
|
vtkHyperOctree* GetTree() { return this->Tree; }
|
||
|
|
unsigned short GetLevel() {return this->Level;}
|
||
|
|
private:
|
||
|
|
vtkHyperOctree* Tree;
|
||
|
|
int Index;
|
||
|
|
unsigned short IsLeaf;
|
||
|
|
unsigned short Level;
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif
|