ITK  5.0.0
Insight Segmentation and Registration Toolkit
itkMeshFileTestHelper.h
Go to the documentation of this file.
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 itkMeshFileTestHelper_h
19 #define itkMeshFileTestHelper_h
20 
21 /*
22  * This file is contains helper functions for the ITK MeshIO module testing.
23  * It should not be considered as part of the toolkit API and it may change at
24  * any time without notice. We mean it.
25  */
26 
27 #include "itkMeshFileReader.h"
28 #include "itkMeshFileWriter.h"
29 #include <itksys/SystemTools.hxx>
30 
31 template< typename TMesh >
32 int
33 TestPointsContainer( typename TMesh::PointsContainerPointer points0,
34  typename TMesh::PointsContainerPointer points1 )
35 {
36  using MeshType = TMesh;
37  using PointsContainerConstIterator = typename MeshType::PointsContainerConstIterator;
38 
39  if ( points0.IsNotNull() && points1.IsNotNull() )
40  {
41  if( points0->Size() != points1->Size() )
42  {
43  std::cerr << "Input mesh and output mesh have different number of cells!" <<std::endl;
44  return EXIT_FAILURE;
45  }
46 
47  PointsContainerConstIterator pt0 = points0->Begin();
48  PointsContainerConstIterator pt1 = points1->Begin();
49 
50  const double tol = 1e-6;
51  while ( ( pt0 != points0->End() ) && ( pt1 != points1->End() ) )
52  {
53  if( pt0->Index() != pt1->Index() )
54  {
55  std::cerr << "Input mesh and output mesh are different in points!" << std::endl;
56  std::cerr << "Input point ID = " << pt0.Index() << std::endl;
57  std::cerr << "Output point ID = " << pt1.Index() << std::endl;
58  return EXIT_FAILURE;
59  }
60  if ( pt0.Value().SquaredEuclideanDistanceTo( pt1.Value() ) > tol )
61  {
62  std::cerr << "Input mesh and output mesh are different in points!" << std::endl;
63  std::cerr << "Input point = " << pt0.Value() << std::endl;
64  std::cerr << "Output point = " << pt1.Value() << std::endl;
65  return EXIT_FAILURE;
66  }
67  ++pt0;
68  ++pt1;
69  }
70  }
71  else
72  {
73  if ( points0 != points1.GetPointer() )
74  {
75  std::cerr << "Input mesh and output mesh are different in points!" << std::endl;
76  std::cerr << "points0 = " << points0.GetPointer() << std::endl;
77  std::cerr << "points1 = " << points1.GetPointer() << std::endl;
78  return EXIT_FAILURE;
79  }
80  }
81 
82  return EXIT_SUCCESS;
83 }
84 
85 template< typename TMesh >
86 int
87 TestCellsContainer( typename TMesh::CellsContainerPointer cells0,
88  typename TMesh::CellsContainerPointer cells1 )
89 {
90  using MeshType = TMesh;
91  using CellsContainerConstIterator = typename MeshType::CellsContainerConstIterator;
92  using CellPointIdIterator = typename MeshType::CellType::PointIdIterator;
93 
94  if ( cells0.IsNotNull() && cells1.IsNotNull() )
95  {
96  if( cells0->Size() != cells1->Size() )
97  {
98  std::cerr << "Input mesh and output mesh have different number of cells!" <<std::endl;
99  return EXIT_FAILURE;
100  }
101  CellsContainerConstIterator ceIt0 = cells0->Begin();
102  CellsContainerConstIterator ceIt1 = cells1->Begin();
103 
104  while ( ( ceIt0 != cells0->End() ) && ( ceIt1 != cells1->End() ) )
105  {
106  if ( ceIt0.Value()->GetType() != ceIt1.Value()->GetType() )
107  {
108  std::cerr << "Input mesh and output mesh are different in cell type!" << std::endl;
109  return EXIT_FAILURE;
110  }
111  if ( ceIt0.Index() != ceIt1.Index() )
112  {
113  std::cerr << "Input mesh and output mesh have different cell IDs" << std::endl;
114  std::cerr << "Input mesh cell ID: " << ceIt0.Index() << std::endl;
115  std::cerr << "Output mesh cell ID: " << ceIt1.Index() << std::endl;
116  return EXIT_FAILURE;
117  }
118  CellPointIdIterator pit0 = ceIt0.Value()->PointIdsBegin();
119  CellPointIdIterator pit1 = ceIt1.Value()->PointIdsBegin();
120  while ( pit0 != ceIt0.Value()->PointIdsEnd() )
121  {
122  if ( *pit0 != *pit1 )
123  {
124  std::cerr << "Input mesh and output mesh are different in cells!" << std::endl;
125  return EXIT_FAILURE;
126  }
127  ++pit0;
128  ++pit1;
129  }
130  ++ceIt0;
131  ++ceIt1;
132  }
133  }
134  else
135  {
136  if ( cells0 != cells1.GetPointer() )
137  {
138  std::cerr << "Input mesh and output mesh are different in cells!" << std::endl;
139  std::cerr << "cells0 = " << cells0.GetPointer() << std::endl;
140  std::cerr << "cells1 = " << cells1.GetPointer() << std::endl;
141  return EXIT_FAILURE;
142  }
143  }
144 
145  return EXIT_SUCCESS;
146 }
147 
148 template< typename TMesh >
149 int
150 TestPointDataContainer( typename TMesh::PointDataContainerPointer pointData0,
151  typename TMesh::PointDataContainerPointer pointData1 )
152 {
153  using MeshType = TMesh;
154  using PointDataContainerIterator = typename MeshType::PointDataContainerIterator;
155 
156  if ( pointData0.IsNotNull() && pointData1.IsNotNull() )
157  {
158  if( pointData0->Size() != pointData1->Size() )
159  {
160  std::cerr << "Input mesh and output mesh have different number of cells!" <<std::endl;
161  return EXIT_FAILURE;
162  }
163  PointDataContainerIterator pdIt0 = pointData0->Begin();
164  PointDataContainerIterator pdIt1 = pointData1->Begin();
165 
166  while ( ( pdIt0 != pointData0->End() ) && ( pdIt1 != pointData1->End() ) )
167  {
168  if( pdIt0->Index() != pdIt1->Index() )
169  {
170  std::cerr << "Input mesh and output mesh are different in point data!" << std::endl;
171  std::cerr << "Input point ID = " << pdIt0.Index() << std::endl;
172  std::cerr << "Output point ID = " << pdIt1.Index() << std::endl;
173  return EXIT_FAILURE;
174  }
175  if ( itk::Math::NotExactlyEquals(pdIt0.Value(), pdIt1.Value()) )
176  {
177  std::cerr << "Input mesh and output mesh are different in point data!" << std::endl;
178  std::cerr << "Input = " << pdIt0.Value() << std::endl;
179  std::cerr << "Output = " << pdIt1.Value() << std::endl;
180  return EXIT_FAILURE;
181  }
182  ++pdIt0;
183  ++pdIt1;
184  }
185  }
186  else
187  {
188  if ( pointData0 != pointData1.GetPointer() )
189  {
190  std::cerr << "Input mesh and output mesh are different in point data!" << std::endl;
191  std::cerr << "pointData0 = " << pointData0.GetPointer() << std::endl;
192  std::cerr << "pointData1 = " << pointData1.GetPointer() << std::endl;
193  return EXIT_FAILURE;
194  }
195  }
196  return EXIT_SUCCESS;
197 }
198 
199 template< typename TMesh >
200 int
201 TestCellDataContainer( typename TMesh::CellDataContainerPointer cellData0,
202  typename TMesh::CellDataContainerPointer cellData1 )
203 {
204  using MeshType = TMesh;
205  using CellDataContainerIterator = typename MeshType::CellDataContainerIterator;
206 
207  if ( cellData0.IsNotNull() && cellData1.IsNotNull() )
208  {
209  if( cellData0->Size() != cellData1->Size() )
210  {
211  std::cerr << "Input mesh and output mesh have different number of cells!" <<std::endl;
212  return EXIT_FAILURE;
213  }
214 
215  CellDataContainerIterator cdIt0 = cellData0->Begin();
216  CellDataContainerIterator cdIt1 = cellData1->Begin();
217  while ( cdIt0 != cellData0->End() )
218  {
219  if( cdIt0->Index() != cdIt1->Index() )
220  {
221  std::cerr << "Input mesh and output mesh are different in cell data!" << std::endl;
222  std::cerr << "Input cell ID = " << cdIt0.Index() << std::endl;
223  std::cerr << "Output cell ID = " << cdIt1.Index() << std::endl;
224  return EXIT_FAILURE;
225  }
226  if ( itk::Math::NotExactlyEquals(cdIt0.Value(), cdIt1.Value()) )
227  {
228  std::cerr << "Input mesh and output mesh are different in cell data!" << std::endl;
229  std::cerr << "Input = " << cdIt0.Value() << std::endl;
230  std::cerr << "Output = " << cdIt1.Value() << std::endl;
231  return EXIT_FAILURE;
232  }
233  ++cdIt0;
234  ++cdIt1;
235  }
236  }
237  else
238  {
239  if ( cellData0 != cellData1.GetPointer() )
240  {
241  std::cerr << "Input mesh and output mesh are different in cell data!" << std::endl;
242  std::cerr << "pointData0 = " << cellData0.GetPointer() << std::endl;
243  std::cerr << "pointData1 = " << cellData1.GetPointer() << std::endl;
244  return EXIT_FAILURE;
245  }
246  }
247  return EXIT_SUCCESS;
248 }
249 
250 template< typename TMesh >
251 int
252 test(char *INfilename, char *OUTfilename, bool IsBinary)
253 {
254  using MeshType = TMesh;
255 
256  using MeshFileReaderType = itk::MeshFileReader< MeshType >;
257  using MeshFileReaderPointer = typename MeshFileReaderType::Pointer;
258 
259  using MeshFileWriterType = itk::MeshFileWriter< MeshType >;
260  using MeshFileWriterPointer = typename MeshFileWriterType::Pointer;
261 
262  MeshFileReaderPointer reader = MeshFileReaderType::New();
263  reader->SetFileName(INfilename);
264  try
265  {
266  reader->Update();
267  }
268  catch ( itk::ExceptionObject & err )
269  {
270  std::cerr << "Read file " << INfilename << " failed " << std::endl;
271  std::cerr << err << std::endl;
272  return EXIT_FAILURE;
273  }
274  reader->GetMeshIO()->Print( std::cout );
275 
276  if( TMesh::PointDimension != reader->GetMeshIO()->GetPointDimension() )
277  {
278  std::cerr << "Unexpected PointDimension" << std::endl;
279  return EXIT_FAILURE;
280  }
281 
282  MeshFileWriterPointer writer = MeshFileWriterType::New();
283  if( itksys::SystemTools::GetFilenameLastExtension(INfilename) ==
284  itksys::SystemTools::GetFilenameLastExtension(OUTfilename) )
285  {
286  writer->SetMeshIO(reader->GetModifiableMeshIO());
287  }
288  writer->SetFileName(OUTfilename);
289  writer->SetInput( reader->GetOutput() );
290 
291  // NOTE ALEX: we should document the usage
292  if ( IsBinary )
293  {
294  writer->SetFileTypeAsBINARY();
295  }
296 
297  try
298  {
299  writer->Update();
300  }
301  catch ( itk::ExceptionObject & err )
302  {
303  std::cerr << "Write file " << OUTfilename << " failed " << std::endl;
304  std::cerr << err << std::endl;
305  return EXIT_FAILURE;
306  }
307 
308  if ( !itksys::SystemTools::FilesDiffer(INfilename, OUTfilename) )
309  {
310  return EXIT_SUCCESS;
311  }
312 
313  typename MeshFileReaderType::Pointer reader1 = MeshFileReaderType::New();
314  reader1->SetFileName(OUTfilename);
315  try
316  {
317  reader1->Update();
318  }
319  catch ( itk::ExceptionObject & err )
320  {
321  std::cerr << "Read file " << OUTfilename << " failed " << std::endl;
322  std::cerr << err << std::endl;
323  return EXIT_FAILURE;
324  }
325 
326  // Test points
327  if( TestPointsContainer< MeshType >( reader->GetOutput()->GetPoints(),
328  reader1->GetOutput()->GetPoints() ) == EXIT_FAILURE )
329  {
330  return EXIT_FAILURE;
331  }
332 
333 
334  // Test cells
335  if( TestCellsContainer< MeshType >( reader->GetOutput()->GetCells(),
336  reader1->GetOutput()->GetCells() ) == EXIT_FAILURE )
337  {
338  return EXIT_FAILURE;
339  }
340 
341 
342  // Test point data
343  if( TestPointDataContainer< MeshType >( reader->GetOutput()->GetPointData(),
344  reader1->GetOutput()->GetPointData() ) == EXIT_FAILURE )
345  {
346  return EXIT_FAILURE;
347  }
348 
349 
350  // Test cell data
351  if( TestCellDataContainer< MeshType >( reader->GetOutput()->GetCellData(),
352  reader1->GetOutput()->GetCellData() ) == EXIT_FAILURE )
353  {
354  return EXIT_FAILURE;
355  }
356 
357  return EXIT_SUCCESS;
358 }
359 #endif
int TestCellsContainer(typename TMesh::CellsContainerPointer cells0, typename TMesh::CellsContainerPointer cells1)
int TestPointsContainer(typename TMesh::PointsContainerPointer points0, typename TMesh::PointsContainerPointer points1)
Standard exception handling object.
virtual void Print(std::ostream &os) const
bool NotExactlyEquals(const TInput1 &x1, const TInput2 &x2)
Definition: itkMath.h:718
int TestPointDataContainer(typename TMesh::PointDataContainerPointer pointData0, typename TMesh::PointDataContainerPointer pointData1)
int TestCellDataContainer(typename TMesh::CellDataContainerPointer cellData0, typename TMesh::CellDataContainerPointer cellData1)
Writes mesh data to a single file.
static constexpr double e
The base of the natural logarithm or Euler&#39;s number
Definition: itkMath.h:53
int test(char *INfilename, char *OUTfilename, bool IsBinary)
Mesh source that reads mesh data from a single file.