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