/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: PointSet3.cxx,v $
  Language:  C++
  Date:      $Date: 2005/02/08 03:51:53 $
  Version:   $Revision: 1.14 $

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

//  Software Guide : BeginLatex
//
//  The \doxygen{PointSet} class was designed to interact with the Image class.
//  For this reason it was found convenient to allow the points in the set to
//  hold values that could be computed from images. The value associated with
//  the point is referred as \code{PixelType} in order to make it consistent
//  with image terminology. Users can define the type as they please thanks to
//  the flexibility offered by the Generic Programming approach used in the
//  toolkit.  The \code{PixelType} is the first template parameter of the
//  PointSet.
//
//  \index{itk::PointSet!PixelType}
//
//  Software Guide : EndLatex 


#include "itkPointSet.h"

int main(int, char *[])
{
  //  Software Guide : BeginLatex
  //
  //  The following code defines a particular type for a pixel type and
  //  instantiates a PointSet class with it.
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet
  typedef unsigned short  PixelType;
  typedef itk::PointSet< PixelType, 3 > PointSetType;
  // Software Guide : EndCodeSnippet


  // A point set is instantiated here
  PointSetType::Pointer  pointSet = PointSetType::New();


  //  Software Guide : BeginLatex
  //
  //  Data can be inserted into the PointSet using the \code{SetPointData()}
  //  method. This method requires the user to provide an identifier. The data
  //  in question will be associated to the point holding the same identifier.
  //  It is the user's responsibility to verify the appropriate matching between
  //  inserted data and inserted points. The following line illustrates the use
  //  of the \code{SetPointData()} method.
  //
  //  \index{itk::PointSet!SetPointData()}
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet
  unsigned int dataId =  0;
  PixelType value     = 79;
  pointSet->SetPointData( dataId++, value );   
  // Software Guide : EndCodeSnippet


  //  Software Guide : BeginLatex
  //
  //  Data associated with points can be read from the PointSet using the
  //  \code{GetPointData()} method. This method requires the user to provide
  //  the identifier to the point and a valid pointer to a location where the
  //  pixel data can be safely written. In case the identifier does not match
  //  any existing identifier on the PointSet the method will return
  //  \code{false} and the pixel value returned will be invalid. It is the
  //  user's responsibility to check the returned boolean value before
  //  attempting to use it.
  //
  //  \index{itk::PointSet!GetPointData()}
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet

  const bool found = pointSet->GetPointData( dataId, & value );   
  if( found ) 
    {
    std::cout << "Pixel value = " << value << std::endl;
    }
  // Software Guide : EndCodeSnippet



  //  Software Guide : BeginLatex
  //
  //  The \code{SetPointData()} and \code{GetPointData()} methods are not the
  //  most efficient way to get access to point data. It is far more efficient
  //  to use the Iterators provided by the \code{PointDataContainer}. 
  //
  //  Data associated with points is internally stored in
  //  \code{PointDataContainer}s.  In the same way as with points, the actual
  //  container type used depend on whether the style of the PointSet is static
  //  or dynamic. Static point sets will use an \doxygen{VectorContainer} while
  //  dynamic point sets will use an \doxygen{MapContainer}.  The type of the
  //  data container is defined as one of the traits in the PointSet. The
  //  following declaration illustrates how the type can be taken from the
  //  traits and used to conveniently declare a similar type on the global
  //  namespace.
  //
  //  \index{itk::PointSet!PointDataContainer}
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet
  typedef PointSetType::PointDataContainer      PointDataContainer;
  // Software Guide : EndCodeSnippet


  //  Software Guide : BeginLatex
  //
  //  Using the type it is now possible to create an instance of the data
  //  container. This is a standard reference counted object, henceforth it
  //  uses the \code{New()} method for creation and assigns the newly created
  //  object to a SmartPointer.
  //
  //  \index{PointDataContainer!New()}
  //  \index{PointDataContainer!Pointer}
  //
  //  Software Guide : EndLatex 


  // Software Guide : BeginCodeSnippet
  PointDataContainer::Pointer pointData = PointDataContainer::New();
  // Software Guide : EndCodeSnippet


  //  Software Guide : BeginLatex
  //
  //  Pixel data can be inserted in the container with the method
  //  \code{InsertElement()}. This method requires an identified to be provided
  //  for each point data.
  //
  //  \index{PointDataContainer!InsertElement()}
  //  \index{itk::VectorContainer!InsertElement()}
  //  \index{itk::MapContainer!InsertElement()}
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet
  unsigned int pointId = 0;
  
  PixelType value0 = 34;
  PixelType value1 = 67;

  pointData->InsertElement( pointId++ , value0 );
  pointData->InsertElement( pointId++ , value1 );
  // Software Guide : EndCodeSnippet


  //  Software Guide : BeginLatex
  //
  //  Finally the PointDataContainer can be assigned to the PointSet. This will
  //  substitute any previously existing PointDataContainer on the PointSet. The
  //  assignment is done using the \code{SetPointData()} method.
  //
  //  \index{itk::PointSet!SetPointData()}
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet
  pointSet->SetPointData( pointData );
  // Software Guide : EndCodeSnippet


  //  Software Guide : BeginLatex
  //
  //  The PointDataContainer can be obtained from the PointSet using the
  //  \code{GetPointData()} method.  This method returns a pointer (assigned to
  //  a SmartPointer) to the actual container owned by the PointSet.
  //
  //  \index{itk::PointSet!GetPointData()}
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet
  PointDataContainer::Pointer  pointData2 = pointSet->GetPointData();   
  // Software Guide : EndCodeSnippet


  //  Software Guide : BeginLatex
  //
  //  The most efficient way to sequentially visit the data associated with
  //  points is to use the iterators provided by \code{PointDataContainer}. The
  //  \code{Iterator} type belongs to the traits of the PointsContainer
  //  classes. The iterator is not a reference counted class, so it is just
  //  created directly from the traits without using SmartPointers.
  //
  //  \index{PointDataContainer!Iterator}
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet
  typedef PointDataContainer::Iterator     PointDataIterator;
  // 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{PointDataContainer!Begin()}
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet
  PointDataIterator  pointDataIterator = pointData2->Begin();  
  // Software Guide : EndCodeSnippet


  //  Software Guide : BeginLatex
  //
  //  The \code{++} operator on the iterator can be used to advance from one
  //  data point to the next. The actual value of the PixelType to which the
  //  iterator is pointing can be obtained with the \code{Value()}
  //  method. The loop for walking through all the point data 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 point data.
  //
  //  \index{PointDataContainer!End()}
  //  \index{PointDataContainer!increment ++}
  //
  //  Software Guide : EndLatex 

  // Software Guide : BeginCodeSnippet
  PointDataIterator end = pointData2->End();
  while( pointDataIterator != end ) 
    {
    PixelType p = pointDataIterator.Value();  // access the pixel data
    std::cout << p << std::endl;              // print the pixel data
    ++pointDataIterator;                      // advance to next pixel/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 \emph{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.
  // 
  //  Software Guide : EndLatex 


  return 0;
}



