Commit fc207e8a authored by Jerome Dubois's avatar Jerome Dubois Committed by Sebastien Jourdain
Browse files

Refactoring of HyperTreeGrid to optimize and resolve bugs

This work was done by the CEA:
- HyperTreeGrid class now inherits from vtkDataObject instead of vtkDataSet
- Improved HyperTree (HT) class while keeping HT flexible.
- Complete rewrite of (Super)Cursors, more robust and efficient implementation.
- Propagate HT/Cursors refactoring to filters/readers/sources.
- Further optimizations of some filters.

Our thanks go to Los Alamos National Laboratory and Kitware for their support
in the integration of our developments.

Thanks @sebastien.jourdain, @demarle and @patchett2002

.

ToDo (@CEA), review comments in code.
Co-authored-by: default avatarJerome Dubois <Jerome.Dubois@cea.fr>
Co-authored-by: Guénolé Harel's avatarGuenole Harel <Guenole.Harel@cea.fr>
Co-authored-by: Jacques-Bernard Lekien's avatarJacques-Bernard Lekien <Jacques-Bernard.Lekien@cea.fr>
parent 44ea3929
......@@ -127,6 +127,7 @@
#define VTK_UNSTRUCTURED_GRID_BASE 36
#define VTK_PARTITIONED_DATA_SET 37
#define VTK_PARTITIONED_DATA_SET_COLLECTION 38
#define VTK_UNIFORM_HYPER_TREE_GRID 39
/*--------------------------------------------------------------------------*/
/* Define a casting macro for use by the constants below. */
......
......@@ -70,10 +70,24 @@ set(Module_SRCS
vtkHexahedron.cxx
vtkHierarchicalBoxDataIterator.cxx
vtkHierarchicalBoxDataSet.cxx
vtkHyperTree.cxx
vtkHyperTreeCursor.cxx
vtkHyperTreeGrid.cxx
vtkHyperTreeGridCursor.cxx
vtkHyperTreeGridEntry.cxx
vtkHyperTreeGridGeometryEntry.cxx
vtkHyperTreeGridGeometryLevelEntry.cxx
vtkHyperTreeGridLevelEntry.cxx
vtkHyperTreeGridOrientedGeometryCursor.cxx
vtkHyperTreeGridNonOrientedCursor.cxx
vtkHyperTreeGridNonOrientedGeometryCursor.cxx
vtkHyperTreeGridNonOrientedMooreSuperCursor.cxx
vtkHyperTreeGridNonOrientedMooreSuperCursorLight.cxx
vtkHyperTreeGridNonOrientedSuperCursor.cxx
vtkHyperTreeGridNonOrientedSuperCursorLight.cxx
vtkHyperTreeGridNonOrientedVonNeumannSuperCursor.cxx
vtkHyperTreeGridNonOrientedVonNeumannSuperCursorLight.cxx
vtkHyperTreeGridOrientedCursor.cxx
vtkImageData.cxx
vtkImageIterator.cxx
vtkImplicitBoolean.cxx
......@@ -173,7 +187,6 @@ set(Module_SRCS
vtkStaticCellLinks.cxx
vtkStaticCellLinksTemplate.txx
vtkStaticCellLocator.cxx
vtkStaticEdgeLocatorTemplate.txx
vtkStaticPointLocator.cxx
vtkStaticPointLocator2D.cxx
vtkStructuredData.cxx
......@@ -192,6 +205,7 @@ set(Module_SRCS
vtkTriQuadraticHexahedron.cxx
vtkUndirectedGraph.cxx
vtkUniformGrid.cxx
vtkUniformHyperTreeGrid.cxx
vtkUnstructuredGrid.cxx
vtkUnstructuredGridBase.cxx
vtkUnstructuredGridCellIterator.cxx
......@@ -236,7 +250,6 @@ set(${vtk-module}_HDRS
vtkMappedUnstructuredGridCellIterator.h
vtkPeriodicDataArray.h
vtkStaticCellLinksTemplate.h
vtkStaticEdgeLocatorTemplate.h
)
vtk_module_library(vtkCommonDataModel ${Module_SRCS})
This diff is collapsed.
......@@ -18,12 +18,12 @@
* exactly either 2^d or 3^d children.
*
*
* A hypertree is a dataset where each node has either exactly f^d
* An hypertree is a dataset where each node has either exactly f^d
* children or no child at all if the node is a leaf, where f in {2,3}
* is the branching factor of the tree and d in {1,2,3} is the
* dimension of the dataset.
* Such trees have particular names when f=2: bintree (d=1), quadtree
* (d=2), and octree (d=3). When f=3, we respectively call them
* (d=2), and octree (d=2). When f=3, we respectively call them
* 3-tree, 9-tree, and 27-tree.
*
* The original octree class name came from the following paper:
......@@ -43,13 +43,13 @@
* 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 a hybercube
* 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, a hypertree is efficient in memory usage when the
* By construction, an hypertree is efficient in memory usage when the
* geometry is sparse. The LOD feature allows for quick culling of part of the
* dataset.
*
......@@ -128,7 +128,9 @@
* This class was written by Philippe Pebay, Joachim Pouderoux, and Charles Law, Kitware 2013
* This class was modified by Guenole Harel and Jacques-Bernard Lekien 2014
* This class was modified by Philippe Pebay, 2016
* This work was supported by Commissariat a l'Energie Atomique (CEA/DIF)
* JB This class was simplified and optimized (memory) by Jacques-Bernard Lekien 2018
* This work was supported by Commissariat a l'Energie Atomique
* CEA, DAM, DIF, F-91297 Arpajon, France.
*/
#ifndef vtkHyperTree_h
......@@ -137,89 +139,219 @@
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkObject.h"
class vtkHyperTreeCursor;
#include <cassert> // Used internally
#include <memory> // std::shared_ptr
class vtkHyperTreeGridScales;
//=============================================================================
struct vtkHyperTreeData
{
// JB Index de Tree dans l'HyperTreeGrid
vtkIdType TreeIndex;
// Number of levels in tree
unsigned int NumberOfLevels;
// Number of nodes in tree
vtkIdType NumberOfVertices;
// Number of nodes (non-leaf vertices) in tree
vtkIdType NumberOfNodes;
// Offset for the global id mapping
vtkIdType GlobalIndexStart;
};
//=============================================================================
class VTKCOMMONDATAMODEL_EXPORT vtkHyperTree : public vtkObject
{
public:
vtkTypeMacro(vtkHyperTree, vtkObject);
void PrintSelf( ostream&, vtkIndent ) override;
void PrintSelf( ostream& os, vtkIndent indent ) override;
/**
* Restore the initial state: only one node and one leaf: the root.
*/
virtual void Initialize() = 0;
void Initialize( unsigned char branchFactor, unsigned char dimension, unsigned char numberOfChildren );
/*
* JB CopyStructure presque un shallow copy
*/
void CopyStructure( vtkHyperTree* ht );
/**
* JB Return a frozen instance (a priori compact but potentially not changeable).
*/
virtual vtkHyperTree* Frozen() = 0;
//@{
/**
* Set/Get tree index in HTG.
* JB Ces services sont a usage interne.
*/
void SetTreeIndex( vtkIdType treeIndex ) {
this->Datas->TreeIndex = treeIndex;
}
vtkIdType GetTreeIndex() const {
return this->Datas->TreeIndex;
}
//@}
/**
* Return the number of levels.
*/
virtual vtkIdType GetNumberOfLevels() = 0;
unsigned int GetNumberOfLevels() const
{
assert( "post: result_greater_or_equal_to_one" &&
this->Datas->NumberOfLevels >= 1 );
return this->Datas->NumberOfLevels;
}
/**
* Return the number of vertices in the tree.
* Return the number of all vertices in the tree.
*/
virtual vtkIdType GetNumberOfVertices() = 0;
vtkIdType GetNumberOfVertices() const
{
return this->Datas->NumberOfVertices;
}
/**
* Return the number of nodes (non-leaf vertices) in the tree.
*/
virtual vtkIdType GetNumberOfNodes() = 0;
vtkIdType GetNumberOfNodes() const
{
return this->Datas->NumberOfNodes;
}
/**
* Return the number of leaf vertices in the tree.
*/
virtual vtkIdType GetNumberOfLeaves() = 0;
vtkIdType GetNumberOfLeaves() const
{
return this->Datas->NumberOfVertices - this->Datas->NumberOfNodes;
}
/**
* Return the branch factor of the tree.
*/
virtual int GetBranchFactor() = 0;
int GetBranchFactor() const
{
return this->BranchFactor;
}
/**
* Return the dimension of the tree.
*/
virtual int GetDimension() = 0;
int GetDimension() const
{
return this->Dimension;
}
/**
* Return the number of children per node of the tree.
*/
virtual vtkIdType GetNumberOfChildren() = 0;
vtkIdType GetNumberOfChildren() const
{
return this->NumberOfChildren;
}
//@{
/**
* Set/Get scale of the tree in each direction.
* JB Set/Get scale of the tree in each direction for the ground level (0).
*/
virtual void SetScale( double[3] ) = 0;
virtual void GetScale( double[3] ) = 0;
virtual double GetScale( unsigned int ) = 0;
void GetScale( double s[3] ) const;
double GetScale( unsigned int d ) const;
//@}
/**
* JB mailles par niveau. Il est possible de demander la reinitialisation de
* JB ce systeme de cache ce qui est utilise dans le filtre de symetrisation.
*/
std::shared_ptr<vtkHyperTreeGridScales> InitializeScales ( const double *scales, bool reinitialize = false ) const;
/**
* Return an instance of a templated hypertree for given branch
* factor and dimension.
* This is done to hide templates.
* JB Return an instance of a implementation of a hypertree for given branch
* JB factor and dimension.
* JB This is done for permettre l'utilisation d'implementation differentes
* JB de l'hypertree.
* JB Une des possiblites offertes par cela, c'est qu'a partir
* JB d'une indstance d'une implementation de l'hypertree en definir une autre
* JB par l'appel a Frozen (par defaut, ce service ne fait rien), la nouvelle
* JB instance se voulant soit plus compact soit plus rapide, voire les deux.
*/
VTK_NEWINSTANCE
static vtkHyperTree* CreateInstance( unsigned int branchFactor,
unsigned int dimension );
static vtkHyperTree* CreateInstance( unsigned char branchFactor,
unsigned char dimension );
/**
* JB Return the parent index node and this stat return by IsLeaf()
* JB for this node the Index, Parent Index and IsLeaf() of the child
* JB of a node in the hypertree.
* JB L'existence de ce service est liee a celle de CreateInstance.
*/
virtual void FindChildParameters(
unsigned char ichild,
vtkIdType& idx_parent,
bool &isLeaf ) = 0;
/**
* Return memory used in bytes.
* NB: Ignore the attribute array because its size is added by the data set.
*/
virtual unsigned long GetActualMemorySizeBytes() = 0;
/**
* Return memory used in kibibytes (1024 bytes).
* NB: Ignore the attribute array because its size is added by the data set.
*/
unsigned int GetActualMemorySize()
{
// in kilibytes
return static_cast<unsigned int>( this->GetActualMemorySizeBytes() / 1024 );
}
/**
* Set the start global index for the current tree.
* The global index of a node will be this index + the node index.
*/
void SetGlobalIndexStart( vtkIdType start )
{
this->Datas->GlobalIndexStart = start;
}
/**
* Get the start global index for the current tree.
* The global index of a node will be this index + the node index.
*/
vtkIdType GetGlobalIndexStart( ) const
{
return this->Datas->GlobalIndexStart;
}
/**
* JB Set the mapping between a local node identified by idx
* and a global id qui permet de recuperer la valeur du node correspondant
* car ce global id est l'indice dans ce tableau qui decrit une grandeur.
*/
virtual void SetGlobalIndexFromLocal( vtkIdType idx, vtkIdType global ) = 0;
/**
* Find the Index of the parent of a vertex in the hypertree.
* This is done to hide templates.
* JB Get the global id of a local node identified by idx.
* Use the mapping function if available or the start global index.
*/
virtual void FindParentIndex( vtkIdType& );
virtual vtkIdType GetGlobalIndexFromLocal( vtkIdType idx ) const = 0;
/**
* Find the Index, Parent Index and IsLeaf() parameters of the child
* of a node in the hypertree.
* This is done to hide templates.
* JB Returne la valeur maximale atteinte par l'index global.
*/
virtual void FindChildParameters( int, vtkIdType&, bool& );
virtual vtkIdType GetGlobalNodeIndexMax() const = 0;
/**
* Return pointer to new instance of hyper tree cursor
* JB Return if a local node identified by idx is leaf.
*/
virtual vtkHyperTreeCursor* NewCursor() = 0;
virtual bool IsLeaf( vtkIdType idx ) const = 0;
/**
* Subdivide node pointed by cursor, only if its a leaf.
......@@ -227,35 +359,72 @@ public:
* \pre leaf_exists: leaf!=0
* \pre is_a_leaf: leaf->CurrentIsLeaf()
*/
virtual void SubdivideLeaf( vtkHyperTreeCursor* leaf ) = 0;
virtual void SubdivideLeaf( vtkIdType index, unsigned int level ) = 0;
/**
* Return memory used in kibibytes (1024 bytes).
* NB: Ignore the attribute array because its size is added by the data set.
* JB Return if a local node identified by idx is a terminal node,
* c'est-a-dire que this coarse node a toutes ses filles qui sont
* des feuilles.
*/
virtual unsigned int GetActualMemorySize() = 0;
virtual bool IsTerminalNode( vtkIdType idx ) const = 0;
/**
* Set the start global index for the current tree.
* The global index of a node will be this index + the node index.
* JB Return the local index node du premier noeud fille d'un
* parent node identified by idx_parent.
*/
virtual void SetGlobalIndexStart( vtkIdType ) = 0;
virtual vtkIdType GetElderChildIndex( unsigned int idx_parent ) const = 0;
//@{
/**
* Set the mapping between local & global Ids used by HyperTreeGrids.
* JB
*/
virtual void SetGlobalIndexFromLocal( vtkIdType local, vtkIdType global ) = 0;
void SetScales ( std::shared_ptr<vtkHyperTreeGridScales> scales ) const {
this->Scales = scales;
}
//@}
//@{
/**
* Get the global id of a local node.
* Use the mapping function if available or the start global index.
* JB
*/
virtual vtkIdType GetGlobalIndexFromLocal( vtkIdType local ) = 0;
bool HasScales ( ) const {
return ( this->Scales != nullptr );
}
//@}
protected:
vtkHyperTree()
{
//@{
/**
* JB
*/
std::shared_ptr<vtkHyperTreeGridScales> GetScales ( ) const {
assert( this->Scales != nullptr );
return this->Scales;
}
//@}
protected:
vtkHyperTree() { }
virtual void InitializePrivate() = 0;
virtual void PrintSelfPrivate( ostream& os, vtkIndent indent ) = 0;
virtual void CopyStructurePrivate( vtkHyperTree* ht ) = 0;
//-- Global information
// Branching factor of tree (2 or 3)
unsigned char BranchFactor;
// Dimension of tree (1, 2, or 3)
unsigned char Dimension;
// Number of children for coarse cell
unsigned char NumberOfChildren;
//-- Local information
std::shared_ptr< vtkHyperTreeData > Datas;
// JB Storage of pre-computed per-level cell scales
mutable std::shared_ptr<vtkHyperTreeGridScales> Scales;
private:
vtkHyperTree(const vtkHyperTree&) = delete;
......
This diff is collapsed.
......@@ -18,9 +18,8 @@
* arranged as a rectilinear grid.
*
*
* A hypertree grid is a dataset containing a rectilinear grid of root nodes,
* each of which can be refined as a vtkHyperTree grid. Each root node
* corresponds to a cell of the rectilinear grid. This organization of the
* An hypertree grid is a dataset containing a rectilinear grid of root nodes,
* each of which can be refined as a vtkHyperTree grid. This organization of the
* root nodes allows for the definition of tree-based AMR grids that do not have
* uniform geometry.
* Some filters can be applied on this dataset: contour, outline, geometry.
......@@ -37,7 +36,9 @@
* This class was written by Philippe Pebay, Joachim Pouderoux, and Charles Law, Kitware 2013
* This class was modified by Guenole Harel and Jacques-Bernard Lekien 2014
* This class was rewritten by Philippe Pebay, 2016
* This work was supported by Commissariat a l'Energie Atomique (CEA/DIF)
* This class was modified by Jacques-Bernard Lekien 2018
* This work was supported by Commissariat a l'Energie Atomique
* CEA, DAM, DIF, F-91297 Arpajon, France.
*/
#ifndef vtkHyperTreeGrid_h
......@@ -46,11 +47,11 @@
#include "vtkCommonDataModelModule.h" // For export macro
#include "vtkDataSet.h"
#include <map> // STL header for dual point coordinates adjustment
#include <map> // std::map
#include <memory> // std::shared_ptr
class vtkHyperTree;
class vtkHyperTreeCursor;
class vtkHyperTreeGridCursor;
class vtkBitArray;
class vtkBoundingBox;
......@@ -64,12 +65,22 @@ class vtkPixel;
class vtkPoints;
class vtkVoxel;
class vtkHyperTree;
class vtkHyperTreeGridOrientedCursor;
class vtkHyperTreeGridOrientedGeometryCursor;
class vtkHyperTreeGridNonOrientedCursor;
class vtkHyperTreeGridNonOrientedGeometryCursor;
class vtkHyperTreeGridNonOrientedVonNeumannSuperCursor;
class vtkHyperTreeGridNonOrientedVonNeumannSuperCursorLight;
class vtkHyperTreeGridNonOrientedMooreSuperCursor;
class vtkHyperTreeGridNonOrientedMooreSuperCursorLight ;
class VTKCOMMONDATAMODEL_EXPORT vtkHyperTreeGrid : public vtkDataSet
{
public:
class vtkHyperTreeSimpleCursor;
class vtkHyperTreePositionCursor;
class vtkHyperTreeGridIterator;
struct vtkHyperTreeGridSuperCursor;
static vtkInformationIntegerKey* LEVELS();
......@@ -79,7 +90,12 @@ public:
static vtkHyperTreeGrid* New();
vtkTypeMacro(vtkHyperTreeGrid, vtkDataSet);
void PrintSelf( ostream&, vtkIndent ) override;
void PrintSelf( ostream& os, vtkIndent indent ) override;
/**
* Squeeze this representation.
*/
void Squeeze() override;
/**
* Return what type of dataset this is.
......@@ -94,7 +110,7 @@ public:
//@{
/**
* Set/Get the number of local cells in each direction for the underlying rectilinear grid dataset.
* Set/Get sizes of this rectilinear grid dataset
*/
void SetGridSize( unsigned int[3] );
void SetGridSize( unsigned int, unsigned int, unsigned int );
......@@ -103,11 +119,11 @@ public:
//@{
/**
* Set/Get extent of the underlying rectilinear grid dataset. This is the local extent
* and is with respect to the points.
* Set/Get extent of this rectilinear grid dataset.
*/
void SetGridExtent(int extent[6]);
void SetGridExtent(int, int, int, int, int, int );
void SetGridExtent( int extent[6] );
void SetGridExtent( int, int, int, int, int, int );
void GetGridExtent( int extent[6] );
//@}
//@{
......@@ -128,7 +144,7 @@ public:
* Set/Get the dimensionality of the grid.
*/
void SetDimension( unsigned int );
vtkGetMacro(Dimension, unsigned int);
unsigned int GetDimension( ) const { return this->Dimension; }
//@}
//@{
......@@ -138,8 +154,15 @@ public:
* . in 2D: 0, 1, 2 = normal to X, Y, Z axis
* NB: Not used in 3D
*/
virtual void SetOrientation(unsigned int);
vtkGetMacro(Orientation, unsigned int);
virtual void SetOrientation(unsigned char);
unsigned char GetOrientation( ) const { return this->Orientation; }
//@}
//@{
/**
* Get the state of frozen
*/
vtkGetMacro(FrozenState, bool);
//@}
//@{
......@@ -147,13 +170,18 @@ public:
* Set/Get the subdivision factor in the grid refinement scheme
*/
void SetBranchFactor( unsigned int );
vtkGetMacro(BranchFactor, unsigned int);
unsigned int GetBranchFactor( ) const { return this->BranchFactor; }
//@}
//JBDEL2 /**
//JBDEL2 * Return the number of trees in the level 0 grid.
//JBDEL2 */
//JBDEL2 vtkIdType GetNumberOfTrees();
/**
* Return the number of trees in the level 0 grid.
* Return the maximum number of trees in the level 0 grid.
*/
vtkIdType GetNumberOfTrees();
vtkIdType GetMaxNumberOfTrees();
/**
* Get the number of vertices in the primal tree grid.
......@@ -178,18 +206,18 @@ public:
/**
* Return the number of levels in an individual (primal) tree.
*/
vtkIdType GetNumberOfLevels( vtkIdType );
unsigned int GetNumberOfLevels( vtkIdType );
/**
* Return the number of levels in the hyper tree grid.
*/
vtkIdType GetNumberOfLevels();
unsigned int GetNumberOfLevels();
//@{
/**
* Set/Get the grid coordinates in the x-direction.
*/
void SetXCoordinates( vtkDataArray* );
virtual void SetXCoordinates( vtkDataArray* );
vtkGetObjectMacro(XCoordinates, vtkDataArray);
//@}
......@@ -197,7 +225,7 @@ public:
/**
* Set/Get the grid coordinates in the y-direction.
*/
void SetYCoordinates( vtkDataArray* );
virtual void SetYCoordinates( vtkDataArray* );
vtkGetObjectMacro(YCoordinates, vtkDataArray);
//@}
......@@ -205,7 +233,7 @@ public:
/**
* Set/Get the grid coordinates in the z-direction.
*/
void SetZCoordinates( vtkDataArray* );
virtual void SetZCoordinates( vtkDataArray* );
vtkGetObjectMacro(ZCoordinates, vtkDataArray);
//@}
......@@ -222,14 +250,6 @@ public: