236 const node& n =
nullptr);
371 if (G.numberOfEdges() <= 2) {
372 edge e = G.firstEdge();
380 compute(G, nodeLength, edgeLength, &spqrTree, edgeLengthSkel);
384 node bigFaceMu =
nullptr;
388 T sizeMu = largestFaceInSkeleton(spqrTree, mu, nodeLength, edgeLengthSkel);
389 if (sizeMu > biggestFace) {
390 biggestFace = sizeMu;
400 bool alreadySeenMu =
false;
401 for (
int j = 0; j < i && !alreadySeenMu; j++) {
402 if (mus[i] == mus[j]) {
403 alreadySeenMu =
true;
413 largestFaceContainingNode(spqrTree, mus[i], n, nodeLength, edgeLengthSkel);
414 if (sizeInMu > biggestFace) {
415 biggestFace = sizeInMu;
431 adjExternal =
nullptr;
434 expandEdge(spqrTree, treeNodeTreated, bigFaceMu,
nullptr, nodeLength, edgeLengthSkel, newOrder,
435 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, adjExternal, n);
437 for (
node v : G.nodes) {
438 G.sort(v, newOrder[v]);
459 if (!treeNodeTreated[twinNT]) {
462 m_leftNode = twinE->
source();
464 m_leftNode = twinE->
target();
468 adjBeforeNodeArraySource[twinNT] =
before;
470 adjBeforeNodeArrayTarget[twinNT] =
before;
474 expandEdge(spqrTree, treeNodeTreated, twinNT, m_leftNode, nodeLength, edgeLength,
475 newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, adjExternal);
478 if (ae->
theEdge() == referenceEdge) {
481 adjBeforeNodeArraySource[mu] =
before;
485 adjBeforeNodeArrayTarget[mu] =
before;
491 before = adjBeforeNodeArraySource[twinNT];
493 before = adjBeforeNodeArrayTarget[twinNT];
500 if (origNode == origEdge->
source()) {
524 treeNodeTreated[mu] =
true;
526 switch (spqrTree.
typeOf(mu)) {
528 expandEdgeSNode(spqrTree, treeNodeTreated, mu, leftNode, nodeLength, edgeLength, newOrder,
529 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, adjExternal);
532 expandEdgePNode(spqrTree, treeNodeTreated, mu, leftNode, nodeLength, edgeLength, newOrder,
533 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, adjExternal);
536 expandEdgeRNode(spqrTree, treeNodeTreated, mu, leftNode, nodeLength, edgeLength, newOrder,
537 adjBeforeNodeArraySource, adjBeforeNodeArrayTarget, adjExternal, n);
557 startAdjEntry = e->adjSource();
563 startAdjEntry = leftNode->
lastAdj();
565 startAdjEntry = leftNode->
firstAdj();
579 if (referenceEdge && leftNode == referenceEdge->
source()) {
580 before = adjBeforeNodeArraySource[mu];
581 }
else if (referenceEdge) {
582 before = adjBeforeNodeArrayTarget[mu];
586 bool firstStep =
true;
587 while (firstStep || ae != startAdjEntry) {
591 if (ae->
theEdge() == referenceEdge) {
594 adjBeforeNodeArraySource[mu] =
before;
596 adjBeforeNodeArrayTarget[mu] =
before;
599 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
600 edgeLength, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
611 if (ae->
theEdge() == referenceEdge) {
614 adjBeforeNodeArraySource[mu] = beforeSource;
616 adjBeforeNodeArrayTarget[mu] = beforeSource;
619 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
620 edgeLength, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
643 edge altReferenceEdge =
nullptr;
645 node m_leftNode = leftNode;
649 m_leftNode = *(nodeList.begin());
653 if (!referenceEdge) {
656 altReferenceEdge = e;
669 edge longestEdge =
nullptr;
671 if (e == referenceEdge || e == altReferenceEdge) {
674 if (!longestEdge || edgeLength[mu][e] > edgeLength[mu][longestEdge]) {
683 for (
int i = 0; i < 2; ++i) {
690 before = beforeAltRefEdge;
694 if (n == referenceEdge->
source()) {
695 before = adjBeforeNodeArraySource[mu];
697 before = adjBeforeNodeArrayTarget[mu];
707 if (longestEdge->
source() == n) {
713 if (referenceEdge && S.
isVirtual(longestEdge)) {
715 if (longestEdge->
source() == n) {
716 if (referenceEdge->
source() == n) {
717 adjBeforeNodeArrayTarget[nu] = adjBeforeNodeArrayTarget[mu];
719 adjBeforeNodeArrayTarget[nu] = adjBeforeNodeArraySource[mu];
722 if (referenceEdge->
source() == n) {
723 adjBeforeNodeArraySource[nu] = adjBeforeNodeArrayTarget[mu];
725 adjBeforeNodeArraySource[nu] = adjBeforeNodeArraySource[mu];
730 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
731 edgeLength, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
738 for (
edge e : edgeList) {
739 if (e == referenceEdge || e == longestEdge || e == altReferenceEdge
745 if (referenceEdge !=
nullptr && e->
source() == n) {
746 if (referenceEdge->
source() == n) {
747 adjBeforeNodeArrayTarget[nu] = adjBeforeNodeArrayTarget[mu];
749 adjBeforeNodeArrayTarget[nu] = adjBeforeNodeArraySource[mu];
751 }
else if (referenceEdge) {
752 if (referenceEdge->
source() == n) {
753 adjBeforeNodeArraySource[nu] = adjBeforeNodeArrayTarget[mu];
755 adjBeforeNodeArraySource[nu] = adjBeforeNodeArraySource[mu];
761 if (e->source() == n) {
767 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
768 edgeLength, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
773 for (
edge e : edgeList) {
774 if (e == referenceEdge || e == longestEdge || e == altReferenceEdge
781 if (e->source() == n) {
787 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
788 edgeLength, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
792 for (
edge e : rightEdgeOrder) {
793 if (e->source() == n) {
799 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
800 edgeLength, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
807 if (longestEdge->
source() == n) {
813 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
814 edgeLength, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
820 if (n == referenceEdge->
source()) {
821 adjBeforeNodeArraySource[mu] =
before;
823 adjBeforeNodeArrayTarget[mu] =
before;
830 newLeftNode = m_leftNode;
833 if (altReferenceEdge->
source() == n) {
839 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, newLeftNode, nodeLength,
840 edgeLength, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
843 if (i == 0 && S.
isVirtual(altReferenceEdge)) {
845 if (altReferenceEdge->
source() == n) {
846 beforeAltRefEdge = adjBeforeNodeArrayTarget[nu];
848 beforeAltRefEdge = adjBeforeNodeArraySource[nu];
867 face maxFaceContEdge =
nullptr;
873 for (
face f : combinatorialEmbedding.
faces) {
874 bool containsVirtualEdgeOrN =
false;
875 adjEntry this_m_adjExternal =
nullptr;
880 if ((n ==
nullptr && (ae->
theEdge() == referenceEdge || !referenceEdge))
882 containsVirtualEdgeOrN =
true;
884 this_m_adjExternal = ae;
889 this_m_adjExternal = ae;
895 if (containsVirtualEdgeOrN && this_m_adjExternal && sizeOfFace > bigFaceSize) {
896 maxFaceNodes = faceNodes;
897 bigFaceSize = sizeOfFace;
899 m_adjExternal = this_m_adjExternal;
920 if (leftNode == referenceEdge->
source()) {
921 succ_virtualEdge_leftNode = referenceEdge->
adjSource()->
succ();
923 succ_virtualEdge_leftNode = referenceEdge->
adjTarget()->
succ();
925 if (!succ_virtualEdge_leftNode) {
926 succ_virtualEdge_leftNode = leftNode->
firstAdj();
929 bool succVELNAEInExtFace =
false;
931 if (aeExtFace->
theEdge() == succ_virtualEdge_leftNode->
theEdge()) {
932 succVELNAEInExtFace =
true;
937 if (!succVELNAEInExtFace) {
940 for (
adjEntry ae = v->firstAdj(); ae; ae = ae->
succ()) {
945 adjMaxFace = adjMaxFace->
twin();
952 start_ae = adjMaxFace;
954 if (start_ae->
theEdge() == referenceEdge) {
959 }
while (start_ae != adjMaxFace);
961 start_ae = adjMaxFace;
968 bool firstStep =
true;
969 bool after_start_ae =
true;
970 for (
adjEntry ae = start_ae; firstStep || ae != start_ae;
971 after_start_ae = after_start_ae && ae->
succ(),
973 : (!ae->faceCycleSucc() ? adjMaxFace : ae->
faceCycleSucc())) {
978 nodeTreated[ae->theNode()] =
true;
982 edge vE = (ae->theEdge() == referenceEdge) ? referenceEdge : ae->theEdge();
983 node nu = (ae->theEdge() == referenceEdge) ? mu : S.
twinTreeNode(ae->theEdge());
985 if (ae->theNode() == vE->
source()) {
986 before = adjBeforeNodeArraySource[nu];
988 before = adjBeforeNodeArrayTarget[nu];
992 bool after_ae =
true;
994 if (ae->theEdge() == referenceEdge) {
996 m_start_ae = ae->
succ();
1004 for (
adjEntry aeN = m_start_ae; after_ae || aeN != m_start_ae;
1005 after_ae = after_ae && aeN->
succ(),
1006 aeN = after_ae ? aeN->
succ()
1007 : (!aeN->succ() ? ae->theNode()->firstAdj() : aeN->succ())) {
1008 node m_leftNode =
nullptr;
1009 if (S.
isVirtual(aeN->theEdge()) && aeN->theEdge() != referenceEdge) {
1015 bool succInExtFace =
false;
1016 bool aeNInExtFace =
false;
1018 aeExtFace = adjMaxFace;
1021 succInExtFace =
true;
1026 if (aeExtFace->
theEdge() == aeN->theEdge()) {
1027 aeNInExtFace =
true;
1028 if (succInExtFace) {
1033 }
while (aeExtFace != adjMaxFace);
1034 if (aeNInExtFace && succInExtFace) {
1035 m_leftNode = aeN->twinNode();
1037 m_leftNode = aeN->theNode();
1041 if (referenceEdge) {
1042 if (aeN->theEdge()->source() == aeN->theNode()) {
1043 if (aeN->theEdge()->target() == referenceEdge->
source()) {
1044 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArraySource[mu];
1045 }
else if (aeN->theEdge()->target() == referenceEdge->
target()) {
1046 adjBeforeNodeArrayTarget[twinTN] = adjBeforeNodeArrayTarget[mu];
1049 if (aeN->theEdge()->source() == referenceEdge->
source()) {
1050 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArraySource[mu];
1051 }
else if (aeN->theEdge()->source() == referenceEdge->
target()) {
1052 adjBeforeNodeArraySource[twinTN] = adjBeforeNodeArrayTarget[mu];
1058 adjEntryForNode(aeN,
before, spqrTree, treeNodeTreated, mu, m_leftNode, nodeLength,
1059 edgeLength, newOrder, adjBeforeNodeArraySource, adjBeforeNodeArrayTarget,
1065 if (!maxFaceNodes.search(aeN->twinNode()).valid()) {
1066 node orig_aeN_twin_theNode = S.
original(aeN->twinNode());
1067 buffer[aeN->theEdge()] = newOrder[orig_aeN_twin_theNode];
1068 newOrder[orig_aeN_twin_theNode].clear();
1076 if (nodeTreated[v]) {
1081 nodeTreated[v] =
true;
1083 for (
adjEntry ae = v->firstAdj(); ae; ae = ae->
succ()) {
1084 if (buffer[ae->theEdge()].empty()) {
1085 adjEntryForNode(ae,
before, spqrTree, treeNodeTreated, mu, ae->theNode(),
1086 nodeLength, edgeLength, newOrder, adjBeforeNodeArraySource,
1087 adjBeforeNodeArrayTarget, adjExternal);
1089 if (!nodeTreated[ae->twinNode()]) {
1090 node orig_ae_twin_theNode = S.
original(ae->twinNode());
1091 buffer[ae->theEdge()] = newOrder[orig_ae_twin_theNode];
1092 newOrder[orig_ae_twin_theNode].clear();
1095 buffer[ae->theEdge()].reverse();
1098 before = newOrder[v_original].pushFront(*it);
1100 before = newOrder[v_original].insertBefore(*it,
before);
1113 if (G.numberOfNodes() <= 1 || G.numberOfEdges() <= 2) {
1119 edgeLengthSkel.init(spqrTree->
tree());
1124 edgeLengthSkel[v][e] = 0;
1132 bottomUpTraversal(*spqrTree, spqrTree->
rootNode(), nodeLength, edgeLengthSkel);
1134 topDownTraversal(*spqrTree, spqrTree->
rootNode(), nodeLength, edgeLengthSkel);
1142 if (G.numberOfEdges() == 1) {
1143 edge e = G.firstEdge();
1144 return edgeLength[e] + nodeLength[e->
source()] + nodeLength[e->
target()];
1146 if (G.numberOfEdges() == 2) {
1147 edge e1 = G.firstEdge();
1149 return edgeLength[e1] + edgeLength[e2] + nodeLength[e1->
source()] + nodeLength[e1->
target()];
1153 return computeSize(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
1162 if (G.numberOfEdges() == 1) {
1163 edge e = G.firstEdge();
1164 return edgeLength[e] + nodeLength[e->
source()] + nodeLength[e->
target()];
1166 if (G.numberOfEdges() == 2) {
1167 edge e1 = G.firstEdge();
1169 return edgeLength[e1] + edgeLength[e2] + nodeLength[e1->
source()] + nodeLength[e1->
target()];
1175 edgeLengthSkel.init(spqrTree->
tree());
1180 edgeLengthSkel[v][e] = 0;
1188 bottomUpTraversal(*spqrTree, spqrTree->
rootNode(), nodeLength, edgeLengthSkel);
1190 topDownTraversal(*spqrTree, spqrTree->
rootNode(), nodeLength, edgeLengthSkel);
1195 T sizeMu = largestFaceInSkeleton(*spqrTree, mu, nodeLength, edgeLengthSkel);
1196 if (sizeMu > biggestFace) {
1197 biggestFace = sizeMu;
1209 if (G.numberOfEdges() == 1) {
1210 edge e = G.firstEdge();
1211 return edgeLength[e] + nodeLength[e->
source()] + nodeLength[e->
target()];
1213 if (G.numberOfEdges() == 2) {
1214 edge e1 = G.firstEdge();
1216 return edgeLength[e1] + edgeLength[e2] + nodeLength[e1->
source()] + nodeLength[e1->
target()];
1220 compute(G, nodeLength, edgeLength, &spqrTree, edgeLengthSkel);
1221 return computeSize(G, n, nodeLength, edgeLength, &spqrTree, edgeLengthSkel);
1228 compute(G, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
1229 return computeSize(G, n, nodeLength, edgeLength, spqrTree, edgeLengthSkel);
1238 if (G.numberOfEdges() == 1) {
1239 edge e = G.firstEdge();
1240 return edgeLength[e] + nodeLength[e->
source()] + nodeLength[e->
target()];
1241 }
else if (G.numberOfEdges() == 2) {
1242 edge e1 = G.firstEdge();
1244 return edgeLength[e1] + edgeLength[e2] + nodeLength[e1->
source()] + nodeLength[e1->
target()];
1252 bool alreadySeenMu =
false;
1253 for (
int j = 0; j < i && !alreadySeenMu; j++) {
1254 if (mus[i] == mus[j]) {
1255 alreadySeenMu =
true;
1258 if (alreadySeenMu) {
1263 T sizeInMu = largestFaceContainingNode(*spqrTree, mus[i], n, nodeLength, edgeLengthSkel);
1264 if (sizeInMu > biggestFace) {
1265 biggestFace = sizeInMu;
1282 if (ed->
source() == mu) {
1283 bottomUpTraversal(spqrTree, ed->
target(), nodeLength, edgeLength);
1302 T ell = nodeLength[origRefEdgeSource] + nodeLength[origRefEdgeTarget];
1312 sizeOfFace += edgeLength[nu][eS];
1315 edgeLength[mu][e] = sizeOfFace - ell;
1318 edge longestEdge =
nullptr;
1320 if (ed != er && (!longestEdge || edgeLength[nu][ed] > edgeLength[nu][longestEdge])) {
1324 edgeLength[mu][e] = edgeLength[nu][longestEdge];
1331 T biggestFaceSize = -1;
1332 for (
face f : combinatorialEmbedding.
faces) {
1334 bool containsEr =
false;
1339 sizeOfFace += edgeLength[nu][ae->
theEdge()]
1343 if (containsEr && sizeOfFace > biggestFaceSize) {
1344 biggestFaceSize = sizeOfFace;
1348 edgeLength[mu][e] = biggestFaceSize - ell;
1350 edgeLength[mu][e] = 1;
1364 if (ed->
source() != mu) {
1377 L += edgeLength[mu][ed2];
1383 edgeLength[nu][referenceEdgeOfNu] = L - edgeLength[mu][eSnu]
1388 edge longestEdge =
nullptr;
1391 && (!longestEdge || edgeLength[mu][ed2] > edgeLength[mu][longestEdge])) {
1395 edgeLength[nu][referenceEdgeOfNu] = edgeLength[mu][longestEdge];
1405 T biggestFaceSize = -1;
1406 for (
face f : combinatorialEmbedding.
faces) {
1408 bool containsESnu =
false;
1411 containsESnu =
true;
1416 if (containsESnu && sizeOfFace > biggestFaceSize) {
1417 biggestFaceSize = sizeOfFace;
1420 edgeLength[nu][referenceEdgeOfNu] = biggestFaceSize - edgeLength[mu][eSnu]
1423 edgeLength[nu][referenceEdgeOfNu] = 0;
1427 topDownTraversal(spqrTree, ed->
target(), nodeLength, edgeLength);
1435 bool containsARealEdge =
false;
1440 T biggestFaceSize = -1;
1441 for (
face f : combinatorialEmbedding.
faces) {
1443 bool containingN =
false;
1444 bool m_containsARealEdge =
false;
1450 m_containsARealEdge =
true;
1452 sizeOfFace += edgeLength[mu][ae->
theEdge()];
1455 if (containingN && sizeOfFace > biggestFaceSize) {
1456 biggestFaceSize = sizeOfFace;
1457 containsARealEdge = m_containsARealEdge;
1461 if (!containsARealEdge) {
1464 return biggestFaceSize;
1467 edge longestEdges[2] = {
nullptr,
nullptr};
1469 if (!longestEdges[1] || edgeLength[mu][edgeWalker] > edgeLength[mu][longestEdges[1]]) {
1470 if (!longestEdges[0] || edgeLength[mu][edgeWalker] > edgeLength[mu][longestEdges[0]]) {
1471 longestEdges[1] = longestEdges[0];
1472 longestEdges[0] = edgeWalker;
1474 longestEdges[1] = edgeWalker;
1481 containsARealEdge =
true;
1484 if (!containsARealEdge) {
1488 return edgeLength[mu][longestEdges[0]] + edgeLength[mu][longestEdges[1]];
1498 containsARealEdge =
true;
1500 sizeOfFace += edgeLength[mu][eS];
1503 if (!containsARealEdge) {
1517 bool containsARealEdge =
false;
1522 T biggestFaceSize = -1;
1523 for (
face f : combinatorialEmbedding.
faces) {
1524 bool m_containsARealEdge =
false;
1531 m_containsARealEdge =
true;
1533 sizeOfFace += edgeLength[mu][ae->
theEdge()]
1537 if (sizeOfFace > biggestFaceSize) {
1538 biggestFaceSize = sizeOfFace;
1539 containsARealEdge = m_containsARealEdge;
1543 if (!containsARealEdge) {
1547 return biggestFaceSize;
1550 edge longestEdges[2] = {
nullptr,
nullptr};
1552 if (!longestEdges[1] || edgeLength[mu][edgeWalker] > edgeLength[mu][longestEdges[1]]) {
1553 if (!longestEdges[0] || edgeLength[mu][edgeWalker] > edgeLength[mu][longestEdges[0]]) {
1554 longestEdges[1] = longestEdges[0];
1555 longestEdges[0] = edgeWalker;
1557 longestEdges[1] = edgeWalker;
1564 containsARealEdge =
true;
1567 if (!containsARealEdge) {
1571 return edgeLength[mu][longestEdges[0]] + edgeLength[mu][longestEdges[1]];
1581 containsARealEdge =
true;
1583 sizeOfFace += edgeLength[mu][eS];
1586 if (!containsARealEdge) {