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.

164 lines
6.0 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: vtkCosmicTreeLayoutStrategy.h
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
/**
* @class vtkCosmicTreeLayoutStrategy
* @brief tree layout strategy reminiscent of astronomical systems
*
*
* This layout strategy takes an input tree and places all the children of a
* node into a containing circle. The placement is such that each child
* placed can be represented with a circle tangent to the containing circle
* and (usually) 2 other children. The interior of the circle is left empty
* so that graph edges drawn on top of the tree will not obfuscate the tree.
* However, when one child is much larger than all the others, it may
* encroach on the center of the containing circle; that's OK, because it's
* large enough not to be obscured by edges drawn atop it.
*
* @par Thanks:
* Thanks to the galaxy and David Thompson hierarchically nested inside it
* for inspiring this layout strategy.
*/
#ifndef vtkCosmicTreeLayoutStrategy_h
#define vtkCosmicTreeLayoutStrategy_h
#include "vtkGraphLayoutStrategy.h"
#include "vtkInfovisLayoutModule.h" // For export macro
class vtkDoubleArray;
class vtkDataArray;
class vtkPoints;
class vtkTree;
class VTKINFOVISLAYOUT_EXPORT vtkCosmicTreeLayoutStrategy : public vtkGraphLayoutStrategy
{
public:
static vtkCosmicTreeLayoutStrategy* New();
void PrintSelf(ostream& os, vtkIndent indent) override;
vtkTypeMacro(vtkCosmicTreeLayoutStrategy, vtkGraphLayoutStrategy);
/**
* Perform the layout.
*/
void Layout() override;
//@{
/**
* Should node size specifications be obeyed at leaf nodes only or
* (with scaling as required to meet constraints) at every node in
* the tree?
* This defaults to true, so that leaf nodes are scaled according to
* the size specification provided, and the parent node sizes are
* calculated by the algorithm.
*/
vtkSetMacro(SizeLeafNodesOnly, vtkTypeBool);
vtkGetMacro(SizeLeafNodesOnly, vtkTypeBool);
vtkBooleanMacro(SizeLeafNodesOnly, vtkTypeBool);
//@}
//@{
/**
* How many levels of the tree should be laid out?
* For large trees, you may wish to set the root and maximum depth
* in order to retrieve the layout for the visible portion of the tree.
* When this value is zero or negative, all nodes below and including
* the LayoutRoot will be presented.
* This defaults to 0.
*/
vtkSetMacro(LayoutDepth, int);
vtkGetMacro(LayoutDepth, int);
//@}
//@{
/**
* What is the top-most tree node to lay out?
* This node will become the largest containing circle in the layout.
* Use this in combination with SetLayoutDepth to retrieve the
* layout of a subtree of interest for rendering.
* Setting LayoutRoot to a negative number signals that the root node
* of the tree should be used as the root node of the layout.
* This defaults to -1.
*/
vtkSetMacro(LayoutRoot, vtkIdType);
vtkGetMacro(LayoutRoot, vtkIdType);
//@}
//@{
/**
* Set the array to be used for sizing nodes.
* If this is set to an empty string or nullptr (the default),
* then all leaf nodes (or all nodes, when SizeLeafNodesOnly is false)
* will be assigned a unit size.
*/
vtkSetStringMacro(NodeSizeArrayName);
vtkGetStringMacro(NodeSizeArrayName);
//@}
protected:
/// How are node sizes specified?
enum RadiusMode
{
NONE, //!< No node sizes specified... unit radius is assumed.
LEAVES, //!< Only leaf node sizes specified... parents are calculated during layout.
ALL //!< All node sizes specified (overconstrained, so a scale factor for each parent is
//!< calculated during layout).
};
vtkCosmicTreeLayoutStrategy();
~vtkCosmicTreeLayoutStrategy() override;
/**
* Recursive routine used to lay out tree nodes. Called from Layout().
*/
void LayoutChildren(vtkTree* tree, vtkPoints* newPoints, vtkDoubleArray* radii,
vtkDoubleArray* scale, vtkIdType root, int depth, RadiusMode mode);
/**
* Recursive routine that adds each parent node's (x,y) position to its children.
* This must be done only after all the children have been laid out at the origin
* since we will not know the parent's position until after the child radii have
* been determined.
*/
void OffsetChildren(vtkTree* tree, vtkPoints* pts, vtkDoubleArray* radii, vtkDoubleArray* scale,
double parent[4], vtkIdType root, int depth, RadiusMode mode);
/**
* Create an array to hold radii, named appropriately (depends on \a NodeSizeArrayName)
* and initialized to either (a) -1.0 for each node or (b) a deep copy of an existing array.
* @param numVertices The number of vertices on the tree.
* @param initialValue The starting value of each node's radius. Only used when \a inputRadii is
* nullptr.
* @param inputRadii Either nullptr or the address of another array to be copied into the output
* array
* @retval The array of node radii to be set on the output
*/
vtkDoubleArray* CreateRadii(vtkIdType numVertices, double initialValue, vtkDataArray* inputRadii);
/**
* Create an array to hold scale factors, named appropriately (depends on \a NodeSizeArrayName)
* and initialized to -1.0.
* @param numVertices The number of vertices on the tree.
* @retval The array of node scale factors to be set on the output
*/
vtkDoubleArray* CreateScaleFactors(vtkIdType numVertices);
vtkTypeBool SizeLeafNodesOnly;
int LayoutDepth;
vtkIdType LayoutRoot;
char* NodeSizeArrayName;
private:
vtkCosmicTreeLayoutStrategy(const vtkCosmicTreeLayoutStrategy&) = delete;
void operator=(const vtkCosmicTreeLayoutStrategy&) = delete;
};
#endif // vtkCosmicTreeLayoutStrategy_h