1 /** \file 2 * \brief Declaration of classes InOutPoint and IOPoints which 3 * implement the management of in-/out-points 4 * 5 * \author Carsten Gutwenger 6 * 7 * \par License: 8 * This file is part of the Open Graph Drawing Framework (OGDF). 9 * 10 * \par 11 * Copyright (C)<br> 12 * See README.md in the OGDF root directory for details. 13 * 14 * \par 15 * This program is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU General Public License 17 * Version 2 or 3 as published by the Free Software Foundation; 18 * see the file LICENSE.txt included in the packaging of this file 19 * for details. 20 * 21 * \par 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * \par 28 * You should have received a copy of the GNU General Public 29 * License along with this program; if not, see 30 * http://www.gnu.org/copyleft/gpl.html 31 */ 32 33 #pragma once 34 35 #include <ogdf/planarity/PlanRep.h> 36 37 38 namespace ogdf { 39 40 41 //! Representation of an in- or outpoint 42 struct InOutPoint 43 { 44 int m_dx, m_dy; 45 adjEntry m_adj; 46 InOutPointInOutPoint47 InOutPoint() { 48 m_dx = m_dy = 0; m_adj = nullptr; 49 } InOutPointInOutPoint50 explicit InOutPoint(adjEntry adj) { 51 m_adj = adj; m_dx = m_dy = 0; 52 } 53 }; 54 55 56 //! Representation of in- and outpoint lists 57 class IOPoints { 58 public: IOPoints()59 IOPoints() { } IOPoints(const Graph & G)60 explicit IOPoints(const Graph &G) : m_depth(G,0), m_height(G,0), m_in(G), m_out(G), 61 m_mark(G,false), m_pointOf(G,nullptr) { } 62 ~IOPoints()63 ~IOPoints () { } 64 65 66 // length of in- or outpoint list out(node v)67 int out(node v) const { 68 return m_out[v].size(); 69 } in(node v)70 int in(node v) const { 71 return m_in[v].size(); 72 } 73 74 // getting a const-reference to in- or outpoint list inpoints(node v)75 const List<InOutPoint> &inpoints(node v) const { 76 return m_in [v]; 77 } inpoints(node v)78 List<InOutPoint> &inpoints(node v) { 79 return m_in [v]; 80 } 81 outpoints(node v)82 const List<InOutPoint> &outpoints(node v) const { 83 return m_out [v]; 84 } outpoints(node v)85 List<InOutPoint> &outpoints(node v) { 86 return m_out [v]; 87 } 88 89 // getting the in-/outpoint belonging to an adjacency entry pointOf(adjEntry adj)90 const InOutPoint *pointOf(adjEntry adj) const { 91 return m_pointOf[adj]; 92 } 93 94 // marking adjacency entries marked(adjEntry adj)95 bool marked(adjEntry adj) const { 96 return m_mark[adj]; 97 } 98 marked(node v)99 bool marked(node v) { 100 return v->outdeg() == 1 && marked(v->firstAdj()); 101 } 102 103 // finding outpoints belonging to non-marked edges firstRealOut(node v)104 ListConstIterator<InOutPoint> firstRealOut(node v) const { 105 return searchRealForward(m_out[v].begin()); 106 } 107 lastRealOut(node v)108 ListConstIterator<InOutPoint> lastRealOut(node v) const { 109 return searchRealBackward(m_out[v].rbegin()); 110 } 111 nextRealOut(ListConstIterator<InOutPoint> it)112 ListConstIterator<InOutPoint> nextRealOut(ListConstIterator<InOutPoint> it) const { 113 return searchRealForward(it.succ()); 114 } 115 prevRealOut(ListConstIterator<InOutPoint> it)116 ListConstIterator<InOutPoint> prevRealOut(ListConstIterator<InOutPoint> it) const { 117 return searchRealBackward(it.pred()); 118 } 119 120 // building in-/outpoint lists appendInpoint(adjEntry adj)121 void appendInpoint(adjEntry adj) { 122 node v = adj->theNode(); 123 m_pointOf[adj] = &(*m_in[v].pushBack(InOutPoint(adj))); 124 } appendOutpoint(adjEntry adj)125 void appendOutpoint(adjEntry adj) { 126 node v = adj->theNode(); 127 m_pointOf[adj] = &(*m_out[v].pushBack(InOutPoint(adj))); 128 } pushInpoint(adjEntry adj)129 void pushInpoint(adjEntry adj) { 130 node v = adj->theNode(); 131 m_pointOf[adj] = &(*m_in[v].pushFront(InOutPoint(adj))); 132 } 133 134 // setting relative coordinates setOutCoord(ListIterator<InOutPoint> it,int dx,int dy)135 void setOutCoord (ListIterator<InOutPoint> it, int dx, int dy) { 136 (*it).m_dx = dx; 137 (*it).m_dy = dy; 138 } setInCoord(ListIterator<InOutPoint> it,int dx,int dy)139 void setInCoord (ListIterator<InOutPoint> it, int dx, int dy) { 140 (*it).m_dx = dx; 141 (*it).m_dy = dy; 142 } 143 setOutDx(ListIterator<InOutPoint> it,int dx)144 void setOutDx(ListIterator<InOutPoint> it, int dx) { 145 (*it).m_dx = dx; 146 } 147 148 void restoreDeg1Nodes(PlanRep &PG, ArrayBuffer<PlanRep::Deg1RestoreInfo> &S); 149 changeEdge(node v,adjEntry adj_new)150 void changeEdge(node v, adjEntry adj_new) { 151 m_out[v].popBack(); 152 appendInpoint(adj_new); 153 } 154 155 // belongs v to a chain (= at most to non-marked incoming edges isChain(node v)156 bool isChain(node v) const { 157 int i = 0; 158 for(const InOutPoint &iop : m_in[v]) 159 if (!marked(iop.m_adj)) ++i; 160 return i <= 2; 161 } 162 163 // width of the left-/right side of an in-/outpoint list outLeft(node v)164 int outLeft(node v) const { 165 return (m_out[v].empty()) ? 0 : (-m_out[v].front().m_dx); 166 } 167 outRight(node v)168 int outRight(node v) const { 169 return (m_out[v].empty()) ? 0 : (m_out[v].back().m_dx); 170 } 171 inLeft(node v)172 int inLeft(node v) const { 173 return (m_in[v].empty()) ? 0 : (-m_in[v].front().m_dx); 174 } 175 inRight(node v)176 int inRight(node v) const { 177 return (m_in[v].empty()) ? 0 : (m_in[v].back().m_dx); 178 } 179 maxLeft(node v)180 int maxLeft(node v) const { 181 return max(inLeft(v), outLeft(v)); 182 } 183 maxRight(node v)184 int maxRight(node v) const { 185 return max(inRight(v), outRight(v)); 186 } 187 maxPlusLeft(node v)188 int maxPlusLeft(node v) const { 189 return (in(v) >= 3) ? 190 max(inLeft(v)+1, outLeft(v)) : maxLeft(v); 191 } 192 maxPlusRight(node v)193 int maxPlusRight(node v) const { 194 return (in(v) >= 3) ? 195 max(inRight(v)+1, outRight(v)) : maxRight(v); 196 } 197 198 InOutPoint middleNeighbor(node z1) const; 199 200 void numDeg1(node v, int &xl, int &xr, 201 bool doubleCount) const; 202 203 adjEntry switchBeginIn(node v); 204 adjEntry switchEndIn (node v); 205 206 void switchBeginOut(node v); 207 void switchEndOut (node v); 208 209 210 NodeArray<int> m_depth, m_height; 211 212 213 private: 214 NodeArray<List<InOutPoint> > m_in, m_out; 215 AdjEntryArray<bool> m_mark; 216 AdjEntryArray<InOutPoint *> m_pointOf; 217 218 ListConstIterator<InOutPoint> searchRealForward (ListConstIterator<InOutPoint> it) const; 219 ListConstIterator<InOutPoint> searchRealBackward(ListConstIterator<InOutPoint> it) const; 220 }; 221 222 } 223