57
60
* With each tetrahedron is stored various pieces of information
58
61
* regarding the overall skeletal structure and component structure of
59
* the triangulation. This information will be allocated, calculated
62
* the triangulation. This skeletal information will be allocated, calculated
60
63
* and deallocated by the NTriangulation object containing the
61
64
* corresponding tetrahedra.
63
* Whenever the gluings of tetrahedra are altered, the external routine
64
* responsible for changing the gluings (the routine that calls joinTo()
65
* and unjoin()) <b>must</b> call NTriangulation::gluingsHaveChanged()
66
* for the triangulation containing the tetrahedra concerned; this
67
* will ensure that skeletal information and other properties of the
68
* triangulation are recalculated when necessary.
66
* The management of tetrahedra has changed significantly as of Regina 4.90:
68
* - Users no longer need to call NTriangulation::gluingsHaveChanged()
69
* when gluing or ungluing tetrahedra. This notification is now handled
70
* automatically, and NTriangulation::gluingsHaveChanged() now does nothing.
72
* - You should now create tetrahedra by calling
73
* NTriangulation::newTetrahedron() or
74
* NTriangulation::newTetrahedron(const std::string&), which will
75
* automatically add the tetrahedron to the triangulation. You should
76
* not need to call NTriangulation::addTetrahedron() at all.
78
* - When you remove a tetrahedron using NTriangulation::removeTetrahedron()
79
* or NTriangulation::removeTetrahedronAt(), the tetrahedron will now be
80
* automatically destroyed.
82
* - The old way of adding tetrahedra (creating an NTetrahedron and then
83
* calling NTriangulation::addTetrahedron()) is deprecated, and will
84
* be removed completely in the near future. In the meantime, you may
85
* find that tetrahedra are now added to a triangulation automatically (both
86
* NTriangulation::addTetrahedron() and NTetrahedron::joinTo() will
87
* aggressively try to add nearby tetrahedra that do not already belong to
88
* the current triangulation). This is to avoid tetrahedra and
89
* triangulations being in an inconsistent state. Any redundant calls
90
* to NTriangulation::addTetrahedron() (i.e., when the tetrahedron
91
* already belongs to the triangulation) are harmless, and will have no
94
* These changes are designed to ensure that triangulations and
95
* tetrahedra are always in a consistent state, and to make it more
96
* difficult for users to inadvertently crash the program.
70
class NTetrahedron : public ShareableObject, public NMarkedElement {
98
class REGINA_API NTetrahedron : public ShareableObject, public NMarkedElement {
72
100
NTetrahedron* tetrahedra[4];
73
101
/**< Stores the tetrahedra glued to each face of this
77
105
if face \c f lies on the triangulation boundary. Faces are
78
106
numbered from 0 to 3 inclusive, where face \c i is opposite
80
NPerm tetrahedronPerm[4];
108
NPerm4 tetrahedronPerm[4];
81
109
/**< Stores the corresponence between vertices of this
82
110
tetrahedron and adjacent tetrahedra. If face \c f is
83
111
joined to another tetrahedron, <tt>tetrahedronPerm[f]</tt>
101
129
int tmpOrientation[4];
102
130
/**< Temporary array used to represent orientations
103
* of faces and vertex link triangles when calculating
104
* orientability of boundary components and vertex links.
105
* Each orientation will be +/-1.
106
* The array should only be used within these
107
* orientability routines, and its contents afterwards are
109
NPerm edgeMapping[6];
131
of faces and vertex link triangles when calculating
132
orientability of boundary components and vertex links.
133
Each orientation will be +/-1.
134
The array should only be used within these
135
orientability routines, and its contents afterwards are
137
NPerm4 vertexMapping[4];
138
/**< Maps 0 to each vertex of this tetrahedron in turn whilst
139
mapping (1,2,3) in a suitably "orientation-preserving" way,
140
as described in getVertexMapping(). */
141
NPerm4 edgeMapping[6];
110
142
/**< Maps (0,1) to the vertices of this tetrahedron that form
111
each edge, as described in getEdgeMapping(). */
112
NPerm faceMapping[4];
143
each edge whilst mapping (2,3) in a suitably "orientation-
144
preserving" way, as described in getEdgeMapping(). */
145
NPerm4 faceMapping[4];
113
146
/**< Maps (0,1,2) to the vertices of this tetrahedron that form
114
147
each face, as described in getFaceMapping(). */
115
148
int tetOrientation;
116
149
/**< The orientation of this tetrahedron in the triangulation.
117
150
This will either be 1 or -1. */
152
/**< The triangulation to which this tetrahedron belongs. */
118
153
NComponent* component;
119
154
/**< The component to which this tetrahedron belongs in the
120
155
triangulation. */
124
159
* Creates a new tetrahedron with empty description and no
125
160
* faces joined to anything.
161
* The new tetrahedron will not belong to any triangulation.
163
* \deprecated Users should now create new tetrahedra by calling
164
* NTriangulation::newTetrahedron(). For details, see the changes in
165
* tetrahedron management outlined in the NTetrahedron class notes.
129
169
* Creates a new tetrahedron with the given description and
130
170
* no faces joined to anything.
171
* The new tetrahedron will not belong to any triangulation.
173
* \deprecated Users should now create new tetrahedra by calling
174
* NTriangulation::newTetrahedron(const std::string&). For details,
175
* see the changes in tetrahedron management outlined in the
176
* NTetrahedron class notes.
132
178
* @param desc the description to give the new tetrahedron.
271
317
* tetrahedron. The other tetrahedron involved will be
272
318
* automatically updated.
274
* \warning Note that NTriangulation::gluingsHaveChanged() will
275
* have to be called after all joins and unjoins have been performed.
320
* Neither tetrahedron needs to belong to a triangulation (i.e.,
321
* you can join tetrahedra together before or after calling
322
* NTriangulation::addTetrahedron()). However, if both
323
* tetrahedra do belong to a triangulation then it must be the
324
* \e same triangulation.
326
* \pre This and the given tetrahedron do not belong to
327
* different triangulations.
277
328
* \pre The given face of this tetrahedron is not currently glued to
279
330
* \pre The face of the other tetrahedron that will be glued to the
281
332
* \pre If the other tetrahedron involved is this tetrahedron, we are
282
333
* not attempting to glue a face to itself.
335
* \warning If one tetrahedron belongs to a triangulation but
336
* the other does not, the missing tetrahedron (along with anything
337
* that it is joined to, directly or indirectly) will be automatically
338
* added to the triangulation. This is new behaviour as of
339
* Regina 4.90; see the NTetrahedron class notes for details.
284
341
* @param myFace the face of this tetrahedron that will be glued
285
342
* to the given other tetrahedron. This
286
343
* should be between 0 and 3 inclusive, where face \c i is
295
352
* will be glued to the given face of this tetrahedron will be
296
353
* face number <tt>gluing[myFace]</tt>.
298
void joinTo(int myFace, NTetrahedron* you, NPerm gluing);
355
void joinTo(int myFace, NTetrahedron* you, NPerm4 gluing);
300
357
* Unglues the given face of this tetrahedron from whatever is
301
358
* joined to it. The other tetrahedron involved (possibly this
302
359
* one) will be automatically updated.
304
* \warning Note that NTriangulation::gluingsHaveChanged() will
305
* have to be called after all joins and unjoins have been performed.
307
361
* \pre The given face of this tetrahedron has some tetrahedron
308
362
* (possibly this one) glued to it.
378
* Returns the triangulation to which this tetrahedron belongs.
380
* @return the triangulation containing this tetrahedron.
382
NTriangulation* getTriangulation() const;
324
385
* Returns the triangulation component to which this tetrahedron
327
* \pre This tetrahedron belongs to a triangulation whose skeletal
328
* information has already been calculated.
388
* As of Regina 4.90, if the skeletal information for the
389
* triangulation has not been computed then this will be done
390
* automatically. There is no need for users to explicitly
391
* recompute the skeleton themselves.
393
* \pre This tetrahedron belongs to a triangulation (i.e., it
394
* was created using NTriangulation::newTetrahedron() or added
395
* using NTriangulation::addTetrahedron()).
330
397
* @return the component containing this tetrahedron.
334
401
* Returns the vertex in the triangulation skeleton
335
402
* corresponding to the given vertex of this tetrahedron.
337
* \pre This tetrahedron belongs to a triangulation whose skeletal
338
* information has already been calculated.
404
* As of Regina 4.90, if the skeletal information for the
405
* triangulation has not been computed then this will be done
406
* automatically. There is no need for users to explicitly
407
* recompute the skeleton themselves.
409
* \pre This tetrahedron belongs to a triangulation (i.e., it
410
* was created using NTriangulation::newTetrahedron() or added
411
* using NTriangulation::addTetrahedron()).
340
413
* @param vertex the vertex of this tetrahedron to examine.
341
414
* This should be between 0 and 3 inclusive.
347
420
* Returns the edge in the triangulation skeleton
348
421
* corresponding to the given edge of this tetrahedron.
350
* \pre This tetrahedron belongs to a triangulation whose skeletal
351
* information has already been calculated.
423
* See NEdge::edgeNumber and NEdge::edgeVertex for
424
* the conventions of how edges are numbered within a tetrahedron.
426
* As of Regina 4.90, if the skeletal information for the
427
* triangulation has not been computed then this will be done
428
* automatically. There is no need for users to explicitly
429
* recompute the skeleton themselves.
431
* \pre This tetrahedron belongs to a triangulation (i.e., it
432
* was created using NTriangulation::newTetrahedron() or added
433
* using NTriangulation::addTetrahedron()).
353
435
* @param edge the edge of this tetrahedron to examine.
354
436
* This should be between 0 and 5 inclusive.
360
442
* Returns the face in the triangulation skeleton
361
443
* corresponding to the given face of this tetrahedron.
363
* \pre This tetrahedron belongs to a triangulation whose skeletal
364
* information has already been calculated.
445
* As of Regina 4.90, if the skeletal information for the
446
* triangulation has not been computed then this will be done
447
* automatically. There is no need for users to explicitly
448
* recompute the skeleton themselves.
450
* \pre This tetrahedron belongs to a triangulation (i.e., it
451
* was created using NTriangulation::newTetrahedron() or added
452
* using NTriangulation::addTetrahedron()).
366
454
* @param face the face of this tetrahedron to examine.
367
455
* This should be between 0 and 3 inclusive, where face \c i
372
460
NFace* getFace(int face) const;
462
* Returns a permutation that maps 0 to the given vertex of this
463
* tetrahedron, and that maps (1,2,3) to the three remaining vertices
464
* in the following "orientation-preserving" fashion.
466
* The images of (1,2,3) under this permutation imply an
467
* orientation for the tetrahedron face opposite the given vertex.
468
* These orientations will be consistent for all tetrahedra
469
* containing the given vertex, if this is possible (i.e., if
470
* the vertex link is orientable).
472
* Note that there are still arbitrary decisions to be made for
473
* the images of (1,2,3), since there will always be three possible
474
* mappings that yield the correct orientation.
476
* As of Regina 4.90, if the skeletal information for the
477
* triangulation has not been computed then this will be done
478
* automatically. There is no need for users to explicitly
479
* recompute the skeleton themselves.
481
* \pre This tetrahedron belongs to a triangulation (i.e., it
482
* was created using NTriangulation::newTetrahedron() or added
483
* using NTriangulation::addTetrahedron()).
485
* @param vertex the vertex of this tetrahedron to examine.
486
* This should be between 0 and 3 inclusive.
487
* @return a permutation that maps 0 to the given vertex of this
488
* tetrahedron, with the properties outlined above.
490
NPerm4 getVertexMapping(int vertex) const;
374
492
* Examines the given edge of this tetrahedron, and returns a
375
* mapping from the "canonical" vertices of the corresponding
376
* edge of the triangulation to the matching vertices of this
493
* permutation that maps the "canonical" vertices (0,1) of the
494
* corresponding edge of the triangulation to the matching vertices
495
* of this tetrahedron. This permutation also maps (2,3) to the
496
* remaining tetrahedron vertices in an "orientation-preserving"
497
* way, as described below.
379
499
* In detail: Suppose several edges of several tetrahedra are
380
500
* identified within the overall triangulation. We call this a
412
532
* (for internal edges this path is actually a cycle, and the
413
533
* starting point is arbitrary).
415
* \pre This tetrahedron belongs to a triangulation whose
416
* skeletal information has already been calculated.
535
* As of Regina 4.90, if the skeletal information for the
536
* triangulation has not been computed then this will be done
537
* automatically. There is no need for users to explicitly
538
* recompute the skeleton themselves.
540
* \pre This tetrahedron belongs to a triangulation (i.e., it
541
* was created using NTriangulation::newTetrahedron() or added
542
* using NTriangulation::addTetrahedron()).
418
544
* @param edge the edge of this tetrahedron to examine.
419
545
* This should be between 0 and 5 inclusive.
420
546
* @return a mapping from vertices (0,1) of the requested
421
547
* triangulation edge to the vertices of this tetrahedron.
423
NPerm getEdgeMapping(int edge) const;
549
NPerm4 getEdgeMapping(int edge) const;
425
551
* Examines the given face of this tetrahedron, and returns a
426
552
* mapping from the "canonical" vertices of the corresponding
448
574
* course that we pass the correct face number in each case to
449
575
* getFaceMapping()).
451
* \pre This tetrahedron belongs to a triangulation whose
452
* skeletal information has already been calculated.
577
* As of Regina 4.90, if the skeletal information for the
578
* triangulation has not been computed then this will be done
579
* automatically. There is no need for users to explicitly
580
* recompute the skeleton themselves.
582
* \pre This tetrahedron belongs to a triangulation (i.e., it
583
* was created using NTriangulation::newTetrahedron() or added
584
* using NTriangulation::addTetrahedron()).
454
586
* @param face the face of this tetrahedron to examine.
455
587
* This should be between 0 and 3 inclusive.
456
588
* @return a mapping from vertices (0,1,2) of the requested face
457
589
* to the vertices of this tetrahedron.
459
NPerm getFaceMapping(int face) const;
591
NPerm4 getFaceMapping(int face) const;
461
593
* Returns the orientation of this tetrahedron in the
469
601
* In a non-orientable component, orientations are still +1 and
470
602
* -1 but no further guarantees can be made.
472
* \pre This tetrahedron belongs to a triangulation whose skeletal
473
* information has already been calculated.
604
* As of Regina 4.90, if the skeletal information for the
605
* triangulation has not been computed then this will be done
606
* automatically. There is no need for users to explicitly
607
* recompute the skeleton themselves.
609
* \pre This tetrahedron belongs to a triangulation (i.e., it
610
* was created using NTriangulation::newTetrahedron() or added
611
* using NTriangulation::addTetrahedron()).
475
613
* @return +1 or -1 according to the orientation of this tetrahedron.
515
658
return tetrahedronPerm[face][face];
518
inline NPerm NTetrahedron::adjacentGluing(int face) const {
661
inline NPerm4 NTetrahedron::adjacentGluing(int face) const {
519
662
return tetrahedronPerm[face];
522
inline NPerm NTetrahedron::getAdjacentTetrahedronGluing(int face) const {
665
inline NPerm4 NTetrahedron::getAdjacentTetrahedronGluing(int face) const {
523
666
// Deprecated! Finally.
524
667
return tetrahedronPerm[face];
670
inline NTriangulation* NTetrahedron::getTriangulation() const {
527
674
inline NComponent* NTetrahedron::getComponent() const {
675
if (! tri->calculatedSkeleton)
676
tri->calculateSkeleton();
528
677
return component;
531
680
inline NVertex* NTetrahedron::getVertex(int vertex) const {
681
if (! tri->calculatedSkeleton)
682
tri->calculateSkeleton();
532
683
return vertices[vertex];
535
686
inline NEdge* NTetrahedron::getEdge(int edge) const {
687
if (! tri->calculatedSkeleton)
688
tri->calculateSkeleton();
536
689
return edges[edge];
539
692
inline NFace* NTetrahedron::getFace(int face) const {
693
if (! tri->calculatedSkeleton)
694
tri->calculateSkeleton();
540
695
return faces[face];
543
inline NPerm NTetrahedron::getEdgeMapping(int edge) const {
698
inline NPerm4 NTetrahedron::getVertexMapping(int vertex) const {
699
if (! tri->calculatedSkeleton)
700
tri->calculateSkeleton();
701
return vertexMapping[vertex];
704
inline NPerm4 NTetrahedron::getEdgeMapping(int edge) const {
705
if (! tri->calculatedSkeleton)
706
tri->calculateSkeleton();
544
707
return edgeMapping[edge];
547
inline NPerm NTetrahedron::getFaceMapping(int face) const {
710
inline NPerm4 NTetrahedron::getFaceMapping(int face) const {
711
if (! tri->calculatedSkeleton)
712
tri->calculateSkeleton();
548
713
return faceMapping[face];
551
716
inline int NTetrahedron::orientation() const {
717
if (! tri->calculatedSkeleton)
718
tri->calculateSkeleton();
552
719
return tetOrientation;