DGtalTools  0.9.4
3dCurvatureViewerNoise.cpp
1 
29 #include <iostream>
31 #include "DGtal/base/Common.h"
32 #include <cstring>
33 
34 #include <boost/program_options/options_description.hpp>
35 #include <boost/program_options/parsers.hpp>
36 #include <boost/program_options/variables_map.hpp>
37 
38 // Shape constructors
39 #include "DGtal/io/readers/GenericReader.h"
40 #include "DGtal/images/ImageSelector.h"
41 #include "DGtal/images/imagesSetsUtils/SetFromImage.h"
42 #include "DGtal/images/IntervalForegroundPredicate.h"
43 #include "DGtal/topology/SurfelAdjacency.h"
44 #include "DGtal/topology/helpers/Surfaces.h"
45 #include "DGtal/topology/LightImplicitDigitalSurface.h"
46 #include <DGtal/topology/SetOfSurfels.h>
47 
48 #include "DGtal/images/ImageHelper.h"
49 #include "DGtal/topology/DigitalSurface.h"
50 #include "DGtal/graph/DepthFirstVisitor.h"
51 #include "DGtal/graph/GraphVisitorRange.h"
52 
53 // Noise
54 #include "DGtal/geometry/volumes/KanungoNoise.h"
55 
56 // Integral Invariant includes
57 #include "DGtal/geometry/surfaces/estimation/IIGeometricFunctors.h"
58 #include "DGtal/geometry/surfaces/estimation/IntegralInvariantVolumeEstimator.h"
59 #include "DGtal/geometry/surfaces/estimation/IntegralInvariantCovarianceEstimator.h"
60 
61 // Drawing
62 #include "DGtal/io/boards/Board3D.h"
63 #include "DGtal/io/colormaps/GradientColorMap.h"
64 
65 #ifdef WITH_VISU3D_QGLVIEWER
66 #include "DGtal/io/viewers/Viewer3D.h"
67 #endif
68 
69 using namespace DGtal;
70 using namespace functors;
71 
164 const Color AXIS_COLOR_RED( 200, 20, 20, 255 );
165 const Color AXIS_COLOR_GREEN( 20, 200, 20, 255 );
166 const Color AXIS_COLOR_BLUE( 20, 20, 200, 255 );
167 const double AXIS_LINESIZE = 0.05;
168 
170 
176 void missingParam( std::string param )
177 {
178  trace.error() << " Parameter: " << param << " is required.";
179  trace.info() << std::endl;
180 }
181 
182 namespace po = boost::program_options;
183 
184 int main( int argc, char** argv )
185 {
186  // parse command line ----------------------------------------------
187  po::options_description general_opt("Allowed options are");
188  general_opt.add_options()
189  ("help,h", "display this message")
190  ("input,i", po::value< std::string >(), ".vol file")
191  ("radius,r", po::value< double >(), "Kernel radius for IntegralInvariant" )
192  ("noise,k", po::value< double >()->default_value(0.5), "Level of Kanungo noise ]0;1[" )
193  ("threshold,t", po::value< unsigned int >()->default_value(8), "Min size of SCell boundary of an object" )
194  ("minImageThreshold,l", po::value< int >()->default_value(0), "set the minimal image threshold to define the image object (object defined by the voxel with intensity belonging to ]minImageThreshold, maxImageThreshold ] )." )
195  ("maxImageThreshold,u", po::value< int >()->default_value(255), "set the minimal image threshold to define the image object (object defined by the voxel with intensity belonging to ]minImageThreshold, maxImageThreshold] )." )
196  ("mode,m", po::value< std::string >()->default_value("mean"), "type of output : mean, gaussian, k1, k2, prindir1, prindir2 or normal(default mean)")
197  ("exportOBJ,o", po::value< std::string >(), "Export the scene to specified OBJ/MTL filename (extensions added)." )
198  ("exportDAT,d", po::value<std::string>(), "Export resulting curvature (for mean, gaussian, k1 or k2 mode) in a simple data file each line representing a surfel. ")
199  ("exportOnly", "Used to only export the result without the 3d Visualisation (usefull for scripts)." )
200  ("imageScale,s", po::value<std::vector<double> >()->multitoken(), "scaleX, scaleY, scaleZ: re sample the source image according with a grid of size 1.0/scale (usefull to compute curvature on image defined on anisotropic grid). Set by default to 1.0 for the three axis. ")
201  ("normalization,n", "When exporting to OBJ, performs a normalization so that the geometry fits in [-1/2,1/2]^3") ;
202 
203  bool parseOK = true;
204  po::variables_map vm;
205  try
206  {
207  po::store( po::parse_command_line( argc, argv, general_opt ), vm );
208  }
209  catch( const std::exception & ex )
210  {
211  parseOK = false;
212  trace.error() << " Error checking program options: " << ex.what() << std::endl;
213  }
214  bool neededArgsGiven=true;
215 
216  if (parseOK && !(vm.count("input"))){
217  missingParam("--input");
218  neededArgsGiven=false;
219  }
220  if (parseOK && !(vm.count("radius"))){
221  missingParam("--radius");
222  neededArgsGiven=false;
223  }
224 
225  bool normalization = false;
226  if (parseOK && vm.count("normalization"))
227  normalization = true;
228 
229  std::string mode;
230  if( parseOK )
231  mode = vm["mode"].as< std::string >();
232  if ( parseOK && ( mode.compare("gaussian") != 0 ) && ( mode.compare("mean") != 0 ) &&
233  ( mode.compare("k1") != 0 ) && ( mode.compare("k2") != 0 ) &&
234  ( mode.compare("prindir1") != 0 ) && ( mode.compare("prindir2") != 0 )&& ( mode.compare("normal") != 0 ))
235  {
236  parseOK = false;
237  trace.error() << " The selected mode ("<<mode << ") is not defined."<<std::endl;
238  }
239 
240  double noiseLevel = vm["noise"].as< double >();
241  if( noiseLevel < 0.0 || noiseLevel > 1.0 )
242  {
243  parseOK = false;
244  trace.error() << "The noise level should be in the interval: ]0, 1["<< std::endl;
245  }
246 
247 #ifndef WITH_VISU3D_QGLVIEWER
248  bool enable_visu = false;
249 #else
250  bool enable_visu = !vm.count("exportOnly");
251 #endif
252  bool enable_obj = vm.count("exportOBJ");
253  bool enable_dat = vm.count("exportDAT");
254 
255  if( !enable_visu && !enable_obj && !enable_dat )
256  {
257 #ifndef WITH_VISU3D_QGLVIEWER
258  trace.error() << "You should specify what you want to export with --export and/or --exportDat." << std::endl;
259 #else
260  trace.error() << "You should specify what you want to export with --export and/or --exportDat, or remove --exportOnly." << std::endl;
261 #endif
262  neededArgsGiven = false;
263  }
264 
265  if(!neededArgsGiven || !parseOK || vm.count("help") || argc <= 1 )
266  {
267  trace.info()<< "Visualisation of 3d curvature from .vol file using curvature from Integral Invariant" <<std::endl
268  << general_opt << "\n"
269  << "Basic usage: "<<std::endl
270  << "\t3dCurvatureViewerNoise -i file.vol --radius 5 --mode mean --noise 0.5"<<std::endl
271  << std::endl
272  << "Below are the different available modes: " << std::endl
273  << "\t - \"mean\" for the mean curvature" << std::endl
274  << "\t - \"gaussian\" for the Gaussian curvature" << std::endl
275  << "\t - \"k1\" for the first principal curvature" << std::endl
276  << "\t - \"k2\" for the second principal curvature" << std::endl
277  << "\t - \"prindir1\" for the first principal curvature direction" << std::endl
278  << "\t - \"prindir2\" for the second principal curvature direction" << std::endl
279  << "\t - \"normal\" for the normal vector" << std::endl
280  << std::endl;
281  return 0;
282  }
283  unsigned int threshold = vm["threshold"].as< unsigned int >();
284  int minImageThreshold = vm["minImageThreshold"].as< int >();
285  int maxImageThreshold = vm["maxImageThreshold"].as< int >();
286 
287  double h = 1.0;
288 
289  std::string export_obj_filename;
290  std::string export_dat_filename;
291 
292  if( enable_obj )
293  {
294  export_obj_filename = vm["exportOBJ"].as< std::string >();
295  if( export_obj_filename.find(".obj") == std::string::npos )
296  {
297  std::ostringstream oss;
298  oss << export_obj_filename << ".obj" << std::endl;
299  export_obj_filename = oss.str();
300  }
301  }
302 
303 
304  if( enable_dat )
305  {
306  export_dat_filename = vm["exportDAT"].as<std::string>();
307  }
308 
309  double re_convolution_kernel = vm["radius"].as< double >();
310 
311 
312  std::vector< double > aGridSizeReSample;
313  if( vm.count( "imageScale" ))
314  {
315  std::vector< double> vectScale = vm["imageScale"].as<std::vector<double > >();
316  if( vectScale.size() != 3 )
317  {
318  trace.error() << "The grid size should contains 3 elements" << std::endl;
319  return 0;
320  }
321  else
322  {
323  aGridSizeReSample.push_back(1.0/vectScale.at(0));
324  aGridSizeReSample.push_back(1.0/vectScale.at(1));
325  aGridSizeReSample.push_back(1.0/vectScale.at(2));
326  }
327  }
328  else
329  {
330  aGridSizeReSample.push_back(1.0);
331  aGridSizeReSample.push_back(1.0);
332  aGridSizeReSample.push_back(1.0);
333  }
334 
335 
336 
337  // Construction of the shape from vol file
339  typedef Z3i::Point Point;
342  DGtal::int32_t, double > ReSampler;
343  typedef DGtal::ConstImageAdapter<Image, Image::Domain, ReSampler,
344  Image::Value, DGtal::functors::Identity > SamplerImageAdapter;
346  typedef KanungoNoise< ImagePredicate, Z3i::Domain > KanungoPredicate;
347  typedef BinaryPointPredicate<DomainPredicate<Image::Domain>, KanungoPredicate, AndBoolFct2 > Predicate;
348  typedef Z3i::KSpace KSpace;
349  typedef KSpace::SCell SCell;
350  typedef KSpace::Cell Cell;
351 
352  trace.beginBlock("Loading the file");
353  std::string filename = vm["input"].as< std::string >();
354  Image image = GenericReader<Image>::import( filename );
355 
356  PointVector<3,int> shiftVector3D( 0 ,0, 0 );
358  DGtal::int32_t, double > reSampler(image.domain(),
359  aGridSizeReSample, shiftVector3D);
360  const functors::Identity identityFunctor{};
361  SamplerImageAdapter sampledImage ( image, reSampler.getSubSampledDomain(), reSampler, identityFunctor );
362  ImagePredicate predicateIMG = ImagePredicate( sampledImage, minImageThreshold, maxImageThreshold );
363  KanungoPredicate noisifiedPredicateIMG( predicateIMG, sampledImage.domain(), noiseLevel );
364  DomainPredicate<Z3i::Domain> domainPredicate( sampledImage.domain() );
365  AndBoolFct2 andF;
366  Predicate predicate(domainPredicate, noisifiedPredicateIMG, andF );
367 
368 
369  Z3i::Domain domain = sampledImage.domain();
370  Z3i::KSpace K;
371  bool space_ok = K.init( domain.lowerBound()-Z3i::Domain::Point::diagonal(),
372  domain.upperBound()+Z3i::Domain::Point::diagonal(), true );
373  if (!space_ok)
374  {
375  trace.error() << "Error in the Khalimsky space construction."<<std::endl;
376  return 2;
377  }
378  CanonicSCellEmbedder< KSpace > embedder( K );
380  trace.endBlock();
381  // Viewer settings
382 
383 
384  // Extraction of components
385  typedef KSpace::SurfelSet SurfelSet;
386  typedef SetOfSurfels< KSpace, SurfelSet > MySetOfSurfels;
387  typedef DigitalSurface< MySetOfSurfels > MyDigitalSurface;
388 
389 
390 
391  trace.beginBlock("Extracting surfaces");
392  std::vector< std::vector<SCell > > vectConnectedSCell;
393  Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, Sadj, predicate, false);
394  std::ofstream outDat;
395  if( enable_dat )
396  {
397  trace.info() << "Exporting curvature as dat file: "<< export_dat_filename <<std::endl;
398  outDat.open( export_dat_filename.c_str() );
399  outDat << "# data exported from 3dCurvatureViewer implementing the II curvature estimator (Coeurjolly, D.; Lachaud, J.O; Levallois, J., (2013). Integral based Curvature"
400  << " Estimators in Digital Geometry. DGCI 2013.) " << std::endl;
401  outDat << "# format: surfel coordinates (in Khalimsky space) curvature: "<< mode << std::endl;
402  }
403 
404  trace.info()<<"Number of components= "<<vectConnectedSCell.size()<<std::endl;
405  trace.endBlock();
406 
407  if( vectConnectedSCell.size() == 0 )
408  {
409  trace.error()<< "No surface component exists. Please check the vol file threshold parameter.";
410  trace.info()<<std::endl;
411  exit(2);
412  }
413 
414 #ifdef WITH_VISU3D_QGLVIEWER
415  QApplication application( argc, argv );
417 #endif
418  typedef Board3D<Z3i::Space, Z3i::KSpace> Board;
419 
420 #ifdef WITH_VISU3D_QGLVIEWER
421  Viewer viewer( K );
422 #endif
423  Board board( K );
424 
425 #ifdef WITH_VISU3D_QGLVIEWER
426  if( enable_visu )
427  {
428  viewer.show();
429  }
430 #endif
431 
432  unsigned int i = 0;
433  unsigned int max_size = 0;
434  for( unsigned int ii = 0; ii<vectConnectedSCell.size(); ++ii )
435  {
436  if( vectConnectedSCell[ii].size() <= threshold )
437  {
438  continue;
439  }
440  if( vectConnectedSCell[ii].size() > max_size )
441  {
442  max_size = vectConnectedSCell[ii].size();
443  i = ii;
444  }
445  }
446 
447  MySetOfSurfels aSet(K, Sadj);
448 
449  for( std::vector<SCell>::const_iterator it = vectConnectedSCell.at(i).begin();
450  it != vectConnectedSCell.at(i).end();
451  ++it )
452  {
453  aSet.surfelSet().insert( *it);
454  }
455 
456  MyDigitalSurface digSurf( aSet );
457 
458 
459  typedef DepthFirstVisitor<MyDigitalSurface> Visitor;
460  typedef GraphVisitorRange< Visitor > VisitorRange;
461  typedef VisitorRange::ConstIterator SurfelConstIterator;
462  VisitorRange range( new Visitor( digSurf, *digSurf.begin() ) );
463  SurfelConstIterator abegin = range.begin();
464  SurfelConstIterator aend = range.end();
465 
466  VisitorRange range2( new Visitor( digSurf, *digSurf.begin() ) );
467  SurfelConstIterator abegin2 = range2.begin();
468 
469  trace.beginBlock("Curvature computation on a component");
470  if( ( mode.compare("gaussian") == 0 ) || ( mode.compare("mean") == 0 )
471  || ( mode.compare("k1") == 0 ) || ( mode.compare("k2") == 0 ))
472  {
473  typedef double Quantity;
474  std::vector< Quantity > results;
475  std::back_insert_iterator< std::vector< Quantity > > resultsIterator( results );
476  if ( mode.compare("mean") == 0 )
477  {
478  typedef functors::IIMeanCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor;
480 
481  MyIICurvatureFunctor functor;
482  functor.init( h, re_convolution_kernel );
483 
484  MyIIEstimator estimator( functor );
485  estimator.attach( K, predicate );
486  estimator.setParams( re_convolution_kernel/h );
487  estimator.init( h, abegin, aend );
488 
489  estimator.eval( abegin, aend, resultsIterator );
490  }
491  else if ( mode.compare("gaussian") == 0 )
492  {
493  typedef functors::IIGaussianCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor;
495 
496  MyIICurvatureFunctor functor;
497  functor.init( h, re_convolution_kernel );
498 
499  MyIIEstimator estimator( functor ); estimator.attach( K,
500  predicate ); estimator.setParams( re_convolution_kernel/h );
501  estimator.init( h, abegin, aend );
502 
503  estimator.eval( abegin, aend, resultsIterator );
504  }
505  else if ( mode.compare("k1") == 0 )
506  {
509 
510  MyIICurvatureFunctor functor;
511  functor.init( h, re_convolution_kernel );
512 
513  MyIIEstimator estimator( functor );
514  estimator.attach( K, predicate );
515  estimator.setParams( re_convolution_kernel/h );
516  estimator.init( h, abegin, aend );
517 
518  estimator.eval( abegin, aend, resultsIterator );
519  }
520  else if ( mode.compare("k2") == 0 )
521  {
524 
525  MyIICurvatureFunctor functor;
526  functor.init( h, re_convolution_kernel );
527 
528  MyIIEstimator estimator( functor );
529  estimator.attach( K, predicate );
530  estimator.setParams( re_convolution_kernel/h );
531  estimator.init( h, abegin, aend );
532 
533  estimator.eval( abegin, aend, resultsIterator );
534  }
535  trace.endBlock();
536 
537 
538  // Drawing results
539  trace.beginBlock("Visualisation");
540  Quantity min = results[ 0 ];
541  Quantity max = results[ 0 ];
542  for ( unsigned int i = 1; i < results.size(); ++i )
543  {
544  if ( results[ i ] < min )
545  {
546  min = results[ i ];
547  }
548  else if ( results[ i ] > max )
549  {
550  max = results[ i ];
551  }
552  }
553  trace.info() << "Max value= "<<max<<" min value= "<<min<<std::endl;
554  ASSERT( min <= max );
555  typedef GradientColorMap< Quantity > Gradient;
556  Gradient cmap_grad( min, (max==min)? max+1: max );
557  cmap_grad.addColor( Color( 50, 50, 255 ) );
558  cmap_grad.addColor( Color( 255, 0, 0 ) );
559  cmap_grad.addColor( Color( 255, 255, 10 ) );
560 
561 #ifdef WITH_VISU3D_QGLVIEWER
562  if( enable_visu )
563  {
564  viewer << SetMode3D((*abegin2).className(), "Basic" );
565  }
566 #endif
567  if( enable_obj )
568  {
569  board << SetMode3D((K.unsigns(*abegin2)).className(), "Basic" );
570  }
571 
572 
573  for ( unsigned int i = 0; i < results.size(); ++i )
574  {
575 #ifdef WITH_VISU3D_QGLVIEWER
576  if( enable_visu )
577  {
578  viewer << CustomColors3D( Color::Black, cmap_grad( results[ i ] ));
579  viewer << *abegin2;
580  }
581 #endif
582 
583  if( enable_obj )
584  {
585  board << CustomColors3D( Color::Black, cmap_grad( results[ i ] ));
586  board << K.unsigns(*abegin2);
587  }
588 
589  if( enable_dat )
590  {
591  Point kCoords = K.uKCoords(K.unsigns(*abegin2));
592  outDat << kCoords[0] << " " << kCoords[1] << " " << kCoords[2] << " " << results[i] << std::endl;
593  }
594 
595  ++abegin2;
596  }
597  }
598  else
599  {
600  typedef Z3i::Space::RealVector Quantity;
601  std::vector< Quantity > results;
602  std::back_insert_iterator< std::vector< Quantity > > resultsIterator( results );
603 
604  if( mode.compare("prindir1") == 0 )
605  {
606  typedef functors::IIFirstPrincipalDirectionFunctor<Z3i::Space> MyIICurvatureFunctor;
608 
609  MyIICurvatureFunctor functor;
610  functor.init( h, re_convolution_kernel );
611 
612  MyIIEstimator estimator( functor );
613  estimator.attach( K, predicate );
614  estimator.setParams( re_convolution_kernel/h );
615  estimator.init( h, abegin, aend );
616 
617  estimator.eval( abegin, aend, resultsIterator );
618  }
619  else if( mode.compare("prindir2") == 0 )
620  {
621  typedef functors::IISecondPrincipalDirectionFunctor<Z3i::Space> MyIICurvatureFunctor;
623 
624  MyIICurvatureFunctor functor;
625  functor.init( h, re_convolution_kernel );
626 
627  MyIIEstimator estimator( functor );
628  estimator.attach( K, predicate );
629  estimator.setParams( re_convolution_kernel/h );
630  estimator.init( h, abegin, aend );
631 
632  estimator.eval( abegin, aend, resultsIterator );
633  }else if( mode.compare("normal") == 0 )
634  {
635  typedef functors::IINormalDirectionFunctor<Z3i::Space> MyIICurvatureFunctor;
637 
638  MyIICurvatureFunctor functor;
639  functor.init( h, re_convolution_kernel );
640 
641  MyIIEstimator estimator( functor );
642  estimator.attach( K, predicate );
643  estimator.setParams( re_convolution_kernel/h );
644  estimator.init( h, abegin, aend );
645 
646  estimator.eval( abegin, aend, resultsIterator );
647  }
648 
649  //Visualization + export
650 
651 #ifdef WITH_VISU3D_QGLVIEWER
652  if( enable_visu )
653  {
654  viewer << SetMode3D(K.uCell( K.sKCoords(*abegin2) ).className(), "Basic" );
655  }
656 #endif
657 
658  if( enable_obj )
659  {
660  board << SetMode3D(K.uCell( K.sKCoords(*abegin2) ).className(), "Basic" );
661  }
662 
663  for ( unsigned int i = 0; i < results.size(); ++i )
664  {
665  DGtal::Dimension kDim = K.sOrthDir( *abegin2 );
666  SCell outer = K.sIndirectIncident( *abegin2, kDim);
667  if ( predicate(embedder(outer)) )
668  {
669  outer = K.sDirectIncident( *abegin2, kDim);
670  }
671 
672  Cell unsignedSurfel = K.uCell( K.sKCoords(*abegin2) );
673 
674 #ifdef WITH_VISU3D_QGLVIEWER
675  if( enable_visu )
676  {
677  viewer << CustomColors3D( DGtal::Color(255,255,255,255),
678  DGtal::Color(255,255,255,255))
679  << unsignedSurfel;
680  }
681 #endif
682 
683  if( enable_obj )
684  {
685  board << CustomColors3D( DGtal::Color(255,255,255,255),
686  DGtal::Color(255,255,255,255))
687  << unsignedSurfel;
688  }
689 
690  if( enable_dat )
691  {
692  Point kCoords = K.uKCoords(K.unsigns(*abegin2));
693  outDat << kCoords[0] << " " << kCoords[1] << " " << kCoords[2] << " "
694  << results[i][0] << " " << results[i][1] << " " << results[i][2]
695  << std::endl;
696  }
697 
698  RealPoint center = embedder( outer );
699 
700 #ifdef WITH_VISU3D_QGLVIEWER
701  if( enable_visu )
702  {
703  if( mode.compare("prindir1") == 0 )
704  {
705  viewer.setLineColor( AXIS_COLOR_BLUE );
706  }
707  else if( mode.compare("prindir2") == 0 )
708  {
709  viewer.setLineColor( AXIS_COLOR_RED );
710  }
711  else if( mode.compare("normal") == 0 )
712  {
713  viewer.setLineColor( AXIS_COLOR_GREEN );
714  }
715 
716  viewer.addLine (
717  RealPoint(
718  center[0] - 0.5 * results[i][0],
719  center[1] - 0.5 * results[i][1],
720  center[2] - 0.5 * results[i][2]
721  ),
722  RealPoint(
723  center[0] + 0.5 * results[i][0],
724  center[1] + 0.5 * results[i][1],
725  center[2] + 0.5 * results[i][2]
726  ),
727  AXIS_LINESIZE );
728  }
729 #endif
730 
731  if( enable_obj )
732  {
733  if( mode.compare("prindir1") == 0 )
734  {
735  board.setFillColor( AXIS_COLOR_BLUE );
736  }
737  else if( mode.compare("prindir2") == 0 )
738  {
739  board.setFillColor( AXIS_COLOR_RED );
740  }
741  else if( mode.compare("normal") == 0 )
742  {
743  board.setFillColor( AXIS_COLOR_GREEN );
744  }
745 
746  board.addCylinder (
747  RealPoint(
748  center[0] - 0.5 * results[i][0],
749  center[1] - 0.5 * results[i][1],
750  center[2] - 0.5 * results[i][2]),
751  RealPoint(
752  center[0] + 0.5 * results[i][0],
753  center[1] + 0.5 * results[i][1],
754  center[2] + 0.5 * results[i][2]),
755  0.2 );
756  }
757 
758  ++abegin2;
759  }
760  }
761  trace.endBlock();
762 
763 #ifdef WITH_VISU3D_QGLVIEWER
764  if( enable_visu )
765  {
766  viewer << Viewer3D<>::updateDisplay;
767  }
768 #endif
769  if( enable_obj )
770  {
771  trace.info()<< "Exporting object: " << export_obj_filename << " ...";
772  board.saveOBJ(export_obj_filename,normalization);
773  trace.info() << "[done]" << std::endl;
774  }
775  if( enable_dat )
776  {
777  outDat.close();
778  }
779 
780 #ifdef WITH_VISU3D_QGLVIEWER
781  if( enable_visu )
782  {
783  return application.exec();
784  }
785 #endif
786 
787  return 0;
788 }
789 
void beginBlock(const std::string &keyword="")
static const Color Black
const Point & sKCoords(const SCell &c) const
std::set< SCell > SurfelSet
DGtal::uint32_t Dimension
double endBlock()
SCell sDirectIncident(const SCell &p, Dimension k) const
static TContainer import(const std::string &filename, std::vector< unsigned int > dimSpace=std::vector< unsigned int >())
Cell uCell(const PreCell &c) const
void init(const double _h, SurfelConstIterator itb, SurfelConstIterator ite)
const Point & uKCoords(const Cell &c) const
Dimension sOrthDir(const SCell &s) const
bool init(const Point &lower, const Point &upper, bool isClosed)
static void extractAllConnectedSCell(std::vector< std::vector< SCell > > &aVectConnectedSCell, const KSpace &aKSpace, const SurfelAdjacency< KSpace::dimension > &aSurfelAdj, const PointPredicate &pp, bool forceOrientCellExterior=false)
const Point & upperBound() const
Trace trace(traceWriterTerm)
std::ostream & info()
SCell sIndirectIncident(const SCell &p, Dimension k) const
typename Self::Point Point
void init(const double _h, SurfelConstIterator itb, SurfelConstIterator ite)
Cell unsigns(const SCell &p) const
TImageContainer::Value Value
boost::int32_t int32_t
const Point & lowerBound() const
std::ostream & error()
TImageContainer::Domain Domain