Orfeo Toolbox  3.16
itkBalloonForceFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkBalloonForceFilter.txx,v $
5  Language: C++
6  Date: $Date: 2009-09-17 11:04:00 $
7  Version: $Revision: 1.74 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkBalloonForceFilter_txx
18 #define __itkBalloonForceFilter_txx
19 
20 #ifdef _MSC_VER
21 #pragma warning ( disable : 4786 )
22 #endif
23 
24 #include "itkBalloonForceFilter.h"
25 
26 namespace itk
27 {
28 template <typename TInputMesh, typename TOutputMesh>
31 {
32  m_Step = 0;
33  m_GradientBegin = 0;
34  m_DistanceToBoundary = 100;
35  m_DistanceToStop = 10;
36  m_Center.Fill(0);
37  m_Stiffness.Fill(0);
38  m_TimeStep = 0.0;
39  m_DistanceForGradient = 0.0;
40  m_Resolution = 0;
41  m_K = 0;
42  m_NewNodes = 0;
43  m_NewNodeLimit = 0;
44  typename TOutputMesh::Pointer output = TOutputMesh::New();
46  this->ProcessObject::SetNthOutput(0, output.GetPointer());
47 }
48 
49 template <typename TInputMesh, typename TOutputMesh>
52 {
53  if (m_NewNodes)
54  {
55  for (unsigned int i = 0; i < m_NewNodeLimit; i++)
56  {
57  if (m_NewNodes[i])
58  {
59  free(m_NewNodes[i]);
60  m_NewNodes[i] = 0;
61  }
62  }
63  free(m_NewNodes);
64  m_NewNodes = 0;
65  }
66 
67  if (m_K)
68  {
69  free (m_K);
70  }
71 }
72 
73 /*
74  * PrintSelf
75  */
76 template <typename TInputMesh, typename TOutputMesh>
77 void
79 ::PrintSelf(std::ostream& os, Indent indent) const
80 {
81  Superclass::PrintSelf(os,indent);
82 
83  os << indent << "Center = " << m_Center << std::endl;
84  os << indent << "TimeStep = " << m_TimeStep << std::endl;
85  if (m_Gradient)
86  {
87  os << indent << "Gradient = " << m_Gradient << std::endl;
88  }
89  else
90  {
91  os << indent << "Gradient = (None)" << std::endl;
92  }
93  if (m_Forces)
94  {
95  os << indent << "Forces = " << m_Forces << std::endl;
96  }
97  else
98  {
99  os << indent << "Forces = (None)" << std::endl;
100  }
101  os << indent << "Stiffness = " << m_Stiffness << std::endl;
102  os << indent << "DistanceForGradient = " << m_DistanceForGradient << std::endl;
103  os << indent << "GradientBegin = " << m_GradientBegin << std::endl;
104  os << indent << "Resolution = " << m_Resolution << std::endl;
105 
106  if (!m_ImageOutput.IsNull())
107  {
108  os << indent << "ImageOutput = " << m_ImageOutput << std::endl;
109  }
110  if (m_Potential)
111  {
112  os << indent << "Potential = " << m_Potential << std::endl;
113  }
114  else
115  {
116  os << indent << "Potential = (None)" << std::endl;
117  }
118  if (m_Displacements)
119  {
120  os << indent << "Displacements = " << m_Displacements << std::endl;
121  }
122  else
123  {
124  os << indent << "Displacements = (None)" << std::endl;
125  }
126  if (m_Locations)
127  {
128  os << indent << "Locations = " << m_Locations << std::endl;
129  }
130  else
131  {
132  os << indent << "Locations = (None)" << std::endl;
133  }
134  os << indent << "DistanceToStop = " << m_DistanceToStop << std::endl;
135 
136  if (m_Derives)
137  {
138  os << indent << "Derives = " << m_Derives << std::endl;
139  }
140  else
141  {
142  os << indent << "Derives = (None)" << std::endl;
143  }
144  if (m_Normals)
145  {
146  os << indent << "Normals = " << m_Normals << std::endl;
147  }
148  else
149  {
150  os << indent << "Normals = (None)" << std::endl;
151  }
152 }// end PrintSelf
153 
154 /* Set default value of parameters and initialize local data container
155  * such as forces, displacements and displacement derivatives. */
156 template <typename TInputMesh, typename TOutputMesh>
157 void
160 {
161  m_NumberOfNodes = this->GetInput(0)->GetNumberOfPoints();
162  m_NumberOfCells = this->GetInput(0)->GetNumberOfCells();
163 
164  m_Forces = InputMeshType::New();
165  m_Displacements = InputMeshType::New();
166  m_Derives = InputMeshType::New();
167  m_Normals = InputMeshType::New();
168  m_Locations = InputMeshType::New();
169 
170  InputMeshConstPointer inputMesh = this->GetInput(0);
171  InputPointsContainerConstPointer myPoints = inputMesh->GetPoints();
172  InputPointsContainerConstIterator points = myPoints->Begin();
173 
174  InputPointsContainerPointer myForces = m_Forces->GetPoints();
175  myForces->Reserve(m_NumberOfNodes);
176  InputPointsContainerIterator forces = myForces->Begin();
177 
178  InputPointsContainerPointer myDerives = m_Derives->GetPoints();
179  myDerives->Reserve(m_NumberOfNodes);
180  InputPointsContainerIterator derives = myDerives->Begin();
181 
182  InputPointsContainerPointer myDisplacements = m_Displacements->GetPoints();
183  myDisplacements->Reserve(m_NumberOfNodes);
184  InputPointsContainerIterator displacements = myDisplacements->Begin();
185 
186  InputPointsContainerPointer myNormals = m_Normals->GetPoints();
187  myNormals->Reserve(m_NumberOfNodes);
188  InputPointsContainerIterator normals = myNormals->Begin();
189 
190  InputPointsContainerPointer myLocations = m_Locations->GetPoints();
191  myLocations->Reserve(m_NumberOfNodes);
192  InputPointsContainerIterator locations = myLocations->Begin();
193 
194  InputCellsContainerConstPointer myCells = inputMesh->GetCells();
195  InputCellsContainerConstIterator cells = myCells->Begin();
196 
197  InputCellDataContainerConstPointer myCellData = inputMesh->GetCellData();
198  InputCellDataContainerConstIterator celldata = myCellData->Begin();
199 
200  ImageSizeType ImageSize = m_Gradient->GetBufferedRegion().GetSize();
201 
202  m_NumNewNodes = 0;
203  m_NewNodesExisted = 0;
204  m_NewNodeLimit = 200;
205  m_ObjectLabel = m_Potential->GetPixel(m_Center);
206  m_NewNodes = (float**) malloc(sizeof(float *)*m_NewNodeLimit);
207  for (unsigned int i = 0; i < m_NewNodeLimit; i++)
208  {
209  m_NewNodes[i] = 0;
210  }
211 
212  //---------------------------------------------------------------------
213  //Get the image width/height and dePixelTypeh
214  //---------------------------------------------------------------------
215  m_ImageWidth = ImageSize[0];
216  m_ImageHeight = ImageSize[1];
217 
218  float d[3] = {0,0,0};
220 
221 // TimeStep = 0.001;
222 
223  while( points != myPoints->End() )
224  {
225  locations.Value() = points.Value();
226  tmp = locations.Value();
227  ++points;
228  ++locations;
229  }
230 
231  while( forces != myForces->End() )
232  {
233  forces.Value() = d;
234  ++forces;
235  }
236 
237  while( normals != myNormals->End() )
238  {
239  normals.Value() = d;
240  ++normals;
241  }
242 
243  for (unsigned int i=0; i+2 < m_NumberOfNodes; i++ )
244  {
245  m_Forces->SetPointData(i, 1.0);
246  m_Locations->SetPointData(i, 0.0);
247  m_Derives->SetPointData(i, 0.0);
248  m_Displacements->SetPointData(i, 0.0);
249  }
250 
251  for (unsigned int j = 0; j < m_NewNodeLimit; j++)
252  {
253  m_NewNodes[j] = (float*) malloc(sizeof(float)*5);
254  }
255 
256  while( derives != myDerives->End() )
257  {
258  derives.Value() = d;
259  ++derives;
260  }
261 
262  while( displacements != myDisplacements->End() )
263  {
264  displacements.Value() = d;
265  ++displacements;
266  }
267 
268  typename TriCell::CellAutoPointer insertCell;
269  unsigned long tripoints[3];
270  const unsigned long *tp;
271  float x;
272 
273  for (unsigned int i=0; i<m_NumberOfCells; i++)
274  {
275  tp = cells.Value()->GetPointIds();
276  tripoints[0] = tp[0];
277  tripoints[1] = tp[1];
278  tripoints[2] = tp[2];
279  insertCell.TakeOwnership( new TriCell );
280  insertCell->SetPointIds(tripoints);
281  m_Locations->SetCell(i, insertCell);
282  x = celldata.Value();
283  m_Locations->SetCellData(i, (PixelType)x);
284  ++cells;
285  ++celldata;
286  }
287 
288  // This prevents unnecessary re-executions of the pipeline.
289  OutputMeshPointer outputMesh = this->GetOutput();
290  outputMesh->SetBufferedRegion( outputMesh->GetRequestedRegion() );
291 }
292 
293 /*
294  * set the stiffness matrix
295  */
296 template <typename TInputMesh, typename TOutputMesh>
297 void
300 {
301  InputCellDataContainerPointer myCellData = m_Locations->GetCellData();
302  InputCellDataContainerIterator celldata = myCellData->Begin();
303 
304  if (m_K)
305  {
306  free (m_K);
307  }
308  m_K = (vnl_matrix_fixed<double,4,4>**) malloc(sizeof(vnl_matrix_fixed<double,4,4>*)*m_NumberOfCells);
309  float x;
310 
311  float us = vnl_math::pi / 1;
312  float vs = 2.0*vnl_math::pi / m_Resolution;
313  float a = us*us, b = vs*vs;
314  float area = us*vs/2, k00, k01, k02, k11, k12, k22;
315 
316  k00 = area * (m_Stiffness[1]/a + m_Stiffness[1]/b + m_Stiffness[0]);
317  k01 = area * (-m_Stiffness[1]/a + m_Stiffness[0]);
318  k02 = area * (-m_Stiffness[1]/b + m_Stiffness[0]);
319  k11 = area * (m_Stiffness[1]/a + m_Stiffness[0]);
320  k12 = area * m_Stiffness[0];
321  k22 = area * (m_Stiffness[1]/b + m_Stiffness[0]);
322 
323  m_NStiffness[0][0] = k00;
324  m_NStiffness[0][1] = k01;
325  m_NStiffness[0][2] = k02;
326  m_NStiffness[0][3] = 0.0;
327  m_NStiffness[1][0] = k01;
328  m_NStiffness[1][1] = k11;
329  m_NStiffness[1][2] = k12;
330  m_NStiffness[1][3] = 0.0;
331  m_NStiffness[2][0] = k02;
332  m_NStiffness[2][1] = k12;
333  m_NStiffness[2][2] = k22;
334  m_NStiffness[2][3] = 0.0;
335  m_NStiffness[3][0] = 0.0;
336  m_NStiffness[3][1] = 0.0;
337  m_NStiffness[3][2] = 0.0;
338  m_NStiffness[3][3] = 1.0;
339 
340  k00 = area * (m_Stiffness[1]/a + m_Stiffness[0]);
341  k01 = area * (-m_Stiffness[1]/a + m_Stiffness[0]);
342  k02 = area * m_Stiffness[0];
343  k11 = area * (m_Stiffness[1]/a + m_Stiffness[1]/b+m_Stiffness[0]);
344  k12 = area * (-m_Stiffness[1]/b + m_Stiffness[0]);
345  k22 = area * (m_Stiffness[1]/b + m_Stiffness[0]);
346 
347  m_SStiffness[0][0] = k00;
348  m_SStiffness[0][1] = k01;
349  m_SStiffness[0][2] = k02;
350  m_SStiffness[0][3] = 0.0;
351  m_SStiffness[1][0] = k01;
352  m_SStiffness[1][1] = k11;
353  m_SStiffness[1][2] = k12;
354  m_SStiffness[1][3] = 0.0;
355  m_SStiffness[2][0] = k02;
356  m_SStiffness[2][1] = k12;
357  m_SStiffness[2][2] = k22;
358  m_SStiffness[2][3] = 0.0;
359  m_SStiffness[3][0] = 0.0;
360  m_SStiffness[3][1] = 0.0;
361  m_SStiffness[3][2] = 0.0;
362  m_SStiffness[3][3] = 1.0;
363 
364  k00 = area * (m_Stiffness[1]/b + m_Stiffness[0]);
365  k01 = area * (-m_Stiffness[1]/b + m_Stiffness[0]);
366  k02 = area * m_Stiffness[0];
367  k11 = area * (m_Stiffness[1]/a + m_Stiffness[1]/b + m_Stiffness[0]);
368  k12 = area * (-m_Stiffness[1]/a + m_Stiffness[0]);
369  k22 = area * (m_Stiffness[1]/a + m_Stiffness[0]);
370 
371  m_CStiffness[0][0] = k00;
372  m_CStiffness[0][1] = k01;
373  m_CStiffness[0][2] = k02;
374  m_CStiffness[0][3] = 0.0;
375  m_CStiffness[1][0] = k01;
376  m_CStiffness[1][1] = k11;
377  m_CStiffness[1][2] = k12;
378  m_CStiffness[1][3] = 0.0;
379  m_CStiffness[2][0] = k02;
380  m_CStiffness[2][1] = k12;
381  m_CStiffness[2][2] = k22;
382  m_CStiffness[2][3] = 0.0;
383  m_CStiffness[3][0] = 0.0;
384  m_CStiffness[3][1] = 0.0;
385  m_CStiffness[3][2] = 0.0;
386  m_CStiffness[3][3] = 1.0;
387 
388  int j=0;
389  while (celldata != myCellData->End())
390  {
391  x = celldata.Value();
392  ++celldata;
393  switch ((int)(x))
394  {
395  case 1:
396  m_K[j] = &m_SStiffness;
397  break;
398  case 2:
399  m_K[j] = &m_NStiffness;
400  break;
401  case 3:
402  m_K[j] = &m_CStiffness;
403  break;
404  }
405  ++j;
406  }
407 
408 }
409 
410 /*
411  * compute force using the information from image
412  * and the balloon force. The calculation of the
413  * image force not included by far, it will be added
414  * when more experiments are done
415  */
416 template <typename TInputMesh, typename TOutputMesh>
417 void
420 {
421  unsigned int i;
422  IndexType coord; coord.Fill(0);
423  IndexType extend; extend.Fill(0);
424  float extends[2], fo, t, xs, ys;
425  FloatVector n1, n, vec1, vec2;
426  float max;
427  IPixelType x, y, z, f;
428 
429  float dist = 0.0;
430  unsigned short label;
431 
432  InputPointsContainerPointer Points = m_Locations->GetPoints();
433  InputPointsContainerIterator points = Points->Begin();
434 
435  InputPointsContainerPointer myForces = m_Forces->GetPoints();
436  InputPointsContainerIterator forces = myForces->Begin();
437 
438  InputPointsContainerPointer myNormals = m_Normals->GetPoints();
439  InputPointsContainerIterator normals = myNormals->Begin();
440 
441  InputPointDataContainerPointer myForceData = m_Forces->GetPointData();
442  InputPointDataContainerIterator forcedata = myForceData->Begin();
443 
444  InputPointDataContainerPointer myPointData = m_Locations->GetPointData();
445  InputPointDataContainerIterator pointstatus = myPointData->Begin();
446 
447  i = 0;
448 
449  while( i != m_NumberOfNodes - 2 )
450  {
451  xs = ys = 1.0;
452  x = points.Value();
453 
454  coord[0] = (int) x[0];
455  coord[1] = (int) x[1];
456 
457  label = (unsigned short)m_Potential->GetPixel(coord);
458  if ( label != m_ObjectLabel )
459  {
460  xs = ys = 0.0;
461  }
462 
463  //---------------------------------------------------------------------
464  // The following part should be added if the input potential are only
465  // estimation of edges
466  //---------------------------------------------------------------------
467 /*
468  coord[0] = (int) (x[0]+1);
469  coord[1] = (int) (x[1]+1);
470  if ( m_Potential->GetPixel(coord) != m_ObjectLabel )
471  {
472  xs = ys = 0.0;
473  }
474 
475  coord[0] = (int) (x[0]+1);
476  coord[1] = (int) (x[1]);
477  if ( m_Potential->GetPixel(coord) != m_ObjectLabel )
478  {
479  xs = ys = 0.0;
480  }
481 
482  coord[0] = (int) (x[0]+1);
483  coord[1] = (int) (x[1]-1);
484  if ( m_Potential->GetPixel(coord) != m_ObjectLabel )
485  {
486  xs = ys = 0.0;
487  }
488 
489  coord[0] = (int) (x[0]);
490  coord[1] = (int) (x[1]+1);
491  if ( m_Potential->GetPixel(coord) != m_ObjectLabel )
492  {
493  xs = ys = 0.0;
494  }
495 
496  coord[0] = (int) (x[0]);
497  coord[1] = (int) (x[1]-1);
498  if ( m_Potential->GetPixel(coord) != m_ObjectLabel )
499  {
500  xs = ys = 0.0;
501  }
502 
503  coord[0] = (int) (x[0]-1);
504  coord[1] = (int) (x[1]+1);
505  if ( m_Potential->GetPixel(coord) != m_ObjectLabel )
506  {
507  xs = ys = 0.0;
508  }
509 
510  coord[0] = (int) (x[0]-1);
511  coord[1] = (int) (x[1]);
512  if ( m_Potential->GetPixel(coord) != m_ObjectLabel )
513  {
514  xs = ys = 0.0;
515  }
516 
517  coord[0] = (int) (x[0]-1);
518  coord[1] = (int) (x[1]-1);
519  if ( m_Potential->GetPixel(coord) != m_ObjectLabel )
520  {
521  xs = ys = 0.0;
522  }
523 */
524  extends[0] = x[0];
525  extends[1] = x[1];
526 // extends[2] = x[2];
527  extend[0] = (int) x[0];
528  extend[1] = (int) x[1];
529 // extend[2] = (int) x[2];
530 
531  f = normals.Value();
532 
533  max = vcl_abs(f[0]);
534 
535  //---------------------------------------------------------------------
536  // all the movement in z direction is now disabled for further test
537  //---------------------------------------------------------------------
538  if ( vcl_abs(f[1]) > max ) max = vcl_abs(f[1]);
539  n[0] = f[0]/max;
540  n[1] = f[1]/max;
541 
542  t = 0.0;
543 
544  while (t < 5.0)
545  {
546  extends[0] += n[0];
547  extends[1] += n[1];
548  extend[0] = (int) extends[0];
549  extend[1] = (int) extends[1];
550 // extend[2] = 0;
551  if ( (extend[0] < 0) ||
552  (extend[1] < 0) ||
553  (static_cast<unsigned int>(extend[0]) >= m_ImageWidth) ||
554  (static_cast<unsigned int>(extend[1]) >= m_ImageHeight ) )
555  {
556  break;
557  }
558 
559  label = (unsigned short) m_Potential->GetPixel(extend);
560  if ( label != m_ObjectLabel ) break;
561 
562  t += 1.0;
563  }
564 
565  dist = dist + t;
566 
567  if (t < 2) pointstatus.Value() = 1.0;
568  else
569  {
570  pointstatus.Value() = 0.0;
571  // m_ImageOutput->SetPixel(coord, 1);
572  }
573  fo = vcl_sqrt(f[0]*f[0]+f[1]*f[1]);
574  f[0] = t*100*f[0]*xs/fo;
575  f[1] = t*100*f[1]*ys/fo;
576  f[2] = 0;
577 
578  forces.Value() = f;
579  forcedata.Value() = 0.0;
580  ++pointstatus;
581  ++forces;
582  ++forcedata;
583  ++points;
584  ++normals;
585  ++i;
586  }
587 
588 // m_DistanceToBoundary = dist/((float)(m_NumberOfNodes-2));
589 // if (m_DistanceToBoundary < m_DistanceForGradient) m_GradientBegin = 1;
590 }
591 
592 /*
593  * compute the derivatives using d'- Kd = f
594  */
595 template <typename TInputMesh, typename TOutputMesh>
596 void
599 {
600  const unsigned long *tp;
601 
602  InputCellsContainerPointer myCells = m_Locations->GetCells();
603  InputCellsContainerIterator cells_it = myCells->Begin();
604 
605  float p = 1.0; // arnaud: why p is a float?
606  // I guess it should be a typename IPixelType::CoordRepType?
607  // why p is set to 1 and never changed?
608 
609  IPixelType vd[3];
610  IPixelType vf[3];
611 
612  typename IPixelType::VectorType u[3];
613 
614  unsigned long i = 0; // arnaud: I guess i an InputCellIdentifier?
615  for(; cells_it != myCells->End(); ++cells_it, i++ )
616  {
617  tp = cells_it.Value()->GetPointIds();
618  for( unsigned int j = 0; j < 3; j++ )
619  {
620  u[j].Fill( 0.0 );
621  }
622 
623  for( unsigned int j = 0; j < 3; j++ )
624  {
625  m_Displacements->GetPoint (tp[j], &vd[j]);
626  m_Forces->GetPoint (tp[j], &vf[j]);
627 
628  for( unsigned int k = 0; k < 3; k++ )
629  {
630  u[k] += vd[j].GetVectorFromOrigin() * m_K[i]->get( k, j ) * p;
631  }
632  }
633 
634  for( unsigned int j = 0; j < 3; j++ )
635  {
636  vf[j] -= u[j];
637  m_Forces->SetPoint (tp[j], vf[j]);
638  }
639  }
640 
641  InputPointsContainerPointer myForces = m_Forces->GetPoints();
642  InputPointsContainerIterator forces_it = myForces->Begin();
643 
644  InputPointsContainerPointer myDerives = m_Derives->GetPoints();
645  InputPointsContainerIterator derives_it = myDerives->Begin();
646 
647  for (; derives_it != myDerives->End(); ++derives_it, ++forces_it )
648  {
649  derives_it.Value() = forces_it.Value();
650  }
651 
652 }
653 
654 /*
655  * When there is new nodes added, must do a reset to reallocate
656  * the memory and redistribute the nodes and reconstruct the cells,
657  * now the mthod is only suitable for 2D models, it will be a much
658  * different case for 3D model
659  */
660 template <typename TInputMesh, typename TOutputMesh>
661 void
664 {
665  int i, j, cell=0, slice, numnewnodes, res;
666  float status, d[3] = {0,0,0}, w;
667  IPixelType x, y, z;
668  IPixelType* x_PixelType;
669  IPixelType* y_PixelType;
670  x_PixelType = &x;
671  const unsigned long *tp;
672 
673  unsigned long tripoints[3];
674 
675  if (m_NumNewNodes == 0) return;
676  else cell = 1;
677 
678  m_NumberOfNodes = m_NumberOfNodes + m_NumNewNodes;
679  m_NumberOfCells = m_NumberOfCells + m_NumNewNodes*2;
680  m_NumNewNodes = 0;
681 
682  InputPointsContainerPointer myForces = m_Forces->GetPoints();
683  myForces->Reserve(m_NumberOfNodes);
684  InputPointsContainerIterator forces = myForces->Begin();
685 
686  InputPointsContainerPointer myPoints = m_Locations->GetPoints();
687  myPoints->Reserve(m_NumberOfNodes);
688  InputPointsContainerIterator points = myPoints->Begin();
689 
690  InputPointsContainerPointer myNormals = m_Normals->GetPoints();
691  myNormals->Reserve(m_NumberOfNodes);
692  InputPointsContainerIterator normals = myNormals->Begin();
693 
694  InputPointsContainerPointer myDerives = m_Derives->GetPoints();
695  myDerives->Reserve(m_NumberOfNodes);
696  InputPointsContainerIterator derives = myDerives->Begin();
697 
698  InputPointsContainerPointer myDisplacements = m_Displacements->GetPoints();
699  myDisplacements->Reserve(m_NumberOfNodes);
700  InputPointsContainerIterator displacements = myDisplacements->Begin();
701 
702  InputPointDataContainerPointer myForceData = m_Forces->GetPointData();
703  InputPointDataContainerIterator forcedata = myForceData->Begin();
704 
705  InputCellsContainerPointer myCells = m_Locations->GetCells();
706  myCells->Reserve(m_NumberOfCells);
707  InputCellsContainerIterator cells = myCells->Begin();
708 
709  InputCellDataContainerPointer myCellData = m_Locations->GetCellData();
710  myCellData->Reserve(m_NumberOfCells);
711  InputCellDataContainerIterator celldata = myCellData->Begin();
712 
713  InputCellsContainerPointer myOutCells = m_Output->GetCells();
714  myOutCells->Reserve(m_NumberOfCells);
715  InputCellsContainerIterator outcells = myOutCells->Begin();
716 
717  InputCellDataContainerPointer myOutCellData = m_Output->GetCellData();
718  myOutCellData->Reserve(m_NumberOfCells);
719  InputCellDataContainerIterator outcelldata = myOutCellData->Begin();
720 
721  typename TriCell::CellAutoPointer insertCell = new TriCell;
722  insertCell.TakeOwnership();
723 
724  i = 0;
725  j = 0;
726  while (normals != myNormals->End())
727  {
728  if (i > (int) m_NewNodes[j][3])
729  {
730  z[0] = m_NewNodes[j][0];
731  z[1] = m_NewNodes[j][1];
732  z[2] = m_NewNodes[j][2];
733  j++;
734  normals.Value() = z;
735  }
736  else
737  {
738  x = points.Value();
739  i++;
740  normals.Value() = x;
741  ++points;
742  }
743 
744  ++normals;
745  }
746 
747  normals = myNormals->Begin();
748  points = myPoints->Begin();
749 
750  while (points != myNormals->End())
751  {
752  points.Value() = normals.Value();
753  ++points;
754  ++normals;
755  }
756 
757  while( forces != myForces->End() )
758  {
759  forces.Value() = d;
760  ++forces;
761  }
762 
763  while( derives != myDerives->End() )
764  {
765  derives.Value() = d;
766  ++derives;
767  }
768 
769  while( displacements != myDisplacements->End() )
770  {
771  displacements.Value() = d;
772  ++displacements;
773  }
774 
775  i = 0;
776  j = 0;
777  res = 0;
778  while ( outcells != myOutCells->End() )
779  {
780  tp = cells.Value()->GetPointIds();
781 
782  if ( tp[0] > (unsigned long) m_NewNodes[j][3] )
783  {
784  }
785  else
786  {
787  outcells.Value() = cells.Value();
788  ++cells;
789  ++outcells;
790  outcells.Value() = cells.Value();
791  ++cells;
792  ++outcells;
793  }
794 
795  i++;
796  if (tp[0] != tp[1] - 1)
797  {
798  res = i;
799  i = 0;
800  }
801  }
802 
803  if (cell == 1)
804  {
805  int p = 0, jn;
806 
807  // store cells containing the south pole nodes
808  for (j=0; j<m_Resolution; j++)
809  {
810  jn = (j+1)%m_Resolution;
811  tripoints[0] = m_NumberOfNodes-2;
812  tripoints[1] = jn;
813  tripoints[2] = j;
814  insertCell->SetPointIds(tripoints);
815  m_Locations->SetCell(p, insertCell);
816  m_Locations->SetCellData(p, (PixelType)1.0);
817  p++;
818  insertCell.TakeOwnership( new TriCell );
819  }
820 
821  // store cells containing the north pole nodes
822  for (j=0; j<m_Resolution; j++)
823  {
824  jn = (j+1)%m_Resolution;
825  tripoints[2] = (1-1)*m_Resolution+j;
826  tripoints[1] = m_NumberOfNodes-1;
827  tripoints[0] = tripoints[2]-j+jn;
828  insertCell->SetPointIds(tripoints);
829  m_Locations->SetCell(p, insertCell);
830  m_Locations->SetCellData(p, (PixelType)2.0);
831  p++;
832  insertCell = TriCell::New();
833  }
834 
835  m_NumberOfCells = p;
836 
837  m_K = (vnl_matrix_fixed<double,4,4>**)
838  malloc(sizeof(vnl_matrix_fixed<double,4,4>*)*m_NumberOfCells);
839 
840  celldata = m_Locations->GetCellData()->Begin();
841 
842  j=0;
843  while (celldata != m_Locations->GetCellData()->End())
844  {
845  w = celldata.Value();
846  ++celldata;
847  switch ((int)(w))
848  {
849  case 1:
850  m_K[j] = &m_SStiffness;
851  break;
852  case 2:
853  m_K[j] = &m_NStiffness;
854  break;
855  case 3:
856  m_K[j] = &m_CStiffness;
857  break;
858  }
859  ++j;
860  }
861  }
862 }
863 
864 /*
865  * update the displacements using d_{new} = d_{old} + timestep*d'
866  */
867 template <typename TInputMesh, typename TOutputMesh>
868 void
871 {
872  typename TInputMesh::PointType s, d, ds;
873  float dist=0.0;
874  int i;
875 
876  InputPointsContainerPointer myDerives = m_Derives->GetPoints();
877  InputPointsContainerIterator derives = myDerives->Begin();
878  InputPointsContainerPointer myDisplacements = m_Displacements->GetPoints();
879  InputPointsContainerIterator displacements = myDisplacements->Begin();
880  InputPointsContainerPointer myPoints = m_Locations->GetPoints();
881  InputPointsContainerIterator points = myPoints->Begin();
882 
883  i=0;
884  while( i < static_cast<int>(m_NumberOfNodes)-2 )
885  {
886  ds = derives.Value();
887  s = points.Value();
888  d = displacements.Value();
889  s[0] += m_TimeStep*ds[0];
890  s[1] += m_TimeStep*ds[1];
891  if ( m_GradientBegin )
892  {
893  d[0] += m_TimeStep*ds[0];
894  d[1] += m_TimeStep*ds[1];
895  }
896  else
897  {
898  d[0] = 0;
899  d[1] = 0;
900  }
901 
903  if ( (s[0] > 0) && (s[1] > 0) &&
904  (s[0] < m_ImageWidth) && (s[1] < m_ImageHeight) )
905  {
906  points.Value() = s;
907  displacements.Value() = d;
908  }
909 
910  if ( m_GradientBegin )
911  {
912  dist += vcl_sqrt(ds[0]*ds[0]+ds[1]*ds[1])*m_TimeStep;
913  m_DistanceToBoundary = dist/((float)(m_NumberOfNodes-2));
914  }
915 
916  i++;
917  ++derives;
918  ++points;
919  ++displacements;
920  }
921 
922  s[0] = 0;
923 
924 }
925 
926 /*
927  * copy the content of m_Location into output
928  */
929 template <typename TInputMesh, typename TOutputMesh>
930 void
933 {
934  typename TriCell::CellAutoPointer insertCell;
935  unsigned long tripoints[3];
936  const unsigned long *tp;
937  double x;
938 
939  m_Output = this->GetOutput();
940 
941  OutputPointsContainerPointer myPoints = m_Output->GetPoints();
942  myPoints->Reserve(m_NumberOfNodes);
943  OutputPointsContainerIterator points = myPoints->Begin();
944 
945  InputPointsContainerPointer myLocations = m_Locations->GetPoints();
946  InputPointsContainerIterator locations = myLocations->Begin();
947 
948  InputMeshConstPointer inputMesh = this->GetInput(0);
949 
950  InputCellsContainerConstPointer myCells = inputMesh->GetCells();
951  InputCellsContainerConstIterator cells = myCells->Begin();
952 
953  InputCellDataContainerConstPointer myCellData = inputMesh->GetCellData();
954  InputCellDataContainerConstIterator celldata = myCellData->Begin();
955 
956  {
957  for (unsigned int i=0; i<m_NumberOfNodes; i++)
958  {
959  points.Value() = locations.Value();
960  ++locations;
961  ++points;
962  }
963  }
964 
965  {
966  for (unsigned int i=0; i<m_NumberOfCells; i++)
967  {
968  tp = cells.Value()->GetPointIds();
969  tripoints[0] = tp[0];
970  tripoints[1] = tp[1];
971  tripoints[2] = tp[2];
972  insertCell.TakeOwnership( new TriCell );
973  insertCell->SetPointIds(tripoints);
974  m_Output->SetCell(i, insertCell );
975  x = celldata.Value();
976  m_Output->SetCellData(i, (PixelType)x);
977  ++cells;
978  ++celldata;
979  }
980  }
981 }
982 
986 template <typename TInputMesh, typename TOutputMesh>
987 void
990 {
991  this->Initialize();
992  this->SetStiffnessMatrix();
993  while (m_Step < 300)
994  {
995  this->ComputeNormals();
996  if ( m_GradientBegin ) this->GradientFit();
997  else this->ComputeForce();
998  this->ComputeDt();
999  this->Advance();
1000  this->ACDSearch();
1001  this->NodesRearrange();
1002  m_Step++;
1003  }
1004  this->ComputeOutput();
1005 }
1006 
1011 template <typename TInputMesh, typename TOutputMesh>
1012 void
1015 {
1016  InputPointsContainerPointer Points = m_Locations->GetPoints();
1017  InputPointsContainerIterator points = Points->Begin();
1018 
1019  InputPointDataContainerPointer myPointData = m_Locations->GetPointData();
1020  InputPointDataContainerIterator pointstatus = myPointData->Begin();
1021 
1022  InputCellsContainerPointer myCells = m_Locations->GetCells();
1023  InputCellsContainerIterator cells = myCells->Begin();
1024 
1025  int i, q, res = 1;
1026  IPixelType x, y, z;
1027  IPixelType* y_PixelType;
1028  IPixelType* z_PixelType;
1029  y_PixelType = &y;
1030  z_PixelType = &z;
1031  float gap, dis[3]={0, 0, 0}, st, *st_PixelType;
1032  st_PixelType = &st;
1033  const unsigned long *tp;
1034 
1035  i = 0;
1036  while( i != m_NumberOfNodes - 2 )
1037  {
1038  x = points.Value();
1039  ++points;
1040 
1041  tp = cells.Value()->GetPointIds();
1042  ++cells;
1043  ++cells;
1044 
1045  if (tp[0] == tp[1] - 1) y = points.Value();
1046  else
1047  {
1048  m_Locations->GetPoint (tp[1], y_PixelType);
1049  res++;
1050  }
1051 
1052  dis[0] = x[0] - y[0];
1053  dis[1] = x[1] - y[1];
1054  dis[2] = x[2] - y[2];
1055  gap = vcl_sqrt(dis[0]*dis[0]+dis[1]*dis[1]+dis[2]*dis[2]);
1056 
1057  m_Locations->GetPointData(q, st_PixelType);
1058  if (gap > 3)
1059  {
1060  if ( pointstatus.Value() == 1.0)
1061  {
1062  ++pointstatus;
1063  if ( pointstatus.Value() == 1.0)
1064  {
1065  z[0] = 0.5*(x[0]+y[0]);
1066  z[1] = 0.5*(x[1]+y[1]);
1067  z[2] = 0.5*(x[2]+y[2]);
1068  this->NodeAddition(i, res, z);
1069  }
1070  }
1071  else ++pointstatus;
1072  }
1073  else ++pointstatus;
1074 
1075  i++;
1076  }
1077 
1078  this->Reset();
1079 }
1080 
1084 template <typename TInputMesh, typename TOutputMesh>
1085 void
1087 ::NodeAddition(int node, int res, IPixelType z)
1088 {
1089  m_NumNewNodes++;
1090 
1091  if (m_NumNewNodes > m_NewNodeLimit)
1092  {
1093  m_NewNodes = realloc( m_NewNodes, m_NewNodeLimit*sizeof(float*)*2 );
1094  for (int i = m_NewNodeLimit; i < 2*m_NewNodeLimit; i++)
1095  {
1096  m_NewNodes[i] = (float*) malloc(sizeof(float)*5);
1097  }
1098  m_NewNodeLimit = m_NewNodeLimit*2;
1099  }
1100 
1101  m_NewNodes[m_NumNewNodes-1][0] = z[0];
1102  m_NewNodes[m_NumNewNodes-1][1] = z[1];
1103  m_NewNodes[m_NumNewNodes-1][2] = z[2];
1104  m_NewNodes[m_NumNewNodes-1][3] = (float) node;
1105  m_NewNodes[m_NumNewNodes-1][4] = (float) res;
1106 }
1107 
1111 template <typename TInputMesh, typename TOutputMesh>
1112 void
1115 {
1116  typedef typename GradientIndexType::IndexValueType IndexValueType;
1117 
1118  GradientIndexType coord, coord2, tmp_co_1, tmp_co_2;
1119  IPixelType v1, v2;
1120  PixelType mag;
1121 
1122  typename TInputMesh::PointType vec_nor, vec_loc, vec_for, tmp_vec_1, tmp_vec_2, tmp_vec_3;
1123 
1124  InputPointsContainerPointer myLocations = m_Locations->GetPoints();
1125  InputPointsContainerIterator locations = myLocations->Begin();
1126 
1127  InputPointsContainerPointer myForces = m_Forces->GetPoints();
1128  InputPointsContainerIterator forces = myForces->Begin();
1129 
1130  InputPointDataContainerPointer myForceData = m_Forces->GetPointData();
1131  InputPointDataContainerIterator forcedata = myForceData->Begin();
1132 
1133  InputPointsContainerPointer myNormals = m_Normals->GetPoints();
1134  InputPointsContainerIterator normals = myNormals->Begin();
1135 
1136  /* New gradient fit method testing. */
1137  while( forces != myForces->End() )
1138  {
1139  vec_loc = locations.Value();
1140  vec_nor = normals.Value();
1141 
1142  coord[0] = static_cast<IndexValueType>(vec_loc[0]);
1143  coord[1] = static_cast<IndexValueType>(vec_loc[1]);
1144 
1145  coord2[0] = static_cast<IndexValueType>( vcl_ceil( vec_loc[0] ) );
1146  coord2[1] = static_cast<IndexValueType>( vcl_ceil( vec_loc[1] ) );
1147 
1148  tmp_co_1[0] = coord2[0];
1149  tmp_co_1[1] = coord[1];
1150  tmp_co_2[0] = coord[0];
1151  tmp_co_2[1] = coord2[1];
1152 
1153 
1154  if ( (coord[0] >= 0) &&
1155  (coord[1] >= 0) &&
1156  (static_cast<unsigned int>( coord2[0] ) < m_ImageWidth) &&
1157  (static_cast<unsigned int>( coord2[1] ) < m_ImageHeight) )
1158  {
1159  vec_for[0] = m_Gradient->GetPixel(coord)[0];
1160  vec_for[1] = m_Gradient->GetPixel(coord)[1];
1161 
1162  tmp_vec_1[0] = m_Gradient->GetPixel(tmp_co_1)[0] - m_Gradient->GetPixel(coord)[0];
1163  tmp_vec_1[1] = m_Gradient->GetPixel(tmp_co_1)[1] - m_Gradient->GetPixel(coord)[1];
1164  tmp_vec_2[0] = m_Gradient->GetPixel(tmp_co_2)[0] - m_Gradient->GetPixel(coord)[0];
1165  tmp_vec_2[1] = m_Gradient->GetPixel(tmp_co_2)[1] - m_Gradient->GetPixel(coord)[1];
1166 
1167  vec_for[0] = vec_for[0] + (vec_loc[0]-coord[0])*tmp_vec_1[0] + (vec_loc[1]-coord[1])*tmp_vec_2[0];
1168  vec_for[1] = vec_for[1] + (vec_loc[1]-coord[1])*tmp_vec_2[1] + (vec_loc[0]-coord[0])*tmp_vec_1[1];
1169 
1170  }
1171  else
1172  {
1173  vec_for[0] = 0;
1174  vec_for[1] = 0;
1175  }
1176  mag = vec_for[0]*vec_nor[0] + vec_for[1]*vec_nor[1];
1177  vec_for[0] = mag*vec_nor[0];
1178  vec_for[1] = mag*vec_nor[1];
1179  vec_for[2] = 0.0;
1180 
1181  forces.Value() = vec_for;
1182 
1183  ++forces;
1184  ++forcedata;
1185  ++locations;
1186  ++normals;
1187  }
1188 
1189 }
1190 
1194 template <typename TInputMesh, typename TOutputMesh>
1195 void
1198 {
1199  const unsigned long *tp;
1200  IPixelType v1, v2, v3, v4;
1201  v1.Fill(0.);
1202  v2.Fill(0.);
1203  v3.Fill(0.);
1204  v4.Fill(0.);
1205 
1206  float coa, cob, coc;
1207  float absvec;
1208 
1209  InputCellsContainerPointer myCells = m_Locations->GetCells();
1210  InputCellsContainerIterator cells = myCells->Begin();
1211 
1212  InputPointsContainerPointer myNormals = m_Normals->GetPoints();
1213  InputPointsContainerIterator normals = myNormals->Begin();
1214 
1215  static float d[3]={0, 0, 0};
1216  while( normals != myNormals->End() )
1217  {
1218  normals.Value() = d;
1219  ++normals;
1220  }
1221 
1222  while ( cells != myCells->End() )
1223  {
1224  tp = cells.Value()->GetPointIds();
1225  ++cells;
1226 
1227  m_Locations->GetPoint (tp[0], &v1 );
1228  m_Locations->GetPoint (tp[1], &v2 );
1229  m_Locations->GetPoint (tp[2], &v3 );
1230 
1231  coa = -(v1[1]*(v2[2]-v3[2]) +
1232  v2[1]*(v3[2]-v1[2]) +
1233  v3[1]*(v1[2]-v2[2]));
1234  cob = -(v1[2] * (v2[0]-v3[0]) +
1235  v2[2]*(v3[0]-v1[0]) +
1236  v3[2]*(v1[0]-v2[0]));
1237  coc = -(v1[0] * (v2[1]-v3[1]) +
1238  v2[0]*(v3[1]-v1[1]) +
1239  v3[0]*(v1[1]-v2[1]));
1240 
1241  absvec = -vcl_sqrt ((double) ((coa*coa) + (cob*cob) + (coc*coc)));
1242 
1243  assert (absvec != 0);
1244 
1245  v4[0] = coa/absvec;
1246  v4[1] = cob/absvec;
1247  v4[2] = coc/absvec;
1248  m_Normals->GetPoint (tp[0], &v1 );
1249  m_Normals->GetPoint (tp[1], &v2 );
1250  m_Normals->GetPoint (tp[2], &v3 );
1251 
1252  v1[0] += v4[0];
1253  v1[1] += v4[1];
1254  v1[2] += v4[2];
1255 
1256  v2[0] += v4[0];
1257  v2[1] += v4[1];
1258  v2[2] += v4[2];
1259 
1260  v3[0] += v4[0];
1261  v3[1] += v4[1];
1262  v3[2] += v4[2];
1263 
1264  m_Normals->SetPoint (tp[0], v1);
1265  m_Normals->SetPoint (tp[1], v2);
1266  m_Normals->SetPoint (tp[2], v3);
1267 
1268  }
1269 
1270  normals = myNormals->Begin();
1271  while( normals != myNormals->End() )
1272  {
1273  v1 = normals.Value();
1274  absvec = vcl_sqrt( v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2] );
1275  v1[0] = v1[0]/absvec;
1276  v1[1] = v1[1]/absvec;
1277  v1[2] = v1[2]/absvec;
1278  normals.Value() = v1;
1279  ++normals;
1280  }
1281 }
1282 
1286 template <typename TInputMesh, typename TOutputMesh>
1287 void
1290 {
1291  int i, j, k;
1292  float dis, l1, l2;
1293  float length;
1294  IPixelType v1, v2, v3, v4;
1295 
1296  typename TInputMesh::PointType s, s1, d1, d2;
1297 
1298  InputPointsContainerPointer myLocations = m_Locations->GetPoints();
1299  InputPointsContainerIterator locations = myLocations->Begin();
1300 
1301  InputPointsContainerPointer myDisplacements = m_Displacements->GetPoints();
1302  InputPointsContainerIterator displacements = myDisplacements->Begin();
1303 
1304  InputPointsContainerPointer myNormals = m_Normals->GetPoints();
1305  InputPointsContainerIterator normals = myNormals->Begin();
1306 
1307  InputPointsContainerPointer myForces = m_Forces->GetPoints();
1308  InputPointsContainerIterator forces = myForces->Begin();
1309  InputPointsContainerIterator forcescopy;
1310 
1311  v1 = locations.Value();
1312  s = locations.Value();
1313  ++locations;
1314  s1 = locations.Value();
1315  i = 1;
1316  forcescopy = forces;
1317  forces++;
1318 
1319  while ( (i+1)%m_Resolution != 0 )
1320  {
1321  v2 = locations.Value();
1322  ++locations;
1323  v3 = locations.Value();
1324  d1[0] = v1[0] - v2[0];
1325  d2[0] = v3[0] - v2[0];
1326  d1[1] = v1[1] - v2[1];
1327  d2[1] = v3[1] - v2[1];
1328  // d1[2] = v1[2] - v2[2];
1329  // d2[2] = v3[2] - v2[2];
1330  v1[0] = v2[0];
1331  v1[1] = v2[1];
1332  // v1[2] = v2[2];
1333  dis = d1[0]*d2[0]+d1[1]*d2[1]/*+d1[2]*d2[2]*/;
1334  if ( dis > 0 )
1335  {
1336  l1 = vcl_sqrt(d1[0]*d1[0]+d1[1]*d1[1]/*+d1[2]*d1[2]*/);
1337  l2 = vcl_sqrt(d2[0]*d2[0]+d2[1]*d2[1]/*+d2[2]*d2[2]*/);
1338  dis = dis/vcl_sqrt(l1*l2);
1339  d1[0] = d1[0]/l1;
1340  d1[1] = d1[1]/l1;
1341  // d1[2] = d1[2]/l1;
1342  d2[0] = d2[0]/l2;
1343  d2[1] = d2[1]/l2;
1344  // d2[2] = d2[2]/l2;
1345  d1[0] = (d1[0]+d2[0]);
1346  d1[1] = (d1[1]+d2[1]);
1347  // d1[2] = (d1[2]+d2[2]);
1348  l1 = vcl_sqrt(d1[0]*d1[0]+d1[1]*d1[1]/*+d1[2]*d1[2]*/);
1349  d1[0] = d1[0]/l1;
1350  d1[1] = d1[1]/l1;
1351  // d1[2] = d1[2]/l1;
1352  v2[0] = v2[0] + dis * d1[0];
1353  v2[1] = v2[1] + dis * d1[1];
1354  // v2[2] = v2[2]/* + dis * d1[2];*/
1355  }
1356 
1357  forces.Value() = v2;
1358  i++;
1359  ++forces;
1360  }
1361 
1362  // for the last node in the slice
1363  v2 = locations.Value();
1364  ++locations;
1365  v3[0] = s[0];
1366  v3[1] = s[1];
1367  v3[2] = s[2];
1368  d1[0] = v1[0] - v2[0];
1369  d2[0] = v3[0] - v2[0];
1370  d1[1] = v1[1] - v2[1];
1371  d2[1] = v3[1] - v2[1];
1372  // d1[2] = v1[2] - v2[2];
1373  // d2[2] = v3[2] - v2[2];
1374  v1[0] = v2[0];
1375  v1[1] = v2[1];
1376  // v1[2] = v2[2];
1377  dis = d1[0]*d2[0]+d1[1]*d2[1]/*+d1[2]*d2[2]*/;
1378  if ( dis > 0 )
1379  {
1380  l1 = vcl_sqrt(d1[0]*d1[0]+d1[1]*d1[1]/*+d1[2]*d1[2]*/);
1381  l2 = vcl_sqrt(d2[0]*d2[0]+d2[1]*d2[1]/*+d2[2]*d2[2]*/);
1382  dis = dis/vcl_sqrt(l1*l2);
1383  d1[0] = d1[0]/l1;
1384  d1[1] = d1[1]/l1;
1385  // d1[2] = d1[2]/l1;
1386  d2[0] = d2[0]/l2;
1387  d2[1] = d2[1]/l2;
1388  // d2[2] = d2[2]/l2;
1389  d1[0] = (d1[0]+d2[0]);
1390  d1[1] = (d1[1]+d2[1]);
1391  // d1[2] = (d1[2]+d2[2]);
1392  l1 = vcl_sqrt(d1[0]*d1[0]+d1[1]*d1[1]/*+d1[2]*d1[2]*/);
1393  d1[0] = d1[0]/l1;
1394  d1[1] = d1[1]/l1;
1395  // d1[2] = d1[2]/l1;
1396  v2[0] = v2[0] + dis * d1[0];
1397  v2[1] = v2[1] + dis * d1[1];
1398  // v2[2] = v2[2] /* + dis * d1[2];*/
1399  }
1400 
1401  forces.Value() = v2;
1402  ++forces;
1403 
1404  // from the first node in the slice
1405  v2[0] = s[0];
1406  v2[1] = s[1];
1407  // v2[2] = s[2];
1408  v3[0] = s1[0];
1409  v3[1] = s1[1];
1410  // v3[2] = s1[2];
1411  d1[0] = v1[0] - v2[0];
1412  d2[0] = v3[0] - v2[0];
1413  d1[1] = v1[1] - v2[1];
1414  d2[1] = v3[1] - v2[1];
1415  // d1[2] = v1[2] - v2[2];
1416  // d2[2] = v3[2] - v2[2];
1417  // v1[0] = v2[0];
1418  // v1[1] = v2[1];
1419  // v1[2] = v2[2];
1420  dis = d1[0]*d2[0]+d1[1]*d2[1];
1421  if ( dis > 0 )
1422  {
1423  l1 = vcl_sqrt(d1[0]*d1[0]+d1[1]*d1[1]);
1424  l2 = vcl_sqrt(d2[0]*d2[0]+d2[1]*d2[1]);
1425  dis = dis/vcl_sqrt(l1*l2);
1426  d1[0] = d1[0]/l1;
1427  d1[1] = d1[1]/l1;
1428  // d1[2] = d1[2]/l1;
1429  d2[0] = d2[0]/l2;
1430  // d2[1] = d2[1]/l2;
1431  // d2[2] = d2[2]/l2;
1432  d1[0] = (d1[0]+d2[0]);
1433  d1[1] = (d1[1]+d2[1]);
1434  // d1[2] = (d1[2]+d2[2]);
1435  l1 = vcl_sqrt(d1[0]*d1[0]+d1[1]*d1[1]);
1436  d1[0] = d1[0]/l1;
1437  d1[1] = d1[1]/l1;
1438  // d1[2] = d1[2]/l1;
1439  v2[0] = v2[0] + dis * d1[0];
1440  v2[1] = v2[1] + dis * d1[1];
1441  // v2[2] = v2[2]/* + dis * d1[2];*/
1442  }
1443 
1444  forcescopy.Value() = v2;
1445 
1446  forces = myForces->Begin();
1447 
1448  dis = 0;
1449  i = 0;
1450  s = forces.Value();
1451  // forcescopy = forces;
1452 
1453  while ( i < m_Resolution - 1 )
1454  {
1455  v1 = forces.Value();
1456  ++forces;
1457  v2 = forces.Value();
1458  // m_Displacements->GetPointData(i+j*m_Resolution, d_PixelTyper);
1459  dis += vcl_sqrt((v1[0]-v2[0])*(v1[0]-v2[0])+(v1[1]-v2[1])*(v1[1]-v2[1]));
1460  i++;
1461  }
1462  // m_Displacements->GetPointData(i+j*m_Resolution, d_PixelTyper);
1463  dis += vcl_sqrt((s[0]-v2[0])*(s[0]-v2[0])+(s[1]-v2[1])*(s[1]-v2[1]));
1464  length = dis/m_Resolution;
1465  ++forces;
1466 
1467  forces = myForces->Begin();
1468 
1469  k = 1;
1470  i = 0;
1471  l1 = 0;
1472  v1 = forces.Value();
1473  normals.Value() = v1;
1474  ++normals;
1475  v3 = forces.Value();
1476  while ( i < m_Resolution - 1 )
1477  {
1478  v1 = forces.Value();
1479  ++forces;
1480  v2 = forces.Value();
1481  dis = vcl_sqrt((v1[0]-v2[0])*(v1[0]-v2[0])+(v1[1]-v2[1])*(v1[1]-v2[1]));
1482  l2 = -1*l1;
1483  l1 += dis;
1484  // m_Displacements->GetPointData(i+j*m_Resolution, d_PixelTyper);
1485  while ( l1 > length )
1486  {
1487  if (k==m_Resolution) break;
1488  s[0] = v1[0] + (length+l2)*(v2[0] - v1[0])/dis;
1489  s[1] = v1[1] + (length+l2)*(v2[1] - v1[1])/dis;
1490  // s[2] = v1[2];
1491  normals.Value() = s;
1492  ++normals;
1493  k++;
1494  l2 += length;
1495  l1 -= length;
1496  }
1497  i++;
1498  if (k==m_Resolution) break;
1499  }
1500 
1501  if (k==m_Resolution)
1502  {
1503  while (i < m_Resolution)
1504  {
1505  i++;
1506  ++forces;
1507  }
1508  }
1509 
1510  v1 = forces.Value();
1511  ++forces;
1512  dis = vcl_sqrt((v1[0]-v3[0])*(v1[0]-v3[0])+(v1[1]-v3[1])*(v1[1]-v3[1]));
1513  l2 = -1*l1;
1514  l1 += dis;
1515  // m_Displacements->GetPointData(i+j*m_Resolution, d_PixelTyper);
1516  while ( l1 > length )
1517  {
1518  if (k==m_Resolution) break;
1519  s[0] = v1[0] + (length+l2)*(v3[0] - v1[0])/dis;
1520  s[1] = v1[1] + (length+l2)*(v3[1] - v1[1])/dis;
1521  // s[2] = v1[2];
1522  normals.Value() = s;
1523  ++normals;
1524  k++;
1525  l2 += length;
1526  l1 -= length;
1527  }
1528 
1529  locations = myLocations->Begin();
1530  normals = myNormals->Begin();
1531  displacements = myDisplacements->Begin();
1532  forces = myForces->Begin();
1533 
1534  {
1535  i = 0;
1536  while ( i < static_cast<int>(m_NumberOfNodes) - 2 )
1537  {
1538  v1 = normals.Value();
1539  // v1 = forces.Value();
1540  v2 = locations.Value();
1541  v3 = displacements.Value();
1542  v3[0] += v1[0] - v2[0];
1543  v3[1] += v1[1] - v2[1];
1544  // v3[2] += v1[2] - v2[2];
1545  locations.Value() = v1;
1546  if ( m_GradientBegin ) displacements.Value() = v3;
1547  ++normals;
1548  // ++forces;
1549  ++locations;
1550  ++displacements;
1551  i++;
1552  }
1553  }
1554 
1555  locations = myLocations->Begin();
1556  j = 0;
1557  for (; j < 1; j++)
1558  {
1559  //dis = 0;
1560  i = 0;
1561  s = locations.Value();
1562  while ( i < m_Resolution - 1 )
1563  {
1564  v1 = locations.Value();
1565  ++locations;
1566  v2 = locations.Value();
1567  //dis = vcl_sqrt((v1[0]-v2[0])*(v1[0]-v2[0])+(v1[1]-v2[1])*(v1[1]-v2[1]));
1568  i++;
1569  }
1570  ++locations;
1571  }
1572 
1573 }
1574 
1575 template <typename TInputMesh, typename TOutputMesh>
1576 void
1579 {
1580  unsigned int i;
1581  int j, l, m, n, PixelType1, PixelType2;
1582  float s;
1583  IPixelType v, v1, v2, v3;
1584  m_ACD = (int**) malloc(sizeof(int *)*m_ImageHeight/2);
1585 
1586  for (i=0; i<m_ImageHeight/2; i++)
1587  {
1588  m_ACD[i] = (int*) malloc(sizeof(int)*m_ImageWidth/2);
1589  }
1590 
1591  InputPointsContainerPointer myLocations = m_Locations->GetPoints();
1592  InputPointsContainerIterator locations = myLocations->Begin();
1593  InputPointsContainerIterator locationscopy;
1594  InputPointsContainerIterator locationscopy1;
1595  InputPointsContainerPointer myDisplacements = m_Displacements->GetPoints();
1596  InputPointsContainerIterator displacements = myDisplacements->Begin();
1599 
1600  for (j = 0; j < 1; j++)
1601  {
1602  i = 0;
1603  locationscopy = locations;
1604  dpcopy = displacements;
1605 
1606  for (unsigned int ll=0; ll < m_ImageHeight/2; ll++)
1607  {
1608  for (unsigned int mm=0; mm < m_ImageWidth/2; mm++)
1609  {
1610  m_ACD[ll][mm] = -1;
1611  }
1612  }
1613 
1614  for (; i < static_cast<unsigned int>( m_Resolution ); i++)
1615  {
1616  v = locations.Value();
1617  ++locations;
1618  ++displacements;
1619  l = (int)(v[0]/2);
1620  m = (int)(v[1]/2);
1621 
1622  int ii = static_cast<int>( i );
1623 
1624  if (m_ACD[m][l] == -1)
1625  {
1626  m_ACD[m][l] = ii;
1627  }
1628  else
1629  {
1630  if (((ii - m_ACD[m][l]) > m_Resolution/10) &&
1631  ((m_Resolution-ii+m_ACD[m][l])>m_Resolution/10))
1632  {
1633  locationscopy1 = locationscopy;
1634  n = 0;
1635  v1[0] = 0;
1636  v1[1] = 0;
1637  // v1[2] = 0;
1638  if ( (ii - m_ACD[m][l]) < 0.5*m_Resolution )
1639  {
1640  if (m_ACD[m][l] == 0)
1641  {
1642  PixelType1 = m_Resolution - 1;
1643  }
1644  else
1645  {
1646  PixelType1 = m_ACD[m][l] - 1;
1647  }
1648  if (ii == m_Resolution - 1)
1649  {
1650  PixelType2 = 0;
1651  }
1652  else
1653  {
1654  PixelType2 = ii + 1;
1655  }
1656  while (n<m_Resolution)
1657  {
1658  v = locationscopy1.Value();
1659  if ((n>m_ACD[m][l]) && (n<ii))
1660  {
1661  v1[0] += v[0];
1662  v1[1] += v[1];
1663  }
1664  else
1665  {
1666  if ( n == PixelType1) v2 = locationscopy1.Value();
1667  if ( n == PixelType2 ) v3 = locationscopy1.Value();
1668  }
1669  ++locationscopy1;
1670  n++;
1671  }
1672  v1[0] = v1[0]/(ii-m_ACD[m][l]-1);
1673  v1[1] = v1[1]/(ii-m_ACD[m][l]-1);
1674  s = 1;
1675  if (s > 0)
1676  {
1677  locationscopy1 = locationscopy;
1678  dpcopy1 = dpcopy;
1679  n = 0;
1680  while (n<m_Resolution)
1681  {
1682  if ((n>m_ACD[m][l]) && (n<ii))
1683  {
1684  v1 = locationscopy1.Value();
1685  locationscopy1.Value() = v;
1686  v2 = dpcopy1.Value();
1687  v2[0] += v[0] - v1[0];
1688  v2[1] += v[1] - v1[1];
1689  // v2[2] += v[2] - v1[2];
1690  dpcopy1.Value() = v2;
1691  }
1692  if ( n == m_ACD[m][l] )
1693  {
1694  v = locationscopy1.Value();
1695  }
1696  ++locationscopy1;
1697  ++dpcopy1;
1698  n++;
1699  }
1700  }
1701  }
1702  else
1703  {
1704  while (n<m_Resolution)
1705  {
1706  PixelType1 = m_ACD[m][l] + 1;
1707  PixelType2 = ii - 1;
1708  v = locationscopy1.Value();
1709  if ((n<m_ACD[m][l]) && (n>ii))
1710  {
1711  v1[0] += v[0];
1712  v1[1] += v[1];
1713  }
1714  else
1715  {
1716  if ( n == PixelType1 ) v2 = locationscopy1.Value();
1717  if ( n == PixelType2 ) v3 = locationscopy1.Value();
1718  }
1719  ++locationscopy1;
1720  n++;
1721  }
1722  v1[0] = v1[0]/(ii-m_ACD[m][l]-1);
1723  v1[1] = v1[1]/(ii-m_ACD[m][l]-1);
1724  s = -1;
1725  if (s < 0)
1726  {
1727  locationscopy1 = locationscopy;
1728  dpcopy1 = dpcopy;
1729  n = 0;
1730  while (n<m_Resolution)
1731  {
1732  if ( n == ii )
1733  {
1734  v = locationscopy1.Value();
1735  }
1736  ++locationscopy1;
1737  n++;
1738  }
1739  locationscopy1 = locationscopy;
1740  n = 0;
1741  while (n<m_Resolution)
1742  {
1743  if ((n<m_ACD[m][l]) && (n>ii))
1744  {
1745  v1 = locationscopy1.Value();
1746  locationscopy1.Value() = v;
1747  v2 = dpcopy1.Value();
1748  v2[0] += v[0] - v1[0];
1749  v2[1] += v[1] - v1[1];
1750  // v2[2] += v[2] - v1[2];
1751  dpcopy1.Value() = v2;
1752  }
1753  ++locationscopy1;
1754  ++dpcopy1;
1755  n++;
1756  }
1757  }
1758  }
1759 
1760  m_ModelRestart = 1;
1761  break;
1762  }
1763  }
1764  }
1765  }
1766 
1767  m_ModelRestart = 0;
1768  for (i=0; i<m_ImageHeight/2; i++)
1769  {
1770  free(m_ACD[i]);
1771  }
1772  free(m_ACD);
1773 
1774 }
1775 
1776 } // end namespace itk
1777 
1778 #endif

Generated at Sat May 11 2013 23:27:56 for Orfeo Toolbox with doxygen 1.8.3.1