17 #ifndef __itkDeformableMesh3DFilter_txx
18 #define __itkDeformableMesh3DFilter_txx
21 #pragma warning ( disable : 4786 )
25 #include "itkNumericTraits.h"
30 template <
typename TInputMesh,
typename TOutputMesh>
40 m_Stiffness.Fill( 0.1 );
42 m_PotentialMagnitude = NumericTraits<PixelType>::One;
43 m_GradientMagnitude = NumericTraits<PixelType>::One;
49 typename TOutputMesh::Pointer output = TOutputMesh::New();
54 template <
typename TInputMesh,
typename TOutputMesh>
67 template <
typename TInputMesh,
typename TOutputMesh>
72 Superclass::PrintSelf(os,indent);
73 os << indent <<
"Stiffness = " << m_Stiffness;
74 os << indent <<
"PotentialMagnitude = "
75 <<
static_cast<typename NumericTraits<PixelType>::PrintType
>(m_PotentialMagnitude)
77 os << indent <<
"GradientMagnitude = "
78 <<
static_cast<typename NumericTraits<PixelType>::PrintType
>(m_GradientMagnitude)
80 os << indent <<
"Scale = " << m_Scale;
81 os << indent <<
"TimeStep = " << m_TimeStep << std::endl;
82 os << indent <<
"PotentialOn = " << m_PotentialOn << std::endl;
83 os << indent <<
"ObjectLabel = "
84 <<
static_cast<typename NumericTraits<unsigned char>::PrintType
>(m_ObjectLabel)
86 os << indent <<
"StepThreshold = " << m_StepThreshold << std::endl;
89 os << indent <<
"Normals = " << m_Normals << std::endl;
93 os << indent <<
"Normals = " <<
"(None)" << std::endl;
97 os << indent <<
"Gradient = " << m_Gradient << std::endl;
101 os << indent <<
"Gradient = " <<
"(None)" << std::endl;
103 os << indent <<
"Step = " << m_Step << std::endl;
104 os << indent <<
"ImageDepth = " << m_ImageDepth << std::endl;
105 os << indent <<
"ImageHeight = " << m_ImageHeight << std::endl;
106 os << indent <<
"ImageWidth = " << m_ImageWidth << std::endl;
111 template <
typename TInputMesh,
typename TOutputMesh>
116 m_NumberOfNodes = this->GetInput(0)->GetNumberOfPoints();
117 m_NumberOfCells = this->GetInput(0)->GetNumberOfCells();
119 m_Forces = InputMeshType::New();
120 m_Displacements = InputMeshType::New();
121 m_Derives = InputMeshType::New();
122 m_Normals = InputMeshType::New();
123 m_Locations = InputMeshType::New();
130 myForces->Reserve(m_NumberOfNodes);
134 myDerives->Reserve(m_NumberOfNodes);
138 myDisplacements->Reserve(m_NumberOfNodes);
142 myNormals->Reserve(m_NumberOfNodes);
146 myLocations->Reserve(m_NumberOfNodes);
157 m_ImageWidth = ImageSize[0];
158 m_ImageHeight = ImageSize[1];
159 m_ImageDepth = ImageSize[2];
162 m_ModelXDownLimit = m_ImageWidth;
164 m_ModelYDownLimit = m_ImageHeight;
166 m_ModelZDownLimit = m_ImageDepth;
171 while( points != myPoints->End() )
173 for (
int i=0; i<3; i++ )
175 locations.Value()[i] = m_Scale[i] * points.Value()[i];
185 displacements.Value() = d;
187 m_Forces->SetPointData(j, 0.0);
191 const unsigned long *tp;
195 while( cells != myCells->End() )
197 typename InputMeshType::CellType * cellPtr = cells.Value();
198 tp = cellPtr->GetPointIds();
199 for (
int i=0; i<3; i++ ) {
200 m_Forces->GetPointData((
int)(tp[i]), x_pt);
202 m_Forces->SetPointData((
int)(tp[i]), x);
207 this->SetDefaultStiffnessMatrix();
211 outputMesh->SetBufferedRegion( outputMesh->GetRequestedRegion() );
215 template <
typename TInputMesh,
typename TOutputMesh>
222 double a = us*us, b = vs*vs;
223 double area = us*vs/2, k00, k01, k02, k11, k12, k22;
225 k00 = area * (m_Stiffness[1]/a + m_Stiffness[1]/b + m_Stiffness[0]);
226 k01 = area * (-m_Stiffness[1]/a + m_Stiffness[0] * 0.5);
227 k11 = area * (m_Stiffness[1]/a + m_Stiffness[0]);
228 k02 = area * (-m_Stiffness[1]/b + m_Stiffness[0] * 0.5);
229 k12 = area * m_Stiffness[0] * 0.5;
230 k22 = area * (m_Stiffness[1]/b + m_Stiffness[0]);
232 m_StiffnessMatrix[0][0][0] = k00;
233 m_StiffnessMatrix[0][0][1] = k01;
234 m_StiffnessMatrix[0][0][2] = k02;
235 m_StiffnessMatrix[0][0][3] = 0.0;
236 m_StiffnessMatrix[0][1][0] = k01;
237 m_StiffnessMatrix[0][1][1] = k11;
238 m_StiffnessMatrix[0][1][2] = k12;
239 m_StiffnessMatrix[0][1][3] = 0.0;
240 m_StiffnessMatrix[0][2][0] = k02;
241 m_StiffnessMatrix[0][2][1] = k12;
242 m_StiffnessMatrix[0][2][2] = k22;
243 m_StiffnessMatrix[0][2][3] = 0.0;
244 m_StiffnessMatrix[0][3][0] = 0.0;
245 m_StiffnessMatrix[0][3][1] = 0.0;
246 m_StiffnessMatrix[0][3][2] = 0.0;
247 m_StiffnessMatrix[0][3][3] = 1.0;
252 template <
typename TInputMesh,
typename TOutputMesh>
257 m_StiffnessMatrix[i][0][0] = stiff[0][0];
258 m_StiffnessMatrix[i][0][1] = stiff[0][1];
259 m_StiffnessMatrix[i][0][2] = stiff[0][2];
260 m_StiffnessMatrix[i][0][3] = stiff[0][3];
261 m_StiffnessMatrix[i][1][0] = stiff[1][0];
262 m_StiffnessMatrix[i][1][1] = stiff[1][1];
263 m_StiffnessMatrix[i][1][2] = stiff[1][2];
264 m_StiffnessMatrix[i][1][3] = stiff[1][3];
265 m_StiffnessMatrix[i][2][0] = stiff[2][0];
266 m_StiffnessMatrix[i][2][1] = stiff[2][1];
267 m_StiffnessMatrix[i][2][2] = stiff[2][2];
268 m_StiffnessMatrix[i][2][3] = stiff[2][3];
269 m_StiffnessMatrix[i][3][0] = stiff[3][0];
270 m_StiffnessMatrix[i][3][1] = stiff[3][1];
271 m_StiffnessMatrix[i][3][2] = stiff[3][2];
272 m_StiffnessMatrix[i][3][3] = stiff[3][3];
276 template <
typename TInputMesh,
typename TOutputMesh>
288 while (celldata != myCellData->End())
290 const double x = celldata.Value();
291 m_K[j] = m_StiffnessMatrix+((int) x);
299 template <
typename TInputMesh,
typename TOutputMesh>
305 const unsigned long *tp;
324 while( cells != myCells->End() )
326 tp = cells.Value()->GetPointIds();
328 m_Displacements->GetPoint (tp[0], &v1);
329 m_Displacements->GetPoint (tp[1], &v2);
330 m_Displacements->GetPoint (tp[2], &v3);
331 v1[0] *= m_K[i]->get(0, 0)*p;
332 v1[1] *= m_K[i]->get(0, 0)*p;
333 v1[2] *= m_K[i]->get(0, 0)*p;
334 v2[0] *= m_K[i]->get(0, 1)*p;
335 v2[1] *= m_K[i]->get(0, 1)*p;
336 v2[2] *= m_K[i]->get(0, 1)*p;
337 v3[0] *= m_K[i]->get(0, 2)*p;
338 v3[1] *= m_K[i]->get(0, 2)*p;
339 v3[2] *= m_K[i]->get(0, 2)*p;
340 v1[0] += v2[0]+v3[0];
341 v1[1] += v2[1]+v3[1];
342 v1[2] += v2[2]+v3[2];
343 m_Forces->GetPoint (tp[0], &v2);
349 m_Forces->SetPoint (tp[0], v2);
351 m_Displacements->GetPoint (tp[0], &v1);
352 m_Displacements->GetPoint (tp[1], &v2);
353 m_Displacements->GetPoint (tp[2], &v3);
354 v1[0] *= m_K[i]->get(1, 0)*p;
355 v1[1] *= m_K[i]->get(1, 0)*p;
356 v1[2] *= m_K[i]->get(1, 0)*p;
357 v2[0] *= m_K[i]->get(1, 1)*p;
358 v2[1] *= m_K[i]->get(1, 1)*p;
359 v2[2] *= m_K[i]->get(1, 1)*p;
360 v3[0] *= m_K[i]->get(1, 2)*p;
361 v3[1] *= m_K[i]->get(1, 2)*p;
362 v3[2] *= m_K[i]->get(1, 2)*p;
363 v1[0] += v2[0]+v3[0];
364 v1[1] += v2[1]+v3[1];
365 v1[2] += v2[2]+v3[2];
366 m_Forces->GetPoint (tp[1], &v2);
372 m_Forces->SetPoint (tp[1], v2);
374 m_Displacements->GetPoint (tp[0], &v1);
375 m_Displacements->GetPoint (tp[1], &v2);
376 m_Displacements->GetPoint (tp[2], &v3);
377 v1[0] *= m_K[i]->get(2, 0)*p;
378 v1[1] *= m_K[i]->get(2, 0)*p;
379 v1[2] *= m_K[i]->get(2, 0)*p;
380 v2[0] *= m_K[i]->get(2, 1)*p;
381 v2[1] *= m_K[i]->get(2, 1)*p;
382 v2[2] *= m_K[i]->get(2, 1)*p;
383 v3[0] *= m_K[i]->get(2, 2)*p;
384 v3[1] *= m_K[i]->get(2, 2)*p;
385 v3[2] *= m_K[i]->get(2, 2)*p;
386 v1[0] += v2[0]+v3[0];
387 v1[1] += v2[1]+v3[1];
388 v1[2] += v2[2]+v3[2];
389 m_Forces->GetPoint (tp[2], &v2);
395 m_Forces->SetPoint (tp[2], v2);
399 while ( derives != myDerives->End() )
401 derives.Value() = forces.Value();
408 template <
typename TInputMesh,
typename TOutputMesh>
413 typename TInputMesh::PointType s, d, ds;
422 while( derives != myDerives->End() )
424 ds = derives.Value();
426 d = displacements.Value();
427 s[0] += m_TimeStep*ds[0];
428 s[1] += m_TimeStep*ds[1];
429 s[2] += m_TimeStep*ds[2];
430 d[0] += m_TimeStep*ds[0];
431 d[1] += m_TimeStep*ds[1];
432 d[2] += m_TimeStep*ds[2];
435 if ( (s[0] > 0) && (s[1] > 0) && (s[2] > 0) &&
436 (s[2] < m_ImageDepth) && (s[0] < m_ImageWidth) && (s[1] < m_ImageHeight) )
439 displacements.Value() = d;
450 template <
typename TInputMesh,
typename TOutputMesh>
457 typename TriCell::CellAutoPointer insertCell;
458 unsigned long tripoints[3];
459 const unsigned long *tp;
464 typedef typename OutputMeshType::CellsContainer CellsContainer;
466 output->SetCells(CellsContainer::New());
468 output->GetCells()->Reserve( m_NumberOfCells );
470 output->SetCellsAllocationMethod( OutputMeshType::CellsAllocatedDynamicallyCellByCell );
473 myPoints->Reserve(m_NumberOfNodes);
487 for (; i<m_NumberOfNodes; i++)
489 points.Value() = locations.Value();
494 for (i=0; i<m_NumberOfCells; i++)
496 tp = cells.Value()->GetPointIds();
497 tripoints[0] = tp[0];
498 tripoints[1] = tp[1];
499 tripoints[2] = tp[2];
500 insertCell.TakeOwnership(
new TriCell );
501 insertCell->SetPointIds(tripoints);
502 output->SetCell(i, insertCell );
503 x = celldata.Value();
512 template <
typename TInputMesh,
typename TOutputMesh>
518 this->SetMeshStiffness();
520 while (m_Step < m_StepThreshold)
523 const float progress =
524 static_cast<float>( m_Step ) /
525 static_cast<float>( m_StepThreshold );
527 this->UpdateProgress( progress );
528 this->ComputeNormals();
533 this->PotentialFit();
541 this->ComputeOutput();
545 template <
typename TInputMesh,
typename TOutputMesh>
551 PixelType max, extends[3], t, xs, ys, zs;
552 typename TInputMesh::PointType vec_for, vec_nor, vec_p, vec_1, vec_2;
570 while( i < m_NumberOfNodes )
573 vec_p = points.Value();
575 coord[0] = (int) vec_p[0];
576 coord[1] = (int) vec_p[1];
577 coord[2] = (int) vec_p[2];
579 if ( m_Potential->GetPixel(coord) != m_ObjectLabel )
584 extends[0] = vec_p[0];
585 extends[1] = vec_p[1];
586 extends[2] = vec_p[2];
587 extend[0] = (int) vec_p[0];
588 extend[1] = (int) vec_p[1];
589 extend[2] = (int) vec_p[2];
591 vec_nor = normals.Value();
593 max = vcl_abs(vec_nor[0]);
598 if ( vcl_abs(vec_nor[1]) > max ) max = vcl_abs(vec_nor[1]);
599 if ( vcl_abs(vec_nor[2]) > max ) max = vcl_abs(vec_nor[2]);
602 vec_1[0] = -1*vec_nor[0]/max;
603 vec_1[1] = -1*vec_nor[1]/max;
604 vec_1[2] = -1*vec_nor[2]/max;
608 vec_1[0] = vec_nor[0]/max;
609 vec_1[1] = vec_nor[1]/max;
610 vec_1[2] = vec_nor[2]/max;
617 extends[0] += vec_1[0];
618 extends[1] += vec_1[1];
619 extends[2] += vec_1[2];
620 extend[0] = (int) (extends[0]+1);
621 extend[1] = (int) (extends[1]+1);
622 extend[2] = (int) (extends[2]+1);
623 if ((extend[0] <= 0) || (extend[1] <= 0) || (extend[2] <= 0))
break;
625 extend[0] = (int) (extends[0]);
626 extend[1] = (int) (extends[1]);
627 extend[2] = (int) (extends[2]);
628 if ((extend[0] >= m_ImageWidth) || (extend[1] >= m_ImageHeight) ||
629 (extend[2] >= m_ImageDepth))
break;
631 label = m_Potential->GetPixel(extend);
634 if ( label != m_ObjectLabel )
break;
636 else if ( label == m_ObjectLabel )
break;
641 vec_2[0] = t*m_PotentialMagnitude*vec_nor[0]*xs;
642 vec_2[1] = t*m_PotentialMagnitude*vec_nor[1]*ys;
643 vec_2[2] = t*m_PotentialMagnitude*vec_nor[2]*zs;
645 vec_for = forces.Value();
646 vec_for[0] += vec_2[0];
647 vec_for[1] += vec_2[1];
648 vec_for[2] += vec_2[2];
649 forces.Value() = vec_for;
660 template <
typename TInputMesh,
typename TOutputMesh>
671 typename TInputMesh::PointType vec_nor, vec_loc, vec_for, tmp_vec_1, tmp_vec_2, tmp_vec_3;
686 while( forces != myForces->End() )
688 vec_loc = locations.Value();
689 vec_nor = normals.Value();
691 coord[0] =
static_cast<IndexValueType
>(vec_loc[0]);
692 coord[1] =
static_cast<IndexValueType
>(vec_loc[1]);
693 coord[2] =
static_cast<IndexValueType
>(vec_loc[2]);
695 coord2[0] =
static_cast<IndexValueType
>( vcl_ceil(vec_loc[0]) );
696 coord2[1] =
static_cast<IndexValueType
>( vcl_ceil(vec_loc[1]) );
697 coord2[2] =
static_cast<IndexValueType
>( vcl_ceil(vec_loc[2]) );
699 tmp_co_1[0] = coord2[0];
700 tmp_co_1[1] = coord[1];
701 tmp_co_1[2] = coord[2];
703 tmp_co_2[0] = coord[0];
704 tmp_co_2[1] = coord2[1];
705 tmp_co_2[2] = coord[2];
707 tmp_co_3[0] = coord[0];
708 tmp_co_3[1] = coord[1];
709 tmp_co_3[2] = coord2[2];
711 if ( (coord[0] >= 0) && (coord[1] >= 0) && (coord[2] >= 0) &&
712 (coord2[0] < m_ImageWidth) && (coord2[1] < m_ImageHeight) && (coord2[2] < m_ImageDepth) )
714 vec_for[0] = m_Gradient->GetPixel(coord)[0];
715 vec_for[1] = m_Gradient->GetPixel(coord)[1];
716 vec_for[2] = m_Gradient->GetPixel(coord)[2];
718 tmp_vec_1[0] = m_Gradient->GetPixel(tmp_co_1)[0] - m_Gradient->GetPixel(coord)[0];
719 tmp_vec_1[1] = m_Gradient->GetPixel(tmp_co_1)[1] - m_Gradient->GetPixel(coord)[1];
720 tmp_vec_1[2] = m_Gradient->GetPixel(tmp_co_1)[2] - m_Gradient->GetPixel(coord)[2];
721 tmp_vec_2[0] = m_Gradient->GetPixel(tmp_co_2)[0] - m_Gradient->GetPixel(coord)[0];
722 tmp_vec_2[1] = m_Gradient->GetPixel(tmp_co_2)[1] - m_Gradient->GetPixel(coord)[1];
723 tmp_vec_2[2] = m_Gradient->GetPixel(tmp_co_2)[2] - m_Gradient->GetPixel(coord)[2];
724 tmp_vec_3[0] = m_Gradient->GetPixel(tmp_co_3)[0] - m_Gradient->GetPixel(coord)[0];
725 tmp_vec_3[1] = m_Gradient->GetPixel(tmp_co_3)[1] - m_Gradient->GetPixel(coord)[1];
726 tmp_vec_3[2] = m_Gradient->GetPixel(tmp_co_3)[2] - m_Gradient->GetPixel(coord)[2];
728 vec_for[0] = vec_for[0] + (vec_loc[0]-coord[0])*tmp_vec_1[0]
729 + (vec_loc[1]-coord[1])*tmp_vec_2[0] + (vec_loc[2]-coord[2])*tmp_vec_3[0];
730 vec_for[1] = vec_for[1] + (vec_loc[1]-coord[1])*tmp_vec_2[1]
731 + (vec_loc[0]-coord[0])*tmp_vec_1[1] + (vec_loc[2]-coord[2])*tmp_vec_3[1];
732 vec_for[2] = vec_for[2] + (vec_loc[2]-coord[2])*tmp_vec_3[2]
733 + (vec_loc[1]-coord[1])*tmp_vec_2[2] + (vec_loc[0]-coord[0])*tmp_vec_1[2];
742 mag = vec_for[0]*vec_nor[0] + vec_for[1]*vec_nor[1]+ vec_for[2]*vec_nor[2];
744 vec_for[0] = m_GradientMagnitude*mag*vec_nor[0];
745 vec_for[1] = m_GradientMagnitude*mag*vec_nor[1];
746 vec_for[2] = m_GradientMagnitude*mag*vec_nor[2];
748 mag = vcl_sqrt(vec_for[0]*vec_for[0] + vec_for[1]*vec_for[1]+ vec_for[2]*vec_for[2]);
751 for (
int i=0; i<3; i++)
753 vec_for[i] = (0.5 * vec_for[i])/mag;
756 forces.Value() = vec_for;
766 template <
typename TInputMesh,
typename TOutputMesh>
771 const unsigned long *tp;
778 double coa, cob, coc;
788 while( normals != myNormals->End() )
794 while ( cells != myCells->End() )
796 tp = cells.Value()->GetPointIds();
799 m_Locations->GetPoint (tp[0], &v1);
800 m_Locations->GetPoint (tp[1], &v2);
801 m_Locations->GetPoint (tp[2], &v3);
803 coa = -(v1[1]*(v2[2]-v3[2]) +
804 v2[1]*(v3[2]-v1[2]) +
805 v3[1]*(v1[2]-v2[2]));
806 cob = -(v1[2] * (v2[0]-v3[0]) +
807 v2[2]*(v3[0]-v1[0]) +
808 v3[2]*(v1[0]-v2[0]));
809 coc = -(v1[0] * (v2[1]-v3[1]) +
810 v2[0]*(v3[1]-v1[1]) +
811 v3[0]*(v1[1]-v2[1]));
813 absvec = -vcl_sqrt ((
double) ((coa*coa) + (cob*cob) + (coc*coc)));
815 assert (absvec != 0);
820 m_Normals->GetPoint (tp[0], &v1);
821 m_Normals->GetPoint (tp[1], &v2);
822 m_Normals->GetPoint (tp[2], &v3);
836 m_Normals->SetPoint (tp[0], v1);
837 m_Normals->SetPoint (tp[1], v2);
838 m_Normals->SetPoint (tp[2], v3);
842 normals = myNormals->Begin();
843 while( normals != myNormals->End() )
845 v1 = normals.Value();
847 absvec = vcl_sqrt((
double) ((v1[0]*v1[0]) + (v1[1]*v1[1]) +
849 v1[0] = v1[0]/absvec;
850 v1[1] = v1[1]/absvec;
851 v1[2] = v1[2]/absvec;
853 normals.Value() = v1;