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 
19 #include "itkQuadEdgeMeshEulerOperatorDeleteCenterVertexFunction.h"
20 #include "itkQuadEdgeMeshEulerOperatorCreateCenterVertexFunction.h"
21 #include "itkQuadEdgeMeshEulerOperatorsTestHelper.h"
22 
itkQuadEdgeMeshEulerOperatorDeleteCenterVertexTest(int argc,char * argv[])23 int itkQuadEdgeMeshEulerOperatorDeleteCenterVertexTest(int argc, char* argv[] )
24 {
25   (void)argc;
26   (void)argv;
27 
28   using MeshType = itk::QuadEdgeMesh< double, 3 >;
29   using MeshPointer = MeshType::Pointer;
30   using QEType = MeshType::QEType;
31   using PointType = MeshType::PointType;
32   using CellType = MeshType::CellType;
33 
34   using DeleteCenterVertex = itk::QuadEdgeMeshEulerOperatorDeleteCenterVertexFunction< MeshType,
35     QEType>;
36 
37   using CreateCenterVertex = itk::QuadEdgeMeshEulerOperatorCreateCenterVertexFunction< MeshType,
38     QEType>;
39 
40   /////////////////////////////////////////
41   //
42   //          Delete Center Vertex
43   //
44   /////////////////////////////////////////
45   // first test with the center vertex.
46   // we take 6-->12 as incoming parameter.
47   //
48   //    Vertices: 24 , Edges: 50, Faces: 27, Boundary = 1, Chi = 1
49   //
50   //   20 --------- 21 --------- 22 --------- 23 --------- 24
51   //    |        __/ |        __/ |        __/ |        __/ |
52   //    |     __/    |     __/    |     __/    |     __/    |
53   //    |  __/       |  __/       |  __/       |  __/       |
54   //    | /          | /          | /          | /          |
55   //   15 --------- 16 --------- 17 --------- 18 --------- 19
56   //    |        __/ |        __/              |        __/ |
57   //    |     __/    |     __/                 |     __/    |
58   //    |  __/       |  __/                    |  __/       |
59   //    | /          | /                       | /          |
60   //   10 --------- 11                        13 --------- 14
61   //    |        __/ |                     __/ |        __/ |
62   //    |     __/    |                  __/    |     __/    |
63   //    |  __/       |               __/       |  __/       |
64   //    | /          |              /          | /          |
65   //    5 ---------- 6 ---------- 7 ---------- 8 ---------  9
66   //    |        __/ |        __/ |        __/ |        __/ |
67   //    |     __/    |     __/    |     __/    |     __/    |
68   //    |  __/       |  __/       |  __/       |  __/       |
69   //    | /          | /          | /          | /          |
70   //    0 ---------- 1 ---------- 2  --------- 3 ---------  4
71   std::cout << "Checking DeleteCenterVertex." << std::endl;
72 
73   MeshPointer mesh = MeshType::New();
74   CreateSquareTriangularMesh<MeshType>( mesh );
75 
76   DeleteCenterVertex::Pointer deleteCenterVertex = DeleteCenterVertex::New( );
77   std::cout << "     " << "Test No Mesh Input";
78   if( deleteCenterVertex->Evaluate( (QEType*)1 ) )
79     {
80     std::cout << "FAILED." << std::endl;
81     return EXIT_FAILURE;
82     }
83   std::cout << "OK" << std::endl;
84 
85   (void)deleteCenterVertex->GetNameOfClass();
86 
87   deleteCenterVertex->SetInput( mesh );
88   std::cout << "     " << "Test No QE Input";
89   if( deleteCenterVertex->Evaluate( (QEType*)nullptr ) )
90     {
91     std::cout << "FAILED." << std::endl;
92     return EXIT_FAILURE;
93     }
94   std::cout << "OK" << std::endl;
95 
96   deleteCenterVertex->SetInput( mesh );
97   std::cout << "     " << "Test one-ring not full (impossible)";
98   if( deleteCenterVertex->Evaluate( mesh->FindEdge( 15, 21 ) ) )
99     {
100     std::cout << "FAILED." << std::endl;
101     return EXIT_FAILURE;
102     }
103   std::cout << "OK" << std::endl;
104 
105     {
106     MeshPointer  specialmesh = MeshType::New();
107     PointType pts3[4];
108     pts3[ 0][0] = 0.0;  pts3[ 0][1] = 0.0;  pts3[ 0][2] = 0.0;
109     pts3[ 1][0] = 1.0;  pts3[ 1][1] = 0.0;  pts3[ 1][2] = 0.0;
110     pts3[ 2][0] = 0.0;  pts3[ 2][1] = 1.0;  pts3[ 2][2] = 0.0;
111     pts3[ 3][0] = 0.0;  pts3[ 3][1] = 0.0;  pts3[ 3][2] = 1.0;
112     for(int i=0; i<4; i++)
113       {
114       specialmesh->SetPoint( i, pts3[i] );
115       }
116     int specialCells[12] =
117     {  0,  1,  2,
118        0,  2,  3,
119        3,  1,  0,
120        1,  3,  2 };
121 
122     CellType::CellAutoPointer cellpointer;
123     using QEPolygonCellType = itk::QuadEdgeMeshPolygonCell< CellType >;
124     QEPolygonCellType *poly;
125     for(int i=0; i<4; i++)
126       {
127       poly = new QEPolygonCellType( 3 );
128       cellpointer.TakeOwnership( poly );
129       cellpointer->SetPointId( 0, specialCells[3*i] );
130       cellpointer->SetPointId( 1, specialCells[3*i+1] );
131       cellpointer->SetPointId( 2, specialCells[3*i+2] );
132       specialmesh->SetCell( i, cellpointer );
133       }
134     deleteCenterVertex->SetInput( specialmesh );
135     std::cout << "     ";
136     std::cout << "Delete a vertex of a non-collapsable mesh (impossible).";
137     if( deleteCenterVertex->Evaluate( specialmesh->FindEdge( 0, 1 ) ) )
138       {
139       std::cout << "FAILED." << std::endl;
140       return EXIT_FAILURE;
141       }
142     }
143 
144   deleteCenterVertex->SetInput( mesh );
145   std::cout << "     ";
146   std::cout << "Delete center vertex with internal 1-ring (possible).";
147   if( !deleteCenterVertex->Evaluate( mesh->FindEdge( 6, 12 ) ) )
148     {
149     std::cout << "FAILED." << std::endl;
150     return EXIT_FAILURE;
151     }
152   mesh->DeletePoint( deleteCenterVertex->GetOldPointID( ) );
153   if( ! AssertTopologicalInvariants< MeshType >
154           ( mesh, 24, 50, 27, 1, 0 ) )
155     {
156     std::cout << "FAILED." << std::endl;
157     return EXIT_FAILURE;
158     }
159   std::cout << ".OK" << std::endl;
160   // The initial configuration and numbering of simpleSquare.vtk:
161   //    Vertices: 25 , Edges: 56, Faces: 32, Boundary = 1, Chi = 1
162   //
163   //   20 --------- 21 --------- 22 --------- 23 --------- 24
164   //    |        __/ |        __/ |        __/              |
165   //    |     __/    |     __/    |     __/                 |
166   //    |  __/       |  __/       |  __/                    |
167   //    | /          | /          | /                       |
168   //   15 --------- 16 --------- 17                        19
169   //    |        __/ |        __/ |                     __/ |
170   //    |     __/    |     __/    |                  __/    |
171   //    |  __/       |  __/       |               __/       |
172   //    | /          | /          |              /          |
173   //   10 --------- 11 --------- 12 --------- 13 --------- 14
174   //    |        __/ |        __/ |        __/ |        __/ |
175   //    |     __/    |     __/    |     __/    |     __/    |
176   //    |  __/       |  __/       |  __/       |  __/       |
177   //    | /          | /          | /          | /          |
178   //    5 ---------- 6 ---------- 7 ---------- 8 ---------  9
179   //    |        __/ |        __/ |        __/ |        __/ |
180   //    |     __/    |     __/    |     __/    |     __/    |
181   //    |  __/       |  __/       |  __/       |  __/       |
182   //    | /          | /          | /          | /          |
183   //    0 ---------- 1 ---------- 2  --------- 3 ---------  4
184   //
185   CreateSquareTriangularMesh<MeshType>( mesh );
186   std::cout << "     ";
187   std::cout << "Delete center vertex with border 1-ring (possible).";
188   deleteCenterVertex->SetInput( mesh );
189   if( !deleteCenterVertex->Evaluate( mesh->FindEdge( 17, 18 ) ) )
190     {
191     std::cout << "FAILED." << std::endl;
192     return EXIT_FAILURE;
193     }
194   mesh->DeletePoint( deleteCenterVertex->GetOldPointID( ) );
195   if( ! AssertTopologicalInvariants< MeshType >
196           ( mesh, 24, 50, 27, 1, 0 ) )
197     {
198     std::cout << "FAILED." << std::endl;
199     return EXIT_FAILURE;
200     }
201   std::cout << ".OK" << std::endl;
202   // test that border points can not be deleted.
203   CreateSquareTriangularMesh<MeshType>( mesh );
204   std::cout << "     ";
205   std::cout << "Check deleting a border vertex (impossible).";
206 
207   deleteCenterVertex->SetInput( mesh );
208   if( deleteCenterVertex->Evaluate( mesh->FindEdge( 23, 24 ) ) )
209     {
210     std::cout << "FAILED." << std::endl;
211     return EXIT_FAILURE;
212     }
213   if( ! AssertTopologicalInvariants< MeshType >
214           ( mesh, 25, 56, 32, 1, 0 ) )
215     {
216     std::cout << "FAILED." << std::endl;
217     return EXIT_FAILURE;
218     }
219   std::cout << ".OK" << std::endl;
220 
221   // test that points including an hole in the 1-ring
222   // can not be deleted.
223   CreateSquareTriangularMesh<MeshType>( mesh );
224   std::cout << "     ";
225   std::cout << "Check deleting a vertex around an hole (impossible).";
226   mesh->LightWeightDeleteEdge( mesh->FindEdge(  6, 12 ) );
227   deleteCenterVertex->SetInput( mesh );
228   if( deleteCenterVertex->Evaluate( mesh->FindEdge(  6,  7 ) ) )
229     {
230     std::cout << "FAILED." << std::endl;
231     return EXIT_FAILURE;
232     }
233   if( !AssertTopologicalInvariants< MeshType >
234           ( mesh, 25, 55, 30, 2, 0 ) )
235     {
236     std::cout << "FAILED." << std::endl;
237     return EXIT_FAILURE;
238     }
239   std::cout << ".OK" << std::endl;
240 
241   std::cout << "Checking DeleteCenterVertex." << "OK" << std::endl << std::endl;
242 
243   std::cout << "Checking DeleteCenterVertex( CreateCenterVertex()) Invariance.";
244 
245   CreateCenterVertex::Pointer createCenterVertex = CreateCenterVertex::New();
246   createCenterVertex->SetInput( mesh );
247 
248   CreateSquareTriangularMesh<MeshType>( mesh );
249   if( !deleteCenterVertex->Evaluate(
250     createCenterVertex->Evaluate( mesh->FindEdge( 0, 1 ) ) ) )
251     {
252     std::cout << "FAILED." << std::endl;
253     return EXIT_FAILURE;
254     }
255   mesh->DeletePoint( deleteCenterVertex->GetOldPointID( ) );
256   if( ! AssertTopologicalInvariants< MeshType >
257           ( mesh, 25, 56, 32, 1, 0 ) )
258     {
259     std::cout << "FAILED." << std::endl;
260     return EXIT_FAILURE;
261     }
262   std::cout << ".OK" << std::endl;
263   return EXIT_SUCCESS;
264 }
265