ITK  4.4.0
Insight Segmentation and Registration Toolkit
PointSet2.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
//
// The \doxygen{PointSet} class uses an internal container to manage the storage of
// \doxygen{Point}s. It is more efficient, in general, to manage points by using the
// access methods provided directly on the points container. The following
// example illustrates how to interact with the point container and how to use
// point iterators.
//
// Software Guide : EndLatex
#include "itkPointSet.h"
int main(int, char *[])
{
typedef itk::PointSet< unsigned short, 3 > PointSetType;
// Software Guide : BeginLatex
//
// The type is defined by the \emph{traits} of the PointSet
// class. The following line conveniently takes the PointsContainer type
// from the PointSet traits and declare it in the global namespace.
//
// \index{itk::PointSet!PointsContainer}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef PointSetType::PointsContainer PointsContainer;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The actual type of the PointsContainer depends on what style of
// PointSet is being used. The dynamic PointSet use the
// \doxygen{MapContainer} while the static PointSet uses the
// \doxygen{VectorContainer}. The vector and map containers are basically
// ITK wrappers around the \href{http://www.sgi.com/tech/stl/}{STL}
// classes \href{http://www.sgi.com/tech/stl/Map.html}{\code{std::map}}
// and \href{http://www.sgi.com/tech/stl/Vector.html}{\code{std::vector}}.
// By default, the PointSet uses a static style, hence the default
// type of point container is an VectorContainer. Both the map
// and vector container are templated over the type of the elements they
// contain. In this case they are templated over PointType.
// Containers are reference counted object. They are then created with the
// \code{New()} method and assigned to a \doxygen{SmartPointer} after
// creation. The following line creates a point container compatible with
// the type of the PointSet from which the trait has been taken.
//
// \index{PointsContainer!New()}
// \index{PointsContainer!Pointer}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
PointsContainer::Pointer points = PointsContainer::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Points can now be defined using the \code{PointType} trait from the
// PointSet.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef PointSetType::PointType PointType;
PointType p0;
PointType p1;
p0[0] = -1.0; p0[1] = 0.0; p0[2] = 0.0; // Point 0 = {-1,0,0 }
p1[0] = 1.0; p1[1] = 0.0; p1[2] = 0.0; // Point 1 = { 1,0,0 }
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The created points can be inserted in the PointsContainer using the
// generic method \code{InsertElement()} which requires an identifier to
// be provided for each point.
//
// \index{PointsContainer!InsertElement()}
// \index{PointsContainer!InsertElement()}
// \index{itk::VectorContainer!InsertElement()}
// \index{itk::MapContainer!InsertElement()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
unsigned int pointId = 0;
points->InsertElement( pointId++ , p0 );
points->InsertElement( pointId++ , p1 );
// Software Guide : EndCodeSnippet
PointSetType::Pointer pointSet = PointSetType::New();
// Software Guide : BeginLatex
//
// Finally the PointsContainer can be assigned to the PointSet. This will
// substitute any previously existing PointsContainer on the PointSet. The
// assignment is done using the \code{SetPoints()} method.
//
// \index{itk::PointSet!SetPoints()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
pointSet->SetPoints( points );
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The PointsContainer object can be obtained from the PointSet using the
// \code{GetPoints()} method. This method returns a pointer
// to the actual container owned by the PointSet which is then assigned to
// a SmartPointer.
//
// \index{itk::PointSet!GetPoints()}
// \index{PointsContainer!Pointer}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
PointsContainer::Pointer points2 = pointSet->GetPoints();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The most efficient way to sequentially visit the points is to use the
// iterators provided by PointsContainer. The \code{Iterator} type belongs
// to the traits of the PointsContainer classes. It behaves pretty much like
// the STL iterators.\footnote{If you dig deep enough into the code, you
// will discover that these iterators are actually ITK wrappers around STL
// iterators.} The Points iterator is not a reference counted class, so it
// is created directly from the traits without using SmartPointers.
//
// \index{PointsContainer!Iterator}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef PointsContainer::Iterator PointsIterator;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The subsequent use of the iterator follows what you may expect from a STL
// iterator. The iterator to the first point is obtained from the container
// with the \code{Begin()} method and assigned to another iterator.
//
// \index{PointsContainer!Begin()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
PointsIterator pointIterator = points->Begin();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The \code{++} operator on the iterator can be used to advance from one
// point to the next. The actual value of the Point to which the iterator is
// pointing can be obtained with the \code{Value()} method. The loop for
// walking through all the points can be controlled by comparing the current
// iterator with the iterator returned by the \code{End()} method of the
// PointsContainer. The following lines illustrate the typical loop for
// walking through the points.
//
// \index{PointsContainer!End()}
// \index{PointsContainer!Iterator}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
PointsIterator end = points->End();
while( pointIterator != end )
{
PointType p = pointIterator.Value(); // access the point
std::cout << p << std::endl; // print the point
++pointIterator; // advance to next point
}
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Note that as in STL, the iterator returned by the \code{End()} method is
// not a valid iterator. This is called a past-end iterator in order to
// indicate that it is the value resulting from advancing one step after
// visiting the last element in the container.
//
// The number of elements stored in a container can be queried with the
// \code{Size()} method. In the case of the PointSet, the following two
// lines of code are equivalent, both of them returning the number of points
// in the PointSet.
//
// \index{itk::PointSet!GetNumberOfPoints()}
// \index{itk::PointSet!GetPoints()}
// \index{PointsContainer!Size()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
std::cout << pointSet->GetNumberOfPoints() << std::endl;
std::cout << pointSet->GetPoints()->Size() << std::endl;
// Software Guide : EndCodeSnippet
return 0;
}