-
Notifications
You must be signed in to change notification settings - Fork 0
/
embedded_bctree.hpp
1306 lines (1059 loc) · 43.7 KB
/
embedded_bctree.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef _WAILEA_UNDIRECTED_EMBEDDED_BCTREE_HPP_
#define _WAILEA_UNDIRECTED_EMBEDDED_BCTREE_HPP_
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <exception>
#include "undirected/base.hpp"
#include "undirected/planar_dual_graph_maker.hpp"
#include "undirected/bctree.hpp"
#include "directed/di_base.hpp"
#ifdef UNIT_TESTS
#include "gtest/gtest_prod.h"
#endif
namespace Wailea {
namespace Undirected {
/**
* @file undirected/embedded_bctree.hpp
*
* @brief
*
* @remark
* This file handles a combinatorial and geometric embedding of a connected
* graph. Here we define a combinatorial embedding as a set of permissible
* ordering of the incident edges around each node, and a geometric embedidng
* as a combinatorial embedding with its outer face and the orientation fixed.
* A geometric embedding is used to generate a visibility representation of
* the connected graph.
*
* A connected graph can be decomposed into block-cut-tree, or BC-tree.
* Each node of a BC-tree is either a cut vertex or a block.
* A biconnected decomposition into a BC-tree can be considered to be a 2-tier
* structure, where the higher level is the rootless tree with its nodes
* cutvertices and blocks, and each block as the lower level is a biconnected
* subgraph.
* A combinatorial embedding of a biconnected component is usually found by
* some variants of planarity testing algorithm such as Booth & Lueker.
* On the other hand, a combinatorial embedding of a tree is always planar,
* and sometimes the combinatorial embedding is given externally.
*
* ===============================================================
* How to represent a combinatorial embedding of a connected graph
* ===============================================================
* Our representation is based on the BC-tree decomposion.
* We assume a connected component has been decomposed into a
* BC-tree and for each block, a combinatorial embedding and its dual graph
* have been already found independently.
* The main task is then unifying the embeddings of the blocks incident to
* each cut vertex.
* A convenient way to think about the unification is first to form some groups
* of faces incident to the cut vertex.
* We denote such a group by face unification group. Each unification
* face group consists of zero or one face from each incident block.
* No face can be part of more than one unification group for the same cut
* vertex.
* Multiple faces from a single block can participate in unification groups.
* At least one face from a block must participate in a unification group
* for the cut vertex.
* If we form a graph with its nodes for the incident blocks, all the
* participating faces, and all the face unification groups for the cut vertex,
* and connect two nodes with an edge if:
* - one is a block and the other is a participating face from the block
* - one is a face unification group and the other is the participating face
* then the graph must not contain a cycle. I.e, the graph must be a tree.
*
* Each face unification group specifies a circular ordering and orientation
* of the participating block around the cut vertex.
* In each face unification group, each participating block nominates a face
* to be unified in the face unification group.
* If the block is not k2, then the block also specifes the
* ordering of two incident edges to the nominated face. This ordering
* specifies one of the two orientations (like the two sides of a coin)
* of the block relative to the unification group.
*
* An easy way to visualize this unification of a face unification group is
* temporarily making the nominated faces outer face of each block.
*
* Consider a situation where three blocks B1, B2, and B3 are incident to a
* cut vertex cv1 and B2, B4, and B5 are incident to a cut vertex cv2
* as follows.
*
* B1 B2 B3
* _______________ _______________ _______________
* |e6\ e1/ | | \e12 e7/ | | \e18 e13/ |
* | \ / | | \ / | | \ / |
* | \ f1 / | | \ f7 / | | \ f13/ |
* | f6 \ / f2 | | f12 \ / f8 | | f18 \ / f14|
* | \ / | | \ / | | \ / |
* |------cv1------| |------cv1------| |------cv1------|
* |e6 / \ e2 | |e11 / \ e8 | |e17 / \ e14|
* | / \ | | / \ | | / \ |
* | f5 / \ f3 | | f11/ \ f9 | | f17/ \ f15|
* | / f4 \ | | / f10 \ | | / f16 \ |
* |e4/ e3\ | | /e10 e9\ | | /e16 e15\ |
* --------------- -cv2------------- ---------------
*
* B4 B5
* _______________ _______________
* |e24 e19/ | | \e30 e25/ |
* | \ / | | \ / |
* | \ f19/ | | \ f25/ |
* | f24 \ / f20| | f30 \ / f26|
* | \ / | | \ / |
* |------cv2------| |------cv2------|
* |e23 / \ e20| |e29 / \ e26|
* | / \ | | / \ |
* | f23/ \ f21| | f29/ \ f27|
* | / f22 \ | | / f28 \ |
* |e22 e21\ | | /e28 e27\ |
* --------------- -----------------
*
* Assume we want to embedded the blocks in the circular ordering of
* (B1, B3, B2).
* The faces f4, f10, and f16 are nominated as the faces to be unified.
* The orientations of the blocks are: ( (e4, e3), (e16, e15), (e9, e10) ).
*
* This can be visualized as follows.
*
* _________
* \ /
* \ B1 /
* e3\ /e4 Unified faces: (f4, f16, and f10)
* \ /
* __e16___cv1___e10__
* \ / \ /
* \ B3 / \e9 /
* \ /e15 \ B2/
* \_/ \_/
*
* Please note that one UF group around one cut vertex may be further
* unified with other UF groups around another cut vertices as follows.
* We denote such a set of UF groups by UF group tree.
*
*
* _________ _____
* \ / | /
* \ B1 / |B5 /
* e3\ /e4 e30| /e25
* \ / | /
* __e16___cv1___e10__cv2__e24__
* \ / \ / \ /
* \ B3 / \e9 / \ B4 /
* \ /e15 \ B2/ e19\ /
* \_/ \_/ \_/
*
* face unification group 1 : (f4, f16, f10)
* face unification group 2 : (f10 f25, f19)
* face unification group tree T(V,E) = ( {group 1, group 2}, {(cv1,cv2)} )
* Unified faces: (f4, f16, f10, f25, and f19)
*
* To formalize our representation of a combinatorial embedding of a
* connected graph G, we need the following.
* - BC-tree of G
* - For each block B, combinatorial embedding Gamma(B), and its Dual(B)
* - For each cut vertex CV, set S(CV) of face unification groups.
* - Each face unification group G has a circular ordering of the incident
* edges of the nominated faces of the participating blocks.
*
* This can be implemented by augumenting BC-tree. The nodes of block type
* contain combinatorial embeddings and their duals, and the nodes of
* cut vertex type and the tree edges contain the UF groups described above.
* This is implemented into EmbeddedBCTree[Node,Edge] below.
*
* ================================================================
* Finding a geometric embedding of a connected graph and
* a permissible classification of inner/outer faces of each block
* ================================================================
* We define a geometric embedding as a combinatorial embedding with its
* outer face and the orientation determined.
* Any face of any block can be part of the outer face of the resultant
* embedding for the connected graph.
*
* First, in a geometric embedding, we observe that among the faces in a
* face unification group tree, all except for one have to be the outer faces
* of corresponding blocks when decomposed.
* This comes from the fact that two inner faces can not be unified without
* making crossings in a geometric embedding. Please see the example below.
*
* B4 B5
* f20 f28
* ________cv2_______ ________cv2_______
* | / / \ \ | | / / \ \ |
* |f19 / | | \f21| | f29/ | | \f27|
* | / | | \ | | / | | \ |
* | / f24|f23| f22\ | | / f30|f25|f26 \ |
* |------------------| |------------------|
* |\/\/\/\/\/\/\/\/\/| |\/\/\/\/\/\/\/\/\/|
* |\/\/\/\/\/\/\/\/\/| |\/\/\/\/\/\/\/\/\/|
* ------------------ ------------------
*
* - f20 and f28 can be unified. In this case B4 and B5 will be placed
* side-by-side.
* - f20 and f30 can be unified. In this case B4 will be enclosed by f30.
* - f23 and f28 can be unified. In this case B5 will be enclosed by f23.
* - f24 and f30 can not be unified without making a crossing, as both are
* inner faces.
*
* We have to first determine the outer face and the top node for
* each block.
* There are two constraints in the way each face is classified into
* outer or inner face.
* - For each block, exactly one face will be outer face, and the rest
* will be inner faces.
* - For each face participating in a face unification group for a cut vertex,
* at most one face can be inner face, the rest must be outer faces.
* Please note that this classification is valid if we look at the embedding
* of each block individually. An outer face of a block may be unified
* with an inner face of another block, in which case the former will be
* enclosed in the latter and the former will not be part of the outer face
* of the entire connected graph.
*
* To meet those contraints, we nominate one face in each unification group
* as 'the absorber', and the rest as 'the absorbees'.
* The absorber can be an inner face, but the absorbees must be outer faces
* in order to keep the planarity.
* If we take apart the connected graph at the cut vertex, then we will get
* several connected subgraphs and each of them are represented by the faces
* participating to the unification groups at the cut vertex.
* The sugraphs (with their embeddings) identified by the absorbees can be
* considered absorbed in their absorber face at each unification group.
* Please note that there can be multiple face unification groups at a cut
* vertex.
* At each block, we can have at most one absorbee and all the other faces
* that participate to face unification groups must be absorbor, as they
* have to be inner faces. This means only the outer face can be an absorbee.
*
* The above observation about the constraints and the absorber/absorbee
* relationships among the blocks give a partial order among the block nodes
* of the BC-tree, which can be represented in a rooted directed tree.
* Such a tree is represented by EmbeddedBCTree::ExplorationTree.
* Please note that ExplorationTree is not a directed version of BC-tree.
*
* For any given combinatorial embedding of a connected graph represented
* as above, there is following freedom to make inner/outer classification.
* - What block to be the root block?
* - What face to be the outer face of the root block?
* - What node incident to the face to be the top node? : (This is needed
* for the visibility representation algorithm)
* Once those are determined, the outer/inner face classification will be done
* from the root block down to the leaf blocks recursively as follows.
*
* - For each block node:
* - If it is a root node, make the outer face the absorbee.
* Otherwise, the absorbee has been already determined before reaching here
* - For each cut vertex do:
* for each face unificaton group do:
* for each face in the face unification group do:
* - if the face blongs to this block, make it absorber.
* - else make it absorbee and recursively process the block.
*
*
* For that purpose, EmbeddedBCTree provides findGeometricEmbedding(), which
* classifies the faces and generates EmbeddedBCTree::ExplorationTree.
*/
class ConstantsEmbeddedBCTree {
public:
static constexpr const char* kExceptionBCTreeRootNotSet
= "The root is not set for the tree or the tree is empty.";
static constexpr const char* kExceptionEmbeddingNotSet
= "The embedding is not set for this edge.";
};
class EmbeddedBCTreeNode;
class EmbeddedBCTreeEdge;
class UnificationFace;
class UnificationFaceRef;
class UnificationGroup;
class SortedUnificationGroup;
/** @class EmbeddedBCTree
*
* @brief BC-tree with a combinatorial embedding.
* The combinatorial embeding is specified by the following.
* - embedding (and its dual) of each block
* - face unification groups of each cut vertex
* The details about the face unification groups is described
* above at "How to represent a combinatorial embedding of
* a connected graph".
*
* The input graph is assumed to be planar. If it is not planar, the
* behavior is undefined.
* It provides a convenience function, makeDefaultEmbedding, which
* finds an embedding for each block using Booth-Lueker planarity
* algorithm, and a single face unification group is created at
* each cut vertex. From each block the biggest incident face is
* selected and those are places in one group in the order found in the
* BC-tree.
*
* If the user does not use make DefaultEmbedding, s/he must provide
* the following:
*
* For each EmbeddedBCTreeNode of type BCTreeNode::BlockType
* The incident edges of each node in Block must represent
* planar combinatorial embedding.
* An EmbeddedGraph and a DualGraph that refer to
* the underlying planar Block in the BC-tree.
* Those are set by EmbeddedBCTreeNode::setEmbedding().
*
* For each EmbeddedBCTreeEdge, which spans a block and a cut vertex,
* fit: The face nominated from the block to be unified at
* the cut vertex.
* eCW: EmbeddedEdge incident to the face and the copy of
* the cut vertex above. On the clockwise side to be unified
* around the cut vertex.
* eCCW: EmbeddedEdge incident to the face and the copy of
* the cut vertex above. On the counter-clockwise side.
* If eCW and eCCW are not in the same orientation as in the
* orientation of the half edges around the face, then the
* block in which the face reside will be flipped when unified.
*
* For each EmbeddedBCTreeNode of type BCTreeNode::CutVertexType
* face unification groups. A face unification group is a
* vector<edge_list_it_t>, and the ordering in the vector
* specifies the counter-clockwise ordering of the embedding.
* of the blocks (faces) specified in EmbeddedBCTreeEdge.
* Those are set by EmbeddedBCTreeNode::pushBackUnificationGroup()
*
* It provides a function findGeometricEmbedding() to find a
* geometric embedding by classifying outer face/inner faces of the
* embedding of each block, and by generating a rooted tree structure
* among block nodes.
* The function can take the following three parameters:
* - Root block
* - Outer face of the root block
* - Top node of the outer face of the root block
* The top node is used to find a visibility representation.
*
* @dependencies
* It depends on BCTree in bctree.hpp. An EmbeddedBCTree references to
* the nodes, edges, blocks, and cut vertices of BCTree.
* ExplorationTree is derived from Directed::DiGraph.
*
*/
class EmbeddedBCTree : public Graph {
public:
/** @brief this is a directed tree as the result of orient() operation
* by which the outer face is determined for each block.
* this tree is rooted and oriented.
* The tree nodes represent the block nodes of the BC-tree.
* This tree is used to generate a visibility
* representation of the connected graph the BC-tree represents.
* This tree is different from any oriented BC-tree in the sense
* there are no nodes that represent cut vertices.
*/
class ExplorationNode;
class ExplorationTree : public Directed::DiGraph {
public:
// Move constructor and assignment are allowed.
inline ExplorationTree(ExplorationTree&& rhs) noexcept;
inline ExplorationTree& operator=(ExplorationTree&& rhs) noexcept;
/** @brief returns the root ExplorationNode that corresponds to
* the root block node in EmbeddedBCTree.
*
* @throws invalid_argument(ConstantsEmbeddedBCTree::
* kExceptionBCTreeRootNotSet)
* if the tree is empty.
*/
inline ExplorationNode& root();
private:
inline ExplorationTree();
inline void setRoot(node_list_it_t root);
node_list_it_t mRoot;
friend class EmbeddedBCTree;
#ifdef UNIT_TESTS
friend class EmbeddedBCTreeTests;
#endif
};
class ExplorationNode : public Directed::DiNode {
public:
/** @brief reset the internal counter for bottom-up tree traversal.
*/
inline void resetNumChildrenProcessed();
/** @brief increment the internal counter for bottom-up tree traversal.
*/
inline void incrementNumChildrenProcessed();
/** @brief returns the current value of the internal counter
* for bottom-up tree traversal.
*/
inline long numChildrenProcessed();
/** @brief returns the sorted unification groups with the absorber
* absorbees classification.
*/
inline vector<SortedUnificationGroup>& sortedUnificationGroups();
private:
inline ExplorationNode(EmbeddedBCTreeNode& org);
/** @brief set of subordinate face unification groups whose absorber
* faces are in this block.
* This is used when generating visibility representation.
*/
vector<SortedUnificationGroup> mSortedUnificationGroups;
/** @brief internal counter for bottom-up tree traversal.
*/
long mNumChildrenProcessed;
friend class EmbeddedBCTree;
friend std::unique_ptr<ExplorationNode> std::make_unique<ExplorationNode,
EmbeddedBCTreeNode&>(EmbeddedBCTreeNode&);
#ifdef UNIT_TESTS
friend class EmbeddedBCTreeTests;
#endif
};
class ExplorationEdge : public Directed::DiEdge {
public:
private:
inline ExplorationEdge();
friend class EmbeddedBCTree;
friend std::unique_ptr<ExplorationEdge> std::make_unique<ExplorationEdge>();
#ifdef UNIT_TESTS
friend class EmbeddedBCTreeTests;
#endif
};
/** @brief constructor from a BCTree.
*
* @param tree (in): BC-tree.
*/
EmbeddedBCTree(BCTree& tree);
/** @brief generates a default combinatorial embedding.
* It generates an embedding and its dual for each block
* and then one face unification group per cut vertex.
* the face to be unified is chosen to be the largest one
* incident to the cut vertex. The ordering of the unified faces
* is taken from the ordering of the incident blocks around the
* cut vertex in the BC-tree.
*
* BlockNodes & BlockEdges of each Block in BCTreeNode of
* BlockType and EmbeddedNodes & EmbeddedEdges in
* EmbeddedBCTreeNode::embeddedGraph() are cross-linked with
* IGForwardLink and IGBackwardLink.
*/
void makeDefaultEmbedding();
/** @brief find the geometric embedding based on the given block node
* in the BC-tree and the outer face of the block.
* The root top node can be considered a dummy cut vertex to
* make the root block consistent with the others.
* Also, the top node is used to find visibility representation.
*
* @param rootBlock (in): The top level block from which absorber/
* absorbee classification starts.
*
* @param rootOuterFace (in):
* The face that will become the outer face of the
* geometric embedding in the rootBlock
*
* @param rootTopNode (in):
* The node in EmbeddedNode for the block that will
* become the top node to generate a visibility
* representation for the block.
*
* @remark if rootTopNode is not specified, an arbitrary node incident
* to the outer face is chosen.
* If rootOuterFace is not specified, an arbitrary biggest face
* is chosen.
* If rootBlock is not specified, an arbitrary largest block is
* chosen.
*
* @remark
*
*
*/
void findGeometricEmbedding(
node_list_it_t rootBlock,
node_list_it_t rootOuterFace,
node_list_it_t rootTopNode
);
void findGeometricEmbedding(
node_list_it_t rootBlock, node_list_it_t rootOuterFace);
void findGeometricEmbedding(node_list_it_t rootBlock);
void findGeometricEmbedding();
/** @brief returns the underlying BCTree that holds all the Blocks.
*/
inline BCTree& bcTree();
/** @brief returns the root block in EmbeddedBCTree.
*
* @throws ConstantsEmbeddedBCTree::kExceptionBCTreeRootNotSet if
* the tree is empty, or if findGeometricEmbedding has not been
* called.
*/
inline EmbeddedBCTreeNode& root();
/** @brief returns the ExplorationTree generated by
* findGeometricEmbedding()
*/
inline ExplorationTree& explorationTree();
private:
/** @brief underlying BCTre specified in the constructor.
*/
BCTree* mTree;
/** @brief the root block specified to or determined in
* findGeometricEmbedding.
*/
node_list_it_t mRoot;
/** @brief ExplorationTree generated by findGeometricEmbedding.
*/
ExplorationTree mExpTree;
/** @brief finds the biggest face around the given node (EmbeddedNode)
*
* @param TN (in): EmbeddedNode
* @param cCWIt (out): EmbeddedEdge incident to TN and the face
* clockwise side of the block.
* @param cCCWIt (out): EmbeddedEdge incident to TN and the face
* counter-clockwise side of the block.
*
* @return iterator to the face found
*/
node_list_it_t findBiggestFace(
EmbeddedNode& TN,
edge_list_it_t& eCWIt,
edge_list_it_t& eCCWIt
);
#ifdef UNIT_TESTS
friend class EmbeddedBCTreeTests;
#endif
};
/** @class EmbeddedBCTreeNode
*
* @brief Augumentation of BCTreeNode with the necessary embedding
* information by composition (as opposed to inheritance)
* For the block nodes:
* - Combinatorial embedding of block and its dual.
*
* For the cut-vertex nodes:
* - Face unification groups as in a set of ordered list of
* edge pointers to EmbeddedBCTreeEdge.
*
* After calling findGeometricEmbedding():
* For the block nodes:
* - Outer face
* - Top node (cut vertex) used to make a visibility representation.
* - If the block is flipped or not
*/
class EmbeddedBCTreeNode : public Node {
public:
/** @brief returns the type of the node based on the underlying
* BCTreeNode: BlockType or CutVertexType.
*/
inline enum BCTreeNode::type type();
/** @brief returns the embedding of the block.
* valid if this is BlockType.
*/
inline EmbeddedGraph& embeddedGraph();
/** @brief returns the dual graph of the embedding of the block
* valid if this is BlockType.
*/
inline DualGraph& dualGraph();
/** @brief returns the number of face unification groups.
* valid if this is CutVertexType.
*/
inline size_t numUnificationGroups();
/** @brief returns the face unification group specified by the index.
* valid if this is CutVertexType.
*/
inline UnificationGroup& unificationGroup(size_t index);
/** @brief returns the outer face of this block.
* valid if this is BlockType, and
* EmbeddedBCTree::findGeometricEmbedding() has been called.
*/
inline EmbeddedFace& outerFace();
/** @brief returns the top node of this block.
* valid if this is BlockType, and
* EmbeddedBCTree::findGeometricEmbedding() has been called.
*/
inline EmbeddedNode& topNode();
/** @brief called manually if the user of EmbeddedBCTree wants to
* specify the embedding of the block manually.
*
* @param eg (in): embedding
* @param dg (in): dual graph
*
* @throws ConstantsBCTree::kExceptionBCTreeInvalidNodeType
* if this node is not for a block.
*
* @remark IMPORTANT
* BlockNodes & BlockEdges of each Block in BCTreeNode of
* BlockType and EmbeddedNodes & EmbeddedEdges in
* EmbeddedBCTreeNode::embeddedGraph() must be
* cross-linked with IGForwardLink and IGBackwardLink.
*/
inline void setEmbedding(EmbeddedGraph&& eg, DualGraph&& dg);
/** @brief called manually if the user of EmbeddedBCTree wants to
* specify the face unification groups manually.
* The specified unification group is pushed back internally
* to a vector which is indexed by a number.
*
* @param ug (in): unification group.
*
* @throws ConstantsBCTree::kExceptionBCTreeInvalidNodeType
* if this node is not for a cut vertex.
*/
inline void pushBackUnificationGroup(UnificationGroup&& ug);
inline void pushBackUnificationGroup(const UnificationGroup& ug);
inline list<UnificationFaceRef>& unexploredFaces();
private:
EmbeddedBCTreeNode()=delete;
/** @brief constructor with the corresponding BCTreeNode
*/
inline EmbeddedBCTreeNode(BCTreeNode& original);
/** @brief aggregate setter for outer face and top node
* EmbeddedBCTree::findGeometricEmbedding().
*/
inline void setOrientation(
node_list_it_t outerFace, node_list_it_t topNode);
/** @brief type of the underlying BCTreeNode.
* we keep the copy of the type here as IGBackwardLink stack
* may change over time.
*/
enum BCTreeNode::type mType;
/** @brief embedding of the block if this is BlockType.
*/
EmbeddedGraph mEG;
/** @brief dual of the embedding of the block if this is BlockType.
*/
DualGraph mDG;
/** @brief unification groups if this node is of CutVertexType.
*/
vector<UnificationGroup> mUnificationGroups;
/** @brief outer face
*/
node_list_it_t mOuterFace;
/** @brief top node of the visibility representation in embedded graph
* its the copy of the cut vertex at the unification.
*/
node_list_it_t mTopNode;
/** @remark
*/
list<UnificationFaceRef> mUnexploredFaces;
friend class EmbeddedBCTree;
friend std::unique_ptr<EmbeddedBCTreeNode>
std::make_unique<EmbeddedBCTreeNode, BCTreeNode&>(BCTreeNode&);
friend class UnificationFace;
#ifdef UNIT_TESTS
friend class EmbeddedBCTreeTests;
#endif
};
/** @class EmbeddedBCTreeEdge
*
* @brief Augumentation of BCTreeEdge with the necessary embedding
* information by composition (as opposed to inheritance)
* - Copy of the cut vertex (top node) in the block
* - Face to be unified in the specified face unification group.
* in the dual graph of the embedding of the block.
* - Two edges incident to the top node and the face on the
* block, both counter-clockwise side and clockwise side around
* the top node.
* - Indices into the face unification group in the incident
* EmbededBCTreeNode of CutVertexType.
*/
class EmbeddedBCTreeEdge : public Edge {
public:
/** @brief returns the incident node of the block type.
*/
inline EmbeddedBCTreeNode& incidentNodeBlockType();
private:
EmbeddedBCTreeEdge()=delete;
/** @brief constructor with the corresponding BCTreeEdge
*/
inline EmbeddedBCTreeEdge(BCTreeEdge& original);
friend class EmbeddedBCTree;
friend class EmbeddedBCTreeNode;
friend std::unique_ptr<EmbeddedBCTreeEdge>
std::make_unique<EmbeddedBCTreeEdge, BCTreeEdge&>(BCTreeEdge&);
#ifdef UNIT_TESTS
friend class EmbeddedBCTreeTests;
#endif
};
/** @brief internal class to reference a unification face in a unification
* group from an embedded bc-tree node of block type to another
* of cut-vertex.
*/
class UnificationFaceRef {
public:
inline UnificationFaceRef(
EmbeddedBCTreeNode& CVNode, size_t groupIndex, size_t faceIndex);
inline UnificationFace& unificationFace();
inline EmbeddedBCTreeNode& cvNode();
inline UnificationGroup& group();
inline size_t faceIndex();
private:
EmbeddedBCTreeNode& mCVNodeRef;
size_t mGroupIndex;
size_t mFaceIndex;
};
class UnificationFace {
public:
inline UnificationFace(
node_list_it_t nodeInEmbeddedBCTree,
node_list_it_t faceInDG,
node_list_it_t cutVertexInEG,
edge_list_it_t edgeCWInEG,
edge_list_it_t edgeCCWInEG
);
inline virtual ~UnificationFace();
inline EmbeddedBCTreeNode& treeNode();
inline EmbeddedFace& faceInDG();
inline node_list_it_t faceInDGIt();
inline EmbeddedNode& cutVertexInEG();
inline node_list_it_t cutVertexInEGIt();
inline EmbeddedEdge& edgeCCWInEG();
inline edge_list_it_t edgeCCWInEGIt();
inline EmbeddedEdge& edgeCWInEG();
inline edge_list_it_t edgeCWInEGIt();
inline bool roleOfECWReversed();
inline bool operator==(const UnificationFace& rhs) const;
private:
inline void markExplored();
inline void setOrientation();
inline void setBackIt(list<UnificationFaceRef>::iterator it);
/** @brief default constructor used by SortedUnificationGroup */
inline UnificationFace();
/** @brief pointer to the node in embedded bctree */
node_list_it_t mNodeInEmbeddedBCTree;
/** @brief pointer to embedded face to be unified */
node_list_it_t mFaceInDG;
/** @brief pointer to the cut vertex (EmbeddedNode) */
node_list_it_t mCutVertexInEG;
/** @brief the incident edge to the face and the cut vertex
* on the clockwise side to be unified around the cut vertex.
*/
edge_list_it_t mEdgeCWInEG;
/** @brief the incident edge to the face and the cut vertex
* on the counter-clockwise side to be unified around the cut
* vertex.
*/
edge_list_it_t mEdgeCCWInEG;
/** @brief indicates if the orientation of mEdgeCCWInEG -> mEdgeCWInEG
* is different from their natural orientation in the embedding
* of the block.
*/
bool mRoleOfECWReversed;
/** @brief back pointer to the embedded bctree node */
list<UnificationFaceRef>::iterator mUnexploredBackIt;
friend class EmbeddedBCTree;
friend class UnificationGroup;
friend class SortedUnificationGroup;
#ifdef UNIT_TESTS
friend class EmbeddedBCTreeTests;
#endif
};
/** @class UnificationGroup
*
* @brief represents a face unification group.
* It specifies a subset of the incident blocks around the cut vertex
* in the counter-clockwise ordering.
*/
class UnificationGroup {
public:
inline UnificationGroup();
inline virtual ~UnificationGroup();
/** @brief set a face to this face unification group.
*/
inline void push(UnificationFace&& uf);
inline void push(const UnificationFace& uf);
/** @brief get the face at the specified index.
*/
inline UnificationFace& at(size_t index);
/** @brief number of faces stored
*/
inline size_t size();
inline void markExplored();
private:
vector<UnificationFace> mUnificationFaces;
#ifdef UNIT_TESTS
friend class EmbeddedBCTreeTests;
#endif
};
/** @class SortedUnificationGroup
*
* @brief represents a face unification group with the absorber/absorbee
* classification.
*/
class SortedUnificationGroup : public UnificationGroup {
public:
inline SortedUnificationGroup(UnificationGroup& UG, size_t absorberIndex);
inline virtual ~SortedUnificationGroup();
/** @returns the absorber face.
*/
inline UnificationFace& absorber();
/** @brief get the absorbee face at the specified index.
*/
inline UnificationFace& absorbeeAt(size_t index);
/** @brief number of absorbee faces stored
*/
inline size_t absorbeesSize();
/** @brief used in VisRepFinder to specify the first index
* in the second row after split.
*/
size_t mIndexSecondStart;
private:
UnificationFace mAbsorber;
#ifdef UNIT_TESTS
friend class EmbeddedBCTreeTests;
#endif
};
/** @brief inline function definitions */
EmbeddedBCTree::ExplorationTree& EmbeddedBCTree::explorationTree(){
return mExpTree; }
EmbeddedBCTree::ExplorationTree::ExplorationTree(){;}
EmbeddedBCTree::ExplorationTree::ExplorationTree(ExplorationTree&& rhs)
noexcept: Directed::DiGraph(std::move(rhs)), mRoot(std::move(rhs.mRoot)){;}
EmbeddedBCTree::ExplorationTree&
EmbeddedBCTree::ExplorationTree::operator=(ExplorationTree&& rhs) noexcept
{
mRoot = std::move(rhs.mRoot);
DiGraph::operator=(std::move(rhs));
return *this;
}
void EmbeddedBCTree::ExplorationTree::setRoot(node_list_it_t root){
mRoot = root; }
EmbeddedBCTree::ExplorationNode& EmbeddedBCTree::ExplorationTree::root(){
if (numNodes()==0||mRoot==nodes().second) {
throw std::invalid_argument(
ConstantsEmbeddedBCTree::kExceptionBCTreeRootNotSet);
}
return dynamic_cast<ExplorationNode&>(*(*mRoot));
}
EmbeddedBCTree::ExplorationNode::ExplorationNode(EmbeddedBCTreeNode& org):
mNumChildrenProcessed(0)
{
pushIGBackwardLink(org.backIt());
}
void EmbeddedBCTree::ExplorationNode::resetNumChildrenProcessed()
{
mNumChildrenProcessed = 0;
}
void EmbeddedBCTree::ExplorationNode::incrementNumChildrenProcessed()
{
mNumChildrenProcessed++;
}
long EmbeddedBCTree::ExplorationNode::numChildrenProcessed()
{
return mNumChildrenProcessed;
}
vector<SortedUnificationGroup>&
EmbeddedBCTree::ExplorationNode::sortedUnificationGroups()
{
return mSortedUnificationGroups;