| | 1 | /* -*- mode: C++; indent-tabs-mode: nil; -*- |
| | 2 | * |
| | 3 | * This file is a part of LEMON, a generic C++ optimization library. |
| | 4 | * |
| | 5 | * Copyright (C) 2003-2010 |
| | 6 | * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
| | 7 | * (Egervary Research Group on Combinatorial Optimization, EGRES). |
| | 8 | * |
| | 9 | * Permission to use, modify and distribute this software is granted |
| | 10 | * provided that this copyright notice appears in all copies. For |
| | 11 | * precise terms see the accompanying LICENSE file. |
| | 12 | * |
| | 13 | * This software is provided "AS IS" with no warranty of any kind, |
| | 14 | * express or implied, and with no claim as to its suitability for any |
| | 15 | * purpose. |
| | 16 | * |
| | 17 | */ |
| | 18 | |
| | 19 | #ifndef LEMON_PLANAR_GRAPH_H |
| | 20 | #define LEMON_PLANAR_GRAPH_H |
| | 21 | |
| | 22 | ///\ingroup graphs |
| | 23 | ///\file |
| | 24 | ///\brief PlanarGraph classes. UNDER CONSTRUCTION. |
| | 25 | |
| | 26 | #include <lemon/core.h> |
| | 27 | #include <lemon/error.h> |
| | 28 | #include <lemon/bits/graph_extender.h> |
| | 29 | #include <lemon/planarity.h> |
| | 30 | |
| | 31 | #include <vector> |
| | 32 | #include <list> |
| | 33 | #include <set> |
| | 34 | |
| | 35 | #ifdef REMOVE_BEFORE_RELEASE |
| | 36 | #include <iostream> |
| | 37 | #endif |
| | 38 | |
| | 39 | namespace lemon { |
| | 40 | |
| | 41 | class PlanarGraphBase { |
| | 42 | |
| | 43 | protected: |
| | 44 | |
| | 45 | struct NodeT { |
| | 46 | int first_out, last_out; |
| | 47 | int prev, next; |
| | 48 | int outer_face; |
| | 49 | int component; |
| | 50 | }; |
| | 51 | |
| | 52 | struct ArcT { |
| | 53 | int target; |
| | 54 | int left_face; |
| | 55 | int prev_out, next_out; |
| | 56 | }; |
| | 57 | |
| | 58 | struct FaceT { |
| | 59 | int first_arc; |
| | 60 | int prev, next; |
| | 61 | }; |
| | 62 | |
| | 63 | struct ComponentT { |
| | 64 | int num_nodes; |
| | 65 | int prev, next; |
| | 66 | }; |
| | 67 | |
| | 68 | std::vector<NodeT> nodes; |
| | 69 | int first_node; |
| | 70 | int first_free_node; |
| | 71 | |
| | 72 | std::vector<ArcT> arcs; |
| | 73 | int first_free_arc; |
| | 74 | |
| | 75 | std::vector<FaceT> faces; |
| | 76 | int first_face; |
| | 77 | int first_free_face; |
| | 78 | |
| | 79 | std::vector<ComponentT> components; |
| | 80 | int first_component; |
| | 81 | int first_free_component; |
| | 82 | |
| | 83 | public: |
| | 84 | |
| | 85 | typedef PlanarGraphBase Graph; |
| | 86 | |
| | 87 | class Node { |
| | 88 | friend class PlanarGraphBase; |
| | 89 | protected: |
| | 90 | |
| | 91 | int id; |
| | 92 | explicit Node(int pid) { |
| | 93 | id = pid; |
| | 94 | } |
| | 95 | |
| | 96 | public: |
| | 97 | Node() {} |
| | 98 | Node (Invalid) { |
| | 99 | id = -1; |
| | 100 | } |
| | 101 | bool operator==(const Node& node) const { |
| | 102 | return id == node.id; |
| | 103 | } |
| | 104 | bool operator!=(const Node& node) const { |
| | 105 | return id != node.id; |
| | 106 | } |
| | 107 | bool operator<(const Node& node) const { |
| | 108 | return id < node.id; |
| | 109 | } |
| | 110 | }; |
| | 111 | |
| | 112 | class Edge { |
| | 113 | friend class PlanarGraphBase; |
| | 114 | protected: |
| | 115 | |
| | 116 | int id; |
| | 117 | explicit Edge(int pid) { |
| | 118 | id = pid; |
| | 119 | } |
| | 120 | |
| | 121 | public: |
| | 122 | Edge() {} |
| | 123 | Edge (Invalid) { |
| | 124 | id = -1; |
| | 125 | } |
| | 126 | bool operator==(const Edge& edge) const { |
| | 127 | return id == edge.id; |
| | 128 | } |
| | 129 | bool operator!=(const Edge& edge) const { |
| | 130 | return id != edge.id; |
| | 131 | } |
| | 132 | bool operator<(const Edge& edge) const { |
| | 133 | return id < edge.id; |
| | 134 | } |
| | 135 | }; |
| | 136 | |
| | 137 | class Arc { |
| | 138 | friend class PlanarGraphBase; |
| | 139 | protected: |
| | 140 | |
| | 141 | int id; |
| | 142 | explicit Arc(int pid) { |
| | 143 | id = pid; |
| | 144 | } |
| | 145 | |
| | 146 | public: |
| | 147 | operator Edge() const { |
| | 148 | return id != -1 ? edgeFromId(id / 2) : INVALID; |
| | 149 | } |
| | 150 | |
| | 151 | Arc() {} |
| | 152 | Arc (Invalid) { |
| | 153 | id = -1; |
| | 154 | } |
| | 155 | bool operator==(const Arc& arc) const { |
| | 156 | return id == arc.id; |
| | 157 | } |
| | 158 | bool operator!=(const Arc& arc) const { |
| | 159 | return id != arc.id; |
| | 160 | } |
| | 161 | bool operator<(const Arc& arc) const { |
| | 162 | return id < arc.id; |
| | 163 | } |
| | 164 | }; |
| | 165 | |
| | 166 | class Face { |
| | 167 | friend class PlanarGraphBase; |
| | 168 | protected: |
| | 169 | |
| | 170 | int id; |
| | 171 | explicit Face(int pid) { |
| | 172 | id = pid; |
| | 173 | } |
| | 174 | |
| | 175 | public: |
| | 176 | Face() {} |
| | 177 | Face (Invalid) { |
| | 178 | id = -1; |
| | 179 | } |
| | 180 | bool operator==(const Face& face) const { |
| | 181 | return id == face.id; |
| | 182 | } |
| | 183 | bool operator!=(const Face& face) const { |
| | 184 | return id != face.id; |
| | 185 | } |
| | 186 | bool operator<(const Face& face) const { |
| | 187 | return id < face.id; |
| | 188 | } |
| | 189 | }; |
| | 190 | |
| | 191 | PlanarGraphBase() |
| | 192 | : nodes(), first_node(-1), first_free_node(-1), |
| | 193 | arcs(), first_free_arc(-1), |
| | 194 | faces(), first_face(-1), first_free_face(-1), |
| | 195 | components(), first_component(-1), first_free_component(-1) { |
| | 196 | } |
| | 197 | |
| | 198 | |
| | 199 | int maxNodeId() const { |
| | 200 | return nodes.size()-1; |
| | 201 | } |
| | 202 | int maxEdgeId() const { |
| | 203 | return arcs.size() / 2 - 1; |
| | 204 | } |
| | 205 | int maxArcId() const { |
| | 206 | return arcs.size()-1; |
| | 207 | } |
| | 208 | int maxFaceId() const { |
| | 209 | return faces.size()-1; |
| | 210 | } |
| | 211 | |
| | 212 | int numComponents() const { |
| | 213 | int result = 0; |
| | 214 | int c = first_component; |
| | 215 | while (c != -1) { |
| | 216 | ++result; |
| | 217 | c = components[c].next; |
| | 218 | } |
| | 219 | return result; |
| | 220 | } |
| | 221 | |
| | 222 | Node source(Arc e) const { |
| | 223 | return Node(arcs[e.id ^ 1].target); |
| | 224 | } |
| | 225 | Node target(Arc e) const { |
| | 226 | return Node(arcs[e.id].target); |
| | 227 | } |
| | 228 | Face leftFace(Arc e) const { |
| | 229 | return Face(arcs[e.id].left_face); |
| | 230 | } |
| | 231 | Face rightFace(Arc e) const { |
| | 232 | return Face(arcs[e.id ^ 1].left_face); |
| | 233 | } |
| | 234 | Face outerFace(Node n) const { |
| | 235 | return Face(nodes[n.id].outer_face); |
| | 236 | } |
| | 237 | |
| | 238 | Node u(Edge e) const { |
| | 239 | return Node(arcs[2 * e.id].target); |
| | 240 | } |
| | 241 | Node v(Edge e) const { |
| | 242 | return Node(arcs[2 * e.id + 1].target); |
| | 243 | } |
| | 244 | Face w1(Edge e) const { |
| | 245 | return Face(arcs[2 * e.id].left_face); |
| | 246 | } |
| | 247 | Face w2(Edge e) const { |
| | 248 | return Face(arcs[2 * e.id + 1].left_face); |
| | 249 | } |
| | 250 | |
| | 251 | static bool direction(Arc e) { |
| | 252 | return (e.id & 1) == 1; |
| | 253 | } |
| | 254 | |
| | 255 | static Arc direct(Edge e, bool d) { |
| | 256 | return Arc(e.id * 2 + (d ? 1 : 0)); |
| | 257 | } |
| | 258 | |
| | 259 | //Primitives to use in iterators |
| | 260 | void first(Node& node) const { |
| | 261 | node.id = first_node; |
| | 262 | } |
| | 263 | |
| | 264 | void next(Node& node) const { |
| | 265 | node.id = nodes[node.id].next; |
| | 266 | } |
| | 267 | |
| | 268 | void first(Arc& e) const { |
| | 269 | int n = first_node; |
| | 270 | while (n != -1 && nodes[n].first_out == -1) { |
| | 271 | n = nodes[n].next; |
| | 272 | } |
| | 273 | e.id = (n == -1) ? -1 : nodes[n].first_out; |
| | 274 | } |
| | 275 | |
| | 276 | void next(Arc& e) const { |
| | 277 | if (arcs[e.id].next_out != -1) { |
| | 278 | e.id = arcs[e.id].next_out; |
| | 279 | } else { |
| | 280 | int n = nodes[arcs[e.id ^ 1].target].next; |
| | 281 | while (n != -1 && nodes[n].first_out == -1) { |
| | 282 | n = nodes[n].next; |
| | 283 | } |
| | 284 | e.id = (n == -1) ? -1 : nodes[n].first_out; |
| | 285 | } |
| | 286 | } |
| | 287 | |
| | 288 | void first(Edge& e) const { |
| | 289 | int n = first_node; |
| | 290 | while (n != -1) { |
| | 291 | e.id = nodes[n].first_out; |
| | 292 | while ((e.id & 1) != 1) { |
| | 293 | e.id = arcs[e.id].next_out; |
| | 294 | } |
| | 295 | if (e.id != -1) { |
| | 296 | e.id /= 2; |
| | 297 | return; |
| | 298 | } |
| | 299 | n = nodes[n].next; |
| | 300 | } |
| | 301 | e.id = -1; |
| | 302 | } |
| | 303 | |
| | 304 | void next(Edge& e) const { |
| | 305 | int n = arcs[e.id * 2].target; |
| | 306 | e.id = arcs[(e.id * 2) | 1].next_out; |
| | 307 | while ((e.id & 1) != 1) { |
| | 308 | e.id = arcs[e.id].next_out; |
| | 309 | } |
| | 310 | if (e.id != -1) { |
| | 311 | e.id /= 2; |
| | 312 | return; |
| | 313 | } |
| | 314 | n = nodes[n].next; |
| | 315 | while (n != -1) { |
| | 316 | e.id = nodes[n].first_out; |
| | 317 | while ((e.id & 1) != 1) { |
| | 318 | e.id = arcs[e.id].next_out; |
| | 319 | } |
| | 320 | if (e.id != -1) { |
| | 321 | e.id /= 2; |
| | 322 | return; |
| | 323 | } |
| | 324 | n = nodes[n].next; |
| | 325 | } |
| | 326 | e.id = -1; |
| | 327 | } |
| | 328 | |
| | 329 | void firstOut(Arc &e, const Node& v) const { |
| | 330 | e.id = nodes[v.id].first_out; |
| | 331 | } |
| | 332 | void nextOut(Arc &e) const { |
| | 333 | e.id = arcs[e.id].next_out; |
| | 334 | } |
| | 335 | |
| | 336 | void lastOut(Arc &e, const Node& v) const { |
| | 337 | e.id = nodes[v.id].last_out; |
| | 338 | } |
| | 339 | void prevOut(Arc &e) const { |
| | 340 | e.id = arcs[e.id].prev_out; |
| | 341 | } |
| | 342 | |
| | 343 | void firstIn(Arc &e, const Node& v) const { |
| | 344 | e.id = ((nodes[v.id].first_out) ^ 1); |
| | 345 | if (e.id == -2) e.id = -1; |
| | 346 | } |
| | 347 | void nextIn(Arc &e) const { |
| | 348 | e.id = ((arcs[e.id ^ 1].next_out) ^ 1); |
| | 349 | if (e.id == -2) e.id = -1; |
| | 350 | } |
| | 351 | void lastIn(Arc &e, const Node& v) const { |
| | 352 | e.id = ((nodes[v.id].last_out) ^ 1); |
| | 353 | if (e.id == -2) e.id = -1; |
| | 354 | } |
| | 355 | void prevIn(Arc &e) const { |
| | 356 | e.id = ((arcs[e.id ^ 1].prev_out) ^ 1); |
| | 357 | if (e.id == -2) e.id = -1; |
| | 358 | } |
| | 359 | |
| | 360 | void firstCcwF(Arc &e, const Face &f) const { |
| | 361 | e.id = faces[f.id].first_arc; |
| | 362 | turnRight(e); |
| | 363 | setToOpposite(e); |
| | 364 | } |
| | 365 | void nextCcwF(Arc &e) const { |
| | 366 | if (e.id == faces[arcs[e.id].left_face].first_arc) e = INVALID; |
| | 367 | else { |
| | 368 | turnRight(e); |
| | 369 | setToOpposite(e); |
| | 370 | } |
| | 371 | } |
| | 372 | void firstCwF(Arc &e, const Face &f) const { |
| | 373 | e.id = faces[f.id].first_arc; |
| | 374 | } |
| | 375 | void nextCwF(Arc &e) const { |
| | 376 | turnLeft(e); |
| | 377 | setToOpposite(e); |
| | 378 | if (e.id == faces[arcs[e.id].left_face].first_arc) e = INVALID; |
| | 379 | } |
| | 380 | |
| | 381 | void firstInF(Arc &e, const Face &f) const { |
| | 382 | e.id = faces[f.id].first_arc; |
| | 383 | } |
| | 384 | void nextInF(Arc &e) const { |
| | 385 | setToOpposite(e); |
| | 386 | turnRight(e); |
| | 387 | if (e.id == faces[arcs[e.id].left_face].first_arc) e = INVALID; |
| | 388 | } |
| | 389 | void lastInF(Arc &e, const Face &f) const { |
| | 390 | e.id = faces[f.id].first_arc; |
| | 391 | setToOpposite(e); |
| | 392 | turnRight(e); |
| | 393 | } |
| | 394 | void prevInF(Arc &e) const { |
| | 395 | if (e.id == faces[arcs[e.id].left_face].first_arc) { |
| | 396 | e = INVALID; |
| | 397 | return; |
| | 398 | } |
| | 399 | setToOpposite(e); |
| | 400 | turnRight(e); |
| | 401 | } |
| | 402 | |
| | 403 | void firstOutF(Arc &e, const Face &f) const { |
| | 404 | e.id = faces[e.id].first_arc ^ 1; |
| | 405 | } |
| | 406 | void nextOutF(Arc &e) const { |
| | 407 | turnRight(e); |
| | 408 | setToOpposite(e); |
| | 409 | if (e.id == faces[arcs[e.id ^ 1].left_face].first_arc) e = INVALID; |
| | 410 | } |
| | 411 | |
| | 412 | void first(Arc &arc, const Face& face) const { |
| | 413 | arc.id = faces[face.id].first_arc; |
| | 414 | } |
| | 415 | |
| | 416 | void turnLeftF(Arc &e) const { |
| | 417 | setToOpposite(e); |
| | 418 | turnRight(e); |
| | 419 | } |
| | 420 | |
| | 421 | void turnRightF(Arc &e) const { |
| | 422 | turnLeft(e); |
| | 423 | setToOpposite(e); |
| | 424 | } |
| | 425 | |
| | 426 | void turnLeft(Arc &e) const { |
| | 427 | if (arcs[e.id].next_out > -1) { |
| | 428 | e.id = arcs[e.id].next_out; |
| | 429 | } else { |
| | 430 | e.id = nodes[arcs[e.id ^ 1].target].first_out; |
| | 431 | } |
| | 432 | } |
| | 433 | void turnRight(Arc &e) const { |
| | 434 | if (arcs[e.id].prev_out > -1) { |
| | 435 | e.id = arcs[e.id].prev_out; |
| | 436 | } else { |
| | 437 | e.id = nodes[arcs[e.id ^ 1].target].last_out; |
| | 438 | } |
| | 439 | } |
| | 440 | void setToOpposite(Arc &a) const { |
| | 441 | if (a.id != -1) a.id ^= 1; |
| | 442 | } |
| | 443 | |
| | 444 | void firstInc(Edge &e, bool& d, const Node& v) const { |
| | 445 | int a = nodes[v.id].first_out; |
| | 446 | if (a != -1 ) { |
| | 447 | e.id = a / 2; |
| | 448 | d = ((a & 1) == 1); |
| | 449 | } else { |
| | 450 | e.id = -1; |
| | 451 | d = true; |
| | 452 | } |
| | 453 | } |
| | 454 | void nextInc(Edge &e, bool& d) const { |
| | 455 | int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out); |
| | 456 | if (a != -1 ) { |
| | 457 | e.id = a / 2; |
| | 458 | d = ((a & 1) == 1); |
| | 459 | } else { |
| | 460 | e.id = -1; |
| | 461 | d = true; |
| | 462 | } |
| | 463 | } |
| | 464 | |
| | 465 | void first(Face& face) const { |
| | 466 | face.id = first_face; |
| | 467 | } |
| | 468 | |
| | 469 | void next(Face& face) const { |
| | 470 | face.id = faces[face.id].next; |
| | 471 | } |
| | 472 | |
| | 473 | Arc arcAt(Node n, Edge e) { |
| | 474 | if (e.id == -1) return INVALID; |
| | 475 | return Arc((e.id*2) | (arcs[e.id*2].target == n.id?1:0)); |
| | 476 | } |
| | 477 | |
| | 478 | static int id(Node v) { |
| | 479 | return v.id; |
| | 480 | } |
| | 481 | static int id(Arc e) { |
| | 482 | return e.id; |
| | 483 | } |
| | 484 | static int id(Edge e) { |
| | 485 | return e.id; |
| | 486 | } |
| | 487 | static int id(Face f) { |
| | 488 | return f.id; |
| | 489 | } |
| | 490 | |
| | 491 | static Node nodeFromId(int id) { |
| | 492 | return Node(id); |
| | 493 | } |
| | 494 | static Arc arcFromId(int id) { |
| | 495 | return Arc(id); |
| | 496 | } |
| | 497 | static Edge edgeFromId(int id) { |
| | 498 | return Edge(id); |
| | 499 | } |
| | 500 | static Face faceFromId(int id) { |
| | 501 | return Face(id); |
| | 502 | } |
| | 503 | |
| | 504 | bool valid(Node n) const { |
| | 505 | return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && |
| | 506 | nodes[n.id].prev != -2; |
| | 507 | } |
| | 508 | |
| | 509 | bool valid(Arc a) const { |
| | 510 | return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && |
| | 511 | arcs[a.id].prev_out != -2; |
| | 512 | } |
| | 513 | |
| | 514 | bool valid(Edge e) const { |
| | 515 | return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) && |
| | 516 | arcs[2 * e.id].prev_out != -2; |
| | 517 | } |
| | 518 | |
| | 519 | bool valid(Face f) const { |
| | 520 | return f.id >= 0 && f.id < static_cast<int>(faces.size()) && |
| | 521 | faces[f.id].prev != -2; |
| | 522 | } |
| | 523 | |
| | 524 | Node addNode() { |
| | 525 | int n = link_node(); |
| | 526 | |
| | 527 | nodes[n].component = addComponent(); |
| | 528 | components[nodes[n].component].num_nodes = 1; |
| | 529 | nodes[n].outer_face = addFace().id; |
| | 530 | |
| | 531 | return Node(n); |
| | 532 | } |
| | 533 | |
| | 534 | Edge addEdge(Node u, Node v, Edge e_u, Edge e_v) { |
| | 535 | |
| | 536 | Arc p_u = arcAt(u,e_u); |
| | 537 | Arc p_v = arcAt(v,e_v); |
| | 538 | |
| | 539 | if (p_u.id > -1 && p_v.id > -1 && arcs[p_u.id].left_face != arcs[p_v.id]. |
| | 540 | left_face && nodes[u.id].component == nodes[v.id].component) return |
| | 541 | INVALID; |
| | 542 | |
| | 543 | int n = link_edge(); |
| | 544 | |
| | 545 | arcs[n].target = u.id; |
| | 546 | arcs[n | 1].target = v.id; |
| | 547 | |
| | 548 | arcs[n].prev_out = p_v.id; |
| | 549 | if (p_v.id > -1) { |
| | 550 | arcs[n].next_out = arcs[p_v.id].next_out; |
| | 551 | arcs[p_v.id].next_out = n; |
| | 552 | } else { |
| | 553 | arcs[n].next_out = nodes[v.id].first_out; |
| | 554 | nodes[v.id].first_out = n; |
| | 555 | } |
| | 556 | if (arcs[n].next_out > -1) { |
| | 557 | arcs[arcs[n].next_out].prev_out = n; |
| | 558 | } else { |
| | 559 | nodes[v.id].last_out = n; |
| | 560 | } |
| | 561 | |
| | 562 | arcs[n | 1].prev_out = p_u.id; |
| | 563 | if (p_u.id > -1) { |
| | 564 | arcs[n | 1].next_out = arcs[p_u.id].next_out; |
| | 565 | arcs[p_u.id].next_out = n | 1; |
| | 566 | } else { |
| | 567 | arcs[n | 1].next_out = nodes[u.id].first_out; |
| | 568 | nodes[u.id].first_out = n | 1; |
| | 569 | } |
| | 570 | if (arcs[n | 1].next_out > -1) { |
| | 571 | arcs[arcs[n | 1].next_out].prev_out = n | 1; |
| | 572 | } else { |
| | 573 | nodes[u.id].last_out = n | 1; |
| | 574 | } |
| | 575 | |
| | 576 | int ca = nodes[u.id].component; |
| | 577 | int cb = nodes[v.id].component; |
| | 578 | |
| | 579 | //Add the extra face, if needed |
| | 580 | if (p_u.id > -1 & p_v.id > -1) { |
| | 581 | int oldf = arcs[p_u.id].left_face; |
| | 582 | int oldfb = arcs[p_v.id].left_face; |
| | 583 | arcs[n].left_face = arcs[n | 1].left_face = oldf; |
| | 584 | Face f = addFace(); |
| | 585 | faces[f.id].first_arc = n | 1; |
| | 586 | faces[oldf].first_arc = n; |
| | 587 | Arc arc(n | 1); |
| | 588 | wall_paint(arc,f.id,arc); |
| | 589 | if (nodes[v.id].component != nodes[u.id].component) { |
| | 590 | erase(Face(oldf)); |
| | 591 | erase(Face(oldfb)); |
| | 592 | if (components[ca].num_nodes > components[cb].num_nodes) { |
| | 593 | component_relabel(v,ca); |
| | 594 | eraseComponent(cb); |
| | 595 | } else { |
| | 596 | component_relabel(u,cb); |
| | 597 | eraseComponent(ca); |
| | 598 | } |
| | 599 | } |
| | 600 | } else if (p_u.id > -1) { |
| | 601 | arcs[n].left_face = arcs[n | 1].left_face = arcs[p_u.id].left_face; |
| | 602 | faces[arcs[n].left_face].first_arc = n | 1; |
| | 603 | nodes[v.id].component = nodes[u.id].component; |
| | 604 | ++components[ca].num_nodes; |
| | 605 | eraseComponent(cb); |
| | 606 | erase(Face(nodes[v.id].outer_face)); |
| | 607 | } else if (p_v.id > -1) { |
| | 608 | arcs[n].left_face = arcs[n | 1].left_face = arcs[p_v.id].left_face; |
| | 609 | faces[arcs[n].left_face].first_arc = n | 1; |
| | 610 | ++components[cb].num_nodes; |
| | 611 | eraseComponent(ca); |
| | 612 | nodes[u.id].component = nodes[v.id].component; |
| | 613 | erase(Face(nodes[u.id].outer_face)); |
| | 614 | } else if (u.id != v.id) { //both prevs are INVALID |
| | 615 | Face f(nodes[u.id].outer_face); |
| | 616 | arcs[n].left_face = arcs[n | 1].left_face = f.id; |
| | 617 | faces[f.id].first_arc = n | 1; |
| | 618 | ++components[ca].num_nodes; |
| | 619 | eraseComponent(cb); |
| | 620 | nodes[v.id].component = nodes[u.id].component; |
| | 621 | erase(Face(nodes[v.id].outer_face)); |
| | 622 | } else { //insert a loop to a new node |
| | 623 | Face f(nodes[u.id].outer_face); |
| | 624 | Face f2 = addFace(); |
| | 625 | arcs[n].left_face = f2.id; |
| | 626 | arcs[n | 1].left_face = f.id; |
| | 627 | faces[f.id].first_arc = n | 1; |
| | 628 | faces[f2.id].first_arc = n; |
| | 629 | } |
| | 630 | |
| | 631 | nodes[u.id].outer_face = nodes[v.id].outer_face = -1; |
| | 632 | return Edge(n / 2); |
| | 633 | } |
| | 634 | |
| | 635 | void erase(const Node& node) { |
| | 636 | int n = node.id; |
| | 637 | |
| | 638 | eraseComponent(nodes[n].component); |
| | 639 | erase(Face(nodes[n].outer_face)); |
| | 640 | |
| | 641 | unlink_node(n); |
| | 642 | } |
| | 643 | |
| | 644 | void erase(const Edge& edge) { |
| | 645 | int n = edge.id * 2; |
| | 646 | |
| | 647 | //"retreat" the incident faces' first arcs |
| | 648 | int fl = arcs[n].left_face; |
| | 649 | if ((faces[fl].first_arc | 1) == (n | 1)) { |
| | 650 | Arc e(faces[fl].first_arc); |
| | 651 | turnRightF(e); |
| | 652 | if ((e.id | 1) == (n | 1)) turnRightF(e); |
| | 653 | faces[fl].first_arc = e.id; |
| | 654 | } |
| | 655 | |
| | 656 | int fr = arcs[n | 1].left_face; |
| | 657 | |
| | 658 | bool comp_split = false; |
| | 659 | if (fr != fl) { |
| | 660 | Arc arc(faces[fr].first_arc); |
| | 661 | wall_paint(arc,fl,arc); |
| | 662 | if ((faces[fl].first_arc | 1) == (n | 1)) |
| | 663 | faces[fl].first_arc = faces[fr].first_arc; |
| | 664 | erase(Face(fr)); |
| | 665 | } else { |
| | 666 | comp_split = true; |
| | 667 | if ((arcs[n].next_out > -1 || arcs[n].prev_out > -1) && |
| | 668 | (arcs[n | 1].next_out > -1 || arcs[n | 1].prev_out > -1)) { |
| | 669 | Arc arc(n); |
| | 670 | Arc ed = arc; |
| | 671 | ed.id ^= 1; |
| | 672 | turnRightF(arc); |
| | 673 | Face f = addFace(); |
| | 674 | wall_paint(arc,f.id,ed); |
| | 675 | faces[f.id].first_arc = arc.id; |
| | 676 | turnRightF(ed); |
| | 677 | faces[fr].first_arc = ed.id; |
| | 678 | } |
| | 679 | } |
| | 680 | |
| | 681 | if (arcs[n].next_out != -1) { |
| | 682 | arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
| | 683 | } else { |
| | 684 | nodes[arcs[n].target].last_out = arcs[n].prev_out; |
| | 685 | } |
| | 686 | |
| | 687 | if (arcs[n].prev_out != -1) { |
| | 688 | arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
| | 689 | } else { |
| | 690 | nodes[arcs[n | 1].target].first_out = arcs[n].next_out; |
| | 691 | } |
| | 692 | |
| | 693 | if (arcs[n | 1].next_out != -1) { |
| | 694 | arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out; |
| | 695 | } else { |
| | 696 | nodes[arcs[n | 1].target].last_out = arcs[n | 1].prev_out; |
| | 697 | } |
| | 698 | |
| | 699 | if (arcs[n | 1].prev_out != -1) { |
| | 700 | arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out; |
| | 701 | } else { |
| | 702 | nodes[arcs[n].target].first_out = arcs[n | 1].next_out; |
| | 703 | } |
| | 704 | |
| | 705 | unlink_edge(edge); |
| | 706 | |
| | 707 | if (comp_split) component_relabel(Node(arcs[n | 1].target), |
| | 708 | addComponent()); |
| | 709 | if (nodes[arcs[n].target].first_out == -1 && nodes[arcs[n | 1].target]. |
| | 710 | first_out == -1) { |
| | 711 | int t1 = arcs[n].target; |
| | 712 | int t2 = arcs[n | 1].target; |
| | 713 | if (t1 != t2) { |
| | 714 | nodes[t1].outer_face = addFace().id; |
| | 715 | nodes[t2].outer_face = fr; |
| | 716 | } else { |
| | 717 | faces[fl].first_arc = -1; |
| | 718 | nodes[t1].outer_face = fl; |
| | 719 | } |
| | 720 | } else if (nodes[arcs[n].target].first_out == -1) |
| | 721 | nodes[arcs[n].target].outer_face = addFace().id; |
| | 722 | else if (nodes[arcs[n | 1].target].first_out == -1) |
| | 723 | nodes[arcs[n | 1].target].outer_face = addFace().id; |
| | 724 | |
| | 725 | } |
| | 726 | |
| | 727 | void clear() { |
| | 728 | arcs.clear(); |
| | 729 | nodes.clear(); |
| | 730 | faces.clear(); |
| | 731 | components.clear(); |
| | 732 | first_node = first_free_node = first_free_arc = first_face = |
| | 733 | first_free_face = first_component = first_free_component = -1; |
| | 734 | } |
| | 735 | |
| | 736 | Node split(Edge e) { |
| | 737 | Node v; |
| | 738 | Edge e2; |
| | 739 | inner_split1(v,e2); |
| | 740 | return inner_split2(e,v,e2); |
| | 741 | } |
| | 742 | |
| | 743 | Node split(Node n1, Edge e1, Edge e2, bool b) { |
| | 744 | Node n2; |
| | 745 | inner_split1(n1,n2); |
| | 746 | Edge a3; |
| | 747 | inner_split2(n1,n2,e1,e2,b,a3); |
| | 748 | if (!b && a3 != INVALID) erase(a3); |
| | 749 | return n2; |
| | 750 | } |
| | 751 | |
| | 752 | void contract(Edge e) { |
| | 753 | Node n1 = u(e); |
| | 754 | Node n2 = v(e); |
| | 755 | Node nd; |
| | 756 | bool simple; |
| | 757 | inner_contract1(n1,n2,nd,simple); |
| | 758 | inner_contract2(e,n1,n2,nd,simple); |
| | 759 | } |
| | 760 | |
| | 761 | protected: |
| | 762 | |
| | 763 | //Adds a node to the linked list and sets default properties. Used by |
| | 764 | //addNode and other functions that take care of the planar properties by |
| | 765 | //themselves. |
| | 766 | int link_node() { |
| | 767 | int n; |
| | 768 | if (first_free_node==-1) { |
| | 769 | n = nodes.size(); |
| | 770 | nodes.push_back(NodeT()); |
| | 771 | } else { |
| | 772 | n = first_free_node; |
| | 773 | first_free_node = nodes[n].next; |
| | 774 | } |
| | 775 | |
| | 776 | nodes[n].next = first_node; |
| | 777 | if (first_node != -1) nodes[first_node].prev = n; |
| | 778 | first_node = n; |
| | 779 | nodes[n].prev = -1; |
| | 780 | nodes[n].first_out = nodes[n].last_out = -1; |
| | 781 | return n; |
| | 782 | } |
| | 783 | |
| | 784 | //Removes a node from the linked list. Used by |
| | 785 | //erase(Node) and other functions that take care of the planar properties by |
| | 786 | //themselves. |
| | 787 | void unlink_node(int n) { |
| | 788 | if (nodes[n].next != -1) { |
| | 789 | nodes[nodes[n].next].prev = nodes[n].prev; |
| | 790 | } |
| | 791 | |
| | 792 | if (nodes[n].prev != -1) { |
| | 793 | nodes[nodes[n].prev].next = nodes[n].next; |
| | 794 | } else { |
| | 795 | first_node = nodes[n].next; |
| | 796 | } |
| | 797 | |
| | 798 | nodes[n].next = first_free_node; |
| | 799 | first_free_node = n; |
| | 800 | nodes[n].prev = -2; |
| | 801 | } |
| | 802 | |
| | 803 | //Adds an edge to the linked list. Used by |
| | 804 | //addEdge and other functions that take care of the planar properties by |
| | 805 | //themselves. |
| | 806 | int link_edge() { |
| | 807 | int n; |
| | 808 | if (first_free_arc == -1) { |
| | 809 | n = arcs.size(); |
| | 810 | arcs.push_back(ArcT()); |
| | 811 | arcs.push_back(ArcT()); |
| | 812 | } else { |
| | 813 | n = first_free_arc; |
| | 814 | first_free_arc = arcs[n].next_out; |
| | 815 | } |
| | 816 | return n; |
| | 817 | } |
| | 818 | |
| | 819 | //Removes an edge from the linked list. Used by |
| | 820 | //erase(Edge) and other functions that take care of the planar properties by |
| | 821 | //themselves. |
| | 822 | void unlink_edge(Edge e) { |
| | 823 | int n = e.id*2; |
| | 824 | arcs[n].next_out = first_free_arc; |
| | 825 | first_free_arc = n; |
| | 826 | arcs[n].prev_out = -2; |
| | 827 | arcs[n | 1].prev_out = -2; |
| | 828 | } |
| | 829 | |
| | 830 | //Primitives of split(Edge) |
| | 831 | void inner_split1(Node &v, Edge &e2) { |
| | 832 | v = Node(link_node()); |
| | 833 | e2 = Arc(link_edge()); |
| | 834 | } |
| | 835 | |
| | 836 | Node inner_split2(Edge e, Node v, Edge e2) { |
| | 837 | Arc a(e.id*2); |
| | 838 | int b = e2.id*2; |
| | 839 | nodes[v.id].component = nodes[arcs[a.id].target].component; |
| | 840 | ++components[nodes[v.id].component].num_nodes; |
| | 841 | nodes[v.id].first_out = a.id; |
| | 842 | nodes[v.id].last_out = b | 1; |
| | 843 | |
| | 844 | arcs[b] = arcs[a.id]; |
| | 845 | arcs[b].target = v.id; |
| | 846 | if (arcs[a.id].next_out > -1) |
| | 847 | arcs[arcs[a.id].next_out].prev_out = b; |
| | 848 | else |
| | 849 | nodes[arcs[a.id | 1].target].last_out = b; |
| | 850 | if (arcs[a.id].prev_out > -1) |
| | 851 | arcs[arcs[a.id].prev_out].next_out = b; |
| | 852 | else |
| | 853 | nodes[arcs[a.id | 1].target].first_out = b; |
| | 854 | |
| | 855 | arcs[b | 1] = arcs[a.id | 1]; |
| | 856 | arcs[b | 1].next_out = -1; |
| | 857 | arcs[b | 1].prev_out = a.id; |
| | 858 | |
| | 859 | arcs[a.id].next_out = b | 1; |
| | 860 | arcs[a.id].prev_out = -1; |
| | 861 | arcs[a.id | 1].target = v.id; |
| | 862 | |
| | 863 | return v; |
| | 864 | } |
| | 865 | |
| | 866 | //Primitives of contract(Edge) |
| | 867 | void inner_contract1(Node n1, Node n2, Node &to_delete, bool &simple) { |
| | 868 | if (nodes[n1.id].first_out == nodes[n1.id].last_out) { |
| | 869 | simple = true; |
| | 870 | to_delete = n1; |
| | 871 | } else if (nodes[n2.id].first_out == nodes[n2.id].last_out) { |
| | 872 | simple = true; |
| | 873 | to_delete = n2; |
| | 874 | } else { |
| | 875 | simple = false; |
| | 876 | to_delete = n2; |
| | 877 | } |
| | 878 | } |
| | 879 | |
| | 880 | void inner_contract2(Edge e, Node n1, Node n2, Node &to_delete, bool |
| | 881 | &simple) { |
| | 882 | if (simple) { |
| | 883 | erase(e); |
| | 884 | erase(to_delete); |
| | 885 | return; |
| | 886 | } |
| | 887 | Arc a(e.id*2); |
| | 888 | int fl = arcs[a.id].left_face; |
| | 889 | if ((faces[fl].first_arc | 1) == a.id | 1) { |
| | 890 | Arc b = a; |
| | 891 | turnRightF(b); |
| | 892 | faces[fl].first_arc = b.id; |
| | 893 | } |
| | 894 | int fr = arcs[a.id | 1].left_face; |
| | 895 | if ((faces[fr].first_arc | 1) == a.id | 1) { |
| | 896 | Arc b(a.id | 1); |
| | 897 | turnRightF(b); |
| | 898 | faces[fr].first_arc = b.id; |
| | 899 | } |
| | 900 | Arc b = a; |
| | 901 | turnLeft(b); |
| | 902 | while (b != a) { |
| | 903 | arcs[b.id ^ 1].target = n1.id; |
| | 904 | if (arcs[b.id].next_out > -1) |
| | 905 | b.id = arcs[b.id].next_out; |
| | 906 | else |
| | 907 | b.id = nodes[n2.id].first_out; |
| | 908 | } |
| | 909 | arcs[nodes[n2.id].last_out].next_out = nodes[n2.id].first_out; |
| | 910 | arcs[nodes[n2.id].first_out].prev_out = nodes[n2.id].last_out; |
| | 911 | if (arcs[a.id | 1].prev_out > -1) { |
| | 912 | arcs[arcs[a.id | 1].prev_out].next_out = arcs[a.id].next_out; |
| | 913 | } else { |
| | 914 | nodes[n1.id].first_out = arcs[a.id].next_out; |
| | 915 | } |
| | 916 | arcs[arcs[a.id].next_out].prev_out = arcs[a.id | 1].prev_out; |
| | 917 | if (arcs[a.id | 1].next_out > -1) { |
| | 918 | arcs[arcs[a.id | 1].next_out].prev_out = arcs[a.id].prev_out; |
| | 919 | } else { |
| | 920 | nodes[n1.id].last_out = arcs[a.id].prev_out; |
| | 921 | } |
| | 922 | arcs[arcs[a.id].prev_out].next_out = arcs[a.id | 1].next_out; |
| | 923 | |
| | 924 | unlink_edge(e); |
| | 925 | --components[nodes[n2.id].component].num_nodes; |
| | 926 | unlink_node(n2.id); |
| | 927 | } |
| | 928 | |
| | 929 | //Primitives of split(Node) |
| | 930 | void inner_split1(Node n1, Node &n2) { |
| | 931 | n2 = Node(link_node()); |
| | 932 | } |
| | 933 | |
| | 934 | void inner_split2(Node n1, Node n2, Edge e1, Edge e2, bool b, Edge &e3) { |
| | 935 | e3 = INVALID; |
| | 936 | if (nodes[n1.id].first_out == -1) { |
| | 937 | if (b) e3 = addEdge(n1,n2,INVALID,INVALID); |
| | 938 | return; |
| | 939 | } |
| | 940 | arcs[nodes[n1.id].first_out].prev_out = nodes[n1.id].last_out; |
| | 941 | arcs[nodes[n1.id].last_out].next_out = nodes[n1.id].first_out; |
| | 942 | nodes[n2.id].component = nodes[n1.id].component; |
| | 943 | ++components[nodes[n2.id].component].num_nodes; |
| | 944 | Arc a1(e1.id*2); |
| | 945 | if (arcs[a1.id].target != n1.id) a1.id |= 1; |
| | 946 | Arc a2(e2.id*2); |
| | 947 | if (arcs[a2.id].target != n1.id) a2.id |= 1; |
| | 948 | Arc a3(link_edge()); |
| | 949 | e3 = a3; |
| | 950 | arcs[a3.id].target = n1.id; |
| | 951 | arcs[a3.id | 1].target = n2.id; |
| | 952 | arcs[a3.id].left_face = arcs[a1.id].left_face; |
| | 953 | arcs[a3.id | 1].left_face = arcs[a2.id].left_face; |
| | 954 | |
| | 955 | arcs[a3.id].prev_out = arcs[a2.id ^ 1].prev_out; |
| | 956 | arcs[arcs[a2.id ^ 1].prev_out].next_out = a3.id; |
| | 957 | arcs[a3.id | 1].prev_out = arcs[a1.id ^ 1].prev_out; |
| | 958 | arcs[arcs[a1.id ^ 1].prev_out].next_out = a3.id | 1; |
| | 959 | nodes[n1.id].first_out = a2.id ^ 1; |
| | 960 | arcs[a1.id ^ 1].prev_out = -1; |
| | 961 | nodes[n1.id].last_out = a3.id | 1; |
| | 962 | arcs[a3.id | 1].next_out = -1; |
| | 963 | nodes[n2.id].first_out = a1.id ^ 1; |
| | 964 | arcs[a2.id ^ 1].prev_out = -1; |
| | 965 | nodes[n2.id].last_out = a3.id; |
| | 966 | arcs[a3.id].next_out = -1; |
| | 967 | |
| | 968 | Arc a4(a1.id); |
| | 969 | while (a4.id != (a3.id | 1)) { |
| | 970 | arcs[a4.id].target = n2.id; |
| | 971 | a4.id = arcs[a4.id ^ 1].next_out ^ 1; |
| | 972 | } |
| | 973 | } |
| | 974 | |
| | 975 | //Relabels the "wall" of a face with a new face ID. |
| | 976 | void wall_paint(Arc arc, int f_id, Arc ed) { |
| | 977 | do { |
| | 978 | arcs[arc.id].left_face = f_id; |
| | 979 | turnRightF(arc); |
| | 980 | } while (arc != ed); |
| | 981 | } |
| | 982 | |
| | 983 | //Relabels a component with a new component ID. |
| | 984 | void component_relabel(Node node, int comp_id) { |
| | 985 | std::vector<int> ns(nodes.size()); |
| | 986 | std::list<int> q; |
| | 987 | q.push_back(node.id); |
| | 988 | ns[node.id] = 1; |
| | 989 | int cnt = 0; |
| | 990 | while (!q.empty()) { |
| | 991 | int n = q.front(); |
| | 992 | ns[n] = 2; |
| | 993 | --components[nodes[n].component].num_nodes; |
| | 994 | nodes[n].component = comp_id; |
| | 995 | ++cnt; |
| | 996 | q.pop_front(); |
| | 997 | Arc arc; |
| | 998 | firstOut(arc,Node(n)); |
| | 999 | while (arc.id > -1) { |
| | 1000 | int m = arcs[arc.id].target; |
| | 1001 | if (ns[m] == 0 && nodes[m].component != comp_id) { |
| | 1002 | ns[m] = 1; |
| | 1003 | q.push_back(m); |
| | 1004 | } |
| | 1005 | nextOut(arc); |
| | 1006 | } |
| | 1007 | } |
| | 1008 | components[comp_id].num_nodes += cnt; |
| | 1009 | } |
| | 1010 | |
| | 1011 | Face addFace() { |
| | 1012 | int n; |
| | 1013 | |
| | 1014 | if (first_free_face==-1) { |
| | 1015 | n = faces.size(); |
| | 1016 | faces.push_back(FaceT()); |
| | 1017 | } else { |
| | 1018 | n = first_free_face; |
| | 1019 | first_free_face = faces[n].next; |
| | 1020 | } |
| | 1021 | |
| | 1022 | faces[n].next = first_face; |
| | 1023 | if (first_face != -1) faces[first_face].prev = n; |
| | 1024 | first_face = n; |
| | 1025 | faces[n].prev = -1; |
| | 1026 | |
| | 1027 | faces[n].first_arc = -1; |
| | 1028 | |
| | 1029 | return Face(n); |
| | 1030 | } |
| | 1031 | |
| | 1032 | void erase(const Face& face) { |
| | 1033 | int n = face.id; |
| | 1034 | |
| | 1035 | if (faces[n].next != -1) { |
| | 1036 | faces[faces[n].next].prev = faces[n].prev; |
| | 1037 | } |
| | 1038 | |
| | 1039 | if (faces[n].prev != -1) { |
| | 1040 | faces[faces[n].prev].next = faces[n].next; |
| | 1041 | } else { |
| | 1042 | first_face = faces[n].next; |
| | 1043 | } |
| | 1044 | |
| | 1045 | faces[n].next = first_free_face; |
| | 1046 | first_free_face = n; |
| | 1047 | faces[n].prev = -2; |
| | 1048 | } |
| | 1049 | |
| | 1050 | int addComponent() { |
| | 1051 | int n; |
| | 1052 | |
| | 1053 | if (first_free_component==-1) { |
| | 1054 | n = components.size(); |
| | 1055 | components.push_back(ComponentT()); |
| | 1056 | } else { |
| | 1057 | n = first_free_component; |
| | 1058 | first_free_component = components[n].next; |
| | 1059 | } |
| | 1060 | |
| | 1061 | components[n].next = first_component; |
| | 1062 | if (first_component != -1) components[first_component].prev = n; |
| | 1063 | first_component = n; |
| | 1064 | components[n].prev = -1; |
| | 1065 | |
| | 1066 | components[n].num_nodes = 0; |
| | 1067 | |
| | 1068 | return n; |
| | 1069 | } |
| | 1070 | |
| | 1071 | void eraseComponent(const int n) { |
| | 1072 | |
| | 1073 | if (components[n].next != -1) { |
| | 1074 | components[components[n].next].prev = components[n].prev; |
| | 1075 | } |
| | 1076 | |
| | 1077 | if (components[n].prev != -1) { |
| | 1078 | components[components[n].prev].next = components[n].next; |
| | 1079 | } else { |
| | 1080 | first_component = components[n].next; |
| | 1081 | } |
| | 1082 | |
| | 1083 | components[n].next = first_free_component; |
| | 1084 | first_free_component = n; |
| | 1085 | components[n].prev = -2; |
| | 1086 | } |
| | 1087 | |
| | 1088 | int idComponent(Node n) |
| | 1089 | { |
| | 1090 | return nodes[n.id].component; |
| | 1091 | } |
| | 1092 | |
| | 1093 | #ifdef REMOVE_BEFORE_RELEASE |
| | 1094 | public: |
| | 1095 | void print() { |
| | 1096 | std::cout << "Nodes: " << std::endl; |
| | 1097 | for (int i=0; i<nodes.size(); ++i) |
| | 1098 | std::cout << i << ":" |
| | 1099 | << " fo=" << nodes[i].first_out |
| | 1100 | << " lo=" << nodes[i].last_out |
| | 1101 | << " pr=" << nodes[i].prev |
| | 1102 | << " nx=" << nodes[i].next |
| | 1103 | << " co=" << nodes[i].component |
| | 1104 | << " of=" << nodes[i].outer_face |
| | 1105 | <<std::endl; |
| | 1106 | std::cout << "Arcs: " << std::endl; |
| | 1107 | for (int i=0; i<arcs.size(); ++i) { |
| | 1108 | if (arcs[i].next_out > -2) { |
| | 1109 | std::cout << i << ":" |
| | 1110 | << " tg=" << arcs[i].target |
| | 1111 | << " po=" << arcs[i].prev_out |
| | 1112 | << " no=" << arcs[i].next_out |
| | 1113 | << " lf=" << arcs[i].left_face |
| | 1114 | <<std::endl; |
| | 1115 | } else std::cout << i << ": (deleted)" << std::endl; |
| | 1116 | } |
| | 1117 | std::cout << "Faces: " << std::endl; |
| | 1118 | for (int i=0; i<faces.size(); ++i) { |
| | 1119 | if (faces[i].prev > -2) { |
| | 1120 | std::cout << i |
| | 1121 | << " pr=" << faces[i].prev |
| | 1122 | << " nx=" << faces[i].next |
| | 1123 | << " fa=" << faces[i].first_arc |
| | 1124 | <<std::endl; |
| | 1125 | } else std::cout << i << ": (deleted)" << std::endl; |
| | 1126 | } |
| | 1127 | std::cout << "Components: " << std::endl; |
| | 1128 | for (int i=0; i<components.size(); ++i) { |
| | 1129 | std::cout << i << ':'; |
| | 1130 | if (components[i].prev > -2) { |
| | 1131 | std::cout |
| | 1132 | << " pr=" << components[i].prev |
| | 1133 | << " nx=" << components[i].next |
| | 1134 | << " nn=" << components[i].num_nodes |
| | 1135 | <<std::endl; |
| | 1136 | } else std::cout << " (deleted)" << std::endl; |
| | 1137 | } |
| | 1138 | } |
| | 1139 | #endif |
| | 1140 | |
| | 1141 | }; |
| | 1142 | |
| | 1143 | // Face counting: |
| | 1144 | |
| | 1145 | namespace _core_bits { |
| | 1146 | |
| | 1147 | template <typename Graph, typename Enable = void> |
| | 1148 | struct CountFacesSelector { |
| | 1149 | static int count(const Graph &g) { |
| | 1150 | return countItems<Graph, typename Graph::Face>(g); |
| | 1151 | } |
| | 1152 | }; |
| | 1153 | |
| | 1154 | template <typename Graph> |
| | 1155 | struct CountFacesSelector< |
| | 1156 | Graph, typename |
| | 1157 | enable_if<typename Graph::FaceNumTag, void>::type> |
| | 1158 | { |
| | 1159 | static int count(const Graph &g) { |
| | 1160 | return g.faceNum(); |
| | 1161 | } |
| | 1162 | }; |
| | 1163 | } |
| | 1164 | |
| | 1165 | /// \brief Function to count the faces in the graph. |
| | 1166 | /// |
| | 1167 | /// This function counts the faces in the graph. |
| | 1168 | /// The complexity of the function is <em>O</em>(<em>n</em>), but for some |
| | 1169 | /// graph structures it is specialized to run in <em>O</em>(1). |
| | 1170 | /// |
| | 1171 | /// \note If the graph contains a \c faceNum() member function and a |
| | 1172 | /// \c FaceNumTag tag then this function calls directly the member |
| | 1173 | /// function to query the cardinality of the face set. |
| | 1174 | template <typename Graph> |
| | 1175 | inline int countFaces(const Graph& g) { |
| | 1176 | return _core_bits::CountFacesSelector<Graph>::count(g); |
| | 1177 | } |
| | 1178 | |
| | 1179 | template <typename Graph, typename DegIt> |
| | 1180 | inline int countFaceDegree(const Graph& _g, const typename Graph::Face& _n) { |
| | 1181 | int num = 0; |
| | 1182 | for (DegIt it(_g, _n); it != INVALID; ++it) { |
| | 1183 | ++num; |
| | 1184 | } |
| | 1185 | return num; |
| | 1186 | } |
| | 1187 | /// \brief Function to count the number of the boundary arcs of face \c f. |
| | 1188 | /// |
| | 1189 | /// This function counts the number of the boundary arcs of face \c f |
| | 1190 | /// in the undirected graph \c g. |
| | 1191 | template <typename Graph> |
| | 1192 | inline int countBoundaryArcs(const Graph& g, const typename Graph::Face& f) { |
| | 1193 | return countFaceDegree<Graph, typename Graph::CwBoundaryArcIt>(g, f); |
| | 1194 | } |
| | 1195 | |
| | 1196 | |
| | 1197 | template <typename GR, typename Enable = void> |
| | 1198 | struct FaceNotifierIndicator { |
| | 1199 | typedef InvalidType Type; |
| | 1200 | }; |
| | 1201 | template <typename GR> |
| | 1202 | struct FaceNotifierIndicator< |
| | 1203 | GR, |
| | 1204 | typename enable_if<typename GR::FaceNotifier::Notifier, void>::type |
| | 1205 | > { |
| | 1206 | typedef typename GR::FaceNotifier Type; |
| | 1207 | }; |
| | 1208 | |
| | 1209 | template <typename GR> |
| | 1210 | class ItemSetTraits<GR, typename GR::Face> { |
| | 1211 | public: |
| | 1212 | |
| | 1213 | typedef GR Graph; |
| | 1214 | typedef GR Digraph; |
| | 1215 | |
| | 1216 | typedef typename GR::Face Item; |
| | 1217 | typedef typename GR::FaceIt ItemIt; |
| | 1218 | |
| | 1219 | typedef typename FaceNotifierIndicator<GR>::Type ItemNotifier; |
| | 1220 | |
| | 1221 | template <typename V> |
| | 1222 | class Map : public GR::template FaceMap<V> { |
| | 1223 | typedef typename GR::template FaceMap<V> Parent; |
| | 1224 | |
| | 1225 | public: |
| | 1226 | typedef typename GR::template FaceMap<V> Type; |
| | 1227 | typedef typename Parent::Value Value; |
| | 1228 | |
| | 1229 | Map(const GR& _digraph) : Parent(_digraph) {} |
| | 1230 | Map(const GR& _digraph, const Value& _value) |
| | 1231 | : Parent(_digraph, _value) {} |
| | 1232 | |
| | 1233 | }; |
| | 1234 | |
| | 1235 | }; |
| | 1236 | |
| | 1237 | template<typename Base> |
| | 1238 | class PlanarGraphExtender : public Base{ |
| | 1239 | |
| | 1240 | typedef Base Parent; |
| | 1241 | |
| | 1242 | public: |
| | 1243 | typedef PlanarGraphExtender Graph; |
| | 1244 | |
| | 1245 | typedef typename Parent::Node Node; |
| | 1246 | typedef typename Parent::Arc Arc; |
| | 1247 | typedef typename Parent::Edge Edge; |
| | 1248 | typedef typename Parent::Face Face; |
| | 1249 | |
| | 1250 | typedef typename Parent::NodeNotifier NodeNotifier; |
| | 1251 | typedef typename Parent::EdgeNotifier EdgeNotifier; |
| | 1252 | typedef typename Parent::ArcNotifier ArcNotifier; |
| | 1253 | typedef AlterationNotifier<PlanarGraphExtender, Face> FaceNotifier; |
| | 1254 | |
| | 1255 | protected: |
| | 1256 | mutable FaceNotifier face_notifier; |
| | 1257 | |
| | 1258 | public: |
| | 1259 | |
| | 1260 | int maxId(Face) const { |
| | 1261 | return Parent::maxFaceId(); |
| | 1262 | } |
| | 1263 | |
| | 1264 | NodeNotifier& notifier(Node) const { |
| | 1265 | return Parent::node_notifier; |
| | 1266 | } |
| | 1267 | |
| | 1268 | ArcNotifier& notifier(Arc) const { |
| | 1269 | return Parent::arc_notifier; |
| | 1270 | } |
| | 1271 | |
| | 1272 | EdgeNotifier& notifier(Edge) const { |
| | 1273 | return Parent::edge_notifier; |
| | 1274 | } |
| | 1275 | |
| | 1276 | FaceNotifier& notifier(Face) const { |
| | 1277 | return face_notifier; |
| | 1278 | } |
| | 1279 | |
| | 1280 | template <typename _Value> |
| | 1281 | class FaceMap |
| | 1282 | : public MapExtender<DefaultMap<Graph, Face, _Value> > { |
| | 1283 | typedef MapExtender<DefaultMap<Graph, Face, _Value> > Parent; |
| | 1284 | |
| | 1285 | public: |
| | 1286 | explicit FaceMap(const Graph& graph) |
| | 1287 | : Parent(graph) {} |
| | 1288 | FaceMap(const Graph& graph, const _Value& value) |
| | 1289 | : Parent(graph, value) {} |
| | 1290 | |
| | 1291 | private: |
| | 1292 | FaceMap& operator=(const FaceMap& cmap) { |
| | 1293 | return operator=<FaceMap>(cmap); |
| | 1294 | } |
| | 1295 | |
| | 1296 | template <typename CMap> |
| | 1297 | FaceMap& operator=(const CMap& cmap) { |
| | 1298 | Parent::operator=(cmap); |
| | 1299 | return *this; |
| | 1300 | } |
| | 1301 | |
| | 1302 | }; |
| | 1303 | |
| | 1304 | |
| | 1305 | /// Iterator class for the faces. |
| | 1306 | |
| | 1307 | /// This iterator goes through the faces of a planar graph. |
| | 1308 | class FaceIt : public Face { |
| | 1309 | const Graph* _graph; |
| | 1310 | public: |
| | 1311 | |
| | 1312 | FaceIt() {} |
| | 1313 | |
| | 1314 | FaceIt(Invalid i) : Face(i) { } |
| | 1315 | |
| | 1316 | explicit FaceIt(const Graph& graph) : _graph(&graph) { |
| | 1317 | _graph->first(static_cast<Face&>(*this)); |
| | 1318 | } |
| | 1319 | |
| | 1320 | FaceIt(const Graph& graph, const Face& face) |
| | 1321 | : Face(face), _graph(&graph) {} |
| | 1322 | |
| | 1323 | FaceIt& operator++() { |
| | 1324 | _graph->next(*this); |
| | 1325 | return *this; |
| | 1326 | } |
| | 1327 | |
| | 1328 | }; |
| | 1329 | |
| | 1330 | |
| | 1331 | /// Iterator class for the common faces of two nodes |
| | 1332 | |
| | 1333 | /// This iterator goes through the common faces of two nodes |
| | 1334 | class CommonFacesIt : public Face { |
| | 1335 | const Graph* _graph; |
| | 1336 | const Node _n1, _n2; |
| | 1337 | std::set<Face> _f1, _f2; |
| | 1338 | typename std::set<Face>::const_iterator _fi2; |
| | 1339 | public: |
| | 1340 | |
| | 1341 | CommonFacesIt() {} |
| | 1342 | |
| | 1343 | CommonFacesIt(Invalid i) : Face(i) { } |
| | 1344 | |
| | 1345 | explicit CommonFacesIt(const Graph& graph, Node n1, Node n2) : _graph( |
| | 1346 | &graph), _n1(n1), _n2(n2), _f1(), _f2(){ |
| | 1347 | Arc _i1; |
| | 1348 | _graph->firstOut(_i1,_n1); |
| | 1349 | while (_i1 != INVALID) { |
| | 1350 | _f1.insert(_graph->leftFace(_i1)); |
| | 1351 | _graph->nextOut(_i1); |
| | 1352 | } |
| | 1353 | Arc _i2; |
| | 1354 | _graph->firstOut(_i2,_n2); |
| | 1355 | while (_i2 != INVALID) { |
| | 1356 | _f2.insert(_graph->leftFace(_i2)); |
| | 1357 | _graph->nextOut(_i2); |
| | 1358 | } |
| | 1359 | |
| | 1360 | _fi2 = _f2.begin(); |
| | 1361 | while (_fi2 != _f2.end() && _f1.count(*_fi2) == 0) |
| | 1362 | ++_fi2; |
| | 1363 | static_cast<Face&>(*this) = (_fi2 != _f2.end())?*_fi2:INVALID; |
| | 1364 | } |
| | 1365 | |
| | 1366 | CommonFacesIt& operator++() { |
| | 1367 | ++_fi2; |
| | 1368 | while (_fi2 != _f2.end() && _f1.count(*_fi2) == 0) |
| | 1369 | ++_fi2; |
| | 1370 | static_cast<Face&>(*this) = (_fi2 != _f2.end())?*_fi2:INVALID; |
| | 1371 | return *this; |
| | 1372 | } |
| | 1373 | |
| | 1374 | }; |
| | 1375 | |
| | 1376 | /// Iterator class for the common nodes of two facess |
| | 1377 | |
| | 1378 | /// This iterator goes through the common nodes of two faces |
| | 1379 | class CommonNodesIt : public Node { |
| | 1380 | const Graph* _graph; |
| | 1381 | const Face _f1, _f2; |
| | 1382 | std::set<Node> _ns1,_ns2; |
| | 1383 | typename std::set<Node>::const_iterator _ni2; |
| | 1384 | public: |
| | 1385 | |
| | 1386 | CommonNodesIt() {} |
| | 1387 | |
| | 1388 | CommonNodesIt(Invalid i) : Face(i) { } |
| | 1389 | |
| | 1390 | explicit CommonNodesIt(const Graph& graph, Face f1, Face f2) : _graph( |
| | 1391 | &graph), _f1(f1), _f2(f2), _ns1(), _ns2(){ |
| | 1392 | Arc _i1; |
| | 1393 | _graph->firstCwF(_i1,_f1); |
| | 1394 | while (_i1 != INVALID) { |
| | 1395 | _ns1.insert(_graph->source(_i1)); |
| | 1396 | _graph->nextCwF(_i1); |
| | 1397 | } |
| | 1398 | Arc _i2; |
| | 1399 | _graph->firstCwF(_i2,_f2); |
| | 1400 | while (_i2 != INVALID) { |
| | 1401 | _ns2.insert(_graph->source(_i2)); |
| | 1402 | _graph->nextCwF(_i2); |
| | 1403 | } |
| | 1404 | |
| | 1405 | _ni2 = _ns2.begin(); |
| | 1406 | while (_ni2 != _ns2.end() && _ns1.count(*_ni2) == 0) |
| | 1407 | ++_ni2; |
| | 1408 | static_cast<Node&>(*this) = (_ni2 != _ns2.end())?*_ni2:INVALID; |
| | 1409 | } |
| | 1410 | |
| | 1411 | CommonNodesIt& operator++() { |
| | 1412 | ++_ni2; |
| | 1413 | while (_ni2 != _ns2.end() && _ns1.count(*_ni2) == 0) |
| | 1414 | ++_ni2; |
| | 1415 | static_cast<Node&>(*this) = (_ni2 != _ns2.end())?*_ni2:INVALID; |
| | 1416 | return *this; |
| | 1417 | } |
| | 1418 | |
| | 1419 | }; |
| | 1420 | |
| | 1421 | /// Iterator class for the arcs on the boundary of a face. |
| | 1422 | |
| | 1423 | /// This iterator goes through the arcs on the boundary of a face clockwise. |
| | 1424 | class CwBoundaryArcIt : public Arc { |
| | 1425 | const Graph* _graph; |
| | 1426 | Face _face; |
| | 1427 | Arc f_arc; |
| | 1428 | public: |
| | 1429 | |
| | 1430 | CwBoundaryArcIt() { } |
| | 1431 | |
| | 1432 | CwBoundaryArcIt(Invalid i) : Arc(i) { } |
| | 1433 | |
| | 1434 | CwBoundaryArcIt(const Graph& graph, const Face& face) |
| | 1435 | : _graph(&graph), _face(face) { |
| | 1436 | _graph->firstCwF(static_cast<Arc&>(*this),face); |
| | 1437 | f_arc = *this; |
| | 1438 | } |
| | 1439 | |
| | 1440 | CwBoundaryArcIt(const Graph& graph, const Arc& arc) |
| | 1441 | : Arc(arc), _graph(&graph) {} |
| | 1442 | |
| | 1443 | CwBoundaryArcIt& operator++() { |
| | 1444 | _graph->nextCwF(*this); |
| | 1445 | return *this; |
| | 1446 | } |
| | 1447 | |
| | 1448 | }; |
| | 1449 | |
| | 1450 | /// Iterator class for the arcs around a node. |
| | 1451 | |
| | 1452 | /// This iterator goes through the arcs around a node anticlockwise. |
| | 1453 | class CcwArcIt : public Arc { |
| | 1454 | const Graph* _graph; |
| | 1455 | const Node _node; |
| | 1456 | public: |
| | 1457 | |
| | 1458 | CcwArcIt() { } |
| | 1459 | |
| | 1460 | CcwArcIt(Invalid i) : Arc(i) { } |
| | 1461 | |
| | 1462 | CcwArcIt(const Graph& graph, const Node& node) |
| | 1463 | : _graph(&graph), _node(node) { |
| | 1464 | _graph->firstCcw(*this, node); |
| | 1465 | } |
| | 1466 | |
| | 1467 | CcwArcIt(const Graph& graph, const Arc& arc) |
| | 1468 | : Arc(arc), _graph(&graph) {} |
| | 1469 | |
| | 1470 | CcwArcIt& operator++() { |
| | 1471 | _graph->nextCcw(*this, _node); |
| | 1472 | return *this; |
| | 1473 | } |
| | 1474 | |
| | 1475 | }; |
| | 1476 | |
| | 1477 | void clear() { |
| | 1478 | notifier(Face()).clear(); |
| | 1479 | Parent::clear(); |
| | 1480 | } |
| | 1481 | |
| | 1482 | template <typename Graph, typename NodeRefMap, typename EdgeRefMap> |
| | 1483 | void build(const Graph& graph, NodeRefMap& nodeRef, |
| | 1484 | EdgeRefMap& edgeRef) { |
| | 1485 | Parent::build(graph, nodeRef, edgeRef); |
| | 1486 | notifier(Face()).build(); |
| | 1487 | } |
| | 1488 | |
| | 1489 | PlanarGraphExtender() { |
| | 1490 | face_notifier.setContainer(*this); |
| | 1491 | } |
| | 1492 | |
| | 1493 | ~PlanarGraphExtender() { |
| | 1494 | face_notifier.clear(); |
| | 1495 | } |
| | 1496 | |
| | 1497 | }; |
| | 1498 | |
| | 1499 | typedef PlanarGraphExtender<GraphExtender<PlanarGraphBase> > |
| | 1500 | ExtendedPlanarGraphBase; |
| | 1501 | |
| | 1502 | |
| | 1503 | /// \addtogroup graphs |
| | 1504 | /// @{ |
| | 1505 | |
| | 1506 | ///An undirected planar graph structure. |
| | 1507 | |
| | 1508 | ///\ref PlanarGraph is a versatile and fast undirected planar graph |
| | 1509 | ///implementation based on linked lists that are stored in |
| | 1510 | ///\c std::vector structures. It maintains a topology of nodes, edges |
| | 1511 | ///and faces. |
| | 1512 | /// |
| | 1513 | ///This type fully conforms to the \ref concepts::Graph "Graph concept" |
| | 1514 | ///and it also provides several useful additional functionalities, including |
| | 1515 | ///those specific to planar graphs. |
| | 1516 | ///Most of its member functions and nested classes are documented |
| | 1517 | ///only in the concept class. |
| | 1518 | /// |
| | 1519 | ///This class provides only linear time counting for nodes, edges, arcs and |
| | 1520 | ///faces. |
| | 1521 | /// |
| | 1522 | ///A disconnected planar graph has have an outer face for each of its |
| | 1523 | ///components, effectively turning them into separate graphs. Each component |
| | 1524 | ///has a corresponding component in the dual. |
| | 1525 | ///\sa concepts::Graph |
| | 1526 | ///\sa PlaneGraph |
| | 1527 | class PlanarGraph : public ExtendedPlanarGraphBase { |
| | 1528 | typedef ExtendedPlanarGraphBase Parent; |
| | 1529 | |
| | 1530 | public: |
| | 1531 | /// Graphs are \e not copy constructible. Use GraphCopy instead. |
| | 1532 | PlanarGraph(const PlanarGraph &) = delete; |
| | 1533 | /// \brief Assignment of a graph to another one is \e not allowed. |
| | 1534 | /// Use GraphCopy instead. |
| | 1535 | void operator=(const PlanarGraph &) = delete; |
| | 1536 | |
| | 1537 | /// \brief Constructor |
| | 1538 | |
| | 1539 | /// Constructor. |
| | 1540 | /// |
| | 1541 | PlanarGraph() {} |
| | 1542 | |
| | 1543 | |
| | 1544 | ///\brief Constructor that copies a planar embedding |
| | 1545 | |
| | 1546 | ///Constructor that copies a planar embedding. |
| | 1547 | template<typename Graph> |
| | 1548 | PlanarGraph(const Graph &g, const lemon::PlanarEmbedding<Graph> &em) { |
| | 1549 | typename Graph::template NodeMap<Node> nm(g); |
| | 1550 | typename Graph::template ArcMap<Arc> am(g); |
| | 1551 | this->copyEmbedding(g,em,nm,am); |
| | 1552 | } |
| | 1553 | |
| | 1554 | template<typename Graph> |
| | 1555 | PlanarGraph(const Graph &g, const lemon::PlanarEmbedding<Graph> &em, |
| | 1556 | typename Graph::template NodeMap<Node> &nm, |
| | 1557 | typename Graph::template ArcMap<Arc> &am) { |
| | 1558 | this->copyEmbedding(g,em,nm,am); |
| | 1559 | } |
| | 1560 | |
| | 1561 | typedef Parent::OutArcIt IncEdgeIt; |
| | 1562 | |
| | 1563 | protected: |
| | 1564 | |
| | 1565 | template<typename Graph> |
| | 1566 | void copyEmbedding(const Graph &g, const lemon::PlanarEmbedding<Graph> &em, |
| | 1567 | typename Graph::template NodeMap<Node> &nm, |
| | 1568 | typename Graph::template ArcMap<Arc> &am) { |
| | 1569 | for (typename Graph::NodeIt it(g); it != INVALID; ++it) { |
| | 1570 | nm[it] = addNode(); |
| | 1571 | } |
| | 1572 | for (typename Graph::ArcIt it(g); it != INVALID; ++it) { |
| | 1573 | am[it] = INVALID; |
| | 1574 | } |
| | 1575 | for (typename Graph::NodeIt it(g); it != INVALID; ++it) { |
| | 1576 | for (typename Graph::OutArcIt it2(g,it); it2 != INVALID; ++it2) { |
| | 1577 | if (am[it2] == INVALID) { |
| | 1578 | typename Graph::Arc p_u = em.next(it2); |
| | 1579 | while (am[p_u] == INVALID && it2 != p_u) { |
| | 1580 | p_u = em.next(p_u); |
| | 1581 | } |
| | 1582 | typename Graph::Arc ra = g.oppositeArc(it2); |
| | 1583 | typename Graph::Arc p_v = em.next(ra); |
| | 1584 | while (am[p_v] == INVALID && ra != p_v) { |
| | 1585 | p_v = em.next(p_v); |
| | 1586 | } |
| | 1587 | am[it2] = direct(addEdge(nm[g.source(it2)],nm[g.target(it2)], |
| | 1588 | am[p_u],am[p_v]),nm[g.source(it2)]); |
| | 1589 | am[g.oppositeArc(it2)] = oppositeArc(am[it2]); |
| | 1590 | } |
| | 1591 | } |
| | 1592 | } |
| | 1593 | } |
| | 1594 | |
| | 1595 | void edge_add_notify(Edge edge) { |
| | 1596 | notifier(Edge()).add(edge); |
| | 1597 | std::vector<Arc> ev; |
| | 1598 | ev.push_back(Parent::direct(edge, true)); |
| | 1599 | ev.push_back(Parent::direct(edge, false)); |
| | 1600 | notifier(Arc()).add(ev); |
| | 1601 | } |
| | 1602 | |
| | 1603 | void edge_erase_notify(Edge edge) { |
| | 1604 | std::vector<Arc> av; |
| | 1605 | av.push_back(Parent::direct(edge, true)); |
| | 1606 | av.push_back(Parent::direct(edge, false)); |
| | 1607 | notifier(Arc()).erase(av); |
| | 1608 | notifier(Edge()).erase(edge); |
| | 1609 | } |
| | 1610 | |
| | 1611 | public: |
| | 1612 | /// \brief Add a new node to the graph. |
| | 1613 | /// |
| | 1614 | /// This function adds a new node to the graph. A new outer face is created |
| | 1615 | /// for the node. |
| | 1616 | /// \return The new node. |
| | 1617 | Node addNode() { |
| | 1618 | Node n = PlanarGraphBase::addNode(); |
| | 1619 | notifier(Node()).add(n); |
| | 1620 | notifier(Face()).add(outerFace(n)); |
| | 1621 | return n; |
| | 1622 | } |
| | 1623 | |
| | 1624 | /// \brief Add a new edge to the graph. |
| | 1625 | /// |
| | 1626 | /// This function adds a new edge to the graph between nodes |
| | 1627 | /// \c u and \c v with inherent orientation from node \c u to |
| | 1628 | /// node \c v. \c p_u and \c p_v are the edges that directly precede the new |
| | 1629 | /// edge in anticlockwise order at the nodes \c u and \c v, respectively. |
| | 1630 | /// INVALID should be passed as \c p_u or \c p_v if and only if the |
| | 1631 | /// respective node is isolated. |
| | 1632 | /// |
| | 1633 | /// If \c u and \c v are in the same component, \c p_u and \c p_v must share |
| | 1634 | /// the same left face (when looking from \c u or \c v). This face will be |
| | 1635 | /// split in two. If \c u and \c v are in different components, one of the |
| | 1636 | /// outer faces will be deleted. |
| | 1637 | /// \note It can be costly to join components unless one of them is an |
| | 1638 | /// isolated node. |
| | 1639 | /// \note Even if a face is not deleted in the process, BoundaryArcIt |
| | 1640 | /// iterators might run an incomplete lap or revisit previously passed edges |
| | 1641 | /// if edges are added to or removed from the boundary of the face. |
| | 1642 | /// \return The new edge, or INVALID if the parameters don't meet the |
| | 1643 | /// preconditions. |
| | 1644 | Edge addEdge(Node u, Node v, Edge p_u, Edge p_v) { |
| | 1645 | Face f_u = INVALID, f_v = INVALID; |
| | 1646 | if (p_u != INVALID) { |
| | 1647 | Arc a_u = direct(p_u,u); |
| | 1648 | f_u = leftFace(a_u); |
| | 1649 | } |
| | 1650 | if (p_v != INVALID) { |
| | 1651 | Arc a_v = direct(p_v,v); |
| | 1652 | f_v = leftFace(a_v); |
| | 1653 | } |
| | 1654 | Face o_u = outerFace(u); |
| | 1655 | Face o_v = outerFace(v); |
| | 1656 | Edge edge = PlanarGraphBase::addEdge(u, v, p_u, p_v); |
| | 1657 | if (edge == INVALID) return edge; |
| | 1658 | if (!valid(f_u)) notifier(Face()).erase(f_u); |
| | 1659 | if (!valid(f_v) && f_u != f_v) notifier(Face()).erase(f_v); |
| | 1660 | if (!valid(o_u)) notifier(Face()).erase(o_u); |
| | 1661 | if (!valid(o_v)) notifier(Face()).erase(o_v); |
| | 1662 | edge_add_notify(edge); |
| | 1663 | Face e_l = leftFace(direct(edge,u)); |
| | 1664 | Face e_r = rightFace(direct(edge,u)); |
| | 1665 | if (e_l != f_u && e_l != f_v && e_l != o_u && e_l != o_v) |
| | 1666 | notifier(Face()).add(e_l); |
| | 1667 | if (e_r != f_u && e_r != f_v && e_r != o_u && e_r != o_v && e_r != e_l) |
| | 1668 | notifier(Face()).add(e_r); |
| | 1669 | return edge; |
| | 1670 | } |
| | 1671 | |
| | 1672 | ///\brief Erase a node from the graph. |
| | 1673 | /// |
| | 1674 | /// This function erases the given node along with its incident arcs |
| | 1675 | /// from the graph. |
| | 1676 | /// |
| | 1677 | /// \note All iterators referencing the removed node or the incident |
| | 1678 | /// edges are invalidated, of course. |
| | 1679 | void erase(Node n) { |
| | 1680 | notifier(Face()).erase(outerFace(n)); |
| | 1681 | Parent::erase(n); |
| | 1682 | } |
| | 1683 | |
| | 1684 | ///\brief Erase an edge from the graph. |
| | 1685 | /// |
| | 1686 | /// This function erases the given edge from the graph. The faces on the two |
| | 1687 | /// sides are merged into one, unless the edge holds two components |
| | 1688 | /// together. In the latter case, a new outer face is added and the |
| | 1689 | /// component is split in two. |
| | 1690 | /// |
| | 1691 | /// \note It can be costly to split a component, unless one of the resulting |
| | 1692 | /// components is an isolated node. |
| | 1693 | /// \note All iterators referencing the removed edge are invalidated, |
| | 1694 | /// of course. |
| | 1695 | /// \note Even if a face is not deleted in the process, BoundaryArcIt |
| | 1696 | /// iterators might run an incomplete lap or revisit previously passed edges |
| | 1697 | /// if edges are added to or removed from the boundary of the face. |
| | 1698 | void erase(Edge e) { |
| | 1699 | Node n1 = u(e); |
| | 1700 | Node n2 = v(e); |
| | 1701 | Face f_l = leftFace(direct(e,n1)); |
| | 1702 | Face f_r = rightFace(direct(e,n1)); |
| | 1703 | Parent::erase(e); |
| | 1704 | Face o_u = outerFace(n1); |
| | 1705 | Face o_v = outerFace(n2); |
| | 1706 | if (!valid(f_l)) notifier(Face()).erase(f_l); |
| | 1707 | if (!valid(f_r)) notifier(Face()).erase(f_r); |
| | 1708 | if (valid(o_u) && o_u != f_l && o_u != f_r) |
| | 1709 | notifier(Face()).add(o_u); |
| | 1710 | if (valid(o_v) && o_v != f_l && o_v != f_r) |
| | 1711 | notifier(Face()).add(o_v); |
| | 1712 | } |
| | 1713 | /// Node validity check |
| | 1714 | |
| | 1715 | /// This function gives back \c true if the given node is valid, |
| | 1716 | /// i.e. it is a real node of the graph. |
| | 1717 | /// |
| | 1718 | /// \warning A removed node could become valid again if new nodes are |
| | 1719 | /// added to the graph. |
| | 1720 | bool valid(Node n) const { |
| | 1721 | return Parent::valid(n); |
| | 1722 | } |
| | 1723 | /// Edge validity check |
| | 1724 | |
| | 1725 | /// This function gives back \c true if the given edge is valid, |
| | 1726 | /// i.e. it is a real edge of the graph. |
| | 1727 | /// |
| | 1728 | /// \warning A removed edge could become valid again if new edges are |
| | 1729 | /// added to the graph. |
| | 1730 | bool valid(Edge e) const { |
| | 1731 | return Parent::valid(e); |
| | 1732 | } |
| | 1733 | /// Arc validity check |
| | 1734 | |
| | 1735 | /// This function gives back \c true if the given arc is valid, |
| | 1736 | /// i.e. it is a real arc of the graph. |
| | 1737 | /// |
| | 1738 | /// \warning A removed arc could become valid again if new edges are |
| | 1739 | /// added to the graph. |
| | 1740 | bool valid(Arc a) const { |
| | 1741 | return Parent::valid(a); |
| | 1742 | } |
| | 1743 | |
| | 1744 | /// Face validity check |
| | 1745 | |
| | 1746 | /// This function gives back \c true if the given face is valid, |
| | 1747 | /// i.e. it is a real face of the graph. |
| | 1748 | /// |
| | 1749 | /// \warning A removed face could become valid again if new faces are |
| | 1750 | /// added to the graph. |
| | 1751 | bool valid(Face f) const { |
| | 1752 | return Parent::valid(f); |
| | 1753 | } |
| | 1754 | |
| | 1755 | /// \brief Change the first node of an edge. |
| | 1756 | /// |
| | 1757 | /// Planar graphs don't support changing the endpoints of edges. |
| | 1758 | void changeU(Edge e, Node n) = delete; |
| | 1759 | /// \brief Change the second node of an edge. |
| | 1760 | /// |
| | 1761 | /// Planar graphs don't support changing the endpoints of edges. |
| | 1762 | void changeV(Edge e, Node n) = delete; |
| | 1763 | |
| | 1764 | /// \brief Contract two nodes. |
| | 1765 | /// |
| | 1766 | /// This function contracts the two ends of the given edge. |
| | 1767 | /// One of the nodes on \c e is removed, but instead of deleting |
| | 1768 | /// its incident edges, they are joined to the other node. |
| | 1769 | /// \c e will be deleted. |
| | 1770 | /// |
| | 1771 | /// The deleted node is v(e) unless the degree of v(e) is higher than 1 and |
| | 1772 | /// the degree of u(e) is 1, in which case u(e) is deleted. |
| | 1773 | /// |
| | 1774 | /// \note All edge and arc iterators whose base node is |
| | 1775 | /// the deleted one are invalidated. |
| | 1776 | /// Moreover all iterators referencing the removed node or |
| | 1777 | /// edge are also invalidated. Other iterators remain valid. However, they |
| | 1778 | /// might run an incomplete lap or revisit previously passed edges if |
| | 1779 | /// incremented. |
| | 1780 | /// |
| | 1781 | ///\warning This functionality cannot be used together with the |
| | 1782 | ///Snapshot feature. |
| | 1783 | void contract(Edge e) { |
| | 1784 | Node n1 = u(e); |
| | 1785 | Node n2 = v(e); |
| | 1786 | if (n1 == n2) return; |
| | 1787 | Node nd; |
| | 1788 | bool simple; |
| | 1789 | inner_contract1(n1,n2,nd,simple); |
| | 1790 | notifier(Node()).erase(nd); |
| | 1791 | edge_erase_notify(e); |
| | 1792 | inner_contract2(e,n1,n2,nd,simple); |
| | 1793 | } |
| | 1794 | |
| | 1795 | /// \brief Split an edge. |
| | 1796 | /// |
| | 1797 | ///This function splits the given edge. First, a new node \c v is |
| | 1798 | ///added to the graph, then the target node of the original edge |
| | 1799 | ///is set to \c v. Finally, an edge from \c v to the original target |
| | 1800 | ///is added. |
| | 1801 | ///\return The newly created node. |
| | 1802 | /// |
| | 1803 | ///\note Iterators referencing the original edge are |
| | 1804 | ///invalidated. Other iterators remain valid. |
| | 1805 | /// |
| | 1806 | ///\warning This functionality cannot be used together with the |
| | 1807 | ///Snapshot feature. |
| | 1808 | Node split(Edge e) { |
| | 1809 | Node v; |
| | 1810 | Edge e2; |
| | 1811 | inner_split1(v,e2); |
| | 1812 | notifier(Node()).add(v); |
| | 1813 | edge_add_notify(e2); |
| | 1814 | return inner_split2(e,v,e2); |
| | 1815 | } |
| | 1816 | |
| | 1817 | ///Split a node. |
| | 1818 | |
| | 1819 | ///This function splits the given node. First, a new node is added |
| | 1820 | ///to the graph, then all edges in anticlockwise order from \c e1 until but |
| | 1821 | ///not including \c e2 |
| | 1822 | ///are re-anchored from \c n to the new node. |
| | 1823 | ///If the second parameter \c connect is \c true (this is the default |
| | 1824 | ///value), then a new edge from node \c n to the newly created node |
| | 1825 | ///is also added. \c e1 and \c e2 must be INVALID if and only if \c n is |
| | 1826 | ///isolated. If \c connect is false, the component of \c n might be split in |
| | 1827 | ///two. It can be costly to split components unless one of the resulting |
| | 1828 | ///components is an isolated node. |
| | 1829 | ///\return The newly created node. |
| | 1830 | /// |
| | 1831 | ///\note All iterators remain valid but some might run an incomplete lap or |
| | 1832 | ///revisit previously passed nodes when incremented. |
| | 1833 | /// |
| | 1834 | ///\warning This functionality cannot be used together with the |
| | 1835 | ///Snapshot feature. |
| | 1836 | Node split(Node n1, Edge e1, Edge e2, bool connect) { |
| | 1837 | Node n2; |
| | 1838 | inner_split1(n1,n2); |
| | 1839 | notifier(Node()).add(n2); |
| | 1840 | Edge a3; |
| | 1841 | inner_split2(n1,n2,e1,e2,connect,a3); |
| | 1842 | if (!connect) { |
| | 1843 | if (a3 != INVALID) |
| | 1844 | erase(a3); |
| | 1845 | } else { |
| | 1846 | edge_add_notify(a3); |
| | 1847 | } |
| | 1848 | return n2; |
| | 1849 | } |
| | 1850 | |
| | 1851 | |
| | 1852 | ///Clear the graph. |
| | 1853 | |
| | 1854 | ///This function erases all nodes and arcs from the graph. |
| | 1855 | /// |
| | 1856 | ///\note All iterators of the graph are invalidated, of course. |
| | 1857 | void clear() { |
| | 1858 | Parent::clear(); |
| | 1859 | } |
| | 1860 | |
| | 1861 | /// Reserve memory for nodes. |
| | 1862 | |
| | 1863 | /// Using this function, it is possible to avoid superfluous memory |
| | 1864 | /// allocation: if you know that the graph you want to build will |
| | 1865 | /// be large (e.g. it will contain millions of nodes and/or edges), |
| | 1866 | /// then it is worth reserving space for this amount before starting |
| | 1867 | /// to build the graph. |
| | 1868 | /// \sa reserveEdge() |
| | 1869 | void reserveNode(int n) { |
| | 1870 | nodes.reserve(n); |
| | 1871 | }; |
| | 1872 | |
| | 1873 | /// Reserve memory for edges. |
| | 1874 | |
| | 1875 | /// Using this function, it is possible to avoid superfluous memory |
| | 1876 | /// allocation: if you know that the graph you want to build will |
| | 1877 | /// be large (e.g. it will contain millions of nodes and/or edges), |
| | 1878 | /// then it is worth reserving space for this amount before starting |
| | 1879 | /// to build the graph. |
| | 1880 | /// \sa reserveNode() |
| | 1881 | void reserveEdge(int m) { |
| | 1882 | arcs.reserve(2 * m); |
| | 1883 | }; |
| | 1884 | |
| | 1885 | /// Reserve memory for faces. |
| | 1886 | |
| | 1887 | /// Using this function, it is possible to avoid superfluous memory |
| | 1888 | /// allocation: if you know that the graph you want to build will |
| | 1889 | /// be large (e.g. it will contain millions of nodes and/or edges), |
| | 1890 | /// then it is worth reserving space for this amount before starting |
| | 1891 | /// to build the graph. |
| | 1892 | /// \sa reserveFace() |
| | 1893 | void reserveFace(int n) { |
| | 1894 | faces.reserve(n); |
| | 1895 | }; |
| | 1896 | |
| | 1897 | class DualBase { |
| | 1898 | const Graph *_graph; |
| | 1899 | protected: |
| | 1900 | void initialize(const Graph *graph) { |
| | 1901 | _graph = graph; |
| | 1902 | } |
| | 1903 | public: |
| | 1904 | |
| | 1905 | typedef PlanarGraph::Face Node; |
| | 1906 | typedef PlanarGraph::Arc Arc; |
| | 1907 | typedef PlanarGraph::Edge Edge; |
| | 1908 | typedef PlanarGraph::Node Face; |
| | 1909 | |
| | 1910 | int maxNodeId() const { |
| | 1911 | return _graph->maxFaceId(); |
| | 1912 | } |
| | 1913 | int maxArcId() const { |
| | 1914 | return _graph->maxArcId(); |
| | 1915 | } |
| | 1916 | int maxFaceId() const { |
| | 1917 | return _graph->maxNodeId(); |
| | 1918 | } |
| | 1919 | |
| | 1920 | Node source(Arc e) const { |
| | 1921 | return _graph->leftFace(e); |
| | 1922 | } |
| | 1923 | Node target(Arc e) const { |
| | 1924 | return _graph->rightFace(e); |
| | 1925 | } |
| | 1926 | Face leftFace(Arc e) const { |
| | 1927 | return _graph->target(e); |
| | 1928 | } |
| | 1929 | Face rightFace(Arc e) const { |
| | 1930 | return _graph->source(e); |
| | 1931 | } |
| | 1932 | Arc direct(const Edge &edge, const Node &node) const { |
| | 1933 | return _graph->direct(edge, _graph->w1(edge) == node); |
| | 1934 | } |
| | 1935 | |
| | 1936 | void first(Node &i) const { |
| | 1937 | _graph->first(i); |
| | 1938 | } |
| | 1939 | void next(Node &i) const { |
| | 1940 | _graph->next(i); |
| | 1941 | } |
| | 1942 | void first(Arc &i) const { |
| | 1943 | _graph->first(i); |
| | 1944 | } |
| | 1945 | void next(Arc &i) const { |
| | 1946 | _graph->next(i); |
| | 1947 | } |
| | 1948 | void firstCcw(Arc& i, const Node& n) const { |
| | 1949 | _graph->lastInF(i, n); |
| | 1950 | } |
| | 1951 | void nextCcw(Arc& i, const Node &n) const { |
| | 1952 | _graph->prevInF(i); |
| | 1953 | } |
| | 1954 | void firstIn(Arc& i, const Node& n) const { |
| | 1955 | _graph->firstInF(i, n); |
| | 1956 | } |
| | 1957 | void nextIn(Arc& i) const { |
| | 1958 | _graph->nextInF(i); |
| | 1959 | } |
| | 1960 | void firstCwF(Arc& i, const Face& n) const { |
| | 1961 | _graph->lastIn(i, n); |
| | 1962 | } |
| | 1963 | void nextCwF(Arc& i) const { |
| | 1964 | _graph->prevIn(i); |
| | 1965 | } |
| | 1966 | void firstOut(Arc& i, const Node& n ) const { |
| | 1967 | _graph->firstOutF(i, n); |
| | 1968 | } |
| | 1969 | void nextOut(Arc& i) const { |
| | 1970 | _graph->nextOutF(i); |
| | 1971 | } |
| | 1972 | void first(Face &i) const { |
| | 1973 | _graph->first(i); |
| | 1974 | } |
| | 1975 | void next(Face &i) const { |
| | 1976 | _graph->next(i); |
| | 1977 | } |
| | 1978 | |
| | 1979 | static int id(Node v) { |
| | 1980 | return PlanarGraph::id(v); |
| | 1981 | } |
| | 1982 | static int id(Arc e) { |
| | 1983 | return PlanarGraph::id(e); |
| | 1984 | } |
| | 1985 | static int id(Face f) { |
| | 1986 | return PlanarGraph::id(f); |
| | 1987 | } |
| | 1988 | static Node nodeFromId(int id) { |
| | 1989 | return PlanarGraph::faceFromId(id); |
| | 1990 | } |
| | 1991 | static Arc arcFromId(int id) { |
| | 1992 | return PlanarGraph::arcFromId(id); |
| | 1993 | } |
| | 1994 | static Face faceFromId(int id) { |
| | 1995 | return PlanarGraph::nodeFromId(id); |
| | 1996 | } |
| | 1997 | |
| | 1998 | bool valid(Node n) const { |
| | 1999 | return _graph->valid(n); |
| | 2000 | } |
| | 2001 | bool valid(Arc n) const { |
| | 2002 | return _graph->valid(n); |
| | 2003 | } |
| | 2004 | bool valid(Face n) const { |
| | 2005 | return _graph->valid(n); |
| | 2006 | } |
| | 2007 | |
| | 2008 | }; |
| | 2009 | |
| | 2010 | typedef PlanarGraphExtender<GraphExtender<DualBase> > ExtendedDualBase; |
| | 2011 | |
| | 2012 | /// Adaptor class for the dual of a planar graph. |
| | 2013 | |
| | 2014 | /// This is an adaptor class for the dual of a planar graph. |
| | 2015 | class Dual : public ExtendedDualBase { |
| | 2016 | public: |
| | 2017 | Dual(const PlanarGraph &graph) { |
| | 2018 | initialize(&graph); |
| | 2019 | } |
| | 2020 | |
| | 2021 | }; |
| | 2022 | /// \brief Class to make a snapshot of the graph and restore |
| | 2023 | /// it later. |
| | 2024 | /// |
| | 2025 | /// Class to make a snapshot of the graph and restore it later. |
| | 2026 | /// |
| | 2027 | /// The newly added nodes and edges can be removed |
| | 2028 | /// using the restore() function. |
| | 2029 | /// |
| | 2030 | /// \note After a state is restored, you cannot restore a later state, |
| | 2031 | /// i.e. you cannot add the removed nodes and edges again using |
| | 2032 | /// another Snapshot instance. |
| | 2033 | /// |
| | 2034 | /// \warning Node and edge deletions and other modifications |
| | 2035 | /// (e.g. changing the end-nodes of edges or contracting nodes) |
| | 2036 | /// cannot be restored. These events invalidate the snapshot. |
| | 2037 | /// However, the edges and nodes that were added to the graph after |
| | 2038 | /// making the current snapshot can be removed without invalidating it. |
| | 2039 | class Snapshot { |
| | 2040 | protected: |
| | 2041 | |
| | 2042 | typedef Parent::NodeNotifier NodeNotifier; |
| | 2043 | |
| | 2044 | class NodeObserverProxy : public NodeNotifier::ObserverBase { |
| | 2045 | public: |
| | 2046 | |
| | 2047 | NodeObserverProxy(Snapshot& _snapshot) |
| | 2048 | : snapshot(_snapshot) {} |
| | 2049 | |
| | 2050 | using NodeNotifier::ObserverBase::attach; |
| | 2051 | using NodeNotifier::ObserverBase::detach; |
| | 2052 | using NodeNotifier::ObserverBase::attached; |
| | 2053 | |
| | 2054 | protected: |
| | 2055 | |
| | 2056 | virtual void add(const Node& node) { |
| | 2057 | snapshot.addNode(node); |
| | 2058 | } |
| | 2059 | virtual void add(const std::vector<Node>& nodes) { |
| | 2060 | for (int i = nodes.size() - 1; i >= 0; ++i) { |
| | 2061 | snapshot.addNode(nodes[i]); |
| | 2062 | } |
| | 2063 | } |
| | 2064 | virtual void erase(const Node& node) { |
| | 2065 | snapshot.eraseNode(node); |
| | 2066 | } |
| | 2067 | virtual void erase(const std::vector<Node>& nodes) { |
| | 2068 | for (int i = 0; i < int(nodes.size()); ++i) { |
| | 2069 | snapshot.eraseNode(nodes[i]); |
| | 2070 | } |
| | 2071 | } |
| | 2072 | virtual void build() { |
| | 2073 | Node node; |
| | 2074 | std::vector<Node> nodes; |
| | 2075 | for (notifier()->first(node); node != INVALID; |
| | 2076 | notifier()->next(node)) { |
| | 2077 | nodes.push_back(node); |
| | 2078 | } |
| | 2079 | for (int i = nodes.size() - 1; i >= 0; --i) { |
| | 2080 | snapshot.addNode(nodes[i]); |
| | 2081 | } |
| | 2082 | } |
| | 2083 | virtual void clear() { |
| | 2084 | Node node; |
| | 2085 | for (notifier()->first(node); node != INVALID; |
| | 2086 | notifier()->next(node)) { |
| | 2087 | snapshot.eraseNode(node); |
| | 2088 | } |
| | 2089 | } |
| | 2090 | |
| | 2091 | Snapshot& snapshot; |
| | 2092 | }; |
| | 2093 | |
| | 2094 | class EdgeObserverProxy : public EdgeNotifier::ObserverBase { |
| | 2095 | public: |
| | 2096 | |
| | 2097 | EdgeObserverProxy(Snapshot& _snapshot) |
| | 2098 | : snapshot(_snapshot) {} |
| | 2099 | |
| | 2100 | using EdgeNotifier::ObserverBase::attach; |
| | 2101 | using EdgeNotifier::ObserverBase::detach; |
| | 2102 | using EdgeNotifier::ObserverBase::attached; |
| | 2103 | |
| | 2104 | protected: |
| | 2105 | |
| | 2106 | virtual void add(const Edge& edge) { |
| | 2107 | snapshot.addEdge(edge); |
| | 2108 | } |
| | 2109 | virtual void add(const std::vector<Edge>& edges) { |
| | 2110 | for (int i = edges.size() - 1; i >= 0; ++i) { |
| | 2111 | snapshot.addEdge(edges[i]); |
| | 2112 | } |
| | 2113 | } |
| | 2114 | virtual void erase(const Edge& edge) { |
| | 2115 | snapshot.eraseEdge(edge); |
| | 2116 | } |
| | 2117 | virtual void erase(const std::vector<Edge>& edges) { |
| | 2118 | for (int i = 0; i < int(edges.size()); ++i) { |
| | 2119 | snapshot.eraseEdge(edges[i]); |
| | 2120 | } |
| | 2121 | } |
| | 2122 | virtual void build() { |
| | 2123 | Edge edge; |
| | 2124 | std::vector<Edge> edges; |
| | 2125 | for (notifier()->first(edge); edge != INVALID; |
| | 2126 | notifier()->next(edge)) { |
| | 2127 | edges.push_back(edge); |
| | 2128 | } |
| | 2129 | for (int i = edges.size() - 1; i >= 0; --i) { |
| | 2130 | snapshot.addEdge(edges[i]); |
| | 2131 | } |
| | 2132 | } |
| | 2133 | virtual void clear() { |
| | 2134 | Edge edge; |
| | 2135 | for (notifier()->first(edge); edge != INVALID; |
| | 2136 | notifier()->next(edge)) { |
| | 2137 | snapshot.eraseEdge(edge); |
| | 2138 | } |
| | 2139 | } |
| | 2140 | |
| | 2141 | Snapshot& snapshot; |
| | 2142 | }; |
| | 2143 | |
| | 2144 | PlanarGraph *graph; |
| | 2145 | |
| | 2146 | NodeObserverProxy node_observer_proxy; |
| | 2147 | EdgeObserverProxy edge_observer_proxy; |
| | 2148 | |
| | 2149 | std::list<Node> added_nodes; |
| | 2150 | std::list<Edge> added_edges; |
| | 2151 | |
| | 2152 | |
| | 2153 | void addNode(const Node& node) { |
| | 2154 | added_nodes.push_front(node); |
| | 2155 | } |
| | 2156 | void eraseNode(const Node& node) { |
| | 2157 | std::list<Node>::iterator it = |
| | 2158 | std::find(added_nodes.begin(), added_nodes.end(), node); |
| | 2159 | if (it == added_nodes.end()) { |
| | 2160 | clear(); |
| | 2161 | edge_observer_proxy.detach(); |
| | 2162 | throw NodeNotifier::ImmediateDetach(); |
| | 2163 | } else { |
| | 2164 | added_nodes.erase(it); |
| | 2165 | } |
| | 2166 | } |
| | 2167 | |
| | 2168 | void addEdge(const Edge& edge) { |
| | 2169 | added_edges.push_front(edge); |
| | 2170 | } |
| | 2171 | void eraseEdge(const Edge& edge) { |
| | 2172 | std::list<Edge>::iterator it = |
| | 2173 | std::find(added_edges.begin(), added_edges.end(), edge); |
| | 2174 | if (it == added_edges.end()) { |
| | 2175 | clear(); |
| | 2176 | node_observer_proxy.detach(); |
| | 2177 | throw EdgeNotifier::ImmediateDetach(); |
| | 2178 | } else { |
| | 2179 | added_edges.erase(it); |
| | 2180 | } |
| | 2181 | } |
| | 2182 | |
| | 2183 | void attach(PlanarGraph &_graph) { |
| | 2184 | graph = &_graph; |
| | 2185 | node_observer_proxy.attach(graph->notifier(Node())); |
| | 2186 | edge_observer_proxy.attach(graph->notifier(Edge())); |
| | 2187 | } |
| | 2188 | |
| | 2189 | void detach() { |
| | 2190 | node_observer_proxy.detach(); |
| | 2191 | edge_observer_proxy.detach(); |
| | 2192 | } |
| | 2193 | |
| | 2194 | bool attached() const { |
| | 2195 | return node_observer_proxy.attached(); |
| | 2196 | } |
| | 2197 | |
| | 2198 | void clear() { |
| | 2199 | added_nodes.clear(); |
| | 2200 | added_edges.clear(); |
| | 2201 | } |
| | 2202 | |
| | 2203 | public: |
| | 2204 | |
| | 2205 | /// \brief Default constructor. |
| | 2206 | /// |
| | 2207 | /// Default constructor. |
| | 2208 | /// You have to call save() to actually make a snapshot. |
| | 2209 | Snapshot() |
| | 2210 | : graph(0), node_observer_proxy(*this), |
| | 2211 | edge_observer_proxy(*this) {} |
| | 2212 | |
| | 2213 | /// \brief Constructor that immediately makes a snapshot. |
| | 2214 | /// |
| | 2215 | /// This constructor immediately makes a snapshot of the given graph. |
| | 2216 | Snapshot(PlanarGraph &gr) |
| | 2217 | : node_observer_proxy(*this), |
| | 2218 | edge_observer_proxy(*this) { |
| | 2219 | attach(gr); |
| | 2220 | } |
| | 2221 | |
| | 2222 | /// \brief Make a snapshot. |
| | 2223 | /// |
| | 2224 | /// This function makes a snapshot of the given graph. |
| | 2225 | /// It can be called more than once. In case of a repeated |
| | 2226 | /// call, the previous snapshot gets lost. |
| | 2227 | void save(PlanarGraph &gr) { |
| | 2228 | if (attached()) { |
| | 2229 | detach(); |
| | 2230 | clear(); |
| | 2231 | } |
| | 2232 | attach(gr); |
| | 2233 | } |
| | 2234 | |
| | 2235 | /// \brief Undo the changes until the last snapshot. |
| | 2236 | /// |
| | 2237 | /// This function undos the changes until the last snapshot |
| | 2238 | /// created by save() or Snapshot(PlanarGraph&). |
| | 2239 | /// |
| | 2240 | /// \warning This method invalidates the snapshot, i.e. repeated |
| | 2241 | /// restoring is not supported unless you call save() again. |
| | 2242 | void restore() { |
| | 2243 | detach(); |
| | 2244 | for (std::list<Edge>::iterator it = added_edges.begin(); |
| | 2245 | it != added_edges.end(); ++it) { |
| | 2246 | graph->erase(*it); |
| | 2247 | } |
| | 2248 | for (std::list<Node>::iterator it = added_nodes.begin(); |
| | 2249 | it != added_nodes.end(); ++it) { |
| | 2250 | graph->erase(*it); |
| | 2251 | } |
| | 2252 | clear(); |
| | 2253 | } |
| | 2254 | |
| | 2255 | /// \brief Returns \c true if the snapshot is valid. |
| | 2256 | /// |
| | 2257 | /// This function returns \c true if the snapshot is valid. |
| | 2258 | bool valid() const { |
| | 2259 | return attached(); |
| | 2260 | } |
| | 2261 | }; |
| | 2262 | }; |
| | 2263 | |
| | 2264 | /// @} |
| | 2265 | } //namespace lemon |
| | 2266 | |
| | 2267 | |
| | 2268 | #endif |