17 #ifndef __itkParallelSparseFieldLevelSetImageFilter_txx
18 #define __itkParallelSparseFieldLevelSetImageFilter_txx
25 #include "itkNumericTraits.h"
33 template <
class TNeighborhoodType>
37 typedef typename NeighborhoodType::ImageType ImageType;
38 typename ImageType::Pointer dummy_image = ImageType::New();
40 unsigned int i, nCenter;
44 for (i = 0; i < Dimension; ++i)
49 NeighborhoodType it(m_Radius, dummy_image, dummy_image->GetRequestedRegion());
50 nCenter = it.Size() / 2;
52 m_Size = 2 * Dimension;
53 m_ArrayIndex.reserve(m_Size);
54 m_NeighborhoodOffset.reserve(m_Size);
56 for (i = 0; i < m_Size; ++i)
58 m_NeighborhoodOffset.push_back(zero_offset);
61 for (d = Dimension - 1, i = 0; d >= 0; --d, ++i)
63 m_ArrayIndex.push_back( nCenter - it.GetStride(d) );
64 m_NeighborhoodOffset[i][d] = -1;
66 for (d = 0; d < static_cast<int> (Dimension); ++d, ++i)
68 m_ArrayIndex.push_back( nCenter + it.GetStride(d) );
69 m_NeighborhoodOffset[i][d] = 1;
72 for (i = 0; i < Dimension; ++i)
74 m_StrideTable[i] = it.GetStride(i);
78 template <
class TNeighborhoodType>
83 os <<
"ParallelSparseFieldCityBlockNeighborList: " << std::endl;
84 for (
unsigned i = 0; i < this->GetSize(); ++i)
86 os <<
"m_ArrayIndex[" << i <<
"]: " << m_ArrayIndex[i] << std::endl
87 <<
"m_NeighborhoodOffset[" << i <<
"]: " << m_NeighborhoodOffset[i] << std::endl;
91 template<
class TInputImage,
class TOutputImage>
95 TOutputImage>::ValueType >::One;
97 template<
class TInputImage,
class TOutputImage>
101 TOutputImage>::ValueType >::Zero;
103 template<
class TInputImage,
class TOutputImage>
107 TOutputImage>::StatusType >::NonpositiveMin();
109 template<
class TInputImage,
class TOutputImage>
112 ::m_StatusChanging = -1;
114 template<
class TInputImage,
class TOutputImage>
117 ::m_StatusActiveChangingUp = -2;
119 template<
class TInputImage,
class TOutputImage>
122 ::m_StatusActiveChangingDown = -3;
124 template<
class TInputImage,
class TOutputImage>
127 ::m_StatusBoundaryPixel = -4;
129 template<
class TInputImage,
class TOutputImage>
133 m_IsoSurfaceValue = m_ValueZero;
134 m_NumberOfLayers = ImageDimension;
135 this->SetRMSChange( static_cast<double>( m_ValueOne ) );
136 m_InterpolateSurfaceLocation =
true;
137 m_BoundsCheckingActive =
false;
138 m_ConstantGradientValue = 1.0;
139 m_GlobalZHistogram = 0;
140 m_ZCumulativeFrequency = 0;
141 m_MapZToThreadNumber = 0;
146 template<
class TInputImage,
class TOutputImage>
151 if (this->GetState() == Superclass::UNINITIALIZED)
154 this->DeallocateData();
157 m_OutputImage= this->GetOutput();
158 m_OutputImage->SetBufferedRegion(m_OutputImage->GetRequestedRegion());
159 m_OutputImage->Allocate();
163 this->CopyInputToOutput();
167 this->SetElapsedIterations(0);
178 if (this->GetManualReinitialization() ==
false)
180 this->DeallocateData();
181 this->SetStateToUninitialized();
186 template<
class TInputImage,
class TOutputImage>
200 typename ShiftScaleFilterType::Pointer shiftScaleFilter = ShiftScaleFilterType::New();
201 shiftScaleFilter->SetInput( this->GetInput() );
202 shiftScaleFilter->SetShift( - m_IsoSurfaceValue );
204 m_ShiftedImage = shiftScaleFilter->GetOutput();
208 zeroCrossingFilter->SetInput(m_ShiftedImage);
209 zeroCrossingFilter->GraftOutput(m_OutputImage);
210 zeroCrossingFilter->SetBackgroundValue(m_ValueOne);
211 zeroCrossingFilter->SetForegroundValue(m_ValueZero);
212 zeroCrossingFilter->SetNumberOfThreads(1);
213 zeroCrossingFilter->Update();
216 this->GraftOutput(zeroCrossingFilter->GetOutput());
219 template<
class TInputImage,
class TOutputImage>
227 m_LayerNodeStore = LayerNodeStorageType::New();
228 m_LayerNodeStore->SetGrowthStrategyToExponential();
231 m_StatusImage = StatusImageType::New();
232 m_StatusImage->SetRegions(m_OutputImage->GetRequestedRegion());
233 m_StatusImage->Allocate();
237 m_StatusImage->GetRequestedRegion());
238 for (statusIt = statusIt.Begin(); ! statusIt.IsAtEnd(); ++statusIt)
240 statusIt.
Set( m_StatusNull );
249 BFCType faceCalculator;
250 typename BFCType::FaceListType faceList;
251 typename BFCType::SizeType sz;
252 typename BFCType::FaceListType::iterator fit;
255 faceList = faceCalculator(m_StatusImage, m_StatusImage->GetRequestedRegion(),
257 fit = faceList.begin();
259 for (++fit; fit != faceList.end(); ++fit)
262 for (statusIt.GoToBegin(); ! statusIt.IsAtEnd(); ++statusIt)
264 statusIt.
Set( m_StatusBoundaryPixel );
269 m_Layers.reserve(2 * m_NumberOfLayers + 1);
270 for (i = 0; i < 2 * static_cast<unsigned int>(m_NumberOfLayers) + 1; ++i)
272 m_Layers.push_back( LayerType::New() );
275 m_SplitAxis = m_OutputImage->GetImageDimension() - 1;
276 if (m_OutputImage->GetImageDimension() < 1)
279 itkDebugMacro (
"Unable to choose an axis for workload distribution among threads");
283 typename OutputImageType::SizeType requestedRegionSize
284 = m_OutputImage->GetRequestedRegion().GetSize();
285 m_ZSize = requestedRegionSize[m_SplitAxis];
288 m_GlobalZHistogram =
new int[m_ZSize];
289 for (i = 0; i < m_ZSize; i++)
291 m_GlobalZHistogram[i] = 0;
296 this->ConstructActiveLayer();
300 for (i = 1; i < m_Layers.size() - 2; ++i)
302 this->ConstructLayer(i, i+2);
306 this->InitializeActiveLayerValues();
309 this->PropagateAllLayerValues();
315 this->InitializeBackgroundPixels();
317 m_NumOfThreads = this->GetNumberOfThreads();
321 m_ZCumulativeFrequency =
new int[m_ZSize];
322 for (i = 0; i < m_ZSize; i++)
324 m_ZCumulativeFrequency[i] = 0;
328 m_MapZToThreadNumber =
new unsigned int[m_ZSize];
329 for (i = 0; i < m_ZSize; i++)
331 m_MapZToThreadNumber[i] = 0;
335 m_Boundary =
new unsigned int[m_NumOfThreads];
336 for (i = 0; i < m_NumOfThreads; i++)
343 m_BoundaryChanged =
false;
347 m_Barrier->Initialize(m_NumOfThreads);
353 template <
class TInputImage,
class TOutputImage>
365 m_ShiftedImage, m_OutputImage->GetRequestedRegion());
367 m_OutputImage, m_OutputImage->GetRequestedRegion());
369 m_StatusImage, m_OutputImage->GetRequestedRegion());
373 bool bounds_status =
true;
377 typename OutputImageType::SizeType regionSize
378 = m_OutputImage->GetRequestedRegion().GetSize();
379 typename OutputImageType::IndexType startIndex
380 = m_OutputImage->GetRequestedRegion().GetIndex();
381 typedef typename OutputImageType::IndexType::IndexValueType StartIndexValueType;
383 for (outputIt.GoToBegin(); !outputIt.IsAtEnd(); ++outputIt)
385 bounds_status =
true;
386 if ( outputIt.GetCenterPixel() == m_ValueZero )
390 statusIt.SetLocation( center_index );
392 for(
unsigned int j = 0; j < ImageDimension; j++)
394 if ( (center_index[j]) <= (startIndex[j]) ||
395 (center_index[j]) >= startIndex[j] +
396 static_cast<StartIndexValueType>(regionSize[j]-1))
398 bounds_status =
false;
402 if(bounds_status ==
true)
405 m_GlobalZHistogram[ center_index[m_SplitAxis] ]++;
408 node = m_LayerNodeStore->Borrow();
413 m_Layers[0]->PushFront( node );
414 statusIt.SetCenterPixel( 0 );
417 shiftedIt.SetLocation( center_index );
421 for (
unsigned int i = 0; i < m_NeighborList.GetSize(); ++i)
423 offset_index = center_index + m_NeighborList.GetNeighborhoodOffset(i);
425 if ( outputIt.GetPixel(m_NeighborList.GetArrayIndex(i)) != m_ValueZero &&
426 statusIt.GetPixel(m_NeighborList.GetArrayIndex(i)) == m_StatusNull)
428 value = shiftedIt.
GetPixel(m_NeighborList.GetArrayIndex(i));
430 if ( value < m_ValueZero )
439 statusIt.SetPixel( m_NeighborList.GetArrayIndex(i), layer_number, bounds_status );
440 if ( bounds_status ==
true )
442 node = m_LayerNodeStore->Borrow();
444 m_Layers[layer_number]->PushFront( node );
453 template<
class TInputImage,
class TOutputImage>
459 bool boundary_status;
462 m_OutputImage->GetRequestedRegion() );
465 for (fromIt = m_Layers[from]->Begin(); fromIt != m_Layers[from]->End(); ++fromIt)
473 for (
unsigned int i = 0; i < m_NeighborList.GetSize(); ++i)
475 if ( statusIt.GetPixel( m_NeighborList.GetArrayIndex(i) ) == m_StatusNull )
477 statusIt.SetPixel(m_NeighborList.GetArrayIndex(i), to, boundary_status);
479 if (boundary_status ==
true)
481 node = m_LayerNodeStore->Borrow();
482 node->
m_Index = statusIt.GetIndex() + m_NeighborList.GetNeighborhoodOffset(i);
483 m_Layers[to]->PushFront( node );
490 template <
class TInputImage,
class TOutputImage>
495 const ValueType CHANGE_FACTOR = m_ConstantGradientValue / 2.0;
497 if (this->GetUseImageSpacing())
500 for (
unsigned int i=0; i<ImageDimension; i++)
502 minSpacing = vnl_math_min(minSpacing,this->GetInput()->GetSpacing()[i]);
504 MIN_NORM *= minSpacing;
509 m_OutputImage->GetRequestedRegion());
511 unsigned int center = shiftedIt.
Size() /2;
514 const NeighborhoodScalesType neighborhoodScales = this->GetDifferenceFunction()->ComputeNeighborhoodScales();
516 ValueType dx_forward, dx_backward, length, distance;
519 for (activeIt = m_Layers[0]->Begin(); activeIt != m_Layers[0]->End(); ++activeIt)
523 shiftedIt.SetLocation( activeIt->m_Index );
525 length = m_ValueZero;
526 for (
unsigned int i = 0; i < static_cast<unsigned int>(ImageDimension); ++i)
528 stride = shiftedIt.GetStride(i);
530 dx_forward = ( shiftedIt.GetPixel(center + stride) - shiftedIt.GetCenterPixel() ) * neighborhoodScales[i];
531 dx_backward = ( shiftedIt.GetCenterPixel() - shiftedIt.GetPixel(center - stride) ) * neighborhoodScales[i];
533 if ( vnl_math_abs(dx_forward) > vnl_math_abs(dx_backward) )
535 length += dx_forward * dx_forward;
539 length += dx_backward * dx_backward;
542 length = vcl_sqrt(length) + MIN_NORM;
543 distance = shiftedIt.GetCenterPixel() / length;
545 m_OutputImage->SetPixel( activeIt->m_Index ,
546 vnl_math_min(vnl_math_max(-CHANGE_FACTOR, distance), CHANGE_FACTOR));
550 template <
class TInputImage,
class TOutputImage>
558 this->PropagateLayerValues (0, 1, 3, 1);
559 this->PropagateLayerValues (0, 2, 4, 0);
562 for (
unsigned int i = 1; i < m_Layers.size() - 2; ++i)
564 this->PropagateLayerValues (i, i+2, i+4, (i+2)%2);
568 template <
class TInputImage,
class TOutputImage>
575 bool found_neighbor_flag;
582 delta = - m_ConstantGradientValue;
586 delta = m_ConstantGradientValue;
590 m_OutputImage->GetRequestedRegion());
592 m_OutputImage->GetRequestedRegion());
595 while ( toIt != m_Layers[to]->End() )
597 statusIt.SetLocation( toIt->m_Index );
601 if (statusIt.GetCenterPixel() != to)
603 node = toIt.GetPointer();
605 m_Layers[to]->Unlink( node );
606 m_LayerNodeStore->Return( node );
613 found_neighbor_flag =
false;
614 for (i = 0; i < m_NeighborList.GetSize(); ++i)
619 if ( statusIt.GetPixel( m_NeighborList.GetArrayIndex(i) ) == from )
621 value_temp = outputIt.GetPixel( m_NeighborList.GetArrayIndex(i) );
623 if (found_neighbor_flag ==
false)
629 if (vnl_math_abs(value_temp+delta) < vnl_math_abs(value+delta))
635 found_neighbor_flag =
true;
638 if (found_neighbor_flag ==
true)
642 outputIt.SetCenterPixel( value + delta );
651 node = toIt.GetPointer();
653 m_Layers[to]->Unlink( node );
654 if ( promote > past_end )
656 m_LayerNodeStore->Return( node );
661 m_Layers[promote]->PushFront( node );
662 statusIt.SetCenterPixel(promote);
668 template <
class TInputImage,
class TOutputImage>
679 const ValueType outside_value = (max_layer+1) * m_ConstantGradientValue;
680 const ValueType inside_value = -(max_layer+1) * m_ConstantGradientValue;
683 this->GetOutput()->GetRequestedRegion());
686 this->GetOutput()->GetRequestedRegion());
689 this->GetOutput()->GetRequestedRegion());
691 for (outputIt = outputIt.
Begin(), statusIt = statusIt.
Begin(),
692 shiftedIt = shiftedIt.
Begin();
693 ! outputIt.
IsAtEnd(); ++outputIt, ++statusIt, ++shiftedIt)
695 if (statusIt.Get() == m_StatusNull || statusIt.Get() == m_StatusBoundaryPixel)
697 if (shiftedIt.
Get() > m_ValueZero)
699 outputIt.
Set(outside_value);
703 outputIt.
Set(inside_value);
712 template<
class TInputImage,
class TOutputImage>
724 m_ZCumulativeFrequency[0] = m_GlobalZHistogram[0];
725 for (i= 1; i < m_ZSize; i++)
727 m_ZCumulativeFrequency[i] = m_ZCumulativeFrequency[i-1] + m_GlobalZHistogram[i];
732 m_Boundary[m_NumOfThreads - 1] = m_ZSize - 1;
734 for (i= 0; i < m_NumOfThreads - 1; i++)
738 float cutOff = 1.0 * (i+1) * m_ZCumulativeFrequency[m_ZSize-1] / m_NumOfThreads;
741 for (j = (i == 0 ? 0 : m_Boundary[i-1]); j < m_ZSize; j++)
743 if (cutOff > m_ZCumulativeFrequency[j])
756 for (k= 1; j+k < m_ZSize; k++)
758 if (m_ZCumulativeFrequency[j+k] != m_ZCumulativeFrequency[j])
765 m_Boundary[i]=
static_cast<unsigned int>( (j + k / 2) );
775 for (i = 0; i <= m_Boundary[0]; i++)
778 m_MapZToThreadNumber[i]= 0;
781 for (
unsigned int t= 1; t < m_NumOfThreads; t++)
783 for (i = m_Boundary[t-1]+1; i <= m_Boundary[t]; i++)
786 m_MapZToThreadNumber[i]= t;
791 template<
class TInputImage,
class TOutputImage>
796 static const float SAFETY_FACTOR = 4.0;
801 m_Data[ThreadId].m_Semaphore[0]->Initialize(0);
802 m_Data[ThreadId].m_Semaphore[1]->Initialize(0);
805 m_Data[ThreadId].m_Layers.reserve(2 * m_NumberOfLayers + 1);
806 for (i = 0; i < 2 * static_cast<unsigned int>(m_NumberOfLayers) + 1; ++i)
808 m_Data[ThreadId].m_Layers.push_back( LayerType::New() );
811 if (m_Data[ThreadId].m_Layers.size() < 3)
813 itkExceptionMacro( <<
"Not enough layers have been allocated for the sparse"
814 <<
"field. Requires at least one layer." );
818 m_Data[ThreadId].m_LoadTransferBufferLayers
820 for (i = 0; i < 2 * static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
822 m_Data[ThreadId].m_LoadTransferBufferLayers[i].reserve( m_NumOfThreads );
824 for (j = 0; j < m_NumOfThreads; j++)
826 m_Data[ThreadId].m_LoadTransferBufferLayers[i].push_back(LayerType::New());
831 m_Data[ThreadId].m_LayerNodeStore = LayerNodeStorageType::New();
832 m_Data[ThreadId].m_LayerNodeStore->SetGrowthStrategyToExponential();
836 unsigned int nodeNum=
static_cast<unsigned int>(SAFETY_FACTOR * m_Layers[0]->Size()
837 * (2*m_NumberOfLayers+1) / m_NumOfThreads);
839 m_Data[ThreadId].m_LayerNodeStore->Reserve(nodeNum);
840 m_Data[ThreadId].m_RMSChange = m_ValueZero;
843 for (i = 0; i < 2; ++i)
845 m_Data[ThreadId].UpList[i] = LayerType::New();
846 m_Data[ThreadId].DownList[i] = LayerType::New();
851 m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[0]
855 m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[1]
858 for (i= 0; i < static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
860 m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[0][i] =
862 m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[1][i] =
866 for (i= 0; i < static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
868 for (j= 0; j < m_NumOfThreads; j++)
870 m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[0][i][j]
872 m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[1][i][j]
878 m_Data[ThreadId].m_ZHistogram =
new int[m_ZSize];
879 for (i = 0; i < m_ZSize; i++)
881 m_Data[ThreadId].m_ZHistogram[i] = 0;
885 m_Data[ThreadId].globalData
886 = this->GetDifferenceFunction()->GetGlobalDataPointer();
889 m_Data[ThreadId].m_SemaphoreArrayNumber = 0;
892 template<
class TInputImage,
class TOutputImage>
901 for (
unsigned int i = 0; i < 2 * static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
906 while (layerIt != layerEnd)
911 unsigned int k = this->GetThreadNumber(nodePtr->
m_Index[m_SplitAxis]);
921 nodeTempPtr= m_Data[ThreadId].m_LayerNodeStore->Borrow ();
924 m_Data[ThreadId].m_Layers[i]->PushFront(nodeTempPtr);
930 m_Data[ThreadId].m_ZHistogram[ (nodePtr->
m_Index)[m_SplitAxis] ]
931 = m_Data[ThreadId].m_ZHistogram[ (nodePtr->
m_Index)[m_SplitAxis] ] + 1;
947 for (outputIt = outputIt.
Begin(), statusIt = statusIt.
Begin(),
948 outputItNew = outputItNew.
Begin(), statusItNew = statusItNew.
Begin();
949 ! outputIt.
IsAtEnd(); ++outputIt, ++statusIt, ++outputItNew, ++statusItNew)
951 statusItNew.
Set (statusIt.Get());
952 outputItNew.Set (outputIt.
Get());
956 template <
class TInputImage,
class TOutputImage>
963 if ( m_GlobalZHistogram != 0 )
965 delete [] m_GlobalZHistogram;
966 m_GlobalZHistogram = 0;
968 if ( m_ZCumulativeFrequency != 0 )
970 delete [] m_ZCumulativeFrequency;
971 m_ZCumulativeFrequency = 0;
973 if ( m_MapZToThreadNumber != 0 )
975 delete [] m_MapZToThreadNumber;
976 m_MapZToThreadNumber = 0;
980 delete [] m_Boundary;
991 if (! m_Layers.empty())
993 for (i = 0; i < 2* static_cast<unsigned int>(m_NumberOfLayers)+1; i++)
998 while (! layerPtr->Empty())
1000 nodePtr= layerPtr->Front();
1001 layerPtr->PopFront();
1002 m_LayerNodeStore->Return (nodePtr);
1006 if (m_LayerNodeStore)
1008 m_LayerNodeStore->Clear();
1015 for (
unsigned int ThreadId= 0; ThreadId < m_NumOfThreads; ThreadId++)
1018 m_Data[ThreadId].m_Semaphore[0]->Remove();
1019 m_Data[ThreadId].m_Semaphore[1]->Remove();
1021 delete [] m_Data[ThreadId].m_ZHistogram;
1023 if (m_Data[ThreadId].globalData != 0)
1025 this->GetDifferenceFunction()->ReleaseGlobalDataPointer (m_Data[ThreadId].globalData);
1026 m_Data[ThreadId].globalData= 0;
1030 for (i = 0; i < 2 * static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
1035 while (! layerPtr->Empty())
1037 nodePtr= layerPtr->Front();
1038 layerPtr->PopFront();
1039 m_Data[ThreadId].m_LayerNodeStore->Return(nodePtr);
1042 m_Data[ThreadId].m_Layers.clear();
1046 for (i = 0; i < 2 * static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
1048 for (j= 0; j < m_NumOfThreads; j++)
1057 LayerPointerType layerPtr= m_Data[ThreadId].m_LoadTransferBufferLayers[i][j];
1059 while (! layerPtr->Empty())
1061 nodePtr= layerPtr->Front();
1062 layerPtr->PopFront();
1063 m_Data[ThreadId].m_LayerNodeStore->Return (nodePtr);
1066 m_Data[ThreadId].m_LoadTransferBufferLayers[i].clear();
1068 delete [] m_Data[ThreadId].m_LoadTransferBufferLayers;
1071 for (i= 0; i < m_NumOfThreads; i++)
1074 for (
unsigned int InOrOut= 0; InOrOut < 2; InOrOut++)
1077 = m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[InOrOut][m_NumberOfLayers][i];
1079 while (! layerPtr->Empty())
1081 nodePtr= layerPtr->Front();
1082 layerPtr->PopFront();
1083 m_Data[ThreadId].m_LayerNodeStore->Return(nodePtr);
1089 for (i = 0; i < static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
1091 delete [] m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[0][i];
1092 delete [] m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[1][i];
1094 delete [] m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[0];
1095 delete [] m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[1];
1100 m_Data[ThreadId].m_LayerNodeStore->Clear();
1108 template<
class TInputImage,
class TOutputImage>
1118 template<
class TInputImage,
class TOutputImage>
1128 this->GetMultiThreader()->SetNumberOfThreads (m_NumOfThreads);
1136 for (
unsigned int i =0; i < m_NumOfThreads; ++i)
1142 this->GetMultiThreader()->SetSingleMethod(this->IterateThreaderCallback, &str);
1144 this->GetMultiThreader()->SingleMethodExecute ();
1150 template<
class TInputImage,
class TOutputImage>
1157 const unsigned int LOAD_BALANCE_ITERATION_FREQUENCY = 30;
1167 #ifdef ITK_USE_SPROC
1172 if (MultiThreader::GetThreadArena() != 0)
1174 int code= usadd (MultiThreader::GetThreadArena());
1177 OStringStream message;
1178 message <<
"Thread failed to join SGI arena: error";
1179 throw ::itk::ExceptionObject(__FILE__, __LINE__, message.str().c_str(),ITK_LOCATION);
1296 unsigned int count = 0;
1355 % LOAD_BALANCE_ITERATION_FREQUENCY == 0)
1382 template <
class TInputImage,
class TOutputImage>
1390 ValueType norm_grad_phi_squared, dx_forward, dx_backward;
1391 ValueType centerValue, forwardValue, backwardValue;
1393 if (this->GetUseImageSpacing())
1396 for (
unsigned int i=0; i<ImageDimension; i++)
1398 minSpacing = vnl_math_min(minSpacing,this->GetInput()->GetSpacing()[i]);
1400 MIN_NORM *= minSpacing;
1404 m_OutputImage->GetRequestedRegion());
1405 if ( m_BoundsCheckingActive ==
false )
1409 unsigned int i, center = outputIt.Size() /2;
1411 const NeighborhoodScalesType neighborhoodScales = this->GetDifferenceFunction()->ComputeNeighborhoodScales();
1421 for (; layerIt != layerEnd; ++layerIt)
1423 outputIt.SetLocation(layerIt->m_Index);
1427 if (this->m_InterpolateSurfaceLocation &&
1434 norm_grad_phi_squared = 0.0;
1436 for (i = 0; i < static_cast<unsigned int>(ImageDimension); ++i)
1438 forwardValue = outputIt.GetPixel(center + m_NeighborList.GetStride(i));
1439 backwardValue= outputIt.GetPixel(center - m_NeighborList.GetStride(i));
1441 if (forwardValue * backwardValue >= 0)
1444 dx_forward = forwardValue - centerValue;
1445 dx_backward = centerValue - backwardValue;
1448 if (vnl_math_abs(dx_forward) > vnl_math_abs(dx_backward))
1450 offset[i]= dx_forward;
1454 offset[i]= dx_backward;
1461 if (centerValue * forwardValue < 0)
1463 offset[i]= forwardValue - centerValue;
1467 offset[i]= centerValue - backwardValue;
1471 norm_grad_phi_squared += offset[i] * offset[i];
1474 for (i = 0; i < static_cast<unsigned int>(ImageDimension); ++i)
1476 offset[i] = ( offset[i] * outputIt.GetCenterPixel() )
1477 / (norm_grad_phi_squared + MIN_NORM);
1480 layerIt->m_Value = df->ComputeUpdate (outputIt, (
void *) m_Data[ThreadId].globalData, offset);
1484 layerIt->m_Value = df->ComputeUpdate (outputIt, (
void *) m_Data[ThreadId].globalData);
1488 TimeStepType timeStep= df->ComputeGlobalTimeStep ((
void*) m_Data[ThreadId].globalData);
1493 template <
class TInputImage,
class TOutputImage>
1498 this->ThreadedUpdateActiveLayerValues(dt,
1499 m_Data[ThreadId].UpList[0],
1500 m_Data[ThreadId].DownList[0],
1506 this->SignalNeighborsAndWait(ThreadId);
1510 this->ThreadedProcessStatusList( 0, 1, 2, 1, 1, 0, ThreadId);
1511 this->ThreadedProcessStatusList( 0, 1, 1, 2, 0, 0, ThreadId);
1513 this->SignalNeighborsAndWait(ThreadId);
1516 this->ThreadedProcessFirstLayerStatusLists( 1, 0, 3, 1, 1, ThreadId);
1517 this->ThreadedProcessFirstLayerStatusLists( 1, 0, 4, 0, 1, ThreadId);
1522 this->SignalNeighborsAndWait(ThreadId);
1526 unsigned char j= 0, k= 1;
1529 while ( down_search < 2 * m_NumberOfLayers + 1 )
1531 this->ThreadedProcessStatusList(j, k, up_to, up_search, 1,
1532 (up_search - 1) / 2, ThreadId);
1533 this->ThreadedProcessStatusList(j, k, down_to, down_search, 0,
1534 (up_search - 1) / 2, ThreadId);
1536 this->SignalNeighborsAndWait(ThreadId);
1551 this->ThreadedProcessStatusList(j, k, up_to, m_StatusNull, 1,
1552 (up_search - 1) / 2, ThreadId);
1553 this->ThreadedProcessStatusList(j, k, down_to, m_StatusNull, 0,
1554 (up_search - 1) / 2, ThreadId);
1556 this->SignalNeighborsAndWait(ThreadId);
1558 this->ThreadedProcessOutsideList(k,(2 * m_NumberOfLayers + 1) - 2, 1,
1559 (up_search + 1) / 2, ThreadId);
1560 this->ThreadedProcessOutsideList(k,(2 * m_NumberOfLayers + 1) - 1, 0,
1561 (up_search + 1) / 2, ThreadId);
1563 if (m_OutputImage->GetImageDimension() < 3)
1565 this->SignalNeighborsAndWait(ThreadId);
1575 this->ThreadedPropagateLayerValues(0, 1, 3, 1, ThreadId);
1576 this->ThreadedPropagateLayerValues(0, 2, 4, 0, ThreadId);
1578 this->SignalNeighborsAndWait (ThreadId);
1582 for (i = 1; i < (2 * static_cast<unsigned int>(m_NumberOfLayers) + 1) - 2; i += 2)
1585 this->ThreadedPropagateLayerValues(i, i+2, i+4, 1, ThreadId);
1586 this->ThreadedPropagateLayerValues(j, j+2, j+4, 0, ThreadId);
1587 this->SignalNeighborsAndWait (ThreadId);
1591 template <
class TInputImage,
class TOutputImage>
1595 LayerType * DownList,
unsigned int ThreadId)
1604 ValueType LOWER_ACTIVE_THRESHOLD = - (m_ConstantGradientValue / 2.0);
1605 ValueType UPPER_ACTIVE_THRESHOLD = m_ConstantGradientValue / 2.0;
1613 unsigned long int counter =0;
1615 float rms_change_accumulator = m_ValueZero;
1617 unsigned int Neighbor_Size = m_NeighborList.GetSize();
1620 = m_Data[ThreadId].m_Layers[0]->Begin();
1622 = m_Data[ThreadId].m_Layers[0]->End();
1624 while (layerIt != layerEnd )
1626 centerIndex = layerIt->m_Index;
1627 centerValue = m_OutputImage->GetPixel(centerIndex);
1629 new_value = this->ThreadedCalculateUpdateValue(ThreadId, centerIndex, dt,
1630 centerValue, layerIt->m_Value);
1643 if (new_value > UPPER_ACTIVE_THRESHOLD)
1649 for (
unsigned int i = 0; i < Neighbor_Size; ++i)
1651 if (m_StatusImage->GetPixel(centerIndex + m_NeighborList.GetNeighborhoodOffset(i))
1652 == m_StatusActiveChangingDown)
1664 rms_change_accumulator += vnl_math_sqr(static_cast<float>(new_value - centerValue ));
1666 m_OutputImage->SetPixel (centerIndex, new_value);
1672 m_Data[ThreadId].m_Layers[0]->Unlink(release_node);
1673 m_Data[ThreadId].m_ZHistogram[ release_node->
m_Index[m_SplitAxis] ]
1674 = m_Data[ThreadId].m_ZHistogram[ release_node->
m_Index[m_SplitAxis] ] - 1;
1680 m_StatusImage->SetPixel(centerIndex, m_StatusActiveChangingUp);
1682 else if (new_value < LOWER_ACTIVE_THRESHOLD)
1687 for (
unsigned int i = 0; i < Neighbor_Size; ++i)
1689 if (m_StatusImage->GetPixel(centerIndex+m_NeighborList.GetNeighborhoodOffset(i))
1690 == m_StatusActiveChangingUp)
1702 rms_change_accumulator += vnl_math_sqr(static_cast<float>(new_value - centerValue));
1704 m_OutputImage->SetPixel(centerIndex, new_value );
1710 m_Data[ThreadId].m_Layers[0]->Unlink(release_node);
1711 m_Data[ThreadId].m_ZHistogram[ release_node->
m_Index[m_SplitAxis] ]
1712 = m_Data[ThreadId].m_ZHistogram[ release_node->
m_Index[m_SplitAxis] ] - 1;
1717 m_StatusImage->SetPixel(centerIndex, m_StatusActiveChangingDown);
1721 rms_change_accumulator += vnl_math_sqr(static_cast<float>(new_value - centerValue));
1723 m_OutputImage->SetPixel(centerIndex, new_value );
1732 m_Data[ThreadId].m_RMSChange = m_ValueZero;
1736 m_Data[ThreadId].m_RMSChange = rms_change_accumulator;
1739 m_Data[ThreadId].m_Count = counter;
1742 template <
class TInputImage,
class TOutputImage>
1754 while (layerIt != layerEnd)
1760 nodeTempPtr= m_Data[ThreadId].m_LayerNodeStore->Borrow();
1764 ToListPtr->PushFront (nodeTempPtr);
1768 template <
class TInputImage,
class TOutputImage>
1775 while (! ListPtr->Empty())
1777 nodePtr= ListPtr->Front();
1779 ListPtr->PopFront();
1781 m_Data[ThreadId].m_LayerNodeStore->Return (nodePtr);
1785 template <
class TInputImage,
class TOutputImage>
1789 unsigned int InOrOut,
unsigned int BufferLayerNumber)
1793 CopyInsertList(ThreadId,
1794 m_Data[this->GetThreadNumber(m_Boundary[ThreadId-1])].m_InterNeighborNodeTransferBufferLayers[InOrOut][BufferLayerNumber][ThreadId],
1798 if (m_Boundary[ThreadId] != m_ZSize - 1)
1800 CopyInsertList(ThreadId,
1801 m_Data[this->GetThreadNumber (m_Boundary[ThreadId] + 1)].m_InterNeighborNodeTransferBufferLayers[InOrOut][BufferLayerNumber][ThreadId],
1806 template <
class TInputImage,
class TOutputImage>
1810 unsigned int BufferLayerNumber)
1812 for (
unsigned int i= 0; i < m_NumOfThreads; i++)
1814 ClearList(ThreadId, m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[InOrOut][BufferLayerNumber][i]);
1818 template <
class TInputImage,
class TOutputImage>
1823 unsigned int InOrOut,
unsigned int BufferLayerNumber,
unsigned int ThreadId)
1828 bool found_neighbor_flag;
1832 unsigned int neighbor_Size = m_NeighborList.GetSize();
1839 delta = - m_ConstantGradientValue;
1841 InputList = m_Data[ThreadId].UpList[InputLayerNumber];
1842 OutputList = m_Data[ThreadId].UpList[OutputLayerNumber];
1846 delta = m_ConstantGradientValue;
1848 InputList = m_Data[ThreadId].DownList[InputLayerNumber];
1849 OutputList = m_Data[ThreadId].DownList[OutputLayerNumber];
1856 CopyInsertInterNeighborNodeTransferBufferLayers(ThreadId, InputList, InOrOut,
1857 BufferLayerNumber - 1);
1861 while (layerIt != layerEnd)
1866 center_index = nodePtr->
m_Index;
1869 InputList->Unlink(nodePtr);
1878 if (m_StatusImage->GetPixel(center_index) == 0)
1881 m_Data[ThreadId].m_LayerNodeStore->Return (nodePtr);
1886 m_StatusImage->SetPixel(center_index, 0);
1888 m_Data[ThreadId].m_Layers[0]->PushFront(nodePtr);
1890 m_Data[ThreadId].m_ZHistogram[ nodePtr->
m_Index[m_SplitAxis] ]
1891 = m_Data[ThreadId].m_ZHistogram[ nodePtr->
m_Index[m_SplitAxis] ] + 1;
1893 value = m_OutputImage->GetPixel(center_index);
1894 found_neighbor_flag =
false;
1895 for (
unsigned int i = 0; i < neighbor_Size; ++i)
1897 n_index = center_index + m_NeighborList.GetNeighborhoodOffset(i);
1898 neighbor_status = m_StatusImage->GetPixel(n_index);
1901 if ( neighbor_status == m_StatusBoundaryPixel )
1903 m_BoundsCheckingActive =
true;
1906 if (neighbor_status == from)
1908 value_temp = m_OutputImage->GetPixel(n_index);
1910 if (found_neighbor_flag ==
false)
1916 if (vnl_math_abs(value_temp+delta) < vnl_math_abs(value+delta))
1922 found_neighbor_flag =
true;
1925 if (neighbor_status == SearchForStatus)
1930 m_StatusImage->SetPixel(n_index, m_StatusChanging);
1932 unsigned int tmpId = this->GetThreadNumber(n_index[m_SplitAxis]);
1934 nodePtr = m_Data[ThreadId].m_LayerNodeStore->Borrow();
1937 if (tmpId != ThreadId)
1939 m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[InOrOut][BufferLayerNumber][tmpId]->PushFront(nodePtr);
1943 OutputList->PushFront(nodePtr);
1947 m_OutputImage->SetPixel(center_index, value + delta );
1949 this->ThreadedProcessPixelEnteringActiveLayer (center_index, value + delta, ThreadId);
1953 template <
class TInputImage,
class TOutputImage>
1958 const unsigned int itkNotUsed(ThreadId))
1964 template <
class TInputImage,
class TOutputImage>
1969 unsigned int InOrOut,
unsigned int BufferLayerNumber,
unsigned int ThreadId)
1985 InputList = m_Data[ThreadId].UpList[InputLayerNumber];
1986 OutputList = m_Data[ThreadId].UpList[OutputLayerNumber];
1990 InputList = m_Data[ThreadId].DownList[InputLayerNumber];
1991 OutputList = m_Data[ThreadId].DownList[OutputLayerNumber];
1997 if (BufferLayerNumber >= 2)
1999 ClearInterNeighborNodeTransferBufferLayers(ThreadId, InOrOut,
2000 BufferLayerNumber - 2);
2005 if (BufferLayerNumber == 0)
2007 ClearInterNeighborNodeTransferBufferLayers(ThreadId, InOrOut, m_NumberOfLayers);
2013 if (BufferLayerNumber > 0)
2015 CopyInsertInterNeighborNodeTransferBufferLayers(ThreadId, InputList,
2016 InOrOut, BufferLayerNumber - 1);
2019 unsigned int neighbor_size = m_NeighborList.GetSize();
2020 while ( ! InputList->Empty() )
2022 nodePtr = InputList->Front();
2023 center_index = nodePtr->
m_Index;
2025 InputList->PopFront();
2031 if ((BufferLayerNumber != 0)
2032 && (m_StatusImage->GetPixel(center_index) == ChangeToStatus))
2035 m_Data[ThreadId].m_LayerNodeStore->Return (nodePtr);
2041 m_Data[ThreadId].m_Layers[ChangeToStatus]->PushFront (nodePtr);
2043 m_StatusImage->SetPixel(center_index, ChangeToStatus);
2045 for (i = 0; i < neighbor_size; ++i)
2047 n_index = center_index + m_NeighborList.GetNeighborhoodOffset(i);
2049 neighbor_status = m_StatusImage->GetPixel(n_index);
2052 if ( neighbor_status == m_StatusBoundaryPixel )
2054 m_BoundsCheckingActive =
true;
2057 if (neighbor_status == SearchForStatus)
2062 m_StatusImage->SetPixel(n_index, m_StatusChanging);
2064 unsigned int tmpId = this->GetThreadNumber (n_index[m_SplitAxis]);
2066 nodePtr = m_Data[ThreadId].m_LayerNodeStore->Borrow();
2069 if (tmpId != ThreadId)
2071 m_Data[ThreadId].m_InterNeighborNodeTransferBufferLayers[InOrOut][BufferLayerNumber][tmpId]->PushFront(nodePtr);
2075 OutputList->PushFront(nodePtr);
2082 template <
class TInputImage,
class TOutputImage>
2086 unsigned int InOrOut,
unsigned int BufferLayerNumber,
unsigned int ThreadId)
2091 OutsideList= m_Data[ThreadId].UpList [InputLayerNumber];
2095 OutsideList= m_Data[ThreadId].DownList[InputLayerNumber];
2103 ClearInterNeighborNodeTransferBufferLayers(ThreadId, InOrOut, BufferLayerNumber - 2);
2108 CopyInsertInterNeighborNodeTransferBufferLayers(ThreadId, OutsideList, InOrOut,
2109 BufferLayerNumber - 1);
2114 while ( ! OutsideList->Empty() )
2116 nodePtr = OutsideList->Front();
2117 OutsideList->PopFront();
2119 m_StatusImage->SetPixel(nodePtr->
m_Index, ChangeToStatus);
2120 m_Data[ThreadId].m_Layers[ChangeToStatus]->PushFront (nodePtr);
2124 template <
class TInputImage,
class TOutputImage>
2128 unsigned int InOrOut,
unsigned int ThreadId)
2131 bool found_neighbor_flag;
2140 delta = - m_ConstantGradientValue;
2144 delta = m_ConstantGradientValue;
2147 unsigned int Neighbor_Size = m_NeighborList.GetSize();
2148 toIt = m_Data[ThreadId].m_Layers[to]->Begin();
2149 toEnd = m_Data[ThreadId].m_Layers[to]->End();
2154 while ( toIt != toEnd )
2156 centerIndex = toIt->m_Index;
2158 centerStatus = m_StatusImage->GetPixel(centerIndex);
2160 if (centerStatus != to)
2167 m_Data[ThreadId].m_Layers[to]->Unlink( nodePtr );
2168 m_Data[ThreadId].m_LayerNodeStore->Return( nodePtr );
2172 value = m_ValueZero;
2173 found_neighbor_flag =
false;
2174 for (
unsigned int i = 0; i < Neighbor_Size; ++i)
2176 nIndex = centerIndex + m_NeighborList.GetNeighborhoodOffset(i);
2177 nStatus = m_StatusImage->GetPixel(nIndex);
2182 if (nStatus == from)
2184 value_temp = m_OutputImage->GetPixel(nIndex);
2186 if (found_neighbor_flag ==
false)
2192 if (vnl_math_abs(value_temp+delta) < vnl_math_abs(value+delta))
2198 found_neighbor_flag =
true;
2201 if (found_neighbor_flag ==
true)
2205 m_OutputImage->SetPixel (centerIndex, value + delta);
2216 m_Data[ThreadId].m_Layers[to]->Unlink( nodePtr );
2218 if ( promote > past_end )
2220 m_Data[ThreadId].m_LayerNodeStore->Return( nodePtr );
2221 m_StatusImage->SetPixel(centerIndex, m_StatusNull);
2225 m_Data[ThreadId].m_Layers[promote]->PushFront( nodePtr );
2226 m_StatusImage->SetPixel(centerIndex, promote);
2232 template<
class TInputImage,
class TOutputImage>
2240 const float MAX_PIXEL_DIFFERENCE_PERCENT = 0.025;
2241 m_BoundaryChanged =
false;
2248 for (i = 0; i < m_NumOfThreads; i++)
2250 long int count = m_Data[i].m_Layers[0]->Size();
2252 if (min > count) min = count;
2253 if (max < count) max = count;
2256 if (max - min < MAX_PIXEL_DIFFERENCE_PERCENT * total / m_NumOfThreads)
2266 for (i= 0; i < m_NumOfThreads; i++)
2268 for (j= (i == 0 ? 0 : m_Boundary[i-1] + 1); j <= m_Boundary[i]; j++)
2270 m_GlobalZHistogram[j] = m_Data[i].m_ZHistogram[j];
2275 m_ZCumulativeFrequency[0] = m_GlobalZHistogram[0];
2276 for (i= 1; i < m_ZSize; i++)
2278 m_ZCumulativeFrequency[i] = m_ZCumulativeFrequency[i-1] + m_GlobalZHistogram[i];
2282 m_Boundary[m_NumOfThreads - 1] = m_ZSize - 1;
2284 for (i= 0; i < m_NumOfThreads - 1; i++)
2287 float cutOff= 1.0f * (i+1) * m_ZCumulativeFrequency[m_ZSize-1] / m_NumOfThreads;
2290 for (j= (i == 0 ? 0 : m_Boundary[i-1]); j < m_ZSize; j++)
2292 if (cutOff > m_ZCumulativeFrequency[j])
2305 for (k= 1; j+k < m_ZSize; k++)
2307 if (m_ZCumulativeFrequency[j+k] != m_ZCumulativeFrequency[j])
2315 unsigned int newBoundary=
static_cast<unsigned int> ((j + (j+k)) / 2);
2316 if (newBoundary != m_Boundary[i])
2319 m_BoundaryChanged=
true;
2320 m_Boundary[i]= newBoundary;
2327 if (m_BoundaryChanged ==
false)
2334 for (i= 0; i < m_NumOfThreads; i++)
2338 for (j= 0; j <= m_Boundary[i-1]; j++)
2340 m_Data[i].m_ZHistogram[j] = 0;
2344 for (j= (i == 0 ? 0 : m_Boundary[i-1] + 1); j <= m_Boundary[i]; j++)
2347 m_Data[i].m_ZHistogram[j] = m_GlobalZHistogram[j];
2350 m_MapZToThreadNumber[j]= i;
2353 for (j= m_Boundary[i] + 1; j < m_ZSize; j++)
2355 m_Data[i].m_ZHistogram[j] = 0;
2360 template<
class TInputImage,
class TOutputImage>
2384 for (i = 0; i < 2 * static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
2386 for (j= 0; j < m_NumOfThreads; j++)
2394 ClearList(ThreadId, m_Data[ThreadId].m_LoadTransferBufferLayers[i][j]);
2399 for (i = 0; i < 2 * static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
2404 while (layerIt != layerEnd)
2411 unsigned int tmpId = this->GetThreadNumber(nodePtr->
m_Index[m_SplitAxis]);
2413 if (tmpId != ThreadId)
2416 m_Data[ThreadId].m_Layers[i]->Unlink(nodePtr);
2424 m_Data[ThreadId].m_LoadTransferBufferLayers[i][tmpId]->PushFront(nodePtr);
2435 for (i = 0; i < 2 * static_cast<unsigned int>(m_NumberOfLayers) + 1; i++)
2438 for (j= 0; j < m_NumOfThreads; j++)
2445 CopyInsertList(ThreadId, m_Data[j].m_LoadTransferBufferLayers[i][ThreadId],
2446 m_Data[ThreadId].m_Layers[i]);
2451 template<
class TInputImage,
class TOutputImage>
2457 ThreadRegion = m_OutputImage->GetRequestedRegion();
2460 typename TOutputImage::IndexType threadRegionIndex = ThreadRegion.GetIndex();
2463 if (m_Boundary[ThreadId-1] < m_Boundary[m_NumOfThreads -1])
2465 threadRegionIndex[m_SplitAxis] += m_Boundary[ThreadId-1] + 1;
2469 threadRegionIndex[m_SplitAxis] += m_Boundary[ThreadId-1];
2473 ThreadRegion.SetIndex (threadRegionIndex);
2476 typename TOutputImage::SizeType threadRegionSize = ThreadRegion.GetSize();
2477 threadRegionSize[m_SplitAxis] = (ThreadId == 0
2478 ? (m_Boundary[0] + 1)
2479 : m_Boundary[ThreadId] - m_Boundary[ThreadId-1]);
2480 ThreadRegion.SetSize(threadRegionSize);
2483 template<
class TInputImage,
class TOutputImage>
2489 ThreadRegion = m_OutputImage->GetRequestedRegion();
2491 typename TOutputImage::IndexType threadRegionIndex = ThreadRegion.GetIndex();
2492 threadRegionIndex[m_SplitAxis]
2493 +=
static_cast<unsigned int> (1.0 * ThreadId * m_ZSize / m_NumOfThreads);
2494 ThreadRegion.SetIndex(threadRegionIndex);
2496 typename TOutputImage::SizeType threadRegionSize = ThreadRegion.GetSize();
2499 if (ThreadId < m_NumOfThreads - 1)
2501 threadRegionSize [m_SplitAxis] =
static_cast<unsigned int> (1.0 * (ThreadId+1) * m_ZSize / m_NumOfThreads)
2502 -
static_cast<unsigned int> (1.0 * ThreadId * m_ZSize / m_NumOfThreads);
2506 threadRegionSize [m_SplitAxis] = m_ZSize
2507 -
static_cast<unsigned int> (1.0 * ThreadId * m_ZSize / m_NumOfThreads);
2509 ThreadRegion.SetSize(threadRegionSize);
2512 template<
class TInputImage,
class TOutputImage>
2522 const ValueType outside_value = (max_layer+1) * m_ConstantGradientValue;
2523 const ValueType inside_value = -(max_layer+1) * m_ConstantGradientValue;
2528 for (outputIt = outputIt.
Begin(), statusIt = statusIt.
Begin();
2529 ! outputIt.
IsAtEnd(); ++outputIt, ++statusIt)
2531 if (statusIt.
Get() == m_StatusNull || statusIt.
Get() == m_StatusBoundaryPixel)
2533 if (outputIt.
Get() > m_ValueZero)
2535 outputIt.
Set (outside_value);
2539 outputIt.
Set (inside_value);
2545 template<
class TInputImage,
class TOutputImage>
2550 return ( m_MapZToThreadNumber[splitAxisValue] );
2553 template<
class TInputImage,
class TOutputImage>
2564 if (m_Boundary[ThreadId-1] == m_Boundary[ThreadId])
2566 m_Data[ThreadId].m_SemaphoreArrayNumber= 1
2567 - m_Data[ThreadId].m_SemaphoreArrayNumber;
2572 unsigned int lastThreadId = m_NumOfThreads - 1;
2573 if (lastThreadId == 0)
2581 this->SignalNeighbor(m_Data[ThreadId].m_SemaphoreArrayNumber,
2582 this->GetThreadNumber ( m_Boundary[ThreadId-1] ));
2584 if (m_Boundary[ThreadId] != m_ZSize - 1)
2586 this->SignalNeighbor (m_Data[ThreadId].m_SemaphoreArrayNumber,
2587 this->GetThreadNumber ( m_Boundary[ThreadId] + 1 ));
2591 if ((ThreadId == 0) || (m_Boundary[ThreadId] == m_ZSize - 1))
2595 this->WaitForNeighbor (m_Data[ThreadId].m_SemaphoreArrayNumber, ThreadId);
2596 m_Data[ThreadId].m_SemaphoreArrayNumber= 1 - m_Data[ThreadId].m_SemaphoreArrayNumber;
2601 this->WaitForNeighbor (m_Data[ThreadId].m_SemaphoreArrayNumber, ThreadId);
2602 this->WaitForNeighbor (m_Data[ThreadId].m_SemaphoreArrayNumber, ThreadId);
2604 m_Data[ThreadId].m_SemaphoreArrayNumber= 1 - m_Data[ThreadId].m_SemaphoreArrayNumber;
2608 template<
class TInputImage,
class TOutputImage>
2613 m_Data[ThreadId].m_Semaphore[SemaphoreArrayNumber]->Up();
2616 template<
class TInputImage,
class TOutputImage>
2621 m_Data[ThreadId].m_Semaphore[SemaphoreArrayNumber]->Down();
2624 template<
class TInputImage,
class TOutputImage>
2632 template<
class TInputImage,
class TOutputImage>
2637 Superclass::PrintSelf(os, indent);
2641 os << indent <<
"m_IsoSurfaceValue: " << this->GetIsoSurfaceValue() << std::endl;
2642 os << indent <<
"m_LayerNodeStore: " << m_LayerNodeStore;
2643 unsigned int ThreadId;
2644 for (ThreadId=0; ThreadId < m_NumOfThreads; ThreadId++)
2646 os << indent <<
"ThreadId: " << ThreadId << std::endl;
2649 for (i=0; i < m_Data[ThreadId].m_Layers.size(); i++)
2651 os << indent <<
"m_Layers[" << i <<
"]: size="
2652 << m_Data[ThreadId].m_Layers[i]->Size() << std::endl;
2653 os << indent << m_Data[ThreadId].m_Layers[i];