ITK  4.6.0
Insight Segmentation and Registration Toolkit
DataRepresentation/Mesh/Mesh2.cxx
/*=========================================================================
*
* Copyright Insight Software Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
// Software Guide : BeginLatex
//
// A \doxygen{Mesh} can contain a variety of cell types. Typical cells are
// the \doxygen{LineCell}, \doxygen{TriangleCell},
// \doxygen{QuadrilateralCell} and \doxygen{TetrahedronCell}. Additional
// flexibility is provided for managing cells at the price of a bit more of
// complexity than in the case of point management.
//
// The following code creates a polygonal line in order to illustrate the
// simplest case of cell management in a Mesh. The only cell type used here is
// the LineCell. The header file of this class has to be included.
//
// \index{itk::LineCell!Header}
//
// Software Guide : EndLatex
#include "itkMesh.h"
// Software Guide : BeginCodeSnippet
#include "itkLineCell.h"
// Software Guide : EndCodeSnippet
int main(int, char *[])
{
typedef float PixelType;
typedef itk::Mesh< PixelType, 3 > MeshType;
// Software Guide : BeginLatex
//
// In order to be consistent with the Mesh, cell types have to be configured
// with a number of custom types taken from the mesh traits. The set of
// traits relevant to cells are packaged by the Mesh class into the
// \code{CellType} trait. This trait needs to be passed to the actual cell
// types at the moment of their instantiation. The following line shows how
// to extract the Cell traits from the Mesh type.
//
// \index{itk::Mesh!CellType}
// \index{itk::Mesh!traits}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef MeshType::CellType CellType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The LineCell type can now be instantiated using the traits
// taken from the Mesh.
//
// \index{itk::LineCell!Instantiation}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef itk::LineCell< CellType > LineType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The main difference in the way cells and points are managed by
// the Mesh is that points are stored by copy on the
// PointsContainer while cells are stored in the CellsContainer
// using pointers. The reason for using pointers is that cells use
// C++ polymorphism on the mesh. This means that the mesh is only
// aware of having pointers to a generic cell which is the base
// class of all the specific cell types. This architecture makes it
// possible to combine different cell types in the same
// mesh. Points, on the other hand, are of a single type and have a
// small memory footprint, which makes it efficient to copy them
// directly into the container.
//
// \index{itk::Cell!CellAutoPointer}
// \index{itk::Mesh!CellAutoPointer}
// \index{CellAutoPointer}
// \index{itk::AutoPointer}
//
// Managing cells by pointers add another level of complexity to the Mesh
// since it is now necessary to establish a protocol to make clear who is
// responsible for allocating and releasing the cells' memory. This protocol
// is implemented in the form of a specific type of pointer called the
// \code{CellAutoPointer}. This pointer, based on the \doxygen{AutoPointer},
// differs in many respects from the SmartPointer. The CellAutoPointer has an
// internal pointer to the actual object and a boolean flag that indicates
// if the CellAutoPointer is responsible for releasing the cell memory
// whenever the time comes for its own destruction. It is said that a
// \code{CellAutoPointer} \emph{owns} the cell when it is responsible for
// its destruction. Many CellAutoPointer can point to the same cell but at
// any given time, only \textbf{one} CellAutoPointer can own the cell.
//
// The \code{CellAutoPointer} trait is defined in the MeshType and can be
// extracted as illustrated in the following line.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef CellType::CellAutoPointer CellAutoPointer;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Note that the CellAutoPointer is pointing to a generic cell type. It is
// not aware of the actual type of the cell, which can be for example
// LineCell, TriangleCell or TetrahedronCell. This fact will influence the
// way in which we access cells later on.
//
// At this point we can actually create a mesh and insert some points on it.
//
// \index{itk::Mesh!New()}
// \index{itk::Mesh!SetPoint()}
// \index{itk::Mesh!PointType}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
MeshType::Pointer mesh = MeshType::New();
MeshType::PointType p0;
MeshType::PointType p1;
MeshType::PointType p2;
p0[0] = -1.0; p0[1] = 0.0; p0[2] = 0.0;
p1[0] = 1.0; p1[1] = 0.0; p1[2] = 0.0;
p2[0] = 1.0; p2[1] = 1.0; p2[2] = 0.0;
mesh->SetPoint( 0, p0 );
mesh->SetPoint( 1, p1 );
mesh->SetPoint( 2, p2 );
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The following code creates two CellAutoPointers and initializes
// them with newly created cell objects. The actual cell type
// created in this case is LineCell. Note that cells are
// created with the normal \code{new} C++ operator. The
// CellAutoPointer takes ownership of the received pointer by using
// the method \code{TakeOwnership()}. Even though this may seem
// verbose, it is necessary in order to make it explicit from the
// code that the responsibility of memory release is assumed by the
// AutoPointer.
//
// \index{itk::AutoPointer!TakeOwnership()}
// \index{CellAutoPointer!TakeOwnership()}
// \index{CellType!creation}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
CellAutoPointer line0;
CellAutoPointer line1;
line0.TakeOwnership( new LineType );
line1.TakeOwnership( new LineType );
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The LineCells should now be associated with points in the mesh. This is
// done using the identifiers assigned to points when they were inserted
// in the mesh. Every cell type has a specific number of points that must
// be associated with it.\footnote{Some cell types like polygons have a
// variable number of points associated with them.} For example a
// LineCell requires two points, a TriangleCell
// requires three and a TetrahedronCell requires four. Cells use
// an internal numbering system for points. It is simply an index in the
// range $\{0,NumberOfPoints-1\}$. The association of points and cells is
// done by the \code{SetPointId()} method which requires the user to
// provide the internal index of the point in the cell and the
// corresponding PointIdentifier in the Mesh. The internal cell index is
// the first parameter of \code{SetPointId()} while the mesh
// point-identifier is the second.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
line0->SetPointId( 0, 0 ); // line between points 0 and 1
line0->SetPointId( 1, 1 );
line1->SetPointId( 0, 1 ); // line between points 1 and 2
line1->SetPointId( 1, 2 );
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Cells are inserted in the mesh using the \code{SetCell()} method. It
// requires an identifier and the AutoPointer to the cell. The Mesh will
// take ownership of the cell to which the AutoPointer is pointing. This is
// done internally by the \code{SetCell()} method. In this way, the
// destruction of the CellAutoPointer will not induce the destruction of the
// associated cell.
//
// \index{itk::Mesh!SetCell()}
// \index{SetCell()!itk::Mesh}
// \index{itk::Mesh!Inserting cells}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
mesh->SetCell( 0, line0 );
mesh->SetCell( 1, line1 );
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// After serving as an argument of the \code{SetCell()} method, a
// CellAutoPointer no longer holds ownership of the cell. It is important
// not to use this same CellAutoPointer again as argument to
// \code{SetCell()} without first securing ownership of another cell.
//
// Software Guide : EndLatex
std::cout << "Points = " << mesh->GetNumberOfPoints() << std::endl;
// Software Guide : BeginLatex
//
// The number of Cells currently inserted in the mesh can be queried with
// the \code{GetNumberOfCells()} method.
//
// \index{itk::Mesh!GetNumberOfCells()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
std::cout << "Cells = " << mesh->GetNumberOfCells() << std::endl;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// In a way analogous to points, cells can be accessed using Iterators to
// the CellsContainer in the mesh. The trait for the cell iterator can be
// extracted from the mesh and used to define a local type.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef MeshType::CellsContainer::Iterator CellIterator;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Then the iterators to the first and past-end cell in the mesh can be
// obtained respectively with the \code{Begin()} and \code{End()} methods of
// the CellsContainer. The CellsContainer of the mesh is returned by the
// \code{GetCells()} method.
//
// \index{itk::Mesh!Iterating cells}
// \index{itk::Mesh!GetCells()}
// \index{CellsContainer!Begin()}
// \index{CellsContainer!End()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
CellIterator cellIterator = mesh->GetCells()->Begin();
CellIterator end = mesh->GetCells()->End();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Finally a standard loop is used to iterate over all the cells. Note the
// use of the \code{Value()} method used to get the actual pointer to the
// cell from the CellIterator. Note also that the values returned are
// pointers to the generic CellType. These pointers have to be down-casted
// in order to be used as actual LineCell types. Safe down-casting is
// performed with the \code{dynamic\_cast} operator which will throw an
// exception if the conversion cannot be safely performed.
//
// \index{down casting}
// \index{CellIterator!Value()}
// \index{CellIterator!increment}
// \index{itk::Mesh!CellType casting}
// \index{Print()}
// \index{CellType!Print()}
// \index{CellType!GetNumberOfPoints()}
// \index{LineCell!Print()}
// \index{LineCell!GetNumberOfPoints()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
while( cellIterator != end )
{
MeshType::CellType * cellptr = cellIterator.Value();
LineType * line = dynamic_cast<LineType *>( cellptr );
std::cout << line->GetNumberOfPoints() << std::endl;
++cellIterator;
}
// Software Guide : EndCodeSnippet
return 0;
}