Ejemplo n.º 1
0
void displayAxes( Viewer3D<space, kspace> & viewer,
                  const Point & lowerBound, const Point & upperBound,
		  const std::string & mode )
{
  RealPoint p0( (double)lowerBound[ 0 ]-0.5,
                (double)lowerBound[ 1 ]-0.5,
                (double)lowerBound[ 2 ]-0.5 );
  RealPoint p1( (double)upperBound[ 0 ]-0.5,
                (double)upperBound[ 1 ]-0.5,
                (double)upperBound[ 2 ]-0.5 );
  if ( ( mode == "WIRED" ) || ( mode == "COLORED" ) )
    {
      viewer.setLineColor(AXIS_COLOR);
      viewer.addLine( DGtal::Z3i::RealPoint(p0[ 0 ], p0[ 1 ], p0[ 2 ]),
		      DGtal::Z3i::RealPoint(p1[ 0 ], p0[ 1 ], p0[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p0[ 0 ], p0[ 1 ], p0[ 2 ]),
		      DGtal::Z3i::RealPoint(p0[ 0 ], p1[ 1 ], p0[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p0[ 0 ], p0[ 1 ], p0[ 2 ]),
		      DGtal::Z3i::RealPoint(p0[ 0 ], p0[ 1 ], p1[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p1[ 0 ], p0[ 1 ], p0[ 2 ]),
		      DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p0[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p1[ 0 ], p0[ 1 ], p0[ 2 ]),
		      DGtal::Z3i::RealPoint(p1[ 0 ], p0[ 1 ], p1[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p0[ 0 ], p1[ 1 ], p0[ 2 ]),
		      DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p0[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p0[ 0 ], p1[ 1 ], p0[ 2 ]),
		      DGtal::Z3i::RealPoint(p0[ 0 ], p1[ 1 ], p1[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p0[ 0 ], p0[ 1 ], p1[ 2 ]),
		      DGtal::Z3i::RealPoint(p1[ 0 ], p0[ 1 ], p1[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p0[ 0 ], p0[ 1 ], p1[ 2 ]),
		      DGtal::Z3i::RealPoint(p0[ 0 ], p1[ 1 ], p1[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p0[ 2 ]),
		      DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p1[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p1[ 0 ], p0[ 1 ], p1[ 2 ]),
		      DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p1[ 2 ]),  AXIS_LINESIZE );
      viewer.addLine( DGtal::Z3i::RealPoint(p0[ 0 ], p1[ 1 ], p1[ 2 ]),
		      DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p1[ 2 ]),  AXIS_LINESIZE );
    }
  if ( mode == "COLORED" )
    {
      viewer.setFillColor(XY_COLOR);
      viewer.addQuad(DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p1[ 2 ]),
		     DGtal::Z3i::RealPoint(p1[ 0 ], p0[ 1 ], p1[ 2 ]),
		     DGtal::Z3i::RealPoint(p0[ 0 ], p0[ 1 ], p1[ 2 ]),
		     DGtal::Z3i::RealPoint(p0[ 0 ], p1[ 1 ], p1[ 2 ]) );
      viewer.setFillColor(XZ_COLOR);
      viewer.addQuad(DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p1[ 2 ]),
		     DGtal::Z3i::RealPoint(p0[ 0 ], p1[ 1 ], p1[ 2 ]),
		     DGtal::Z3i::RealPoint(p0[ 0 ], p1[ 1 ], p0[ 2 ]),
		     DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p0[ 2 ]));
      viewer.setFillColor(YZ_COLOR);
      viewer.addQuad(DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p1[ 2 ]),
		     DGtal::Z3i::RealPoint(p1[ 0 ], p0[ 1 ], p1[ 2 ]),
		     DGtal::Z3i::RealPoint(p1[ 0 ], p0[ 1 ], p0[ 2 ]),
		     DGtal::Z3i::RealPoint(p1[ 0 ], p1[ 1 ], p0[ 2 ]));
    }
}
int main( int argc, char** argv )
{
 QApplication application(argc,argv);
//! [DigiHelixConstr]
 typedef EllipticHelix < Space > MyHelix;
 typedef NaiveParametricCurveDigitizer3D < MyHelix >  DigitizerHelix;
 typedef NaiveParametricCurveDigitizer3D < MyHelix >::DigitalCurve MyDigitalCurve;
 typedef NaiveParametricCurveDigitizer3D < MyHelix >::MetaData MyMetaData;
//! [DigiHelixConstr]
 trace.info() << "exampleParamCurve3dDigitization" << endl;

 Viewer3D<> viewer;

//! [DigiHelixInit]
 MyDigitalCurve digitalCurve;
 MyMetaData metaData;
 MyHelix helix( 15, 10, 1 );
 DigitizerHelix digitize;
 digitize.init ( M_PI / 2., ( MyHelix::getPeriod() * 10. ) + M_PI / 2., 0.0001 );
 digitize.attach ( &helix );
//! [DigiHelixInit]

//! [DigiHelixComp]
 digitize.digitize( back_insert_iterator < MyDigitalCurve> ( digitalCurve ), back_insert_iterator < MyMetaData > ( metaData ) );
//! [DigiHelixComp]

 trace.info() << "Number of points: " << digitalCurve.size () << " number of metadata: " << metaData.size () << endl;

 viewer.show();

//! [DigiHelixMetadata]
 for ( unsigned int i = 0; i < digitalCurve.size ( ); i++ )
 {
  if ( findMainAxis ( helix, metaData.at ( i ).first ) == 0 )
   viewer.setFillColor ( Color ( 255, 0, 0, 128 ) );
  if ( findMainAxis ( helix, metaData.at ( i ).first ) == 1 )
   viewer.setFillColor ( Color ( 0, 255, 0, 128 ) );
  if ( findMainAxis ( helix, metaData.at ( i ).first ) == 2 )
   viewer.setFillColor ( Color ( 0, 0, 255, 128 ) );
  viewer << SetMode3D ( digitalCurve.at ( i ).className ( ), "PavingWired" ) << digitalCurve.at ( i );
 }
//! [DigiHelixMetadata]
 viewer << Viewer3D<>::updateDisplay;

 return application.exec();
}
Ejemplo n.º 3
0
int main( int argc, char** argv )
{
  
  typedef DGtal::ImageContainerBySTLVector< DGtal::Z3i::Domain, unsigned int>  Image3D;
  typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain>,
                                   Image3D::Value,  DGtal::DefaultFunctor >  ImageAdapterExtractor;

 QApplication application(argc,argv);
 Viewer3D<> viewer;
 viewer.setWindowTitle("simpleViewer");
 viewer.show();
  
 trace.beginBlock("Testing Viewer with Image Embedder ");
 Point pcenter( 10, 20, 20 );
 Point pcenterImg( 10, 20, 20 );

 std::string filename =  testPath + "samples/cat10.pgm3d";
 Image3D image = DGtal::GenericReader<Image3D>::import(filename); 
 
 const int IMAGE_PATCH_WIDTH = 80;  
 // Setting the image domain of the resulting image to be displayed in 3D:
 DGtal::Z2i::Domain domainImage2D (DGtal::Z2i::Point(0,0), 
                                   DGtal::Z2i::Point(IMAGE_PATCH_WIDTH, IMAGE_PATCH_WIDTH)); 
  
 DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain >  embedder(image.domain(), 
                                                           pcenterImg, Z3i::RealPoint(1, 1, 1), 
                                                           IMAGE_PATCH_WIDTH);
 DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain >  embedder2(image.domain(), 
                                                           pcenterImg, Z3i::RealPoint(1, 0, 0), 
                                                           IMAGE_PATCH_WIDTH);
 DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain >  embedder3(image.domain(), 
                                                           pcenterImg, Z3i::RealPoint(0, 1, 0 ), 
                                                           IMAGE_PATCH_WIDTH);
 DGtal::Point2DEmbedderIn3D<DGtal::Z3i::Domain >  embedder4(image.domain(), 
                                                           pcenterImg, Z3i::RealPoint(0, 0, 1 ), 
                                                           IMAGE_PATCH_WIDTH);
 
 DGtal::DefaultFunctor idV;
 ImageAdapterExtractor extractedImage(image, domainImage2D, embedder, idV);
 ImageAdapterExtractor extractedImage2(image, domainImage2D, embedder2, idV);
 ImageAdapterExtractor extractedImage3(image, domainImage2D, embedder3, idV);
 ImageAdapterExtractor extractedImage4(image, domainImage2D, embedder4, idV);

 viewer << extractedImage;
 viewer << extractedImage2;
 viewer << extractedImage3;
 viewer << extractedImage4;
 viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(0, 
                                                                  embedder(Z2i::RealPoint(0,0),false),
                                                                  embedder(Z2i::RealPoint(IMAGE_PATCH_WIDTH,0),false),
                                                                  embedder(domainImage2D.upperBound(), false),
                                                                  embedder(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH), false));
 viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(1, 
                                                                  embedder2(Z2i::RealPoint(0,0),false),
                                                                  embedder2(Z2i::RealPoint(IMAGE_PATCH_WIDTH,0),false),
                                                                  embedder2(domainImage2D.upperBound(), false),
                                                                  embedder2(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH), false));
 viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(2, 
                                                                  embedder3(Z2i::RealPoint(0,0),false),
                                                                  embedder3(Z2i::RealPoint(IMAGE_PATCH_WIDTH,0),false),
                                                                  embedder3(domainImage2D.upperBound(), false),
                                                                  embedder3(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH), false));
 viewer << DGtal::UpdateImage3DEmbedding<Z3i::Space, Z3i::KSpace>(3, 
                                                                  embedder4(Z2i::RealPoint(0,0),false),
                                                                  embedder4(Z2i::RealPoint(IMAGE_PATCH_WIDTH,0),false),
                                                                  embedder4(domainImage2D.upperBound(), false),
                                                                  embedder4(Z2i::RealPoint(0, IMAGE_PATCH_WIDTH), false));
 viewer.setFillColor(DGtal::Color(250,20,20,255));
 viewer << pcenter;
 
 

 viewer << Viewer3D<>::updateDisplay;

 
 bool res = application.exec();
 trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
 trace.endBlock();
 return res ? 0 : 1;

}
Ejemplo n.º 4
0
int main( int argc, char** argv )
{
  trace.beginBlock ( "Example ctopo-2-3d" );
  // for 3D display with Viewer3D
  QApplication application(argc,argv);
  
  typedef ImageSelector < Z3i::Domain, int>::Type Image;
  std::string inputFilename = examplesPath + "samples/cat10.vol"; 
  Image image = VolReader<Image>::importVol(inputFilename);
  Z3i::DigitalSet set3d (image.domain());
  SetPredicate<Z3i::DigitalSet> set3dPredicate( set3d );
  SetFromImage<Z3i::DigitalSet>::append<Image>(set3d, image, 0,255);
  Viewer3D viewer;  
  viewer.show(); 
  
  
  // Construct the Khalimsky space from the image domain
  Z3i::KSpace ks;
  bool space_ok = ks.init( image.domain().lowerBound(), image.domain().upperBound(), true );
  
  ASSERT(space_ok);

  std::vector<Z3i::SCell> vectBdrySCell;
  std::vector<Z3i::SCell> vectBdrySCell2;
  std::set<Z3i::SCell> vectBdrySCellALL;
  SurfelAdjacency<3> SAdj( true );
  

  
  //Extract an initial boundary cell
  Z3i::SCell aCell = Surfaces<Z3i::KSpace>::findABel(ks, set3dPredicate);
  
  // Extracting all boundary surfels which are connected to the initial boundary Cell.
  Surfaces<Z3i::KSpace>::trackBoundary( vectBdrySCellALL,
          ks,SAdj, set3dPredicate, aCell );
    
  // Extract the bondary contour associated to the initial surfel in its first direction
  Surfaces<Z3i::KSpace>::track2DBoundary( vectBdrySCell,
             ks, *(ks.sDirs( aCell )), SAdj, 
            set3dPredicate, aCell );
  
  // Extract the bondary contour associated to the initial surfel in its second direction
  Surfaces<Z3i::KSpace>::track2DBoundary( vectBdrySCell2,
             ks, *(++(ks.sDirs( aCell ))), SAdj, 
            set3dPredicate, aCell );  
  
  
  // Displaying all the surfels in transparent mode
  viewer << SetMode3D((*(vectBdrySCellALL.begin())).styleName(), "Transparent");
  for( std::set<Z3i::SCell>::iterator it=vectBdrySCellALL.begin(); 
       it!= vectBdrySCellALL.end(); it++){
    viewer<< *it;
  } 
  
  // Displaying First surfels cut with gradient colors.;
  GradientColorMap<int> cmap_grad( 0, vectBdrySCell2.size() );
  cmap_grad.addColor( Color( 50, 50, 255 ) );
  cmap_grad.addColor( Color( 255, 0, 0 ) );
  cmap_grad.addColor( Color( 255, 255, 10 ) );
  
  // Need to avoid surfel superposition (the surfel size in increased)
  viewer << Viewer3D::shiftSurfelVisu; 
  viewer << SetMode3D((*(vectBdrySCell2.begin())).styleName(), "");
  viewer.setFillColor(Color(180, 200, 25, 255));
  
  int d=0;
  for( std::vector<Z3i::SCell>::iterator it=vectBdrySCell2.begin(); 
       it!= vectBdrySCell2.end(); it++){
    Color col= cmap_grad(d);
    viewer.setFillColor(Color(col.red(),col.green() ,col.blue(), 255));
    viewer<< *it;
    d++;
  }
  
  GradientColorMap<int> cmap_grad2( 0, vectBdrySCell.size() );
  cmap_grad2.addColor( Color( 50, 50, 255 ) );
  cmap_grad2.addColor( Color( 255, 0, 0 ) );
  cmap_grad2.addColor( Color( 255, 255, 10 ) );
  
  d=0;
  for( std::vector<Z3i::SCell>::iterator it=vectBdrySCell.begin(); 
       it!= vectBdrySCell.end(); it++){
     Color col= cmap_grad2(d);
     viewer.setFillColor(Color(col.red(),col.green() ,col.blue(), 255));
     viewer<< *it;
    d++;
  }
  
  // On need once again to avoid superposition.
  viewer << Viewer3D::shiftSurfelVisu; 
  viewer.setFillColor(Color(18, 200, 25, 255));
  viewer << aCell ;
  viewer << Viewer3D::updateDisplay;
    
  return application.exec();
}
Ejemplo n.º 5
0
int main( int argc, char** argv )
{
  // for 3D display with Viewer3D
  QApplication application(argc,argv);
  
  //! [digitalSurfaceSlice-readVol]
  trace.beginBlock( "Reading vol file into an image." );
  typedef ImageSelector < Domain, int>::Type Image;
  std::string inputFilename = examplesPath + "samples/Al.100.vol"; 
  Image image = VolReader<Image>::importVol(inputFilename);
  DigitalSet set3d (image.domain());
  SetPredicate<DigitalSet> set3dPredicate( set3d );
  SetFromImage<DigitalSet>::append<Image>(set3d, image, 
                                          0, 1 );
  Viewer3D viewer;  
  viewer.show(); 
  trace.endBlock();
  //! [digitalSurfaceSlice-readVol]
  
  //! [digitalSurfaceSlice-KSpace]
  trace.beginBlock( "Construct the Khalimsky space from the image domain." );
  KSpace ks;
  bool space_ok = ks.init( image.domain().lowerBound(), 
                           image.domain().upperBound(), true );
  if (!space_ok)
    {
      trace.error() << "Error in the Khamisky space construction."<<std::endl;
      return 2;
    }
  trace.endBlock();
  //! [digitalSurfaceSlice-KSpace]

  //! [digitalSurfaceSlice-SurfelAdjacency]
  typedef SurfelAdjacency<KSpace::dimension> MySurfelAdjacency;
  MySurfelAdjacency surfAdj( true ); // interior in all directions.
  //! [digitalSurfaceSlice-SurfelAdjacency]

  //! [digitalSurfaceSlice-ExtractingSurface]
  trace.beginBlock( "Extracting boundary by scanning the space. " );
  typedef KSpace::Surfel Surfel;
  typedef KSpace::SurfelSet SurfelSet;
  typedef SetOfSurfels< KSpace, SurfelSet > MySetOfSurfels;
  typedef DigitalSurface< MySetOfSurfels > MyDigitalSurface;
  MySetOfSurfels theSetOfSurfels( ks, surfAdj );
  Surfaces<KSpace>::sMakeBoundary( theSetOfSurfels.surfelSet(),
                                   ks, set3dPredicate,
                                   image.domain().lowerBound(), 
                                   image.domain().upperBound() );
  MyDigitalSurface digSurf( theSetOfSurfels );
  trace.info() << "Digital surface has " << digSurf.size() << " surfels."
               << std::endl;
  trace.endBlock();
  //! [digitalSurfaceSlice-ExtractingSurface]
  
  //! [digitalSurfaceSlice-ExtractingSlice]
  trace.beginBlock( "Extract slices." );
  typedef MyDigitalSurface::DigitalSurfaceTracker MyTracker;
  typedef DigitalSurface2DSlice< MyTracker > My2DSlice;
  //Extract an initial boundary cell
  Surfel surf = *digSurf.begin();
  MyTracker* tracker1 = digSurf.container().newTracker( surf );
  MyTracker* tracker2 = digSurf.container().newTracker( surf );
  // Extract the bondary contour associated to the initial surfel in
  // its first direction
  My2DSlice slice1( tracker1, *(ks.sDirs( surf )) ); 
  // Extract the bondary contour associated to the initial surfel in
  // its second direction
  My2DSlice slice2( tracker2, *++(ks.sDirs( surf )) ); 
  delete tracker1;
  delete tracker2;
  trace.endBlock();
  //! [digitalSurfaceSlice-ExtractingSlice]

  ASSERT( slice1.start() == slice1.begin() );
  ASSERT( slice1.cstart() == slice1.c() );
  ASSERT( *slice1.begin() == surf );
  ASSERT( *slice1.c() == surf );
  ASSERT( *slice1.start() == surf );
  ASSERT( *slice1.cstart() == surf );
  ASSERT( *slice1.rcstart() == surf );
  ASSERT( slice1.rcstart() == slice1.rc() );
  ASSERT( *slice1.rc() == surf );
  ASSERT( *(slice1.c()+1) == *(slice1.begin()+1) );
  ASSERT( *(slice1.rc()+1) == *(slice1.rbegin()) );

  //! [digitalSurfaceSlice-displayingAll]
  trace.beginBlock( "Display all with QGLViewer." );
  // Displaying all the surfels in transparent mode
  viewer << SetMode3D( surf.className(), "Transparent");
  for( MyDigitalSurface::ConstIterator it = theSetOfSurfels.begin(),
         it_end = theSetOfSurfels.end(); it != it_end; ++it )
    viewer<< *it;
  
  // Displaying First surfels cut with gradient colors.;
  GradientColorMap<int> cmap_grad( 0, slice1.size() );
  cmap_grad.addColor( Color( 50, 50, 255 ) );
  cmap_grad.addColor( Color( 255, 0, 0 ) );
  cmap_grad.addColor( Color( 255, 255, 10 ) );
  
  // Need to avoid surfel superposition (the surfel size in increased)
  viewer << Viewer3D::shiftSurfelVisu; 
  viewer << SetMode3D( surf.className(), "");
  viewer.setFillColor(Color(180, 200, 25, 255));
  
  int d=0;
  for ( My2DSlice::ConstIterator it = slice1.begin(),
          it_end = slice1.end(); it != it_end; ++it )
    {        
      Color col= cmap_grad(d);
      viewer.setFillColor(Color(col.red(),col.green() ,col.blue(), 255));
      viewer<< *it;
      d++;
    }
  
  GradientColorMap<int> cmap_grad2( 0, slice2.size() );
  cmap_grad2.addColor( Color( 50, 50, 255 ) );
  cmap_grad2.addColor( Color( 255, 0, 0 ) );
  cmap_grad2.addColor( Color( 255, 255, 10 ) );
  
  d=0;
  for ( My2DSlice::ConstIterator it = slice2.begin(),
          it_end = slice2.end(); it != it_end; ++it )
    {        
      Color col= cmap_grad2(d);
      viewer.setFillColor(Color(col.red(),col.green() ,col.blue(), 255));
      viewer<< *it;
      d++;
    }
  
  // One need once again to avoid superposition.
  viewer << Viewer3D::shiftSurfelVisu; 
  viewer.setFillColor(Color(18, 200, 25, 255));
  viewer << surf ;
  viewer << Viewer3D::updateDisplay;
  trace.endBlock();
    
  return application.exec();
  //! [digitalSurfaceSlice-displayingAll]
}
Ejemplo n.º 6
0
int main( int argc, char** argv )
{
  trace.info() <<  "exampleGridCurve3d: the type can be changed in example source code with  <gridcurve>, <inner>, <outer>, <incident> " << std::endl;

  string type = "gridcurve";

  //vol reading and digital set construction
  trace.beginBlock( "Reading vol file into an image." );
  typedef ImageSelector < Domain, int>::Type Image;
  std::string inputFilename = examplesPath + "samples/cat10.vol";
  Image image = VolReader<Image>::importVol(inputFilename);
  DigitalSet set3d (image.domain());
  setFromImage( image, DigitalSetInserter<DigitalSet>(set3d), 1);
  trace.info() << set3d.size() << " voxels." << std::endl;
  trace.endBlock();

  //Khalimsky space construction
  trace.beginBlock( "Construct the Khalimsky space from the image domain." );
  KSpace ks;
/*  bool space_ok = ks.init( image.domain().lowerBound(),
                           image.domain().upperBound(), true );
  if (!space_ok)
    {
      trace.error() << "Error in the Khamisky space construction."<<std::endl;
      return 2;
    }*/
  trace.endBlock();

  //digital surface construction
  typedef SurfelAdjacency<KSpace::dimension> MySurfelAdjacency;
  MySurfelAdjacency surfAdj( true ); // interior in all directions.

  trace.beginBlock( "Extracting boundary by scanning the space. " );
  typedef KSpace::Surfel Surfel;
  typedef KSpace::SurfelSet SurfelSet;
  typedef SetOfSurfels< KSpace, SurfelSet > MySetOfSurfels;
  typedef DigitalSurface< MySetOfSurfels > MyDigitalSurface;
  MySetOfSurfels theSetOfSurfels( ks, surfAdj );
  Surfaces<KSpace>::sMakeBoundary( theSetOfSurfels.surfelSet(),
                                   ks, set3d,
                                   image.domain().lowerBound(),
                                   image.domain().upperBound() );
  MyDigitalSurface digSurf( theSetOfSurfels );
  trace.info() << digSurf.size() << " surfels." << std::endl;
  trace.endBlock();

  //slice retrieving
  trace.beginBlock( "Extracting slice and constructing a grid curve. " );
  typedef MyDigitalSurface::DigitalSurfaceTracker MyTracker;
  typedef DigitalSurface2DSlice< MyTracker > My2DSlice;

  //Extract an initial boundary cell
  Surfel surf = *digSurf.begin();
  MyTracker* tracker = digSurf.container().newTracker( surf );

  // Extract the bondary contour associated to the initial surfel in
  // its first direction
  My2DSlice slice( tracker, *(ks.sDirs( surf )) );
  delete tracker;

  //! [exampleGridCurve3d-Construction]
  GridCurve<KSpace> gc(ks);
  gc.initFromSCellsRange( slice.begin(), slice.end() );
  //! [exampleGridCurve3d-Construction]

  trace.endBlock();


  // for 3D display with Viewer3D
  QApplication application(argc,argv);
  trace.beginBlock( "Display all with QGLViewer." );
  Viewer3D<> viewer;
  viewer.show();
  // Displaying all the surfels in transparent mode
  viewer << SetMode3D( surf.className(), "Transparent");
  for( MyDigitalSurface::ConstIterator it = theSetOfSurfels.begin(),
         it_end = theSetOfSurfels.end(); it != it_end; ++it )
    viewer<< *it;


  // Displaying slice
  viewer << Viewer3D<>::shiftSurfelVisu;
  viewer << SetMode3D( surf.className(), "");
  viewer.setFillColor( Color( 50, 50, 255 ) );

  if (type == "gridcurve")
    {
      viewer  << gc;
    }
  else if (type == "inner")
    {
      viewer << gc.getInnerPointsRange();
    }
  else if (type == "outer")
    {
      viewer << gc.getOuterPointsRange();
    }
  else if (type == "incident")
    {
      viewer << gc.getIncidentPointsRange();
    }
  else
    {
      trace.info() << "Display type not known. Use option -h" << std::endl;
    }

  viewer << Viewer3D<>::updateDisplay;
  trace.endBlock();

  return application.exec();
}