00001 /*========================================================================= 00002 00003 Program: Insight Segmentation & Registration Toolkit 00004 Module: $RCSfile: PointSet2.cxx,v $ 00005 Language: C++ 00006 Date: $Date: 2005/11/19 16:31:49 $ 00007 Version: $Revision: 1.18 $ 00008 00009 Copyright (c) Insight Software Consortium. All rights reserved. 00010 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 #if defined(_MSC_VER) 00018 #pragma warning ( disable : 4786 ) 00019 #endif 00020 00021 // Software Guide : BeginLatex 00022 // 00023 // The \doxygen{PointSet} class uses an internal container to manage the storage of 00024 // \doxygen{Point}s. It is more efficient, in general, to manage points by using the 00025 // access methods provided directly on the points container. The following 00026 // example illustrates how to interact with the point container and how to use 00027 // point iterators. 00028 // 00029 // Software Guide : EndLatex 00030 00031 00032 #include "itkPointSet.h" 00033 00034 int main(int, char *[]) 00035 { 00036 typedef itk::PointSet< unsigned short, 3 > PointSetType; 00037 00038 // Software Guide : BeginLatex 00039 // 00040 // The type is defined by the \emph{traits} of the PointSet 00041 // class. The following line conveniently takes the PointsContainer type 00042 // from the PointSet traits and declare it in the global namespace. 00043 // 00044 // \index{itk::PointSet!PointsContainer} 00045 // 00046 // Software Guide : EndLatex 00047 00048 // Software Guide : BeginCodeSnippet 00049 typedef PointSetType::PointsContainer PointsContainer; 00050 // Software Guide : EndCodeSnippet 00051 00052 // Software Guide : BeginLatex 00053 // 00054 // The actual type of the PointsContainer depends on what style of 00055 // PointSet is being used. The dynamic PointSet use the 00056 // \doxygen{MapContainer} while the static PointSet uses the 00057 // \doxygen{VectorContainer}. The vector and map containers are basically 00058 // ITK wrappers around the \href{http://www.sgi.com/tech/stl/}{STL} 00059 // classes \href{http://www.sgi.com/tech/stl/Map.html}{\code{std::map}} 00060 // and \href{http://www.sgi.com/tech/stl/Vector.html}{\code{std::vector}}. 00061 // By default, the PointSet uses a static style, hence the default 00062 // type of point container is an VectorContainer. Both the map 00063 // and vector container are templated over the type of the elements they 00064 // contain. In this case they are templated over PointType. 00065 // Containers are reference counted object. They are then created with the 00066 // \code{New()} method and assigned to a \doxygen{SmartPointer} after 00067 // creation. The following line creates a point container compatible with 00068 // the type of the PointSet from which the trait has been taken. 00069 // 00070 // \index{PointsContainer!New()} 00071 // \index{PointsContainer!Pointer} 00072 // 00073 // Software Guide : EndLatex 00074 00075 00076 // Software Guide : BeginCodeSnippet 00077 PointsContainer::Pointer points = PointsContainer::New(); 00078 // Software Guide : EndCodeSnippet 00079 00080 00081 // Software Guide : BeginLatex 00082 // 00083 // Points can now be defined using the \code{PointType} trait from the 00084 // PointSet. 00085 // 00086 // Software Guide : EndLatex 00087 00088 // Software Guide : BeginCodeSnippet 00089 typedef PointSetType::PointType PointType; 00090 PointType p0; 00091 PointType p1; 00092 p0[0] = -1.0; p0[1] = 0.0; p0[2] = 0.0; // Point 0 = {-1,0,0 } 00093 p1[0] = 1.0; p1[1] = 0.0; p1[2] = 0.0; // Point 1 = { 1,0,0 } 00094 // Software Guide : EndCodeSnippet 00095 00096 00097 // Software Guide : BeginLatex 00098 // 00099 // The created points can be inserted in the PointsContainer using the 00100 // generic method \code{InsertElement()} which requires an identifier to 00101 // be provided for each point. 00102 // 00103 // \index{PointsContainer!InsertElement()} 00104 // \index{PointsContainer!InsertElement()} 00105 // \index{itk::VectorContainer!InsertElement()} 00106 // \index{itk::MapContainer!InsertElement()} 00107 // 00108 // Software Guide : EndLatex 00109 00110 // Software Guide : BeginCodeSnippet 00111 unsigned int pointId = 0; 00112 points->InsertElement( pointId++ , p0 ); 00113 points->InsertElement( pointId++ , p1 ); 00114 // Software Guide : EndCodeSnippet 00115 00116 PointSetType::Pointer pointSet = PointSetType::New(); 00117 00118 00119 // Software Guide : BeginLatex 00120 // 00121 // Finally the PointsContainer can be assigned to the PointSet. This will 00122 // substitute any previously existing PointsContainer on the PointSet. The 00123 // assignment is done using the \code{SetPoints()} method. 00124 // 00125 // \index{itk::PointSet!SetPoints()} 00126 // 00127 // Software Guide : EndLatex 00128 00129 // Software Guide : BeginCodeSnippet 00130 pointSet->SetPoints( points ); 00131 // Software Guide : EndCodeSnippet 00132 00133 00134 // Software Guide : BeginLatex 00135 // 00136 // The PointsContainer object can be obtained from the PointSet using the 00137 // \code{GetPoints()} method. This method returns a pointer 00138 // to the actual container owned by the PointSet which is then assigned to 00139 // a SmartPointer. 00140 // 00141 // \index{itk::PointSet!GetPoints()} 00142 // \index{PointsContainer!Pointer} 00143 // 00144 // Software Guide : EndLatex 00145 00146 00147 // Software Guide : BeginCodeSnippet 00148 PointsContainer::Pointer points2 = pointSet->GetPoints(); 00149 // Software Guide : EndCodeSnippet 00150 00151 00152 // Software Guide : BeginLatex 00153 // 00154 // The most efficient way to sequentially visit the points is to use the 00155 // iterators provided by PointsContainer. The \code{Iterator} type belongs 00156 // to the traits of the PointsContainer classes. It behaves pretty much like 00157 // the STL iterators.\footnote{If you dig deep enough into the code, you 00158 // will discover that these iterators are actually ITK wrappers around STL 00159 // iterators.} The Points iterator is not a reference counted class, so it 00160 // is created directly from the traits without using SmartPointers. 00161 // 00162 // \index{PointsContainer!Iterator} 00163 // 00164 // Software Guide : EndLatex 00165 00166 // Software Guide : BeginCodeSnippet 00167 typedef PointsContainer::Iterator PointsIterator; 00168 // Software Guide : EndCodeSnippet 00169 00170 00171 // Software Guide : BeginLatex 00172 // 00173 // The subsequent use of the iterator follows what you may expect from a STL 00174 // iterator. The iterator to the first point is obtained from the container 00175 // with the \code{Begin()} method and assigned to another iterator. 00176 // 00177 // \index{PointsContainer!Begin()} 00178 // 00179 // Software Guide : EndLatex 00180 00181 // Software Guide : BeginCodeSnippet 00182 PointsIterator pointIterator = points->Begin(); 00183 // Software Guide : EndCodeSnippet 00184 00185 00186 // Software Guide : BeginLatex 00187 // 00188 // The \code{++} operator on the iterator can be used to advance from one 00189 // point to the next. The actual value of the Point to which the iterator is 00190 // pointing can be obtained with the \code{Value()} method. The loop for 00191 // walking through all the points can be controlled by comparing the current 00192 // iterator with the iterator returned by the \code{End()} method of the 00193 // PointsContainer. The following lines illustrate the typical loop for 00194 // walking through the points. 00195 // 00196 // \index{PointsContainer!End()} 00197 // \index{PointsContainer!Iterator} 00198 // 00199 // Software Guide : EndLatex 00200 00201 // Software Guide : BeginCodeSnippet 00202 PointsIterator end = points->End(); 00203 while( pointIterator != end ) 00204 { 00205 PointType p = pointIterator.Value(); // access the point 00206 std::cout << p << std::endl; // print the point 00207 ++pointIterator; // advance to next point 00208 } 00209 // Software Guide : EndCodeSnippet 00210 00211 00212 // Software Guide : BeginLatex 00213 // 00214 // Note that as in STL, the iterator returned by the \code{End()} method is 00215 // not a valid iterator. This is called a past-end iterator in order to 00216 // indicate that it is the value resulting from advancing one step after 00217 // visiting the last element in the container. 00218 // 00219 // The number of elements stored in a container can be queried with the 00220 // \code{Size()} method. In the case of the PointSet, the following two 00221 // lines of code are equivalent, both of them returning the number of points 00222 // in the PointSet. 00223 // 00224 // \index{itk::PointSet!GetNumberOfPoints()} 00225 // \index{itk::PointSet!GetPoints()} 00226 // \index{PointsContainer!Size()} 00227 // 00228 // Software Guide : EndLatex 00229 00230 00231 // Software Guide : BeginCodeSnippet 00232 std::cout << pointSet->GetNumberOfPoints() << std::endl; 00233 std::cout << pointSet->GetPoints()->Size() << std::endl; 00234 // Software Guide : EndCodeSnippet 00235 00236 return 0; 00237 } 00238 00239 00240