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