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 #ifndef itkQuadraticTriangleCell_hxx
19 #define itkQuadraticTriangleCell_hxx
20 #include "itkQuadraticTriangleCell.h"
21 
22 namespace itk
23 {
24 /**
25  * Standard CellInterface:
26  */
27 template< typename TCellInterface >
28 void
29 QuadraticTriangleCell< TCellInterface >
MakeCopy(CellAutoPointer & cellPointer) const30 ::MakeCopy(CellAutoPointer & cellPointer) const
31 {
32   cellPointer.TakeOwnership(new Self);
33   cellPointer->SetPointIds( this->GetPointIds() );
34 }
35 
36 /**
37  * Standard CellInterface:
38  * Get the topological dimension of this cell.
39  */
40 template< typename TCellInterface >
41 unsigned int
42 QuadraticTriangleCell< TCellInterface >
GetDimension() const43 ::GetDimension() const
44 {
45   return Self::CellDimension;
46 }
47 
48 /**
49  * Standard CellInterface:
50  * Get the number of points required to define the cell.
51  */
52 template< typename TCellInterface >
53 unsigned int
54 QuadraticTriangleCell< TCellInterface >
GetNumberOfPoints() const55 ::GetNumberOfPoints() const
56 {
57   return Self::NumberOfPoints;
58 }
59 
60 /**
61  * Standard CellInterface:
62  * Get the number of boundary features of the given dimension.
63  */
64 template< typename TCellInterface >
65 typename QuadraticTriangleCell< TCellInterface >::CellFeatureCount
66 QuadraticTriangleCell< TCellInterface >
GetNumberOfBoundaryFeatures(int dimension) const67 ::GetNumberOfBoundaryFeatures(int dimension) const
68 {
69   switch ( dimension )
70     {
71     case 0:
72       return GetNumberOfVertices();
73     case 1:
74       return GetNumberOfEdges();
75     default:
76       return 0;
77     }
78 }
79 
80 /**
81  * Standard CellInterface:
82  * Get the boundary feature of the given dimension specified by the given
83  * cell feature Id.
84  * The Id can range from 0 to GetNumberOfBoundaryFeatures(dimension)-1.
85  */
86 template< typename TCellInterface >
87 bool
88 QuadraticTriangleCell< TCellInterface >
GetBoundaryFeature(int dimension,CellFeatureIdentifier featureId,CellAutoPointer & cellPointer)89 ::GetBoundaryFeature(int dimension, CellFeatureIdentifier featureId,
90                      CellAutoPointer & cellPointer)
91 {
92   switch ( dimension )
93     {
94     case 0:
95       {
96       VertexAutoPointer vertexPointer;
97       if ( this->GetVertex(featureId, vertexPointer) )
98         {
99         TransferAutoPointer(cellPointer, vertexPointer);
100         return true;
101         }
102       break;
103       }
104     case 1:
105       {
106       EdgeAutoPointer edgePointer;
107       if ( this->GetEdge(featureId, edgePointer) )
108         {
109         TransferAutoPointer(cellPointer, edgePointer);
110         return true;
111         }
112       break;
113       }
114     default:
115       break; // just fall through
116     }
117   cellPointer.Reset();
118   return false;
119 }
120 
121 /**
122  * Standard CellInterface:
123  * Set the point id list used by the cell.  It is assumed that the given
124  * iterator can be incremented and safely de-referenced enough times to
125  * get all the point ids needed by the cell.
126  */
127 template< typename TCellInterface >
128 void
129 QuadraticTriangleCell< TCellInterface >
SetPointIds(PointIdConstIterator first)130 ::SetPointIds(PointIdConstIterator first)
131 {
132   PointIdConstIterator ii(first);
133 
134   for ( unsigned int i = 0; i < Self::NumberOfPoints; ++i )
135     {
136     m_PointIds[i] = *ii++;
137     }
138 }
139 
140 /**
141  * Standard CellInterface:
142  * Set the point id list used by the cell.  It is assumed that the range
143  * of iterators [first, last) contains the correct number of points needed to
144  * define the cell.  The position *last is NOT referenced, so it can safely
145  * be one beyond the end of an array or other container.
146  */
147 template< typename TCellInterface >
148 void
149 QuadraticTriangleCell< TCellInterface >
SetPointIds(PointIdConstIterator first,PointIdConstIterator last)150 ::SetPointIds(PointIdConstIterator first, PointIdConstIterator last)
151 {
152   int                  localId = 0;
153   PointIdConstIterator ii(first);
154 
155   while ( ii != last )
156     {
157     m_PointIds[localId++] = *ii++;
158     }
159 }
160 
161 /**
162  * Standard CellInterface:
163  * Set an individual point identifier in the cell.
164  */
165 template< typename TCellInterface >
166 void
167 QuadraticTriangleCell< TCellInterface >
SetPointId(int localId,PointIdentifier ptId)168 ::SetPointId(int localId, PointIdentifier ptId)
169 {
170   m_PointIds[localId] = ptId;
171 }
172 
173 /**
174  * Standard CellInterface:
175  * Get a begin iterator to the list of point identifiers used by the cell.
176  */
177 template< typename TCellInterface >
178 typename QuadraticTriangleCell< TCellInterface >::PointIdIterator
179 QuadraticTriangleCell< TCellInterface >
PointIdsBegin()180 ::PointIdsBegin()
181 {
182   return &m_PointIds[0];
183 }
184 
185 /**
186  * Standard CellInterface:
187  * Get a const begin iterator to the list of point identifiers used
188  * by the cell.
189  */
190 template< typename TCellInterface >
191 typename QuadraticTriangleCell< TCellInterface >::PointIdConstIterator
192 QuadraticTriangleCell< TCellInterface >
PointIdsBegin() const193 ::PointIdsBegin() const
194 {
195   return &m_PointIds[0];
196 }
197 
198 /**
199  * Standard CellInterface:
200  * Get an end iterator to the list of point identifiers used by the cell.
201  */
202 template< typename TCellInterface >
203 typename QuadraticTriangleCell< TCellInterface >::PointIdIterator
204 QuadraticTriangleCell< TCellInterface >
PointIdsEnd()205 ::PointIdsEnd()
206 {
207   return &m_PointIds[Self::NumberOfPoints - 1] + 1;
208 }
209 
210 /**
211  * Standard CellInterface:
212  * Get a const end iterator to the list of point identifiers used
213  * by the cell.
214  */
215 template< typename TCellInterface >
216 typename QuadraticTriangleCell< TCellInterface >::PointIdConstIterator
217 QuadraticTriangleCell< TCellInterface >
PointIdsEnd() const218 ::PointIdsEnd() const
219 {
220   return &m_PointIds[Self::NumberOfPoints - 1] + 1;
221 }
222 
223 /**
224  * Triangle-specific:
225  * Get the number of vertices defining the triangle.
226  */
227 template< typename TCellInterface >
228 typename QuadraticTriangleCell< TCellInterface >::CellFeatureCount
229 QuadraticTriangleCell< TCellInterface >
GetNumberOfVertices() const230 ::GetNumberOfVertices() const
231 {
232   return Self::NumberOfVertices;
233 }
234 
235 /**
236  * Triangle-specific:
237  * Get the number of edges defined for the triangle.
238  */
239 template< typename TCellInterface >
240 typename QuadraticTriangleCell< TCellInterface >::CellFeatureCount
241 QuadraticTriangleCell< TCellInterface >
GetNumberOfEdges() const242 ::GetNumberOfEdges() const
243 {
244   return Self::NumberOfEdges;
245 }
246 
247 /**
248  * Triangle-specific:
249  * Get the vertex specified by the given cell feature Id.
250  * The Id can range from 0 to GetNumberOfVertices()-1.
251  */
252 template< typename TCellInterface >
253 bool
254 QuadraticTriangleCell< TCellInterface >
GetVertex(CellFeatureIdentifier vertexId,VertexAutoPointer & vertexPointer)255 ::GetVertex(CellFeatureIdentifier vertexId, VertexAutoPointer & vertexPointer)
256 {
257   auto * vert = new VertexType;
258 
259   vert->SetPointId(0, m_PointIds[vertexId]);
260   vertexPointer.TakeOwnership(vert);
261   return true;
262 }
263 
264 /**
265  * Triangle-specific:
266  * Get the edge specified by the given cell feature Id.
267  * The Id can range from 0 to GetNumberOfEdges()-1.
268  */
269 template< typename TCellInterface >
270 bool
271 QuadraticTriangleCell< TCellInterface >
GetEdge(CellFeatureIdentifier edgeId,EdgeAutoPointer & edgePointer)272 ::GetEdge(CellFeatureIdentifier edgeId, EdgeAutoPointer & edgePointer)
273 {
274   auto * edge = new EdgeType;
275 
276   for ( unsigned int i = 0; i < EdgeType::NumberOfPoints; ++i )
277     {
278     edge->SetPointId(i, m_PointIds[m_Edges[edgeId][i]]);
279     }
280   edgePointer.TakeOwnership(edge);
281   return true;
282 }
283 
284 /** Given the parametric coordinates of a point in the cell
285  *  determine the value of its Shape Functions
286  *  returned through an itkArray<InterpolationWeightType>).  */
287 template< typename TCellInterface >
288 void
289 QuadraticTriangleCell< TCellInterface >
EvaluateShapeFunctions(const ParametricCoordArrayType & parametricCoordinates,ShapeFunctionsArrayType & weights) const290 ::EvaluateShapeFunctions(
291   const ParametricCoordArrayType & parametricCoordinates,
292   ShapeFunctionsArrayType  & weights) const
293 {
294   if ( parametricCoordinates.size() != 3 )
295     {
296     itkGenericExceptionMacro(<< "QuadraticTriangleCell expect three coordinates");
297     }
298 
299   const double L1 = parametricCoordinates[0];
300   const double L2 = parametricCoordinates[1];
301   const double L3 = parametricCoordinates[2];
302 
303   weights = ShapeFunctionsArrayType(6);
304 
305   weights[0] = L1 * ( 2.0 * L1 - 1.0 );
306   weights[1] = L2 * ( 2.0 * L2 - 1.0 );
307   weights[2] = L3 * ( 2.0 * L3 - 1.0 );
308   weights[3] = 4.0 * L1 * L3;
309   weights[4] = 4.0 * L1 * L2;
310   weights[5] = 4.0 * L2 * L3;
311 }
312 } // end namespace itk
313 
314 #endif
315