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