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 itkPolygonCell_hxx
29 #define itkPolygonCell_hxx
30 #include "itkPolygonCell.h"
31 
32 namespace itk
33 {
34 /**
35  * Standard CellInterface:
36  */
37 template< typename TCellInterface >
38 void
39 PolygonCell< TCellInterface >
MakeCopy(CellAutoPointer & cellPointer) const40 ::MakeCopy(CellAutoPointer & cellPointer) const
41 {
42   auto * newPolygonCell = new Self;
43 
44   cellPointer.TakeOwnership(newPolygonCell);
45   const PointIdentifier numberOfPoints = this->GetNumberOfPoints();
46   if ( numberOfPoints )
47     {
48     newPolygonCell->SetPointIds( 0, numberOfPoints, this->GetPointIds() );
49     }
50   else
51     {
52     newPolygonCell->ClearPoints();
53     // Make sure the new cell has no points or edges
54     }
55 }
56 
57 /**
58  * Standard CellInterface:
59  * Get the topological dimension of this cell.
60  */
61 template< typename TCellInterface >
62 unsigned int
63 PolygonCell< TCellInterface >
GetDimension() const64 ::GetDimension() const
65 {
66   return Self::CellDimension;
67 }
68 
69 /**
70  * Standard CellInterface:
71  * Get the number of points required to define the cell.
72  */
73 template< typename TCellInterface >
74 unsigned int
75 PolygonCell< TCellInterface >
GetNumberOfPoints() const76 ::GetNumberOfPoints() const
77 {
78   return static_cast< unsigned int >( m_PointIds.size() );
79 }
80 
81 /**
82  * Standard CellInterface:
83  * Get the number of boundary features of the given dimension.
84  */
85 template< typename TCellInterface >
86 typename PolygonCell< TCellInterface >::CellFeatureCount
87 PolygonCell< TCellInterface >
GetNumberOfBoundaryFeatures(int dimension) const88 ::GetNumberOfBoundaryFeatures(int dimension) const
89 {
90   switch ( dimension )
91     {
92     case 0:
93       return this->GetNumberOfVertices();
94     case 1:
95       return this->GetNumberOfEdges();
96     default:
97       return 0;
98     }
99 }
100 
101 /**
102  * Standard CellInterface:
103  * Get the boundary feature of the given dimension specified by the given
104  * cell feature Id.
105  * The Id can range from 0 to GetNumberOfBoundaryFeatures(dimension)-1.
106  */
107 template< typename TCellInterface >
108 bool
109 PolygonCell< TCellInterface >
GetBoundaryFeature(int dimension,CellFeatureIdentifier featureId,CellAutoPointer & cellPointer)110 ::GetBoundaryFeature(int dimension, CellFeatureIdentifier featureId,
111                      CellAutoPointer & cellPointer)
112 {
113   switch ( dimension )
114     {
115     case 0:
116       {
117       VertexAutoPointer vertexPointer;
118       if ( this->GetVertex(featureId, vertexPointer) )
119         {
120         TransferAutoPointer(cellPointer, vertexPointer);
121         return true;
122         }
123       break;
124       }
125     case 1:
126       {
127       EdgeAutoPointer edgePointer;
128       if ( this->GetEdge(featureId, edgePointer) )
129         {
130         TransferAutoPointer(cellPointer, edgePointer);
131         return true;
132         }
133       break;
134       }
135     default:
136       break; //just fall through
137     }
138   cellPointer.Reset();
139   return false;
140 }
141 
142 /**
143  * Standard CellInterface:
144  * Set the point id list used by the cell.  It is assumed that the given
145  * iterator can be incremented and safely de-referenced enough times to
146  * get all the point ids needed by the cell.
147  */
148 template< typename TCellInterface >
149 void
150 PolygonCell< TCellInterface >
SetPointIds(int itkNotUsed (dummy),int num,PointIdConstIterator first)151 ::SetPointIds(int itkNotUsed(dummy), int num, PointIdConstIterator first)
152 {
153   PointIdConstIterator ii(first);
154 
155   m_PointIds.clear();
156   for ( int i = 0; i < num; ++i )
157     {
158     m_PointIds.push_back(*ii++);
159     }
160   this->BuildEdges();
161 }
162 
163 /**
164  * after input the points in order, generate the edge connections
165  */
166 template< typename TCellInterface >
167 void
168 PolygonCell< TCellInterface >
BuildEdges()169 ::BuildEdges()
170 {
171   if ( !m_PointIds.empty() )
172     {
173     m_Edges.resize( m_PointIds.size() );
174     const auto numberOfPoints = static_cast< unsigned int >( m_PointIds.size() );
175     for ( unsigned int i = 1; i < numberOfPoints; i++ )
176       {
177       m_Edges[i - 1][0] = i - 1;
178       m_Edges[i - 1][1] = i;
179       }
180     m_Edges[numberOfPoints - 1][0] = numberOfPoints - 1;
181     m_Edges[numberOfPoints - 1][1] = 0;
182     }
183   else
184     {
185     m_Edges.clear();
186     }
187 }
188 
189 /**
190  * Standard CellInterface:
191  * Set the point id list used by the cell.  It is assumed that the given
192  * iterator can be incremented and safely de-referenced enough times to
193  * get all the point ids needed by the cell.
194  */
195 template< typename TCellInterface >
196 void
197 PolygonCell< TCellInterface >
SetPointIds(PointIdConstIterator first)198 ::SetPointIds(PointIdConstIterator first)
199 {
200   PointIdConstIterator ii(first);
201 
202   for ( unsigned int i = 0; i < m_PointIds.size(); ++i )
203     {
204     m_PointIds[i] = *ii++;
205     }
206 }
207 
208 /**
209  * Add one points to the points list
210  */
211 template< typename TCellInterface >
212 void
213 PolygonCell< TCellInterface >
AddPointId(PointIdentifier ptID)214 ::AddPointId(PointIdentifier ptID)
215 {
216   m_PointIds.push_back(ptID);
217 }
218 
219 /**
220  * Remove one points from the points list
221  */
222 template< typename TCellInterface >
223 void
224 PolygonCell< TCellInterface >
RemovePointId(PointIdentifier ptID)225 ::RemovePointId(PointIdentifier ptID)
226 {
227   auto position = std::find(m_PointIds.begin(), m_PointIds.end(), ptID);
228   if ( position != m_PointIds.end() )
229     {
230     m_PointIds.erase(position);
231     }
232 }
233 
234 /**
235  * clear all the point and edge informations
236  */
237 template< typename TCellInterface >
238 void
239 PolygonCell< TCellInterface >
ClearPoints()240 ::ClearPoints()
241 {
242   m_PointIds.clear();
243   m_Edges.clear();
244 }
245 
246 /**
247  * Standard CellInterface:
248  * Set the point id list used by the cell.  It is assumed that the range
249  * of iterators [first, last) contains the correct number of points needed to
250  * define the cell.  The position *last is NOT referenced, so it can safely
251  * be one beyond the end of an array or other container.
252  */
253 template< typename TCellInterface >
254 void
255 PolygonCell< TCellInterface >
SetPointIds(PointIdConstIterator first,PointIdConstIterator last)256 ::SetPointIds(PointIdConstIterator first, PointIdConstIterator last)
257 {
258   PointIdConstIterator ii(first);
259 
260   m_PointIds.clear();
261   while ( ii != last )
262     {
263     m_PointIds.push_back(*ii++);
264     }
265 
266   this->BuildEdges();
267 }
268 
269 /**
270  * Standard CellInterface:
271  * Set an individual point identifier in the cell.
272  */
273 template< typename TCellInterface >
274 void
275 PolygonCell< TCellInterface >
SetPointId(int localId,PointIdentifier ptId)276 ::SetPointId(int localId, PointIdentifier ptId)
277 {
278   if ( m_PointIds.size() < (unsigned int)( localId + 1 ) )
279     {
280     m_PointIds.resize(localId + 1);
281     }
282   m_PointIds[localId] = ptId;
283 }
284 
285 /**
286  * Standard CellInterface:
287  * Get a begin iterator to the list of point identifiers used by the cell.
288  */
289 template< typename TCellInterface >
290 typename PolygonCell< TCellInterface >::PointIdIterator
291 PolygonCell< TCellInterface >
PointIdsBegin()292 ::PointIdsBegin()
293 {
294   if ( !m_PointIds.empty() )
295     {
296     return &*( m_PointIds.begin() );
297     }
298   else
299     {
300     return nullptr;
301     }
302 }
303 
304 /**
305  * Standard CellInterface:
306  * Get a const begin iterator to the list of point identifiers used
307  * by the cell.
308  */
309 template< typename TCellInterface >
310 typename PolygonCell< TCellInterface >::PointIdConstIterator
311 PolygonCell< TCellInterface >
PointIdsBegin() const312 ::PointIdsBegin() const
313 {
314   if ( !m_PointIds.empty() )
315     {
316     return &*( m_PointIds.begin() );
317     }
318   else
319     {
320     return nullptr;
321     }
322 }
323 
324 /**
325  * Standard CellInterface:
326  * Get an end iterator to the list of point identifiers used by the cell.
327  */
328 template< typename TCellInterface >
329 typename PolygonCell< TCellInterface >::PointIdIterator
330 PolygonCell< TCellInterface >
PointIdsEnd()331 ::PointIdsEnd()
332 {
333   if ( !m_PointIds.empty() )
334     {
335     return &m_PointIds[m_PointIds.size() - 1] + 1;
336     }
337   else
338     {
339     return nullptr;
340     }
341 }
342 
343 /**
344  * Standard CellInterface:
345  * Get a const end iterator to the list of point identifiers used
346  * by the cell.
347  */
348 template< typename TCellInterface >
349 typename PolygonCell< TCellInterface >::PointIdConstIterator
350 PolygonCell< TCellInterface >
PointIdsEnd() const351 ::PointIdsEnd() const
352 {
353   if ( !m_PointIds.empty() )
354     {
355     return &m_PointIds[m_PointIds.size() - 1] + 1;
356     }
357   else
358     {
359     return nullptr;
360     }
361 }
362 
363 /**
364  * Polygon-specific:
365  * Get the number of vertices defining the Polygon.
366  */
367 template< typename TCellInterface >
368 typename PolygonCell< TCellInterface >::CellFeatureCount
369 PolygonCell< TCellInterface >
GetNumberOfVertices() const370 ::GetNumberOfVertices() const
371 {
372   return static_cast< CellFeatureCount >( m_PointIds.size() );
373 }
374 
375 /**
376  * Polygon-specific:
377  * Get the number of edges defined for the Polygon.
378  */
379 template< typename TCellInterface >
380 typename PolygonCell< TCellInterface >::CellFeatureCount
381 PolygonCell< TCellInterface >
GetNumberOfEdges() const382 ::GetNumberOfEdges() const
383 {
384   return static_cast< CellFeatureCount >( m_Edges.size() );
385 }
386 
387 /**
388  * Polygon-specific:
389  * Get the vertex specified by the given cell feature Id.
390  * The Id can range from 0 to GetNumberOfVertices()-1.
391  */
392 template< typename TCellInterface >
393 bool
394 PolygonCell< TCellInterface >
GetVertex(CellFeatureIdentifier vertexId,VertexAutoPointer & vertexPointer)395 ::GetVertex(CellFeatureIdentifier vertexId, VertexAutoPointer & vertexPointer)
396 {
397   auto * vert = new VertexType;
398 
399   vert->SetPointId(0, m_PointIds[vertexId]);
400   vertexPointer.TakeOwnership(vert);
401   return true;
402 }
403 
404 /**
405  * Polygon-specific:
406  * Get the edge specified by the given cell feature Id.
407  * The Id can range from 0 to GetNumberOfEdges()-1.
408  */
409 template< typename TCellInterface >
410 bool
411 PolygonCell< TCellInterface >
GetEdge(CellFeatureIdentifier edgeId,EdgeAutoPointer & edgePointer)412 ::GetEdge(CellFeatureIdentifier edgeId, EdgeAutoPointer & edgePointer)
413 {
414   auto * edge = new EdgeType;
415   unsigned int max_pointId = this->GetNumberOfPoints() - 1;
416 
417   if ( edgeId < max_pointId )
418     {
419     edge->SetPointId(0, m_PointIds[edgeId]);
420     edge->SetPointId(1, m_PointIds[edgeId + 1]);
421     }
422   else if ( edgeId == max_pointId )
423     {
424     edge->SetPointId(0, m_PointIds[max_pointId]);
425     edge->SetPointId(1, m_PointIds[0]);
426     }
427   edgePointer.TakeOwnership(edge);
428   return true;
429 }
430 } // end namespace itk
431 
432 #endif
433