This file is indexed.

/usr/include/ITK-4.9/itkGeometricalQuadEdge.hxx is in libinsighttoolkit4-dev 4.9.0-4ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkGeometricalQuadEdge_hxx
#define itkGeometricalQuadEdge_hxx
#include "itkGeometricalQuadEdge.h"
#include "vcl_limits.h"
#include <iostream>

namespace itk
{
/**
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
const typename GeometricalQuadEdge< TVRef, TFRef,
                                    TPrimalData, TDualData, PrimalDual >::OriginRefType
GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::m_NoPoint =
  std::numeric_limits< OriginRefType >::max();

/**
 *   Constructor
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >
::GeometricalQuadEdge() :
  m_Origin(m_NoPoint),
  m_Data(),
  m_DataSet(false),
  m_LineCellIdent(0)
{
}

/**
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::SetLnextRingWithSameLeftFace(
  const DualOriginRefType faceGeom,
  int maxSize)
{
#ifndef NDEBUG
  if ( !this->IsLnextSharingSameFace(maxSize) )
    {
    itkQEDebugMacro("Lnext() edges do NOT share the same Left().");
    return ( false );
    }
#endif

  IteratorGeom it = this->BeginGeomLnext();

  while ( maxSize && ( it != this->EndGeomLnext() ) )
    {
    it.Value()->SetLeft(faceGeom);
    it++;
    maxSize--;
    }

  return ( true );
}

/**
 * \brief Check wether the Lnext() ring of "this" edge is exactly of
 *        size three AND if those three edges all share the same Left().
 * @return Returns true when the Lnext() ring is the one of a triangle.
 *         Returns false otherwise.
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::IsLnextOfTriangle()
{
  return ( this->IsLnextSharingSameFace(3) );
}

/**
 * \brief Check wether the incoming argument is in the Onext() ring
 *        of "this" edge or not.
 * @param b The edge to test.
 * @return Returns true when "this" edge and the incoming argument are
 *         in the same Onext() ring. Returns false otherwise.
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::IsInOnextRing(Self *b)
{
  for ( IteratorGeom it  = this->BeginGeomOnext();
        it != this->EndGeomOnext();
        it++ )
    {
    if ( b == it.Value() )
      {
      return true;
      }
    }
  return false;
}

/**
 * \brief Check wether the incoming argument is in the Lnext() ring
 *        of "this" edge or not.
 * @param b The edge to test.
 * @return Returns true when "this" edge and the incoming argument are
 *         in the same Lnext() ring. Returns false otherwise.
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::IsInLnextRing(Self *b)
{
  for ( IteratorGeom it  = this->BeginGeomLnext();
        it != this->EndGeomLnext();
        it++ )
    {
    if ( b == it.Value() )
      {
      return true;
      }
    }
  return false;
}

/**
 * \brief Check wether edge's Origin is internal to the mesh (as opposed
 *        to being on the boundary) by looking if all the edges in the
 *        Onext() ring have a face set on both their Left() and Right()
 *        side.
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool
GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >
::IsOriginInternal() const
{
  ConstIteratorGeom it = this->BeginGeomOnext();

  while ( it != this->EndGeomOnext() )
    {
    typedef typename ConstIteratorGeom::QuadEdgeType QuadEdgeType;
    const QuadEdgeType *value = it.Value();
    if ( !value->IsInternal() ) { return false; }
    ++it;
    }
  return true;
}

/**
 * \brief Consider the first few edges in Lnext() ring of "this" edge.
 *         Check wether those edges all share the same Left().
 * @param  maxSize Looks at most maxSize edges in the Lnext() ring.
 * @return Returns true when the Lnext() ring share THE same
 *         Left() faces. Return false otherwise.
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::IsLnextSharingSameFace(int maxSize)
{
  IteratorGeom it = this->BeginGeomLnext();

  while ( maxSize && ( it != this->EndGeomLnext() ) )
    {
    // The condition isn't complicated: if left faces aren't set,
    // continue, if just one is set return false, if both are set
    // check if the face is the same
    bool facesAreNotSet = !this->IsLeftSet() && !it.Value()->IsLeftSet();
    bool facesAreTheSame = this->GetLeft() == it.Value()->GetLeft();
    bool facesAreSet = this->IsLeftSet() && it.Value()->IsLeftSet();
    //
    // FIXME: This boolean expression can be simplified.
    // ALEX : what about the version below ?
    //
    // if ( this->IsLeftSet() )         // one left set
    // {
    //     if (it.Value()->IsLeftSet()) // two left set
    //     {
    //         if( !(this->GetLeft() == it.Value()->GetLeft()) )
    //          {
    //              return( false );    // not same face
    //           }
    //      }
    //      else                        // only one set
    //      {
    //          return( false );
    //       }
    // }
    // else // one not set
    // {
    //     if(it.Value()->IsLeftSet()) // only one set
    //     {
    //         return( false );
    //     }
    // }
    //
    if ( !( facesAreNotSet || ( facesAreSet && facesAreTheSame ) ) )
      {
      return ( false );
      }
    it++;
    maxSize--;
    }

  if ( it != this->EndGeomLnext() )
    {
    // The Lnext ring is bigger than the caller expected
    return ( false );
    }
  return ( true );
}

/**
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
typename GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::Self *
GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::GetNextBorderEdgeWithUnsetLeft(Self *edgeTest)
{
  // Definition: an edge is said to be a boundary edge when it is adjacent to
  // noface i.e. when at least one of the faces edge->GetLeft() or
  // edge->GetRight() is unset.  Definition: an point is said to be a boundary
  // point when at least one of the edges of it's Onext() ring is a boundary
  // edge.
  //
  // Assume "this" edge belongs to a triangulation (i.e. it belongs to a QEMesh
  // which represents a 2-manifold) which possesses a boundary.  Assume "this"
  // edge instance is a boundary edge. Let us denote by P the point which is
  // the origin of "this" edge i.e. P is this->Origin().  By definition P is a
  // boundary point.  Then AT LEAST two [see the note below] edges of the
  // Onext() ring of P [which all have the point P as Origin()] are themselves
  // boundary edges. And among those boundary edges AT LEAST one has it's
  // Left() face unset.  By iterating over the Onext() ring (which defines a
  // local ordering on edges) this method searches for the first edge whose
  // Left() face is unset AND which is encountered AFTER edgeTest.
  //
  // @param edgeTest When present, this edge will be considered as
  //        the entry edge in the Onext() ring. When absent it shall
  //        be defaulted to "this" edge. (see the warning below).
  // @return When "this" edge is a boundary edge, return the first
  //         edge in "this" Onext() ring whose Left() face is unset
  //         AND located after edgeTest.
  //         When "this" edge is NOT a boundary edge the 0 is
  //         returned.
  // @warning When the Mesh possessing "this" edge is a 2-manifold
  //          then result of this method is unique in the sense that
  //          it is independent from the edgeTest parameter.
  //          But when the Mesh is not 2-manifold (this state can
  //          happen at intermediary stages of the building process,
  //          or during "surgical" operations on the Mesh, and
  //          even though the Mesh represents a triangulation)
  //          the result of this method is not unique in the sense
  //          that the result depends on the edgeTest parameter.
  //          Let us illusatre this dependence by considering a
  //          Mesh (which is a triangulation) which is not a 2-manifold.
  //          Assume the point P (the origin of "this" edge i.e.
  //          P = this->Originv()) is TWICE on the border i.e. it
  //          is adjacent twice to noface. We can consider the situation
  //          of the following diagram, which depicts some Onext()
  //          ring around point P:
  //
  //                       \         /                               //
  //                        \   *   /                                //
  //                        i3     b2              counter-clockwise //
  //                  *       \   /   NO FACE      Onext() order.    //
  //                           \ /                                   //
  //                 ----b4-----P----b1------                        //
  //                           /|\                                   //
  //               NO FACE    / | \                                  //
  //                         /  |  \    *  <------ a * indicates the //
  //                        /   |   \         the presence of a face //
  //                       /    |    \                               //
  //                     b5    i6     i7                             //
  //                     /   *  |  *   \                             //
  //                    /       |       \                            //
  //
  //          On this example, and if we assume the Onext() oder is
  //          represented counter-clockwise, the edges are ordered as
  //          follows:
  //             b1, b2, i3, b4, b5, i6, i7
  //          (when arbitrarily starting at edge b1).
  //          We have four Boundary edges labeled b1, b2, b4, b5 and
  //          we have three internal edges (i.e. non boundary edges)
  //          labeled i3, i6 and i7.
  //          Depending on edgeTest, the result of this method
  //          will NOT return the same edge:
  //            - when edgeTest == b5 (or i6 or i7 or b1) then the edge
  //              b1 will be returned,
  //            - when edgeTest == b2 (or i3 or b4) then the edge
  //              b4 will be returned,
  //          Eventually, when edgeTest is absent, the result shall
  //          depend on the position of "this" in the Onext() ring().
  //

  // Be sure the Onext ring isn't already full
  if ( this->IsOriginInternal() )
    {
    itkQEDebugMacro("Internal point.");
    return ( ITK_NULLPTR );
    }

  // Update reference
  edgeTest = ( !edgeTest ) ? this : edgeTest;

  // On efficiency purposes
  if ( edgeTest->IsIsolated() )
    {
    return ( edgeTest );
    }

  // Ok, no more special cases
  IteratorGeom it   = edgeTest->BeginGeomOnext();
  IteratorGeom end  = edgeTest->EndGeomOnext();

  while ( it != end )
    {
    if ( !it.Value()->IsLeftSet() )
      {
      return ( it.Value() );
      }
    it++;
    }

  // No border edge found
  itkQEDebugMacro("Unfound border edge.");
  return ( ITK_NULLPTR );
}

/**
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::InsertAfterNextBorderEdgeWithUnsetLeft(
  Self *isol,
  Self *hint)
{
  // When the geometry of isol is set it must match the
  // one of "this" Origin(). If the geometry is not set, we assume
  // that both Origin are the same, regardless their actual value.
  // Note: The purpose of this test is to avoid introducing some
  //       incoherence in the geometry at Origin().
  // The things should go this way:
  // 1/ when the geometry of "this" Origin is not set, then be paranoid
  //    and suspect the situation is already snafu:
  //    1a/ if all edges of "this" Onext ring have an unset Origin()
  //        (the situation is coherent), then proceed (Result=0)
  //        whatever the value of isol.Origin() might be.
  //    1b/ if one of the edges of "this" Onext ring has an Origin() set,
  //        then we deduce that there is already some geometrical
  //        incoherence at this->Origin() and exit this method (Result=1).
  // 2/ Then when we didn't exit at stage 1, consider isol.Origin():
  //    2a/ when isol.Origin() is absent proceed (result=0),
  //    2b/ when isol.Origin() is present and Origin == isol.OriginSet then
  //        proceed (result=0),
  //    2c/ when isol.Origin() is present and Origin != isol.OriginSet then
  //        exit (result=1).
  //
  // Here is what is implemented:
  // +-----------+----------------+--------------------------+--------+
  // | OriginSet | isol.OriginSet | Origin == isol.OriginSet | Result |
  // +-----------+----------------+--------------------------+--------+
  // |      0    |         0      |           0              |    0   |
  // |      0    |         0      |           1              |    0   |
  // |      0    |         1      |           0              |    1   |
  // |      0    |         1      |           1              |    1   |
  // +-----------+----------------+--------------------------+--------+
  // |      1    |         0      |           0              |    1   |
  // |      1    |         0      |           1              |    1   |
  // |      1    |         1      |           0              |    1   |
  // |      1    |         1      |           1              |    0   |
  // +-----------+----------------+--------------------------+--------+
  //
  if ( !(   !( IsOriginSet() || isol->IsOriginSet() )
            || ( IsOriginSet()
                 && isol->IsOriginSet()
                 && ( m_Origin == isol->m_Origin ) )
            )
       )
    {
    itkQEDebugMacro("Isolated Origin() differs from this Origin.");
    return ( false );
    }

  // Find out if this point has some room left for edge insertion:
  Self *edgeAfter = this->GetNextBorderEdgeWithUnsetLeft(hint);
  if ( !edgeAfter )
    {
    itkQEDebugMacro("This point is yet surrounded by faces.");
    return ( false );
    }

  // Normally, an edge was found
  edgeAfter->Splice(isol);
  return ( true );
}

/**
 */
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::ReorderOnextRingBeforeAddFace(
  Self *second)
{
  // Assume "this->Originv()" is a boundary point P that is thrice adjacent
  // to noface and consider the given situation is the one depicted by
  // the following diagram where:
  //   - P is "this->Originv()" instance,
  //   - the * (star) indicates the presence of a face,
  //   - b1, b2, b3, b4, b5, b6 denote boundary edges,
  //   - p denotes some generic point,
  //   - A and B denote some specific points we want to discuss,
  //   - the Onext() ring order is represented counter-clockwise
  //     [which is coherent with the definition of edge->GetRigth()]
  //     i.e. the ordering of the edges is:
  //          b1, b2, b3, b4, b5, b6, b1...
  //
  //                    p       N       p
  //                   / \      O      / \                            //
  //                  /   \           /   \                           //
  //                 /     \    F    /     \       counter-clockwise  //
  //                /      b3   A   b2      \      Onext() ring order //
  //               /         \  C  /         \                        //
  //              /     *     \ E /     *     \                       //
  //             /             \ /             \                      //
  //             A------b4------P------b1-------B                     //
  //                           / \                                    //
  //                          /   \                                   //
  //             NO FACE     /     \      NO FACE                     //
  //                        /       \                                 //
  //                      b5         b6                               //
  //                      /     *     \                               //
  //                     /             \                              //
  //                    p---------------p                             //
  //
  // At P this Mesh doesn't represent a 2-manifold (since we are thrice
  // on the boundary). Nevertheless such a situation could arise in
  // intermediary stages (e.g. when building the Mesh, or during
  // surgical changes on the Mesh).
  //    Now, assume we are asked to build the triangle [P, A, B]. Note
  // that this request is not absurd since the current situation at
  // P isn't the one of a 2-manifold: hence when building the current
  // Onext() ring of P, we had not enough information to decide
  // wheter b4.Onext() should be b5 or b1. It is ONLY when we are
  // required to build the triangle [P, A, B] that we have the
  // additional information that b4.Onext() is indeed b1.
  //    When we are required to build triangle [P, A, B], we hence
  // need to change the Onext() ring order at P, i.e. we need to deal
  // with the triangle [P, b5, b6] which currently prevents
  // b4.Onext() to be b1. In other terms, when considering the
  // additional information that b4.Onext() is b1, and before
  // building the triangle [P, A, B], we need to reorder
  // the Onext() ring of P from it's current state
  //    b1, b2, b3, b4, b5, b6, b1...
  // to an order coherent with the [P, A, B] request, i.e.
  //     b1, b2, b5, b6, b3, b4, b1...
  //
  // In order to establish the "proper" Onext() ring at P we use
  // two Splice operations. The algorithm goes:
  //   - first disconnect the piece of the surface containing the edge
  //     [PB] (it would be the same process if we chose [PA]) from
  //     the Onext() ring at P.
  //   - second, re-integrate the disconnected piece at the desired
  //     location i.e. side by side with [PA] (respectively [PB] if
  //     we chose [PA] at first stage).
  // By "piece of surface containing the edge [PB]" we mean [all]
  // the triangle[s] starting at [PB] in the Onext() order and
  // having a left face set.
  //
  // We can illustrate this process on bit more general diagram than
  // the last case (where the "piece of surface containing the edge
  // [PB]" is constituted by two triangles) and when using
  // the arguments of this method (i.e. [PA] = this and [PB] = second).
  // The initial stage is the following (we note first=this=[PA] and
  // second=[PB]) where the Onext() ring order is:
  //     first, b2, b3, second, b5, bsplice, b7, first...
  //
  //                    p       N       A                            //
  //                   / \      O      / \                           //
  //                  /   \           /   \                          //
  //                 /     \    F    /     \     counter-clockwise   //
  //                /      b2   A  first    \    Onext() ring order  //
  //               /         \  C  /         \                       //
  //              /     *     \ E /     *     \                      //
  //             /             \ /             \                     //
  //            p-------b3------P------b7-------p                    //
  //                           /|\                                   //
  //                          / | \                                  //
  //          NO FACE        /  |  \      NO FACE                    //
  //                        /   |   \                                //
  //                  second   b5   bsplice                          //
  //                      /  *  |  *  \                              //
  //                     /      |      \                             //
  //                    B-------p-------p                            //
  //
  // The first stage, implemented as
  //     second->Oprev()->Splice( bsplice ),
  // yields the following diagram:
  //
  //                    p       N       A                            //
  //                   / \      O      / \                           //
  //                  /   \     F     /   \                          //
  //                 /     \    A    /     \      counter-clockwise  //
  //                /      b2   C  first    \     Onext() ring order //
  //               /         \  E  /         \                       //
  //              /     *     \   /     *     \                      //
  //             /             \ /             \                     //
  //            p-------b3------P------b7-------p                    //
  //                                                                 //
  //                         NO FACE                                 //
  //                                                                 //
  //                           /|\                                   //
  //                          / | \                                  //
  //                         /  |  \                                 //
  //                        /   |   \                                //
  //                  second   b5   bsplice                          //
  //                      /  *  |  *  \                              //
  //                     /      |      \                             //
  //                    B-------p-------p                            //
  //
  // and the second stage, implemented as
  //      first->Splice( bsplice ),
  // yields the following diagram:
  //
  //                                    A                            //
  //         B__        NO FACE        / \                           //
  //         |  \__                   /   \                          //
  //         |     \__               /     \       counter-          //
  //         |      second         first    \      clockwise for all //
  //         |           \__       /         \                       //
  //         |     *        \__   /     *     \                      //
  //         |                 \ /             \                     //
  //         p-------b5---------P------b7-------p                    //
  //         |               __/|\                                   //
  //         |     *      __/   | \                                  //
  //         |           /      |  \      NO FACE                    //
  //         |     bsplice      |   \                                //
  //         |   __/           b2    b3                              //
  //         p__/               |  *  \                              //
  //                NO FACE     |      \                             //
  //                            p-------p                            //
  //
  Self *first = this;

  // Making sure point adjacency is correct:
  if ( first->GetOrigin() != second->GetOrigin() )
    {
    itkQEDebugMacro("Edges not adjacent at same point!");
    return ( false );
    }

  if ( first->GetOnext() == second )
    {
    return ( true );
    }

  if ( first->IsLeftSet() )
    {
    itkQEDebugMacro("First should NOT have a left face.");
    return ( false );
    }

  // Second is an internal edge.
  if ( second->IsInternal() )
    {
    return ( false );
    }

  Self *bsplice; // Does not require initialisation;
  // Disconnect the triangles containing second:
  if ( second->IsLeftSet() )
    {
    bsplice = second->GetNextBorderEdgeWithUnsetLeft();
    second->GetOprev()->Splice(bsplice);
    }
  else
    {
    // Orientation is localy clockwise:
    bsplice = second;
    second->GetOprev()->Splice(bsplice);
    }

  // Reconnect second after first:
  first->Splice(bsplice);
  return ( true );
}

// ---------------------------------------------------------------------
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
void GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >::Disconnect()
{
  if ( this->IsDisconnected() )
    {
    return;
    }

  // Update faces if the edge isn't a wire
  if ( this->IsAtBorder() )
    {
    Self *       e = ( this->IsRightSet() ) ? this->GetSym() : this;
    IteratorGeom it = e->BeginGeomLnext();
    while ( it != e->EndGeomLnext() )
      {
      it.Value()->UnsetLeft();
      it++;
      }
    }
  else if ( this->IsInternal() )
    {
    // Consolidate face
    DualOriginRefType face = this->GetRight();
    for ( IteratorGeom it  = this->BeginGeomLnext();
          it != this->EndGeomLnext();
          it++ )
      {
      it.Value()->SetLeft(face);
      }
    }

  // Hint edges
  Self *e0 = this->GetOprev();
  Self *e1 = this->GetLnext();

  // Disconnect entries
  if ( !this->IsOriginDisconnected() )
    {
    e0->Splice(this);
    }
  if ( !this->IsDestinationDisconnected() )
    {
    e1->Splice( this->GetSym() );
    }

  // Normally, this edge is converted to a simple wire
  this->UnsetOrigin();
  this->UnsetDestination();
  this->UnsetLeft();
  this->UnsetRight();
}

// ---------------------------------------------------------------------
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool
GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >
::IsOriginSet() const
{
  return ( this->m_Origin != m_NoPoint );
}

// ---------------------------------------------------------------------
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool
GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >
::IsDestinationSet() const
{
  const Self *p1 = this->GetSym();

  if ( p1 == ITK_NULLPTR )
    {
    return false; // FIXME: Is this the right answer ?
    }

  return p1->IsOriginSet();
}

// ---------------------------------------------------------------------
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool
GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >
::IsRightSet() const
{
  const DualType *p1 = this->GetRot();

  if ( p1 == ITK_NULLPTR )
    {
    return false;  // FIXME: Is this the right answer ?
    }

  return p1->IsOriginSet();
}

// ---------------------------------------------------------------------
template< typename TVRef, typename TFRef,
          typename TPrimalData, typename TDualData, bool PrimalDual >
bool
GeometricalQuadEdge< TVRef, TFRef, TPrimalData, TDualData, PrimalDual >
::IsLeftSet() const
{
  const DualType *p1 = this->GetInvRot();

  if ( p1 == ITK_NULLPTR )
    {
    return false;  // FIXME: Is this the right answer ?
    }

  return p1->IsOriginSet();
}
} // end of namespace itk

#endif