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.

230 lines
8.1 KiB
C

/*=========================================================================
Program: Visualization Toolkit
Module: vtkSphereTree.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 vtkSphereTree
* @brief class to build and traverse sphere trees
*
* vtkSphereTree is a helper class used to build and traverse sphere
* trees. Various types of trees can be constructed for different VTK
* dataset types, as well well as different approaches to organize
* the tree into hierarchies.
*
* Typically building a complete sphere tree consists of two parts: 1)
* creating spheres for each cell in the dataset, then 2) creating an
* organizing hierarchy. The structure of the hierarchy varies depending on
* the topological characteristics of the dataset.
*
* Once the tree is constructed, various geometric operations are available
* for quickly selecting cells based on sphere tree operations; for example,
* process all cells intersecting a plane (i.e., use the sphere tree to identify
* candidate cells for plane intersection).
*
* This class does not necessarily create optimal sphere trees because
* some of its requirements (fast build time, provide simple reference
* code, a single bounding sphere per cell, etc.) precludes optimal
* performance. It is also oriented to computing on cells versus the
* classic problem of collision detection for polygonal models. For
* more information you want to read Gareth Bradshaw's PhD thesis
* "Bounding Volume Hierarchies for Level-of-Detail Collision
* Handling" which does a nice job of laying out the challenges and
* important algorithms relative to sphere trees and BVH (bounding
* volume hierarchies).
*
* @sa
* vtkSphereTreeFilter vtkPlaneCutter
*/
#ifndef vtkSphereTree_h
#define vtkSphereTree_h
#include "vtkCommonExecutionModelModule.h" // For export macro
#include "vtkObject.h"
#include "vtkPlane.h" // to specify the cutting plane
class vtkDoubleArray;
class vtkDataArray;
class vtkIdList;
class vtkDataSet;
class vtkStructuredGrid;
class vtkUnstructuredGrid;
class vtkTimeStamp;
struct vtkSphereTreeHierarchy;
#define VTK_MAX_SPHERE_TREE_RESOLUTION 10
#define VTK_MAX_SPHERE_TREE_LEVELS 20
// VTK Class proper
class VTKCOMMONEXECUTIONMODEL_EXPORT vtkSphereTree : public vtkObject
{
public:
/**
* Instantiate the sphere tree.
*/
static vtkSphereTree* New();
//@{
/**
* Standard type related macros and PrintSelf() method.
*/
vtkTypeMacro(vtkSphereTree, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent) override;
//@}
//@{
/**
* Specify the dataset from which to build the sphere tree.
*/
virtual void SetDataSet(vtkDataSet*);
vtkGetObjectMacro(DataSet, vtkDataSet);
//@}
//@{
/**
* Build the sphere tree (if necessary) from the data set specified. The
* build time is recorded so the sphere tree will only build if something has
* changed. An alternative method is available to both set the dataset and
* then build the sphere tree.
*/
void Build();
void Build(vtkDataSet* input);
//@}
//@{
/**
* Control whether the tree hierarchy is built. If not, then just
* cell spheres are created (one for each cell).
*/
vtkSetMacro(BuildHierarchy, bool);
vtkGetMacro(BuildHierarchy, bool);
vtkBooleanMacro(BuildHierarchy, bool);
//@}
//@{
/**
* Methods for cell selection based on a geometric query. Internally
* different methods are used depending on the dataset type. The array
* returned is set to non-zero for each cell that intersects the geometric
* entity. SelectPoint marks all cells with a non-zero value that may
* contain a point. SelectLine marks all cells that may intersect an
* infinite line. SelectPlane marks all cells that may intersect with an
* infinite plane.
*/
const unsigned char* SelectPoint(double point[3], vtkIdType& numSelected);
const unsigned char* SelectLine(double origin[3], double ray[3], vtkIdType& numSelected);
const unsigned char* SelectPlane(double origin[3], double normal[3], vtkIdType& numSelected);
//@}
//@{
/**
* Methods for cell selection based on a geometric query. Internally
* different methods are used depending on the dataset type. The method
* pupulates an vtkIdList with cell ids that may satisfy the geometric
* query (the user must provide a vtkLdList which the methods fill in).
* SelectPoint lists all cells with a non-zero value that may contain a
* point. SelectLine lists all cells that may intersect an infinite
* line. SelectPlane lists all cells that may intersect with an infinite
* plane.
*/
void SelectPoint(double point[3], vtkIdList* cellIds);
void SelectLine(double origin[3], double ray[3], vtkIdList* cellIds);
void SelectPlane(double origin[3], double normal[3], vtkIdList* cellIds);
//@}
//@{
/**
* Sphere tree creation requires gathering spheres into groups. The
* Resolution variable is a rough guide to the size of each group (the size
* different meanings depending on the type of data (structured versus
* unstructured). For example, in 3D structured data, blocks of resolution
* Resolution^3 are created. By default the Resolution is three.
*/
vtkSetClampMacro(Resolution, int, 2, VTK_MAX_SPHERE_TREE_RESOLUTION);
vtkGetMacro(Resolution, int);
//@}
//@{
/**
* Specify the maximum number of levels for the tree. By default, the
* number of levels is set to ten. If the number of levels is set to one or
* less, then no hierarchy is built (i.e., just the spheres for each cell
* are created). Note that the actual level of the tree may be less than
* this value depending on the number of cells and Resolution factor.
*/
vtkSetClampMacro(MaxLevel, int, 1, VTK_MAX_SPHERE_TREE_LEVELS);
vtkGetMacro(MaxLevel, int);
//@}
/**
* Get the current depth of the sphere tree. This value may change each
* time the sphere tree is built and the branching factor (i.e.,
* resolution) changes. Note that after building the sphere tree there are
* [0,this->NumberOfLevels) defined levels.
*/
vtkGetMacro(NumberOfLevels, int);
//@{
/**
* Special methods to retrieve the sphere tree data. This is
* generally used for debugging or with filters like
* vtkSphereTreeFilter. Both methods return an array of double*
* where four doubles represent a sphere (center + radius). In the
* first method a sphere per cell is returned. In the second method
* the user must also specify a level in the sphere tree (used to
* retrieve the hierarchy of the tree). Note that null pointers can
* be returned if the request is not consistent with the state of
* the sphere tree.
*/
const double* GetCellSpheres();
const double* GetTreeSpheres(int level, vtkIdType& numSpheres);
//@}
protected:
vtkSphereTree();
~vtkSphereTree() override;
// Data members
vtkDataSet* DataSet;
unsigned char* Selected;
int Resolution;
int MaxLevel;
int NumberOfLevels;
bool BuildHierarchy;
// The tree and its hierarchy
vtkDoubleArray* Tree;
double* TreePtr;
vtkSphereTreeHierarchy* Hierarchy;
// Supporting data members
double AverageRadius; // average radius of cell sphere
double SphereBounds[6]; // the dataset bounds computed from cell spheres
vtkTimeStamp BuildTime; // time at which tree was built
// Supporting methods
void BuildTreeSpheres(vtkDataSet* input);
void ExtractCellIds(const unsigned char* selected, vtkIdList* cellIds, vtkIdType numSelected);
void BuildTreeHierarchy(vtkDataSet* input);
void BuildStructuredHierarchy(vtkStructuredGrid* input, double* tree);
void BuildUnstructuredHierarchy(vtkDataSet* input, double* tree);
int SphereTreeType; // keep track of the type of tree hierarchy generated
private:
vtkSphereTree(const vtkSphereTree&) = delete;
void operator=(const vtkSphereTree&) = delete;
};
#endif