17 #ifndef __itkHexahedronCell_txx
18 #define __itkHexahedronCell_txx
20 #include "vnl/vnl_matrix_fixed.h"
21 #include "vnl/algo/vnl_determinant.h"
29 template <
typename TCellInterface >
34 cellPointer.TakeOwnership(
new Self );
35 cellPointer->SetPointIds(this->GetPointIds());
42 template <
typename TCellInterface>
47 return Self::CellDimension;
54 template <
typename TCellInterface>
59 return Self::NumberOfPoints;
66 template <
typename TCellInterface>
73 case 0:
return GetNumberOfVertices();
74 case 1:
return GetNumberOfEdges();
75 case 2:
return GetNumberOfFaces();
86 template <
typename TCellInterface>
90 CellAutoPointer & cellPointer )
97 if( this->GetVertex(featureId,vertexPointer) )
112 if( this->GetEdge(featureId,edgePointer) )
127 if( this->GetFace(featureId,facePointer) )
154 template <
typename TCellInterface>
159 PointIdConstIterator ii(first);
160 for(
int i=0; i < Self::NumberOfPoints; ++i )
162 m_PointIds[i] = *ii++;
173 template <
typename TCellInterface>
179 PointIdConstIterator ii(first);
183 m_PointIds[localId++] = *ii++;
191 template <
typename TCellInterface>
196 m_PointIds[localId] = ptId;
203 template <
typename TCellInterface>
208 return &m_PointIds[0];
216 template <
typename TCellInterface>
221 return &m_PointIds[0];
228 template <
typename TCellInterface>
233 return &m_PointIds[Self::NumberOfPoints-1] + 1;
241 template <
typename TCellInterface>
246 return &m_PointIds[Self::NumberOfPoints-1] + 1;
253 template <
typename TCellInterface>
258 return Self::NumberOfVertices;
265 template <
typename TCellInterface>
270 return Self::NumberOfEdges;
277 template <
typename TCellInterface>
282 return Self::NumberOfFaces;
290 template <
typename TCellInterface>
297 vertexPointer.TakeOwnership( vert );
306 template <
typename TCellInterface>
312 for(
int i=0; i < EdgeType::NumberOfPoints; ++i)
314 edge->
SetPointId(i, m_PointIds[ m_Edges[edgeId][i] ]);
316 edgePointer.TakeOwnership( edge );
326 template <
typename TCellInterface>
332 for(
unsigned int i=0; i < FaceType::NumberOfPoints; ++i)
334 face->
SetPointId(i, m_PointIds[ m_Faces[faceId][i] ]);
336 facePointer.TakeOwnership( face );
341 template <
typename TCellInterface>
345 PointsContainer* points,
346 CoordRepType* closestPoint,
347 CoordRepType pcoord[3],
349 InterpolationWeightType* weight)
351 static const int ITK_HEX_MAX_ITERATION=10;
352 static const double ITK_HEX_CONVERGED=1.e-03;
353 static const double ITK_DIVERGED = 1.e6;
355 int iteration, converged;
357 double fcol[3], rcol[3], scol[3], tcol[3];
360 CoordRepType derivs[24];
361 InterpolationWeightType weights[8];
365 CoordRepType pcoords[3];
366 pcoords[0] = pcoords[1] = pcoords[2] = params[0] = params[1] = params[2]=0.5;
369 for (iteration=converged=0;
370 !converged && (iteration < ITK_HEX_MAX_ITERATION); iteration++)
373 this->InterpolationFunctions(pcoords, weights);
374 this->InterpolationDerivs(pcoords, derivs);
377 for (
unsigned int i=0; i<3; i++)
379 fcol[i] = rcol[i] = scol[i] = tcol[i] = 0.0;
381 for (
unsigned int i=0; i<8; i++)
383 pt = points->GetElement( m_PointIds[i] );
384 for (
unsigned int j=0; j<3; j++)
386 fcol[j] += pt[j] * weights[i];
387 rcol[j] += pt[j] * derivs[i];
388 scol[j] += pt[j] * derivs[i+8];
389 tcol[j] += pt[j] * derivs[i+16];
393 for (
unsigned int i=0; i<3; i++)
399 vnl_matrix_fixed<CoordRepType,3,PointDimension> mat;
400 for(
unsigned int i=0;i<PointDimension;i++)
402 mat.put(0,i,rcol[i]);
403 mat.put(1,i,scol[i]);
404 mat.put(2,i,tcol[i]);
407 d = vnl_determinant(mat);
409 if ( vcl_abs(d) < 1.e-20)
414 vnl_matrix_fixed<CoordRepType,3,PointDimension> mat1;
415 for(
unsigned int i=0;i<PointDimension;i++)
417 mat1.put(0,i,fcol[i]);
418 mat1.put(1,i,scol[i]);
419 mat1.put(2,i,tcol[i]);
422 vnl_matrix_fixed<CoordRepType,3,PointDimension> mat2;
423 for(
unsigned int i=0;i<PointDimension;i++)
425 mat2.put(0,i,rcol[i]);
426 mat2.put(1,i,fcol[i]);
427 mat2.put(2,i,tcol[i]);
430 vnl_matrix_fixed<CoordRepType,3,PointDimension> mat3;
431 for(
unsigned int i=0;i<PointDimension;i++)
433 mat3.put(0,i,rcol[i]);
434 mat3.put(1,i,scol[i]);
435 mat3.put(2,i,fcol[i]);
438 pcoords[0] = params[0] - vnl_determinant(mat1) / d;
439 pcoords[1] = params[1] - vnl_determinant(mat2) / d;
440 pcoords[2] = params[2] - vnl_determinant(mat3) / d;
444 pcoord[0] = pcoords[0];
445 pcoord[1] = pcoords[1];
446 pcoord[2] = pcoords[2];
450 if ( ((vcl_abs(pcoords[0]-params[0])) < ITK_HEX_CONVERGED) &&
451 ((vcl_abs(pcoords[1]-params[1])) < ITK_HEX_CONVERGED) &&
452 ((vcl_abs(pcoords[2]-params[2])) < ITK_HEX_CONVERGED) )
458 else if ((vcl_abs(pcoords[0]) > ITK_DIVERGED) ||
459 (vcl_abs(pcoords[1]) > ITK_DIVERGED) ||
460 (vcl_abs(pcoords[2]) > ITK_DIVERGED))
468 params[0] = pcoords[0];
469 params[1] = pcoords[1];
470 params[2] = pcoords[2];
481 this->InterpolationFunctions(pcoords, weights);
485 for(
unsigned int i=0;i<8;i++)
487 weight[i] = weights[i];
491 if ( pcoords[0] >= -0.001 && pcoords[0] <= 1.001 &&
492 pcoords[1] >= -0.001 && pcoords[1] <= 1.001 &&
493 pcoords[2] >= -0.001 && pcoords[2] <= 1.001 )
497 closestPoint[0] = x[0]; closestPoint[1] = x[1]; closestPoint[2] = x[2];
504 CoordRepType pc[3], w[8];
507 for (
unsigned int i=0; i<3; i++)
509 if (pcoords[i] < 0.0)
513 else if (pcoords[i] > 1.0)
522 this->EvaluateLocation(subId, points, pc, closestPoint, (InterpolationWeightType *)w);
525 for(
unsigned int i=0;i<3;i++)
527 *dist2 += (closestPoint[i]-x[i])*(closestPoint[i]-x[i]);
535 template <
typename TCellInterface>
540 const double rm = 1. - pcoords[0];
541 const double sm = 1. - pcoords[1];
542 const double tm = 1. - pcoords[2];
545 sf[1] = pcoords[0]*sm*tm;
546 sf[2] = pcoords[0]*pcoords[1]*tm;
547 sf[3] = rm*pcoords[1]*tm;
548 sf[4] = rm*sm*pcoords[2];
549 sf[5] = pcoords[0]*sm*pcoords[2];
550 sf[6] = pcoords[0]*pcoords[1]*pcoords[2];
551 sf[7] = rm*pcoords[1]*pcoords[2];
555 template <
typename TCellInterface>
560 const double rm = 1. - pcoords[0];
561 const double sm = 1. - pcoords[1];
562 const double tm = 1. - pcoords[2];
567 derivs[2] = pcoords[1]*tm;
568 derivs[3] = -pcoords[1]*tm;
569 derivs[4] = -sm*pcoords[2];
570 derivs[5] = sm*pcoords[2];
571 derivs[6] = pcoords[1]*pcoords[2];
572 derivs[7] = -pcoords[1]*pcoords[2];
576 derivs[9] = -pcoords[0]*tm;
577 derivs[10] = pcoords[0]*tm;
579 derivs[12] = -rm*pcoords[2];
580 derivs[13] = -pcoords[0]*pcoords[2];
581 derivs[14] = pcoords[0]*pcoords[2];
582 derivs[15] = rm*pcoords[2];
586 derivs[17] = -pcoords[0]*sm;
587 derivs[18] = -pcoords[0]*pcoords[1];
588 derivs[19] = -rm*pcoords[1];
590 derivs[21] = pcoords[0]*sm;
591 derivs[22] = pcoords[0]*pcoords[1];
592 derivs[23] = rm*pcoords[1];
596 template <
typename TCellInterface>
600 CoordRepType x[3], InterpolationWeightType *weights)
603 this->InterpolationFunctions(pcoords, weights);
604 x[0] = x[1] = x[2] = 0.0;
605 for (
unsigned int i=0; i<8; i++)
607 pt = points->GetElement( m_PointIds[i] );
609 for (
unsigned int j=0; j<3; j++)
611 x[j] += pt[j] * weights[i];