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  *
20  *  Portions of this file are subject to the VTK Toolkit Version 3 copyright.
21  *
22  *  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
23  *
24  *  For complete copyright, license and disclaimer of warranty information
25  *  please refer to the NOTICE file at the top of the ITK source tree.
26  *
27  *=========================================================================*/
28 #ifndef itkPointSet_hxx
29 #define itkPointSet_hxx
30 
31 #include "itkPointSet.h"
32 #include "itkProcessObject.h"
33 #include <algorithm>
34 
35 namespace itk
36 {
37 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
38 void
39 PointSet< TPixelType, VDimension, TMeshTraits >
PrintSelf(std::ostream & os,Indent indent) const40 ::PrintSelf(std::ostream & os, Indent indent) const
41 {
42   Superclass::PrintSelf(os, indent);
43   os << indent << "Number Of Points: "
44      << this->GetNumberOfPoints()  << std::endl;
45 
46   os << indent << "Requested Number Of Regions: "
47      << m_RequestedNumberOfRegions << std::endl;
48   os << indent << "Requested Region: " << m_RequestedRegion << std::endl;
49   os << indent << "Buffered Region: " << m_BufferedRegion << std::endl;
50   os << indent << "Maximum Number Of Regions: "
51      << m_MaximumNumberOfRegions << std::endl;
52   os << indent << "Point Data Container pointer: "
53      << ( ( this->m_PointDataContainer ) ?  this->m_PointDataContainer.GetPointer() : nullptr ) << std::endl;
54   os << indent << "Size of Point Data Container: "
55      << ( ( this->m_PointDataContainer ) ?  this->m_PointDataContainer->Size() : 0 ) << std::endl;
56 }
57 
58 /**
59  * Access routine to set the points container.
60  */
61 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
62 void
63 PointSet< TPixelType, VDimension, TMeshTraits >
SetPoints(PointsContainer * points)64 ::SetPoints(PointsContainer *points)
65 {
66   itkDebugMacro("setting Points container to " << points);
67   if ( m_PointsContainer != points )
68     {
69     m_PointsContainer = points;
70     this->Modified();
71     }
72 }
73 
74 /**
75  * Access routine to get the points container.
76  */
77 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
78 typename PointSet< TPixelType, VDimension, TMeshTraits >::PointsContainer *
79 PointSet< TPixelType, VDimension, TMeshTraits >
GetPoints()80 ::GetPoints()
81 {
82   itkDebugMacro("Starting GetPoints()");
83   if ( !m_PointsContainer )
84     {
85     this->SetPoints( PointsContainer::New() );
86     }
87   itkDebugMacro("returning Points container of " << m_PointsContainer);
88   return m_PointsContainer;
89 }
90 
91 /**
92  * Access routine to get the points container.
93  */
94 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
95 const typename PointSet< TPixelType, VDimension, TMeshTraits >::PointsContainer *
96 PointSet< TPixelType, VDimension, TMeshTraits >
GetPoints() const97 ::GetPoints() const
98 {
99   itkDebugMacro("returning Points container of " << m_PointsContainer);
100   return m_PointsContainer.GetPointer();
101 }
102 
103 /**
104  * Access routine to set the point data container.
105  */
106 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
107 void
108 PointSet< TPixelType, VDimension, TMeshTraits >
SetPointData(PointDataContainer * pointData)109 ::SetPointData(PointDataContainer *pointData)
110 {
111   itkDebugMacro("setting PointData container to " << pointData);
112   if ( m_PointDataContainer != pointData )
113     {
114     m_PointDataContainer = pointData;
115     this->Modified();
116     }
117 }
118 
119 /**
120  * Access routine to get the point data container.
121  */
122 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
123 typename PointSet< TPixelType, VDimension, TMeshTraits >::PointDataContainer *
124 PointSet< TPixelType, VDimension, TMeshTraits >
GetPointData()125 ::GetPointData()
126 {
127   if ( !m_PointDataContainer )
128     {
129     this->SetPointData( PointDataContainer::New() );
130     }
131   itkDebugMacro("returning PointData container of " << m_PointDataContainer);
132   return m_PointDataContainer;
133 }
134 
135 /**
136  * Access routine to get the point data container.
137  */
138 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
139 const typename PointSet< TPixelType, VDimension, TMeshTraits >::PointDataContainer *
140 PointSet< TPixelType, VDimension, TMeshTraits >
GetPointData() const141 ::GetPointData() const
142 {
143   itkDebugMacro("returning PointData container of "
144                 << m_PointDataContainer);
145   return m_PointDataContainer.GetPointer();
146 }
147 
148 /**
149  * Assign a point to a point identifier.  If a spot for the point identifier
150  * does not exist, it will be created automatically.
151  */
152 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
153 void
154 PointSet< TPixelType, VDimension, TMeshTraits >
SetPoint(PointIdentifier ptId,PointType point)155 ::SetPoint(PointIdentifier ptId, PointType point)
156 {
157   /**
158    * Make sure a points container exists.
159    */
160   if ( !m_PointsContainer )
161     {
162     this->SetPoints( PointsContainer::New() );
163     }
164 
165   /**
166    * Insert the point into the container with the given identifier.
167    */
168   m_PointsContainer->InsertElement(ptId, point);
169 }
170 
171 /**
172  * Check if a point exists for a given point identifier.  If a spot for
173  * the point identifier exists, "point" is set, and true is returned.
174  * Otherwise, false is returned, and "point" is not modified.
175  * If "point" is nullptr, then it is never set, but the existence of the point
176  * is still returned.
177  */
178 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
179 bool
180 PointSet< TPixelType, VDimension, TMeshTraits >
GetPoint(PointIdentifier ptId,PointType * point) const181 ::GetPoint(PointIdentifier ptId, PointType *point) const
182 {
183   /**
184    * If the points container doesn't exist, then the point doesn't either.
185    */
186   if ( !m_PointsContainer )
187     {
188     return false;
189     }
190 
191   /**
192    * Ask the container if the point identifier exists.
193    */
194   return m_PointsContainer->GetElementIfIndexExists(ptId, point);
195 }
196 
197 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
198 typename PointSet< TPixelType, VDimension, TMeshTraits >::PointType
199 PointSet< TPixelType, VDimension, TMeshTraits >
GetPoint(PointIdentifier ptId) const200 ::GetPoint(PointIdentifier ptId) const
201 {
202   /**
203    * If the points container doesn't exist, then the point doesn't either.
204    */
205   if ( !m_PointsContainer )
206     {
207     itkExceptionMacro("Point container doesn't exist.");
208     }
209 
210   /**
211    * Ask the container if the point identifier exists.
212    */
213   PointType point;
214   bool exist = m_PointsContainer->GetElementIfIndexExists(ptId, &point);
215   if( ! exist )
216     {
217     itkExceptionMacro("Point id doesn't exist: " << ptId);
218     }
219   return point;
220 }
221 
222 /**
223  * Assign data to a point identifier.  If a spot for the point identifier
224  * does not exist, it will be created automatically.  There is no check if
225  * a point with the same identifier exists.
226  */
227 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
228 void
229 PointSet< TPixelType, VDimension, TMeshTraits >
SetPointData(PointIdentifier ptId,PixelType data)230 ::SetPointData(PointIdentifier ptId, PixelType data)
231 {
232   /**
233    * Make sure a point data container exists.
234    */
235   if ( !m_PointDataContainer )
236     {
237     this->SetPointData( PointDataContainer::New() );
238     }
239 
240   /**
241    * Insert the point data into the container with the given identifier.
242    */
243   m_PointDataContainer->InsertElement(ptId, data);
244 }
245 
246 /**
247  * Check if point data exists for a given point identifier.  If a spot for
248  * the point identifier exists, "data" is set, and true is returned.
249  * Otherwise, false is returned, and "data" is not modified.
250  * If "data" is nullptr, then it is never set, but the existence of the point
251  * data is still returned.
252  */
253 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
254 bool
255 PointSet< TPixelType, VDimension, TMeshTraits >
GetPointData(PointIdentifier ptId,PixelType * data) const256 ::GetPointData(PointIdentifier ptId, PixelType *data) const
257 {
258   /**
259    * If the point data container doesn't exist, then the point data doesn't
260    * either.
261    */
262   if ( !m_PointDataContainer )
263     {
264     return false;
265     }
266 
267   /**
268    * Ask the container if the point identifier exists.
269    */
270   return m_PointDataContainer->GetElementIfIndexExists(ptId, data);
271 }
272 
273 /**
274  * Copy the geometric and topological structure of the given input pointSet.
275  * The copying is done via reference counting.
276  */
277 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
278 void
279 PointSet< TPixelType, VDimension, TMeshTraits >
PassStructure(Self *)280 ::PassStructure(Self *)
281 {
282   // IMPLEMENT ME
283 }
284 
285 /**
286  * Get the number of points in the PointsContainer.
287  */
288 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
289 typename PointSet< TPixelType, VDimension, TMeshTraits >::PointIdentifier
290 PointSet< TPixelType, VDimension, TMeshTraits >
GetNumberOfPoints() const291 ::GetNumberOfPoints() const
292 {
293   if ( m_PointsContainer )
294     {
295     return m_PointsContainer->Size();
296     }
297   return 0;
298 }
299 
300 /**
301  * Restore the PointSet to its initial state.  Useful for data pipeline updates
302  * without memory re-allocation.
303  */
304 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
305 void
306 PointSet< TPixelType, VDimension, TMeshTraits >
Initialize()307 ::Initialize()
308 {
309   Superclass::Initialize();
310 
311   m_PointsContainer = nullptr;
312   m_PointDataContainer = nullptr;
313 }
314 
315 /******************************************************************************
316  * PROTECTED METHOD DEFINITIONS
317  *****************************************************************************/
318 
319 /**
320  * A protected default constructor allows the New() routine to create an
321  * instance of PointSet.  All the containers are initialized to non-existent.
322  */
323 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
324 PointSet< TPixelType, VDimension, TMeshTraits >
PointSet()325 ::PointSet():
326   m_PointsContainer(nullptr),
327   m_PointDataContainer(nullptr)
328 {
329 
330   // If we used unstructured regions instead of structured regions, then
331   // assume this object was created by the user and this is region 0 of
332   // 1 region.
333   m_MaximumNumberOfRegions = 1;
334   m_NumberOfRegions = 1;
335   m_BufferedRegion  = -1;
336   m_RequestedNumberOfRegions = 0;
337   m_RequestedRegion = -1;
338 }
339 
340 //----------------------------------------------------------------------------
341 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
342 void
343 PointSet< TPixelType, VDimension, TMeshTraits >
UpdateOutputInformation()344 ::UpdateOutputInformation()
345 {
346   if ( this->GetSource() )
347     {
348     this->GetSource()->UpdateOutputInformation();
349     }
350 
351   // Now we should know what our largest possible region is. If our
352   // requested region was not set yet, (or has been set to something
353   // invalid - with no data in it ) then set it to the largest
354   // possible region.
355   if ( m_RequestedRegion == -1 && m_RequestedNumberOfRegions == 0 )
356     {
357     this->SetRequestedRegionToLargestPossibleRegion();
358     }
359 }
360 
361 //----------------------------------------------------------------------------
362 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
363 void
364 PointSet< TPixelType, VDimension, TMeshTraits >
SetRequestedRegionToLargestPossibleRegion()365 ::SetRequestedRegionToLargestPossibleRegion()
366 {
367   m_RequestedNumberOfRegions     = 1;
368   m_RequestedRegion           = 0;
369 }
370 
371 //----------------------------------------------------------------------------
372 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
373 void
374 PointSet< TPixelType, VDimension, TMeshTraits >
CopyInformation(const DataObject * data)375 ::CopyInformation(const DataObject *data)
376 {
377   const auto * pointSet = dynamic_cast< const PointSet * >( data );
378 
379   if ( !pointSet )
380     {
381     // pointer could not be cast back down
382     itkExceptionMacro( << "itk::PointSet::CopyInformation() cannot cast "
383                        << typeid( data ).name() << " to "
384                        << typeid( PointSet * ).name() );
385     }
386 
387   m_MaximumNumberOfRegions = pointSet->GetMaximumNumberOfRegions();
388 
389   m_NumberOfRegions = pointSet->m_NumberOfRegions;
390   m_RequestedNumberOfRegions = pointSet->m_RequestedNumberOfRegions;
391   m_BufferedRegion  = pointSet->m_BufferedRegion;
392   m_RequestedRegion = pointSet->m_RequestedRegion;
393 }
394 
395 //----------------------------------------------------------------------------
396 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
397 void
398 PointSet< TPixelType, VDimension, TMeshTraits >
Graft(const DataObject * data)399 ::Graft(const DataObject *data)
400 {
401   // Copy Meta Data
402   this->CopyInformation(data);
403 
404   const auto * pointSet = dynamic_cast< const Self * >( data );
405 
406   if ( !pointSet )
407     {
408     // pointer could not be cast back down
409     itkExceptionMacro( << "itk::PointSet::CopyInformation() cannot cast "
410                        << typeid( data ).name() << " to "
411                        << typeid( Self * ).name() );
412     }
413 
414   this->SetPoints(pointSet->m_PointsContainer);
415   this->SetPointData(pointSet->m_PointDataContainer);
416 }
417 
418 //----------------------------------------------------------------------------
419 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
420 void
421 PointSet< TPixelType, VDimension, TMeshTraits >
SetRequestedRegion(const DataObject * data)422 ::SetRequestedRegion(const DataObject *data)
423 {
424   const auto * pointSet = dynamic_cast< const Self * >( data );
425 
426   if ( pointSet )
427     {
428     // only copy the RequestedRegion if the parameter is another PointSet
429     m_RequestedRegion = pointSet->m_RequestedRegion;
430     m_RequestedNumberOfRegions = pointSet->m_RequestedNumberOfRegions;
431     }
432 }
433 
434 //----------------------------------------------------------------------------
435 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
436 void
437 PointSet< TPixelType, VDimension, TMeshTraits >
SetRequestedRegion(const RegionType & region)438 ::SetRequestedRegion(const RegionType & region)
439 {
440   if ( m_RequestedRegion != region )
441     {
442     m_RequestedRegion = region;
443     }
444 }
445 
446 //----------------------------------------------------------------------------
447 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
448 void
449 PointSet< TPixelType, VDimension, TMeshTraits >
SetBufferedRegion(const RegionType & region)450 ::SetBufferedRegion(const RegionType & region)
451 {
452   if ( m_BufferedRegion != region )
453     {
454     m_BufferedRegion = region;
455     this->Modified();
456     }
457 }
458 
459 //----------------------------------------------------------------------------
460 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
461 bool
462 PointSet< TPixelType, VDimension, TMeshTraits >
RequestedRegionIsOutsideOfTheBufferedRegion()463 ::RequestedRegionIsOutsideOfTheBufferedRegion()
464 {
465   if ( m_RequestedRegion != m_BufferedRegion
466        || m_RequestedNumberOfRegions != m_NumberOfRegions )
467     {
468     return true;
469     }
470 
471   return false;
472 }
473 
474 template< typename TPixelType, unsigned int VDimension, typename TMeshTraits >
475 bool
476 PointSet< TPixelType, VDimension, TMeshTraits >
VerifyRequestedRegion()477 ::VerifyRequestedRegion()
478 {
479   bool retval = true;
480 
481   // Are we asking for more regions than we can get?
482   if ( m_RequestedNumberOfRegions > m_MaximumNumberOfRegions )
483     {
484     itkExceptionMacro(<< "Cannot break object into "
485                       << m_RequestedNumberOfRegions << ". The limit is "
486                       << m_MaximumNumberOfRegions);
487     }
488 
489   if ( m_RequestedRegion >= m_RequestedNumberOfRegions
490        || m_RequestedRegion < 0 )
491     {
492     itkExceptionMacro(<< "Invalid update region " << m_RequestedRegion
493                       << ". Must be between 0 and "
494                       << m_RequestedNumberOfRegions - 1);
495     }
496 
497   return retval;
498 }
499 } // end namespace itk
500 
501 #endif
502