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; |