/*========================================================================= Program: Visualization Toolkit Module: vtkSimple3DCirclesStrategy.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 vtkSimple3DCirclesStrategy * @brief places vertices on circles in 3D * * * Places vertices on circles depending on the graph vertices hierarchy level. * The source graph could be vtkDirectedAcyclicGraph or vtkDirectedGraph if MarkedStartPoints array * was added. The algorithm collects the standalone points, too and take them to a separated circle. * If method is FixedRadiusMethod, the radius of the circles will be equal. If method is * FixedDistanceMethod, the distance between the points on circles will be equal. * * In first step initial points are searched. A point is initial, if its in degree equal zero and * out degree is greater than zero (or marked by MarkedStartVertices and out degree is greater than * zero). Independent vertices (in and out degree equal zero) are collected separatelly. In second * step the hierarchical level is generated for every vertex. In third step the hierarchical order * is generated. If a vertex has no hierarchical level and it is not independent, the graph has loop * so the algorithm exit with error message. Finally the vertices positions are calculated by the * hierarchical order and by the vertices hierarchy levels. * * @par Thanks: * Ferenc Nasztanovics, naszta@naszta.hu, Budapest University of Technology and Economics, * Department of Structural Mechanics * * @par References: * in 3D rotation was used: http://en.citizendium.org/wiki/Rotation_matrix */ #ifndef vtkSimple3DCirclesStrategy_h #define vtkSimple3DCirclesStrategy_h #include "vtkGraphLayoutStrategy.h" #include "vtkInfovisLayoutModule.h" // For export macro #include "vtkVariant.h" // For variant API class vtkAbstractArray; class vtkDirectedGraph; class vtkIdTypeArray; class vtkIntArray; class vtkSimple3DCirclesStrategyInternal; class VTKINFOVISLAYOUT_EXPORT vtkSimple3DCirclesStrategy : public vtkGraphLayoutStrategy { public: static vtkSimple3DCirclesStrategy* New(); vtkTypeMacro(vtkSimple3DCirclesStrategy, vtkGraphLayoutStrategy); void PrintSelf(ostream& os, vtkIndent indent) override; enum { FixedRadiusMethod = 0, FixedDistanceMethod = 1 }; //@{ /** * Set or get circle generating method (FixedRadiusMethod/FixedDistanceMethod). Default is * FixedRadiusMethod. */ vtkSetMacro(Method, int); vtkGetMacro(Method, int); //@} //@{ /** * If Method is FixedRadiusMethod: Set or get the radius of the circles. * If Method is FixedDistanceMethod: Set or get the distance of the points in the circle. */ vtkSetMacro(Radius, double); vtkGetMacro(Radius, double); //@} //@{ /** * Set or get the vertical (local z) distance between the circles. If AutoHeight is on, this is * the minimal height between the circle layers */ vtkSetMacro(Height, double); vtkGetMacro(Height, double); //@} //@{ /** * Set or get the origin of the geometry. This is the center of the first circle. SetOrigin(x,y,z) */ vtkSetVector3Macro(Origin, double); vtkGetVector3Macro(Origin, double); //@} //@{ /** * Set or get the normal vector of the circles plain. The height is growing in this direction. The * direction must not be zero vector. The default vector is (0.0,0.0,1.0) */ virtual void SetDirection(double dx, double dy, double dz); virtual void SetDirection(double d[3]); vtkGetVector3Macro(Direction, double); //@} //@{ /** * Set or get initial vertices. If MarkedStartVertices is added, loop is accepted in the graph. * (If all of the loop start vertices are marked in MarkedStartVertices array.) * MarkedStartVertices size must be equal with the number of the vertices in the graph. Start * vertices must be marked by MarkedValue. (E.g.: if MarkedValue=3 and MarkedStartPoints is { 0, * 3, 5, 3 }, the start points ids will be {1,3}.) ) */ virtual void SetMarkedStartVertices(vtkAbstractArray* _arg); vtkGetObjectMacro(MarkedStartVertices, vtkAbstractArray); //@} //@{ /** * Set or get MarkedValue. See: MarkedStartVertices. */ virtual void SetMarkedValue(vtkVariant _arg); virtual vtkVariant GetMarkedValue(void); //@} //@{ /** * Set or get ForceToUseUniversalStartPointsFinder. If ForceToUseUniversalStartPointsFinder is * true, MarkedStartVertices won't be used. In this case the input graph must be * vtkDirectedAcyclicGraph (Default: false). */ vtkSetMacro(ForceToUseUniversalStartPointsFinder, vtkTypeBool); vtkGetMacro(ForceToUseUniversalStartPointsFinder, vtkTypeBool); vtkBooleanMacro(ForceToUseUniversalStartPointsFinder, vtkTypeBool); //@} //@{ /** * Set or get auto height (Default: false). If AutoHeight is true, (r(i+1) - r(i-1))/Height will * be smaller than tan(MinimumRadian). If you want equal distances and parallel circles, you * should turn off AutoHeight. */ vtkSetMacro(AutoHeight, vtkTypeBool); vtkGetMacro(AutoHeight, vtkTypeBool); vtkBooleanMacro(AutoHeight, vtkTypeBool); //@} //@{ /** * Set or get minimum radian (used by auto height). */ vtkSetMacro(MinimumRadian, double); vtkGetMacro(MinimumRadian, double); //@} //@{ /** * Set or get minimum degree (used by auto height). There is no separated minimum degree, so * minimum radian will be changed. */ virtual void SetMinimumDegree(double degree); virtual double GetMinimumDegree(void); //@} //@{ /** * Set or get hierarchical layers id by vertices (An usual vertex's layer id is greater or equal * to zero. If a vertex is standalone, its layer id is -2.) If no HierarchicalLayers array is * defined, vtkSimple3DCirclesStrategy will generate it automatically (default). */ virtual void SetHierarchicalLayers(vtkIntArray* _arg); vtkGetObjectMacro(HierarchicalLayers, vtkIntArray); //@} //@{ /** * Set or get hierarchical ordering of vertices (The array starts from the first vertex's id. All * id must be greater or equal to zero!) If no HierarchicalOrder is defined, * vtkSimple3DCirclesStrategy will generate it automatically (default). */ virtual void SetHierarchicalOrder(vtkIdTypeArray* _arg); vtkGetObjectMacro(HierarchicalOrder, vtkIdTypeArray); //@} /** * Standard layout method */ void Layout(void) override; /** * Set graph (warning: HierarchicalOrder and HierarchicalLayers will set to zero. These reference * counts will be decreased!) */ void SetGraph(vtkGraph* graph) override; protected: vtkSimple3DCirclesStrategy(); ~vtkSimple3DCirclesStrategy() override; inline void Transform(double Local[], double Global[]); double Radius; double Height; double Origin[3]; double Direction[3]; int Method; vtkAbstractArray* MarkedStartVertices; vtkVariant MarkedValue; vtkTypeBool ForceToUseUniversalStartPointsFinder; vtkTypeBool AutoHeight; double MinimumRadian; vtkIntArray* HierarchicalLayers; vtkIdTypeArray* HierarchicalOrder; private: /** * Search and fill in target all zero input degree vertices where the output degree is more than * zero. The finded vertices hierarchical layer ID will be zero. */ virtual int UniversalStartPoints(vtkDirectedGraph* input, vtkSimple3DCirclesStrategyInternal* target, vtkSimple3DCirclesStrategyInternal* StandAlones, vtkIntArray* layers); /** * Build hierarchical layers in the graph. A vertices hierarchical layer number is equal the * maximum of its inputs hierarchical layer numbers plus one. */ virtual int BuildLayers( vtkDirectedGraph* input, vtkSimple3DCirclesStrategyInternal* source, vtkIntArray* layers); /** * Build hierarchical ordering of the graph points. */ virtual void BuildPointOrder(vtkDirectedGraph* input, vtkSimple3DCirclesStrategyInternal* source, vtkSimple3DCirclesStrategyInternal* StandAlones, vtkIntArray* layers, vtkIdTypeArray* order); double T[3][3]; vtkSimple3DCirclesStrategy(const vtkSimple3DCirclesStrategy&) = delete; void operator=(const vtkSimple3DCirclesStrategy&) = delete; }; #endif