]> Creatis software - cpMesh.git/blobdiff - lib/cpm/Plugins/SimpleFillRegion.cxx
Almost compatible with new cpPlugins
[cpMesh.git] / lib / cpm / Plugins / SimpleFillRegion.cxx
index 167c9e040e5d2e1dab0b07464a27af7a88df0b87..1821ca2ad8f79f9668dba417150490b64a35215d 100644 (file)
@@ -1,4 +1,36 @@
 #include <cpm/Plugins/SimpleFillRegion.h>
+#include <cpPlugins/Interface/Image.h>
+
+#include <itkBinaryThresholdImageFunction.h>
+#include <itkFloodFilledImageFunctionConditionalConstIterator.h>
+
+#define ITK_MANUAL_INSTANTIATION
+#include <itkImage.h>
+
+// -------------------------------------------------------------------------
+#define cpmPlugins_SimpleFillRegion_Dimension( r, d, i1, i2, f )     \
+  if(                                                                \
+    dynamic_cast< itk::ImageBase< d >* >( i1 ) != NULL &&            \
+    dynamic_cast< itk::ImageBase< d >* >( i2 ) != NULL               \
+    )                                                                \
+    r = this->f< d >( )
+
+// -------------------------------------------------------------------------
+#define cpmPlugins_SimpleFillRegion_Pixel1( r, p, d, i, f )          \
+  if( dynamic_cast< itk::Image< p, d >* >( i ) != NULL )             \
+    r = this->f< p, d >( )
+
+// -------------------------------------------------------------------------
+#define cpmPlugins_SimpleFillRegion_Pixel2( r, p1, p2, d, i, f )     \
+  if( dynamic_cast< itk::Image< p2, d >* >( i ) != NULL )            \
+    r = this->f< p1, p2, d >( )
+
+// -------------------------------------------------------------------------
+std::string cpm::Plugins::SimpleFillRegion::
+GetClassName( ) const
+{
+  return( "cpm::Plugins::SimpleFillRegion" );
+}
 
 // -------------------------------------------------------------------------
 cpm::Plugins::SimpleFillRegion::
@@ -6,10 +38,18 @@ SimpleFillRegion( )
   : Superclass( )
 {
   this->SetNumberOfInputs( 2 );
+  this->SetNumberOfOutputs( 1 );
+  this->_MakeOutput< cpPlugins::Interface::Image >( 0 );
+
+  using namespace cpPlugins::Interface;
+  this->m_DefaultParameters.Configure( Parameters::Real, "MinDelta" );
+  this->m_DefaultParameters.Configure( Parameters::Real, "MaxDelta" );
+  this->m_DefaultParameters.Configure( Parameters::Point, "Seed" );
 
-  this->m_DefaultParameters[ "MinDelta" ] = TParameter( "double", "0" );
-  this->m_DefaultParameters[ "MaxDelta" ] = TParameter( "double", "0" );
-  this->m_DefaultParameters[ "Seed" ] = TParameter( "point", "0:0:0" );
+  this->m_DefaultParameters.SetValueAsReal( "MinDelta", 0 );
+  this->m_DefaultParameters.SetValueAsReal( "MaxDelta", 0 );
+  this->m_DefaultParameters.SetValueAsPoint( "Seed", 3, 0.0, 0.0, 0.0 );
+  this->m_Parameters = this->m_DefaultParameters;
 }
 
 // -------------------------------------------------------------------------
@@ -20,16 +60,190 @@ cpm::Plugins::SimpleFillRegion::
 
 // -------------------------------------------------------------------------
 std::string cpm::Plugins::SimpleFillRegion::
-GetClassName( ) const
+_GenerateData( )
 {
-  return( "cpm::Plugins::SimpleFillRegion" );
+  itk::DataObject* i1 = this->_GetInput( 0 );
+  itk::DataObject* i2 = this->_GetInput( 1 );
+
+  std::string r =
+    "cpm::Plugins::SimpleFillRegion: itk::Image(s) dimensions not supported";
+  cpmPlugins_SimpleFillRegion_Dimension( r, 2, i1, i2, _GD0 );
+  else cpmPlugins_SimpleFillRegion_Dimension( r, 3, i1, i2, _GD0 );
+  return( r );
 }
 
 // -------------------------------------------------------------------------
+template< unsigned int D >
 std::string cpm::Plugins::SimpleFillRegion::
-_GenerateData( )
+_GD0( )
+{
+  typedef itk::ImageBase< D > _TImage;
+
+  _TImage* i1 = dynamic_cast< _TImage* >( this->_GetInput( 0 ) );
+
+  std::string r =
+    "cpm::Plugins::SimpleFillRegion: first image's pixel type not supported";
+  cpmPlugins_SimpleFillRegion_Pixel1( r, char, D, i1, _GD1 );
+  else cpmPlugins_SimpleFillRegion_Pixel1( r, short, D, i1, _GD1 );
+  else cpmPlugins_SimpleFillRegion_Pixel1( r, int, D, i1, _GD1 );
+  else cpmPlugins_SimpleFillRegion_Pixel1( r, long, D, i1, _GD1 );
+  else cpmPlugins_SimpleFillRegion_Pixel1( r, unsigned char, D, i1, _GD1 );
+  else cpmPlugins_SimpleFillRegion_Pixel1( r, unsigned short, D, i1, _GD1 );
+  else cpmPlugins_SimpleFillRegion_Pixel1( r, unsigned int, D, i1, _GD1 );
+  else cpmPlugins_SimpleFillRegion_Pixel1( r, unsigned long, D, i1, _GD1 );
+  else cpmPlugins_SimpleFillRegion_Pixel1( r, float, D, i1, _GD1 );
+  else cpmPlugins_SimpleFillRegion_Pixel1( r, double, D, i1, _GD1 );
+  return( r );
+}
+
+// -------------------------------------------------------------------------
+template< class P1, unsigned int D >
+std::string cpm::Plugins::SimpleFillRegion::
+_GD1( )
 {
-  std::cout << "Simple fill region" << std::endl;
+  typedef itk::ImageBase< D > _TImage;
+
+  _TImage* i2 = dynamic_cast< _TImage* >( this->_GetInput( 1 ) );
+
+  std::string r =
+    "cpm::Plugins::SimpleFillRegion: second image's pixel type not supported";
+  cpmPlugins_SimpleFillRegion_Pixel2( r, P1, char, D, i2, _GD2 );
+  else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, short, D, i2, _GD2 );
+  else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, int, D, i2, _GD2 );
+  else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, long, D, i2, _GD2 );
+  else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, unsigned char, D, i2, _GD2 );
+  else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, unsigned short, D, i2, _GD2 );
+  else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, unsigned int, D, i2, _GD2 );
+  else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, unsigned long, D, i2, _GD2 );
+  else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, float, D, i2, _GD2 );
+  else cpmPlugins_SimpleFillRegion_Pixel2( r, P1, double, D, i2, _GD2 );
+  return( r );
+}
+
+// -------------------------------------------------------------------------
+template< typename I1, class I2, typename TCoordRep >
+class SimpleFillRegionFunction
+  : public itk::BinaryThresholdImageFunction< I1, TCoordRep >
+{
+public:
+  typedef SimpleFillRegionFunction                 Self;
+  typedef itk::BinaryThresholdImageFunction< I1, TCoordRep > Superclass;
+  typedef itk::SmartPointer< Self >                          Pointer;
+  typedef itk::SmartPointer< const Self >                    ConstPointer;
+
+  itkTypeMacro( SimpleFillRegionFunction, itkBinaryThresholdImageFunction );
+  itkNewMacro( Self );
+
+  itkSetConstObjectMacro( InputSegmentation, I2 );
+
+  typedef typename Superclass::InputImageType InputImageType;
+  typedef typename I1::PixelType PixelType;
+  itkStaticConstMacro(ImageDimension, unsigned int, Superclass::ImageDimension);
+  typedef typename Superclass::PointType PointType;
+  typedef typename Superclass::IndexType IndexType;
+  typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
+
+  virtual bool EvaluateAtIndex( const IndexType& index ) const
+    {
+      bool cont = true;
+      if( this->m_InputSegmentation.IsNotNull( ) )
+        cont = (
+          this->m_InputSegmentation->GetPixel( index ) ==
+          ( typename I2::PixelType )( 0 )
+          );
+      if( cont )
+        return( this->Superclass::EvaluateAtIndex( index ) );
+      else
+        return( false );
+    }
+
+protected:
+  SimpleFillRegionFunction( )
+    : Superclass( )
+    {
+    }
+  virtual ~SimpleFillRegionFunction( )
+    {
+    }
+
+private:
+  // Purposely not implemented
+  SimpleFillRegionFunction( const Self& );
+  Self& operator=( const Self& );
+
+protected:
+  typename I2::ConstPointer m_InputSegmentation;
+};
+
+// -------------------------------------------------------------------------
+template< class P1, class P2, unsigned int D >
+std::string cpm::Plugins::SimpleFillRegion::
+_GD2( )
+{
+  typedef itk::Image< P1, D > _TImage1;
+  typedef itk::Image< P2, D > _TImage2;
+
+  _TImage1* i1 = dynamic_cast< _TImage1* >( this->_GetInput( 0 ) );
+  _TImage2* i2 = dynamic_cast< _TImage2* >( this->_GetInput( 1 ) );
+
+  // Transform input seed
+  typename _TImage1::PointType pnt =
+    this->m_Parameters.GetValueAsPoint< typename _TImage1::PointType >( "Seed" );
+  typename _TImage1::IndexType idx;
+  i1->TransformPhysicalPointToIndex( pnt, idx );
+
+  // Check spatial compatilibity
+  if( i1->GetLargestPossibleRegion( ) != i2->GetLargestPossibleRegion( ) )
+    return( "cpm::Plugins::SimpleFillRegion: incompatible regions." );
+  if( i1->GetSpacing( ) != i2->GetSpacing( ) )
+    return( "cpm::Plugins::SimpleFillRegion: incompatible spacings." );
+  if( i1->GetOrigin( ) != i2->GetOrigin( ) )
+    return( "cpm::Plugins::SimpleFillRegion: incompatible origins." );
+  if( i1->GetDirection( ) != i2->GetDirection( ) )
+    return( "cpm::Plugins::SimpleFillRegion: incompatible directions." );
+
+  // Create output
+  typename _TImage2::Pointer out = _TImage2::New( );
+  this->_SetOutput( 0, out );
+
+  // Create memory, if needed
+  if(
+    i1->GetLargestPossibleRegion( ) != out->GetLargestPossibleRegion( ) ||
+    i1->GetSpacing( ) != out->GetSpacing( ) ||
+    i1->GetOrigin( ) != out->GetOrigin( ) ||
+    i1->GetDirection( ) != out->GetDirection( )
+    )
+  {
+    out->SetLargestPossibleRegion( i1->GetLargestPossibleRegion( ) );
+    out->SetRequestedRegion( i1->GetRequestedRegion( ) );
+    out->SetBufferedRegion( i1->GetBufferedRegion( ) );
+    out->SetDirection( i1->GetDirection( ) );
+    out->SetOrigin( i1->GetOrigin( ) );
+    out->SetSpacing( i1->GetSpacing( ) );
+    out->Allocate( );
+
+  } // fi
+  out->FillBuffer( P2( 0 ) );
+
+  P1 min_delta = P1( this->m_Parameters.GetValueAsReal( "MinDelta" ) );
+  P1 max_delta = P1( this->m_Parameters.GetValueAsReal( "MaxDelta" ) );
+  P1 lower = i1->GetPixel( idx ) - min_delta;
+  P1 upper = i1->GetPixel( idx ) + min_delta;
+
+  typedef SimpleFillRegionFunction< _TImage1, _TImage2, double > _TFunction;
+  typename _TFunction::Pointer f = _TFunction::New( );
+  f->SetInputImage( i1 );
+  f->SetInputSegmentation( i2 );
+  f->ThresholdBetween( lower, upper );
+
+  typedef
+    itk::FloodFilledImageFunctionConditionalConstIterator< _TImage1, _TFunction >
+    _TIterator;
+  _TIterator fIt( i1, f, idx );
+  for( fIt.GoToBegin( ); !fIt.IsAtEnd( ); ++fIt )
+    out->SetPixel( fIt.GetIndex( ), 1 );
+
+  return( "" );
 }
 
 // eof - $RCSfile$