Adaptagrams
hyperedgeimprover.h
1 /*
2  * vim: ts=4 sw=4 et tw=0 wm=0
3  *
4  * libavoid - Fast, Incremental, Object-avoiding Line Router
5  *
6  * Copyright (C) 2011-2014 Monash University
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  * See the file LICENSE.LGPL distributed with the library.
13  *
14  * Licensees holding a valid commercial license may use this file in
15  * accordance with the commercial license agreement provided with the
16  * 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): Michael Wybrow
23 */
24 
25 #ifndef AVOID_IMPROVEHYPEREDGES_H
26 #define AVOID_IMPROVEHYPEREDGES_H
27 
28 #include <map>
29 #include <set>
30 #include <list>
31 
32 
33 namespace Avoid {
34 
35 struct HyperedgeTreeNode;
36 struct HyperedgeTreeEdge;
37 class HyperedgeShiftSegment;
38 class ConnRef;
39 class JunctionRef;
40 class ShiftSegment;
41 class VertInf;
42 
43 typedef std::list<ShiftSegment *> ShiftSegmentList;
44 typedef std::map<JunctionRef *, ShiftSegmentList> RootSegmentsMap;
45 typedef std::map<JunctionRef *, HyperedgeTreeNode *>
46  JunctionHyperedgeTreeNodeMap;
47 typedef std::set<JunctionRef *> JunctionSet;
48 typedef std::list<ConnRef *> ConnRefList;
49 typedef std::list<JunctionRef *> JunctionRefList;
50 
51 class HyperedgeImprover
52 {
53 public:
54  // Constructor.
55  HyperedgeImprover();
56 
57  void clear(void);
58 
59  // Set the router that this HyperedgeImprover will act upon.
60  void setRouter(Router *router);
61 
62  // Returns lists of junctions and connectors created and deleted during
63  // hyperedge improvement.
64  HyperedgeNewAndDeletedObjectLists newAndDeletedObjectLists(void) const;
65 
66  // Execute local improvement process.
67  void execute(bool canMakeMajorChanges);
68 
69 private:
70  // Helper method for buildHyperedgeSegments() for hyperedge tree nodes.
71  void createShiftSegmentsForDimensionExcluding(HyperedgeTreeNode *node,
72  const size_t dim, HyperedgeTreeEdge *ignore,
73  ShiftSegmentList& segments);
74 
75  // Helper method for buildHyperedgeSegments() for hyperedge tree edges.
76  void createShiftSegmentsForDimensionExcluding(HyperedgeTreeEdge *edge,
77  const size_t dim, HyperedgeTreeNode *ignore,
78  ShiftSegmentList& segments);
79 
80  // During creation and nudging of shift segments it is often necessary
81  // to merge collinear or overlapping segments. This method does the
82  // merging for these cases. Effectively merging is done by adding
83  // additional vertex pointers to the shift segment.
84  void mergeOverlappingSegments(ShiftSegmentList& segments);
85 
86  // Given a hyperedge tree and a dimension, this method creates shift
87  // segments for all edges in that orientation. These segments are the
88  // objects on which the local improvement nudging operates, and they
89  // in turn make changes back to the hyperedge tree.
90  void buildHyperedgeSegments(const size_t dim);
91 
92  // This method looks for and corrects situations where the middle section
93  // of a zigzag is optimised away by bringing the outside segments in line
94  // and leading to the middle segment being zero length. These zero length
95  // edges are removed.
96  void removeZeroLengthEdges(void);
97 
98  // This method looks for and correct situations where multiple overlapping
99  // edges lead to a junction and one or more of these segments could be
100  // removed by moving the junction (and thus divergence point) along the
101  // edge.
102  void moveJunctionsAlongCommonEdges(void);
103 
104  // Given a set of hyperedge shift segments in a particular dimension,
105  // with limits and balance values precomputed, this method shifts and
106  // merges segments to improve the overall cost (length + bend penalties)
107  // for the hyperedge.
108  void nudgeHyperedgeSegments(size_t dimension, unsigned int& versionNumber);
109 
110  // Write the paths from an improved hyperedgetree object back as routes
111  // to the component connectors that form the hyperedge.
112  void writeHyperedgeSegmentsBackToConnPaths(void);
113 
114  // Output the hyperedge tree to an SVG file, optionally highlighting
115  // a segment of interest (usually the segment being moved).
116  void outputHyperedgesToSVG(unsigned int pass,
117  HyperedgeShiftSegment *activeSegment = nullptr);
118 
119  // Given a junction, this method follows the attached connectors and
120  // junctions to determine a hyperedge and returns the set of vertices
121  // representing its endpoints.
122  void getEndpoints(JunctionRef *junction, JunctionRef *ignore,
123  std::set<VertInf *>& endpoints);
124 
125  // This method moves the junction at the given node along any shared paths
126  // (so long as this action would not create any additional shared paths),
127  // while also removing and freeing merged edges and nodes in the process.
128  // It returns the new node where the junction is now located.
129  HyperedgeTreeNode *moveJunctionAlongCommonEdge(HyperedgeTreeNode *self,
130  bool& nodeMapHasChanged);
131 
132  // This method traverses the hyperedge tree removing zero length edges.
133  //
134  void removeZeroLengthEdges(HyperedgeTreeNode *self,
135  HyperedgeTreeEdge *ignored);
136 
137  // This method traverses the hyperedge tree removing zero length edges.
138  //
139  void removeZeroLengthEdges(HyperedgeTreeEdge *self,
140  HyperedgeTreeNode *ignored);
141 
142  Router *m_router;
143  JunctionHyperedgeTreeNodeMap m_hyperedge_tree_junctions;
144  JunctionSet m_hyperedge_tree_roots;
145  RootSegmentsMap m_root_shift_segments;
146  ShiftSegmentList m_all_shift_segments;
147  JunctionRefList m_new_junctions;
148  JunctionRefList m_deleted_junctions;
149  ConnRefList m_new_connectors;
150  ConnRefList m_deleted_connectors;
151  ConnRefList m_changed_connectors;
152  int m_debug_count;
153  bool m_can_make_major_changes;
154 };
155 
156 
157 }
158 #endif
159 
std::list< ConnRef * > ConnRefList
A list of ConnRef objects.
Definition: connector.h:47
libavoid: Object-avoiding orthogonal and polyline connector routing library.
Definition: actioninfo.cpp:33
std::list< JunctionRef * > JunctionRefList
A list of JunctionRef objects.
Definition: hyperedge.h:53