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
230 lines
8.1 KiB
C
3 weeks ago
|
/*=========================================================================
|
||
|
|
||
|
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
|