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 "itkDefaultDynamicMeshTraits.h"
20 #include "itkTetrahedronCell.h"
21 
22 // Software Guide : BeginLatex
23 //
24 // \index{itk::MeshSpatialObject}
25 //
26 // A \doxygen{MeshSpatialObject} contains a pointer to an \doxygen{Mesh} but adds the
27 // notion of spatial transformations and parent-child hierarchy.
28 // This example shows how to create an \doxygen{MeshSpatialObject},
29 // use it to form a binary image, and write the mesh to disk.
30 //
31 // Let's begin by including the appropriate header file.
32 //
33 // Software Guide : EndLatex
34 
35 // Software Guide : BeginCodeSnippet
36 #include "itkSpatialObjectToImageFilter.h"
37 #include "itkMeshSpatialObject.h"
38 #include "itkSpatialObjectReader.h"
39 #include "itkSpatialObjectWriter.h"
40 // Software Guide : EndCodeSnippet
41 
main(int,char * [])42 int main(int, char * [] )
43 {
44   // Software Guide : BeginLatex
45   //
46   // The \code{MeshSpatialObject} wraps an \doxygen{Mesh}, therefore we first
47   // create a mesh.
48   //
49   // Software Guide : EndLatex
50 
51   // Software Guide : BeginCodeSnippet
52   using MeshTrait = itk::DefaultDynamicMeshTraits< float, 3, 3 >;
53   using MeshType = itk::Mesh< float, 3, MeshTrait >;
54   using CellTraits = MeshType::CellTraits;
55   using CellInterfaceType = itk::CellInterface< float, CellTraits >;
56   using TetraCellType = itk::TetrahedronCell< CellInterfaceType >;
57   using PointType = MeshType::PointType;
58   using CellType = MeshType::CellType;
59   using CellAutoPointer = CellType::CellAutoPointer;
60   // Software Guide : EndCodeSnippet
61 
62   // Software Guide : BeginCodeSnippet
63   MeshType::Pointer myMesh = MeshType::New();
64 
65   MeshType::CoordRepType testPointCoords[4][3]
66     = { {0,0,0}, {9,0,0}, {9,9,0}, {0,0,9} };
67 
68   MeshType::PointIdentifier tetraPoints[4] = {0,1,2,4};
69 
70   int i;
71   for(i=0; i < 4; ++i)
72     {
73     myMesh->SetPoint(i, PointType(testPointCoords[i]));
74     }
75 
76   myMesh->SetCellsAllocationMethod(
77       MeshType::CellsAllocatedDynamicallyCellByCell );
78   CellAutoPointer testCell1;
79   testCell1.TakeOwnership(  new TetraCellType );
80   testCell1->SetPointIds(tetraPoints);
81   // Software Guide : EndCodeSnippet
82 
83   // Software Guide : BeginCodeSnippet
84   myMesh->SetCell(0, testCell1 );
85   // Software Guide : EndCodeSnippet
86 
87   // Software Guide : BeginLatex
88   //
89   // We then create a \code{MeshSpatialObject} which is templated over the type of mesh
90   // previously defined...
91   //
92   // Software Guide : EndLatex
93 
94   // Software Guide : BeginCodeSnippet
95   using MeshSpatialObjectType = itk::MeshSpatialObject< MeshType >;
96   MeshSpatialObjectType::Pointer myMeshSpatialObject
97     = MeshSpatialObjectType::New();
98   // Software Guide : EndCodeSnippet
99 
100   // Software Guide : BeginLatex
101   //
102   // ... and pass the Mesh pointer to the \code{MeshSpatialObject}
103   //
104   // Software Guide : EndLatex
105 
106   // Software Guide : BeginCodeSnippet
107   myMeshSpatialObject->SetMesh(myMesh);
108   myMeshSpatialObject->Update();
109   // Software Guide : EndCodeSnippet
110 
111   // Software Guide : BeginLatex
112   //
113   // The actual pointer to the passed mesh can be retrieved using the
114   // \code{GetMesh()} function, just like any other SpatialObjects.
115   //
116   // Software Guide : EndLatex
117 
118   // Software Guide : BeginCodeSnippet
119   myMeshSpatialObject->GetMesh();
120   // Software Guide : EndCodeSnippet
121 
122   // Software Guide : BeginLatex
123   //
124   // The \code{GetBoundingBoxInWorldSpace()}, \code{ValueAtInWorldSpace()},
125   // \code{IsInsideInWorldSpace()}, and related functions in ObjectSpace
126   // can be used to access important information.
127   //
128   // Software Guide : EndLatex
129 
130   // Software Guide : BeginCodeSnippet
131   std::cout << "Mesh bounds : "
132     << myMeshSpatialObject->GetMyBoundingBoxInWorldSpace()->GetBounds()
133     << std::endl;
134   MeshSpatialObjectType::PointType myPhysicalPoint;
135   myPhysicalPoint.Fill(1);
136   std::cout << "Is my physical point inside? : "
137     << myMeshSpatialObject->IsInsideInWorldSpace(myPhysicalPoint) << std::endl;
138   // Software Guide : EndCodeSnippet
139 
140   // Software Guide : BeginLatex
141   //
142   // Now that we have defined the \code{MeshSpatialObject}, we can save the actual mesh
143   // using the \doxygen{SpatialObjectWriter}. In order to do so,
144   // we need to specify the type of Mesh we are writing.
145   //
146   // Software Guide : EndLatex
147 
148   // Software Guide : BeginCodeSnippet
149   using WriterType = itk::SpatialObjectWriter< 3, float, MeshTrait >;
150   WriterType::Pointer writer = WriterType::New();
151   // Software Guide : EndCodeSnippet
152 
153   // Software Guide : BeginLatex
154   //
155   // Then we set the mesh spatial object and the name of the file and call the
156   // the \code{Update()} function.
157   //
158   // Software Guide : EndLatex
159 
160   // Software Guide : BeginCodeSnippet
161   writer->SetInput(myMeshSpatialObject);
162   writer->SetFileName("myMesh.meta");
163   writer->Update();
164   // Software Guide : EndCodeSnippet
165 
166   // Software Guide : BeginLatex
167   //
168   // Reading the saved mesh is done using the \doxygen{SpatialObjectReader}.
169   // Once again we need to specify the type of mesh we intend to read.
170   //
171   // Software Guide : EndLatex
172 
173   // Software Guide : BeginCodeSnippet
174   using ReaderType = itk::SpatialObjectReader< 3, float, MeshTrait >;
175   ReaderType::Pointer reader = ReaderType::New();
176   // Software Guide : EndCodeSnippet
177 
178   // Software Guide : BeginLatex
179   //
180   // We set the name of the file we want to read and call update
181   //
182   // Software Guide : EndLatex
183 
184   // Software Guide : BeginCodeSnippet
185   reader->SetFileName("myMesh.meta");
186   reader->Update();
187   // Software Guide : EndCodeSnippet
188 
189   // Software Guide : BeginLatex
190   //
191   // Next, we show how to create a binary image of a \code{MeshSpatialObject}
192   // using the \doxygen{SpatialObjectToImageFilter}. The resulting image
193   // will have ones inside and zeros outside the mesh.
194   // First we define and instantiate the SpatialObjectToImageFilter.
195   //
196   // Software Guide : EndLatex
197 
198   // Software Guide : BeginCodeSnippet
199   using ImageType = itk::Image< unsigned char, 3 >;
200   using GroupType = itk::GroupSpatialObject< 3 >;
201   using SpatialObjectToImageFilterType =
202       itk::SpatialObjectToImageFilter< GroupType, ImageType >;
203   SpatialObjectToImageFilterType::Pointer imageFilter =
204     SpatialObjectToImageFilterType::New();
205   // Software Guide : EndCodeSnippet
206 
207   // Software Guide : BeginLatex
208   //
209   // Then we pass the output of the reader, i.e the \code{MeshSpatialObject}, to the
210   // filter.
211   //
212   // Software Guide : EndLatex
213 
214   // Software Guide : BeginCodeSnippet
215   imageFilter->SetInput(  reader->GetGroup()  );
216   // Software Guide : EndCodeSnippet
217 
218   //  Software Guide : BeginLatex
219   //
220   //  Finally we trigger the execution of the filter by calling the
221   //  \code{Update()} method. Note that depending on the size of the mesh,
222   //  the computation time can increase significantly.
223   //  \index{itk::SpatialObjectToImageFilter!Update()}
224   //
225   //  Software Guide : EndLatex
226 
227   //  Software Guide : BeginCodeSnippet
228   imageFilter->Update();
229   //  Software Guide : EndCodeSnippet
230 
231   //  Software Guide : BeginLatex
232   //
233   //  Then we can get the resulting binary image using the \code{GetOutput()} function.
234   //
235   //  Software Guide : EndLatex
236 
237   //  Software Guide : BeginCodeSnippet
238   ImageType::Pointer myBinaryMeshImage = imageFilter->GetOutput();
239   //  Software Guide : EndCodeSnippet
240 
241   return EXIT_SUCCESS;
242 }
243