Adaptagrams
trees.h
1 /*
2  * vim: ts=4 sw=4 et tw=0 wm=0
3  *
4  * libdialect - A library for computing DiAlEcT layouts:
5  * D = Decompose/Distribute
6  * A = Arrange
7  * E = Expand/Emend
8  * T = Transform
9  *
10  * Copyright (C) 2018 Monash University
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  * See the file LICENSE.LGPL distributed with the library.
17  *
18  * This library is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21  *
22  * Author(s): Steve Kieffer <http://skieffer.info>
23 */
24 
25 #ifndef DIALECT_TREES_H
26 #define DIALECT_TREES_H
27 
28 #include <set>
29 #include <map>
30 #include <vector>
31 #include <string>
32 
33 #include "libavoid/geomtypes.h"
34 
35 #include "libdialect/graphs.h"
36 #include "libdialect/commontypes.h"
37 #include "libdialect/ortho.h"
38 #include "libdialect/opts.h"
39 #include "libdialect/util.h"
40 #include "libdialect/routing.h"
41 
42 namespace dialect {
43 
44 class Tree {
45 public:
46 
51  Tree(Graph_SP G, Node_SP root);
52 
62  void symmetricLayout(CardinalDir growthDir, double nodeSep, double rankSep,
63  bool convexOrdering = true);
64 
67  void flip(void);
68 
72  void translate(Avoid::Point vect);
73 
77  void rotate(CardinalDir dg);
78 
81  void rotateGrowthDirCW(unsigned quarterTurns);
82 
84  Graph_SP underlyingGraph(void) const { return m_graph; }
85 
87  Node_SP getRootNode(void) const { return m_root; }
88 
91  std::string repr(void) const;
92 
94  id_type getRootNodeID(void) const { return m_root->id(); }
95 
102  bool isSymmetrical(void) const { return m_isSymmetric; }
103 
116  Node_SP buildRootlessBox(CardinalDir growthDir) const;
117 
119  size_t size(void) const { return m_nodes.size(); }
120 
130  void addNetworkToRoutingAdapter(RoutingAdapter &ra, TreeRoutingType trt, Graph_SP core = nullptr);
131 
139  void addNetwork(Graph &G, NodesById &treeNodes, EdgesById &treeEdges);
140 
147  void addConstraints(Graph &G, bool alignRoot);
148 
154  void addBufferNodesAndConstraints(Graph &G, NodesById &bufferNodes);
155 
156 private:
157 
158  void clearRankBounds(void);
159  std::vector<double> getBounds(unsigned rank, double nodeSep) const;
160  Trees getCTrees(void) const;
161  std::string computeIsomString(void) const;
162 
163  // the underlying Graph
164  Graph_SP m_graph;
165  // the root Node
166  Node_SP m_root;
167  // Depth of the tree (number of ranks)
168  unsigned m_depth;
169  // Breadth of the tree (width of widest rank)
170  unsigned m_breadth;
171  // Is the layout symmetric?
172  bool m_isSymmetric;
173  // All nodes lying at or below the root.
174  // This can differ from the set of nodes in the underlying Graph m_graph when we are working
175  // with C-trees, a special type of subtree used in the symmetric layout process.
176  NodesById m_nodes;
177  // IDs of those nodes that are leaves
178  std::set<unsigned> m_leafIDs;
179  // map rank numbers (0-based) to the Nodes belonging to that rank
180  std::vector<Nodes> m_nodesByRank;
181  // We also want the Nodes of each rank partitioned according to whether they are leaves.
182  std::vector<Nodes> m_leavesByRank;
183  std::vector<Nodes> m_nonleavesByRank;
184  // map Node IDs to the ranks to which those Nodes belong
185  std::map<id_type, unsigned> m_rankByNodeID;
186  // map ID of child to parent Node
187  NodesById m_parents;
188  // For layout, we keep track of a pair <lb, ub>, i.e.
189  // the lower and upper bounds on the lateral coordinates
190  // of the tree, for each rank (e.g. for NORTH growth direction the
191  // bounds are on x-coordinates).
192  std::vector<std::vector<double>> m_boundsByRank;
193  // We also keep global lower and upper bounds on rank coords.
194  double m_lb;
195  double m_ub;
196  /*
197  * If the boundary is tight then the bounds for each rank cover just the
198  * nodes on that rank plus half nodeSep on each end; else the bounds for
199  * every rank are equal to the tight bounds for the widest rank.
200  */
201  bool m_boundaryTight;
202  // Growth direction
203  CardinalDir m_growthDir;
204 };
205 
206 } // namespace dialect
207 
208 #endif // DIALECT_TREES_H
libdialect: A library for computing human-like orthogonal network (DiAlEcT) layouts.
Definition: cola.h:44
Contains the interface for various geometry types and classes.
The Point class defines a point in the plane.
Definition: geomtypes.h:52
TreeRoutingType
Definition: opts.h:50