32 #include "DGtal/base/Common.h"    34 #include "DGtal/io/Display3D.h"    35 #include "DGtal/io/viewers/Viewer3D.h"    36 #include "DGtal/io/readers/MeshReader.h"    37 #include "DGtal/helpers/StdDefs.h"    38 #include "DGtal/io/readers/PointListReader.h"    40 #include <boost/program_options/options_description.hpp>    41 #include <boost/program_options/parsers.hpp>    42 #include <boost/program_options/variables_map.hpp>    46 using namespace DGtal;
   117 class CustomViewer3D: 
public Viewer3D<>
   124     Viewer3D<>::setKeyDescription ( Qt::Key_I, 
"Display mesh informations about #faces, #vertices" );
   125     Viewer3D<>::setGLDoubleRenderingMode(
false);
   127   virtual void keyPressEvent(QKeyEvent *e){
   128     bool handled = 
false;
   129     if( e->key() == Qt::Key_I)
   132       myIsDisplayingInfoMode = !myIsDisplayingInfoMode;
   133       std::stringstream sstring;
   134       Viewer3D<>::displayMessage(QString(myIsDisplayingInfoMode ?
   135                                                       myInfoDisplay.c_str() : 
" "), 1000000);
   136       Viewer3D<>::updateGL();
   140         Viewer3D<>::keyPressEvent(e);        
   145   std::string myInfoDisplay = 
"No information loaded...";
   146   bool myIsDisplayingInfoMode = 
false;
   153 namespace po = boost::program_options;
   155 int main( 
int argc, 
char** argv )
   159   po::options_description general_opt(
"Allowed options are: ");
   160   general_opt.add_options()
   161   (
"help,h", 
"display this message")
   162   (
"input,i", po::value<std::vector<string> >()->multitoken(), 
"off files (.off), or OFS file (.ofs) " )
   163   (
"scaleX,x",  po::value<float>()->default_value(1.0), 
"set the scale value in the X direction (default 1.0)" )
   164   (
"scaleY,y",  po::value<float>()->default_value(1.0), 
"set the scale value in the Y direction (default 1.0)" )
   165   (
"scaleZ,z",  po:: value<float>()->default_value(1.0), 
"set the scale value in the Z direction (default 1.0)")
   166   (
"minLineWidth,w",  po:: value<float>()->default_value(1.5), 
"set the min line width of the mesh faces (default 1.5)")
   167   (
"customColorMesh",po::value<std::vector<unsigned int> >()->multitoken(), 
"set the R, G, B, A components of the colors of the mesh faces and eventually the color R, G, B, A of the mesh edge lines (set by default to black). " )
   168   (
"customColorSDP",po::value<std::vector<unsigned int> >()->multitoken(), 
"set the R, G, B, A components of the colors of  the sdp view" )
   169   (
"displayVectorField,f",po::value<std::string>(),  
"display a vector field from a simple sdp file (two points per line)" )
   170   (
"vectorFieldIndex",po::value<std::vector<unsigned int> >()->multitoken(), 
"specify special indices for the two point coordinates (instead usinf the default indices: 0 1, 2, 3, 4, 5)" )
   171   (
"customLineColor",po::value<std::vector<unsigned int> >()->multitoken(), 
"set the R, G, B components of the colors of the lines displayed from the --displayVectorField option (red by default). " )
   172   (
"displaySDP,s", po::value<std::string>(), 
"Add the display of a set of discrete points as ball of radius 0.5.")
   173   (
"SDPradius", po::value<double>()->default_value(0.5), 
"change the ball radius to display a set of discrete points (used with displaySDP option)")
   174   (
"invertNormal,n", 
"invert face normal vectors." )
   175   (
"drawVertex,v", 
"draw the vertex of the mesh" );
   178   po::variables_map vm;
   180     po::store(po::parse_command_line(argc, argv, general_opt), vm);
   181   }
catch(
const std::exception& ex){
   183     trace.info()<< 
"Error checking program options: "<< ex.what()<< endl;
   186   if( !parseOK || vm.count(
"help")||argc<=1)
   188     std::cout << 
"Usage: " << argv[0] << 
" [input]\n"   189     << 
"Display OFF mesh file by using QGLviewer"   190     << general_opt << 
"\n";
   194   if(! vm.count(
"input"))
   196     trace.error() << 
" The file name was defined" << endl;
   202   std::vector<std::string> inputFilenameVect = vm[
"input"].as<std::vector<std::string > >();
   203   float sx = vm[
"scaleX"].as<
float>();
   204   float sy = vm[
"scaleY"].as<
float>();
   205   float sz = vm[
"scaleZ"].as<
float>();
   207   unsigned int  meshColorR = 240;
   208   unsigned int  meshColorG = 240;
   209   unsigned int  meshColorB = 240;
   210   unsigned int  meshColorA = 255;
   212   unsigned int  meshColorRLine = 0;
   213   unsigned int  meshColorGLine = 0;
   214   unsigned int  meshColorBLine = 0;
   215   unsigned int  meshColorALine = 255;
   218   unsigned int  sdpColorR = 240;
   219   unsigned int  sdpColorG = 240;
   220   unsigned int  sdpColorB = 240;
   221   unsigned int  sdpColorA = 255;
   224   bool displayVectorField = vm.count(
"displayVectorField");
   225   std::vector<unsigned int> vectFieldIndices = {0,1,2,3,4,5};
   227   if (displayVectorField) {
   228     if(vm.count(
"vectorFieldIndex")){
   229       vectFieldIndices = vm[
"vectorFieldIndex"].as<std::vector<unsigned int> >();
   230       if (vectFieldIndices.size() != 6) {
   231         trace.warning() << 
"you should specify indices for each of the 6 fields of the two coordinates." << std::endl;
   232         vectFieldIndices = {0,1,2,3,4,5};
   237   float lineWidth = vm[
"minLineWidth"].as<
float>();
   239   DGtal::Color vFieldLineColor = DGtal::Color::Red;
   240   if(vm.count(
"customLineColor")){
   241     std::vector<unsigned int > vectCol = vm[
"customLineColor"].as<std::vector<unsigned int> >();
   242     if(vectCol.size()!=3 ){
   243       trace.error() << 
"colors specification should contain R,G,B values (using default red)."<< std::endl;
   245     vFieldLineColor.setRGBi(vectCol[0], vectCol[1], vectCol[2], 255);
   248   if(vm.count(
"customColorMesh")){
   249     std::vector<unsigned int > vectCol = vm[
"customColorMesh"].as<std::vector<unsigned int> >();
   250     if(vectCol.size()!=4 && vectCol.size()!=8 ){
   251       trace.error() << 
"colors specification should contain R,G,B and Alpha values"<< std::endl;
   253     meshColorR = vectCol[0];
   254     meshColorG = vectCol[1];
   255     meshColorB = vectCol[2];
   256     meshColorA = vectCol[3];
   257     if(vectCol.size() == 8){
   258       meshColorRLine = vectCol[4];
   259       meshColorGLine = vectCol[5];
   260       meshColorBLine = vectCol[6];
   261       meshColorALine = vectCol[7];
   266   if(vm.count(
"customColorSDP")){
   267     std::vector<unsigned int > vectCol = vm[
"customColorSDP"].as<std::vector<unsigned int> >();
   268     if(vectCol.size()!=4){
   269       trace.error() << 
"colors specification should contain R,G,B and Alpha values"<< std::endl;
   271     sdpColorR = vectCol[0];
   272     sdpColorG = vectCol[1];
   273     sdpColorB = vectCol[2];
   274     sdpColorA = vectCol[3];
   279   QApplication application(argc,argv);
   280   CustomViewer3D viewer;
   281   std::stringstream title;
   282   title  << 
"Simple Mesh Viewer: " << inputFilenameVect[0];
   283   viewer.setWindowTitle(title.str().c_str());
   285   viewer.myGLLineMinWidth = lineWidth;
   286   viewer.setGLScale(sx, sy, sz);
   287   bool invertNormal= vm.count(
"invertNormal");
   290   double ballRadius = vm[
"SDPradius"].as<
double>();
   292   trace.info() << 
"Importing mesh... ";
   294   std::vector<Mesh<DGtal::Z3i::RealPoint> >  vectMesh;
   295   for(
unsigned int i = 0; i< inputFilenameVect.size(); i++){
   296     Mesh<DGtal::Z3i::RealPoint> aMesh(!vm.count(
"customColorMesh"));
   297     aMesh << inputFilenameVect[i];
   298     vectMesh.push_back(aMesh);
   302   bool import = vectMesh.size()==inputFilenameVect.size();
   304     trace.info() << 
"File import failed. " << std::endl;
   308   trace.info() << 
"[done]. "<< std::endl;
   309   if(vm.count(
"displaySDP")){
   310     std::string filenameSDP = vm[
"displaySDP"].as<std::string>();
   311     vector<Z3i::RealPoint> vectPoints;
   312     vectPoints = PointListReader<Z3i::RealPoint>::getPointsFromFile(filenameSDP);
   313     viewer << CustomColors3D(Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA),
   314                              Color(sdpColorR, sdpColorG, sdpColorB, sdpColorA));
   315     for(
unsigned int i=0;i< vectPoints.size(); i++){
   316       viewer.addBall(vectPoints.at(i), ballRadius);
   320     for(
unsigned int i=0; i<vectMesh.size(); i++){
   321       vectMesh[i].invertVertexFaceOrder();
   325   viewer << CustomColors3D(Color(meshColorRLine, meshColorGLine, meshColorBLine, meshColorALine),
   326                            Color(meshColorR, meshColorG, meshColorB, meshColorA));
   327   for(
unsigned int i=0; i<vectMesh.size(); i++){
   328     viewer << vectMesh[i];
   331   if(vm.count(
"drawVertex")){
   332     for(
unsigned int i=0; i<vectMesh.size(); i++){
   333       for( Mesh<DGtal::Z3i::RealPoint>::VertexStorage::const_iterator it = vectMesh[i].vertexBegin();
   334           it!=vectMesh[i].vertexEnd(); ++it){
   335         DGtal::Z3i::Point pt;
   336         pt[0]=(*it)[0]; pt[1]=(*it)[1]; pt[2]=(*it)[2];
   343   if (displayVectorField) {
   344     std::vector<unsigned int > vectFieldIndices1 = {vectFieldIndices[0],vectFieldIndices[1], vectFieldIndices[2]};
   345     std::vector<unsigned int > vectFieldIndices2 = {vectFieldIndices[3],vectFieldIndices[4], vectFieldIndices[5]};
   347     std::vector<DGtal::Z3i::RealPoint> vectPt1 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(vm[
"displayVectorField"].as<std::string>(), vectFieldIndices1);
   348     std::vector<DGtal::Z3i::RealPoint> vectPt2 = PointListReader<DGtal::Z3i::RealPoint>::getPointsFromFile(vm[
"displayVectorField"].as<std::string>(), vectFieldIndices2);
   349     viewer.createNewLineList();
   350     for (
unsigned int i = 0; i < vectPt1.size(); i++) {
   352       viewer.setLineColor(vFieldLineColor);
   353       viewer.addLine(vectPt1[i], vectPt2[i]);
   356   unsigned int nbVertex = 0;
   357   unsigned int nbFaces = 0;
   358   for(
auto const &m:  vectMesh)
   360       nbVertex += m.nbVertex();
   361       nbFaces +=m.nbFaces();
   364   ss << 
"# faces: " << std::fixed << nbFaces << 
"    #vertex: " <<  nbVertex;
   365   viewer.myInfoDisplay = ss.str();
   366   viewer  << CustomViewer3D::updateDisplay;
   367   return application.exec();