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
|
/**************************************************************************
* *
* Regina - A Normal Surface Theory Calculator *
* Computational Engine *
* *
* Copyright (c) 1999-2011, Ben Burton *
* For further details contact Ben Burton (bab@debian.org). *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
**************************************************************************/
/* end stub */
#include <queue>
#include "triangulation/ntriangulation.h"
namespace regina {
void NTriangulation::makeDoubleCover() {
unsigned long sheetSize = tetrahedra.size();
if (sheetSize == 0)
return;
ChangeEventSpan span(this);
// Create a second sheet of tetrahedra.
NTetrahedron** upper = new NTetrahedron*[sheetSize];
unsigned long i;
for (i = 0; i < sheetSize; i++)
upper[i] = newTetrahedron(tetrahedra[i]->getDescription());
// Reset each tetrahedron orientation.
TetrahedronIterator tit = tetrahedra.begin();
for (i = 0; i < sheetSize; i++) {
(*tit++)->tetOrientation = 0;
upper[i]->tetOrientation = 0;
}
// Run through the upper sheet and recreate the gluings as we
// propagate tetrahedron orientations through components.
std::queue<unsigned long> tetQueue;
/**< Tetrahedra whose orientation must be propagated. */
int face;
unsigned long upperTet;
NTetrahedron* lowerTet;
unsigned long upperAdj;
NTetrahedron* lowerAdj;
int lowerAdjOrientation;
NPerm4 gluing;
for (i = 0; i < sheetSize; i++)
if (upper[i]->tetOrientation == 0) {
// We've found a new component.
// Completely recreate the gluings for this component.
upper[i]->tetOrientation = 1;
tetrahedra[i]->tetOrientation = -1;
tetQueue.push(i);
while (! tetQueue.empty()) {
upperTet = tetQueue.front();
tetQueue.pop();
lowerTet = tetrahedra[upperTet];
for (face = 0; face < 4; face++) {
lowerAdj = lowerTet->adjacentTetrahedron(face);
// See if this tetrahedron is glued to something in the
// lower sheet.
if (! lowerAdj)
continue;
// Make sure we haven't already fixed this gluing in
// the upper sheet.
if (upper[upperTet]->adjacentTetrahedron(face))
continue;
// Determine the expected orientation of the
// adjacent tetrahedron in the lower sheet.
gluing = lowerTet->adjacentGluing(face);
lowerAdjOrientation = (gluing.sign() == 1 ?
-lowerTet->tetOrientation : lowerTet->tetOrientation);
upperAdj = tetrahedronIndex(lowerAdj);
if (lowerAdj->tetOrientation == 0) {
// We haven't seen the adjacent tetrahedron yet.
lowerAdj->tetOrientation = lowerAdjOrientation;
upper[upperAdj]->tetOrientation = -lowerAdjOrientation;
upper[upperTet]->joinTo(face, upper[upperAdj], gluing);
tetQueue.push(upperAdj);
} else if (lowerAdj->tetOrientation ==
lowerAdjOrientation) {
// The adjacent tetrahedron already has the
// correct orientation.
upper[upperTet]->joinTo(face, upper[upperAdj], gluing);
} else {
// The adjacent tetrahedron already has the
// incorrect orientation. Make a cross between
// the two sheets.
lowerTet->unjoin(face);
lowerTet->joinTo(face, upper[upperAdj], gluing);
upper[upperTet]->joinTo(face, lowerAdj, gluing);
}
}
}
}
// Tidy up.
delete[] upper;
}
} // namespace regina
|