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