int main( int narg, char **argv ) { trace.beginBlock("Identifying the domain."); Z3i::Domain domain = scene_dimensions( argv[1] ) ; if ( domain.lowerBound() == domain.upperBound() ) { trace.error()<<"Invalid domain ("<<__FILE__<<")"<<std::endl; return -1 ; } trace.endBlock() ; trace.beginBlock("Reading slices."); Z3i::DigitalSet set3d( domain ) ; SetPredicate<Z3i::DigitalSet> set3dPredicate( set3d ) ; for ( uint depth = 0 ; depth < domain.upperBound().at(2) ; depth++ ) process_slice( argv[1], depth, set3d ) ; trace.endBlock() ; if ( 0) { try { Gray3DImage aImage( domain ); for ( Z3i::Domain::ConstIterator pt = domain.begin() ; pt != domain.end() ; pt++ ) aImage.setValue( (*pt), 255 ) ; boost::filesystem::path pathvolname = argv[1] ; pathvolname /= "obj.vol" ; if ( ! DGtal::VolWriter< Gray3DImage, GrayColorMap >::exportVol ( pathvolname.string(), aImage, 0, 255 ) ) { trace.error() <<"Can not export data (generated 3D object)"<<std::endl; return -4 ; } else { trace.info()<<"export data to "<<pathvolname.string()<<std::endl; } pathvolname = argv[1] ; pathvolname /= "obj.pgm3d" ; if ( ! PNMWriter<Gray3DImage, GrayColorMap >::exportPGM3D( pathvolname.string(), aImage, 0, 255 ) ) { trace.error() <<"Can not export data (generated 3D object)"<<std::endl; return -4 ; } else { trace.info()<<"export data to "<<pathvolname.string()<<std::endl; } } catch ( std::exception &e ) { trace.error() <<"Can not export data (generated 3D object) "<<e.what()<<std::endl; return -8 ; } } trace.beginBlock( "Decompose the object into connected components." ); { DGtal::Z3i::Object6_18 scene( DGtal::Z3i::dt6_18, set3d ) ; std::vector< Z3i::Object6_18 > v_obj ; back_insert_iterator< std::vector< Z3i::Object6_18 > > it( v_obj ) ; scene.writeComponents( it ) ; boost::filesystem::path scenefilename = argv[1] ; scenefilename /= "scene.pgm3d" ; IOPgm3d::write( v_obj, scenefilename.string().c_str() ) ; } trace.endBlock( ); return -64; trace.beginBlock( "Construct the Khalimsky space from the image domain." ); Z3i::KSpace ks; bool space_ok = ks.init( domain.lowerBound(), domain.upperBound(), true ); if (!space_ok) { trace.error() << "Error in the Khamisky space construction."<<std::endl; return -2; } trace.endBlock(); typedef SurfelAdjacency<Z3i::KSpace::dimension> MySurfelAdjacency; MySurfelAdjacency surfAdj( true ); // interior in all directions. trace.beginBlock( "Extracting boundary by tracking from an initial bel." ); Z3i::KSpace::SCellSet boundary; Z3i::SCell bel = Surfaces<Z3i::KSpace>::findABel( ks, set3dPredicate, 100000 ); Surfaces<Z3i::KSpace>::trackBoundary( boundary, ks, surfAdj, set3dPredicate, bel ); trace.endBlock(); trace.beginBlock( "Displaying surface in Viewer3D." ); QApplication application(narg,argv); Viewer3D viewer; viewer.show(); viewer << SetMode3D( boundary.begin()->className(), "") ; //CustomColors3D(Color(250, 0, 0 ), Color( 128, 128, 128 ) ); unsigned long nbSurfels = 0; for ( Z3i::KSpace::SCellSet::const_iterator it = boundary.begin(), it_end = boundary.end(); it != it_end; ++it, ++nbSurfels ) viewer << ks.uCell( Z3i::Point( (*it).myCoordinates.at(0), (*it).myCoordinates.at(1), (*it).myCoordinates.at(2) ) ) ; /** for ( Z3i::KSpace::SCellSet::const_iterator it = boundary.begin(), it_end = boundary.end(); it != it_end; ++it, ++nbSurfels ) viewer << (*it) ; */ trace.info() << *boundary.begin()<<std::endl; viewer << Viewer3D::updateDisplay; trace.info() << "nb surfels = " << nbSurfels << std::endl; trace.endBlock(); return application.exec(); }
int main( int argc, char** argv ) { // parse command line ---------------------------------------------- po::options_description general_opt("Allowed options are"); general_opt.add_options() ("help,h", "display this message") ("input,i", po::value< std::string >(), ".vol file") ("radius,r", po::value< double >(), "Kernel radius for IntegralInvariant" ) ("threshold,t", po::value< unsigned int >()->default_value(8), "Min size of SCell boundary of an object" ) ("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 ] )." ) ("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] )." ) ("mode,m", po::value< std::string >()->default_value("mean"), "type of output : mean, gaussian, k1, k2, prindir1, prindir2 or normal (default mean)") ("exportOBJ,o", po::value< std::string >(), "Export the scene to specified OBJ/MTL filename (extensions added)." ) ("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. ") ("exportOnly", "Used to only export the result without the 3d Visualisation (usefull for scripts)." ) ("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. ") ("normalization,n", "When exporting to OBJ, performs a normalization so that the geometry fits in [-1/2,1/2]^3") ; bool parseOK = true; po::variables_map vm; try { po::store( po::parse_command_line( argc, argv, general_opt ), vm ); } catch( const std::exception & ex ) { parseOK = false; trace.error() << " Error checking program options: " << ex.what() << std::endl; } bool neededArgsGiven=true; if (parseOK && !(vm.count("input"))){ missingParam("--input"); neededArgsGiven=false; } if (parseOK && !(vm.count("radius"))){ missingParam("--radius"); neededArgsGiven=false; } bool normalization = false; if (parseOK && vm.count("normalization")) normalization = true; std::string mode; if( parseOK ) mode = vm["mode"].as< std::string >(); if ( parseOK && ( mode.compare("gaussian") != 0 ) && ( mode.compare("mean") != 0 ) && ( mode.compare("k1") != 0 ) && ( mode.compare("k2") != 0 ) && ( mode.compare("prindir1") != 0 ) && ( mode.compare("prindir2") != 0 ) && ( mode.compare("normal") != 0 )) { parseOK = false; trace.error() << " The selected mode ("<<mode << ") is not defined."<<std::endl; } #ifndef WITH_VISU3D_QGLVIEWER bool enable_visu = false; #else bool enable_visu = !vm.count("exportOnly"); ///<! Default QGLViewer viewer. Disabled if exportOnly is set. #endif bool enable_obj = vm.count("exportOBJ"); ///<! Export to a .obj file. bool enable_dat = vm.count("exportDAT"); ///<! Export to a .dat file. if( !enable_visu && !enable_obj && !enable_dat ) { #ifndef WITH_VISU3D_QGLVIEWER trace.error() << "You should specify what you want to export with --export and/or --exportDat." << std::endl; #else trace.error() << "You should specify what you want to export with --export and/or --exportDat, or remove --exportOnly." << std::endl; #endif neededArgsGiven = false; } if(!neededArgsGiven || !parseOK || vm.count("help") || argc <= 1 ) { trace.info()<< "Visualisation of 3d curvature from .vol file using curvature from Integral Invariant" <<std::endl << general_opt << "\n" << "Basic usage: "<<std::endl << "\t3dCurvatureViewer -i file.vol --radius 5 --mode mean"<<std::endl << std::endl << "Below are the different available modes: " << std::endl << "\t - \"mean\" for the mean curvature" << std::endl << "\t - \"gaussian\" for the Gaussian curvature" << std::endl << "\t - \"k1\" for the first principal curvature" << std::endl << "\t - \"k2\" for the second principal curvature" << std::endl << "\t - \"prindir1\" for the first principal curvature direction" << std::endl << "\t - \"prindir2\" for the second principal curvature direction" << std::endl << "\t - \"normal\" for the normal vector" << std::endl << std::endl; return 0; } unsigned int threshold = vm["threshold"].as< unsigned int >(); int minImageThreshold = vm["minImageThreshold"].as< int >(); int maxImageThreshold = vm["maxImageThreshold"].as< int >(); double h = 1.0; std::string export_obj_filename; std::string export_dat_filename; if( enable_obj ) { export_obj_filename = vm["exportOBJ"].as< std::string >(); if( export_obj_filename.find(".obj") == std::string::npos ) { std::ostringstream oss; oss << export_obj_filename << ".obj" << std::endl; export_obj_filename = oss.str(); } } if( enable_dat ) { export_dat_filename = vm["exportDAT"].as<std::string>(); } double re_convolution_kernel = vm["radius"].as< double >(); std::vector< double > aGridSizeReSample; if( vm.count( "imageScale" )) { std::vector< double> vectScale = vm["imageScale"].as<std::vector<double > >(); if( vectScale.size() != 3 ) { trace.error() << "The grid size should contains 3 elements" << std::endl; return 0; } else { aGridSizeReSample.push_back(1.0/vectScale.at(0)); aGridSizeReSample.push_back(1.0/vectScale.at(1)); aGridSizeReSample.push_back(1.0/vectScale.at(2)); } } else { aGridSizeReSample.push_back(1.0); aGridSizeReSample.push_back(1.0); aGridSizeReSample.push_back(1.0); } // Construction of the shape from vol file typedef Z3i::Space::RealPoint RealPoint; typedef Z3i::Point Point; typedef ImageSelector< Z3i::Domain, int>::Type Image; typedef DGtal::functors::BasicDomainSubSampler< HyperRectDomain<SpaceND<3, int> >, DGtal::int32_t, double > ReSampler; typedef DGtal::ConstImageAdapter<Image, Image::Domain, ReSampler, Image::Value, DGtal::functors::Identity > SamplerImageAdapter; typedef IntervalForegroundPredicate< SamplerImageAdapter > ImagePredicate; typedef BinaryPointPredicate<DomainPredicate<Image::Domain>, ImagePredicate, AndBoolFct2 > Predicate; typedef Z3i::KSpace KSpace; typedef KSpace::SCell SCell; typedef KSpace::Cell Cell; trace.beginBlock("Loading the file"); std::string filename = vm["input"].as< std::string >(); Image image = GenericReader<Image>::import( filename ); PointVector<3,int> shiftVector3D( 0 ,0, 0 ); DGtal::functors::BasicDomainSubSampler< HyperRectDomain< SpaceND< 3, int > >, DGtal::int32_t, double > reSampler(image.domain(), aGridSizeReSample, shiftVector3D); const functors::Identity identityFunctor{}; SamplerImageAdapter sampledImage ( image, reSampler.getSubSampledDomain(), reSampler, identityFunctor ); ImagePredicate predicateIMG = ImagePredicate( sampledImage, minImageThreshold, maxImageThreshold ); DomainPredicate<Z3i::Domain> domainPredicate( sampledImage.domain() ); AndBoolFct2 andF; Predicate predicate(domainPredicate, predicateIMG, andF ); Z3i::Domain domain = sampledImage.domain(); Z3i::KSpace K; bool space_ok = K.init( domain.lowerBound()-Z3i::Domain::Point::diagonal(), domain.upperBound()+Z3i::Domain::Point::diagonal(), true ); if (!space_ok) { trace.error() << "Error in the Khalimsky space construction."<<std::endl; return 2; } CanonicSCellEmbedder< KSpace > embedder( K ); SurfelAdjacency< Z3i::KSpace::dimension > Sadj( true ); trace.endBlock(); // Viewer settings // Extraction of components typedef KSpace::SurfelSet SurfelSet; typedef SetOfSurfels< KSpace, SurfelSet > MySetOfSurfels; typedef DigitalSurface< MySetOfSurfels > MyDigitalSurface; trace.beginBlock("Extracting surfaces"); std::vector< std::vector<SCell > > vectConnectedSCell; Surfaces<KSpace>::extractAllConnectedSCell(vectConnectedSCell,K, Sadj, predicate, false); std::ofstream outDat; if( enable_dat ) { trace.info() << "Exporting curvature as dat file: "<< export_dat_filename <<std::endl; outDat.open( export_dat_filename.c_str() ); outDat << "# data exported from 3dCurvatureViewer implementing the II curvature estimator (Coeurjolly, D.; Lachaud, J.O; Levallois, J., (2013). Integral based Curvature" << " Estimators in Digital Geometry. DGCI 2013.) " << std::endl; outDat << "# format: surfel coordinates (in Khalimsky space) curvature: "<< mode << std::endl; } trace.info()<<"Number of components= "<<vectConnectedSCell.size()<<std::endl; trace.endBlock(); if( vectConnectedSCell.size() == 0 ) { trace.error()<< "No surface component exists. Please check the vol file threshold parameter."; trace.info()<<std::endl; exit(2); } #ifdef WITH_VISU3D_QGLVIEWER QApplication application( argc, argv ); typedef Viewer3D<Z3i::Space, Z3i::KSpace> Viewer; #endif typedef Board3D<Z3i::Space, Z3i::KSpace> Board; #ifdef WITH_VISU3D_QGLVIEWER Viewer viewer( K ); #endif Board board( K ); #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer.show(); } #endif for( unsigned int i = 0; i<vectConnectedSCell.size(); ++i ) { if( vectConnectedSCell[i].size() <= threshold ) { continue; } MySetOfSurfels aSet(K, Sadj); for( std::vector<SCell>::const_iterator it = vectConnectedSCell.at(i).begin(); it != vectConnectedSCell.at(i).end(); ++it ) { aSet.surfelSet().insert( *it); } MyDigitalSurface digSurf( aSet ); typedef DepthFirstVisitor<MyDigitalSurface> Visitor; typedef GraphVisitorRange< Visitor > VisitorRange; typedef VisitorRange::ConstIterator SurfelConstIterator; VisitorRange range( new Visitor( digSurf, *digSurf.begin() ) ); SurfelConstIterator abegin = range.begin(); SurfelConstIterator aend = range.end(); VisitorRange range2( new Visitor( digSurf, *digSurf.begin() ) ); SurfelConstIterator abegin2 = range2.begin(); trace.beginBlock("Curvature computation on a component"); if( ( mode.compare("gaussian") == 0 ) || ( mode.compare("mean") == 0 ) || ( mode.compare("k1") == 0 ) || ( mode.compare("k2") == 0 )) { typedef double Quantity; std::vector< Quantity > results; std::back_insert_iterator< std::vector< Quantity > > resultsIterator( results ); if ( mode.compare("mean") == 0 ) { typedef functors::IIMeanCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantVolumeEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if ( mode.compare("gaussian") == 0 ) { typedef functors::IIGaussianCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if ( mode.compare("k1") == 0 ) { typedef functors::IIFirstPrincipalCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if ( mode.compare("k2") == 0 ) { typedef functors::IISecondPrincipalCurvature3DFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } trace.endBlock(); // Drawing results trace.beginBlock("Visualisation"); Quantity min = results[ 0 ]; Quantity max = results[ 0 ]; for ( unsigned int i = 1; i < results.size(); ++i ) { if ( results[ i ] < min ) { min = results[ i ]; } else if ( results[ i ] > max ) { max = results[ i ]; } } trace.info() << "Max value= "<<max<<" min value= "<<min<<std::endl; ASSERT( min <= max ); typedef GradientColorMap< Quantity > Gradient; Gradient cmap_grad( min, (max==min)? max+1: max ); cmap_grad.addColor( Color( 50, 50, 255 ) ); cmap_grad.addColor( Color( 255, 0, 0 ) ); cmap_grad.addColor( Color( 255, 255, 10 ) ); #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << SetMode3D((*abegin2).className(), "Basic" ); } #endif if( enable_obj ) { board << SetMode3D((K.unsigns(*abegin2)).className(), "Basic" ); } for ( unsigned int i = 0; i < results.size(); ++i ) { #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << CustomColors3D( Color::Black, cmap_grad( results[ i ] )); viewer << *abegin2; } #endif if( enable_obj ) { board << CustomColors3D( Color::Black, cmap_grad( results[ i ] )); board << K.unsigns(*abegin2); } if( enable_dat ) { Point kCoords = K.uKCoords(K.unsigns(*abegin2)); outDat << kCoords[0] << " " << kCoords[1] << " " << kCoords[2] << " " << results[i] << std::endl; } ++abegin2; } } else { typedef Z3i::Space::RealVector Quantity; std::vector< Quantity > results; std::back_insert_iterator< std::vector< Quantity > > resultsIterator( results ); if( mode.compare("prindir1") == 0 ) { typedef functors::IIFirstPrincipalDirectionFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if( mode.compare("prindir2") == 0 ) { typedef functors::IISecondPrincipalDirectionFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } else if( mode.compare("normal") == 0 ) { typedef functors::IINormalDirectionFunctor<Z3i::Space> MyIICurvatureFunctor; typedef IntegralInvariantCovarianceEstimator<Z3i::KSpace, Predicate, MyIICurvatureFunctor> MyIIEstimator; MyIICurvatureFunctor functor; functor.init( h, re_convolution_kernel ); MyIIEstimator estimator( functor ); estimator.attach( K, predicate ); estimator.setParams( re_convolution_kernel/h ); estimator.init( h, abegin, aend ); estimator.eval( abegin, aend, resultsIterator ); } ///Visualizaton / export #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << SetMode3D(K.uCell( K.sKCoords(*abegin2) ).className(), "Basic" ); } #endif if( enable_obj ) { board << SetMode3D(K.uCell( K.sKCoords(*abegin2) ).className(), "Basic" ); } for ( unsigned int i = 0; i < results.size(); ++i ) { DGtal::Dimension kDim = K.sOrthDir( *abegin2 ); SCell outer = K.sIndirectIncident( *abegin2, kDim); if ( predicate(embedder(outer)) ) { outer = K.sDirectIncident( *abegin2, kDim); } Cell unsignedSurfel = K.uCell( K.sKCoords(*abegin2) ); #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << CustomColors3D( DGtal::Color(255,255,255,255), DGtal::Color(255,255,255,255)) << unsignedSurfel; } #endif if( enable_obj ) { board << CustomColors3D( DGtal::Color(255,255,255,255), DGtal::Color(255,255,255,255)) << unsignedSurfel; } if( enable_dat ) { Point kCoords = K.uKCoords(K.unsigns(*abegin2)); outDat << kCoords[0] << " " << kCoords[1] << " " << kCoords[2] << " " << results[i][0] << " " << results[i][1] << " " << results[i][2] << std::endl; } RealPoint center = embedder( outer ); #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { if( mode.compare("prindir1") == 0 ) { viewer.setLineColor( AXIS_COLOR_BLUE ); } else if( mode.compare("prindir2") == 0 ) { viewer.setLineColor( AXIS_COLOR_RED ); } else if( mode.compare("normal") == 0 ) { viewer.setLineColor( AXIS_COLOR_GREEN ); } viewer.addLine ( RealPoint( center[0] - 0.5 * results[i][0], center[1] - 0.5 * results[i][1], center[2] - 0.5 * results[i][2] ), RealPoint( center[0] + 0.5 * results[i][0], center[1] + 0.5 * results[i][1], center[2] + 0.5 * results[i][2] ), AXIS_LINESIZE ); } #endif if( enable_obj ) { if( mode.compare("prindir1") == 0 ) { board.setFillColor( AXIS_COLOR_BLUE ); } else if( mode.compare("prindir2") == 0 ) { board.setFillColor( AXIS_COLOR_RED ); } else if( mode.compare("normal") == 0 ) { board.setFillColor( AXIS_COLOR_GREEN ); } board.addCylinder ( RealPoint( center[0] - 0.5 * results[i][0], center[1] - 0.5 * results[i][1], center[2] - 0.5 * results[i][2]), RealPoint( center[0] + 0.5 * results[i][0], center[1] + 0.5 * results[i][1], center[2] + 0.5 * results[i][2]), 0.2 ); } ++abegin2; } } trace.endBlock(); } #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { viewer << Viewer3D<>::updateDisplay; } #endif if( enable_obj ) { trace.info()<< "Exporting object: " << export_obj_filename << " ..."; board.saveOBJ(export_obj_filename,normalization); trace.info() << "[done]" << std::endl; } if( enable_dat ) { outDat.close(); } #ifdef WITH_VISU3D_QGLVIEWER if( enable_visu ) { return application.exec(); } #endif return 0; }
int main( int argc, char** argv ) { typedef PointVector<4, double> Point4D; typedef PointVector<1, int> Point1D; // parse command line ---------------------------------------------- po::options_description general_opt("Allowed options are: "); general_opt.add_options() ("help,h", "display this message") ("input,i", po::value<std::string>(), "input file: sdp (sequence of discrete points with attribute)" ) ("noWindows,n", "Don't display Viewer windows." ) ("doSnapShotAndExit,d", po::value<std::string>(), "save display snapshot into file." ) ("fixMaxColorValue", po::value<double>(), "fix the maximal color value for the scale error display (else the scale is set from the maximal value)" ) ("fixMinColorValue", po::value<double>(), "fix the minimal color value for the scale error display (else the scale is set from the minimal value)" ) ("labelIndex", po::value<unsigned int>(), "set the index of the label (by default set to 3) " ) ("SDPindex", po::value<std::vector <unsigned int> >()->multitoken(), "specify the sdp index (by default 0,1,2)."); bool parseOK=true; bool cannotStart= false; po::variables_map vm; try{ po::store(po::parse_command_line(argc, argv, general_opt), vm); }catch(const std::exception& ex){ parseOK=false; trace.error()<< "Error checking program options: "<< ex.what()<< endl; } po::notify(vm); if(parseOK && ! vm.count("input")) { trace.error() << " The input file name was not defined" << endl; cannotStart = true; } if( !parseOK || cannotStart || vm.count("help")||argc<=1) { trace.info() << "Usage: " << argv[0] << " [input]\n" << "Display surfel data from SDP file with color attributes given as scalar interpreted as color." << general_opt << "\n"; return 0; } Z3i::KSpace K; string inputFilename = vm["input"].as<std::string>(); std::vector<Point4D> surfelAndScalarInput; if(vm.count("SDPindex")) { std::vector<unsigned int > vectIndex = vm["SDPindex"].as<std::vector<unsigned int > >(); if(vectIndex.size()!=4){ trace.error() << "you need to specify the three indexes of vertex." << std::endl; return 0; } surfelAndScalarInput = PointListReader<Point4D>::getPointsFromFile(inputFilename, vectIndex); }else{ surfelAndScalarInput = PointListReader<Point4D>::getPointsFromFile(inputFilename); } Point4D ptLower = surfelAndScalarInput.at(0); Point4D ptUpper = surfelAndScalarInput.at(0); getBoundingUpperAndLowerPoint(surfelAndScalarInput, ptLower, ptUpper); K.init(Z3i::Point(2*ptLower[0]+1, 2*ptLower[1]+1, 2*ptLower[2]+1), Z3i::Point(2*ptUpper[0]+1, 2*ptUpper[1]+1, 2*ptUpper[2]+1), true); std::vector<Cell> vectSurfelsInput; // Construction of the set of surfels for(unsigned int i =0; i<surfelAndScalarInput.size(); i++){ Point4D pt4d = surfelAndScalarInput.at(i); Cell c = K.uCell(Z3i::Point(pt4d[0], pt4d[1], pt4d[2])); vectSurfelsInput.push_back(c); } CanonicCellEmbedder<KSpace> embeder(K); std::vector<unsigned int> vectIndexMinToReference; //------------------------- // Displaying input with color given from scalar values QApplication application(argc,argv); typedef ViewerSnap<> Viewer; Viewer viewer(K, vm.count("doSnapShotAndExit")); if(vm.count("doSnapShotAndExit")){ viewer.setSnapshotFileName(QString(vm["doSnapShotAndExit"].as<std::string>().c_str())); } viewer.setWindowTitle("3dCompSurfel Viewer"); viewer.show(); viewer.restoreStateFromFile(); double minScalarVal=surfelAndScalarInput.at(0)[3]; double maxScalarVal=surfelAndScalarInput.at(0)[3]; for(unsigned int i=1; i <surfelAndScalarInput.size(); i++){ double scalVal = surfelAndScalarInput.at(i)[3]; if(scalVal < minScalarVal){ minScalarVal = scalVal; } if(scalVal > maxScalarVal){ maxScalarVal = scalVal; } } if(vm.count("fixMaxColorValue")){ maxScalarVal = vm["fixMaxColorValue"].as<double>(); } if(vm.count("fixMinColorValue")){ minScalarVal = vm["fixMinColorValue"].as<double>(); } GradientColorMap<double> gradientColorMap( minScalarVal, maxScalarVal ); gradientColorMap.addColor( Color(255,0,0,100 ) ); gradientColorMap.addColor( Color(0,255,0,100 ) ); gradientColorMap.addColor( Color(0,0,255,100 ) ); bool useGrad = minScalarVal!=maxScalarVal; viewer << SetMode3D(vectSurfelsInput.at(0).className(), "Basic"); for(unsigned int i=0; i <surfelAndScalarInput.size(); i++){ double valInput = surfelAndScalarInput.at(i)[3]; if(useGrad){ viewer.setFillColor(gradientColorMap(valInput)); }else{ viewer.setFillColor(Color::White); } viewer << vectSurfelsInput.at(i); } viewer << Viewer::updateDisplay; if(vm.count("doSnapShotAndExit")){ // Appy cleaning just save the last snap std::string name = vm["doSnapShotAndExit"].as<std::string>(); std::string extension = name.substr(name.find_last_of(".") + 1); std::string basename = name.substr(0, name.find_last_of(".")); for(int i=0; i< viewer.snapshotCounter()-1; i++){ std::stringstream s; s << basename << "-"<< setfill('0') << setw(4)<< i << "." << extension; trace.info() << "erase temp file: " << s.str() << std::endl; remove(s.str().c_str()); } std::stringstream s; s << basename << "-"<< setfill('0') << setw(4)<< viewer.snapshotCounter()-1 << "." << extension; rename(s.str().c_str(), name.c_str()); return 0; } if(vm.count("noWindows")){ return 0; }else{ return application.exec(); } }