60 | | int target_at(bool d) const { |
61 | | return d?target:source; |
| 107 | class Edge { |
| 108 | friend class PlanarGraphBase; |
| 109 | protected: |
| 110 | |
| 111 | int id; |
| 112 | explicit Edge(int pid) { |
| 113 | id = pid; |
| 114 | } |
| 115 | |
| 116 | public: |
| 117 | Edge() {} |
| 118 | Edge (Invalid) { |
| 119 | id = -1; |
| 120 | } |
| 121 | bool operator==(const Edge& edge) const { |
| 122 | return id == edge.id; |
| 123 | } |
| 124 | bool operator!=(const Edge& edge) const { |
| 125 | return id != edge.id; |
| 126 | } |
| 127 | bool operator<(const Edge& edge) const { |
| 128 | return id < edge.id; |
| 129 | } |
| 130 | }; |
| 131 | |
| 132 | class Arc { |
| 133 | friend class PlanarGraphBase; |
| 134 | protected: |
| 135 | |
| 136 | int id; |
| 137 | explicit Arc(int pid) { |
| 138 | id = pid; |
| 139 | } |
| 140 | |
| 141 | public: |
| 142 | operator Edge() const { |
| 143 | return id != -1 ? edgeFromId(id / 2) : INVALID; |
| 144 | } |
| 145 | |
| 146 | Arc() {} |
| 147 | Arc (Invalid) { |
| 148 | id = -1; |
| 149 | } |
| 150 | bool operator==(const Arc& arc) const { |
| 151 | return id == arc.id; |
| 152 | } |
| 153 | bool operator!=(const Arc& arc) const { |
| 154 | return id != arc.id; |
| 155 | } |
| 156 | bool operator<(const Arc& arc) const { |
| 157 | return id < arc.id; |
| 158 | } |
| 159 | }; |
| 160 | |
| 161 | class Face { |
| 162 | friend class PlanarGraphBase; |
| 163 | protected: |
| 164 | |
| 165 | int id; |
| 166 | explicit Face(int pid) { |
| 167 | id = pid; |
| 168 | } |
| 169 | |
| 170 | public: |
| 171 | Face() {} |
| 172 | Face (Invalid) { |
| 173 | id = -1; |
| 174 | } |
| 175 | bool operator==(const Face& face) const { |
| 176 | return id == face.id; |
| 177 | } |
| 178 | bool operator!=(const Face& face) const { |
| 179 | return id != face.id; |
| 180 | } |
| 181 | bool operator<(const Face& face) const { |
| 182 | return id < face.id; |
| 183 | } |
| 184 | }; |
| 185 | |
| 186 | PlanarGraphBase() |
| 187 | : nodes(), first_node(-1), first_free_node(-1), |
| 188 | arcs(), first_free_arc(-1), |
| 189 | faces(), first_face(-1), first_free_face(-1), |
| 190 | component_id(0) { |
| 191 | } |
| 192 | |
| 193 | |
| 194 | int maxNodeId() const { |
| 195 | return nodes.size()-1; |
| 196 | } |
| 197 | int maxEdgeId() const { |
| 198 | return arcs.size() / 2 - 1; |
| 199 | } |
| 200 | int maxArcId() const { |
| 201 | return arcs.size()-1; |
| 202 | } |
| 203 | int maxFaceId() const { |
| 204 | return faces.size()-1; |
| 205 | } |
| 206 | |
| 207 | Node source(Arc e) const { |
| 208 | return Node(arcs[e.id ^ 1].target); |
| 209 | } |
| 210 | Node target(Arc e) const { |
| 211 | return Node(arcs[e.id].target); |
| 212 | } |
| 213 | Face leftFace(Arc e) const { |
| 214 | return Face(arcs[e.id].left_face); |
| 215 | } |
| 216 | Face rightFace(Arc e) const { |
| 217 | return Face(arcs[e.id ^ 1].left_face); |
| 218 | } |
| 219 | |
| 220 | Node u(Edge e) const { |
| 221 | return Node(arcs[2 * e.id].target); |
| 222 | } |
| 223 | Node v(Edge e) const { |
| 224 | return Node(arcs[2 * e.id + 1].target); |
| 225 | } |
| 226 | Face w1(Edge e) const { |
| 227 | return Face(arcs[2 * e.id].left_face); |
| 228 | } |
| 229 | Face w2(Edge e) const { |
| 230 | return Face(arcs[2 * e.id + 1].left_face); |
| 231 | } |
| 232 | |
| 233 | static bool direction(Arc e) { |
| 234 | return (e.id & 1) == 1; |
| 235 | } |
| 236 | |
| 237 | static Arc direct(Edge e, bool d) { |
| 238 | return Arc(e.id * 2 + (d ? 1 : 0)); |
| 239 | } |
| 240 | |
| 241 | //Primitives to use in iterators |
| 242 | void first(Node& node) const { |
| 243 | node.id = first_node; |
| 244 | } |
| 245 | |
| 246 | void next(Node& node) const { |
| 247 | node.id = nodes[node.id].next; |
| 248 | } |
| 249 | |
| 250 | void first(Arc& e) const { |
| 251 | int n = first_node; |
| 252 | while (n != -1 && nodes[n].first_out == -1) { |
| 253 | n = nodes[n].next; |
| 254 | } |
| 255 | e.id = (n == -1) ? -1 : nodes[n].first_out; |
| 256 | } |
| 257 | |
| 258 | void next(Arc& e) const { |
| 259 | if (arcs[e.id].next_out != -1) { |
| 260 | e.id = arcs[e.id].next_out; |
| 261 | } else { |
| 262 | int n = nodes[arcs[e.id ^ 1].target].next; |
| 263 | while (n != -1 && nodes[n].first_out == -1) { |
| 264 | n = nodes[n].next; |
| 265 | } |
| 266 | e.id = (n == -1) ? -1 : nodes[n].first_out; |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | void first(Edge& e) const { |
| 271 | int n = first_node; |
| 272 | while (n != -1) { |
| 273 | e.id = nodes[n].first_out; |
| 274 | while ((e.id & 1) != 1) { |
| 275 | e.id = arcs[e.id].next_out; |
| 276 | } |
| 277 | if (e.id != -1) { |
| 278 | e.id /= 2; |
| 279 | return; |
| 280 | } |
| 281 | n = nodes[n].next; |
| 282 | } |
| 283 | e.id = -1; |
| 284 | } |
| 285 | |
| 286 | void next(Edge& e) const { |
| 287 | int n = arcs[e.id * 2].target; |
| 288 | e.id = arcs[(e.id * 2) | 1].next_out; |
| 289 | while ((e.id & 1) != 1) { |
| 290 | e.id = arcs[e.id].next_out; |
| 291 | } |
| 292 | if (e.id != -1) { |
| 293 | e.id /= 2; |
| 294 | return; |
| 295 | } |
| 296 | n = nodes[n].next; |
| 297 | while (n != -1) { |
| 298 | e.id = nodes[n].first_out; |
| 299 | while ((e.id & 1) != 1) { |
| 300 | e.id = arcs[e.id].next_out; |
| 301 | } |
| 302 | if (e.id != -1) { |
| 303 | e.id /= 2; |
| 304 | return; |
| 305 | } |
| 306 | n = nodes[n].next; |
| 307 | } |
| 308 | e.id = -1; |
| 309 | } |
| 310 | |
| 311 | void firstOut(Arc &e, const Node& v) const { |
| 312 | e.id = nodes[v.id].first_out; |
| 313 | } |
| 314 | void nextOut(Arc &e) const { |
| 315 | e.id = arcs[e.id].next_out; |
| 316 | } |
| 317 | |
| 318 | void firstIn(Arc &e, const Node& v) const { |
| 319 | e.id = ((nodes[v.id].first_out) ^ 1); |
| 320 | if (e.id == -2) e.id = -1; |
| 321 | } |
| 322 | void nextIn(Arc &e) const { |
| 323 | e.id = ((arcs[e.id ^ 1].next_out) ^ 1); |
| 324 | if (e.id == -2) e.id = -1; |
| 325 | } |
| 326 | void lastIn(Arc &e, const Node& v) const { |
| 327 | e.id = ((nodes[v.id].last_out) ^ 1); |
| 328 | if (e.id == -2) e.id = -1; |
| 329 | } |
| 330 | void prevIn(Arc &e) const { |
| 331 | e.id = ((arcs[e.id ^ 1].prev_out) ^ 1); |
| 332 | if (e.id == -2) e.id = -1; |
| 333 | } |
| 334 | |
| 335 | void firstCwF(Arc &e, const Face &f) const { |
| 336 | e.id = faces[f.id].first_arc; |
| 337 | } |
| 338 | void nextCwF(Arc &e) const { |
| 339 | turnLeft(e); |
| 340 | setToOpposite(e); |
| 341 | if (e.id == faces[arcs[e.id].left_face].first_arc) e = INVALID; |
| 342 | } |
| 343 | |
| 344 | void firstInF(Arc &e, const Face &f) const { |
| 345 | e.id = faces[f.id].first_arc; |
| 346 | } |
| 347 | void nextInF(Arc &e) const { |
| 348 | setToOpposite(e); |
| 349 | turnRight(e); |
| 350 | if (e.id == faces[arcs[e.id].left_face].first_arc) e = INVALID; |
| 351 | } |
| 352 | void lastInF(Arc &e, const Face &f) const { |
| 353 | e.id = faces[f.id].first_arc; |
| 354 | setToOpposite(e); |
| 355 | turnRight(e); |
| 356 | } |
| 357 | void prevInF(Arc &e) const { |
| 358 | if (e.id == faces[arcs[e.id].left_face].first_arc) { |
| 359 | e = INVALID; |
| 360 | return; |
| 361 | } |
| 362 | setToOpposite(e); |
| 363 | turnRight(e); |
| 364 | } |
| 365 | |
| 366 | void firstOutF(Arc &e, const Face &f) const { |
| 367 | e.id = faces[e.id].first_arc ^ 1; |
| 368 | } |
| 369 | void nextOutF(Arc &e) const { |
| 370 | turnRight(e); |
| 371 | setToOpposite(e); |
| 372 | if (e.id == faces[arcs[e.id ^ 1].left_face].first_arc) e = INVALID; |
| 373 | } |
| 374 | |
| 375 | void first(Arc &arc, const Face& face) const { |
| 376 | arc.id = faces[face.id].first_arc; |
| 377 | } |
| 378 | |
| 379 | void turnLeftF(Arc &e) const { |
| 380 | setToOpposite(e); |
| 381 | turnRight(e); |
| 382 | } |
| 383 | |
| 384 | void turnRightF(Arc &e) const { |
| 385 | turnLeft(e); |
| 386 | setToOpposite(e); |
| 387 | } |
| 388 | |
| 389 | void turnLeft(Arc &e) const { |
| 390 | if (arcs[e.id].next_out > -1) { |
| 391 | e.id = arcs[e.id].next_out; |
| 392 | } else { |
| 393 | e.id = nodes[arcs[e.id ^ 1].target].first_out; |
| 394 | } |
| 395 | } |
| 396 | void turnRight(Arc &e) const { |
| 397 | if (arcs[e.id].prev_out > -1) { |
| 398 | e.id = arcs[e.id].prev_out; |
| 399 | } else { |
| 400 | e.id = nodes[arcs[e.id ^ 1].target].last_out; |
| 401 | } |
| 402 | } |
| 403 | void setToOpposite(Arc &a) const { |
| 404 | if (a.id != -1) a.id ^= 1; |
| 405 | } |
| 406 | |
| 407 | void firstInc(Edge &e, bool& d, const Node& v) const { |
| 408 | int a = nodes[v.id].first_out; |
| 409 | if (a != -1 ) { |
| 410 | e.id = a / 2; |
| 411 | d = ((a & 1) == 1); |
| 412 | } else { |
| 413 | e.id = -1; |
| 414 | d = true; |
| 415 | } |
| 416 | } |
| 417 | void nextInc(Edge &e, bool& d) const { |
| 418 | int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out); |
| 419 | if (a != -1 ) { |
| 420 | e.id = a / 2; |
| 421 | d = ((a & 1) == 1); |
| 422 | } else { |
| 423 | e.id = -1; |
| 424 | d = true; |
| 425 | } |
| 426 | } |
| 427 | |
| 428 | void first(Face& face) const { |
| 429 | face.id = first_face; |
| 430 | } |
| 431 | |
| 432 | void next(Face& face) const { |
| 433 | face.id = faces[face.id].next; |
| 434 | } |
| 435 | |
| 436 | Arc arcAt(Node n, Edge e) { |
| 437 | if (e.id == -1) return INVALID; |
| 438 | return Arc((e.id*2) | (arcs[e.id*2].target == n.id?1:0)); |
| 439 | } |
| 440 | |
| 441 | static int id(Node v) { |
| 442 | return v.id; |
| 443 | } |
| 444 | static int id(Arc e) { |
| 445 | return e.id; |
| 446 | } |
| 447 | static int id(Edge e) { |
| 448 | return e.id; |
| 449 | } |
| 450 | static int id(Face f) { |
| 451 | return f.id; |
| 452 | } |
| 453 | |
| 454 | static Node nodeFromId(int id) { |
| 455 | return Node(id); |
| 456 | } |
| 457 | static Arc arcFromId(int id) { |
| 458 | return Arc(id); |
| 459 | } |
| 460 | static Edge edgeFromId(int id) { |
| 461 | return Edge(id); |
| 462 | } |
| 463 | static Face faceFromId(int id) { |
| 464 | return Face(id); |
| 465 | } |
| 466 | |
| 467 | bool valid(Node n) const { |
| 468 | return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && |
| 469 | nodes[n.id].prev != -2; |
| 470 | } |
| 471 | |
| 472 | bool valid(Arc a) const { |
| 473 | return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && |
| 474 | arcs[a.id].prev_out != -2; |
| 475 | } |
| 476 | |
| 477 | bool valid(Edge e) const { |
| 478 | return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) && |
| 479 | arcs[2 * e.id].prev_out != -2; |
| 480 | } |
| 481 | |
| 482 | bool valid(Face f) const { |
| 483 | return f.id >= 0 && f.id < static_cast<int>(faces.size()) && |
| 484 | faces[f.id].prev != -2; |
| 485 | } |
| 486 | |
| 487 | Node addNode() { |
| 488 | int n; |
| 489 | |
| 490 | if (first_free_node==-1) { |
| 491 | n = nodes.size(); |
| 492 | nodes.push_back(NodeT()); |
| 493 | } else { |
| 494 | n = first_free_node; |
| 495 | first_free_node = nodes[n].next; |
| 496 | } |
| 497 | |
| 498 | nodes[n].next = first_node; |
| 499 | nodes[n].component = component_id++; |
| 500 | if (first_node != -1) nodes[first_node].prev = n; |
| 501 | first_node = n; |
| 502 | nodes[n].prev = -1; |
| 503 | |
| 504 | nodes[n].first_out = nodes[n].last_out = -1; |
| 505 | |
| 506 | return Node(n); |
| 507 | } |
| 508 | |
| 509 | Edge addEdge(Node u, Node v, Edge e_u, Edge e_v) { |
| 510 | |
| 511 | Arc p_u = arcAt(u,e_u); |
| 512 | Arc p_v = arcAt(v,e_v); |
| 513 | |
| 514 | if (p_u.id > -1 && p_v.id > -1 && arcs[p_u.id].left_face != arcs[p_v.id]. |
| 515 | left_face && nodes[u.id].component == nodes[v.id].component) return |
| 516 | INVALID; |
| 517 | |
| 518 | int n = addBlankEdge(); |
| 519 | |
| 520 | arcs[n].target = u.id; |
| 521 | arcs[n | 1].target = v.id; |
| 522 | |
| 523 | arcs[n].prev_out = p_v.id; |
| 524 | if (p_v.id > -1) { |
| 525 | arcs[n].next_out = arcs[p_v.id].next_out; |
| 526 | arcs[p_v.id].next_out = n; |
| 527 | } else { |
| 528 | arcs[n].next_out = nodes[v.id].first_out; |
| 529 | nodes[v.id].first_out = n; |
| 530 | } |
| 531 | if (arcs[n].next_out > -1) { |
| 532 | arcs[arcs[n].next_out].prev_out = n; |
| 533 | } else { |
| 534 | nodes[v.id].last_out = n; |
| 535 | } |
| 536 | |
| 537 | arcs[n | 1].prev_out = p_u.id; |
| 538 | if (p_u.id > -1) { |
| 539 | arcs[n | 1].next_out = arcs[p_u.id].next_out; |
| 540 | arcs[p_u.id].next_out = n | 1; |
| 541 | } else { |
| 542 | arcs[n | 1].next_out = nodes[u.id].first_out; |
| 543 | nodes[u.id].first_out = n | 1; |
| 544 | } |
| 545 | if (arcs[n | 1].next_out > -1) { |
| 546 | arcs[arcs[n | 1].next_out].prev_out = n | 1; |
| 547 | } else { |
| 548 | nodes[u.id].last_out = n | 1; |
| 549 | } |
| 550 | |
| 551 | //Add the extra face, if needed |
| 552 | if (p_u.id > -1 & p_v.id > -1) { |
| 553 | int oldf = arcs[p_u.id].left_face; |
| 554 | int oldfb = arcs[p_v.id].left_face; |
| 555 | arcs[n].left_face = arcs[n | 1].left_face = oldf; |
| 556 | Face f = addFace(); |
| 557 | faces[f.id].first_arc = n | 1; |
| 558 | faces[oldf].first_arc = n; |
| 559 | Arc arc(n | 1); |
| 560 | wall_paint(arc,f.id,arc); |
| 561 | if (nodes[v.id].component != nodes[u.id].component) { |
| 562 | erase(Face(oldf)); |
| 563 | erase(Face(oldfb)); |
| 564 | int ca = nodes[u.id].component; |
| 565 | int cb = nodes[v.id].component; |
| 566 | int k = first_node; |
| 567 | while (k != -1) { |
| 568 | if (nodes[k].component == cb) |
| 569 | nodes[k].component = ca; |
| 570 | k = nodes[k].next; |
| 571 | } |
| 572 | } |
| 573 | } else if (p_u.id > -1) { |
| 574 | arcs[n].left_face = arcs[n | 1].left_face = arcs[p_u.id].left_face; |
| 575 | faces[arcs[n].left_face].first_arc = n | 1; |
| 576 | nodes[v.id].component = nodes[u.id].component; |
| 577 | } else if (p_v.id > -1) { |
| 578 | arcs[n].left_face = arcs[n | 1].left_face = arcs[p_v.id].left_face; |
| 579 | faces[arcs[n].left_face].first_arc = n | 1; |
| 580 | nodes[u.id].component = nodes[v.id].component; |
| 581 | } else { //both prevs are INVALID |
| 582 | Face f = addFace(); |
| 583 | arcs[n].left_face = arcs[n | 1].left_face = f.id; |
| 584 | faces[f.id].first_arc = n | 1; |
| 585 | nodes[v.id].component = nodes[u.id].component; |
| 586 | } |
| 587 | |
| 588 | return Edge(n / 2); |
| 589 | } |
| 590 | |
| 591 | void erase(const Node& node) { |
| 592 | int n = node.id; |
| 593 | |
| 594 | if (nodes[n].next != -1) { |
| 595 | nodes[nodes[n].next].prev = nodes[n].prev; |
| 596 | } |
| 597 | |
| 598 | if (nodes[n].prev != -1) { |
| 599 | nodes[nodes[n].prev].next = nodes[n].next; |
| 600 | } else { |
| 601 | first_node = nodes[n].next; |
| 602 | } |
| 603 | |
| 604 | nodes[n].next = first_free_node; |
| 605 | first_free_node = n; |
| 606 | nodes[n].prev = -2; |
| 607 | } |
| 608 | |
| 609 | void erase(const Edge& edge) { |
| 610 | int n = edge.id * 2; |
| 611 | |
| 612 | //"retreat" the incident faces' first arcs |
| 613 | int fl = arcs[n].left_face; |
| 614 | if ((faces[fl].first_arc | 1) == (n | 1)) { |
| 615 | Arc e(faces[fl].first_arc); |
| 616 | turnRightF(e); |
| 617 | if ((e.id | 1) == (n | 1)) turnRightF(e); |
| 618 | faces[fl].first_arc = e.id; |
| 619 | } |
| 620 | |
| 621 | int fr = arcs[n | 1].left_face; |
| 622 | |
| 623 | bool comp_split = false; |
| 624 | if (fr != fl) { |
| 625 | Arc arc(faces[fr].first_arc); |
| 626 | wall_paint(arc,fl,arc); |
| 627 | erase(Face(fr)); |
| 628 | } else if ((arcs[n].next_out > -1 || arcs[n].prev_out > -1) && |
| 629 | (arcs[n | 1].next_out > -1 || arcs[n | 1].prev_out > -1)) { |
| 630 | comp_split = true; |
| 631 | Arc arc(n); |
| 632 | Arc ed = arc; |
| 633 | ed.id ^= 1; |
| 634 | turnRightF(arc); |
| 635 | Face f = addFace(); |
| 636 | wall_paint(arc,f.id,ed); |
| 637 | faces[f.id].first_arc = arc.id; |
| 638 | } |
| 639 | |
| 640 | if (arcs[n].next_out != -1) { |
| 641 | arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
| 642 | } else { |
| 643 | nodes[arcs[n].target].last_out = arcs[n].prev_out; |
| 644 | } |
| 645 | |
| 646 | if (arcs[n].prev_out != -1) { |
| 647 | arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
| 648 | } else { |
| 649 | nodes[arcs[n | 1].target].first_out = arcs[n].next_out; |
| 650 | } |
| 651 | |
| 652 | if (arcs[n | 1].next_out != -1) { |
| 653 | arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out; |
| 654 | } else { |
| 655 | nodes[arcs[n | 1].target].last_out = arcs[n | 1].prev_out; |
| 656 | } |
| 657 | |
| 658 | if (arcs[n | 1].prev_out != -1) { |
| 659 | arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out; |
| 660 | } else { |
| 661 | nodes[arcs[n].target].first_out = arcs[n | 1].next_out; |
| 662 | } |
| 663 | |
| 664 | arcs[n].next_out = first_free_arc; |
| 665 | first_free_arc = n; |
| 666 | arcs[n].prev_out = -2; |
| 667 | arcs[n | 1].prev_out = -2; |
| 668 | |
| 669 | if (comp_split) component_relabel(Node(arcs[n | 1].target), |
| 670 | component_id++); |
| 671 | |
| 672 | } |
| 673 | |
| 674 | void clear() { |
| 675 | arcs.clear(); |
| 676 | nodes.clear(); |
| 677 | faces.clear(); |
| 678 | first_node = first_free_node = first_free_arc = first_face = |
| 679 | first_free_face = -1; |
| 680 | } |
| 681 | |
| 682 | Node split(Edge e) { |
| 683 | Node v = addNode(); |
| 684 | Arc a(e.id*2); |
| 685 | int b = addBlankEdge(); |
| 686 | |
| 687 | nodes[v.id].component = nodes[arcs[a.id].target].component; |
| 688 | nodes[v.id].first_out = a.id; |
| 689 | nodes[v.id].last_out = b | 1; |
| 690 | |
| 691 | arcs[b] = arcs[a.id]; |
| 692 | arcs[b].target = v.id; |
| 693 | if (arcs[a.id].next_out > -1) |
| 694 | arcs[arcs[a.id].next_out].prev_out = b; |
| 695 | else |
| 696 | nodes[arcs[a.id | 1].target].last_out = b; |
| 697 | if (arcs[a.id].prev_out > -1) |
| 698 | arcs[arcs[a.id].prev_out].next_out = b; |
| 699 | else |
| 700 | nodes[arcs[a.id | 1].target].first_out = b; |
| 701 | |
| 702 | arcs[b | 1] = arcs[a.id | 1]; |
| 703 | arcs[b | 1].next_out = -1; |
| 704 | arcs[b | 1].prev_out = a.id; |
| 705 | |
| 706 | arcs[a.id].next_out = b | 1; |
| 707 | arcs[a.id].prev_out = -1; |
| 708 | arcs[a.id | 1].target = v.id; |
| 709 | |
| 710 | |
| 711 | return v; |
| 712 | } |
| 713 | |
| 714 | protected: |
| 715 | |
| 716 | void wall_paint(Arc arc, int f_id, Arc ed) { |
| 717 | do { |
| 718 | arcs[arc.id].left_face = f_id; |
| 719 | turnRightF(arc); |
| 720 | } while (arc != ed); |
| 721 | } |
| 722 | |
| 723 | void component_relabel(Node node, int comp_id) { |
| 724 | std::vector<int> ns(nodes.size()); |
| 725 | std::list<int> q; |
| 726 | q.push_back(node.id); |
| 727 | ns[node.id] = 1; |
| 728 | while (!q.empty()) { |
| 729 | int n = q.front(); |
| 730 | ns[n] = 2; |
| 731 | nodes[n].component = comp_id; |
| 732 | q.pop_front(); |
| 733 | Arc arc; |
| 734 | firstOut(arc,Node(n)); |
| 735 | while (arc.id > -1) { |
| 736 | int m = arcs[arc.id].target; |
| 737 | if (ns[m] == 0) { |
| 738 | ns[m] = 1; |
| 739 | q.push_back(m); |
| 740 | } |
| 741 | nextOut(arc); |
| 742 | } |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | Face addFace() { |
| 747 | int n; |
| 748 | |
| 749 | if (first_free_face==-1) { |
| 750 | n = faces.size(); |
| 751 | faces.push_back(FaceT()); |
| 752 | } else { |
| 753 | n = first_free_face; |
| 754 | first_free_face = faces[n].next; |
| 755 | } |
| 756 | |
| 757 | faces[n].next = first_face; |
| 758 | if (first_face != -1) faces[first_face].prev = n; |
| 759 | first_face = n; |
| 760 | faces[n].prev = -1; |
| 761 | |
| 762 | faces[n].first_arc = -1; |
| 763 | |
| 764 | return Face(n); |
| 765 | } |
| 766 | |
| 767 | void erase(const Face& face) { |
| 768 | int n = face.id; |
| 769 | |
| 770 | if (faces[n].next != -1) { |
| 771 | faces[faces[n].next].prev = faces[n].prev; |
| 772 | } |
| 773 | |
| 774 | if (faces[n].prev != -1) { |
| 775 | faces[faces[n].prev].next = faces[n].next; |
| 776 | } else { |
| 777 | first_face = faces[n].next; |
| 778 | } |
| 779 | |
| 780 | faces[n].next = first_free_face; |
| 781 | first_free_face = n; |
| 782 | faces[n].prev = -2; |
| 783 | } |
| 784 | |
| 785 | int addBlankEdge() { |
| 786 | int n; |
| 787 | if (first_free_arc == -1) { |
| 788 | n = arcs.size(); |
| 789 | arcs.push_back(ArcT()); |
| 790 | arcs.push_back(ArcT()); |
| 791 | } else { |
| 792 | n = first_free_arc; |
| 793 | first_free_arc = arcs[n].next_out; |
| 794 | } |
| 795 | return n; |
| 796 | } |
| 797 | |
| 798 | #ifdef REMOVE_BEFORE_RELEASE |
| 799 | public: |
| 800 | void print() { |
| 801 | std::cout << "Nodes: " << std::endl; |
| 802 | for (int i=0; i<nodes.size(); ++i) |
| 803 | std::cout << i << ":" |
| 804 | << " fo=" << nodes[i].first_out |
| 805 | << " pr=" << nodes[i].prev |
| 806 | << " nx=" << nodes[i].next |
| 807 | << " co=" << nodes[i].component |
| 808 | <<std::endl; |
| 809 | std::cout << "Arcs: " << std::endl; |
| 810 | for (int i=0; i<arcs.size(); ++i) { |
| 811 | if (arcs[i].next_out > -2) { |
| 812 | std::cout << i << ":" |
| 813 | << " tg=" << arcs[i].target |
| 814 | << " po=" << arcs[i].prev_out |
| 815 | << " no=" << arcs[i].next_out |
| 816 | << " lf=" << arcs[i].left_face |
| 817 | <<std::endl; |
| 818 | } else std::cout << i << ": (deleted)" << std::endl; |
| 819 | } |
| 820 | std::cout << "Faces: " << std::endl; |
| 821 | for (int i=0; i<faces.size(); ++i) |
| 822 | std::cout << i |
| 823 | << " pr=" << faces[i].prev |
| 824 | << " nx=" << faces[i].next |
| 825 | << " fa=" << faces[i].first_arc |
| 826 | <<std::endl; |
| 827 | } |
| 828 | #endif |
| 829 | |
| 830 | }; |
| 831 | |
| 832 | template<typename Base> |
| 833 | class PlanarGraphExtender : public Base{ |
| 834 | |
| 835 | typedef Base Parent; |
| 836 | |
| 837 | public: |
| 838 | typedef PlanarGraphExtender Graph; |
| 839 | |
| 840 | PlanarGraphExtender() {} |
| 841 | |
| 842 | typedef typename Parent::Node Node; |
| 843 | typedef typename Parent::Arc Arc; |
| 844 | typedef typename Parent::Edge Edge; |
| 845 | typedef typename Parent::Face Face; |
| 846 | |
| 847 | /// Iterator class for the faces. |
| 848 | |
| 849 | /// This iterator goes through the faces of a planar graph. |
| 850 | class FaceIt : public Face { |
| 851 | const Graph* _graph; |
| 852 | public: |
| 853 | |
| 854 | FaceIt() {} |
| 855 | |
| 856 | FaceIt(Invalid i) : Face(i) { } |
| 857 | |
| 858 | explicit FaceIt(const Graph& graph) : _graph(&graph) { |
| 859 | _graph->first(static_cast<Face&>(*this)); |
| 860 | } |
| 861 | |
| 862 | FaceIt(const Graph& graph, const Face& face) |
| 863 | : Face(face), _graph(&graph) {} |
| 864 | |
| 865 | FaceIt& operator++() { |
| 866 | _graph->next(*this); |
| 867 | return *this; |
| 868 | } |
| 869 | |
| 870 | }; |
| 871 | |
| 872 | |
| 873 | /// Iterator class for the arcs on the boundary of a face. |
| 874 | |
| 875 | /// This iterator goes through the arcs on the boundary of a face clockwise. |
| 876 | class CwBoundaryArcIt : public Arc { |
| 877 | const Graph* _graph; |
| 878 | Face _face; |
| 879 | Arc f_arc; |
| 880 | public: |
| 881 | |
| 882 | CwBoundaryArcIt() { } |
| 883 | |
| 884 | CwBoundaryArcIt(Invalid i) : Arc(i) { } |
| 885 | |
| 886 | CwBoundaryArcIt(const Graph& graph, const Face& face) |
| 887 | : _graph(&graph), _face(face) { |
| 888 | _graph->firstCwF(static_cast<Arc&>(*this),face); |
| 889 | f_arc = *this; |
| 890 | } |
| 891 | |
| 892 | CwBoundaryArcIt(const Graph& graph, const Arc& arc) |
| 893 | : Arc(arc), _graph(&graph) {} |
| 894 | |
| 895 | CwBoundaryArcIt& operator++() { |
| 896 | _graph->nextCwF(*this); |
| 897 | return *this; |
| 898 | } |
| 899 | |
| 900 | }; |
| 901 | |
| 902 | /// Iterator class for the arcs around a node. |
| 903 | |
| 904 | /// This iterator goes through the arcs around a node anticlockwise. |
| 905 | class CcwArcIt : public Arc { |
| 906 | const Graph* _graph; |
| 907 | const Node _node; |
| 908 | public: |
| 909 | |
| 910 | CcwArcIt() { } |
| 911 | |
| 912 | CcwArcIt(Invalid i) : Arc(i) { } |
| 913 | |
| 914 | CcwArcIt(const Graph& graph, const Node& node) |
| 915 | : _graph(&graph), _node(node) { |
| 916 | _graph->firstCcw(*this, node); |
| 917 | } |
| 918 | |
| 919 | CcwArcIt(const Graph& graph, const Arc& arc) |
| 920 | : Arc(arc), _graph(&graph) {} |
| 921 | |
| 922 | CcwArcIt& operator++() { |
| 923 | _graph->nextCcw(*this, _node); |
| 924 | return *this; |
| 925 | } |
| 926 | |
| 927 | }; |
| 928 | |
| 929 | }; |
| 930 | |
| 931 | typedef PlanarGraphExtender<GraphExtender<PlanarGraphBase> > |
| 932 | ExtendedPlanarGraphBase; |
| 933 | |
| 934 | |
| 935 | /// \addtogroup graphs |
| 936 | /// @{ |
| 937 | |
| 938 | ///An undirected planar graph structure. |
| 939 | |
| 940 | ///\ref PlanarGraph is a versatile and fast undirected planar graph |
| 941 | ///implementation based on linked lists that are stored in |
| 942 | ///\c std::vector structures. It maintains a topology of nodes, edges |
| 943 | ///and faces. |
| 944 | /// |
| 945 | ///This type fully conforms to the \ref concepts::Graph "Graph concept" |
| 946 | ///and it also provides several useful additional functionalities, including |
| 947 | ///those specific to planar graphs. |
| 948 | ///Most of its member functions and nested classes are documented |
| 949 | ///only in the concept class. |
| 950 | /// |
| 951 | ///This class provides only linear time counting for nodes, edges, arcs and |
| 952 | ///faces. |
| 953 | /// |
| 954 | ///A disconnected planar graph has have an outer face for each of its |
| 955 | ///components, effectively turning them into separate graphs. Each component |
| 956 | ///has a corresponding component in the dual. |
| 957 | ///\sa concepts::Graph |
| 958 | ///\sa PlaneGraph |
| 959 | class PlanarGraph : public ExtendedPlanarGraphBase { |
| 960 | typedef ExtendedPlanarGraphBase Parent; |
| 961 | |
| 962 | public: |
| 963 | /// Graphs are \e not copy constructible. Use GraphCopy instead. |
| 964 | PlanarGraph(const PlanarGraph &) = delete; |
| 965 | /// \brief Assignment of a graph to another one is \e not allowed. |
| 966 | /// Use GraphCopy instead. |
| 967 | void operator=(const PlanarGraph &) = delete; |
| 968 | |
| 969 | /// \brief Constructor |
| 970 | |
| 971 | /// Constructor. |
| 972 | /// |
| 973 | PlanarGraph() {} |
| 974 | |
| 975 | typedef Parent::OutArcIt IncEdgeIt; |
| 976 | |
| 977 | /// \brief Add a new node to the graph. |
| 978 | /// |
| 979 | /// This function adds a new node to the graph. A new outer face is created |
| 980 | /// for the node. |
| 981 | /// \return The new node. |
| 982 | Node addNode() { |
| 983 | return Parent::addNode(); |
| 984 | } |
| 985 | |
| 986 | /// \brief Add a new edge to the graph. |
| 987 | /// |
| 988 | /// This function adds a new edge to the graph between nodes |
| 989 | /// \c u and \c v with inherent orientation from node \c u to |
| 990 | /// node \c v. \c p_u and \c p_v are the edges that directly precede the new |
| 991 | /// edge in anticlockwise order at the nodes \c u and \c v, respectively. |
| 992 | /// INVALID should be passed as \c p_u or \c p_v if and only if the |
| 993 | /// respective node is isolated. |
| 994 | /// |
| 995 | /// If \c u and \c v are in the same component, \c p_u and \c p_v must share |
| 996 | /// the same left face (when looking from \c u or \c v). This face will be |
| 997 | /// split in two. If \c u and \c v are in different components, one of the |
| 998 | /// outer faces will be deleted. |
| 999 | /// \note It can be costly to join components unless one of them is an |
| 1000 | /// isolated node. |
| 1001 | /// \return The new edge, or INVALID if the parameters don't meet the |
| 1002 | /// preconditions. |
| 1003 | Edge addEdge(Node u, Node v, Edge p_u, Edge p_v) { |
| 1004 | return PlanarGraphBase::addEdge(u, v, p_u, p_v); |
| 1005 | } |
| 1006 | |
| 1007 | ///\brief Erase a node from the graph. |
| 1008 | /// |
| 1009 | /// This function erases the given node along with its incident arcs |
| 1010 | /// from the graph. |
| 1011 | /// |
| 1012 | /// \note All iterators referencing the removed node or the incident |
| 1013 | /// edges are invalidated, of course. |
| 1014 | void erase(Node n) { |
| 1015 | Parent::erase(n); |
| 1016 | } |
| 1017 | |
| 1018 | ///\brief Erase an edge from the graph. |
| 1019 | /// |
| 1020 | /// This function erases the given edge from the graph. The faces on the two |
| 1021 | /// sides are merged into one, unless the edge holds two components |
| 1022 | /// together. In the latter case, a new outer face is added and the |
| 1023 | /// component is split in two. |
| 1024 | /// |
| 1025 | /// \note It can be costly to split a component, unless one of the resulting |
| 1026 | /// components is an isolated node. |
| 1027 | /// \note All iterators referencing the removed edge are invalidated, |
| 1028 | /// of course. |
| 1029 | void erase(Edge e) { |
| 1030 | Parent::erase(e); |
| 1031 | } |
| 1032 | /// Node validity check |
| 1033 | |
| 1034 | /// This function gives back \c true if the given node is valid, |
| 1035 | /// i.e. it is a real node of the graph. |
| 1036 | /// |
| 1037 | /// \warning A removed node could become valid again if new nodes are |
| 1038 | /// added to the graph. |
| 1039 | bool valid(Node n) const { |
| 1040 | return Parent::valid(n); |
| 1041 | } |
| 1042 | /// Edge validity check |
| 1043 | |
| 1044 | /// This function gives back \c true if the given edge is valid, |
| 1045 | /// i.e. it is a real edge of the graph. |
| 1046 | /// |
| 1047 | /// \warning A removed edge could become valid again if new edges are |
| 1048 | /// added to the graph. |
| 1049 | bool valid(Edge e) const { |
| 1050 | return Parent::valid(e); |
| 1051 | } |
| 1052 | /// Arc validity check |
| 1053 | |
| 1054 | /// This function gives back \c true if the given arc is valid, |
| 1055 | /// i.e. it is a real arc of the graph. |
| 1056 | /// |
| 1057 | /// \warning A removed arc could become valid again if new edges are |
| 1058 | /// added to the graph. |
| 1059 | bool valid(Arc a) const { |
| 1060 | return Parent::valid(a); |
| 1061 | } |
| 1062 | |
| 1063 | /// Face validity check |
| 1064 | |
| 1065 | /// This function gives back \c true if the given face is valid, |
| 1066 | /// i.e. it is a real face of the graph. |
| 1067 | /// |
| 1068 | /// \warning A removed face could become valid again if new edges are |
| 1069 | /// added to the graph. |
| 1070 | bool valid(Face f) const { |
| 1071 | return Parent::valid(f); |
| 1072 | } |
| 1073 | |
| 1074 | /// \brief Change the first node of an edge. |
| 1075 | /// |
| 1076 | /// Planar graphs don't support changing the endpoints of edges. |
| 1077 | void changeU(Edge e, Node n) = delete; |
| 1078 | /// \brief Change the second node of an edge. |
| 1079 | /// |
| 1080 | /// Planar graphs don't support changing the endpoints of edges. |
| 1081 | void changeV(Edge e, Node n) = delete; |
| 1082 | |
| 1083 | /// \brief Contract two nodes. |
| 1084 | /// |
| 1085 | /// This function contracts the given two nodes. |
| 1086 | /// Node \c b is removed, but instead of deleting |
| 1087 | /// its incident edges, they are joined to node \c a. |
| 1088 | /// The two nodes must have exactly one edge between them, otherwise the |
| 1089 | /// function will fail. The joining edge will be deleted. |
| 1090 | /// |
| 1091 | /// \note All edge and arc iterators whose base node is |
| 1092 | /// \c b are invalidated. |
| 1093 | /// Moreover all iterators referencing node \c b or the removed |
| 1094 | /// edge are also invalidated. Other iterators remain valid. |
| 1095 | /// |
| 1096 | ///\warning This functionality cannot be used together with the |
| 1097 | ///Snapshot feature. |
| 1098 | /*TODO: rewrite this function |
| 1099 | void contract(Node a, Node b, bool r = true) { |
| 1100 | for(IncEdgeIt e(*this, b); e!=INVALID;) { |
| 1101 | IncEdgeIt f = e; ++f; |
| 1102 | if (r && runningNode(e) == a) { |
| 1103 | erase(e); |
| 1104 | } else if (u(e) == b) { |
| 1105 | changeU(e, a); |
| 1106 | } else { |
| 1107 | changeV(e, a); |
| 1108 | } |
| 1109 | e = f; |
| 1110 | } |
| 1111 | erase(b); |
147 | | int id; |
148 | | bool dir; //travel direction during iteration, |
149 | | //true means we are travelling from source to target |
150 | | explicit Arc(int pid) { id = pid; dir = true; } |
151 | | |
152 | | public: |
153 | | Arc() {} |
154 | | Arc (Invalid) { id = -1; } |
155 | | bool operator==(const Arc& arc) const {return id == arc.id;} |
156 | | bool operator!=(const Arc& arc) const {return id != arc.id;} |
157 | | bool operator<(const Arc& arc) const {return id < arc.id;} |
158 | | }; |
159 | | |
160 | | class Face { |
161 | | friend class PlanarDigraphBase; |
162 | | friend class PlanarDigraph; |
163 | | protected: |
164 | | |
165 | | int id; |
166 | | explicit Face(int pid) { id = pid;} |
167 | | |
168 | | public: |
169 | | Face() {} |
170 | | Face (Invalid) { id = -1; } |
171 | | bool operator==(const Face& face) const {return id == face.id;} |
172 | | bool operator!=(const Face& face) const {return id != face.id;} |
173 | | bool operator<(const Face& face) const {return id < face.id;} |
174 | | }; |
175 | | |
176 | | |
177 | | |
178 | | PlanarDigraphBase() |
179 | | : nodes(), first_node(-1), first_free_node(-1), |
180 | | arcs(), first_free_arc(-1), |
181 | | faces(), first_face(-1), first_free_face(-1), |
182 | | component_id(0) { |
183 | | } |
184 | | |
185 | | |
186 | | int maxNodeId() const { return nodes.size()-1; } |
187 | | int maxArcId() const { return arcs.size()-1; } |
188 | | int maxFaceId() const { return faces.size()-1; } |
189 | | |
190 | | Node source(Arc e) const { return Node(arcs[e.id].source); } |
191 | | Node target(Arc e) const { return Node(arcs[e.id].target); } |
192 | | Face leftFace(Arc e) const { return Face(arcs[e.id].left_face); } |
193 | | Face rightFace(Arc e) const { return Face(arcs[e.id].right_face); } |
194 | | |
195 | | |
196 | | void first(Node& node) const { |
197 | | node.id = first_node; |
198 | | } |
199 | | |
200 | | void next(Node& node) const { |
201 | | node.id = nodes[node.id].next; |
202 | | } |
203 | | |
204 | | |
205 | | void first(Arc& arc) const { |
206 | | int n; |
207 | | for(n = first_node; |
208 | | n != -1 && nodes[n].first_out == -1; |
209 | | n = nodes[n].next) {} |
210 | | arc.id = (n == -1) ? -1 : nodes[n].first_out; |
211 | | arc.dir = true; |
212 | | } |
213 | | |
214 | | void next(Arc& arc) const { |
215 | | if (arcs[arc.id].next_out != -1) { |
216 | | arc.id = arcs[arc.id].next_out; |
217 | | } else { |
218 | | int n; |
219 | | for(n = nodes[arcs[arc.id].source].next; |
220 | | n != -1 && nodes[n].first_out == -1; |
221 | | n = nodes[n].next) {} |
222 | | arc.id = (n == -1) ? -1 : nodes[n].first_out; |
223 | | } |
224 | | } |
225 | | |
226 | | void firstOut(Arc &e, const Node& v) const { |
227 | | e.id = nodes[v.id].first_out; |
228 | | e.dir = true; |
229 | | } |
230 | | void nextOut(Arc &e) const { |
231 | | e.id=arcs[e.id].next_out; |
232 | | } |
233 | | |
234 | | void firstIn(Arc &e, const Node& v) const { |
235 | | e.id = nodes[v.id].first_in; |
236 | | e.dir = false; |
237 | | } |
238 | | void nextIn(Arc &e) const { |
239 | | e.id=arcs[e.id].next_in; |
240 | | } |
241 | | |
242 | | |
243 | | void firstCcw(Arc &e, const Node &v) const { |
244 | | e.id = nodes[v.id].first_ccw; |
245 | | if (e.id > -1) e.dir = v.id == arcs[e.id].source; |
246 | | } |
247 | | void nextCcw(Arc &e) const { |
248 | | int n = arcs[e.id].source_at(e.dir); |
249 | | e.id = arcs[e.id].next_at(e.dir); |
250 | | if (e.id > -1) e.dir = arcs[e.id].source == n; |
251 | | } |
252 | | |
253 | | void firstCw(Arc &e, const Node &v) const { |
254 | | e.id = nodes[v.id].last_ccw; |
255 | | if (e.id > -1) e.dir = v.id == arcs[e.id].source; |
256 | | } |
257 | | |
258 | | void nextCw(Arc &e) const { |
259 | | int n = arcs[e.id].source_at(e.dir); |
260 | | e.id = arcs[e.id].prev_at(e.dir); |
261 | | if (e.id > -1) e.dir = arcs[e.id].source == n; |
262 | | } |
263 | | |
264 | | void turnLeft(Arc &e) const { |
265 | | int n = arcs[e.id].source_at(e.dir); |
266 | | e.id = arcs[e.id].next_at(e.dir); |
267 | | if (e.id == -1) e.id = nodes[n].first_ccw; |
268 | | if (e.id > -1) e.dir = arcs[e.id].source == n; |
269 | | } |
270 | | void turnRight(Arc &e) const { |
271 | | int n = arcs[e.id].source_at(e.dir); |
272 | | e.id = arcs[e.id].prev_at(e.dir); |
273 | | if (e.id == -1) e.id = nodes[n].last_ccw; |
274 | | if (e.id > -1) e.dir = arcs[e.id].source == n; |
275 | | } |
276 | | |
277 | | void first(Face& face) const { |
278 | | face.id = first_face; |
279 | | } |
280 | | |
281 | | void next(Face& face) const { |
282 | | face.id = faces[face.id].next; |
283 | | } |
284 | | |
285 | | void firstCcwF(Arc &e, const Face &f) const { |
286 | | e.id = faces[f.id].first_arc; |
287 | | e.dir = faces[f.id].first_arc_dir; |
288 | | } |
289 | | void nextCcwF(Arc &e) const { |
290 | | int f = arcs[e.id].left_face_at(e.dir); |
291 | | turnLeftF(e); |
292 | | if (e.id == faces[f].first_arc && e.dir == faces[f].first_arc_dir) e.id = -1; |
293 | | } |
294 | | |
295 | | void firstCwF(Arc &e, const Face &f) const { |
296 | | e.id = faces[f.id].first_arc; |
297 | | e.dir = faces[f.id].first_arc_dir; |
298 | | } |
299 | | void nextCwF(Arc &e) const { |
300 | | int f = arcs[e.id].left_face_at(e.dir); |
301 | | turnRightF(e); |
302 | | if (e.id == faces[f].first_arc && e.dir == faces[f].first_arc_dir) e = INVALID; |
303 | | } |
304 | | |
305 | | void turnLeftF(Arc &e) const { |
306 | | e.dir = !e.dir; |
307 | | turnRight(e); |
308 | | } |
309 | | |
310 | | void turnRightF(Arc &e) const { |
311 | | turnLeft(e); |
312 | | e.dir = !e.dir; |
313 | | } |
314 | | |
315 | | void firstInF(Arc &e, const Face &f) const { |
316 | | e.id = faces[f.id].first_arc; |
317 | | e.dir = faces[f.id].first_arc_dir; |
318 | | while (e.id > -1 && arcs[e.id].right_face != f.id) { |
319 | | turnLeft(e); |
320 | | } |
321 | | } |
322 | | void nextInF(Arc &e) const { |
323 | | int f = arcs[e.id].right_face_at(e.dir); |
324 | | do { |
325 | | turnLeft(e); |
326 | | if (e.id == faces[f].first_arc && e.dir == faces[f].first_arc_dir) e.id = -1; |
327 | | } while (e.id > -1 && arcs[e.id].right_face != f); |
328 | | } |
329 | | |
330 | | void firstOutF(Arc &e, const Face &f) const { |
331 | | e.id = faces[f.id].first_arc; |
332 | | e.dir = faces[f.id].first_arc_dir; |
333 | | while (e.id > -1 && arcs[e.id].left_face != f.id) { |
334 | | turnRight(e); |
335 | | } |
336 | | } |
337 | | void nextOutF(Arc &e) const { |
338 | | int f = arcs[e.id].left_face_at(e.dir); |
339 | | do { |
340 | | turnLeft(e); |
341 | | if (e.id == faces[f].first_arc && e.dir == faces[f].first_arc_dir) e.id = -1; |
342 | | } while (e.id > -1 && arcs[e.id].left_face != f); |
343 | | } |
344 | | |
345 | | |
346 | | static int id(Node v) { return v.id; } |
347 | | static int id(Arc e) { return e.id; } |
348 | | static int id(Face f) { return f.id; } |
349 | | |
350 | | static Node nodeFromId(int id) { return Node(id);} |
351 | | static Arc arcFromId(int id) { return Arc(id);} |
352 | | static Face faceFromId(int id) { return Face(id);} |
353 | | |
354 | | bool valid(Node n) const { |
355 | | return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && |
356 | | nodes[n.id].prev != -2; |
357 | | } |
358 | | |
359 | | bool valid(Arc a) const { |
360 | | return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && |
361 | | arcs[a.id].prev_in != -2; |
362 | | } |
363 | | |
364 | | bool valid(Face f) const { |
365 | | return f.id >= 0 && f.id < static_cast<int>(faces.size()) && |
366 | | faces[f.id].prev != -2; |
367 | | } |
368 | | |
369 | | Node addNode() { |
370 | | int n; |
371 | | |
372 | | if(first_free_node==-1) { |
373 | | n = nodes.size(); |
374 | | nodes.push_back(NodeT()); |
375 | | } else { |
376 | | n = first_free_node; |
377 | | first_free_node = nodes[n].next; |
378 | | } |
379 | | |
380 | | nodes[n].next = first_node; |
381 | | nodes[n].component = component_id++; |
382 | | if(first_node != -1) nodes[first_node].prev = n; |
383 | | first_node = n; |
384 | | nodes[n].prev = -1; |
385 | | |
386 | | nodes[n].first_in = nodes[n].first_out = -1; |
387 | | nodes[n].first_ccw = -1; |
388 | | nodes[n].last_ccw = -1; |
389 | | |
390 | | return Node(n); |
391 | | } |
392 | | |
393 | | Arc addArc(Node u, Node v, Arc p_u, Arc p_v) { |
394 | | bool ud = p_u.id > -1 && u.id == arcs[p_u.id].source; |
395 | | bool vd = p_v.id > -1 && v.id == arcs[p_v.id].source; |
396 | | |
397 | | if (p_u.id > -1 && p_v.id > -1 && arcs[p_u.id].left_face_at(ud) != arcs[p_v.id].left_face_at(vd) |
398 | | && nodes[u.id].component == nodes[v.id].component) return INVALID; |
399 | | int n = addBlankArc(); |
400 | | |
401 | | arcs[n].source = u.id; |
402 | | arcs[n].target = v.id; |
403 | | |
404 | | arcs[n].next_out = nodes[u.id].first_out; |
405 | | if(nodes[u.id].first_out != -1) { |
406 | | arcs[nodes[u.id].first_out].prev_out = n; |
407 | | } |
408 | | |
409 | | arcs[n].next_in = nodes[v.id].first_in; |
410 | | if(nodes[v.id].first_in != -1) { |
411 | | arcs[nodes[v.id].first_in].prev_in = n; |
412 | | } |
413 | | |
414 | | arcs[n].prev_in = arcs[n].prev_out = -1; |
415 | | |
416 | | nodes[u.id].first_out = nodes[v.id].first_in = n; |
417 | | |
418 | | arcs[n].prev_s = p_u.id; |
419 | | if (p_u.id == -1) { |
420 | | arcs[n].next_s = nodes[u.id].first_ccw; |
421 | | nodes[u.id].first_ccw = n; |
422 | | } else { |
423 | | arcs[n].next_s = arcs[p_u.id].next_at(ud); |
424 | | arcs[p_u.id].next_at(ud) = n; |
425 | | } |
426 | | if (arcs[n].next_s != -1) { |
427 | | bool pvd = u.id == arcs[arcs[n].next_s].source; |
428 | | arcs[n].prev_s = arcs[arcs[n].next_s].prev_at(pvd); |
429 | | arcs[arcs[n].next_s].prev_at(pvd) = n; |
430 | | } else { |
431 | | nodes[u.id].last_ccw = n; |
432 | | } |
433 | | |
434 | | arcs[n].prev_t = p_v.id; |
435 | | if (p_v.id == -1) { |
436 | | arcs[n].next_t = nodes[v.id].first_ccw; |
437 | | nodes[v.id].first_ccw = n; |
438 | | } else { |
439 | | arcs[n].next_t = arcs[p_v.id].next_at(vd); |
440 | | arcs[p_v.id].next_at(vd) = n; |
441 | | } |
442 | | if (arcs[n].next_t != -1) { |
443 | | bool nvd = v.id == arcs[arcs[n].next_t].source; |
444 | | arcs[n].prev_t = arcs[arcs[n].next_t].prev_at(nvd); |
445 | | arcs[arcs[n].next_t].prev_at(nvd) = n; |
446 | | } else { |
447 | | nodes[v.id].last_ccw = n; |
448 | | } |
449 | | |
450 | | //Add the extra face, if needed |
451 | | if (p_u.id > -1 && p_v.id > -1) { |
452 | | int oldf = arcs[p_u.id].left_face_at(ud); |
453 | | int oldfb = arcs[p_v.id].left_face_at(vd); |
454 | | arcs[n].left_face = arcs[n].right_face = oldf; |
455 | | Face f = addFace(); |
456 | | faces[f.id].first_arc = n; |
457 | | faces[f.id].first_arc_dir = true; |
458 | | faces[oldf].first_arc = n; |
459 | | faces[oldf].first_arc_dir = false; |
460 | | Arc arc(n); |
461 | | wall_paint(arc,f.id,arc); |
462 | | if (nodes[v.id].component != nodes[u.id].component) { |
463 | | erase(Face(oldf)); |
464 | | erase(Face(oldfb)); |
465 | | int ca = nodes[u.id].component; |
466 | | int cb = nodes[v.id].component; |
467 | | int k = first_node; |
468 | | while (k != -1) { |
469 | | if (nodes[k].component == cb) |
470 | | nodes[k].component = ca; |
471 | | k = nodes[k].next; |
472 | | } |
473 | | } |
474 | | } else if (p_u.id > -1) { |
475 | | arcs[n].left_face = arcs[n].right_face = arcs[p_u.id].left_face_at(ud); |
476 | | faces[arcs[n].left_face].first_arc = n; |
477 | | faces[arcs[n].left_face].first_arc_dir = true; |
478 | | nodes[v.id].component = nodes[u.id].component; |
479 | | } else if (p_v.id > -1) { |
480 | | arcs[n].left_face = arcs[n].right_face = arcs[p_v.id].left_face_at(vd); |
481 | | faces[arcs[n].left_face].first_arc = n; |
482 | | faces[arcs[n].left_face].first_arc_dir = true; |
483 | | nodes[u.id].component = nodes[v.id].component; |
484 | | } else { //both prevs are INVALID |
485 | | Face f = addFace(); |
486 | | arcs[n].left_face = arcs[n].right_face = f.id; |
487 | | faces[f.id].first_arc = n; |
488 | | faces[f.id].first_arc_dir = true; |
489 | | nodes[v.id].component = nodes[u.id].component; |
490 | | } |
491 | | |
492 | | return Arc(n); |
493 | | } |
494 | | |
495 | | public: |
496 | | |
497 | | void erase(const Node& node) { //breaks graph unless node is isolated |
498 | | int n = node.id; |
499 | | |
500 | | if(nodes[n].next != -1) { |
501 | | nodes[nodes[n].next].prev = nodes[n].prev; |
502 | | } |
503 | | |
504 | | if(nodes[n].prev != -1) { |
505 | | nodes[nodes[n].prev].next = nodes[n].next; |
506 | | } else { |
507 | | first_node = nodes[n].next; |
508 | | } |
509 | | |
510 | | nodes[n].next = first_free_node; |
511 | | first_free_node = n; |
512 | | nodes[n].prev = -2; |
513 | | |
514 | | } |
515 | | |
516 | | void erase(const Arc& arc) { |
517 | | int n = arc.id; |
518 | | |
519 | | //"retreat" the incident faces' first arcs |
520 | | int fl = arcs[n].left_face; |
521 | | if (faces[fl].first_arc == n) { |
522 | | Arc e(faces[fl].first_arc); |
523 | | e.dir = faces[fl].first_arc; |
524 | | turnLeftF(e); |
525 | | if (e.id == n) turnLeftF(e); |
526 | | faces[fl].first_arc = e.id; |
527 | | faces[fl].first_arc_dir = e.dir; |
528 | | } |
529 | | |
530 | | int fr = arcs[n].right_face; |
531 | | |
532 | | bool comp_split = false; |
533 | | if (fr != fl) { |
534 | | Arc arc(faces[fr].first_arc); |
535 | | arc.dir = faces[fr].first_arc_dir; |
536 | | wall_paint(arc,fl,arc); |
537 | | erase(Face(fr)); |
538 | | } else if ((arcs[n].next_s > -1 || arcs[n].prev_s > -1) && (arcs[n].next_t > -1 || arcs[n].prev_t > -1)) { |
539 | | comp_split = true; |
540 | | Arc arc(n); |
541 | | Arc ed = arc; |
542 | | ed.dir = false; |
543 | | turnRightF(arc); |
544 | | Face f = addFace(); |
545 | | wall_paint(arc,f.id,ed); |
546 | | faces[f.id].first_arc = arc.id; |
547 | | faces[f.id].first_arc_dir = arc.dir; |
548 | | } |
549 | | |
550 | | unlink_arc_inout(n); |
551 | | |
552 | | if (arcs[n].next_s != -1) { |
553 | | arcs[arcs[n].next_s].prev_at(arcs[n].source == arcs[arcs[n].next_s].source) = arcs[n].prev_s; |
554 | | } else { |
555 | | nodes[arcs[n].source].last_ccw = arcs[n].prev_s; |
556 | | } |
557 | | if (arcs[n].prev_s != -1) { |
558 | | arcs[arcs[n].prev_s].next_at(arcs[n].source == arcs[arcs[n].prev_s].source) = arcs[n].next_s; |
559 | | } else { |
560 | | nodes[arcs[n].source].first_ccw = arcs[n].next_s; |
561 | | } |
562 | | |
563 | | if (arcs[n].next_t != -1) { |
564 | | arcs[arcs[n].next_t].prev_at(arcs[n].target == arcs[arcs[n].next_t].source) = arcs[n].prev_t; |
565 | | } else { |
566 | | nodes[arcs[n].target].last_ccw = arcs[n].prev_t; |
567 | | } |
568 | | if (arcs[n].prev_t != -1) { |
569 | | arcs[arcs[n].prev_t].next_at(arcs[n].target == arcs[arcs[n].prev_t].source) = arcs[n].next_t; |
570 | | } else { |
571 | | nodes[arcs[n].target].first_ccw = arcs[n].next_t; |
572 | | } |
573 | | |
574 | | unlink_arc_id(n); |
575 | | |
576 | | if (comp_split) component_relabel(Node(arcs[n].target), component_id++); |
577 | | } |
578 | | |
579 | | |
580 | | void clear() { |
581 | | arcs.clear(); |
582 | | nodes.clear(); |
583 | | first_node = first_free_node = first_free_arc = first_face = first_free_face = -1; |
584 | | faces.clear(); |
585 | | } |
586 | | |
587 | | void reverseArc(Arc a) { |
588 | | int n = a.id; |
589 | | int tmp; |
590 | | if (faces[arcs[n].left_face].first_arc == n) |
591 | | faces[arcs[n].left_face].first_arc_dir = !faces[arcs[n].left_face].first_arc_dir; |
592 | | if (faces[arcs[n].right_face].first_arc == n) |
593 | | faces[arcs[n].right_face].first_arc_dir = !faces[arcs[n].right_face].first_arc_dir; |
594 | | |
595 | | if (arcs[n].prev_out > -1) |
596 | | arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
597 | | else |
598 | | nodes[arcs[n].source].first_out = arcs[n].next_out; |
599 | | if (arcs[n].next_out > -1) |
600 | | arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
601 | | |
602 | | if (arcs[n].prev_in > -1) |
603 | | arcs[arcs[n].prev_in].next_in = arcs[n].next_in; |
604 | | else |
605 | | nodes[arcs[n].source].first_in = arcs[n].next_in; |
606 | | if (arcs[n].next_in > -1) |
607 | | arcs[arcs[n].next_in].prev_in = arcs[n].prev_in; |
608 | | |
609 | | tmp = arcs[n].left_face; arcs[n].left_face = arcs[n].right_face; arcs[n].right_face = tmp; |
610 | | tmp = arcs[n].prev_s; arcs[n].prev_s = arcs[n].prev_t; arcs[n].prev_t = tmp; |
611 | | tmp = arcs[n].next_s; arcs[n].next_s = arcs[n].next_t; arcs[n].next_t = tmp; |
612 | | tmp = arcs[n].source; arcs[n].source = arcs[n].target; arcs[n].target = tmp; |
613 | | |
614 | | arcs[n].prev_out = -1; |
615 | | arcs[n].next_out = nodes[arcs[n].source].first_out; |
616 | | nodes[arcs[n].source].first_out = n; |
617 | | |
618 | | arcs[n].prev_in = -1; |
619 | | arcs[n].next_in = nodes[arcs[n].target].first_in; |
620 | | nodes[arcs[n].target].first_in = n; |
621 | | } |
622 | | |
623 | | Node split(Arc a) { |
624 | | Node v = addNode(); |
625 | | nodes[v.id].component = nodes[arcs[a.id].target].component; |
626 | | int b = addBlankArc(); |
627 | | arcs[b] = arcs[a.id]; |
628 | | arcs[b].source = v.id; |
629 | | arcs[b].next_out = -1; |
630 | | arcs[b].prev_out = -1; |
631 | | arcs[b].next_s = -1; |
632 | | arcs[b].prev_s = a.id; |
633 | | |
634 | | if (arcs[b].next_in != -1) { |
635 | | arcs[arcs[b].next_in].prev_in = b; |
636 | | } |
637 | | if (arcs[b].prev_in != -1) { |
638 | | arcs[arcs[b].prev_in].next_in = b; |
639 | | } else { |
640 | | nodes[arcs[b].target].first_in = b; |
641 | | } |
642 | | |
643 | | if (arcs[b].next_t != -1) { |
644 | | arcs[arcs[b].next_t].prev_at(arcs[b].target) = b; |
645 | | } else { |
646 | | nodes[arcs[b].target].last_ccw = b; |
647 | | } |
648 | | if (arcs[b].prev_t != -1) { |
649 | | arcs[arcs[b].prev_t].next_at(arcs[b].target) = b; |
650 | | } else { |
651 | | nodes[arcs[b].target].first_ccw = b; |
652 | | } |
653 | | |
654 | | arcs[a.id].target = v.id; |
655 | | arcs[a.id].next_in = -1; |
656 | | arcs[a.id].prev_in = -1; |
657 | | arcs[a.id].next_t = b; |
658 | | arcs[a.id].prev_t = -1; |
659 | | |
660 | | nodes[v.id].first_in = a.id; |
661 | | nodes[v.id].first_out = b; |
662 | | nodes[v.id].first_ccw = a.id; |
663 | | nodes[v.id].last_ccw = b; |
664 | | |
665 | | return v; |
666 | | } |
667 | | |
668 | | bool contract(Node n1, Node n2) { |
669 | | Arc fs; |
670 | | firstCcw(fs,n1); |
671 | | while (fs != INVALID && arcs[fs.id].target_at(fs.dir) != n2.id) |
672 | | nextCcw(fs); |
673 | | if (fs == INVALID) return false; |
674 | | Arc bs = fs; |
675 | | turnRight(bs); |
676 | | while (bs != fs && arcs[bs.id].target_at(bs.dir) == n2.id) |
677 | | turnRight(bs); |
678 | | if (bs == fs) { |
679 | | while (nodes[n1.id].first_ccw != -1) |
680 | | erase(Arc(nodes[n1.id].first_ccw)); |
681 | | erase(n1); |
682 | | return true; |
683 | | } |
684 | | turnLeft(bs); |
685 | | while (bs != fs) { |
686 | | Arc b2s = bs; |
687 | | turnLeft(b2s); |
688 | | erase(bs); |
689 | | bs = b2s; |
690 | | } |
691 | | |
692 | | int fl = arcs[fs.id].left_face; |
693 | | if (faces[fl].first_arc == fs.id) { |
694 | | Arc e(faces[fl].first_arc); |
695 | | e.dir = faces[fl].first_arc; |
696 | | turnLeftF(e); |
697 | | if (e.id == fs.id) turnLeftF(e); |
698 | | faces[fl].first_arc = e.id; |
699 | | faces[fl].first_arc_dir = e.dir; |
700 | | } |
701 | | int fr = arcs[fs.id].right_face; |
702 | | if (faces[fr].first_arc == fs.id) { |
703 | | Arc e(faces[fr].first_arc); |
704 | | e.dir = faces[fr].first_arc; |
705 | | turnLeftF(e); |
706 | | if (e.id == fs.id) turnLeftF(e); |
707 | | faces[fr].first_arc = e.id; |
708 | | faces[fr].first_arc_dir = e.dir; |
709 | | } |
710 | | |
711 | | Arc a; |
712 | | firstIn(a,n2); |
713 | | while (arcs[a.id].next_in != -1) { |
714 | | if (a.id != fs.id) arcs[a.id].target = n1.id; |
715 | | nextIn(a); |
716 | | } |
717 | | if (a.id != fs.id) arcs[a.id].target = n1.id; |
718 | | arcs[a.id].next_in = nodes[n1.id].first_in; |
719 | | nodes[n1.id].first_in = nodes[n2.id].first_in; |
720 | | |
721 | | firstOut(a,n2); |
722 | | while (arcs[a.id].next_out != -1) { |
723 | | if (a.id != fs.id) arcs[a.id].source = n1.id; |
724 | | nextOut(a); |
725 | | } |
726 | | if (a.id != fs.id) arcs[a.id].source = n1.id; |
727 | | arcs[a.id].next_out = nodes[n1.id].first_out; |
728 | | nodes[n1.id].first_out = nodes[n2.id].first_out; |
729 | | unlink_arc_inout(fs.id); |
730 | | |
731 | | int la = nodes[n2.id].last_ccw; |
732 | | arcs[la].next_at(arcs[la].source == n2.id) = nodes[n2.id].first_ccw; |
733 | | la = nodes[n2.id].first_ccw; |
734 | | arcs[la].prev_at(arcs[la].source == n2.id) = nodes[n2.id].last_ccw; |
735 | | nodes[n2.id].first_ccw = -1; |
736 | | nodes[n2.id].last_ccw = -1; |
737 | | |
738 | | Arc ta = fs; |
739 | | turnRight(ta); |
740 | | if (nodes[n1.id].last_ccw == fs.id) nodes[n1.id].last_ccw = ta.id; |
741 | | arcs[ta.id].next_at(ta.dir) = arcs[fs.id].next_at(!fs.dir); |
742 | | ta = fs; |
743 | | turnLeft(ta); |
744 | | if (nodes[n1.id].first_ccw == fs.id) nodes[n1.id].first_ccw = ta.id; |
745 | | arcs[ta.id].prev_at(ta.dir) = arcs[fs.id].prev_at(!fs.dir); |
746 | | ta = fs; |
747 | | ta.dir = !ta.dir; |
748 | | turnLeft(ta); |
749 | | arcs[ta.id].prev_at(ta.dir) = arcs[fs.id].next_at(fs.dir); |
750 | | ta = fs; |
751 | | ta.dir = !ta.dir; |
752 | | turnRight(ta); |
753 | | arcs[ta.id].next_at(ta.dir) = arcs[fs.id].prev_at(fs.dir); |
754 | | |
755 | | unlink_arc_id(fs.id); |
756 | | erase(n2); |
757 | | return true; |
758 | | } |
759 | | |
760 | | |
761 | | protected: |
762 | | |
763 | | //traverses a face clockwise, relabelling the arcs with the face id |
764 | | void wall_paint(Arc arc, int f_id, Arc ed) { |
765 | | do { |
766 | | arcs[arc.id].left_face_at(arc.dir) = f_id; |
767 | | turnRightF(arc); |
768 | | } while (arc.id != ed.id || arc.dir != ed.dir); |
769 | | } |
770 | | |
771 | | void component_relabel(Node node, int comp_id) { |
772 | | std::vector<int> ns(nodes.size()); |
773 | | std::list<int> q; |
774 | | q.push_back(node.id); |
775 | | ns[node.id] = 1; |
776 | | while (!q.empty()) { |
777 | | int n = q.front(); |
778 | | ns[n] = 2; |
779 | | nodes[n].component = comp_id; |
780 | | q.pop_front(); |
781 | | Arc arc; |
782 | | firstCcw(arc,Node(n)); |
783 | | while (arc.id > -1) { |
784 | | int m = arcs[arc.id].target_at(arcs[arc.id].source == n); |
785 | | if (ns[m] == 0) { |
786 | | ns[m] = 1; |
787 | | q.push_back(m); |
788 | | } |
789 | | nextCcw(arc); |
790 | | } |
791 | | } |
792 | | } |
793 | | |
794 | | void unlink_arc_inout(int n) { |
795 | | if(arcs[n].next_in!=-1) { |
796 | | arcs[arcs[n].next_in].prev_in = arcs[n].prev_in; |
797 | | } |
798 | | |
799 | | if(arcs[n].prev_in!=-1) { |
800 | | arcs[arcs[n].prev_in].next_in = arcs[n].next_in; |
801 | | } else { |
802 | | nodes[arcs[n].target].first_in = arcs[n].next_in; |
803 | | } |
804 | | |
805 | | |
806 | | if(arcs[n].next_out!=-1) { |
807 | | arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
808 | | } |
809 | | |
810 | | if(arcs[n].prev_out!=-1) { |
811 | | arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
812 | | } else { |
813 | | nodes[arcs[n].source].first_out = arcs[n].next_out; |
814 | | } |
815 | | |
816 | | } |
817 | | |
818 | | void unlink_arc_id(int n) { |
819 | | arcs[n].next_in = first_free_arc; |
820 | | first_free_arc = n; |
821 | | arcs[n].prev_in = -2; |
822 | | } |
823 | | |
824 | | int addBlankArc() { |
825 | | int n; |
826 | | if (first_free_arc == -1) { |
827 | | n = arcs.size(); |
828 | | arcs.push_back(ArcT()); |
829 | | } else { |
830 | | n = first_free_arc; |
831 | | first_free_arc = arcs[n].next_in; |
832 | | } |
833 | | return n; |
834 | | |
835 | | } |
836 | | |
837 | | void erase(const Face& face) { |
838 | | int n = face.id; |
839 | | |
840 | | if(faces[n].next != -1) { |
841 | | faces[faces[n].next].prev = faces[n].prev; |
842 | | } |
843 | | |
844 | | if(faces[n].prev != -1) { |
845 | | faces[faces[n].prev].next = faces[n].next; |
846 | | } else { |
847 | | first_face = faces[n].next; |
848 | | } |
849 | | |
850 | | faces[n].next = first_free_face; |
851 | | first_free_face = n; |
852 | | faces[n].prev = -2; |
853 | | |
854 | | } |
855 | | |
856 | | |
857 | | Face addFace() { |
858 | | int n; |
859 | | |
860 | | if(first_free_face==-1) { |
861 | | n = faces.size(); |
862 | | faces.push_back(FaceT()); |
863 | | } else { |
864 | | n = first_free_face; |
865 | | first_free_face = faces[n].next; |
866 | | } |
867 | | |
868 | | faces[n].next = first_face; |
869 | | if(first_face != -1) faces[first_face].prev = n; |
870 | | first_face = n; |
871 | | faces[n].prev = -1; |
872 | | |
873 | | return Face(n); |
874 | | } |
875 | | |
876 | | #ifdef REMOVE_BEFORE_RELEASE |
877 | | public: |
878 | | void print() { |
879 | | std::cout << "Nodes: " << std::endl; |
880 | | for (int i=0; i<nodes.size(); ++i) |
881 | | std::cout << i << ": fi=" << nodes[i].first_in |
882 | | << " fo=" << nodes[i].first_out |
883 | | << " fc=" << nodes[i].first_ccw |
884 | | << " lc=" << nodes[i].last_ccw |
885 | | << " pr=" << nodes[i].prev |
886 | | << " nx=" << nodes[i].next |
887 | | << " co=" << nodes[i].component |
888 | | <<std::endl; |
889 | | std::cout << "Arcs: " << std::endl; |
890 | | for (int i=0; i<arcs.size(); ++i) { |
891 | | if (arcs[i].prev_in > -2) { |
892 | | std::cout << i << ": sc=" << arcs[i].source |
893 | | << " tg=" << arcs[i].target |
894 | | << " pi=" << arcs[i].prev_in |
895 | | << " ni=" << arcs[i].next_in |
896 | | << " po=" << arcs[i].prev_out |
897 | | << " no=" << arcs[i].next_out |
898 | | << " ps=" << arcs[i].prev_s |
899 | | << " ns=" << arcs[i].next_s |
900 | | << " pt=" << arcs[i].prev_t |
901 | | << " nt=" << arcs[i].next_t |
902 | | << " lf=" << arcs[i].left_face |
903 | | << " rf=" << arcs[i].right_face |
904 | | <<std::endl; |
905 | | } else std::cout << i << ": (deleted)" << std::endl; |
906 | | } |
907 | | std::cout << "Faces: " << std::endl; |
908 | | for (int i=0; i<faces.size(); ++i) |
909 | | std::cout << i |
910 | | << " pr=" << faces[i].prev |
911 | | << " nx=" << faces[i].next |
912 | | << " fa=" << faces[i].first_arc |
913 | | << " fd=" << faces[i].first_arc_dir |
914 | | << (faces[i].prev > -2? "" : " (deleted)") |
915 | | <<std::endl; |
916 | | } |
917 | | #endif |
918 | | |
919 | | }; |
920 | | |
921 | | template<typename Base> |
922 | | class PlanarDigraphExtender : public Base{ |
923 | | |
924 | | typedef Base Parent; |
925 | | |
926 | | public: |
927 | | typedef PlanarDigraphExtender Digraph; |
928 | | |
929 | | PlanarDigraphExtender() {} |
930 | | |
931 | | typedef typename Parent::Node Node; |
932 | | typedef typename Parent::Arc Arc; |
933 | | typedef typename Parent::Face Face; |
934 | | |
935 | | class FaceIt : public Face { |
936 | | const Digraph* _digraph; |
937 | | public: |
938 | | |
939 | | FaceIt() {} |
940 | | |
941 | | FaceIt(Invalid i) : Face(i) { } |
942 | | |
943 | | explicit FaceIt(const Digraph& digraph) : _digraph(&digraph) { |
944 | | _digraph->first(static_cast<Face&>(*this)); |
945 | | } |
946 | | |
947 | | FaceIt(const Digraph& digraph, const Face& face) |
948 | | : Face(face), _digraph(&digraph) {} |
949 | | |
950 | | FaceIt& operator++() { |
951 | | _digraph->next(*this); |
952 | | return *this; |
953 | | } |
954 | | |
955 | | }; |
956 | | |
957 | | |
958 | | class CwPerimeterArcIt : public Arc { |
959 | | const Digraph* _digraph; |
960 | | Face _face; |
961 | | public: |
962 | | |
963 | | CwPerimeterArcIt() { } |
964 | | |
965 | | CwPerimeterArcIt(Invalid i) : Arc(i) { } |
966 | | |
967 | | CwPerimeterArcIt(const Digraph& digraph, const Face& face) |
968 | | : _digraph(&digraph), _face(face) { |
969 | | _digraph->firstCwF(*this, _face); |
970 | | } |
971 | | |
972 | | CwPerimeterArcIt(const Digraph& digraph, const Arc& arc) |
973 | | : Arc(arc), _digraph(&digraph) {} |
974 | | |
975 | | CwPerimeterArcIt& operator++() { |
976 | | _digraph->nextCwF(*this); |
977 | | return *this; |
978 | | } |
979 | | |
980 | | }; |
981 | | |
982 | | class CcwArcIt : public Arc { |
983 | | const Digraph* _digraph; |
984 | | const Node _node; |
985 | | public: |
986 | | |
987 | | CcwArcIt() { } |
988 | | |
989 | | CcwArcIt(Invalid i) : Arc(i) { } |
990 | | |
991 | | CcwArcIt(const Digraph& digraph, const Node& node) |
992 | | : _digraph(&digraph), _node(node) { |
993 | | _digraph->firstCcw(*this, node); |
994 | | } |
995 | | |
996 | | CcwArcIt(const Digraph& digraph, const Arc& arc) |
997 | | : Arc(arc), _digraph(&digraph) {} |
998 | | |
999 | | CcwArcIt& operator++() { |
1000 | | _digraph->nextCcw(*this); |
1001 | | return *this; |
1002 | | } |
1003 | | |
1004 | | }; |
1005 | | |
1006 | | }; |
1007 | | |
1008 | | typedef PlanarDigraphExtender<DigraphExtender<PlanarDigraphBase> > ExtendedPlanarDigraphBase; |
1009 | | |
1010 | | /// \addtogroup graphs |
1011 | | /// @{ |
1012 | | |
1013 | | ///A general directed graph structure. |
1014 | | |
1015 | | ///\ref ListDigraph is a versatile and fast directed graph |
1016 | | ///implementation based on linked lists that are stored in |
1017 | | ///\c std::vector structures. |
1018 | | /// |
1019 | | ///This type fully conforms to the \ref concepts::Digraph "Digraph concept" |
1020 | | ///and it also provides several useful additional functionalities. |
1021 | | ///Most of its member functions and nested classes are documented |
1022 | | ///only in the concept class. |
1023 | | /// |
1024 | | ///This class provides only linear time counting for nodes and arcs. |
1025 | | /// |
1026 | | ///\sa concepts::Digraph |
1027 | | ///\sa ListGraph |
1028 | | class PlanarDigraph : public ExtendedPlanarDigraphBase { |
1029 | | typedef ExtendedPlanarDigraphBase Parent; |
1030 | | |
1031 | | private: |
1032 | | /// Digraphs are \e not copy constructible. Use DigraphCopy instead. |
1033 | | PlanarDigraph(const PlanarDigraph &) :ExtendedPlanarDigraphBase() {}; |
1034 | | /// \brief Assignment of a digraph to another one is \e not allowed. |
1035 | | /// Use DigraphCopy instead. |
1036 | | void operator=(const PlanarDigraph &) {} |
1037 | | public: |
1038 | | |
1039 | | /// Constructor |
1040 | | |
1041 | | /// Constructor. |
1042 | | /// |
1043 | | PlanarDigraph() {} |
1044 | | |
1045 | | ///Add a new node to the digraph. |
1046 | | |
1047 | | ///This function adds a new node to the digraph. |
1048 | | ///\return The new node. |
1049 | | Node addNode() { return Parent::addNode(); } |
1050 | | |
1051 | | ///Add a new arc to the digraph. |
1052 | | |
1053 | | ///This function adds a new arc to the digraph with source node \c s |
1054 | | ///and target node \c t. |
1055 | | ///\return The new arc. |
1056 | | Arc addArc(Node s, Node t, Arc p_u, Arc p_v) { |
1057 | | Arc arc = PlanarDigraphBase::addArc(s, t, p_u, p_v); |
1058 | | if (arc != INVALID) |
1059 | | notifier(Arc()).add(arc); |
1060 | | return arc; |
1061 | | } |
1062 | | |
1063 | | ///\brief Erase a node from the digraph. |
1064 | | /// |
1065 | | ///This function erases the given node along with its outgoing and |
1066 | | ///incoming arcs from the digraph. |
1067 | | /// |
1068 | | ///\note All iterators referencing the removed node or the connected |
1069 | | ///arcs are invalidated, of course. |
1070 | | void erase(Node n) { Parent::erase(n); } |
1071 | | |
1072 | | ///\brief Erase an arc from the digraph. |
1073 | | /// |
1074 | | ///This function erases the given arc from the digraph. |
1075 | | /// |
1076 | | ///\note All iterators referencing the removed arc are invalidated, |
1077 | | ///of course. |
1078 | | void erase(Arc a) { Parent::erase(a); } |
1079 | | |
1080 | | /// Node validity check |
1081 | | |
1082 | | /// This function gives back \c true if the given node is valid, |
1083 | | /// i.e. it is a real node of the digraph. |
1084 | | /// |
1085 | | /// \warning A removed node could become valid again if new nodes are |
1086 | | /// added to the digraph. |
1087 | | bool valid(Node n) const { return Parent::valid(n); } |
1088 | | |
1089 | | /// Arc validity check |
1090 | | |
1091 | | /// This function gives back \c true if the given arc is valid, |
1092 | | /// i.e. it is a real arc of the digraph. |
1093 | | /// |
1094 | | /// \warning A removed arc could become valid again if new arcs are |
1095 | | /// added to the digraph. |
1096 | | bool valid(Arc a) const { return Parent::valid(a); } |
1097 | | |
1098 | | /// Change the target node of an arc |
1099 | | |
1100 | | /// Planar graphs don't support changing endpoints of arcs. |
1101 | | void changeTarget(Arc a, Node n) = delete; |
1102 | | /// Change the source node of an arc |
1103 | | |
1104 | | ///Planar graphs don't support changing endpoints of arcs. |
1105 | | void changeSource(Arc a, Node n) = delete; |
1106 | | |
1107 | | /// Reverse the direction of an arc. |
1108 | | |
1109 | | /// This function reverses the direction of the given arc. |
1110 | | ///\note \c ArcIt, \c OutArcIt and \c InArcIt iterators referencing |
1111 | | ///the changed arc are invalidated. |
1112 | | /// |
1113 | | ///\warning This functionality cannot be used together with the Snapshot |
1114 | | ///feature. |
1115 | | void reverseArc(Arc a) { |
1116 | | Parent::reverseArc(a); |
1117 | | } |
1118 | | |
1119 | | ///Contract two nodes. |
1120 | | |
1121 | | ///This function contracts the given two nodes. |
1122 | | ///Node \c v is removed, but instead of deleting its |
1123 | | ///incident arcs, they are joined to node \c u. |
1124 | | ///If the last parameter \c r is \c true (this is the default value), |
1125 | | ///then the newly created loops are removed. |
1126 | | /// |
1127 | | ///\note The moved arcs are joined to node \c u using changeSource() |
1128 | | ///or changeTarget(), thus \c ArcIt and \c OutArcIt iterators are |
1129 | | ///invalidated for the outgoing arcs of node \c v and \c InArcIt |
1130 | | ///iterators are invalidated for the incomming arcs of \c v. |
1131 | | ///Moreover all iterators referencing node \c v or the removed |
1132 | | ///loops are also invalidated. Other iterators remain valid. |
1133 | | /// |
1134 | | ///\warning This functionality cannot be used together with the Snapshot |
1135 | | ///feature. |
1136 | | bool contract(Node u, Node v) |
1137 | | { |
1138 | | return Parent::contract(u,v); |
1139 | | } |
1140 | | |
1141 | | ///Split a node. |
1142 | | |
1143 | | ///Planar digraphs don't support splitting of nodes. |
1144 | | Node split(Node n, bool connect = true) = delete; |
1145 | | /* Node split(Node n, bool connect = true) { |
1146 | | Node b = addNode(); |
1147 | | nodes[b.id].first_out=nodes[n.id].first_out; |
1148 | | nodes[n.id].first_out=-1; |
1149 | | for(int i=nodes[b.id].first_out; i!=-1; i=arcs[i].next_out) { |
1150 | | arcs[i].source=b.id; |
1151 | | } |
1152 | | if (connect) addArc(n,b); |
1153 | | return b; |
1154 | | }*/ |
1155 | | |
1156 | | ///Split an arc. |
1157 | | |
1158 | | ///This function splits the given arc. First, a new node \c v is |
1159 | | ///added to the digraph, then the target node of the original arc |
1160 | | ///is set to \c v. Finally, an arc from \c v to the original target |
1161 | | ///is added. |
1162 | | ///\return The newly created node. |
1163 | | /// |
1164 | | ///\note \c InArcIt iterators referencing the original arc are |
1165 | | ///invalidated. Other iterators remain valid. |
1166 | | /// |
1167 | | ///\warning This functionality cannot be used together with the |
1168 | | ///Snapshot feature. |
1169 | | Node split(Arc a) { |
1170 | | return Parent::split(a); |
1171 | | } |
1172 | | |
1173 | | ///Clear the digraph. |
1174 | | |
1175 | | ///This function erases all nodes and arcs from the digraph. |
1176 | | /// |
1177 | | ///\note All iterators of the digraph are invalidated, of course. |
1178 | | void clear() { |
1179 | | Parent::clear(); |
1180 | | } |
1181 | | |
1182 | | /// Reserve memory for nodes. |
1183 | | |
1184 | | /// Using this function, it is possible to avoid superfluous memory |
1185 | | /// allocation: if you know that the digraph you want to build will |
1186 | | /// be large (e.g. it will contain millions of nodes and/or arcs), |
1187 | | /// then it is worth reserving space for this amount before starting |
1188 | | /// to build the digraph. |
1189 | | /// \sa reserveArc() |
1190 | | void reserveNode(int n) { nodes.reserve(n); }; |
1191 | | |
1192 | | /// Reserve memory for arcs. |
1193 | | |
1194 | | /// Using this function, it is possible to avoid superfluous memory |
1195 | | /// allocation: if you know that the digraph you want to build will |
1196 | | /// be large (e.g. it will contain millions of nodes and/or arcs), |
1197 | | /// then it is worth reserving space for this amount before starting |
1198 | | /// to build the digraph. |
1199 | | /// \sa reserveNode() |
1200 | | void reserveArc(int m) { arcs.reserve(m); }; |
1201 | | |
1202 | | class DualBase { |
1203 | | const Digraph *_digraph; |
1204 | | protected: |
1205 | | void initialize(const Digraph *digraph) { _digraph = digraph; } |
1206 | | public: |
1207 | | |
1208 | | typedef PlanarDigraph::Face Node; |
1209 | | typedef PlanarDigraph::Arc Arc; |
1210 | | typedef PlanarDigraph::Node Face; |
1211 | | |
1212 | | int maxNodeId() const { return _digraph->maxFaceId(); } |
1213 | | int maxArcId() const { return _digraph->maxArcId(); } |
1214 | | int maxFaceId() const { return _digraph->maxNodeId(); } |
1215 | | |
1216 | | Node source(Arc e) const { return _digraph->leftFace(e); } |
1217 | | Node target(Arc e) const { return _digraph->rightFace(e); } |
1218 | | Face leftFace(Arc e) const { return _digraph->target(e); } |
1219 | | Face rightFace(Arc e) const { return _digraph->source(e); } |
1220 | | |
1221 | | void first(Node &i) const { _digraph->first(i); } |
1222 | | void next(Node &i) const { _digraph->next(i); } |
1223 | | void first(Arc &i) const { _digraph->first(i); } |
1224 | | void next(Arc &i) const { _digraph->next(i); } |
1225 | | void firstIn(Arc& i, const Node& n) const { _digraph->firstInF(i, n); } |
1226 | | void nextIn(Arc& i) const { _digraph->nextInF(i); } |
1227 | | void firstOut(Arc& i, const Node& n ) const { _digraph->firstOutF(i, n); } |
1228 | | void nextOut(Arc& i) const { _digraph->nextOutF(i); } |
1229 | | void firstCcw(Arc &e, const Node &v) const { _digraph->firstCcwF(e, v); } |
1230 | | void nextCcw(Arc &e) const { _digraph->nextCcwF(e); } |
1231 | | void turnLeft(Arc &e, const Node &v) const { _digraph->turnLeftF(e); } |
1232 | | void turnRight(Arc &e, const Node &v) const { _digraph->turnRightF(e); } |
1233 | | void first(Face &i) const { _digraph->first(i); } |
1234 | | void next(Face &i) const { _digraph->next(i); } |
1235 | | void firstCwF(Arc &arc, const Face& face) const { _digraph->firstCw(arc, face); } |
1236 | | void nextCwF(Arc &arc) const { _digraph->nextCw(arc); } |
1237 | | |
1238 | | static int id(Node v) { return v.id; } |
1239 | | static int id(Arc e) { return e.id; } |
1240 | | static int id(Face f) { return f.id; } |
1241 | | static Node nodeFromId(int id) { return Node(id);} |
1242 | | static Arc arcFromId(int id) { return Arc(id);} |
1243 | | static Face faceFromId(int id) { return Face(id);} |
1244 | | |
1245 | | bool valid(Node n) const { return _digraph->valid(n); } |
1246 | | bool valid(Arc n) const { return _digraph->valid(n); } |
1247 | | bool valid(Face n) const { return _digraph->valid(n); } |
1248 | | |
1249 | | }; |
1250 | | |
1251 | | typedef PlanarDigraphExtender<DigraphExtender<DualBase> > ExtendedDualBase; |
1252 | | /// \brief Adaptor class for the dual of a planar graph. |
1253 | | /// |
1254 | | /// Adaptor class for the dual of a planar graph. |
1255 | | class Dual : public ExtendedDualBase { |
1256 | | public: |
1257 | | Dual(const PlanarDigraph &digraph) { initialize(&digraph); } |
1258 | | |
1259 | | }; |
1260 | | |
1261 | | /// \brief Class to make a snapshot of the digraph and restore |
1262 | | /// it later. |
1263 | | /// |
1264 | | /// Class to make a snapshot of the digraph and restore it later. |
1265 | | /// |
1266 | | /// The newly added nodes and arcs can be removed using the |
1267 | | /// restore() function. |
1268 | | /// |
1269 | | /// \note After a state is restored, you cannot restore a later state, |
1270 | | /// i.e. you cannot add the removed nodes and arcs again using |
1271 | | /// another Snapshot instance. |
1272 | | /// |
1273 | | /// \warning Node and arc deletions and other modifications (e.g. |
1274 | | /// reversing, contracting, splitting arcs or nodes) cannot be |
1275 | | /// restored. These events invalidate the snapshot. |
1276 | | /// However, the arcs and nodes that were added to the digraph after |
1277 | | /// making the current snapshot can be removed without invalidating it. |
1278 | | class Snapshot { |
1279 | | protected: |
1280 | | |
1281 | | typedef Parent::NodeNotifier NodeNotifier; |
1282 | | |
1283 | | class NodeObserverProxy : public NodeNotifier::ObserverBase { |
1284 | | public: |
1285 | | |
1286 | | NodeObserverProxy(Snapshot& _snapshot) |
1287 | | : snapshot(_snapshot) {} |
1288 | | |
1289 | | using NodeNotifier::ObserverBase::attach; |
1290 | | using NodeNotifier::ObserverBase::detach; |
1291 | | using NodeNotifier::ObserverBase::attached; |
1292 | | |
1293 | | protected: |
1294 | | |
1295 | | virtual void add(const Node& node) { |
1296 | | snapshot.addNode(node); |
1297 | | } |
1298 | | virtual void add(const std::vector<Node>& nodes) { |
1299 | | for (int i = nodes.size() - 1; i >= 0; ++i) { |
1300 | | snapshot.addNode(nodes[i]); |
1301 | | } |
1302 | | } |
1303 | | virtual void erase(const Node& node) { |
1304 | | snapshot.eraseNode(node); |
1305 | | } |
1306 | | virtual void erase(const std::vector<Node>& nodes) { |
1307 | | for (int i = 0; i < int(nodes.size()); ++i) { |
1308 | | snapshot.eraseNode(nodes[i]); |
1309 | | } |
1310 | | } |
1311 | | virtual void build() { |
1312 | | Node node; |
1313 | | std::vector<Node> nodes; |
1314 | | for (notifier()->first(node); node != INVALID; |
1315 | | notifier()->next(node)) { |
1316 | | nodes.push_back(node); |
1317 | | } |
1318 | | for (int i = nodes.size() - 1; i >= 0; --i) { |
1319 | | snapshot.addNode(nodes[i]); |
1320 | | } |
1321 | | } |
1322 | | virtual void clear() { |
1323 | | Node node; |
1324 | | for (notifier()->first(node); node != INVALID; |
1325 | | notifier()->next(node)) { |
1326 | | snapshot.eraseNode(node); |
1327 | | } |
1328 | | } |
1329 | | |
1330 | | Snapshot& snapshot; |
1331 | | }; |
1332 | | |
1333 | | class ArcObserverProxy : public ArcNotifier::ObserverBase { |
1334 | | public: |
1335 | | |
1336 | | ArcObserverProxy(Snapshot& _snapshot) |
1337 | | : snapshot(_snapshot) {} |
1338 | | |
1339 | | using ArcNotifier::ObserverBase::attach; |
1340 | | using ArcNotifier::ObserverBase::detach; |
1341 | | using ArcNotifier::ObserverBase::attached; |
1342 | | |
1343 | | protected: |
1344 | | |
1345 | | virtual void add(const Arc& arc) { |
1346 | | snapshot.addArc(arc); |
1347 | | } |
1348 | | virtual void add(const std::vector<Arc>& arcs) { |
1349 | | for (int i = arcs.size() - 1; i >= 0; ++i) { |
1350 | | snapshot.addArc(arcs[i]); |
1351 | | } |
1352 | | } |
1353 | | virtual void erase(const Arc& arc) { |
1354 | | snapshot.eraseArc(arc); |
1355 | | } |
1356 | | virtual void erase(const std::vector<Arc>& arcs) { |
1357 | | for (int i = 0; i < int(arcs.size()); ++i) { |
1358 | | snapshot.eraseArc(arcs[i]); |
1359 | | } |
1360 | | } |
1361 | | virtual void build() { |
1362 | | Arc arc; |
1363 | | std::vector<Arc> arcs; |
1364 | | for (notifier()->first(arc); arc != INVALID; |
1365 | | notifier()->next(arc)) { |
1366 | | arcs.push_back(arc); |
1367 | | } |
1368 | | for (int i = arcs.size() - 1; i >= 0; --i) { |
1369 | | snapshot.addArc(arcs[i]); |
1370 | | } |
1371 | | } |
1372 | | virtual void clear() { |
1373 | | Arc arc; |
1374 | | for (notifier()->first(arc); arc != INVALID; |
1375 | | notifier()->next(arc)) { |
1376 | | snapshot.eraseArc(arc); |
1377 | | } |
1378 | | } |
1379 | | |
1380 | | Snapshot& snapshot; |
1381 | | }; |
1382 | | |
1383 | | PlanarDigraph *digraph; |
1384 | | |
1385 | | NodeObserverProxy node_observer_proxy; |
1386 | | ArcObserverProxy arc_observer_proxy; |
1387 | | |
1388 | | std::list<Node> added_nodes; |
1389 | | std::list<Arc> added_arcs; |
1390 | | |
1391 | | |
1392 | | void addNode(const Node& node) { |
1393 | | added_nodes.push_front(node); |
1394 | | } |
1395 | | void eraseNode(const Node& node) { |
1396 | | std::list<Node>::iterator it = |
1397 | | std::find(added_nodes.begin(), added_nodes.end(), node); |
1398 | | if (it == added_nodes.end()) { |
1399 | | clear(); |
1400 | | arc_observer_proxy.detach(); |
1401 | | throw NodeNotifier::ImmediateDetach(); |
1402 | | } else { |
1403 | | added_nodes.erase(it); |
1404 | | } |
1405 | | } |
1406 | | |
1407 | | void addArc(const Arc& arc) { |
1408 | | added_arcs.push_front(arc); |
1409 | | } |
1410 | | void eraseArc(const Arc& arc) { |
1411 | | std::list<Arc>::iterator it = |
1412 | | std::find(added_arcs.begin(), added_arcs.end(), arc); |
1413 | | if (it == added_arcs.end()) { |
1414 | | clear(); |
1415 | | node_observer_proxy.detach(); |
1416 | | throw ArcNotifier::ImmediateDetach(); |
1417 | | } else { |
1418 | | added_arcs.erase(it); |
1419 | | } |
1420 | | } |
1421 | | |
1422 | | void attach(PlanarDigraph &_digraph) { |
1423 | | digraph = &_digraph; |
1424 | | node_observer_proxy.attach(digraph->notifier(Node())); |
1425 | | arc_observer_proxy.attach(digraph->notifier(Arc())); |
1426 | | } |
1427 | | |
1428 | | void detach() { |
1429 | | node_observer_proxy.detach(); |
1430 | | arc_observer_proxy.detach(); |
1431 | | } |
1432 | | |
1433 | | bool attached() const { |
1434 | | return node_observer_proxy.attached(); |
1435 | | } |
1436 | | |
1437 | | void clear() { |
1438 | | added_nodes.clear(); |
1439 | | added_arcs.clear(); |
1440 | | } |
1441 | | |
1442 | | public: |
1443 | | |
1444 | | /// \brief Default constructor. |
1445 | | /// |
1446 | | /// Default constructor. |
1447 | | /// You have to call save() to actually make a snapshot. |
1448 | | Snapshot() |
1449 | | : digraph(0), node_observer_proxy(*this), |
1450 | | arc_observer_proxy(*this) {} |
1451 | | |
1452 | | /// \brief Constructor that immediately makes a snapshot. |
1453 | | /// |
1454 | | /// This constructor immediately makes a snapshot of the given digraph. |
1455 | | Snapshot(PlanarDigraph &gr) |
1456 | | : node_observer_proxy(*this), |
1457 | | arc_observer_proxy(*this) { |
1458 | | attach(gr); |
1459 | | } |
1460 | | |
1461 | | /// \brief Make a snapshot. |
1462 | | /// |
1463 | | /// This function makes a snapshot of the given digraph. |
1464 | | /// It can be called more than once. In case of a repeated |
1465 | | /// call, the previous snapshot gets lost. |
1466 | | void save(PlanarDigraph &gr) { |
1467 | | if (attached()) { |
1468 | | detach(); |
1469 | | clear(); |
1470 | | } |
1471 | | attach(gr); |
1472 | | } |
1473 | | |
1474 | | /// \brief Undo the changes until the last snapshot. |
1475 | | /// |
1476 | | /// This function undos the changes until the last snapshot |
1477 | | /// created by save() or Snapshot(ListDigraph&). |
1478 | | /// |
1479 | | /// \warning This method invalidates the snapshot, i.e. repeated |
1480 | | /// restoring is not supported unless you call save() again. |
1481 | | void restore() { |
1482 | | detach(); |
1483 | | for(std::list<Arc>::iterator it = added_arcs.begin(); |
1484 | | it != added_arcs.end(); ++it) { |
1485 | | digraph->erase(*it); |
1486 | | } |
1487 | | for(std::list<Node>::iterator it = added_nodes.begin(); |
1488 | | it != added_nodes.end(); ++it) { |
1489 | | digraph->erase(*it); |
1490 | | } |
1491 | | clear(); |
1492 | | } |
1493 | | |
1494 | | /// \brief Returns \c true if the snapshot is valid. |
1495 | | /// |
1496 | | /// This function returns \c true if the snapshot is valid. |
1497 | | bool valid() const { |
1498 | | return attached(); |
1499 | | } |
1500 | | }; |
1501 | | |
1502 | | }; |
1503 | | |
1504 | | ///@} |
1505 | | |
1506 | | class PlanarGraphBase { |
1507 | | |
1508 | | protected: |
1509 | | |
1510 | | struct NodeT { |
1511 | | int first_out, last_out; |
1512 | | int prev, next; |
1513 | | int component; |
1514 | | }; |
1515 | | |
1516 | | struct ArcT { |
1517 | | int target; |
1518 | | int left_face; |
1519 | | int prev_out, next_out; |
1520 | | }; |
1521 | | |
1522 | | struct FaceT { |
1523 | | int first_arc; |
1524 | | int prev, next; |
1525 | | }; |
1526 | | |
1527 | | std::vector<NodeT> nodes; |
1528 | | |
1529 | | int first_node; |
1530 | | |
1531 | | int first_free_node; |
1532 | | |
1533 | | std::vector<ArcT> arcs; |
1534 | | |
1535 | | int first_free_arc; |
1536 | | |
1537 | | std::vector<FaceT> faces; |
1538 | | |
1539 | | int first_face; |
1540 | | |
1541 | | int first_free_face; |
1542 | | |
1543 | | int component_id; |
1544 | | |
1545 | | public: |
1546 | | |
1547 | | typedef PlanarGraphBase Graph; |
1548 | | |
1549 | | class Node { |
1550 | | friend class PlanarGraphBase; |
1551 | | protected: |
1552 | | |
1553 | | int id; |
1554 | | explicit Node(int pid) { id = pid;} |
1555 | | |
1556 | | public: |
1557 | | Node() {} |
1558 | | Node (Invalid) { id = -1; } |
1559 | | bool operator==(const Node& node) const {return id == node.id;} |
1560 | | bool operator!=(const Node& node) const {return id != node.id;} |
1561 | | bool operator<(const Node& node) const {return id < node.id;} |
1562 | | }; |
1563 | | |
1564 | | class Edge { |
1565 | | friend class PlanarGraphBase; |
1566 | | protected: |
1567 | | |
1568 | | int id; |
1569 | | explicit Edge(int pid) { id = pid;} |
1570 | | |
1571 | | public: |
1572 | | Edge() {} |
1573 | | Edge (Invalid) { id = -1; } |
1574 | | bool operator==(const Edge& edge) const {return id == edge.id;} |
1575 | | bool operator!=(const Edge& edge) const {return id != edge.id;} |
1576 | | bool operator<(const Edge& edge) const {return id < edge.id;} |
1577 | | }; |
1578 | | |
1579 | | class Arc { |
1580 | | friend class PlanarGraphBase; |
1581 | | protected: |
1582 | | |
1583 | | int id; |
1584 | | explicit Arc(int pid) { id = pid;} |
1585 | | |
1586 | | public: |
1587 | | operator Edge() const { |
1588 | | return id != -1 ? edgeFromId(id / 2) : INVALID; |
1589 | | } |
1590 | | |
1591 | | Arc() {} |
1592 | | Arc (Invalid) { id = -1; } |
1593 | | bool operator==(const Arc& arc) const {return id == arc.id;} |
1594 | | bool operator!=(const Arc& arc) const {return id != arc.id;} |
1595 | | bool operator<(const Arc& arc) const {return id < arc.id;} |
1596 | | }; |
1597 | | |
1598 | | class Face { |
1599 | | friend class PlanarGraphBase; |
1600 | | protected: |
1601 | | |
1602 | | int id; |
1603 | | explicit Face(int pid) { id = pid;} |
1604 | | |
1605 | | public: |
1606 | | Face() {} |
1607 | | Face (Invalid) { id = -1; } |
1608 | | bool operator==(const Face& face) const {return id == face.id;} |
1609 | | bool operator!=(const Face& face) const {return id != face.id;} |
1610 | | bool operator<(const Face& face) const {return id < face.id;} |
1611 | | }; |
1612 | | |
1613 | | PlanarGraphBase() |
1614 | | : nodes(), first_node(-1), first_free_node(-1), |
1615 | | arcs(), first_free_arc(-1), |
1616 | | faces(), first_face(-1), first_free_face(-1), |
1617 | | component_id(0) { |
1618 | | } |
1619 | | |
1620 | | |
1621 | | int maxNodeId() const { return nodes.size()-1; } |
1622 | | int maxEdgeId() const { return arcs.size() / 2 - 1; } |
1623 | | int maxArcId() const { return arcs.size()-1; } |
1624 | | int maxFaceId() const { return faces.size()-1; } |
1625 | | |
1626 | | Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); } |
1627 | | Node target(Arc e) const { return Node(arcs[e.id].target); } |
1628 | | Face leftFace(Arc e) const { return Face(arcs[e.id].left_face); } |
1629 | | Face rightFace(Arc e) const { return Face(arcs[e.id ^ 1].left_face); } |
1630 | | |
1631 | | Node u(Edge e) const { return Node(arcs[2 * e.id].target); } |
1632 | | Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); } |
1633 | | Face w1(Edge e) const { return Face(arcs[2 * e.id].left_face); } |
1634 | | Face w2(Edge e) const { return Face(arcs[2 * e.id + 1].left_face); } |
1635 | | |
1636 | | static bool direction(Arc e) { |
1637 | | return (e.id & 1) == 1; |
1638 | | } |
1639 | | |
1640 | | static Arc direct(Edge e, bool d) { |
1641 | | return Arc(e.id * 2 + (d ? 1 : 0)); |
1642 | | } |
1643 | | |
1644 | | //Primitives to use in iterators |
1645 | | void first(Node& node) const { |
1646 | | node.id = first_node; |
1647 | | } |
1648 | | |
1649 | | void next(Node& node) const { |
1650 | | node.id = nodes[node.id].next; |
1651 | | } |
1652 | | |
1653 | | void first(Arc& e) const { |
1654 | | int n = first_node; |
1655 | | while (n != -1 && nodes[n].first_out == -1) { |
1656 | | n = nodes[n].next; |
1657 | | } |
1658 | | e.id = (n == -1) ? -1 : nodes[n].first_out; |
1659 | | } |
1660 | | |
1661 | | void next(Arc& e) const { |
1662 | | if (arcs[e.id].next_out != -1) { |
1663 | | e.id = arcs[e.id].next_out; |
1664 | | } else { |
1665 | | int n = nodes[arcs[e.id ^ 1].target].next; |
1666 | | while(n != -1 && nodes[n].first_out == -1) { |
1667 | | n = nodes[n].next; |
1668 | | } |
1669 | | e.id = (n == -1) ? -1 : nodes[n].first_out; |
1670 | | } |
1671 | | } |
1672 | | |
1673 | | void first(Edge& e) const { |
1674 | | int n = first_node; |
1675 | | while (n != -1) { |
1676 | | e.id = nodes[n].first_out; |
1677 | | while ((e.id & 1) != 1) { |
1678 | | e.id = arcs[e.id].next_out; |
1679 | | } |
1680 | | if (e.id != -1) { |
1681 | | e.id /= 2; |
1682 | | return; |
1683 | | } |
1684 | | n = nodes[n].next; |
1685 | | } |
1686 | | e.id = -1; |
1687 | | } |
1688 | | |
1689 | | void next(Edge& e) const { |
1690 | | int n = arcs[e.id * 2].target; |
1691 | | e.id = arcs[(e.id * 2) | 1].next_out; |
1692 | | while ((e.id & 1) != 1) { |
1693 | | e.id = arcs[e.id].next_out; |
1694 | | } |
1695 | | if (e.id != -1) { |
1696 | | e.id /= 2; |
1697 | | return; |
1698 | | } |
1699 | | n = nodes[n].next; |
1700 | | while (n != -1) { |
1701 | | e.id = nodes[n].first_out; |
1702 | | while ((e.id & 1) != 1) { |
1703 | | e.id = arcs[e.id].next_out; |
1704 | | } |
1705 | | if (e.id != -1) { |
1706 | | e.id /= 2; |
1707 | | return; |
1708 | | } |
1709 | | n = nodes[n].next; |
1710 | | } |
1711 | | e.id = -1; |
1712 | | } |
1713 | | |
1714 | | void firstOut(Arc &e, const Node& v) const { |
1715 | | e.id = nodes[v.id].first_out; |
1716 | | } |
1717 | | void nextOut(Arc &e) const { |
1718 | | e.id = arcs[e.id].next_out; |
1719 | | } |
1720 | | |
1721 | | void firstIn(Arc &e, const Node& v) const { |
1722 | | e.id = ((nodes[v.id].first_out) ^ 1); |
1723 | | if (e.id == -2) e.id = -1; |
1724 | | } |
1725 | | void nextIn(Arc &e) const { |
1726 | | e.id = ((arcs[e.id ^ 1].next_out) ^ 1); |
1727 | | if (e.id == -2) e.id = -1; |
1728 | | } |
1729 | | void lastIn(Arc &e, const Node& v) const { |
1730 | | e.id = ((nodes[v.id].last_out) ^ 1); |
1731 | | if (e.id == -2) e.id = -1; |
1732 | | } |
1733 | | void prevIn(Arc &e) const { |
1734 | | e.id = ((arcs[e.id ^ 1].prev_out) ^ 1); |
1735 | | if (e.id == -2) e.id = -1; |
1736 | | } |
1737 | | |
1738 | | void firstCwF(Arc &e, const Face &f) const { |
1739 | | e.id = faces[f.id].first_arc; |
1740 | | } |
1741 | | void nextCwF(Arc &e) const { |
1742 | | turnLeft(e); |
1743 | | setToOpposite(e); |
1744 | | if (e.id == faces[arcs[e.id].left_face].first_arc) e = INVALID; |
1745 | | } |
1746 | | |
1747 | | void firstInF(Arc &e, const Face &f) const { |
1748 | | e.id = faces[f.id].first_arc; |
1749 | | } |
1750 | | void nextInF(Arc &e) const { |
1751 | | setToOpposite(e); |
1752 | | turnRight(e); |
1753 | | if (e.id == faces[arcs[e.id].left_face].first_arc) e = INVALID; |
1754 | | } |
1755 | | void lastInF(Arc &e, const Face &f) const { |
1756 | | e.id = faces[f.id].first_arc; |
1757 | | setToOpposite(e); |
1758 | | turnRight(e); |
1759 | | } |
1760 | | void prevInF(Arc &e) const { |
1761 | | if (e.id == faces[arcs[e.id].left_face].first_arc) { |
1762 | | e = INVALID; |
1763 | | return; |
1764 | | } |
1765 | | setToOpposite(e); |
1766 | | turnRight(e); |
1767 | | } |
1768 | | |
1769 | | void firstOutF(Arc &e, const Face &f) const { |
1770 | | e.id = faces[e.id].first_arc ^ 1; |
1771 | | } |
1772 | | void nextOutF(Arc &e) const { |
1773 | | turnRight(e); |
1774 | | setToOpposite(e); |
1775 | | if (e.id == faces[arcs[e.id ^ 1].left_face].first_arc) e = INVALID; |
1776 | | } |
1777 | | |
1778 | | void first(Arc &arc, const Face& face) const { |
1779 | | arc.id = faces[face.id].first_arc; |
1780 | | } |
1781 | | |
1782 | | void turnLeftF(Arc &e) const { |
1783 | | setToOpposite(e); |
1784 | | turnRight(e); |
1785 | | } |
1786 | | |
1787 | | void turnRightF(Arc &e) const { |
1788 | | turnLeft(e); |
1789 | | setToOpposite(e); |
1790 | | } |
1791 | | |
1792 | | void turnLeft(Arc &e) const { |
1793 | | if (arcs[e.id].next_out > -1) { |
1794 | | e.id = arcs[e.id].next_out; |
1795 | | } else { |
1796 | | e.id = nodes[arcs[e.id ^ 1].target].first_out; |
1797 | | } |
1798 | | } |
1799 | | void turnRight(Arc &e) const { |
1800 | | if (arcs[e.id].prev_out > -1) { |
1801 | | e.id = arcs[e.id].prev_out; |
1802 | | } else { |
1803 | | e.id = nodes[arcs[e.id ^ 1].target].last_out; |
1804 | | } |
1805 | | } |
1806 | | void setToOpposite(Arc &a) const { |
1807 | | if (a.id != -1) a.id ^= 1; |
1808 | | } |
1809 | | |
1810 | | void firstInc(Edge &e, bool& d, const Node& v) const { |
1811 | | int a = nodes[v.id].first_out; |
1812 | | if (a != -1 ) { |
1813 | | e.id = a / 2; |
1814 | | d = ((a & 1) == 1); |
1815 | | } else { |
1816 | | e.id = -1; |
1817 | | d = true; |
1818 | | } |
1819 | | } |
1820 | | void nextInc(Edge &e, bool& d) const { |
1821 | | int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out); |
1822 | | if (a != -1 ) { |
1823 | | e.id = a / 2; |
1824 | | d = ((a & 1) == 1); |
1825 | | } else { |
1826 | | e.id = -1; |
1827 | | d = true; |
1828 | | } |
1829 | | } |
1830 | | |
1831 | | void first(Face& face) const { |
1832 | | face.id = first_face; |
1833 | | } |
1834 | | |
1835 | | void next(Face& face) const { |
1836 | | face.id = faces[face.id].next; |
1837 | | } |
1838 | | |
1839 | | Arc arcAt(Node n, Edge e) { |
1840 | | if (e.id == -1) return INVALID; |
1841 | | return Arc((e.id*2) | (arcs[e.id*2].target == n.id?1:0)); |
1842 | | } |
1843 | | |
1844 | | static int id(Node v) { return v.id; } |
1845 | | static int id(Arc e) { return e.id; } |
1846 | | static int id(Edge e) { return e.id; } |
1847 | | static int id(Face f) { return f.id; } |
1848 | | |
1849 | | static Node nodeFromId(int id) { return Node(id);} |
1850 | | static Arc arcFromId(int id) { return Arc(id);} |
1851 | | static Edge edgeFromId(int id) { return Edge(id);} |
1852 | | static Face faceFromId(int id) { return Face(id);} |
1853 | | |
1854 | | bool valid(Node n) const { |
1855 | | return n.id >= 0 && n.id < static_cast<int>(nodes.size()) && |
1856 | | nodes[n.id].prev != -2; |
1857 | | } |
1858 | | |
1859 | | bool valid(Arc a) const { |
1860 | | return a.id >= 0 && a.id < static_cast<int>(arcs.size()) && |
1861 | | arcs[a.id].prev_out != -2; |
1862 | | } |
1863 | | |
1864 | | bool valid(Edge e) const { |
1865 | | return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) && |
1866 | | arcs[2 * e.id].prev_out != -2; |
1867 | | } |
1868 | | |
1869 | | bool valid(Face f) const { |
1870 | | return f.id >= 0 && f.id < static_cast<int>(faces.size()) && |
1871 | | faces[f.id].prev != -2; |
1872 | | } |
1873 | | |
1874 | | Node addNode() { |
1875 | | int n; |
1876 | | |
1877 | | if(first_free_node==-1) { |
1878 | | n = nodes.size(); |
1879 | | nodes.push_back(NodeT()); |
1880 | | } else { |
1881 | | n = first_free_node; |
1882 | | first_free_node = nodes[n].next; |
1883 | | } |
1884 | | |
1885 | | nodes[n].next = first_node; |
1886 | | nodes[n].component = component_id++; |
1887 | | if (first_node != -1) nodes[first_node].prev = n; |
1888 | | first_node = n; |
1889 | | nodes[n].prev = -1; |
1890 | | |
1891 | | nodes[n].first_out = nodes[n].last_out = -1; |
1892 | | |
1893 | | return Node(n); |
1894 | | } |
1895 | | |
1896 | | Edge addEdge(Node u, Node v, Edge e_u, Edge e_v) { |
1897 | | |
1898 | | Arc p_u = arcAt(u,e_u); |
1899 | | Arc p_v = arcAt(v,e_v); |
1900 | | |
1901 | | if (p_u.id > -1 && p_v.id > -1 && arcs[p_u.id].left_face != arcs[p_v.id].left_face |
1902 | | && nodes[u.id].component == nodes[v.id].component) return INVALID; |
1903 | | |
1904 | | int n = addBlankEdge(); |
1905 | | |
1906 | | arcs[n].target = u.id; |
1907 | | arcs[n | 1].target = v.id; |
1908 | | |
1909 | | arcs[n].prev_out = p_v.id; |
1910 | | if (p_v.id > -1) { |
1911 | | arcs[n].next_out = arcs[p_v.id].next_out; |
1912 | | arcs[p_v.id].next_out = n; |
1913 | | } else { |
1914 | | arcs[n].next_out = nodes[v.id].first_out; |
1915 | | nodes[v.id].first_out = n; |
1916 | | } |
1917 | | if (arcs[n].next_out > -1) { |
1918 | | arcs[arcs[n].next_out].prev_out = n; |
1919 | | } else { |
1920 | | nodes[v.id].last_out = n; |
1921 | | } |
1922 | | |
1923 | | arcs[n | 1].prev_out = p_u.id; |
1924 | | if (p_u.id > -1) { |
1925 | | arcs[n | 1].next_out = arcs[p_u.id].next_out; |
1926 | | arcs[p_u.id].next_out = n | 1; |
1927 | | } else { |
1928 | | arcs[n | 1].next_out = nodes[u.id].first_out; |
1929 | | nodes[u.id].first_out = n | 1; |
1930 | | } |
1931 | | if (arcs[n | 1].next_out > -1) { |
1932 | | arcs[arcs[n | 1].next_out].prev_out = n | 1; |
1933 | | } else { |
1934 | | nodes[u.id].last_out = n | 1; |
1935 | | } |
1936 | | |
1937 | | //Add the extra face, if needed |
1938 | | if (p_u.id > -1 & p_v.id > -1) { |
1939 | | int oldf = arcs[p_u.id].left_face; |
1940 | | int oldfb = arcs[p_v.id].left_face; |
1941 | | arcs[n].left_face = arcs[n | 1].left_face = oldf; |
1942 | | Face f = addFace(); |
1943 | | faces[f.id].first_arc = n | 1; |
1944 | | faces[oldf].first_arc = n; |
1945 | | Arc arc(n | 1); |
1946 | | wall_paint(arc,f.id,arc); |
1947 | | if (nodes[v.id].component != nodes[u.id].component) { |
1948 | | erase(Face(oldf)); |
1949 | | erase(Face(oldfb)); |
1950 | | int ca = nodes[u.id].component; |
1951 | | int cb = nodes[v.id].component; |
1952 | | int k = first_node; |
1953 | | while (k != -1) { |
1954 | | if (nodes[k].component == cb) |
1955 | | nodes[k].component = ca; |
1956 | | k = nodes[k].next; |
1957 | | } |
1958 | | } |
1959 | | } else if (p_u.id > -1) { |
1960 | | arcs[n].left_face = arcs[n | 1].left_face = arcs[p_u.id].left_face; |
1961 | | faces[arcs[n].left_face].first_arc = n | 1; |
1962 | | nodes[v.id].component = nodes[u.id].component; |
1963 | | } else if (p_v.id > -1) { |
1964 | | arcs[n].left_face = arcs[n | 1].left_face = arcs[p_v.id].left_face; |
1965 | | faces[arcs[n].left_face].first_arc = n | 1; |
1966 | | nodes[u.id].component = nodes[v.id].component; |
1967 | | } else { //both prevs are INVALID |
1968 | | Face f = addFace(); |
1969 | | arcs[n].left_face = arcs[n | 1].left_face = f.id; |
1970 | | faces[f.id].first_arc = n | 1; |
1971 | | nodes[v.id].component = nodes[u.id].component; |
1972 | | } |
1973 | | |
1974 | | return Edge(n / 2); |
1975 | | } |
1976 | | |
1977 | | void erase(const Node& node) { |
1978 | | int n = node.id; |
1979 | | |
1980 | | if(nodes[n].next != -1) { |
1981 | | nodes[nodes[n].next].prev = nodes[n].prev; |
1982 | | } |
1983 | | |
1984 | | if(nodes[n].prev != -1) { |
1985 | | nodes[nodes[n].prev].next = nodes[n].next; |
1986 | | } else { |
1987 | | first_node = nodes[n].next; |
1988 | | } |
1989 | | |
1990 | | nodes[n].next = first_free_node; |
1991 | | first_free_node = n; |
1992 | | nodes[n].prev = -2; |
1993 | | } |
1994 | | |
1995 | | void erase(const Edge& edge) { |
1996 | | int n = edge.id * 2; |
1997 | | |
1998 | | //"retreat" the incident faces' first arcs |
1999 | | int fl = arcs[n].left_face; |
2000 | | if ((faces[fl].first_arc | 1) == (n | 1)) { |
2001 | | Arc e(faces[fl].first_arc); |
2002 | | turnRightF(e); |
2003 | | if ((e.id | 1) == (n | 1)) turnRightF(e); |
2004 | | faces[fl].first_arc = e.id; |
2005 | | } |
2006 | | |
2007 | | int fr = arcs[n | 1].left_face; |
2008 | | |
2009 | | bool comp_split = false; |
2010 | | if (fr != fl) { |
2011 | | Arc arc(faces[fr].first_arc); |
2012 | | wall_paint(arc,fl,arc); |
2013 | | erase(Face(fr)); |
2014 | | } else if ((arcs[n].next_out > -1 || arcs[n].prev_out > -1) && |
2015 | | (arcs[n | 1].next_out > -1 || arcs[n | 1].prev_out > -1)) { |
2016 | | comp_split = true; |
2017 | | Arc arc(n); |
2018 | | Arc ed = arc; |
2019 | | ed.id ^= 1; |
2020 | | turnRightF(arc); |
2021 | | Face f = addFace(); |
2022 | | wall_paint(arc,f.id,ed); |
2023 | | faces[f.id].first_arc = arc.id; |
2024 | | } |
2025 | | |
2026 | | if (arcs[n].next_out != -1) { |
2027 | | arcs[arcs[n].next_out].prev_out = arcs[n].prev_out; |
2028 | | } else { |
2029 | | nodes[arcs[n].target].last_out = arcs[n].prev_out; |
2030 | | } |
2031 | | |
2032 | | if (arcs[n].prev_out != -1) { |
2033 | | arcs[arcs[n].prev_out].next_out = arcs[n].next_out; |
2034 | | } else { |
2035 | | nodes[arcs[n | 1].target].first_out = arcs[n].next_out; |
2036 | | } |
2037 | | |
2038 | | if (arcs[n | 1].next_out != -1) { |
2039 | | arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out; |
2040 | | } else { |
2041 | | nodes[arcs[n | 1].target].last_out = arcs[n | 1].prev_out; |
2042 | | } |
2043 | | |
2044 | | if (arcs[n | 1].prev_out != -1) { |
2045 | | arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out; |
2046 | | } else { |
2047 | | nodes[arcs[n].target].first_out = arcs[n | 1].next_out; |
2048 | | } |
2049 | | |
2050 | | arcs[n].next_out = first_free_arc; |
2051 | | first_free_arc = n; |
2052 | | arcs[n].prev_out = -2; |
2053 | | arcs[n | 1].prev_out = -2; |
2054 | | |
2055 | | if (comp_split) component_relabel(Node(arcs[n | 1].target), component_id++); |
2056 | | |
2057 | | } |
2058 | | |
2059 | | void clear() { |
2060 | | arcs.clear(); |
2061 | | nodes.clear(); |
2062 | | faces.clear(); |
2063 | | first_node = first_free_node = first_free_arc = first_face = first_free_face = -1; |
2064 | | } |
2065 | | |
2066 | | Node split(Edge e) { |
2067 | | Node v = addNode(); |
2068 | | Arc a(e.id*2); |
2069 | | int b = addBlankEdge(); |
2070 | | |
2071 | | nodes[v.id].component = nodes[arcs[a.id].target].component; |
2072 | | nodes[v.id].first_out = a.id; |
2073 | | nodes[v.id].last_out = b | 1; |
2074 | | |
2075 | | arcs[b] = arcs[a.id]; |
2076 | | arcs[b].target = v.id; |
2077 | | if (arcs[a.id].next_out > -1) |
2078 | | arcs[arcs[a.id].next_out].prev_out = b; |
2079 | | else |
2080 | | nodes[arcs[a.id | 1].target].last_out = b; |
2081 | | if (arcs[a.id].prev_out > -1) |
2082 | | arcs[arcs[a.id].prev_out].next_out = b; |
2083 | | else |
2084 | | nodes[arcs[a.id | 1].target].first_out = b; |
2085 | | |
2086 | | arcs[b | 1] = arcs[a.id | 1]; |
2087 | | arcs[b | 1].next_out = -1; |
2088 | | arcs[b | 1].prev_out = a.id; |
2089 | | |
2090 | | arcs[a.id].next_out = b | 1; |
2091 | | arcs[a.id].prev_out = -1; |
2092 | | arcs[a.id | 1].target = v.id; |
2093 | | |
2094 | | |
2095 | | return v; |
2096 | | } |
2097 | | |
2098 | | protected: |
2099 | | |
2100 | | void wall_paint(Arc arc, int f_id, Arc ed) { |
2101 | | do { |
2102 | | arcs[arc.id].left_face = f_id; |
2103 | | turnRightF(arc); |
2104 | | } while (arc != ed); |
2105 | | } |
2106 | | |
2107 | | void component_relabel(Node node, int comp_id) { |
2108 | | std::vector<int> ns(nodes.size()); |
2109 | | std::list<int> q; |
2110 | | q.push_back(node.id); |
2111 | | ns[node.id] = 1; |
2112 | | while (!q.empty()) { |
2113 | | int n = q.front(); |
2114 | | ns[n] = 2; |
2115 | | nodes[n].component = comp_id; |
2116 | | q.pop_front(); |
2117 | | Arc arc; |
2118 | | firstOut(arc,Node(n)); |
2119 | | while (arc.id > -1) { |
2120 | | int m = arcs[arc.id].target; |
2121 | | if (ns[m] == 0) { |
2122 | | ns[m] = 1; |
2123 | | q.push_back(m); |
2124 | | } |
2125 | | nextOut(arc); |
2126 | | } |
2127 | | } |
2128 | | } |
2129 | | |
2130 | | Face addFace() { |
2131 | | int n; |
2132 | | |
2133 | | if(first_free_face==-1) { |
2134 | | n = faces.size(); |
2135 | | faces.push_back(FaceT()); |
2136 | | } else { |
2137 | | n = first_free_face; |
2138 | | first_free_face = faces[n].next; |
2139 | | } |
2140 | | |
2141 | | faces[n].next = first_face; |
2142 | | if (first_face != -1) faces[first_face].prev = n; |
2143 | | first_face = n; |
2144 | | faces[n].prev = -1; |
2145 | | |
2146 | | faces[n].first_arc = -1; |
2147 | | |
2148 | | return Face(n); |
2149 | | } |
2150 | | |
2151 | | void erase(const Face& face) { |
2152 | | int n = face.id; |
2153 | | |
2154 | | if(faces[n].next != -1) { |
2155 | | faces[faces[n].next].prev = faces[n].prev; |
2156 | | } |
2157 | | |
2158 | | if(faces[n].prev != -1) { |
2159 | | faces[faces[n].prev].next = faces[n].next; |
2160 | | } else { |
2161 | | first_face = faces[n].next; |
2162 | | } |
2163 | | |
2164 | | faces[n].next = first_free_face; |
2165 | | first_free_face = n; |
2166 | | faces[n].prev = -2; |
2167 | | } |
2168 | | |
2169 | | int addBlankEdge() { |
2170 | | int n; |
2171 | | if (first_free_arc == -1) { |
2172 | | n = arcs.size(); |
2173 | | arcs.push_back(ArcT()); |
2174 | | arcs.push_back(ArcT()); |
2175 | | } else { |
2176 | | n = first_free_arc; |
2177 | | first_free_arc = arcs[n].next_out; |
2178 | | } |
2179 | | return n; |
2180 | | } |
2181 | | |
2182 | | #ifdef REMOVE_BEFORE_RELEASE |
2183 | | public: |
2184 | | void print() { |
2185 | | std::cout << "Nodes: " << std::endl; |
2186 | | for (int i=0; i<nodes.size(); ++i) |
2187 | | std::cout << i << ":" |
2188 | | << " fo=" << nodes[i].first_out |
2189 | | << " pr=" << nodes[i].prev |
2190 | | << " nx=" << nodes[i].next |
2191 | | << " co=" << nodes[i].component |
2192 | | <<std::endl; |
2193 | | std::cout << "Arcs: " << std::endl; |
2194 | | for (int i=0; i<arcs.size(); ++i) { |
2195 | | if (arcs[i].next_out > -2) { |
2196 | | std::cout << i << ":" |
2197 | | << " tg=" << arcs[i].target |
2198 | | << " po=" << arcs[i].prev_out |
2199 | | << " no=" << arcs[i].next_out |
2200 | | << " lf=" << arcs[i].left_face |
2201 | | <<std::endl; |
2202 | | } else std::cout << i << ": (deleted)" << std::endl; |
2203 | | } |
2204 | | std::cout << "Faces: " << std::endl; |
2205 | | for (int i=0; i<faces.size(); ++i) |
2206 | | std::cout << i |
2207 | | << " pr=" << faces[i].prev |
2208 | | << " nx=" << faces[i].next |
2209 | | << " fa=" << faces[i].first_arc |
2210 | | <<std::endl; |
2211 | | } |
2212 | | #endif |
2213 | | |
2214 | | }; |
2215 | | |
2216 | | template<typename Base> |
2217 | | class PlanarGraphExtender : public Base{ |
2218 | | |
2219 | | typedef Base Parent; |
2220 | | |
2221 | | public: |
2222 | | typedef PlanarGraphExtender Graph; |
2223 | | |
2224 | | PlanarGraphExtender() {} |
2225 | | |
2226 | | typedef typename Parent::Node Node; |
2227 | | typedef typename Parent::Arc Arc; |
2228 | | typedef typename Parent::Edge Edge; |
2229 | | typedef typename Parent::Face Face; |
2230 | | |
2231 | | class FaceIt : public Face { |
2232 | | const Graph* _graph; |
2233 | | public: |
2234 | | |
2235 | | FaceIt() {} |
2236 | | |
2237 | | FaceIt(Invalid i) : Face(i) { } |
2238 | | |
2239 | | explicit FaceIt(const Graph& graph) : _graph(&graph) { |
2240 | | _graph->first(static_cast<Face&>(*this)); |
2241 | | } |
2242 | | |
2243 | | FaceIt(const Graph& graph, const Face& face) |
2244 | | : Face(face), _graph(&graph) {} |
2245 | | |
2246 | | FaceIt& operator++() { |
2247 | | _graph->next(*this); |
2248 | | return *this; |
2249 | | } |
2250 | | |
2251 | | }; |
2252 | | |
2253 | | |
2254 | | class CwPerimeterArcIt : public Arc { |
2255 | | const Graph* _graph; |
2256 | | Face _face; |
2257 | | Arc f_arc; |
2258 | | public: |
2259 | | |
2260 | | CwPerimeterArcIt() { } |
2261 | | |
2262 | | CwPerimeterArcIt(Invalid i) : Arc(i) { } |
2263 | | |
2264 | | CwPerimeterArcIt(const Graph& graph, const Face& face) |
2265 | | : _graph(&graph), _face(face) { |
2266 | | _graph->firstCwF(static_cast<Arc&>(*this),face); |
2267 | | f_arc = *this; |
2268 | | } |
2269 | | |
2270 | | CwPerimeterArcIt(const Graph& graph, const Arc& arc) |
2271 | | : Arc(arc), _graph(&graph) {} |
2272 | | |
2273 | | CwPerimeterArcIt& operator++() { |
2274 | | _graph->nextCwF(*this); |
2275 | | return *this; |
2276 | | } |
2277 | | |
2278 | | }; |
2279 | | |
2280 | | class CcwArcIt : public Arc { |
2281 | | const Graph* _graph; |
2282 | | const Node _node; |
2283 | | public: |
2284 | | |
2285 | | CcwArcIt() { } |
2286 | | |
2287 | | CcwArcIt(Invalid i) : Arc(i) { } |
2288 | | |
2289 | | CcwArcIt(const Graph& graph, const Node& node) |
2290 | | : _graph(&graph), _node(node) { |
2291 | | _graph->firstCcw(*this, node); |
2292 | | } |
2293 | | |
2294 | | CcwArcIt(const Graph& graph, const Arc& arc) |
2295 | | : Arc(arc), _graph(&graph) {} |
2296 | | |
2297 | | CcwArcIt& operator++() { |
2298 | | _graph->nextCcw(*this, _node); |
2299 | | return *this; |
2300 | | } |
2301 | | |
2302 | | }; |
2303 | | |
2304 | | }; |
2305 | | |
2306 | | typedef PlanarGraphExtender<GraphExtender<PlanarGraphBase> > ExtendedPlanarGraphBase; |
2307 | | |
2308 | | |
2309 | | /// \addtogroup graphs |
2310 | | /// @{ |
2311 | | |
2312 | | ///A general undirected graph structure. |
2313 | | |
2314 | | ///\ref ListGraph is a versatile and fast undirected graph |
2315 | | ///implementation based on linked lists that are stored in |
2316 | | ///\c std::vector structures. |
2317 | | /// |
2318 | | ///This type fully conforms to the \ref concepts::Graph "Graph concept" |
2319 | | ///and it also provides several useful additional functionalities. |
2320 | | ///Most of its member functions and nested classes are documented |
2321 | | ///only in the concept class. |
2322 | | /// |
2323 | | ///This class provides only linear time counting for nodes, edges and arcs. |
2324 | | /// |
2325 | | ///\sa concepts::Graph |
2326 | | ///\sa ListDigraph |
2327 | | class PlanarGraph : public ExtendedPlanarGraphBase { |
2328 | | typedef ExtendedPlanarGraphBase Parent; |
2329 | | |
2330 | | private: |
2331 | | /// Graphs are \e not copy constructible. Use GraphCopy instead. |
2332 | | PlanarGraph(const PlanarGraph &) :ExtendedPlanarGraphBase() {}; |
2333 | | /// \brief Assignment of a graph to another one is \e not allowed. |
2334 | | /// Use GraphCopy instead. |
2335 | | void operator=(const PlanarGraph &) {} |
2336 | | public: |
2337 | | /// Constructor |
2338 | | |
2339 | | /// Constructor. |
2340 | | /// |
2341 | | PlanarGraph() {} |
2342 | | |
2343 | | typedef Parent::OutArcIt IncEdgeIt; |
2344 | | |
2345 | | /// \brief Add a new node to the graph. |
2346 | | /// |
2347 | | /// This function adds a new node to the graph. |
2348 | | /// \return The new node. |
2349 | | Node addNode() { return Parent::addNode(); } |
2350 | | |
2351 | | /// \brief Add a new edge to the graph. |
2352 | | /// |
2353 | | /// This function adds a new edge to the graph between nodes |
2354 | | /// \c u and \c v with inherent orientation from node \c u to |
2355 | | /// node \c v. |
2356 | | /// \return The new edge. |
2357 | | Edge addEdge(Node u, Node v, Edge p_u, Edge p_v) { |
2358 | | return PlanarGraphBase::addEdge(u, v, p_u, p_v); |
2359 | | } |
2360 | | |
2361 | | ///\brief Erase a node from the graph. |
2362 | | /// |
2363 | | /// This function erases the given node along with its incident arcs |
2364 | | /// from the graph. |
2365 | | /// |
2366 | | /// \note All iterators referencing the removed node or the incident |
2367 | | /// edges are invalidated, of course. |
2368 | | void erase(Node n) { Parent::erase(n); } |
2369 | | |
2370 | | ///\brief Erase an edge from the graph. |
2371 | | /// |
2372 | | /// This function erases the given edge from the graph. |
2373 | | /// |
2374 | | /// \note All iterators referencing the removed edge are invalidated, |
2375 | | /// of course. |
2376 | | void erase(Edge e) { Parent::erase(e); } |
2377 | | /// Node validity check |
2378 | | |
2379 | | /// This function gives back \c true if the given node is valid, |
2380 | | /// i.e. it is a real node of the graph. |
2381 | | /// |
2382 | | /// \warning A removed node could become valid again if new nodes are |
2383 | | /// added to the graph. |
2384 | | bool valid(Node n) const { return Parent::valid(n); } |
2385 | | /// Edge validity check |
2386 | | |
2387 | | /// This function gives back \c true if the given edge is valid, |
2388 | | /// i.e. it is a real edge of the graph. |
2389 | | /// |
2390 | | /// \warning A removed edge could become valid again if new edges are |
2391 | | /// added to the graph. |
2392 | | bool valid(Edge e) const { return Parent::valid(e); } |
2393 | | /// Arc validity check |
2394 | | |
2395 | | /// This function gives back \c true if the given arc is valid, |
2396 | | /// i.e. it is a real arc of the graph. |
2397 | | /// |
2398 | | /// \warning A removed arc could become valid again if new edges are |
2399 | | /// added to the graph. |
2400 | | bool valid(Arc a) const { return Parent::valid(a); } |
2401 | | |
2402 | | /// \brief Change the first node of an edge. |
2403 | | /// |
2404 | | /// Planar graphs don't support changing the endpoints of edges. |
2405 | | void changeU(Edge e, Node n) = delete; |
2406 | | /// \brief Change the second node of an edge. |
2407 | | /// |
2408 | | /// Planar graphs don't support changing the endpoints of edges. |
2409 | | void changeV(Edge e, Node n) = delete; |
2410 | | |
2411 | | /// \brief Contract two nodes. |
2412 | | /// |
2413 | | /// This function contracts the given two nodes. |
2414 | | /// Node \c b is removed, but instead of deleting |
2415 | | /// its incident edges, they are joined to node \c a. |
2416 | | /// If the last parameter \c r is \c true (this is the default value), |
2417 | | /// then the newly created loops are removed. |
2418 | | /// |
2419 | | /// \note The moved edges are joined to node \c a using changeU() |
2420 | | /// or changeV(), thus all edge and arc iterators whose base node is |
2421 | | /// \c b are invalidated. |
2422 | | /// Moreover all iterators referencing node \c b or the removed |
2423 | | /// loops are also invalidated. Other iterators remain valid. |
2424 | | /// |
2425 | | ///\warning This functionality cannot be used together with the |
2426 | | ///Snapshot feature. |
2427 | | /*TODO: rewrite this function |
2428 | | void contract(Node a, Node b, bool r = true) { |
2429 | | for(IncEdgeIt e(*this, b); e!=INVALID;) { |
2430 | | IncEdgeIt f = e; ++f; |
2431 | | if (r && runningNode(e) == a) { |
2432 | | erase(e); |
2433 | | } else if (u(e) == b) { |
2434 | | changeU(e, a); |
2435 | | } else { |
2436 | | changeV(e, a); |
2437 | | } |
2438 | | e = f; |
2439 | | } |
2440 | | erase(b); |
2441 | | } |
2442 | | */ |
2443 | | |
2444 | | ///Clear the graph. |
2445 | | |
2446 | | ///This function erases all nodes and arcs from the graph. |
2447 | | /// |
2448 | | ///\note All iterators of the graph are invalidated, of course. |
2449 | | void clear() { |
2450 | | Parent::clear(); |
2451 | | } |
2452 | | |
2453 | | /// Reserve memory for nodes. |
2454 | | |
2455 | | /// Using this function, it is possible to avoid superfluous memory |
2456 | | /// allocation: if you know that the graph you want to build will |
2457 | | /// be large (e.g. it will contain millions of nodes and/or edges), |
2458 | | /// then it is worth reserving space for this amount before starting |
2459 | | /// to build the graph. |
2460 | | /// \sa reserveEdge() |
2461 | | void reserveNode(int n) { nodes.reserve(n); }; |
2462 | | |
2463 | | /// Reserve memory for edges. |
2464 | | |
2465 | | /// Using this function, it is possible to avoid superfluous memory |
2466 | | /// allocation: if you know that the graph you want to build will |
2467 | | /// be large (e.g. it will contain millions of nodes and/or edges), |
2468 | | /// then it is worth reserving space for this amount before starting |
2469 | | /// to build the graph. |
2470 | | /// \sa reserveNode() |
2471 | | void reserveEdge(int m) { arcs.reserve(2 * m); }; |
2472 | | |
2473 | | class DualBase { |
2474 | | const Graph *_graph; |
2475 | | protected: |
2476 | | void initialize(const Graph *graph) { _graph = graph; } |
2477 | | public: |
2478 | | |
2479 | | typedef PlanarGraph::Face Node; |
2480 | | typedef PlanarGraph::Arc Arc; |
2481 | | typedef PlanarGraph::Edge Edge; |
2482 | | typedef PlanarGraph::Node Face; |
2483 | | |
2484 | | int maxNodeId() const { return _graph->maxFaceId(); } |
2485 | | int maxArcId() const { return _graph->maxArcId(); } |
2486 | | int maxFaceId() const { return _graph->maxNodeId(); } |
2487 | | |
2488 | | Node source(Arc e) const { return _graph->leftFace(e); } |
2489 | | Node target(Arc e) const { return _graph->rightFace(e); } |
2490 | | Face leftFace(Arc e) const { return _graph->target(e); } |
2491 | | Face rightFace(Arc e) const { return _graph->source(e); } |
2492 | | Arc direct(const Edge &edge, const Node &node) const { return _graph->direct(edge, _graph->w1(edge) == node); } |
2493 | | |
2494 | | void first(Node &i) const { _graph->first(i); } |
2495 | | void next(Node &i) const { _graph->next(i); } |
2496 | | void first(Arc &i) const { _graph->first(i); } |
2497 | | void next(Arc &i) const { _graph->next(i); } |
2498 | | void firstCcw(Arc& i, const Node& n) const { _graph->lastInF(i, n); } |
2499 | | void nextCcw(Arc& i, const Node &n) const { _graph->prevInF(i); } |
2500 | | void firstIn(Arc& i, const Node& n) const { _graph->firstInF(i, n); } |
2501 | | void nextIn(Arc& i) const { _graph->nextInF(i); } |
2502 | | void firstCwF(Arc& i, const Face& n) const { _graph->lastIn(i, n); } |
2503 | | void nextCwF(Arc& i) const { _graph->prevIn(i); } |
2504 | | void firstOut(Arc& i, const Node& n ) const { _graph->firstOutF(i, n); } |
2505 | | void nextOut(Arc& i) const { _graph->nextOutF(i); } |
2506 | | void first(Face &i) const { _graph->first(i); } |
2507 | | void next(Face &i) const { _graph->next(i); } |
2508 | | |
2509 | | static int id(Node v) { return PlanarGraph::id(v); } |
2510 | | static int id(Arc e) { return PlanarGraph::id(e); } |
2511 | | static int id(Face f) { return PlanarGraph::id(f); } |
2512 | | static Node nodeFromId(int id) { return PlanarGraph::faceFromId(id);} |
2513 | | static Arc arcFromId(int id) { return PlanarGraph::arcFromId(id);} |
2514 | | static Face faceFromId(int id) { return PlanarGraph::nodeFromId(id);} |
2515 | | |
2516 | | bool valid(Node n) const { return _graph->valid(n); } |
2517 | | bool valid(Arc n) const { return _graph->valid(n); } |
2518 | | bool valid(Face n) const { return _graph->valid(n); } |
2519 | | |
2520 | | }; |
2521 | | |
2522 | | typedef PlanarGraphExtender<GraphExtender<DualBase> > ExtendedDualBase; |
2523 | | /// \brief Adaptor class for the dual of a planar graph. |
2524 | | /// |
2525 | | /// Adaptor class for the dual of a planar graph. |
2526 | | class Dual : public ExtendedDualBase { |
2527 | | public: |
2528 | | Dual(const PlanarGraph &graph) { initialize(&graph); } |
2529 | | |
2530 | | }; |
2531 | | /// \brief Class to make a snapshot of the graph and restore |
2532 | | /// it later. |
2533 | | /// |
2534 | | /// Class to make a snapshot of the graph and restore it later. |
2535 | | /// |
2536 | | /// The newly added nodes and edges can be removed |
2537 | | /// using the restore() function. |
2538 | | /// |
2539 | | /// \note After a state is restored, you cannot restore a later state, |
2540 | | /// i.e. you cannot add the removed nodes and edges again using |
2541 | | /// another Snapshot instance. |
2542 | | /// |
2543 | | /// \warning Node and edge deletions and other modifications |
2544 | | /// (e.g. changing the end-nodes of edges or contracting nodes) |
2545 | | /// cannot be restored. These events invalidate the snapshot. |
2546 | | /// However, the edges and nodes that were added to the graph after |
2547 | | /// making the current snapshot can be removed without invalidating it. |
2548 | | class Snapshot { |
2549 | | protected: |
2550 | | |
2551 | | typedef Parent::NodeNotifier NodeNotifier; |
2552 | | |
2553 | | class NodeObserverProxy : public NodeNotifier::ObserverBase { |
2554 | | public: |
2555 | | |
2556 | | NodeObserverProxy(Snapshot& _snapshot) |
2557 | | : snapshot(_snapshot) {} |
2558 | | |
2559 | | using NodeNotifier::ObserverBase::attach; |
2560 | | using NodeNotifier::ObserverBase::detach; |
2561 | | using NodeNotifier::ObserverBase::attached; |
2562 | | |
2563 | | protected: |
2564 | | |
2565 | | virtual void add(const Node& node) { |
2566 | | snapshot.addNode(node); |
2567 | | } |
2568 | | virtual void add(const std::vector<Node>& nodes) { |
2569 | | for (int i = nodes.size() - 1; i >= 0; ++i) { |
2570 | | snapshot.addNode(nodes[i]); |
2571 | | } |
2572 | | } |
2573 | | virtual void erase(const Node& node) { |
2574 | | snapshot.eraseNode(node); |
2575 | | } |
2576 | | virtual void erase(const std::vector<Node>& nodes) { |
2577 | | for (int i = 0; i < int(nodes.size()); ++i) { |
2578 | | snapshot.eraseNode(nodes[i]); |
2579 | | } |
2580 | | } |
2581 | | virtual void build() { |
2582 | | Node node; |
2583 | | std::vector<Node> nodes; |
2584 | | for (notifier()->first(node); node != INVALID; |
2585 | | notifier()->next(node)) { |
2586 | | nodes.push_back(node); |
2587 | | } |
2588 | | for (int i = nodes.size() - 1; i >= 0; --i) { |
2589 | | snapshot.addNode(nodes[i]); |
2590 | | } |
2591 | | } |
2592 | | virtual void clear() { |
2593 | | Node node; |
2594 | | for (notifier()->first(node); node != INVALID; |
2595 | | notifier()->next(node)) { |
2596 | | snapshot.eraseNode(node); |
2597 | | } |
2598 | | } |
2599 | | |
2600 | | Snapshot& snapshot; |
2601 | | }; |
2602 | | |
2603 | | class EdgeObserverProxy : public EdgeNotifier::ObserverBase { |
2604 | | public: |
2605 | | |
2606 | | EdgeObserverProxy(Snapshot& _snapshot) |
2607 | | : snapshot(_snapshot) {} |
2608 | | |
2609 | | using EdgeNotifier::ObserverBase::attach; |
2610 | | using EdgeNotifier::ObserverBase::detach; |
2611 | | using EdgeNotifier::ObserverBase::attached; |
2612 | | |
2613 | | protected: |
2614 | | |
2615 | | virtual void add(const Edge& edge) { |
2616 | | snapshot.addEdge(edge); |
2617 | | } |
2618 | | virtual void add(const std::vector<Edge>& edges) { |
2619 | | for (int i = edges.size() - 1; i >= 0; ++i) { |
2620 | | snapshot.addEdge(edges[i]); |
2621 | | } |
2622 | | } |
2623 | | virtual void erase(const Edge& edge) { |
2624 | | snapshot.eraseEdge(edge); |
2625 | | } |
2626 | | virtual void erase(const std::vector<Edge>& edges) { |
2627 | | for (int i = 0; i < int(edges.size()); ++i) { |
2628 | | snapshot.eraseEdge(edges[i]); |
2629 | | } |
2630 | | } |
2631 | | virtual void build() { |
2632 | | Edge edge; |
2633 | | std::vector<Edge> edges; |
2634 | | for (notifier()->first(edge); edge != INVALID; |
2635 | | notifier()->next(edge)) { |
2636 | | edges.push_back(edge); |
2637 | | } |
2638 | | for (int i = edges.size() - 1; i >= 0; --i) { |
2639 | | snapshot.addEdge(edges[i]); |
2640 | | } |
2641 | | } |
2642 | | virtual void clear() { |
2643 | | Edge edge; |
2644 | | for (notifier()->first(edge); edge != INVALID; |
2645 | | notifier()->next(edge)) { |
2646 | | snapshot.eraseEdge(edge); |
2647 | | } |
2648 | | } |
2649 | | |
2650 | | Snapshot& snapshot; |
2651 | | }; |
2652 | | |
2653 | | PlanarGraph *graph; |
2654 | | |
2655 | | NodeObserverProxy node_observer_proxy; |
2656 | | EdgeObserverProxy edge_observer_proxy; |
2657 | | |
2658 | | std::list<Node> added_nodes; |
2659 | | std::list<Edge> added_edges; |
2660 | | |
2661 | | |
2662 | | void addNode(const Node& node) { |
2663 | | added_nodes.push_front(node); |
2664 | | } |
2665 | | void eraseNode(const Node& node) { |
2666 | | std::list<Node>::iterator it = |
2667 | | std::find(added_nodes.begin(), added_nodes.end(), node); |
2668 | | if (it == added_nodes.end()) { |
2669 | | clear(); |
2670 | | edge_observer_proxy.detach(); |
2671 | | throw NodeNotifier::ImmediateDetach(); |
2672 | | } else { |
2673 | | added_nodes.erase(it); |
2674 | | } |
2675 | | } |
2676 | | |
2677 | | void addEdge(const Edge& edge) { |
2678 | | added_edges.push_front(edge); |
2679 | | } |
2680 | | void eraseEdge(const Edge& edge) { |
2681 | | std::list<Edge>::iterator it = |
2682 | | std::find(added_edges.begin(), added_edges.end(), edge); |
2683 | | if (it == added_edges.end()) { |
2684 | | clear(); |
2685 | | node_observer_proxy.detach(); |
2686 | | throw EdgeNotifier::ImmediateDetach(); |
2687 | | } else { |
2688 | | added_edges.erase(it); |
2689 | | } |
2690 | | } |
2691 | | |
2692 | | void attach(PlanarGraph &_graph) { |
2693 | | graph = &_graph; |
2694 | | node_observer_proxy.attach(graph->notifier(Node())); |
2695 | | edge_observer_proxy.attach(graph->notifier(Edge())); |
2696 | | } |
2697 | | |
2698 | | void detach() { |
2699 | | node_observer_proxy.detach(); |
2700 | | edge_observer_proxy.detach(); |
2701 | | } |
2702 | | |
2703 | | bool attached() const { |
2704 | | return node_observer_proxy.attached(); |
2705 | | } |
2706 | | |
2707 | | void clear() { |
2708 | | added_nodes.clear(); |
2709 | | added_edges.clear(); |
2710 | | } |
2711 | | |
2712 | | public: |
2713 | | |
2714 | | /// \brief Default constructor. |
2715 | | /// |
2716 | | /// Default constructor. |
2717 | | /// You have to call save() to actually make a snapshot. |
2718 | | Snapshot() |
2719 | | : graph(0), node_observer_proxy(*this), |
2720 | | edge_observer_proxy(*this) {} |
2721 | | |
2722 | | /// \brief Constructor that immediately makes a snapshot. |
2723 | | /// |
2724 | | /// This constructor immediately makes a snapshot of the given graph. |
2725 | | Snapshot(PlanarGraph &gr) |
2726 | | : node_observer_proxy(*this), |
2727 | | edge_observer_proxy(*this) { |
2728 | | attach(gr); |
2729 | | } |
2730 | | |
2731 | | /// \brief Make a snapshot. |
2732 | | /// |
2733 | | /// This function makes a snapshot of the given graph. |
2734 | | /// It can be called more than once. In case of a repeated |
2735 | | /// call, the previous snapshot gets lost. |
2736 | | void save(PlanarGraph &gr) { |
2737 | | if (attached()) { |
2738 | | detach(); |
2739 | | clear(); |
2740 | | } |
2741 | | attach(gr); |
2742 | | } |
2743 | | |
2744 | | /// \brief Undo the changes until the last snapshot. |
2745 | | /// |
2746 | | /// This function undos the changes until the last snapshot |
2747 | | /// created by save() or Snapshot(ListGraph&). |
2748 | | /// |
2749 | | /// \warning This method invalidates the snapshot, i.e. repeated |
2750 | | /// restoring is not supported unless you call save() again. |
2751 | | void restore() { |
2752 | | detach(); |
2753 | | for(std::list<Edge>::iterator it = added_edges.begin(); |
2754 | | it != added_edges.end(); ++it) { |
2755 | | graph->erase(*it); |
2756 | | } |
2757 | | for(std::list<Node>::iterator it = added_nodes.begin(); |
2758 | | it != added_nodes.end(); ++it) { |
2759 | | graph->erase(*it); |
2760 | | } |
2761 | | clear(); |
2762 | | } |
2763 | | |
2764 | | /// \brief Returns \c true if the snapshot is valid. |
2765 | | /// |
2766 | | /// This function returns \c true if the snapshot is valid. |
2767 | | bool valid() const { |
2768 | | return attached(); |
2769 | | } |
2770 | | }; |
2771 | | }; |
2772 | | |
2773 | | /// @} |
| 1527 | /// @} |