1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkQuadEdgeMeshEulerOperatorSplitFacetFunction_hxx
19 #define itkQuadEdgeMeshEulerOperatorSplitFacetFunction_hxx
20 
21 #include "itkQuadEdgeMeshEulerOperatorSplitFacetFunction.h"
22 
23 namespace itk
24 {
25 template< typename TMesh, typename TQEType >
26 typename QuadEdgeMeshEulerOperatorSplitFacetFunction< TMesh, TQEType >::OutputType
Evaluate(QEType * h,QEType * g)27 QuadEdgeMeshEulerOperatorSplitFacetFunction< TMesh, TQEType >::Evaluate(QEType *h, QEType *g)
28 {
29   //
30   //  g->Dest() ---<----- X                    destPid  --------- X        //
31   //         /     g       \                         / \           \       //
32   //        /               \                   dLnext  \           \      //
33   //       /                 \                     /     \           \     //
34   //      /                   \                   v       ^           \    //
35   //     /      g->Left()      \                 /         \           \   //
36   //    X           =           X               X        newEdge        X  //
37   //     \      h->Left()      /                 \           \         /   //
38   //      \                   /                   \           \       ^    //
39   //       \                 /                     \           \     /     //
40   //        \               /                       \           \ oLnext   //
41   //         \       h     /                         \           \ /       //
42   //          X ----->--- h->Dest()                   X --------- orgPid   //
43   //
44 
45   if ( !h || !g )
46     {
47     itkDebugMacro("At least one of the Input is not an edge.");
48     return ( (QEType *)nullptr );
49     }
50 
51   if ( !this->m_Mesh )
52     {
53     itkDebugMacro("No mesh present.");
54     return ( (QEType *)nullptr );
55     }
56 
57   if ( h == g )
58     {
59     itkDebugMacro("Provided edges should be different.");
60     return ( (QEType *)nullptr );
61     }
62 
63   if ( h->GetLeft() != g->GetLeft() )
64     {
65     itkDebugMacro("The edges are not around the same face.");
66     return ( (QEType *)nullptr );
67     }
68 
69   if ( ( h->GetLnext() == g )
70        || ( g->GetLnext() == h ) )
71     {
72     itkDebugMacro("Provided edges should NOT be consecutive.");
73     return ( (QEType *)nullptr );
74     }
75 
76   using VertexRefType = typename MeshType::VertexRefType;
77 
78   this->m_Mesh->DeleteFace( h->GetLeft() );
79   VertexRefType orgPid  = h->GetDestination();
80   VertexRefType destPid = g->GetDestination();
81 
82   // Create an new isolated edge and set it's geometry:
83   auto * newEdge = new EdgeCellType;
84   QEType *      newEdgeGeom = newEdge->GetQEGeom();
85 
86   // see the code of e.g. AddFace
87   newEdgeGeom->SetOrigin(orgPid);
88   newEdgeGeom->SetDestination(destPid);
89 
90   // Insert newEdge at Org
91   QEType *oLnext = h->GetLnext();
92   oLnext->InsertAfterNextBorderEdgeWithUnsetLeft(newEdgeGeom);
93   // Insert newEdge at Dest
94   QEType *dLnext = g->GetLnext();
95   dLnext->InsertAfterNextBorderEdgeWithUnsetLeft( newEdgeGeom->GetSym() );
96 
97   // Add the new edge to the container
98   this->m_Mesh->PushOnContainer(newEdge);
99 
100   // Build two new faces
101   this->m_Mesh->AddFace(h);
102   this->m_Mesh->AddFace(g);
103   this->m_Mesh->Modified();
104   return ( newEdgeGeom );
105 }
106 
107 } // end namespace itk
108 
109 #endif
110