]> Creatis software - bbtk.git/commitdiff
#3544 ThinningImageFilter3D
authoreduardo.davila@creatis.insa-lyon.fr <eduardo.davila@creatis.insa-lyon.fr>
Mon, 16 Feb 2026 17:25:13 +0000 (18:25 +0100)
committereduardo.davila@creatis.insa-lyon.fr <eduardo.davila@creatis.insa-lyon.fr>
Mon, 16 Feb 2026 17:25:13 +0000 (18:25 +0100)
17 files changed:
kernel/src/bbtkBlackBox.cxx
kernel/src/bbtkConnection.cxx
kernel/src/bbtkFactory.cxx
kernel/src/bbtkPackage.cxx
packages/itk/bbs/appli/exampleThinningImageFilter3D.bbg [new file with mode: 0644]
packages/itk/bbs/appli/exampleThinningImageFilter3D.bbs [new file with mode: 0644]
packages/itk/src/bbitkThinningImageFilter3D.cxx [new file with mode: 0644]
packages/itk/src/bbitkThinningImageFilter3D.h [new file with mode: 0644]
packages/itk/src/itkBinaryThinningImageFilter3D.h [new file with mode: 0644]
packages/itk/src/itkBinaryThinningImageFilter3D.hxx [new file with mode: 0644]
packages/std/src/bbstdCastVector.h
packages/std/src/bbstdDoubleToInt.cxx
packages/std/src/bbstdDoubleToInt.h
packages/std/src/bbstdNumericalVectorToStringVector.cxx [new file with mode: 0644]
packages/std/src/bbstdNumericalVectorToStringVector.h [new file with mode: 0644]
packages/std/src/bbstdVectorFilterDouble.h
packages/std/src/bbstdVectorToString.h

index 6d0afbb20befe58cfa4b2333da35751b44da4442..b74d65a4808f110c3bffd83076278d903d260ae5 100644 (file)
@@ -774,7 +774,7 @@ namespace bbtk
                           ( (bbBoxProcessModeIsManual()==true)&&(bbLetRecursiveExecuteManualMode==true) ) 
                         )
                        {
-
+                
 // printf("EED BlackBox::bbRecursiveExecute bbProcess start %s \n", bbGetFullName().c_str() );
                 
 //auto start = std::chrono::high_resolution_clock::now();
@@ -1041,41 +1041,33 @@ namespace bbtk
     std::string v;
     // Looks for the adaptor
     if (bbGetOutputType(output).name() != typeid(std::string).name() ) 
-      {
-       // Look for factory 
-       Package::Pointer p = bbGetDescriptor()->GetPackage();
-       if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
-         {
-           Factory::Pointer f = p->GetFactorySet().begin()->lock();
-           BlackBox::Pointer a;
-           try
-             {
-               a = f->NewAdaptor(  
-                                 bbGetOutputType(output),
-                                 typeid(std::string),
-                                 "");
-             } catch (bbtk::Exception e) 
-             {
-             }
-           if (a){
-             //                        bbUpdate();
-             a->bbSetInput("In",bbGetOutput(output));
-             a->bbExecute();
-             v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
-           } else {
-             v="? (no adaptor found)";
-           }
-         }
-       else 
-         {
-           v="? (no factory found)";
-         }
-      } 
-    else 
-      {
-       //         bbUpdate();
-       v = bbGetOutput(output).unsafe_get<std::string>() ;
-      }
+    {
+        // Look for factory 
+        Package::Pointer p = bbGetDescriptor()->GetPackage();
+        if ((p != 0) && ( ! p->GetFactorySet().empty() ) )
+        {
+            Factory::Pointer f = p->GetFactorySet().begin()->lock();
+            BlackBox::Pointer a;
+            try {
+                a = f->NewAdaptor( bbGetOutputType(output), typeid(std::string), "");
+            } catch (bbtk::Exception e) {
+            }
+            if (a)
+            {
+                //                     bbUpdate();
+                a->bbSetInput("In",bbGetOutput(output));
+                a->bbExecute();
+                v = a->bbGetOutput("Out").unsafe_get<std::string>() ;
+            } else {
+                v="? (no adaptor found)";
+            } // if a
+        } else {
+          v="? (no factory found)";
+        } // if p
+    } else {
+        //         bbUpdate();
+        v = bbGetOutput(output).unsafe_get<std::string>() ;
+    } // name
     return v;
   }
   //=========================================================================
index 9624cea27f25ffe92f4c73ab2389f6d998a8ea4b..f3d5a9f44e4e63aad913eced29db0d3feeec0107 100644 (file)
@@ -442,13 +442,11 @@ Connection::Connection(BlackBox::Pointer from, const std::string& output,
            mTo->bbSetInput( mInput, 
                             mFrom->bbGetOutput(mOutput),
                             false);
-         }
-       else 
-         {
+         } else {
            // 2) Look for an adaptor
            bbtk::BlackBox::Pointer adaptor;
            try 
-             {
+        {
                adaptor = mFactory.lock()
                  ->NewAdaptor(mFrom->bbGetOutput(mOutput).type(),
                               mTo->bbGetInputType(mInput),
index 368275afb8d5c07af52361ac09576621246b9300..3b8e915d375ea3045a7cfc782254a52542df2ac7 100644 (file)
@@ -110,20 +110,20 @@ namespace bbtk
                                                           pkgname,
                                                           path);
     if (p!=0)
-      {
-       //===================================================================
-       bbtkMessage("output",2,p->GetName()<<" "
+    {
+        //===================================================================
+        bbtkMessage("output",2,p->GetName()<<" "
                    <<p->GetVersion()
                    <<" "
                    <<p->GetAuthor() << " Category(s) :"
                    <<p->GetCategory()
                    <<std::endl);
-       bbtkMessage("output",2,p->GetDescription()<<std::endl);
-       //===================================================================
-       p->AddFactory(GetThisPointer<Factory>());
-       mPackageMap[pkgname] = p;
-       return true;
-      }
+        bbtkMessage("output",2,p->GetDescription()<<std::endl);
+        //===================================================================
+        p->AddFactory(GetThisPointer<Factory>());
+        mPackageMap[pkgname] = p;
+        return true;
+    } // if p
     return false;    
   }
   
@@ -641,27 +641,20 @@ namespace bbtk
                         <<typein<<","
                         <<typeout<<",\""
                         <<name<<"\")"<<bbtkendl);
-
-
     BlackBox::Pointer b; 
     PackageMapType::const_iterator i;
     for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
-      {
-      b = i->second->NewAdaptor(typein,typeout,name);
-      if (b) break; 
-      }
-    if (!b) 
-      {
-       bbtkError("no "<<typein<<" to "<<typeout
-                 <<" adaptor available");
-      } 
-    
+    {
+        b = i->second->NewAdaptor(typein,typeout,name);
+        if (b) break; 
+    } if (!b) {
+        bbtkError("no "<<typein<<"    to    "<<typeout<<" adaptor available in connection:  "<< name);
+    }
     bbtkDebugDecTab("kernel",7);
     return b;
   }
   //===================================================================
 
-
   //===================================================================
   /// Creates an instance of a black box of type <type> with name <name>
   BlackBox::Pointer Factory::NewWidgetAdaptor(const DataInfo& typein,
index bcb83089a34c8c5ff3898cc58779cfa822dc22d3..4b97e165d0b3fc749b658fc814ac0bfd231a7736 100644 (file)
@@ -728,14 +728,13 @@ printf("EED Package::OpenDynamicLibrary  %s   %s \n", libname.c_str(), package_n
                        <<typeout<<",\""
                        <<name<<"\")"<<bbtkendl);
 
-    AdaptorKey key(typein,typeout,
-                  BlackBoxDescriptor::DEFAULT_ADAPTOR);
+    AdaptorKey key(typein,typeout,BlackBoxDescriptor::DEFAULT_ADAPTOR);
     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
     if (i == mAdaptorMap.end())  
-      {
-       bbtkDebugDecTab("kernel",8);
-       return BlackBox::Pointer();
-      }
+    {
+        bbtkDebugDecTab("kernel",8);
+        return BlackBox::Pointer();
+    }
     BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
     bbtkDebugDecTab("kernel",8);
     return bb;
@@ -844,11 +843,11 @@ printf("EED Package::OpenDynamicLibrary  %s   %s \n", libname.c_str(), package_n
     
     DescriptorMapType::iterator i = mDescriptorMap.find(d->GetTypeName());
     if (i!=mDescriptorMap.end())
-      {
-       bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
+    {
+        bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
                    <<d->GetTypeName()<<"> which is already in the package");
-       return false;
-      }
+        return false;
+    }
 
     mDescriptorMap[d->GetTypeName()] = d;
     //    d->Reference();
@@ -856,34 +855,31 @@ printf("EED Package::OpenDynamicLibrary  %s   %s \n", libname.c_str(), package_n
     
     // If it is a default adaptor, also register it in the adaptors map
     if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
-      {
-       bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);   
+    {
+        bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);   
        
-       TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
-       TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
-       DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
-       DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
-       AdaptorKey key(infoin,infoout,d->GetKind());
+        TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
+        TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
+        DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
+        DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
+        AdaptorKey key(infoin,infoout,d->GetKind());
        
-       AdaptorMapType::const_iterator i;
-       i = mAdaptorMap.find(key);        
-       if (i == mAdaptorMap.end())  
-         {
-           mAdaptorMap[key] = d;
-         }
-       // If already an adaptor registered : error
-       else 
-         {
-           if (i->second.lock()->GetTypeName() != d->GetTypeName()) 
-             {
-               bbtkError("Package <"<<GetName()<<
-                         "> : trying to register black box <"
-                         <<d->GetTypeName()
-                         <<"> as default adaptor but there is already a default adaptor registered (<"
-                         <<i->second.lock()->GetTypeName()<<">)");
-             }
-         }
-      }
+        AdaptorMapType::const_iterator i;
+        i = mAdaptorMap.find(key);       
+        if (i == mAdaptorMap.end())  
+        {
+            mAdaptorMap[key] = d;
+        } else { // If already an adaptor registered : error
+            if (i->second.lock()->GetTypeName() != d->GetTypeName())
+            {
+                bbtkError("Package <"<<GetName()<<
+                          "> : trying to register black box <"
+                          <<d->GetTypeName()
+                          <<"> as default adaptor but there is already a default adaptor registered (<"
+                          <<i->second.lock()->GetTypeName()<<">)");
+            } // if name
+        }// if i
+    } // if kind
     // If it is a default adaptor, also register it in the adaptors map
     else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
       {
diff --git a/packages/itk/bbs/appli/exampleThinningImageFilter3D.bbg b/packages/itk/bbs/appli/exampleThinningImageFilter3D.bbg
new file mode 100644 (file)
index 0000000..751a986
--- /dev/null
@@ -0,0 +1,56 @@
+# ----------------------------------
+# - BBTKGEditor v 1.6 BBG BlackBox Diagram file
+# - /Users/davila/Creatis/C23/creatools_source/bbtk/packages/itk/bbs/appli/exampleThinningImageFilter3D.bbg
+# ----------------------------------
+
+APP_START
+CATEGORY:<VOID>
+DESCRIPTION:Description ??
+AUTHOR:Author ??
+EXPORTFORMAT:0
+COMPLEXBOX:FALSE
+COMPLEXINPUTS:0
+BOXES:5
+BOX
+vtk:LoadHola:Box00
+ISEXEC:FALSE
+-10.742698:32.159670:-900.000000
+10.807302:29.659670:-900.000000
+FIN_BOX
+BOX
+creaMaracasVisu:ImageChangeInformation:Box01
+ISEXEC:FALSE
+-11.837496:23.127593:-900.000000
+11.312504:20.627593:-900.000000
+FIN_BOX
+BOX
+itk:TubularStructures_Sato:Box02
+ISEXEC:FALSE
+-21.074848:6.431934:-900.000000
+1.720152:3.931934:-900.000000
+FIN_BOX
+BOX
+vtk:RescaleSlopeIntercept:Box03
+ISEXEC:FALSE
+-17.379907:13.958665:-900.000000
+5.445093:11.458665:-900.000000
+PORT
+OutputFormat:"VTK_DOUBLE"
+FIN_BOX
+BOX
+creaMaracasVisu:ViewerNV:Box04
+ISEXEC:TRUE
+-21.348547:-6.979333:-900.000000
+20.771453:-9.479333:-900.000000
+FIN_BOX
+CONNECTIONS:3
+CONNECTION
+Box00:Out:Box01:In
+NumberOfControlPoints:0
+CONNECTION
+Box01:Out:Box03:In
+NumberOfControlPoints:0
+CONNECTION
+Box03:Out:Box02:In
+NumberOfControlPoints:0
+APP_END
diff --git a/packages/itk/bbs/appli/exampleThinningImageFilter3D.bbs b/packages/itk/bbs/appli/exampleThinningImageFilter3D.bbs
new file mode 100644 (file)
index 0000000..72ee917
--- /dev/null
@@ -0,0 +1,40 @@
+# ----------------------------------
+# - BBTKGEditor v 1.6 BBS BlackBox Script
+# - /Users/davila/Creatis/C23/creatools_source/bbtk/packages/itk/bbs/appli/exampleThinningImageFilter3D.bbs
+# ----------------------------------
+
+# BBTK GEditor Script
+# ----------------------
+
+include std
+include itkvtk
+include vtk
+include creaMaracasVisu
+include itk
+
+author "Author ??"
+description "Description ??"
+category "<VOID>"
+
+new vtk:LoadHola Box00
+
+new creaMaracasVisu:ImageChangeInformation Box01
+
+new itk:TubularStructures_Sato Box02
+
+new vtk:RescaleSlopeIntercept Box03
+  set Box03.OutputFormat "VTK_DOUBLE"
+
+new creaMaracasVisu:ViewerNV Box04
+
+
+connect Box00.Out Box01.In
+
+connect Box01.Out Box03.In
+
+connect Box03.Out Box02.In
+
+
+
+# Complex input ports
+exec Box04
diff --git a/packages/itk/src/bbitkThinningImageFilter3D.cxx b/packages/itk/src/bbitkThinningImageFilter3D.cxx
new file mode 100644 (file)
index 0000000..5eaf4a7
--- /dev/null
@@ -0,0 +1,12 @@
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+#include "bbitkThinningImageFilter3D.h"
+#include "bbitkPackage.h"
+namespace bbitk
+{
+  BBTK_ADD_BLACK_BOX_TO_PACKAGE(itk,ThinningImageFilter3D)
+  BBTK_BLACK_BOX_IMPLEMENTATION(ThinningImageFilter3D,bbtk::AtomicBlackBox);
+}// EO namespace bbitk
+
+
diff --git a/packages/itk/src/bbitkThinningImageFilter3D.h b/packages/itk/src/bbitkThinningImageFilter3D.h
new file mode 100644 (file)
index 0000000..0cebb5b
--- /dev/null
@@ -0,0 +1,169 @@
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+#ifndef __bbitkThinningImageFilter3D_h_INCLUDED__
+#define __bbitkThinningImageFilter3D_h_INCLUDED__
+
+#include "bbitk_EXPORT.h"
+#include "bbtkAtomicBlackBox.h"
+#include "iostream"
+
+#include "itkBinaryThinningImageFilter3D.hxx"
+
+#include "bbitkImage.h"
+
+namespace bbitk
+{
+
+class bbitk_EXPORT ThinningImageFilter3D
+:
+public bbtk::AtomicBlackBox
+{
+    BBTK_BLACK_BOX_INTERFACE(ThinningImageFilter3D,bbtk::AtomicBlackBox);
+    //=====
+    // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+    //=====
+    BBTK_DECLARE_INPUT(In,anyImagePointer);
+    BBTK_DECLARE_OUTPUT(Out,anyImagePointer);
+
+    BBTK_PROCESS(ProcessSwitch);
+    private :
+        inline              void ProcessSwitch();
+        template <class T>  void Process();
+        itk::Object         *mOutput;
+    
+    //=====
+    // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+    //=====
+};
+
+BBTK_BEGIN_DESCRIBE_BLACK_BOX(ThinningImageFilter3D,bbtk::AtomicBlackBox);
+  BBTK_NAME("ThinningImageFilter3D");
+  BBTK_AUTHOR("InfoDev");
+  BBTK_DESCRIPTION("No Description.");
+  BBTK_CATEGORY("empty");
+  BBTK_INPUT(ThinningImageFilter3D,In,"Image (SHORT format)",anyImagePointer,"");
+  BBTK_OUTPUT(ThinningImageFilter3D,Out,"Output image ",anyImagePointer,"");
+BBTK_END_DESCRIBE_BLACK_BOX(ThinningImageFilter3D);
+//=====
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//=====
+
+//===================================================
+void ThinningImageFilter3D::ProcessSwitch()
+{
+    bbtk::TypeInfo t = bbGetInputIn().type();
+//    BBTK_TEMPLATE_ITK_IMAGE_SWITCH(t, this->Process);
+//     BBTK_TEMPLATE_ITK_IMAGE_DIM_3_SWITCH(t, this->Process , "Error format. (you need 3D short,float,double)") ;
+
+     BBTK_BEGIN_TEMPLATE_SWITCH(t)
+//         BBTK_SWITCH_ITK_IMAGE_short_3(t,this->Process,)
+         BBTK_SWITCH_ITK_IMAGE_int16_t_3(t,this->Process,)
+//       BBTK_SWITCH_ITK_IMAGE_float_3(t,this->Process,)
+//       BBTK_SWITCH_ITK_IMAGE_double_3(t,this->Process,)
+     BBTK_END_TEMPLATE_SWITCH(t)
+}
+
+//=====
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//=====
+template <class T>
+void ThinningImageFilter3D::Process()
+{
+    //
+    //   https://github.com/thewtex/ITKBinaryThinningImageFilter3D
+    //
+    printf("EED ThinningImageFilter3D::Process Start\n");
+
+    // Verify the number of parameters in the command line
+//    if (argc <= 2)
+//    {
+//      std::cerr << "Usage: " << std::endl;
+//      std::cerr << argv[0] << " inputImageFile outputImageFile" << std::endl;
+//      return EXIT_FAILURE;
+//    }
+//    char *infilename = argv[1];
+//    char *outfilename = argv[2];
+//
+    const unsigned int Dimension = 3;
+    typedef signed short PixelType; // must be signed for CT since Hounsfield units can be < 0
+    typedef itk::Image<PixelType, Dimension> ImageType;
+
+//    // Read image
+//    typedef itk::ImageFileReader<ImageType> ReaderType;
+//    ReaderType::Pointer reader = ReaderType::New();
+//    reader->SetFileName(infilename);
+//    try
+//    {
+//      reader->Update();
+//    }
+//    catch (itk::ExceptionObject &ex)
+//    {
+//      std::cout << ex << std::endl;
+//      return EXIT_FAILURE;
+//    }
+//    cout << infilename << " sucessfully read." << endl;
+
+    // Define the thinning filter
+    typedef itk::BinaryThinningImageFilter3D<ImageType, ImageType> ThinningFilterType;
+    ThinningFilterType::Pointer thinningFilter = ThinningFilterType::New();
+    
+    T* inputImage = this->bbGetInputIn().get<T*>();
+//    thinningFilter->SetInput( reader->GetOutput() );
+    thinningFilter->SetInput( inputImage );
+
+    thinningFilter->Update();
+    thinningFilter->GetOutput()->Register();
+
+    
+//    // output to file
+//    typedef itk::ImageFileWriter<ImageType> WriterType;
+//    WriterType::Pointer writer = WriterType::New();
+//    writer->SetInput(thinningFilter->GetOutput());
+//    writer->SetFileName(outfilename);
+//
+//    try
+//    {
+//      writer->Update();
+//    }
+//    catch (itk::ExceptionObject &ex)
+//    {
+//      std::cout << ex << std::endl;
+//      return EXIT_FAILURE;
+//    }
+//    cout << outfilename << " sucessfully written." << endl;
+
+//    cout << "Program terminated normally." << endl;
+//    return EXIT_SUCCESS;
+
+    if (mOutput) mOutput->UnRegister();
+    this->bbSetOutputOut( thinningFilter->GetOutput() );
+    mOutput = thinningFilter->GetOutput();
+    printf("EED ThinningImageFilter3D::Process End\n");
+}
+
+//=====
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//=====
+void ThinningImageFilter3D::bbUserSetDefaultValues()
+{   
+    mOutput = 0;
+}
+
+//=====
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//=====
+void ThinningImageFilter3D::bbUserInitializeProcessing()
+{
+}
+
+//=====
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//=====
+void ThinningImageFilter3D::bbUserFinalizeProcessing()
+{
+}
+
+}// EO namespace bbitk
+#endif // __bbitkThinningImageFilter3D_h_INCLUDED__
+
diff --git a/packages/itk/src/itkBinaryThinningImageFilter3D.h b/packages/itk/src/itkBinaryThinningImageFilter3D.h
new file mode 100644 (file)
index 0000000..8441ce1
--- /dev/null
@@ -0,0 +1,172 @@
+/*=========================================================================
+ *
+ *  Copyright Insight Software Consortium
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0.txt
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *=========================================================================*/
+#ifndef itkBinaryThinningImageFilter3D_h
+#define itkBinaryThinningImageFilter3D_h
+
+#include <itkNeighborhoodIterator.h>
+#include <itkImageToImageFilter.h>
+#include <itkImageRegionIteratorWithIndex.h>
+#include <itkConstantBoundaryCondition.h>
+
+namespace itk
+{
+/** \class BinaryThinningImageFilter3D
+*
+* \brief This filter computes one-pixel-wide skeleton of a 3D input image.
+*
+* This class is parametrized over the type of the input image
+* and the type of the output image.
+* 
+* The input is assumed to be a binary image. All non-zero valued voxels
+* are set to 1 internally to simplify the computation. The filter will
+* produce a skeleton of the object.  The output background values are 0,
+* and the foreground values are 1.
+* 
+* A 26-neighbourhood configuration is used for the foreground and a
+* 6-neighbourhood configuration for the background. Thinning is performed
+* symmetrically in order to guarantee that the skeleton lies medial within
+* the object.
+*
+* This filter is a parallel thinning algorithm and is an implementation
+* of the algorithm described in:
+* 
+* T.C. Lee, R.L. Kashyap, and C.N. Chu.
+* Building skeleton models via 3-D medial surface/axis thinning algorithms.
+* Computer Vision, Graphics, and Image Processing, 56(6):462--478, 1994.
+* 
+* To do: Make use of multi-threading.
+*
+* \author Hanno Homann, Oxford University, Wolfson Medical Vision Lab, UK.
+* 
+* \sa MorphologyImageFilter
+* \ingroup ImageEnhancement MathematicalMorphologyImageFilters BinaryThinningImageFilter3D
+*/
+
+template <class TInputImage, class TOutputImage>
+class BinaryThinningImageFilter3D : public ImageToImageFilter<TInputImage, TOutputImage>
+{
+public:
+  /** Standard class typedefs. */
+  typedef BinaryThinningImageFilter3D                   Self;
+  typedef ImageToImageFilter<TInputImage, TOutputImage> Superclass;
+  typedef SmartPointer<Self>                            Pointer;
+  typedef SmartPointer<const Self>                      ConstPointer;
+
+  /** Method for creation through the object factory */
+  itkNewMacro(Self);
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(BinaryThinningImageFilter3D, ImageToImageFilter);
+
+  /** Type for input image. */
+  typedef TInputImage InputImageType;
+
+  /** Type for output image: Skelenton of the object.  */
+  typedef TOutputImage OutputImageType;
+
+  /** Type for the region of the input image. */
+  typedef typename InputImageType::RegionType RegionType;
+
+  /** Type for the index of the input image. */
+  typedef typename RegionType::IndexType IndexType;
+
+  /** Type for the pixel type of the input image. */
+  typedef typename InputImageType::PixelType InputImagePixelType;
+
+  /** Type for the pixel type of the input image. */
+  typedef typename OutputImageType::PixelType OutputImagePixelType;
+
+  /** Type for the size of the input image. */
+  typedef typename RegionType::SizeType SizeType;
+
+  /** Pointer Type for input image. */
+  typedef typename InputImageType::ConstPointer InputImagePointer;
+
+  /** Pointer Type for the output image. */
+  typedef typename OutputImageType::Pointer OutputImagePointer;
+
+  /** Boundary condition type for the neighborhood iterator */
+  typedef ConstantBoundaryCondition<TInputImage> ConstBoundaryConditionType;
+
+  /** Neighborhood iterator type */
+  typedef NeighborhoodIterator<TInputImage, ConstBoundaryConditionType> NeighborhoodIteratorType;
+
+  /** Neighborhood type */
+  typedef typename NeighborhoodIteratorType::NeighborhoodType NeighborhoodType;
+
+  /** Get Skelenton by thinning image. */
+  OutputImageType *GetThinning(void);
+
+  /** ImageDimension enumeration   */
+  itkStaticConstMacro(InputImageDimension, unsigned int,
+                      TInputImage::ImageDimension);
+  itkStaticConstMacro(OutputImageDimension, unsigned int,
+                      TOutputImage::ImageDimension);
+
+#ifdef ITK_USE_CONCEPT_CHECKING
+  /** Begin concept checking */
+  itkConceptMacro(SameDimensionCheck,
+                  (Concept::SameDimension<InputImageDimension, 3>));
+  itkConceptMacro(SameTypeCheck,
+                  (Concept::SameType<InputImagePixelType, OutputImagePixelType>));
+  itkConceptMacro(InputAdditiveOperatorsCheck,
+                  (Concept::AdditiveOperators<InputImagePixelType>));
+  itkConceptMacro(InputConvertibleToIntCheck,
+                  (Concept::Convertible<InputImagePixelType, int>));
+  itkConceptMacro(IntConvertibleToInputCheck,
+                  (Concept::Convertible<int, InputImagePixelType>));
+  itkConceptMacro(InputIntComparableCheck,
+                  (Concept::Comparable<InputImagePixelType, int>));
+  /** End concept checking */
+#endif
+
+protected:
+  BinaryThinningImageFilter3D();
+  virtual ~BinaryThinningImageFilter3D(){};
+  void PrintSelf(std::ostream &os, Indent indent) const;
+
+  /** Compute thinning Image. */
+  void GenerateData();
+
+  /** Prepare data. */
+  void PrepareData();
+
+  /**  Compute thinning Image. */
+  void ComputeThinImage();
+
+  /**  isEulerInvariant [Lee94] */
+  bool isEulerInvariant(NeighborhoodType neighbors, int *LUT);
+  void fillEulerLUT(int *LUT);
+  /**  isSimplePoint [Lee94] */
+  bool isSimplePoint(NeighborhoodType neighbors);
+  /**  Octree_labeling [Lee94] */
+  void Octree_labeling(int octant, int label, int *cube);
+
+private:
+  BinaryThinningImageFilter3D(const Self &); //purposely not implemented
+  void operator=(const Self &);              //purposely not implemented
+
+}; // end of BinaryThinningImageFilter3D class
+
+} //end namespace itk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "itkBinaryThinningImageFilter3D.hxx"
+#endif
+
+#endif // itkBinaryThinningImageFilter3D_h
diff --git a/packages/itk/src/itkBinaryThinningImageFilter3D.hxx b/packages/itk/src/itkBinaryThinningImageFilter3D.hxx
new file mode 100644 (file)
index 0000000..bd7e9e4
--- /dev/null
@@ -0,0 +1,965 @@
+/*=========================================================================
+ *
+ *  Copyright Insight Software Consortium
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0.txt
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *=========================================================================*/
+#ifndef itkBinaryThinningImageFilter3D_hxx
+#define itkBinaryThinningImageFilter3D_hxx
+
+#include <iostream>
+
+#include "itkBinaryThinningImageFilter3D.h"
+#include "itkImageRegionConstIterator.h"
+#include "itkImageRegionIterator.h"
+#include "itkNeighborhoodIterator.h"
+#include <vector>
+
+namespace itk
+{
+/**
+ *    Constructor
+ */
+template <class TInputImage, class TOutputImage>
+BinaryThinningImageFilter3D<TInputImage, TOutputImage>::BinaryThinningImageFilter3D()
+{
+
+    this->SetNumberOfRequiredOutputs(1);
+
+    OutputImagePointer thinImage = OutputImageType::New();
+    this->SetNthOutput(0, thinImage.GetPointer());
+}
+
+/**
+ *  Return the thinning Image pointer
+ */
+template <class TInputImage, class TOutputImage>
+typename BinaryThinningImageFilter3D<
+    TInputImage, TOutputImage>::OutputImageType *
+BinaryThinningImageFilter3D<TInputImage, TOutputImage>::GetThinning(void)
+{
+    return dynamic_cast<OutputImageType *>(
+        this->ProcessObject::GetOutput(0));
+}
+
+/**
+ *  Prepare data for computation
+ *  Copy the input image to the output image, changing from the input
+ *  type to the output type.
+ */
+template <class TInputImage, class TOutputImage>
+void BinaryThinningImageFilter3D<TInputImage, TOutputImage>::PrepareData(void)
+{
+
+    itkDebugMacro(<< "PrepareData Start");
+    OutputImagePointer thinImage = GetThinning();
+
+    InputImagePointer inputImage =
+        dynamic_cast<const TInputImage *>(ProcessObject::GetInput(0));
+
+    thinImage->SetBufferedRegion(thinImage->GetRequestedRegion());
+    thinImage->Allocate();
+
+    typename OutputImageType::RegionType region = thinImage->GetRequestedRegion();
+
+    ImageRegionConstIterator<TInputImage> it(inputImage, region);
+    ImageRegionIterator<TOutputImage> ot(thinImage, region);
+
+    it.GoToBegin();
+    ot.GoToBegin();
+
+    itkDebugMacro(<< "PrepareData: Copy input to output");
+
+    // Copy the input to the output, changing all foreground pixels to
+    // have value 1 in the process.
+    while (!ot.IsAtEnd())
+    {
+        if (it.Get())
+        {
+            ot.Set(NumericTraits<OutputImagePixelType>::One);
+        }
+        else
+        {
+            ot.Set(NumericTraits<OutputImagePixelType>::Zero);
+        }
+        ++it;
+        ++ot;
+    }
+    itkDebugMacro(<< "PrepareData End");
+}
+
+/**
+ *  Post processing for computing thinning
+ */
+template <class TInputImage, class TOutputImage>
+void BinaryThinningImageFilter3D<TInputImage, TOutputImage>::ComputeThinImage()
+{
+    itkDebugMacro(<< "ComputeThinImage Start");
+    OutputImagePointer thinImage = GetThinning();
+
+    typename OutputImageType::RegionType region = thinImage->GetRequestedRegion();
+
+    ConstBoundaryConditionType boundaryCondition;
+    boundaryCondition.SetConstant(0);
+
+    typename NeighborhoodIteratorType::RadiusType radius;
+    radius.Fill(1);
+    NeighborhoodIteratorType ot(radius, thinImage, region);
+    ot.SetBoundaryCondition(boundaryCondition);
+
+    std::vector<IndexType> simpleBorderPoints;
+    typename std::vector<IndexType>::iterator simpleBorderPointsIt;
+
+    // Define offsets
+    typedef typename NeighborhoodIteratorType::OffsetType OffsetType;
+    OffsetType N = {{0, -1, 0}}; // north
+    OffsetType S = {{0, 1, 0}};  // south
+    OffsetType E = {{1, 0, 0}};  // east
+    OffsetType W = {{-1, 0, 0}}; // west
+    OffsetType U = {{0, 0, 1}};  // up
+    OffsetType B = {{0, 0, -1}}; // bottom
+
+    // prepare Euler LUT [Lee94]
+    int eulerLUT[256];
+    fillEulerLUT(eulerLUT);
+    // Loop through the image several times until there is no change.
+    int unchangedBorders = 0;
+    while (unchangedBorders < 6) // loop until no change for all the six border types
+    {
+        unchangedBorders = 0;
+        for (int currentBorder = 1; currentBorder <= 6; currentBorder++)
+        {
+            // Loop through the image.
+            for (ot.GoToBegin(); !ot.IsAtEnd(); ++ot)
+            {
+                // check if point is foreground
+                if (ot.GetCenterPixel() != 1)
+                {
+                    continue; // current point is already background
+                }
+                // check 6-neighbors if point is a border point of type currentBorder
+                bool isBorderPoint = false;
+                if (currentBorder == 1 && ot.GetPixel(N) <= 0)
+                    isBorderPoint = true;
+                if (currentBorder == 2 && ot.GetPixel(S) <= 0)
+                    isBorderPoint = true;
+                if (currentBorder == 3 && ot.GetPixel(E) <= 0)
+                    isBorderPoint = true;
+                if (currentBorder == 4 && ot.GetPixel(W) <= 0)
+                    isBorderPoint = true;
+                if (currentBorder == 5 && ot.GetPixel(U) <= 0)
+                    isBorderPoint = true;
+                if (currentBorder == 6 && ot.GetPixel(B) <= 0)
+                    isBorderPoint = true;
+                if (!isBorderPoint)
+                {
+                    continue; // current point is not deletable
+                }
+                // check if point is the end of an arc
+                int numberOfNeighbors = -1;  // -1 and not 0 because the center pixel will be counted as well
+                for (int i = 0; i < 27; i++) // i =  0..26
+                    if (ot.GetPixel(i) == 1)
+                        numberOfNeighbors++;
+
+                if (numberOfNeighbors == 1)
+                {
+                    continue; // current point is not deletable
+                }
+
+                // check if point is Euler invariant
+                if (!isEulerInvariant(ot.GetNeighborhood(), eulerLUT))
+                {
+                    continue; // current point is not deletable
+                }
+
+                // check if point is simple (deletion does not change connectivity in the 3x3x3 neighborhood)
+                if (!isSimplePoint(ot.GetNeighborhood()))
+                {
+                    continue; // current point is not deletable
+                }
+
+                // add all simple border points to a list for sequential re-checking
+                simpleBorderPoints.push_back(ot.GetIndex());
+            } // end image iteration loop
+
+            // sequential re-checking to preserve connectivity when
+            // deleting in a parallel way
+            bool noChange = true;
+            for (simpleBorderPointsIt = simpleBorderPoints.begin(); simpleBorderPointsIt != simpleBorderPoints.end(); simpleBorderPointsIt++)
+            {
+                // 1. Set simple border point to 0
+                thinImage->SetPixel(*simpleBorderPointsIt, NumericTraits<OutputImagePixelType>::Zero);
+                // 2. Check if neighborhood is still connected
+                ot.SetLocation(*simpleBorderPointsIt);
+                if (!isSimplePoint(ot.GetNeighborhood()))
+                {
+                    // we cannot delete current point, so reset
+                    thinImage->SetPixel(*simpleBorderPointsIt, NumericTraits<OutputImagePixelType>::One);
+                }
+                else
+                {
+                    noChange = false;
+                }
+            }
+            if (noChange)
+                unchangedBorders++;
+
+            simpleBorderPoints.clear();
+        } // end currentBorder for loop
+    }     // end unchangedBorders while loop
+
+    itkDebugMacro(<< "ComputeThinImage End");
+}
+
+/**
+ *  Generate ThinImage
+ */
+template <class TInputImage, class TOutputImage>
+void BinaryThinningImageFilter3D<TInputImage, TOutputImage>::GenerateData()
+{
+
+    this->PrepareData();
+
+    itkDebugMacro(<< "GenerateData: Computing Thinning Image");
+    this->ComputeThinImage();
+} // end GenerateData()
+
+/** 
+ * Fill the Euler look-up table (LUT) for later check of the Euler invariance. (see [Lee94])
+ */
+template <class TInputImage, class TOutputImage>
+void BinaryThinningImageFilter3D<TInputImage, TOutputImage>::fillEulerLUT(int *LUT)
+{
+    LUT[1] = 1;
+    LUT[3] = -1;
+    LUT[5] = -1;
+    LUT[7] = 1;
+    LUT[9] = -3;
+    LUT[11] = -1;
+    LUT[13] = -1;
+    LUT[15] = 1;
+    LUT[17] = -1;
+    LUT[19] = 1;
+    LUT[21] = 1;
+    LUT[23] = -1;
+    LUT[25] = 3;
+    LUT[27] = 1;
+    LUT[29] = 1;
+    LUT[31] = -1;
+    LUT[33] = -3;
+    LUT[35] = -1;
+    LUT[37] = 3;
+    LUT[39] = 1;
+    LUT[41] = 1;
+    LUT[43] = -1;
+    LUT[45] = 3;
+    LUT[47] = 1;
+    LUT[49] = -1;
+    LUT[51] = 1;
+
+    LUT[53] = 1;
+    LUT[55] = -1;
+    LUT[57] = 3;
+    LUT[59] = 1;
+    LUT[61] = 1;
+    LUT[63] = -1;
+    LUT[65] = -3;
+    LUT[67] = 3;
+    LUT[69] = -1;
+    LUT[71] = 1;
+    LUT[73] = 1;
+    LUT[75] = 3;
+    LUT[77] = -1;
+    LUT[79] = 1;
+    LUT[81] = -1;
+    LUT[83] = 1;
+    LUT[85] = 1;
+    LUT[87] = -1;
+    LUT[89] = 3;
+    LUT[91] = 1;
+    LUT[93] = 1;
+    LUT[95] = -1;
+    LUT[97] = 1;
+    LUT[99] = 3;
+    LUT[101] = 3;
+    LUT[103] = 1;
+
+    LUT[105] = 5;
+    LUT[107] = 3;
+    LUT[109] = 3;
+    LUT[111] = 1;
+    LUT[113] = -1;
+    LUT[115] = 1;
+    LUT[117] = 1;
+    LUT[119] = -1;
+    LUT[121] = 3;
+    LUT[123] = 1;
+    LUT[125] = 1;
+    LUT[127] = -1;
+    LUT[129] = -7;
+    LUT[131] = -1;
+    LUT[133] = -1;
+    LUT[135] = 1;
+    LUT[137] = -3;
+    LUT[139] = -1;
+    LUT[141] = -1;
+    LUT[143] = 1;
+    LUT[145] = -1;
+    LUT[147] = 1;
+    LUT[149] = 1;
+    LUT[151] = -1;
+    LUT[153] = 3;
+    LUT[155] = 1;
+
+    LUT[157] = 1;
+    LUT[159] = -1;
+    LUT[161] = -3;
+    LUT[163] = -1;
+    LUT[165] = 3;
+    LUT[167] = 1;
+    LUT[169] = 1;
+    LUT[171] = -1;
+    LUT[173] = 3;
+    LUT[175] = 1;
+    LUT[177] = -1;
+    LUT[179] = 1;
+    LUT[181] = 1;
+    LUT[183] = -1;
+    LUT[185] = 3;
+    LUT[187] = 1;
+    LUT[189] = 1;
+    LUT[191] = -1;
+    LUT[193] = -3;
+    LUT[195] = 3;
+    LUT[197] = -1;
+    LUT[199] = 1;
+    LUT[201] = 1;
+    LUT[203] = 3;
+    LUT[205] = -1;
+    LUT[207] = 1;
+
+    LUT[209] = -1;
+    LUT[211] = 1;
+    LUT[213] = 1;
+    LUT[215] = -1;
+    LUT[217] = 3;
+    LUT[219] = 1;
+    LUT[221] = 1;
+    LUT[223] = -1;
+    LUT[225] = 1;
+    LUT[227] = 3;
+    LUT[229] = 3;
+    LUT[231] = 1;
+    LUT[233] = 5;
+    LUT[235] = 3;
+    LUT[237] = 3;
+    LUT[239] = 1;
+    LUT[241] = -1;
+    LUT[243] = 1;
+    LUT[245] = 1;
+    LUT[247] = -1;
+    LUT[249] = 3;
+    LUT[251] = 1;
+    LUT[253] = 1;
+    LUT[255] = -1;
+}
+
+/** 
+ * Check for Euler invariance. (see [Lee94])
+ */
+template <class TInputImage, class TOutputImage>
+bool BinaryThinningImageFilter3D<TInputImage, TOutputImage>::isEulerInvariant(NeighborhoodType neighbors, int *LUT)
+{
+    // calculate Euler characteristic for each octant and sum up
+    int EulerChar = 0;
+    unsigned char n;
+    // Octant SWU
+    n = 1;
+    if (neighbors[24] == 1)
+        n |= 128;
+    if (neighbors[25] == 1)
+        n |= 64;
+    if (neighbors[15] == 1)
+        n |= 32;
+    if (neighbors[16] == 1)
+        n |= 16;
+    if (neighbors[21] == 1)
+        n |= 8;
+    if (neighbors[22] == 1)
+        n |= 4;
+    if (neighbors[12] == 1)
+        n |= 2;
+    EulerChar += LUT[n];
+    // Octant SEU
+    n = 1;
+    if (neighbors[26] == 1)
+        n |= 128;
+    if (neighbors[23] == 1)
+        n |= 64;
+    if (neighbors[17] == 1)
+        n |= 32;
+    if (neighbors[14] == 1)
+        n |= 16;
+    if (neighbors[25] == 1)
+        n |= 8;
+    if (neighbors[22] == 1)
+        n |= 4;
+    if (neighbors[16] == 1)
+        n |= 2;
+    EulerChar += LUT[n];
+    // Octant NWU
+    n = 1;
+    if (neighbors[18] == 1)
+        n |= 128;
+    if (neighbors[21] == 1)
+        n |= 64;
+    if (neighbors[9] == 1)
+        n |= 32;
+    if (neighbors[12] == 1)
+        n |= 16;
+    if (neighbors[19] == 1)
+        n |= 8;
+    if (neighbors[22] == 1)
+        n |= 4;
+    if (neighbors[10] == 1)
+        n |= 2;
+    EulerChar += LUT[n];
+    // Octant NEU
+    n = 1;
+    if (neighbors[20] == 1)
+        n |= 128;
+    if (neighbors[23] == 1)
+        n |= 64;
+    if (neighbors[19] == 1)
+        n |= 32;
+    if (neighbors[22] == 1)
+        n |= 16;
+    if (neighbors[11] == 1)
+        n |= 8;
+    if (neighbors[14] == 1)
+        n |= 4;
+    if (neighbors[10] == 1)
+        n |= 2;
+    EulerChar += LUT[n];
+    // Octant SWB
+    n = 1;
+    if (neighbors[6] == 1)
+        n |= 128;
+    if (neighbors[15] == 1)
+        n |= 64;
+    if (neighbors[7] == 1)
+        n |= 32;
+    if (neighbors[16] == 1)
+        n |= 16;
+    if (neighbors[3] == 1)
+        n |= 8;
+    if (neighbors[12] == 1)
+        n |= 4;
+    if (neighbors[4] == 1)
+        n |= 2;
+    EulerChar += LUT[n];
+    // Octant SEB
+    n = 1;
+    if (neighbors[8] == 1)
+        n |= 128;
+    if (neighbors[7] == 1)
+        n |= 64;
+    if (neighbors[17] == 1)
+        n |= 32;
+    if (neighbors[16] == 1)
+        n |= 16;
+    if (neighbors[5] == 1)
+        n |= 8;
+    if (neighbors[4] == 1)
+        n |= 4;
+    if (neighbors[14] == 1)
+        n |= 2;
+    EulerChar += LUT[n];
+    // Octant NWB
+    n = 1;
+    if (neighbors[0] == 1)
+        n |= 128;
+    if (neighbors[9] == 1)
+        n |= 64;
+    if (neighbors[3] == 1)
+        n |= 32;
+    if (neighbors[12] == 1)
+        n |= 16;
+    if (neighbors[1] == 1)
+        n |= 8;
+    if (neighbors[10] == 1)
+        n |= 4;
+    if (neighbors[4] == 1)
+        n |= 2;
+    EulerChar += LUT[n];
+    // Octant NEB
+    n = 1;
+    if (neighbors[2] == 1)
+        n |= 128;
+    if (neighbors[1] == 1)
+        n |= 64;
+    if (neighbors[11] == 1)
+        n |= 32;
+    if (neighbors[10] == 1)
+        n |= 16;
+    if (neighbors[5] == 1)
+        n |= 8;
+    if (neighbors[4] == 1)
+        n |= 4;
+    if (neighbors[14] == 1)
+        n |= 2;
+    EulerChar += LUT[n];
+    if (EulerChar == 0)
+        return true;
+    else
+        return false;
+}
+
+/** 
+ * Check if current point is a Simple Point.
+ * This method is named 'N(v)_labeling' in [Lee94].
+ * Outputs the number of connected objects in a neighborhood of a point
+ * after this point would have been removed.
+ */
+template <class TInputImage, class TOutputImage>
+bool BinaryThinningImageFilter3D<TInputImage, TOutputImage>::isSimplePoint(NeighborhoodType neighbors)
+{
+    // copy neighbors for labeling
+    int cube[26];
+    int i;
+    for (i = 0; i < 13; i++) // i =  0..12 -> cube[0..12]
+        cube[i] = neighbors[i];
+    // i != 13 : ignore center pixel when counting (see [Lee94])
+    for (i = 14; i < 27; i++) // i = 14..26 -> cube[13..25]
+        cube[i - 1] = neighbors[i];
+    // set initial label
+    int label = 2;
+    // for all points in the neighborhood
+    for (int i = 0; i < 26; i++)
+    {
+        if (cube[i] == 1) // voxel has not been labelled yet
+        {
+            // start recursion with any octant that contains the point i
+            switch (i)
+            {
+            case 0:
+            case 1:
+            case 3:
+            case 4:
+            case 9:
+            case 10:
+            case 12:
+                Octree_labeling(1, label, cube);
+                break;
+            case 2:
+            case 5:
+            case 11:
+            case 13:
+                Octree_labeling(2, label, cube);
+                break;
+            case 6:
+            case 7:
+            case 14:
+            case 15:
+                Octree_labeling(3, label, cube);
+                break;
+            case 8:
+            case 16:
+                Octree_labeling(4, label, cube);
+                break;
+            case 17:
+            case 18:
+            case 20:
+            case 21:
+                Octree_labeling(5, label, cube);
+                break;
+            case 19:
+            case 22:
+                Octree_labeling(6, label, cube);
+                break;
+            case 23:
+            case 24:
+                Octree_labeling(7, label, cube);
+                break;
+            case 25:
+                Octree_labeling(8, label, cube);
+                break;
+            }
+            label++;
+            if (label - 2 >= 2)
+            {
+                return false;
+            }
+        }
+    }
+    //return label-2; in [Lee94] if the number of connected compontents would be needed
+    return true;
+}
+
+/** 
+ * Octree_labeling [Lee94]
+ * This is a recursive method that calulates the number of connected
+ * components in the 3D neighbourhood after the center pixel would
+ * have been removed.
+ */
+template <class TInputImage, class TOutputImage>
+void BinaryThinningImageFilter3D<TInputImage, TOutputImage>::Octree_labeling(int octant, int label, int *cube)
+{
+    // check if there are points in the octant with value 1
+    if (octant == 1)
+    {
+        // set points in this octant to current label
+        // and recurseive labeling of adjacent octants
+        if (cube[0] == 1)
+            cube[0] = label;
+        if (cube[1] == 1)
+        {
+            cube[1] = label;
+            Octree_labeling(2, label, cube);
+        }
+        if (cube[3] == 1)
+        {
+            cube[3] = label;
+            Octree_labeling(3, label, cube);
+        }
+        if (cube[4] == 1)
+        {
+            cube[4] = label;
+            Octree_labeling(2, label, cube);
+            Octree_labeling(3, label, cube);
+            Octree_labeling(4, label, cube);
+        }
+        if (cube[9] == 1)
+        {
+            cube[9] = label;
+            Octree_labeling(5, label, cube);
+        }
+        if (cube[10] == 1)
+        {
+            cube[10] = label;
+            Octree_labeling(2, label, cube);
+            Octree_labeling(5, label, cube);
+            Octree_labeling(6, label, cube);
+        }
+        if (cube[12] == 1)
+        {
+            cube[12] = label;
+            Octree_labeling(3, label, cube);
+            Octree_labeling(5, label, cube);
+            Octree_labeling(7, label, cube);
+        }
+    }
+    if (octant == 2)
+    {
+        if (cube[1] == 1)
+        {
+            cube[1] = label;
+            Octree_labeling(1, label, cube);
+        }
+        if (cube[4] == 1)
+        {
+            cube[4] = label;
+            Octree_labeling(1, label, cube);
+            Octree_labeling(3, label, cube);
+            Octree_labeling(4, label, cube);
+        }
+        if (cube[10] == 1)
+        {
+            cube[10] = label;
+            Octree_labeling(1, label, cube);
+            Octree_labeling(5, label, cube);
+            Octree_labeling(6, label, cube);
+        }
+        if (cube[2] == 1)
+            cube[2] = label;
+        if (cube[5] == 1)
+        {
+            cube[5] = label;
+            Octree_labeling(4, label, cube);
+        }
+        if (cube[11] == 1)
+        {
+            cube[11] = label;
+            Octree_labeling(6, label, cube);
+        }
+        if (cube[13] == 1)
+        {
+            cube[13] = label;
+            Octree_labeling(4, label, cube);
+            Octree_labeling(6, label, cube);
+            Octree_labeling(8, label, cube);
+        }
+    }
+    if (octant == 3)
+    {
+        if (cube[3] == 1)
+        {
+            cube[3] = label;
+            Octree_labeling(1, label, cube);
+        }
+        if (cube[4] == 1)
+        {
+            cube[4] = label;
+            Octree_labeling(1, label, cube);
+            Octree_labeling(2, label, cube);
+            Octree_labeling(4, label, cube);
+        }
+        if (cube[12] == 1)
+        {
+            cube[12] = label;
+            Octree_labeling(1, label, cube);
+            Octree_labeling(5, label, cube);
+            Octree_labeling(7, label, cube);
+        }
+        if (cube[6] == 1)
+            cube[6] = label;
+        if (cube[7] == 1)
+        {
+            cube[7] = label;
+            Octree_labeling(4, label, cube);
+        }
+        if (cube[14] == 1)
+        {
+            cube[14] = label;
+            Octree_labeling(7, label, cube);
+        }
+        if (cube[15] == 1)
+        {
+            cube[15] = label;
+            Octree_labeling(4, label, cube);
+            Octree_labeling(7, label, cube);
+            Octree_labeling(8, label, cube);
+        }
+    }
+    if (octant == 4)
+    {
+        if (cube[4] == 1)
+        {
+            cube[4] = label;
+            Octree_labeling(1, label, cube);
+            Octree_labeling(2, label, cube);
+            Octree_labeling(3, label, cube);
+        }
+        if (cube[5] == 1)
+        {
+            cube[5] = label;
+            Octree_labeling(2, label, cube);
+        }
+        if (cube[13] == 1)
+        {
+            cube[13] = label;
+            Octree_labeling(2, label, cube);
+            Octree_labeling(6, label, cube);
+            Octree_labeling(8, label, cube);
+        }
+        if (cube[7] == 1)
+        {
+            cube[7] = label;
+            Octree_labeling(3, label, cube);
+        }
+        if (cube[15] == 1)
+        {
+            cube[15] = label;
+            Octree_labeling(3, label, cube);
+            Octree_labeling(7, label, cube);
+            Octree_labeling(8, label, cube);
+        }
+        if (cube[8] == 1)
+            cube[8] = label;
+        if (cube[16] == 1)
+        {
+            cube[16] = label;
+            Octree_labeling(8, label, cube);
+        }
+    }
+    if (octant == 5)
+    {
+        if (cube[9] == 1)
+        {
+            cube[9] = label;
+            Octree_labeling(1, label, cube);
+        }
+        if (cube[10] == 1)
+        {
+            cube[10] = label;
+            Octree_labeling(1, label, cube);
+            Octree_labeling(2, label, cube);
+            Octree_labeling(6, label, cube);
+        }
+        if (cube[12] == 1)
+        {
+            cube[12] = label;
+            Octree_labeling(1, label, cube);
+            Octree_labeling(3, label, cube);
+            Octree_labeling(7, label, cube);
+        }
+        if (cube[17] == 1)
+            cube[17] = label;
+        if (cube[18] == 1)
+        {
+            cube[18] = label;
+            Octree_labeling(6, label, cube);
+        }
+        if (cube[20] == 1)
+        {
+            cube[20] = label;
+            Octree_labeling(7, label, cube);
+        }
+        if (cube[21] == 1)
+        {
+            cube[21] = label;
+            Octree_labeling(6, label, cube);
+            Octree_labeling(7, label, cube);
+            Octree_labeling(8, label, cube);
+        }
+    }
+    if (octant == 6)
+    {
+        if (cube[10] == 1)
+        {
+            cube[10] = label;
+            Octree_labeling(1, label, cube);
+            Octree_labeling(2, label, cube);
+            Octree_labeling(5, label, cube);
+        }
+        if (cube[11] == 1)
+        {
+            cube[11] = label;
+            Octree_labeling(2, label, cube);
+        }
+        if (cube[13] == 1)
+        {
+            cube[13] = label;
+            Octree_labeling(2, label, cube);
+            Octree_labeling(4, label, cube);
+            Octree_labeling(8, label, cube);
+        }
+        if (cube[18] == 1)
+        {
+            cube[18] = label;
+            Octree_labeling(5, label, cube);
+        }
+        if (cube[21] == 1)
+        {
+            cube[21] = label;
+            Octree_labeling(5, label, cube);
+            Octree_labeling(7, label, cube);
+            Octree_labeling(8, label, cube);
+        }
+        if (cube[19] == 1)
+            cube[19] = label;
+        if (cube[22] == 1)
+        {
+            cube[22] = label;
+            Octree_labeling(8, label, cube);
+        }
+    }
+    if (octant == 7)
+    {
+        if (cube[12] == 1)
+        {
+            cube[12] = label;
+            Octree_labeling(1, label, cube);
+            Octree_labeling(3, label, cube);
+            Octree_labeling(5, label, cube);
+        }
+        if (cube[14] == 1)
+        {
+            cube[14] = label;
+            Octree_labeling(3, label, cube);
+        }
+        if (cube[15] == 1)
+        {
+            cube[15] = label;
+            Octree_labeling(3, label, cube);
+            Octree_labeling(4, label, cube);
+            Octree_labeling(8, label, cube);
+        }
+        if (cube[20] == 1)
+        {
+            cube[20] = label;
+            Octree_labeling(5, label, cube);
+        }
+        if (cube[21] == 1)
+        {
+            cube[21] = label;
+            Octree_labeling(5, label, cube);
+            Octree_labeling(6, label, cube);
+            Octree_labeling(8, label, cube);
+        }
+        if (cube[23] == 1)
+            cube[23] = label;
+        if (cube[24] == 1)
+        {
+            cube[24] = label;
+            Octree_labeling(8, label, cube);
+        }
+    }
+    if (octant == 8)
+    {
+        if (cube[13] == 1)
+        {
+            cube[13] = label;
+            Octree_labeling(2, label, cube);
+            Octree_labeling(4, label, cube);
+            Octree_labeling(6, label, cube);
+        }
+        if (cube[15] == 1)
+        {
+            cube[15] = label;
+            Octree_labeling(3, label, cube);
+            Octree_labeling(4, label, cube);
+            Octree_labeling(7, label, cube);
+        }
+        if (cube[16] == 1)
+        {
+            cube[16] = label;
+            Octree_labeling(4, label, cube);
+        }
+        if (cube[21] == 1)
+        {
+            cube[21] = label;
+            Octree_labeling(5, label, cube);
+            Octree_labeling(6, label, cube);
+            Octree_labeling(7, label, cube);
+        }
+        if (cube[22] == 1)
+        {
+            cube[22] = label;
+            Octree_labeling(6, label, cube);
+        }
+        if (cube[24] == 1)
+        {
+            cube[24] = label;
+            Octree_labeling(7, label, cube);
+        }
+        if (cube[25] == 1)
+            cube[25] = label;
+    }
+}
+
+/**
+ *  Print Self
+ */
+template <class TInputImage, class TOutputImage>
+void BinaryThinningImageFilter3D<TInputImage, TOutputImage>::PrintSelf(std::ostream &os, Indent indent) const
+{
+    Superclass::PrintSelf(os, indent);
+
+    os << indent << "Thinning image: " << std::endl;
+}
+
+} // end namespace itk
+
+#endif // itkBinaryThinningImageFilter3D_hxx
index c7bb20d808207d0e303028cec5944530dc42aaec..160ce65616ad0352f9fa825ac496d9cca118b8ac 100644 (file)
@@ -76,9 +76,6 @@ namespace bbstd
   };
   //=================================================================
   
-  
-  
-  
   //=================================================================
   // BlackBox description
   BBTK_BEGIN_DESCRIBE_TEMPLATE2_BLACK_BOX(CastVector,bbtk::AtomicBlackBox);
@@ -95,10 +92,17 @@ namespace bbstd
   BBTK_END_DESCRIBE_TEMPLATE2_BLACK_BOX(CastVector);
   //=================================================================
 
-  template <class T, class U> void CastVector< T , U >::bbUserSetDefaultValues() {}
-  template <class T, class U> void CastVector< T , U >::bbUserInitializeProcessing() {}
-  template <class T, class U> void CastVector< T , U >::bbUserFinalizeProcessing() {}
-
+  template <class T, class U> 
+  void CastVector< T , U >::bbUserSetDefaultValues() 
+  {}
+  
+  template <class T, class U> 
+  void CastVector< T , U >::bbUserInitializeProcessing() 
+  {}
+  
+  template <class T, class U> 
+  void CastVector< T , U >::bbUserFinalizeProcessing() 
+  {}
 
 } // namespace bbstd
 
index 6c41981ebd565f3b7d19db82d1969e0c36fcf215..6968af71b333ff01df811edc61d594dcd7a8fb3f 100644 (file)
@@ -8,12 +8,12 @@ namespace bbstd
 
 BBTK_ADD_BLACK_BOX_TO_PACKAGE(std,DoubleToInt)
 BBTK_BLACK_BOX_IMPLEMENTATION(DoubleToInt,bbtk::AtomicBlackBox);
+
 //===== 
 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
 //===== 
 void DoubleToInt::Process()
 {
-
 // THE MAIN PROCESSING METHOD BODY
 //   Here we simply set the input 'In' value to the output 'Out'
 //   And print out the output value
@@ -25,46 +25,41 @@ void DoubleToInt::Process()
 //      (the one provided in the attribute 'name' of the tag 'input')
 //    * TYPE is the C++ type of the input/output
 //      (the one provided in the attribute 'type' of the tag 'input')
-  bbSetOutputOut( (int)bbGetInputIn() );
-  
+  bbSetOutputOut( (int)bbGetInputIn() );  
 }
+
 //===== 
 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
 //===== 
 void DoubleToInt::bbUserSetDefaultValues()
 {
-
 //  SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX 
 //    Here we initialize the input 'In' to 0
-   bbSetInputIn(0);
-  
+   bbSetInputIn(0);  
 }
+
 //===== 
 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
 //===== 
 void DoubleToInt::bbUserInitializeProcessing()
 {
-
 //  THE INITIALIZATION METHOD BODY :
 //    Here does nothing 
 //    but this is where you should allocate the internal/output pointers 
-//    if any 
-
-  
+//    if any   
 }
+
 //===== 
 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
 //===== 
 void DoubleToInt::bbUserFinalizeProcessing()
 {
-
 //  THE FINALIZATION METHOD BODY :
 //    Here does nothing 
 //    but this is where you should desallocate the internal/output pointers 
-//    if any
-  
+//    if any  
 }
-}
-// EO namespace bbstd
+
+}// EO namespace bbstd
 
 
index 83df9dfda9bb08eccaddfda2bf1fee8f87ed3e40..4a30efcf856780703988eb434552dfacc03dd38a 100644 (file)
@@ -28,18 +28,17 @@ class bbstd_EXPORT DoubleToInt
 };
 
 BBTK_BEGIN_DESCRIBE_BLACK_BOX(DoubleToInt,bbtk::AtomicBlackBox);
-BBTK_NAME("DoubleToInt");
-BBTK_AUTHOR("Claire Mouton");
-BBTK_DESCRIPTION("Converts a double to an int");
-BBTK_CATEGORY("");
-BBTK_INPUT(DoubleToInt,In,"Double input",double,"");
-BBTK_OUTPUT(DoubleToInt,Out,"Int output",int,"");
+  BBTK_NAME("DoubleToInt");
+  BBTK_AUTHOR("Claire Mouton"); 
+  BBTK_DESCRIPTION("Converts a double to an int");
+  BBTK_CATEGORY("");
+  BBTK_INPUT(DoubleToInt,In,"Double input",double,"");
+  BBTK_OUTPUT(DoubleToInt,Out,"Int output",int,"");
 BBTK_END_DESCRIBE_BLACK_BOX(DoubleToInt);
 //===== 
 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
 //===== 
-}
-// EO namespace bbstd
 
+}// EO namespace bbstd
 #endif // __bbstdDoubleToInt_h_INCLUDED__
 
diff --git a/packages/std/src/bbstdNumericalVectorToStringVector.cxx b/packages/std/src/bbstdNumericalVectorToStringVector.cxx
new file mode 100644 (file)
index 0000000..3ed784a
--- /dev/null
@@ -0,0 +1,26 @@
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+#include "bbstdNumericalVectorToStringVector.h"
+#include "bbstdPackage.h"
+namespace bbstd
+{
+
+BBTK_BLACK_BOX_TEMPLATE_IMPLEMENTATION(NumericalVectorToStringVector,bbtk::AtomicBlackBox);
+
+BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,int8_t);
+BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,uint8_t);
+BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,int16_t);
+BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,uint16_t);
+BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,int32_t);
+BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,uint32_t);
+BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,long);
+BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,float);
+BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,double);
+
+//typedef std::string string;
+// BBTK_ADD_TEMPLATE_BLACK_BOX_TO_PACKAGE(std,NumericalVectorToStringVector,string);
+
+} // EO namespace bbstd
+
+
diff --git a/packages/std/src/bbstdNumericalVectorToStringVector.h b/packages/std/src/bbstdNumericalVectorToStringVector.h
new file mode 100644 (file)
index 0000000..87f995d
--- /dev/null
@@ -0,0 +1,71 @@
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+#ifndef __bbstdNumericalVectorToStringVector_h_INCLUDED__
+#define __bbstdNumericalVectorToStringVector_h_INCLUDED__
+
+#include "bbstd_EXPORT.h"
+#include "bbtkAtomicBlackBox.h"
+#include <string>
+
+namespace bbstd
+{
+
+template <class T>
+class bbstd_EXPORT NumericalVectorToStringVector
+ : 
+   public bbtk::AtomicBlackBox
+{
+    BBTK_TEMPLATE_BLACK_BOX_INTERFACE(NumericalVectorToStringVector,bbtk::AtomicBlackBox,T);
+//===== 
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+  BBTK_DECLARE_INPUT(In,std::vector<T>);
+  BBTK_DECLARE_OUTPUT(Out,std::vector<std::string>);
+    BBTK_PROCESS(DoIt);
+    void DoIt();
+//    T decode_item(const std::string&);
+//=====
+// Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
+//===== 
+};
+
+BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX(NumericalVectorToStringVector,bbtk::AtomicBlackBox);
+  BBTK_NAME(bbtk::HumanTypeName<std::vector<T> >() +"ToStringVector");
+  BBTK_AUTHOR("InfoDev");
+  BBTK_DEFAULT_ADAPTOR();
+  BBTK_DESCRIPTION("Converts the content of the input "
+                   +bbtk::HumanTypeName<std::vector<T> >()
+                   +" ("+bbtk::TypeName<std::vector<T> >()+")  to  string vector ");
+  typedef std::vector<T> Tvector;
+  BBTK_TEMPLATE_INPUT(NumericalVectorToStringVector,In,"Input",Tvector);
+  BBTK_TEMPLATE_OUTPUT(NumericalVectorToStringVector,Out,"Output",std::vector<std::string>);
+BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX(NumericalVectorToStringVector);
+
+template <class T> 
+void NumericalVectorToStringVector<T>::bbUserSetDefaultValues()
+{}
+
+template <class T> 
+void NumericalVectorToStringVector<T>::bbUserInitializeProcessing()
+{}
+
+template <class T> 
+void NumericalVectorToStringVector<T>::bbUserFinalizeProcessing()
+{}
+
+template <class T>
+void NumericalVectorToStringVector<T>::DoIt()
+{
+  typedef T type;
+  bbmOutputOut.clear();
+  int lgt = bbGetInputIn().size();
+  for (int i=0; i<lgt; i++)
+  {
+      bbmOutputOut.push_back( std::to_string( bbGetInputIn()[i] ) );
+  } // for i
+}
+
+}// EO namespace bbstd
+#endif // __bbstdNumericalVectorToStringVector_h_INCLUDED__
+
index 64604c0527edf9dd5dfb60c974af6b707d2c9813..68a94715893646caeb9c7b16f9e47df4c46ff930 100644 (file)
@@ -52,7 +52,7 @@ BBTK_BEGIN_DESCRIBE_BLACK_BOX(VectorFilterDouble,bbtk::AtomicBlackBox);
   BBTK_AUTHOR("InfoDev");
   BBTK_DESCRIPTION("No Description.");
   BBTK_CATEGORY("empty");
-  BBTK_INPUT(VectorFilterDouble,Type,"default (0)  0=Erase duplicated lines, 1=Redimention Vectors, 2=Insert intermediat points,3=Adition k1, 4=Substraction k1, 5=Multilication k1, 6=Division k1, 7=Connect mesh X1,Y1,Z1,idxs1,X2,X2,X2,idx2, 8=Order All vectors with the logic of In0 (or the index k1 if exist) , 9=Invert Vectors, 10=Nearest Point in the vector. In3PointXYZ In0LstX In1LstY In2LstZ  (Out0-index Out1-PointXYZ), 11=Mul Spacing (K1[spcX,spcY,spcZ]=Spacing), 12=Div Spacing (K1[spcX,spcY,spcZ]=Spacing), 13=Distance pointIn0 and pontIn1,  14=Select specific segments [k1] in In0=lstPx In1=lstPy In2=lstPz In3=lstIndex (if k1 empty all segments are selected) , 15 swhitch element in a point k1=0 yz, k1=1 nothing k1=2 xz , 16 switch In0 and In1 (k1=0 nothing, k1=1 swhich)",int,"");
+  BBTK_INPUT(VectorFilterDouble,Type,"default (0)  0=Erase consecutive duplicated lines, 1=Redimention Vectors, 2=Insert intermediat points,3=Adition k1, 4=Substraction k1, 5=Multilication k1, 6=Division k1, 7=Connect mesh X1,Y1,Z1,idxs1,X2,X2,X2,idx2, 8=Order All vectors with the logic of In0 (or the index k1 if exist) , 9=Invert Vectors, 10=Nearest Point in the vector. In3PointXYZ In0LstX In1LstY In2LstZ  (Out0-index Out1-PointXYZ), 11=Mul Spacing (K1[spcX,spcY,spcZ]=Spacing), 12=Div Spacing (K1[spcX,spcY,spcZ]=Spacing), 13=Distance pointIn0 and pontIn1,  14=Select specific segments [k1] in In0=lstPx In1=lstPy In2=lstPz In3=lstIndex (if k1 empty all segments are selected) , 15 swhitch element in a point k1=0 yz, k1=1 nothing k1=2 xz , 16 switch In0 and In1 (k1=0 nothing, k1=1 swhich)",int,"");
   BBTK_INPUT(VectorFilterDouble,k1,"(default [0])  nothing (Type0), k1[0]=new size vectors (Type 1) , nothing (Type2), k1[0] = Addition const. (Type 3), k1[0] = Substraction const. (Type 4), k1[0] = Multiplication const. (Type 5) , k1[0] = Division const. (Type 6),  k1[0] In0..9 element base to be order (Type 8)  , k1[spcX,spcY,spcZ] MulSpc In0_X,In1_Y,In2_Z (type 11),  k1[spcX,spcY,spcZ] DivSpc In0_X,In1_Y,In2_Z (type 12) , k1[segment1, segment2,..] (type 14) , direction (type 15), direction (type 16) ",std::vector<double>,"");
   BBTK_INPUT(VectorFilterDouble,In0,"Input vector",std::vector<double>,"");
   BBTK_INPUT(VectorFilterDouble,In1,"Input vector",std::vector<double>,"");
index 2bfa7c95f51fd7a8f95aa10467676265a0970299..17e2e7d3e4127458f6c9f49e7c6be442dc65b2a8 100644 (file)
@@ -58,14 +58,14 @@ namespace bbstd
   //=================================================================
   // BlackBox description
   BBTK_BEGIN_DESCRIBE_TEMPLATE_BLACK_BOX(VectorToString,bbtk::AtomicBlackBox);
-  BBTK_NAME(bbtk::HumanTypeName<std::vector<T> >()+"ToString");
-  BBTK_AUTHOR("laurent.guigues@creatis.insa-lyon.fr");
-  BBTK_DEFAULT_ADAPTOR();
-  BBTK_DESCRIPTION("Converts the content of the input vector ("+bbtk::TypeName<std::vector<T> >()+") to a string in which each item is separated by the value of the input 'Separator'");
+    BBTK_NAME(bbtk::HumanTypeName<std::vector<T> >()+"ToString");
+    BBTK_AUTHOR("laurent.guigues@creatis.insa-lyon.fr");
+    BBTK_DEFAULT_ADAPTOR();
+    BBTK_DESCRIPTION("Converts the content of the input vector ("+bbtk::TypeName<std::vector<T> >()+") to a string in which each item is separated by the value of the input 'Separator'");
   typedef std::vector<T> Tvector;
-  BBTK_TEMPLATE_INPUT(VectorToString, In,"Input",Tvector);
-  BBTK_TEMPLATE_INPUT(VectorToString, Separator,"Separator of item in the output string. Default is whitespace.",std::string);
-  BBTK_TEMPLATE_OUTPUT(VectorToString, Out,"Output",std::string);
+    BBTK_TEMPLATE_INPUT(VectorToString, In,"Input",Tvector);
+    BBTK_TEMPLATE_INPUT(VectorToString, Separator,"Separator of item in the output string. Default is whitespace.",std::string);
+    BBTK_TEMPLATE_OUTPUT(VectorToString, Out,"Output",std::string);
   BBTK_END_DESCRIBE_TEMPLATE_BLACK_BOX(VectorToString);
   //=================================================================