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