| 683 | | Node v = Node(link_node()); |
| 684 | | Arc a(e.id*2); |
| 685 | | int b = link_edge(); |
| 686 | | |
| 687 | | nodes[v.id].component = nodes[arcs[a.id].target].component; |
| 688 | | ++components[nodes[v.id].component].num_nodes; |
| 689 | | nodes[v.id].first_out = a.id; |
| 690 | | nodes[v.id].last_out = b | 1; |
| 691 | | |
| 692 | | arcs[b] = arcs[a.id]; |
| 693 | | arcs[b].target = v.id; |
| 694 | | if (arcs[a.id].next_out > -1) |
| 695 | | arcs[arcs[a.id].next_out].prev_out = b; |
| 696 | | else |
| 697 | | nodes[arcs[a.id | 1].target].last_out = b; |
| 698 | | if (arcs[a.id].prev_out > -1) |
| 699 | | arcs[arcs[a.id].prev_out].next_out = b; |
| 700 | | else |
| 701 | | nodes[arcs[a.id | 1].target].first_out = b; |
| 702 | | |
| 703 | | arcs[b | 1] = arcs[a.id | 1]; |
| 704 | | arcs[b | 1].next_out = -1; |
| 705 | | arcs[b | 1].prev_out = a.id; |
| 706 | | |
| 707 | | arcs[a.id].next_out = b | 1; |
| 708 | | arcs[a.id].prev_out = -1; |
| 709 | | arcs[a.id | 1].target = v.id; |
| 710 | | |
| 711 | | |
| 712 | | return v; |
| | 685 | Node v; |
| | 686 | Edge e2; |
| | 687 | inner_split1(v,e2); |
| | 688 | return inner_split2(e,v,e2); |
| 716 | | Node n2 = Node(link_node()); |
| 717 | | Edge e3; |
| 718 | | if (nodes[n1.id].first_out == -1) { |
| 719 | | if (b) e3 = addEdge(n1,n2,INVALID,INVALID); |
| 720 | | return n2; |
| 721 | | } |
| 722 | | arcs[nodes[n1.id].first_out].prev_out = nodes[n1.id].last_out; |
| 723 | | arcs[nodes[n1.id].last_out].next_out = nodes[n1.id].first_out; |
| 724 | | nodes[n2.id].component = nodes[n1.id].component; |
| 725 | | ++components[nodes[n2.id].component].num_nodes; |
| 726 | | Arc a1(e1.id*2); |
| 727 | | if (arcs[a1.id].target != n1.id) a1.id |= 1; |
| 728 | | Arc a2(e2.id*2); |
| 729 | | if (arcs[a2.id].target != n1.id) a2.id |= 1; |
| 730 | | Arc a3(link_edge()); |
| 731 | | arcs[a3.id].target = n1.id; |
| 732 | | arcs[a3.id | 1].target = n2.id; |
| 733 | | arcs[a3.id].left_face = arcs[a1.id].left_face; |
| 734 | | arcs[a3.id | 1].left_face = arcs[a2.id].left_face; |
| 735 | | |
| 736 | | arcs[a3.id].prev_out = arcs[a2.id ^ 1].prev_out; |
| 737 | | arcs[arcs[a2.id ^ 1].prev_out].next_out = a3.id; |
| 738 | | arcs[a3.id | 1].prev_out = arcs[a1.id ^ 1].prev_out; |
| 739 | | arcs[arcs[a1.id ^ 1].prev_out].next_out = a3.id | 1; |
| 740 | | nodes[n1.id].first_out = a2.id ^ 1; |
| 741 | | arcs[a1.id ^ 1].prev_out = -1; |
| 742 | | nodes[n1.id].last_out = a3.id | 1; |
| 743 | | arcs[a3.id | 1].next_out = -1; |
| 744 | | nodes[n2.id].first_out = a1.id ^ 1; |
| 745 | | arcs[a2.id ^ 1].prev_out = -1; |
| 746 | | nodes[n2.id].last_out = a3.id; |
| 747 | | arcs[a3.id].next_out = -1; |
| 748 | | |
| 749 | | Arc a4(a1.id); |
| 750 | | while (a4.id != (a3.id | 1)) { |
| 751 | | arcs[a4.id].target = n2.id; |
| 752 | | a4.id = arcs[a4.id ^ 1].next_out ^ 1; |
| 753 | | } |
| 754 | | |
| 755 | | if (!b) erase(a3); |
| | 692 | Node n2; |
| | 693 | inner_split1(n1,n2); |
| | 694 | Edge a3; |
| | 695 | inner_split2(n1,n2,e1,e2,b,a3); |
| | 696 | if (!b && a3 != INVALID) erase(a3); |
| 762 | | if (nodes[n1.id].first_out == nodes[n1.id].last_out) { |
| 763 | | erase(e); |
| 764 | | erase(n1); |
| 765 | | return; |
| 766 | | } |
| 767 | | if (nodes[n2.id].first_out == nodes[n2.id].last_out) { |
| 768 | | erase(e); |
| 769 | | erase(n2); |
| 770 | | return; |
| 771 | | } |
| 772 | | Arc a(e.id*2); |
| 773 | | int fl = arcs[a.id].left_face; |
| 774 | | if ((faces[fl].first_arc | 1) == a.id | 1) { |
| 775 | | Arc b = a; |
| 776 | | turnRightF(b); |
| 777 | | faces[fl].first_arc = b.id; |
| 778 | | } |
| 779 | | int fr = arcs[a.id | 1].left_face; |
| 780 | | if ((faces[fr].first_arc | 1) == a.id | 1) { |
| 781 | | Arc b = a; |
| 782 | | turnRightF(b); |
| 783 | | faces[fr].first_arc = b.id; |
| 784 | | } |
| 785 | | Arc b = a; |
| 786 | | turnLeft(b); |
| 787 | | while (b != a) { |
| 788 | | arcs[b.id ^ 1].target = n1.id; |
| 789 | | if (arcs[b.id].next_out > -1) |
| 790 | | b.id = arcs[b.id].next_out; |
| 791 | | else |
| 792 | | b.id = nodes[n2.id].first_out; |
| 793 | | } |
| 794 | | arcs[nodes[n2.id].last_out].next_out = nodes[n2.id].first_out; |
| 795 | | arcs[nodes[n2.id].first_out].prev_out = nodes[n2.id].last_out; |
| 796 | | if (arcs[a.id | 1].prev_out > -1) { |
| 797 | | arcs[arcs[a.id | 1].prev_out].next_out = arcs[a.id].next_out; |
| 798 | | } else { |
| 799 | | nodes[n1.id].first_out = arcs[a.id].next_out; |
| 800 | | } |
| 801 | | arcs[arcs[a.id].next_out].prev_out = arcs[a.id | 1].prev_out; |
| 802 | | if (arcs[a.id | 1].next_out > -1) { |
| 803 | | arcs[arcs[a.id | 1].next_out].prev_out = arcs[a.id].prev_out; |
| 804 | | } else { |
| 805 | | nodes[n1.id].last_out = arcs[a.id].prev_out; |
| 806 | | } |
| 807 | | arcs[arcs[a.id].prev_out].next_out = arcs[a.id | 1].next_out; |
| 808 | | |
| 809 | | unlink_edge(e); |
| 810 | | --components[nodes[n2.id].component].num_nodes; |
| 811 | | unlink_node(n2.id); |
| | 703 | Node nd; |
| | 704 | bool simple; |
| | 705 | inner_contract1(n1,n2,nd,simple); |
| | 706 | inner_contract2(e,n1,n2,nd,simple); |
| | 778 | //Primitives of split(Edge) |
| | 779 | void inner_split1(Node &v, Edge &e2) { |
| | 780 | v = Node(link_node()); |
| | 781 | e2 = Arc(link_edge()); |
| | 782 | } |
| | 783 | |
| | 784 | Node inner_split2(Edge e, Node v, Edge e2) { |
| | 785 | Arc a(e.id*2); |
| | 786 | int b = e2.id*2; |
| | 787 | nodes[v.id].component = nodes[arcs[a.id].target].component; |
| | 788 | ++components[nodes[v.id].component].num_nodes; |
| | 789 | nodes[v.id].first_out = a.id; |
| | 790 | nodes[v.id].last_out = b | 1; |
| | 791 | |
| | 792 | arcs[b] = arcs[a.id]; |
| | 793 | arcs[b].target = v.id; |
| | 794 | if (arcs[a.id].next_out > -1) |
| | 795 | arcs[arcs[a.id].next_out].prev_out = b; |
| | 796 | else |
| | 797 | nodes[arcs[a.id | 1].target].last_out = b; |
| | 798 | if (arcs[a.id].prev_out > -1) |
| | 799 | arcs[arcs[a.id].prev_out].next_out = b; |
| | 800 | else |
| | 801 | nodes[arcs[a.id | 1].target].first_out = b; |
| | 802 | |
| | 803 | arcs[b | 1] = arcs[a.id | 1]; |
| | 804 | arcs[b | 1].next_out = -1; |
| | 805 | arcs[b | 1].prev_out = a.id; |
| | 806 | |
| | 807 | arcs[a.id].next_out = b | 1; |
| | 808 | arcs[a.id].prev_out = -1; |
| | 809 | arcs[a.id | 1].target = v.id; |
| | 810 | |
| | 811 | return v; |
| | 812 | } |
| | 813 | |
| | 814 | //Primitives of contract(Edge) |
| | 815 | void inner_contract1(Node n1, Node n2, Node &to_delete, bool &simple) { |
| | 816 | if (nodes[n1.id].first_out == nodes[n1.id].last_out) { |
| | 817 | simple = true; |
| | 818 | to_delete = n1; |
| | 819 | } else if (nodes[n2.id].first_out == nodes[n2.id].last_out) { |
| | 820 | simple = true; |
| | 821 | to_delete = n2; |
| | 822 | } else { |
| | 823 | simple = false; |
| | 824 | to_delete = n2; |
| | 825 | } |
| | 826 | } |
| | 827 | |
| | 828 | void inner_contract2(Edge e, Node n1, Node n2, Node &to_delete, bool |
| | 829 | &simple) { |
| | 830 | if (simple) { |
| | 831 | erase(e); |
| | 832 | erase(to_delete); |
| | 833 | return; |
| | 834 | } |
| | 835 | Arc a(e.id*2); |
| | 836 | int fl = arcs[a.id].left_face; |
| | 837 | if ((faces[fl].first_arc | 1) == a.id | 1) { |
| | 838 | Arc b = a; |
| | 839 | turnRightF(b); |
| | 840 | faces[fl].first_arc = b.id; |
| | 841 | } |
| | 842 | int fr = arcs[a.id | 1].left_face; |
| | 843 | if ((faces[fr].first_arc | 1) == a.id | 1) { |
| | 844 | Arc b = a; |
| | 845 | turnRightF(b); |
| | 846 | faces[fr].first_arc = b.id; |
| | 847 | } |
| | 848 | Arc b = a; |
| | 849 | turnLeft(b); |
| | 850 | while (b != a) { |
| | 851 | arcs[b.id ^ 1].target = n1.id; |
| | 852 | if (arcs[b.id].next_out > -1) |
| | 853 | b.id = arcs[b.id].next_out; |
| | 854 | else |
| | 855 | b.id = nodes[n2.id].first_out; |
| | 856 | } |
| | 857 | arcs[nodes[n2.id].last_out].next_out = nodes[n2.id].first_out; |
| | 858 | arcs[nodes[n2.id].first_out].prev_out = nodes[n2.id].last_out; |
| | 859 | if (arcs[a.id | 1].prev_out > -1) { |
| | 860 | arcs[arcs[a.id | 1].prev_out].next_out = arcs[a.id].next_out; |
| | 861 | } else { |
| | 862 | nodes[n1.id].first_out = arcs[a.id].next_out; |
| | 863 | } |
| | 864 | arcs[arcs[a.id].next_out].prev_out = arcs[a.id | 1].prev_out; |
| | 865 | if (arcs[a.id | 1].next_out > -1) { |
| | 866 | arcs[arcs[a.id | 1].next_out].prev_out = arcs[a.id].prev_out; |
| | 867 | } else { |
| | 868 | nodes[n1.id].last_out = arcs[a.id].prev_out; |
| | 869 | } |
| | 870 | arcs[arcs[a.id].prev_out].next_out = arcs[a.id | 1].next_out; |
| | 871 | |
| | 872 | unlink_edge(e); |
| | 873 | --components[nodes[n2.id].component].num_nodes; |
| | 874 | unlink_node(n2.id); |
| | 875 | } |
| | 876 | |
| | 877 | //Primitives of split(Node) |
| | 878 | void inner_split1(Node n1, Node &n2) { |
| | 879 | n2 = Node(link_node()); |
| | 880 | } |
| | 881 | |
| | 882 | void inner_split2(Node n1, Node n2, Edge e1, Edge e2, bool b, Edge &e3) { |
| | 883 | e3 = INVALID; |
| | 884 | if (nodes[n1.id].first_out == -1) { |
| | 885 | if (b) e3 = addEdge(n1,n2,INVALID,INVALID); |
| | 886 | return; |
| | 887 | } |
| | 888 | arcs[nodes[n1.id].first_out].prev_out = nodes[n1.id].last_out; |
| | 889 | arcs[nodes[n1.id].last_out].next_out = nodes[n1.id].first_out; |
| | 890 | nodes[n2.id].component = nodes[n1.id].component; |
| | 891 | ++components[nodes[n2.id].component].num_nodes; |
| | 892 | Arc a1(e1.id*2); |
| | 893 | if (arcs[a1.id].target != n1.id) a1.id |= 1; |
| | 894 | Arc a2(e2.id*2); |
| | 895 | if (arcs[a2.id].target != n1.id) a2.id |= 1; |
| | 896 | Arc a3(link_edge()); |
| | 897 | e3 = a3; |
| | 898 | arcs[a3.id].target = n1.id; |
| | 899 | arcs[a3.id | 1].target = n2.id; |
| | 900 | arcs[a3.id].left_face = arcs[a1.id].left_face; |
| | 901 | arcs[a3.id | 1].left_face = arcs[a2.id].left_face; |
| | 902 | |
| | 903 | arcs[a3.id].prev_out = arcs[a2.id ^ 1].prev_out; |
| | 904 | arcs[arcs[a2.id ^ 1].prev_out].next_out = a3.id; |
| | 905 | arcs[a3.id | 1].prev_out = arcs[a1.id ^ 1].prev_out; |
| | 906 | arcs[arcs[a1.id ^ 1].prev_out].next_out = a3.id | 1; |
| | 907 | nodes[n1.id].first_out = a2.id ^ 1; |
| | 908 | arcs[a1.id ^ 1].prev_out = -1; |
| | 909 | nodes[n1.id].last_out = a3.id | 1; |
| | 910 | arcs[a3.id | 1].next_out = -1; |
| | 911 | nodes[n2.id].first_out = a1.id ^ 1; |
| | 912 | arcs[a2.id ^ 1].prev_out = -1; |
| | 913 | nodes[n2.id].last_out = a3.id; |
| | 914 | arcs[a3.id].next_out = -1; |
| | 915 | |
| | 916 | Arc a4(a1.id); |
| | 917 | while (a4.id != (a3.id | 1)) { |
| | 918 | arcs[a4.id].target = n2.id; |
| | 919 | a4.id = arcs[a4.id ^ 1].next_out ^ 1; |
| | 920 | } |
| | 921 | } |
| | 922 | |
| | 1086 | template <typename GR, typename Enable = void> |
| | 1087 | struct FaceNotifierIndicator { |
| | 1088 | typedef InvalidType Type; |
| | 1089 | }; |
| | 1090 | template <typename GR> |
| | 1091 | struct FaceNotifierIndicator< |
| | 1092 | GR, |
| | 1093 | typename enable_if<typename GR::FaceNotifier::Notifier, void>::type |
| | 1094 | > { |
| | 1095 | typedef typename GR::FaceNotifier Type; |
| | 1096 | }; |
| | 1097 | |
| | 1098 | template <typename GR> |
| | 1099 | class ItemSetTraits<GR, typename GR::Face> { |
| | 1100 | public: |
| | 1101 | |
| | 1102 | typedef GR Graph; |
| | 1103 | typedef GR Digraph; |
| | 1104 | |
| | 1105 | typedef typename GR::Face Item; |
| | 1106 | typedef typename GR::FaceIt ItemIt; |
| | 1107 | |
| | 1108 | typedef typename FaceNotifierIndicator<GR>::Type ItemNotifier; |
| | 1109 | |
| | 1110 | template <typename V> |
| | 1111 | class Map : public GR::template FaceMap<V> { |
| | 1112 | typedef typename GR::template FaceMap<V> Parent; |
| | 1113 | |
| | 1114 | public: |
| | 1115 | typedef typename GR::template FaceMap<V> Type; |
| | 1116 | typedef typename Parent::Value Value; |
| | 1117 | |
| | 1118 | Map(const GR& _digraph) : Parent(_digraph) {} |
| | 1119 | Map(const GR& _digraph, const Value& _value) |
| | 1120 | : Parent(_digraph, _value) {} |
| | 1121 | |
| | 1122 | }; |
| | 1123 | |
| | 1124 | }; |
| | 1125 | |
| | 1139 | typedef typename Parent::NodeNotifier NodeNotifier; |
| | 1140 | typedef typename Parent::EdgeNotifier EdgeNotifier; |
| | 1141 | typedef typename Parent::ArcNotifier ArcNotifier; |
| | 1142 | typedef AlterationNotifier<PlanarGraphExtender, Face> FaceNotifier; |
| | 1143 | |
| | 1144 | protected: |
| | 1145 | mutable FaceNotifier face_notifier; |
| | 1146 | |
| | 1147 | public: |
| | 1148 | |
| | 1149 | int maxId(Face) const { |
| | 1150 | return Parent::maxFaceId(); |
| | 1151 | } |
| | 1152 | |
| | 1153 | NodeNotifier& notifier(Node) const { |
| | 1154 | return Parent::node_notifier; |
| | 1155 | } |
| | 1156 | |
| | 1157 | ArcNotifier& notifier(Arc) const { |
| | 1158 | return Parent::arc_notifier; |
| | 1159 | } |
| | 1160 | |
| | 1161 | EdgeNotifier& notifier(Edge) const { |
| | 1162 | return Parent::edge_notifier; |
| | 1163 | } |
| | 1164 | |
| | 1165 | FaceNotifier& notifier(Face) const { |
| | 1166 | return face_notifier; |
| | 1167 | } |
| | 1168 | |
| | 1169 | template <typename _Value> |
| | 1170 | class FaceMap |
| | 1171 | : public MapExtender<DefaultMap<Graph, Face, _Value> > { |
| | 1172 | typedef MapExtender<DefaultMap<Graph, Face, _Value> > Parent; |
| | 1173 | |
| | 1174 | public: |
| | 1175 | explicit FaceMap(const Graph& graph) |
| | 1176 | : Parent(graph) {} |
| | 1177 | FaceMap(const Graph& graph, const _Value& value) |
| | 1178 | : Parent(graph, value) {} |
| | 1179 | |
| | 1180 | private: |
| | 1181 | FaceMap& operator=(const FaceMap& cmap) { |
| | 1182 | return operator=<FaceMap>(cmap); |
| | 1183 | } |
| | 1184 | |
| | 1185 | template <typename CMap> |
| | 1186 | FaceMap& operator=(const CMap& cmap) { |
| | 1187 | Parent::operator=(cmap); |
| | 1188 | return *this; |
| | 1189 | } |
| | 1190 | |
| | 1191 | }; |
| | 1192 | |
| | 1193 | |
| 1357 | | return PlanarGraphBase::addEdge(u, v, p_u, p_v); |
| | 1527 | Face f_u = INVALID, f_v = INVALID; |
| | 1528 | if (p_u != INVALID) { |
| | 1529 | Arc a_u = direct(p_u,u); |
| | 1530 | f_u = leftFace(a_u); |
| | 1531 | } |
| | 1532 | if (p_v != INVALID) { |
| | 1533 | Arc a_v = direct(p_v,v); |
| | 1534 | f_v = leftFace(a_v); |
| | 1535 | } |
| | 1536 | Face o_u = outerFace(u); |
| | 1537 | Face o_v = outerFace(v); |
| | 1538 | Edge edge = PlanarGraphBase::addEdge(u, v, p_u, p_v); |
| | 1539 | if (edge == INVALID) return edge; |
| | 1540 | if (!valid(f_u)) notifier(Face()).erase(f_u); |
| | 1541 | if (!valid(f_v) && f_u != f_v) notifier(Face()).erase(f_v); |
| | 1542 | if (!valid(o_u)) notifier(Face()).erase(o_u); |
| | 1543 | if (!valid(o_v)) notifier(Face()).erase(o_v); |
| | 1544 | edge_add_notify(edge); |
| | 1545 | Face e_l = leftFace(direct(edge,u)); |
| | 1546 | Face e_r = rightFace(direct(edge,u)); |
| | 1547 | if (e_l != f_u && e_l != f_v && e_l != o_u && e_l != o_v) |
| | 1548 | notifier(Face()).add(e_l); |
| | 1549 | if (e_r != f_u && e_r != f_v && e_r != o_u && e_r != o_v && e_r != e_l) |
| | 1550 | notifier(Face()).add(e_r); |
| | 1551 | return edge; |