2 * This program is free software: you can redistribute it and/or modify
 
    3 * it under the terms of the GNU Lesser General Public License as
 
    4 * published by the Free Software Foundation, either version 3 of the
 
    5 * License, or (at your option) any later version.
 
    7 * This program is distributed in the hope that it will be useful,
 
    8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
    9 * MERCHANTABILITY or FITNESSpace FOR A PARTICULAR PURPOSE. See the
 
   10 * GNU General Public License for more details.
 
   12 * You should have received a copy of the GNU General Public License
 
   13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 
   19 * @author Bertrand Kerautret (\c kerautre@loria.fr )
 
   20 * LORIA (CNRS, UMR 7503), University of Nancy, France
 
   24 * Implementation of inline methods defined in Viewer3D.h
 
   26 * This file is part of the DGtal library.
 
   29///////////////////////////////////////////////////////////////////////////////
 
   30// IMPLEMENTATION of inline methods.
 
   31///////////////////////////////////////////////////////////////////////////////
 
   33//////////////////////////////////////////////////////////////////////////////
 
   38#include "DGtal/io/viewers/windows/GL/glext.h"
 
   41#include "DGtal/io/viewers/Viewer3D.h"
 
   52#include "DGtal/io/CDrawableWithDisplay3D.h"
 
   53#include "DGtal/io/viewers/CDrawableWithViewer3D.h"
 
   54#include "DGtal/io/viewers/Viewer3DFactory.h"
 
   55#include "QGLViewer/manipulatedFrame.h"
 
   56#include "QGLViewer/manipulatedCameraFrame.h"
 
   57//////////////////////////////////////////////////////////////////////////////
 
   59using namespace qglviewer;
 
   61///////////////////////////////////////////////////////////////////////////////
 
   62// Implementation of inline methods //
 
   64template <typename TSpace, typename TKSpace>
 
   65inline void DGtal::Viewer3D<TSpace, TKSpace>::rotateDomain(
 
   66Image2DDomainD3D & anDom, double angleRotation, ImageDirection rotationDir )
 
   68  DGtal::PointVector<3, int> pt;
 
   69  pt[0] = (int) (anDom.point1[0]+anDom.point2[0]+anDom.point3[0]+anDom.point4[0])/4.0;
 
   70  pt[1] = (int) (anDom.point1[1]+anDom.point2[1]+anDom.point3[1]+anDom.point4[1])/4.0;
 
   71  pt[2] = (int) (anDom.point1[2]+anDom.point2[2]+anDom.point3[2]+anDom.point4[2])/4.0;
 
   72  rotateImageVertex(anDom, angleRotation, rotationDir);
 
   74  std::vector<typename DGtal::Display3D<TSpace, TKSpace>::LineD3D> & aVectLine =
 
   75  Viewer3D<TSpace, TKSpace>::myLineSetList.at( anDom.myLineSetIndex );
 
   76  for(unsigned int i = 0; i< aVectLine.size();i++){
 
   77    typename DGtal::Display3D<TSpace, TKSpace>::LineD3D & aLine =
 
   79    rotateLineD3D(aLine, pt, angleRotation, rotationDir );
 
   84template <typename TSpace, typename TKSpace>
 
   85template <typename TValues>
 
   86inline void DGtal::Viewer3D<TSpace, TKSpace>::rotatePoint(
 
   87TValues & x, TValues & y, TValues & z, double cx, double cy, double cz,
 
   88double angleRotation, ImageDirection rotationDir )
 
   90  double dx = x-cx; double dy = y-cy; double dz = z-cz;
 
   91  if(rotationDir  == zDirection){
 
   92    x = cx+dx*cos(angleRotation)-dy*sin(angleRotation);
 
   93    y = cy+dx*sin(angleRotation)+dy*cos(angleRotation);
 
   95  if(rotationDir  == yDirection){
 
   96    x = cx+dx*cos(angleRotation)-dz*sin(angleRotation);
 
   97    z = cz+dx*sin(angleRotation)+dz*cos(angleRotation);
 
   99  if(rotationDir  == xDirection){
 
  100    y = cy+dy*cos(angleRotation)-dz*sin(angleRotation);
 
  101    z = cz+dy*sin(angleRotation)+dz*cos(angleRotation);
 
  105template <typename TSpace, typename TKSpace>
 
  106template <typename TContainer>
 
  107inline void DGtal::Viewer3D<TSpace, TKSpace>::rotateLineD3D(
 
  108typename DGtal::Display3D<TSpace, TKSpace>::LineD3D & aLine,
 
  109DGtal::PointVector<3, int, TContainer> pt, double angleRotation,
 
  110ImageDirection dirRotation )
 
  112  double dx1 = aLine.point1[0] - pt[0]; double dy1 = aLine.point1[1] - pt[1]; double dz1 = aLine.point1[2] - pt[2];
 
  113  double dx2 = aLine.point2[0] - pt[0]; double dy2 = aLine.point2[1] - pt[1]; double dz2 = aLine.point2[2] - pt[2];
 
  114  if(dirRotation==zDirection){
 
  115     aLine.point1[0]=pt[0]+dx1*std::cos(angleRotation)-dy1*std::sin(angleRotation);
 
  116     aLine.point1[1]=pt[1]+dx1*std::sin(angleRotation)+dy1*std::cos(angleRotation);
 
  118     aLine.point2[0]=pt[0]+dx2*std::cos(angleRotation)-dy2*std::sin(angleRotation);
 
  119     aLine.point2[1]=pt[1]+dx2*std::sin(angleRotation)+dy2*std::cos(angleRotation);
 
  121  }else if(dirRotation==xDirection){
 
  122    aLine.point1[1]=pt[1]+dy1*std::cos(angleRotation)-dz1*std::sin(angleRotation);
 
  123    aLine.point1[2]=pt[2]+dy1*std::sin(angleRotation)+dz1*std::cos(angleRotation);
 
  125    aLine.point2[1]=pt[1]+dy2*std::cos(angleRotation)-dz2*std::sin(angleRotation);
 
  126    aLine.point2[2]=pt[2]+dy2*std::sin(angleRotation)+dz2*std::cos(angleRotation);
 
  127  }else  if(dirRotation==yDirection){
 
  128    aLine.point1[0]=pt[0]+dx1*std::cos(angleRotation)-dz1*std::sin(angleRotation);
 
  129    aLine.point1[2]=pt[2]+dx1*std::sin(angleRotation)+dz1*std::cos(angleRotation);
 
  131    aLine.point2[0]=pt[0]+dx2*std::cos(angleRotation)-dz2*std::sin(angleRotation);
 
  132    aLine.point2[2]=pt[2]+dx2*std::sin(angleRotation)+dz2*std::cos(angleRotation);
 
  134    trace.error() << "No direction!!"<< std::endl;
 
  139template <typename TSpace, typename TKSpace>
 
  140inline unsigned int DGtal::Viewer3D<TSpace, TKSpace>::getCurrentDomainNumber()
 
  142  return static_cast<unsigned int>(myImageDomainList.size());
 
  145template <typename TSpace, typename TKSpace>
 
  146inline unsigned int DGtal::Viewer3D<TSpace, TKSpace>::getCurrentGLImageNumber()
 
  148  return static_cast<unsigned int>(myGSImageList.size());
 
  151template <typename TSpace, typename TKSpace>
 
  152inline void DGtal::Viewer3D<TSpace, TKSpace>::addTextureImage(
 
  153const typename Viewer3D<TSpace, TKSpace>::TextureImage & image )
 
  155  myGSImageList.push_back(image);
 
  156  Display3D<TSpace, TKSpace>::updateBoundingBox( image.point1 );
 
  157  Display3D<TSpace, TKSpace>::updateBoundingBox( image.point2 );
 
  158  Display3D<TSpace, TKSpace>::updateBoundingBox( image.point3 );
 
  159  Display3D<TSpace, TKSpace>::updateBoundingBox( image.point4 );
 
  162template <typename TSpace, typename TKSpace>
 
  163template <typename TImageType, typename TFunctor>
 
  164inline void DGtal::Viewer3D<TSpace, TKSpace>::updateTextureImage(
 
  165unsigned int imageIndex, const TImageType & image, const TFunctor & aFunctor,
 
  166double xTranslation, double yTranslation, double zTranslation,
 
  167double rotationAngle, ImageDirection rotationDir )
 
  169  BOOST_CONCEPT_ASSERT(( concepts::CConstImage < TImageType > ));
 
  170  assert ( imageIndex< myGSImageList.size());
 
  171  typename Viewer3D<TSpace, TKSpace>::TextureImage & anImage =
 
  172  myGSImageList.at( imageIndex );
 
  173  Display::updateBoundingBox(RealPoint(anImage.point1[0]+xTranslation,
 
  174                                                   anImage.point1[1]+yTranslation,
 
  175                                                   anImage.point1[2]+zTranslation));
 
  176  Display::updateBoundingBox(RealPoint(anImage.point2[0]+xTranslation,
 
  177                                                   anImage.point2[1]+yTranslation,
 
  178                                                   anImage.point2[2]+zTranslation));
 
  179  Display::updateBoundingBox(RealPoint(anImage.point3[0]+xTranslation,
 
  180                                                   anImage.point3[1]+yTranslation,
 
  181                                                   anImage.point3[2]+zTranslation));
 
  182  Display::updateBoundingBox(RealPoint(anImage.point4[0]+xTranslation,
 
  183                                                   anImage.point4[1]+yTranslation,
 
  184                                                   anImage.point4[2]+zTranslation));
 
  185  anImage.updateImageDataAndParam(image, aFunctor, xTranslation, yTranslation, zTranslation);
 
  186  if(anImage.myDrawDomain)
 
  188      *this << DGtal::Translate2DDomain(anImage.myIndexDomain, xTranslation, yTranslation, zTranslation);
 
  191  if(rotationAngle!=0.0){
 
  192    rotateDomain(myImageDomainList.at(anImage.myIndexDomain), rotationAngle, rotationDir);
 
  193    rotateImageVertex(anImage, rotationAngle, rotationDir);
 
  197template <typename TSpace, typename TKSpace>
 
  198inline void DGtal::Viewer3D<TSpace, TKSpace>::updateOrientationTextureImage(
 
  199unsigned int imageIndex, double xPosition, double yPosition, double zPosition,
 
  200ImageDirection newDirection )
 
  202  assert ( imageIndex< myGSImageList.size());
 
  203  typename Viewer3D<TSpace, TKSpace>::TextureImage & anImage =
 
  204  myGSImageList.at( imageIndex );
 
  205  Display3D<TSpace, TKSpace>::updateBoundingBox( anImage.point1 );
 
  206  Display3D<TSpace, TKSpace>::updateBoundingBox( anImage.point2 );
 
  207  Display3D<TSpace, TKSpace>::updateBoundingBox( anImage.point3 );
 
  208  Display3D<TSpace, TKSpace>::updateBoundingBox( anImage.point4 );
 
  209  anImage.updateImageOrientation(newDirection, xPosition, yPosition, zPosition);
 
  210  if(anImage.myDrawDomain)
 
  212      *this << DGtal::Update2DDomainPosition<Space ,KSpace >(anImage.myIndexDomain,
 
  215                                                             yPosition, zPosition);
 
  219template <typename TSpace, typename TKSpace>
 
  220inline void DGtal::Viewer3D<TSpace, TKSpace>::updateEmbeddingTextureImage(
 
  221unsigned int anImageIndex, typename Space::Point aPoint1,
 
  222typename Space::Point aPoint2, typename Space::Point aPoint3,
 
  223typename Space::Point aPoint4 )
 
  225  assert ( anImageIndex< myGSImageList.size());
 
  226  typename Viewer3D<TSpace, TKSpace>::TextureImage & anImage =
 
  227  myGSImageList.at( anImageIndex );
 
  228  Display3D<TSpace, TKSpace>::updateBoundingBox( aPoint1 );
 
  229  Display3D<TSpace, TKSpace>::updateBoundingBox( aPoint2 );
 
  230  Display3D<TSpace, TKSpace>::updateBoundingBox( aPoint3 );
 
  231  Display3D<TSpace, TKSpace>::updateBoundingBox( aPoint4 );
 
  232  anImage.updateImage3DEmbedding(aPoint1, aPoint2, aPoint3, aPoint4);
 
  235template <typename TSpace, typename TKSpace>
 
  237DGtal::Viewer3D<TSpace, TKSpace>::TextureImage::updateImageOrientation(
 
  238ImageDirection normalDir, double xBottomLeft, double yBottomLeft,
 
  241  if(normalDir==zDirection)
 
  243      point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft-0.5; point1[2] = zBottomLeft;
 
  244      point2[0] = xBottomLeft+myImageWidth-0.5; point2[1] = yBottomLeft-0.5; point2[2] = zBottomLeft;
 
  245      point3[0] = xBottomLeft+myImageWidth-0.5; point3[1] = yBottomLeft+myImageHeight-0.5; point3[2] = zBottomLeft;
 
  246      point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft+myImageHeight-0.5; point4[2] = zBottomLeft;
 
  247    }else if(normalDir==yDirection)
 
  249      point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft; point1[2] = zBottomLeft-0.5;
 
  250      point2[0] = xBottomLeft+myImageWidth-0.5; point2[1] = yBottomLeft; point2[2] = zBottomLeft-0.5;
 
  251      point3[0] = xBottomLeft+myImageWidth-0.5; point3[1] = yBottomLeft; point3[2] = zBottomLeft+myImageHeight-0.5;
 
  252      point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft; point4[2] = zBottomLeft+myImageHeight-0.5;
 
  253    }else if(normalDir==xDirection)
 
  255      point1[0] = xBottomLeft; point1[1] = yBottomLeft-0.5; point1[2]= zBottomLeft-0.5;
 
  256      point2[0] = xBottomLeft; point2[1] = yBottomLeft+myImageWidth-0.5; point2[2] = zBottomLeft-0.5;
 
  257      point3[0] = xBottomLeft; point3[1] = yBottomLeft+myImageWidth-0.5; point3[2] = zBottomLeft+myImageHeight-0.5;
 
  258      point4[0] = xBottomLeft; point4[1] = yBottomLeft-0.5; point4[2] = zBottomLeft+myImageHeight-0.5;
 
  260  myDirection=normalDir;
 
  263template <typename TSpace, typename TKSpace>
 
  265DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D::updateDomainOrientation(
 
  266ImageDirection normalDir, double xBottomLeft, double yBottomLeft,
 
  269  if(normalDir==zDirection)
 
  271      point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft-0.5; point1[2] = zBottomLeft;
 
  272      point2[0] = xBottomLeft+myDomainWidth-0.5; point2[1] = yBottomLeft-0.5; point2[2] = zBottomLeft;
 
  273      point3[0] = xBottomLeft+myDomainWidth-0.5; point3[1] = yBottomLeft+myDomainHeight-0.5; point3[2] = zBottomLeft;
 
  274      point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft+myDomainHeight-0.5; point4[2] = zBottomLeft;
 
  275    }else if(normalDir==yDirection)
 
  277      point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft; point1[2] = zBottomLeft-0.5;
 
  278      point2[0] = xBottomLeft+myDomainWidth-0.5; point2[1] = yBottomLeft; point2[2] = zBottomLeft-0.5;
 
  279      point3[0] = xBottomLeft+myDomainWidth-0.5; point3[1] = yBottomLeft; point3[2] = zBottomLeft+myDomainHeight-0.5;
 
  280      point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft; point4[2] = zBottomLeft+myDomainHeight-0.5;
 
  281    }else if(normalDir==xDirection)
 
  283      point1[0] = xBottomLeft; point1[1] = yBottomLeft-0.5; point1[2]= zBottomLeft-0.5;
 
  284      point2[0] = xBottomLeft; point2[1] = yBottomLeft+myDomainWidth-0.5; point2[2] = zBottomLeft-0.5;
 
  285      point3[0] = xBottomLeft; point3[1] = yBottomLeft+myDomainWidth-0.5; point3[2] = zBottomLeft+myDomainHeight-0.5;
 
  286      point4[0] = xBottomLeft; point4[1] = yBottomLeft-0.5; point4[2] = zBottomLeft+myDomainHeight-0.5;
 
  288  myDirection=normalDir;
 
  291template <typename TSpace, typename TKSpace>
 
  292inline void DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D::translateDomain(
 
  293double xTranslation, double yTranslation, double zTranslation )
 
  295  point1[0] += xTranslation; point1[1] += yTranslation; point1[2] += zTranslation;
 
  296  point2[0] += xTranslation; point2[1] += yTranslation; point2[2] += zTranslation;
 
  297  point3[0] += xTranslation; point3[1] += yTranslation; point3[2] += zTranslation;
 
  298  point4[0] += xTranslation; point4[1] += yTranslation; point4[2] += zTranslation;
 
  301template <typename TSpace, typename TKSpace>
 
  302template <typename TDomain>
 
  303void DGtal::Viewer3D<TSpace, TKSpace>::addImage2DDomainD3D(
 
  304const TDomain & aDomain, std::string mode, const DGtal::Color & aColor )
 
  306  typename DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D anImageDomain(
 
  308  anImageDomain.color = aColor;
 
  309  anImageDomain.myMode = mode;
 
  310  anImageDomain.myLineSetIndex =
 
  311  Viewer3D<TSpace, TKSpace>::myLineSetList.size();
 
  313  myImageDomainList.push_back(anImageDomain);
 
  314  Display3D<TSpace, TKSpace>::updateBoundingBox( anImageDomain.point1 );
 
  315  Display3D<TSpace, TKSpace>::updateBoundingBox( anImageDomain.point2 );
 
  316  Display3D<TSpace, TKSpace>::updateBoundingBox( anImageDomain.point3 );
 
  317  Display3D<TSpace, TKSpace>::updateBoundingBox( anImageDomain.point4 );
 
  319  std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D> vectLines =
 
  320  compute2DDomainLineRepresentation( anImageDomain );
 
  321  Viewer3D<TSpace, TKSpace>::myLineSetList.push_back( vectLines );
 
  324template <typename TSpace, typename TKSpace>
 
  325inline std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D>
 
  326DGtal::Viewer3D<TSpace, TKSpace>::compute2DDomainLineRepresentation(
 
  327typename DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D & anImageDomain )
 
  329  std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D>
 
  330  vectLinesResu = compute2DDomainLineRepresentation( anImageDomain, 0.05 );
 
  331  std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D>
 
  332  vectLinesVerso = compute2DDomainLineRepresentation( anImageDomain, -0.05 );
 
  333  for(unsigned int i=0; i<vectLinesVerso.size(); i++)
 
  335      vectLinesResu.push_back(vectLinesVerso.at(i));
 
  337  return vectLinesResu;
 
  340template <typename TSpace, typename TKSpace>
 
  341inline std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D>
 
  342DGtal::Viewer3D<TSpace, TKSpace>::compute2DDomainLineRepresentation(
 
  343typename DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D & anImageDomain,
 
  346  std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D> aLineSet;
 
  347  typename Viewer3D<TSpace, TKSpace>::LineD3D aLine;
 
  348  aLine.color = anImageDomain.color;
 
  351  if( anImageDomain.myMode=="BoundingBox")
 
  353      aLine.point1[0]=anImageDomain.point1[0]; aLine.point1[1]=anImageDomain.point1[1]; aLine.point1[2]=anImageDomain.point1[2];
 
  354      aLine.point2[0]=anImageDomain.point2[0]; aLine.point2[1]=anImageDomain.point2[1]; aLine.point2[2]=anImageDomain.point2[2];
 
  355      aLineSet.push_back(aLine);
 
  356      aLine.point1[0]=anImageDomain.point2[0]; aLine.point1[1]=anImageDomain.point2[1]; aLine.point1[2]=anImageDomain.point2[2];
 
  357      aLine.point2[0]=anImageDomain.point3[0]; aLine.point2[1]=anImageDomain.point3[1]; aLine.point2[2]=anImageDomain.point3[2];
 
  358      aLineSet.push_back(aLine);
 
  359      aLine.point1[0]=anImageDomain.point3[0]; aLine.point1[1]=anImageDomain.point3[1]; aLine.point1[2]=anImageDomain.point3[2];
 
  360      aLine.point2[0]=anImageDomain.point4[0]; aLine.point2[1]=anImageDomain.point4[1]; aLine.point2[2]=anImageDomain.point4[2];
 
  361      aLineSet.push_back(aLine);
 
  362      aLine.point1[0]=anImageDomain.point4[0]; aLine.point1[1]=anImageDomain.point4[1]; aLine.point1[2]=anImageDomain.point4[2];
 
  363      aLine.point2[0]=anImageDomain.point1[0]; aLine.point2[1]=anImageDomain.point1[1]; aLine.point2[2]=anImageDomain.point1[2];
 
  364      aLineSet.push_back(aLine);
 
  365    }else if(anImageDomain.myMode=="InterGrid")
 
  367      if(anImageDomain.myDirection==zDirection)
 
  369          //lines align to the x direction
 
  370          for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
 
  372              aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+i; aLine.point1[2] = anImageDomain.point1[2]+delta;
 
  373              aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point2[1]+i; aLine.point2[2] = anImageDomain.point2[2]+delta;
 
  374              aLineSet.push_back(aLine);
 
  376          //lines align to the y direction
 
  377          for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
 
  379              aLine.point1[0] = anImageDomain.point1[0]+i; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+delta;
 
  380              aLine.point2[0] = anImageDomain.point4[0]+i; aLine.point2[1] = anImageDomain.point4[1]; aLine.point2[2] = anImageDomain.point4[2]+delta;
 
  381              aLineSet.push_back(aLine);
 
  383        }else if(anImageDomain.myDirection==xDirection)
 
  385          //lines align to the y direction
 
  386          for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
 
  388              aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+i;
 
  389              aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point2[1]; aLine.point2[2] = anImageDomain.point1[2]+i;
 
  390              aLineSet.push_back(aLine);
 
  393          //lines align to the z direction
 
  394          for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
 
  396              aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]+i; aLine.point1[2] = anImageDomain.point1[2];
 
  397              aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point1[1]+i; aLine.point2[2] = anImageDomain.point4[2];
 
  398              aLineSet.push_back(aLine);
 
  400        }else if(anImageDomain.myDirection==yDirection)
 
  402          //lines align to the x direction
 
  403          for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
 
  405              aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2]+i;
 
  406              aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point1[2]+i;
 
  407              aLineSet.push_back(aLine);
 
  410          //lines align to the z direction
 
  411          for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
 
  413              aLine.point1[0] = anImageDomain.point1[0]+i; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2];
 
  414              aLine.point2[0] = anImageDomain.point1[0]+i; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point4[2];
 
  415              aLineSet.push_back(aLine);
 
  418    }else if(anImageDomain.myMode=="Grid")
 
  420      if(anImageDomain.myDirection==zDirection)
 
  422          //lines align to the x direction
 
  423          for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
 
  425              aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+i+0.5; aLine.point1[2] = anImageDomain.point1[2]+delta;
 
  426              aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point2[1]+i+0.5; aLine.point2[2] = anImageDomain.point2[2]+delta;
 
  427              aLineSet.push_back(aLine);
 
  429          //lines align to the y direction
 
  430          for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
 
  432              aLine.point1[0] = anImageDomain.point1[0]+i+0.5; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+delta;
 
  433              aLine.point2[0] = anImageDomain.point4[0]+i+0.5; aLine.point2[1] = anImageDomain.point4[1]; aLine.point2[2] = anImageDomain.point4[2]+delta;
 
  434              aLineSet.push_back(aLine);
 
  436        }else if(anImageDomain.myDirection==xDirection)
 
  438          //lines align to the y direction
 
  439          for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
 
  441              aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+i+0.5;
 
  442              aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point2[1]; aLine.point2[2] = anImageDomain.point1[2]+i+0.5;
 
  443              aLineSet.push_back(aLine);
 
  446          //lines align to the z direction
 
  447          for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
 
  449              aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]+i+0.5; aLine.point1[2] = anImageDomain.point1[2];
 
  450              aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point1[1]+i+0.5; aLine.point2[2] = anImageDomain.point4[2];
 
  451              aLineSet.push_back(aLine);
 
  453        }else if(anImageDomain.myDirection==yDirection)
 
  455          //lines align to the x direction
 
  456          for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
 
  458              aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2]+i+0.5;
 
  459              aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point1[2]+i+0.5;
 
  460              aLineSet.push_back(aLine);
 
  463          //lines align to the z direction
 
  464          for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
 
  466              aLine.point1[0] = anImageDomain.point1[0]+i+0.5; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2];
 
  467              aLine.point2[0] = anImageDomain.point1[0]+i+0.5; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point4[2];
 
  468              aLineSet.push_back(aLine);
 
  475template <typename TSpace, typename TKSpace>
 
  476inline void DGtal::Viewer3D<TSpace, TKSpace>::updateAn2DDomainOrientation(
 
  477unsigned int domainIndex, double xPosition, double yPosition, double zPosition,
 
  478ImageDirection newDirection )
 
  480  ASSERT( domainIndex < myImageDomainList.size());
 
  481  typename Viewer3D<TSpace, TKSpace>::Image2DDomainD3D & aDomain =
 
  482  myImageDomainList.at( domainIndex );
 
  484  Display3D<TSpace, TKSpace>::updateBoundingBox( aDomain.point1 );
 
  485  Display3D<TSpace, TKSpace>::updateBoundingBox( aDomain.point2 );
 
  486  Display3D<TSpace, TKSpace>::updateBoundingBox( aDomain.point3 );
 
  487  Display3D<TSpace, TKSpace>::updateBoundingBox( aDomain.point4 );
 
  488  aDomain.updateDomainOrientation(newDirection, xPosition, yPosition, zPosition);
 
  490  std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D> vectNewLines =
 
  491  compute2DDomainLineRepresentation( aDomain );
 
  492  std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D> & vectLines =
 
  493  Viewer3D<TSpace, TKSpace>::myLineSetList.at( aDomain.myLineSetIndex );
 
  495  for(unsigned int i=0; i<vectNewLines.size(); i++)
 
  497      vectLines.push_back(vectNewLines.at(i));
 
  502template <typename TSpace, typename TKSpace>
 
  503inline void DGtal::Viewer3D<TSpace, TKSpace>::translateAn2DDomain(
 
  504unsigned int domainIndex, double xTranslation, double yTranslation,
 
  507  typename Viewer3D<TSpace, TKSpace>::Image2DDomainD3D & anDomain =
 
  508  myImageDomainList.at( domainIndex );
 
  509  anDomain.translateDomain(xTranslation, yTranslation, zTranslation);
 
  511  Display3D<TSpace, TKSpace>::updateBoundingBox( anDomain.point1 );
 
  512  Display3D<TSpace, TKSpace>::updateBoundingBox( anDomain.point2 );
 
  513  Display3D<TSpace, TKSpace>::updateBoundingBox( anDomain.point3 );
 
  514  Display3D<TSpace, TKSpace>::updateBoundingBox( anDomain.point4 );
 
  516  std::vector<typename DGtal::Display3D<TSpace, TKSpace>::LineD3D> & vectLines =
 
  517  Viewer3D<TSpace, TKSpace>::myLineSetList.at( anDomain.myLineSetIndex );
 
  518  for(unsigned int i=0; i<vectLines.size(); i++){
 
  519    typename DGtal::Display3D<TSpace, TKSpace>::LineD3D & aLine =
 
  521    aLine.point1[0]=aLine.point1[0]+xTranslation; aLine.point1[1]=aLine.point1[1]+yTranslation; aLine.point1[2]=aLine.point1[2]+zTranslation;
 
  522    aLine.point2[0]=aLine.point2[0]+xTranslation; aLine.point2[1]=aLine.point2[1]+yTranslation; aLine.point2[2]=aLine.point2[2]+zTranslation;
 
  526template <typename TSpace, typename TKSpace>
 
  528DGtal::Viewer3D<TSpace, TKSpace>::TextureImage::className() const
 
  530  return "TextureImage";
 
  533template <typename TSpace, typename TKSpace>
 
  534inline DGtal::Viewer3D<TSpace, TKSpace> & DGtal::Viewer3D<TSpace, TKSpace>::
 
  535operator<<( const DGtal::Color & aColor )
 
  537  myDefaultColor=aColor;
 
  541template <typename TSpace, typename TKSpace>
 
  542inline DGtal::Viewer3D<TSpace, TKSpace> & DGtal::Viewer3D<TSpace, TKSpace>::
 
  543operator<<( const typename Viewer3D<TSpace, TKSpace>::StreamKey & key )
 
  547    case Viewer3D<TSpace, TKSpace>::updateDisplay:
 
  548      Viewer3D<TSpace, TKSpace>::updateList();
 
  551    case Viewer3D<TSpace, TKSpace>::addNewList:
 
  552      Viewer3D<TSpace, TKSpace>::createNewCubeList();
 
  555    case Viewer3D<TSpace, TKSpace>::shiftSurfelVisu:
 
  556      Viewer3D<TSpace, TKSpace>::myCurrentfShiftVisuPrisms += 0.3;
 
  562template <typename TSpace, typename TKSpace>
 
  563template <typename TDrawableWithViewer3D>
 
  564inline DGtal::Viewer3D<TSpace, TKSpace> & DGtal::Viewer3D<TSpace, TKSpace>::
 
  565operator<<( const TDrawableWithViewer3D & object )
 
  567  BOOST_CONCEPT_ASSERT((concepts::CDrawableWithViewer3D< TDrawableWithViewer3D, Space, KSpace >));
 
  569  DGtal::Viewer3DFactory<TSpace, TKSpace>::draw( *this, object );
 
  574///////////////////////////////////////////////////////////////////////////////
 
  575// Implementation of inline functions and external operators //
 
  577template <typename TSpace, typename TKSpace>
 
  578inline std::ostream & DGtal::
 
  579operator<<( std::ostream & out, const Viewer3D<TSpace, TKSpace> & object )
 
  581  object.selfDisplay ( out );
 
  586///////////////////////////////////////////////////////////////////////////////
 
  589///////////////////////////////////////////////////////////////////////////////
 
  591// heritage of parents templates methods //
 
  595///////////////////////////////////////////////////////////////////////////////
 
  597///////////////////////////////////////////////////////////////////////////////
 
  599// surcharge of parents methods //
 
  602// end of surcharge //
 
  603///////////////////////////////////////////////////////////////////////////////
 
  605template <typename TSpace, typename TKSpace>
 
  606inline void DGtal::Viewer3D<TSpace, TKSpace>::drawWithNames()
 
  608  // JOL: 2014/10/15. This method is called only when the user tries
 
  609  // to select some graphic object through QGLViewer. By default,
 
  610  // selection is left clic + shift key.
 
  611  // JOL: 2014/10/15. This is my addition for interacting with
 
  612  // quads. Seems to work well.
 
  613  if ( myExtension != 0 )
 
  614    myExtension->drawWithNames( *this );
 
  616  glCallList ( myQuadsMapId );
 
  618  glCallList ( myCubesMapId );
 
  620  for ( unsigned int i = 0; i < Viewer3D<TSpace, TKSpace>::myLineSetList.size();
 
  623    glCallList( myLineSetListId + i );
 
  626    for ( unsigned int i = 0;
 
  627          i < Viewer3D<TSpace, TKSpace>::myBallSetList.size(); i++ )
 
  629      glCallList(myBallSetListId+i);
 
  634template <typename TSpace, typename TKSpace>
 
  635inline void DGtal::Viewer3D<TSpace, TKSpace>::draw()
 
  638  glUpdateBackground();
 
  640  if ( myExtension != 0 )
 
  641    myExtension->draw( *this );
 
  644  glMultMatrixd ( manipulatedFrame()->matrix() );
 
  646  glScalef(myGLScaleFactorX, myGLScaleFactorY, myGLScaleFactorZ);
 
  648  glLightfv(GL_LIGHT0, GL_SPECULAR, myLightSpecularCoeffs);
 
  649  glLightfv(GL_LIGHT0, GL_DIFFUSE, myLightDiffuseCoeffs);
 
  650  glLightfv(GL_LIGHT0, GL_AMBIENT, myLightAmbientCoeffs);
 
  651  if( myLightPositionFixToCamera ){
 
  652        updateLightCoordsFromCamera();  
 
  654    updateRelativeCameraFromLightPosition();
 
  656  glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);  
 
  659  typename std::vector<
 
  660  typename Viewer3D<TSpace, TKSpace>::ClippingPlaneD3D>::const_iterator it =
 
  661  Viewer3D<TSpace, TKSpace>::myClippingPlaneList.begin();
 
  663  // OpenGL can't draw more than GL_MAX_CLIP_PLANES clipping plane
 
  664  while ( i < GL_MAX_CLIP_PLANES &&
 
  665          it != Viewer3D<TSpace, TKSpace>::myClippingPlaneList.end() )
 
  672    glEnable( GL_CLIP_PLANE0 + i );
 
  673    glClipPlane( GL_CLIP_PLANE0 + i, eq );
 
  677  if (i == GL_MAX_CLIP_PLANES)
 
  679      std::cerr <<"Warning maximal clipping plane added" << std::endl;
 
  682  Vec centerS = sceneCenter();
 
  683  Vec posCam = camera()->position();
 
  684  double distCam =sqrt ( ( posCam.x-centerS.x ) * ( posCam.x-centerS.x ) +
 
  685                         ( posCam.y-centerS.y ) * ( posCam.y-centerS.y ) +
 
  686                         ( posCam.z-centerS.z ) * ( posCam.z-centerS.z ) );
 
  687  for(unsigned int j=0; j< myVectTextureImage.size(); j++)
 
  689      GLTextureImage &textureImg = myVectTextureImage.at(j);
 
  690      glPushName ( textureImg.myTextureName );
 
  691      glEnable(GL_TEXTURE_2D);
 
  692      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
  693      glBindTexture(GL_TEXTURE_2D, textureImg.myTextureName);
 
  695      glColor4ub ( 255.0, 255.0, 255.0, 255.0 );
 
  696      glNormal3d(textureImg.vectNormal[0], textureImg.vectNormal[1], textureImg.vectNormal[2]);
 
  699      glVertex3f(textureImg.point1[0], textureImg.point1[1], textureImg.point1[2]);
 
  700      glTexCoord2f(textureImg.myTextureFitX, 0.0);
 
  701      glVertex3f(textureImg.point2[0], textureImg.point2[1], textureImg.point2[2]);
 
  702      glTexCoord2f(textureImg.myTextureFitX, textureImg.myTextureFitY);
 
  703      glVertex3f(textureImg.point3[0], textureImg.point3[1], textureImg.point3[2]);
 
  704      glTexCoord2f(0.0, textureImg.myTextureFitY);
 
  705      glVertex3f(textureImg.point4[0], textureImg.point4[1], textureImg.point4[2]);
 
  707      glDisable(GL_TEXTURE_2D);
 
  711    for ( unsigned int j = 0;
 
  712          j < Viewer3D<TSpace, TKSpace>::myLineSetList.size(); j++ )
 
  714      if ( Viewer3D<TSpace, TKSpace>::myLineSetList.at( j ).size() != 0 )
 
  717        std::max( myGLLineMinWidth,
 
  718             Viewer3D<TSpace, TKSpace>::myLineSetList.at( j ).at( 0 ).width ) );
 
  720      glCallList(myLineSetListId+j);
 
  723  glCallList(myPrismListId);
 
  725  glCallList( myCubesMapId );
 
  727  for ( unsigned int j = 0; j < Viewer3D<TSpace, TKSpace>::myBallSetList.size();
 
  730    if ( myUseGLPointsForBalls )
 
  732      if ( Viewer3D<TSpace, TKSpace>::myBallSetList.at( j ).size() != 0 )
 
  734        glPointSize( std::max(
 
  736        ( Viewer3D<TSpace, TKSpace>::myBallSetList.at( j ).at( 0 ).radius ) ) );
 
  740      glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
 
  742    glCallList( myBallSetListId + j );
 
  743    glUpdateLightRenderingMode();
 
  746  glDisable(GL_CULL_FACE);
 
  747  glCallList(myQuadsMapId);
 
  751      std::max( myGLLineMinWidth,
 
  752           Viewer3D<TSpace, TKSpace>::myMeshDefaultLineWidth / distCam ) );
 
  753      glCallList(myQuadsMapWiredId);
 
  756  glDisable(GL_CULL_FACE);
 
  757  glCallList(myTriangleSetListId);
 
  761      std::max( myGLLineMinWidth,
 
  762           Viewer3D<TSpace, TKSpace>::myMeshDefaultLineWidth / distCam ) );
 
  763      glCallList(myTriangleSetListWiredId);
 
  766  glDisable(GL_CULL_FACE);
 
  767  glCallList(myPolygonSetListId);
 
  771      std::max( myGLLineMinWidth,
 
  772           Viewer3D<TSpace, TKSpace>::myMeshDefaultLineWidth / distCam ) );
 
  773      glCallList(myPolygonSetListWiredId);
 
  777    drawLight(GL_LIGHT0);
 
  784template <typename TSpace, typename TKSpace>
 
  785void DGtal::Viewer3D<TSpace, TKSpace>::selfDisplay( std::ostream & out ) const
 
  790template <typename TSpace, typename TKSpace>
 
  791bool DGtal::Viewer3D<TSpace, TKSpace>::isValid() const
 
  796template <typename TSpace, typename TKSpace>
 
  797void DGtal::Viewer3D<TSpace, TKSpace>::init()
 
  799  if ( myExtension != 0 )
 
  800    myExtension->init( *this );
 
  801  myAutoSaveState = false;
 
  802  myIsMovingLight = false;
 
  803  myLigthRotationStep = 0.01;
 
  807  myLightPositionRefCamera[0] = myLightPositionRefCameraDefault[0];
 
  808  myLightPositionRefCamera[1] = myLightPositionRefCameraDefault[1];
 
  809  myLightPositionRefCamera[2] = myLightPositionRefCameraDefault[2];
 
  810  updateLightCoordsFromCamera();
 
  812  glClearColor (0.0, 0.0, 0.0, 0.0);
 
  813  glShadeModel (GL_SMOOTH);  
 
  815  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, myMaterialShininessCoeff);
 
  816  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, myMaterialSpecularCoeffs);
 
  819  glLightfv(GL_LIGHT0, GL_SPECULAR, myLightSpecularCoeffs);
 
  820  glLightfv(GL_LIGHT0, GL_DIFFUSE, myLightDiffuseCoeffs);
 
  821  glLightfv(GL_LIGHT0, GL_AMBIENT, myLightAmbientCoeffs);
 
  823  glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
 
  825  glEnable(GL_LIGHTING);
 
  827  glEnable(GL_DEPTH_TEST);
 
  829  Viewer3D<TSpace, TKSpace>::myMeshDefaultLineWidth = 10.0;
 
  832  setBackgroundColor ( QColor ( 217, 228, 255, 255 ) );
 
  833  setForegroundColor ( QColor ( 217, 22, 25, 255  ) );
 
  835  Viewer3D<TSpace, TKSpace>::createNewCubeList();
 
  836  std::vector<typename Viewer3D<TSpace, TKSpace>::LineD3D> listeLine;
 
  837  Viewer3D<TSpace, TKSpace>::myLineSetList.push_back( listeLine );
 
  838  std::vector<typename Viewer3D<TSpace, TKSpace>::BallD3D> listeBall;
 
  839  Viewer3D<TSpace, TKSpace>::myBallSetList.push_back( listeBall );
 
  840  Viewer3D<TSpace, TKSpace>::myCurrentFillColor = Color( 220, 220, 220 );
 
  841  Viewer3D<TSpace, TKSpace>::myCurrentLineColor = Color( 22, 22, 222, 50 );
 
  842  myDefaultBackgroundColor = Color ( backgroundColor().red(), backgroundColor().green(),
 
  843                                     backgroundColor().blue() );
 
  844  myIsBackgroundDefault=true;
 
  845  Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 0 ] =
 
  846  -10.0; // numeric_limits<double>::max( );
 
  847  Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 1 ] =
 
  848  -10.0; // numeric_limits<double>::max( );
 
  849  Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 2 ] =
 
  850  -10.0; // numeric_limits<double>::max( );
 
  852  Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 0 ] =
 
  853  -10.0; // numeric_limits<double>::min( );
 
  854  Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 1 ] =
 
  855  -10.0; // numeric_limits<double>::min( );
 
  856  Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 2 ] =
 
  857  -10.0; // numeric_limits<double>::min( );
 
  858  Viewer3D<TSpace, TKSpace>::createNewCubeList();
 
  859  typename std::vector<typename Viewer3D<TSpace, TKSpace>::CubeD3D> aKSCubeList;
 
  861  Viewer3D<TSpace, TKSpace>::myCurrentfShiftVisuPrisms = 0.0;
 
  862  Viewer3D<TSpace, TKSpace>::myDefaultColor            = Color( 255, 255, 255 );
 
  863  camera()->showEntireScene();
 
  864  setKeyDescription ( Qt::Key_E, "Export the current display into OFF file (just Cube, surfel and SurfelPrism for now)." );
 
  865  setKeyDescription ( Qt::Key_W, "Switch display with and without wired view of triangle and quad faces." );
 
  866  setKeyDescription ( Qt::Key_T, "Sort elements for display improvements." );
 
  867  setKeyDescription ( Qt::Key_L, "Load last visualisation settings (from a .qglviewer.xml file generated by using SHIFT+L)");
 
  868  setKeyDescription ( Qt::ShiftModifier+Qt::Key_L, "Save visualisation settings." );
 
  869  setKeyDescription ( Qt::Key_B, "Switch background color with White/Black colors." );
 
  870  setKeyDescription ( Qt::Key_C, "Show camera informations." );
 
  871  setKeyDescription ( Qt::Key_R, "Reset default scale for 3 axes to 1.0f." );
 
  872  setKeyDescription ( Qt::Key_D, "Enable/Disable the two side face rendering." );
 
  873  setKeyDescription ( Qt::Key_O, "Switch the ball display mode (quad ball display (default) or OpenGL point)." );
 
  874  setKeyDescription ( Qt::Key_M, "Switch the rendering mode bewteen Default, Metallic and Plastic mode." );
 
  875  setKeyDescription ( Qt::Key_P, "Switch the light source position mode between the camera mode (default: the light source position is fixed according to the camera position) and scene mode (the light source position is fixed according the scene coordinate system)." );
 
  876  setKeyDescription( Qt::Key_Z,
 
  877                     "Move away the light source according to the scence "
 
  878                     "center (move closer with  SHIFT+Z)" );
 
  879  setKeyDescription( Qt::ShiftModifier + Qt::Key_Z,
 
  880                     "Move closer the light source according to the scence "
 
  881                     "center (move awya with key  Z)" );
 
  883#if !defined (QGLVIEWER_VERSION) || QGLVIEWER_VERSION < 0x020500
 
  884  setMouseBindingDescription((Qt::ControlModifier|Qt::ShiftModifier) + Qt::LeftButton, "move light source position defined in the main coordinate system (an x-axis (resp. y-axis) mouse move changes the azimuth (resp. inclination) angle of the light source). Note that light source is always looking at the center point (0,0,0).");
 
  886  setMouseBindingDescription(Qt::KeyboardModifiers( Qt::ControlModifier|Qt::ShiftModifier ), Qt::LeftButton, "move light source position defined in the main coordinate system (an x-axis (resp. y-axis) mouse move changes the azimuth (resp. inclination) angle of the light source). Note that light source is always looking at the center point (0,0,0).");
 
  890  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
 
  892#if !defined (QGLVIEWER_VERSION) || QGLVIEWER_VERSION < 0x020500
 
  893  setMouseBindingDescription ( Qt::ShiftModifier+Qt::RightButton, "Delete the mouse selected list." );
 
  895  setMouseBindingDescription ( Qt::ShiftModifier, Qt::RightButton, "Delete the mouse selected list." );
 
  898  setManipulatedFrame ( new ManipulatedFrame() );
 
  901template <typename TSpace, typename TKSpace>
 
  902void DGtal::Viewer3D<TSpace, TKSpace>::sortSurfelFromCamera()
 
  904  CompFarthestVoxelFromCamera comp;
 
  905  comp.posCam= camera()->position();
 
  907  for ( auto & mapElem : Viewer3D<TSpace, TKSpace>::myCubesMap )
 
  910    DGtal::trace.info() << "sort quad size" << mapElem.second.size()
 
  912    sort( mapElem.second.begin(), mapElem.second.end(), comp );
 
  914  CompFarthestSurfelFromCamera compSurf;
 
  915  DGtal::trace.info() << "sort surfel size"
 
  916                      << Viewer3D<TSpace, TKSpace>::myPrismList.size()
 
  918  sort( Viewer3D<TSpace, TKSpace>::myPrismList.begin(),
 
  919        Viewer3D<TSpace, TKSpace>::myPrismList.end(), compSurf );
 
  922template <typename TSpace, typename TKSpace>
 
  923void DGtal::Viewer3D<TSpace, TKSpace>::sortTriangleFromCamera()
 
  925  CompFarthestTriangleFromCamera comp;
 
  926  comp.posCam= camera()->position();
 
  927  for ( auto & listElem : Viewer3D<TSpace, TKSpace>::myTriangleSetList )
 
  929    sort( listElem.begin(), listElem.end(), comp );
 
  933template <typename TSpace, typename TKSpace>
 
  934void DGtal::Viewer3D<TSpace, TKSpace>::sortQuadFromCamera()
 
  936  CompFarthestSurfelFromCamera comp;
 
  937  comp.posCam= camera()->position();
 
  939  for ( auto & listElem : Viewer3D<TSpace, TKSpace>::myQuadsMap )
 
  941    DGtal::trace.info() << "sort quad size" << listElem.second.size()
 
  943    sort( listElem.second.begin(), listElem.second.end(), comp );
 
  947template <typename TSpace, typename TKSpace>
 
  948void DGtal::Viewer3D<TSpace, TKSpace>::sortPolygonFromCamera()
 
  950  CompFarthestPolygonFromCamera comp;
 
  951  comp.posCam= camera()->position();
 
  953  for ( auto & listElem : Viewer3D<TSpace, TKSpace>::myPolygonSetList )
 
  955    DGtal::trace.info() << "sort polygon size" << listElem.size() << std::endl;
 
  956    sort( listElem.begin(), listElem.end(), comp );
 
  961template <typename TSpace, typename TKSpace>
 
  962void DGtal::Viewer3D<TSpace, TKSpace>::postSelection( const QPoint & point )
 
  964  bool handled = false;
 
  965  if ( myExtension != 0 )
 
  966    handled = myExtension->postSelection( *this, point );
 
  970  camera()->convertClickToLine ( point, myOrig, myDir );
 
  972  this->myPosSelector= point;
 
  973  mySelectedPoint = camera()->pointUnderPixel ( point, found );
 
  976      DGtal::trace.info() << "Element of liste= " << selectedName() << "selected" << std::endl;
 
  978      mySelectedElementId = selectedName();
 
  980      SelectCallbackFct fct = getSelectCallback3D( selectedName(), aData );
 
  981      if ( fct ) fct( this, selectedName(), aData );
 
  982      // I leave the remaining code.      
 
  984    }else if (mySelectedElementId != -1)
 
  986      mySelectedElementId = -1;
 
  991template <typename TSpace, typename TKSpace>
 
  992void DGtal::Viewer3D<TSpace, TKSpace>::updateList(
 
  993bool needToUpdateBoundingBox )
 
  997  glDeleteLists(myCubesMapId, 1);
 
  998  glDeleteLists(myLineSetListId, myNbLineSetList);
 
  999  glDeleteLists(myBallSetListId, myNbBallSetList);
 
 1000  glDeleteLists(myTriangleSetListId, 1);
 
 1001  glDeleteLists(myTriangleSetListWiredId, 1);
 
 1002  glDeleteLists(myPrismListId, 1);
 
 1003  glDeleteLists(myPolygonSetListId, 1);
 
 1004  glDeleteLists(myPolygonSetListWiredId, 1);
 
 1005  glDeleteLists(myQuadsMapId, 1);
 
 1006  glDeleteLists(myQuadsMapWiredId, 1);
 
 1008  // Storing ID for each list
 
 1009  myCubesMapId = glGenLists(1);
 
 1011  glGenLists( static_cast<GLsizei>(Viewer3D<TSpace, TKSpace>::myLineSetList.size() ));
 
 1012  myNbLineSetList = static_cast<unsigned int>(Viewer3D<TSpace, TKSpace>::myLineSetList.size());
 
 1014  glGenLists( static_cast<GLsizei>(Viewer3D<TSpace, TKSpace>::myBallSetList.size() ) );
 
 1015  myNbBallSetList          = static_cast<unsigned int>(Viewer3D<TSpace, TKSpace>::myBallSetList.size());
 
 1016  myTriangleSetListId = glGenLists(1);
 
 1017  myTriangleSetListWiredId = glGenLists(1);
 
 1018  myCubeSetListWiredId = glGenLists(1);
 
 1019  myPolygonSetListId = glGenLists(1);
 
 1020  myPolygonSetListWiredId = glGenLists(1);
 
 1021  myQuadsMapId = glGenLists(1);
 
 1022  myQuadsMapWiredId = glGenLists(1);
 
 1023  myPrismListId = glGenLists(1);
 
 1028  glEnable ( GL_BLEND );
 
 1029  glEnable ( GL_MULTISAMPLE_ARB );
 
 1030  glEnable ( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
 
 1031  glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
 1033  glCreateListCubesMaps( Viewer3D<TSpace, TKSpace>::myCubesMap, myCubesMapId );
 
 1035  glCreateListQuadD3D( Viewer3D<TSpace, TKSpace>::myPrismList, myPrismListId );
 
 1038  for ( unsigned int j = 0; j < Viewer3D<TSpace, TKSpace>::myLineSetList.size();
 
 1041    glCreateListLines( Viewer3D<TSpace, TKSpace>::myLineSetList.at( j ),
 
 1042                       myLineSetListId + j );
 
 1046    for ( unsigned int j = 0;
 
 1047          j < Viewer3D<TSpace, TKSpace>::myBallSetList.size(); j++ )
 
 1049      glCreateListBalls( Viewer3D<TSpace, TKSpace>::myBallSetList.at( j ),
 
 1050                         myBallSetListId + j );
 
 1055  // First list: quad faces.
 
 1056    glCreateListQuadMaps( Viewer3D<TSpace, TKSpace>::myQuadsMap, myQuadsMapId );
 
 1059    // Second list: Wired version of quad face.
 
 1060    glCreateListQuadMapsWired( Viewer3D<TSpace, TKSpace>::myQuadsMap,
 
 1061                               myQuadsMapWiredId );
 
 1064    // Third list: Triangle faces.
 
 1065    glCreateListTriangles( Viewer3D<TSpace, TKSpace>::myTriangleSetList,
 
 1066                           myTriangleSetListId );
 
 1069    // Fourth list: Wired version of triangle face.
 
 1070    glCreateListTrianglesWired( Viewer3D<TSpace, TKSpace>::myTriangleSetList,
 
 1071                                myTriangleSetListWiredId );
 
 1074    // Fifth list: Polygonal faces.
 
 1075    glCreateListPolygons( Viewer3D<TSpace, TKSpace>::myPolygonSetList,
 
 1076                          myPolygonSetListId );
 
 1079    // Sixth list: Wired version of polygonal face.
 
 1080    glCreateListPolygonsWired( Viewer3D<TSpace, TKSpace>::myPolygonSetList,
 
 1081                               myPolygonSetListWiredId );
 
 1084    // Seventh list: Textured images.
 
 1085    glUpdateTextureImages( myGSImageList );
 
 1087    if ( needToUpdateBoundingBox &&
 
 1088         Viewer3D<TSpace, TKSpace>::myBoundingPtChangedTag )
 
 1090      setSceneBoundingBox(
 
 1091      qglviewer::Vec( Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 0 ],
 
 1092                      Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 1 ],
 
 1093                      Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 2 ] ),
 
 1094      qglviewer::Vec( Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 0 ],
 
 1095                      Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 1 ],
 
 1096                      Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 2 ] ) );
 
 1098      Viewer3D<TSpace, TKSpace>::myBoundingPtChangedTag = false;
 
 1104template <typename TSpace, typename TKSpace>
 
 1105void DGtal::Viewer3D<TSpace, TKSpace>::glDrawGLBall(
 
 1106const typename Viewer3D<TSpace, TKSpace>::BallD3D & aBall )
 
 1108  double thetaResolution = aBall.resolution;
 
 1109  double thetaStep= (2.0*M_PI)/thetaResolution;
 
 1110  double phiResolution = aBall.resolution;
 
 1111  double phiStep= M_PI/phiResolution;
 
 1113  double radius = aBall.radius;
 
 1114  double xCenter = aBall.center[0];
 
 1115  double yCenter = aBall.center[1];
 
 1116  double zCenter = aBall.center[2];
 
 1117  glBegin(GL_QUAD_STRIP);
 
 1118  for(unsigned int j =0; j < phiResolution; j++)
 
 1120      double phi0 = M_PI/2.0-j*phiStep;
 
 1121      double phi1 = M_PI/2.0-(j+1)*phiStep;
 
 1122      for(unsigned int i =0; i <= thetaResolution; i++)
 
 1124          double theta0 =  i * thetaStep;
 
 1125          glColor4ub ( aBall.color.red(), aBall.color.green(), aBall.color.blue(), aBall.color.alpha() );
 
 1126          glNormal3f(cos(phi0)*cos(theta0), cos(phi0)*sin(theta0), sin(phi0));
 
 1127          glVertex3f(xCenter+cos(phi0)*cos(theta0)*radius,yCenter+ cos(phi0)*sin(theta0)*radius, zCenter+ sin(phi0)*radius);
 
 1128          glNormal3f(cos(phi1)*cos(theta0), cos(phi1)*sin(theta0), sin(phi1));
 
 1129          glVertex3f(xCenter+cos(phi1)*cos(theta0)*radius,yCenter+ cos(phi1)*sin(theta0)*radius, zCenter+ sin(phi1)*radius);
 
 1136template <typename TSpace, typename TKSpace>
 
 1137void DGtal::Viewer3D<TSpace, TKSpace>::mousePressEvent( QMouseEvent * e )
 
 1139  bool handled = false;
 
 1140  // Checks if an extension is present.
 
 1141  if ( myExtension != 0 )
 
 1143    handled = myExtension->mousePressEvent( *this, e );
 
 1148  if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier))
 
 1150      myIsMovingLight=true;
 
 1151      myRefMouseXPos = e->x();
 
 1152      myRefMouseYPos = e->y();
 
 1153      if( myLightPositionFixToCamera )
 
 1155           updateLightCoordsFromCamera();
 
 1157      myLightR = sqrt( myLightPosition[0]* myLightPosition[0]+
 
 1158                       myLightPosition[1]* myLightPosition[1]+
 
 1159                       myLightPosition[2]* myLightPosition[2]);
 
 1160      myLightTheta = asin( myLightPosition[2]/myLightR);
 
 1161      myLightPhi = atan2( myLightPosition[1], myLightPosition[0]);
 
 1165      QGLViewer::mousePressEvent(e);
 
 1169template <typename TSpace, typename TKSpace>
 
 1170void DGtal::Viewer3D<TSpace, TKSpace>::mouseReleaseEvent( QMouseEvent * e )
 
 1172  bool handled = false;
 
 1173  // Checks if an extension is present.
 
 1174  if ( myExtension != 0 )
 
 1176    handled = myExtension->mouseReleaseEvent( *this, e );
 
 1181  if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier) || myIsMovingLight){
 
 1182    myIsMovingLight=false;
 
 1185    QGLViewer::mouseReleaseEvent(e);
 
 1189template <typename TSpace, typename TKSpace>
 
 1190void DGtal::Viewer3D<TSpace, TKSpace>::mouseMoveEvent( QMouseEvent * e )
 
 1192  bool handled = false;
 
 1193  // Checks if an extension is present.
 
 1194  if ( myExtension != 0 )
 
 1196    handled = myExtension->mouseMoveEvent( *this, e );
 
 1201  if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier)){
 
 1202    int varX = e->x() - myRefMouseXPos;
 
 1203    int varY = e->y() - myRefMouseYPos;
 
 1204    myLightPhi -= varY * myLigthRotationStep;
 
 1205    myLightTheta -= varX * myLigthRotationStep / 2.0;
 
 1206    myLightPosition[0] = myLightR*cos(myLightTheta)*cos(myLightPhi);
 
 1207    myLightPosition[1] = myLightR*cos(myLightTheta)*sin(myLightPhi);
 
 1208    myLightPosition[2] = myLightR*sin(myLightTheta);
 
 1209    if(myLightPositionFixToCamera){
 
 1210      updateRelativeCameraFromLightPosition();
 
 1212    glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
 
 1213    myRefMouseXPos = e->x();
 
 1214    myRefMouseYPos = e->y();
 
 1217    QGLViewer::mouseMoveEvent(e);
 
 1221template <typename TSpace, typename TKSpace>
 
 1222void DGtal::Viewer3D<TSpace, TKSpace>::keyPressEvent( QKeyEvent * e )
 
 1224  bool handled = false;
 
 1225  // Checks if an extension is present.
 
 1226  if ( myExtension != 0 )
 
 1228    handled = myExtension->keyPressEvent( *this, e );
 
 1233  if( e->key() == Qt::Key_D)
 
 1235      myIsDoubleFaceRendering = !myIsDoubleFaceRendering;
 
 1236      glUpdateLightRenderingMode();
 
 1240  if( e->key() == Qt::Key_E)
 
 1242      trace.info() << "Exporting mesh..." ;
 
 1243      operator>><TSpace, TKSpace>( *this, "exportedMesh.off" );
 
 1244      trace.info() << "[done]"<< std::endl ;
 
 1246  if( e->key() == Qt::Key_M)
 
 1248      switch (myRenderingMode)
 
 1250        case RenderingMode::RenderingDefault : 
 
 1251          myRenderingMode = RenderingMode::RenderingMetallic;
 
 1253        case RenderingMode::RenderingMetallic : 
 
 1254          myRenderingMode = RenderingMode::RenderingPlastic;
 
 1256        case RenderingMode::RenderingPlastic :
 
 1257          myRenderingMode = RenderingMode::RenderingLambertian;
 
 1259        case RenderingMode::RenderingLambertian : 
 
 1260          myRenderingMode = RenderingMode::RenderingDefault;
 
 1263      updateRenderingCoefficients(myRenderingMode);
 
 1268  if ( ( e->key() ==Qt::Key_W ) )
 
 1270      myViewWire=!myViewWire;
 
 1274    if ( e->key() == Qt::Key_Z )
 
 1276      if ( myLightPositionFixToCamera )
 
 1278        updateLightCoordsFromCamera();
 
 1280      myLightR = sqrt( myLightPosition[ 0 ] * myLightPosition[ 0 ] +
 
 1281                       myLightPosition[ 1 ] * myLightPosition[ 1 ] +
 
 1282                       myLightPosition[ 2 ] * myLightPosition[ 2 ] );
 
 1283      myLightTheta = asin( myLightPosition[ 2 ] / myLightR );
 
 1284      myLightPhi   = atan2( myLightPosition[ 1 ], myLightPosition[ 0 ] );
 
 1286      std::stringstream ss;
 
 1287      if ( e->modifiers() == Qt::ShiftModifier )
 
 1290        ss << "Move away light source at distance: " << myLightR;
 
 1295        ss << "Move closer light source at distance: " << myLightR;
 
 1297      displayMessage( QString( ss.str().c_str() ), 3000 );
 
 1298      myLightPosition[ 0 ] = myLightR * cos( myLightTheta ) * cos( myLightPhi );
 
 1299      myLightPosition[ 1 ] = myLightR * cos( myLightTheta ) * sin( myLightPhi );
 
 1300      myLightPosition[ 2 ] = myLightR * sin( myLightTheta );
 
 1301      if ( myLightPositionFixToCamera )
 
 1303        updateRelativeCameraFromLightPosition();
 
 1305      myIsMovingLight = true;
 
 1306      glLightfv( GL_LIGHT0, GL_POSITION, myLightPosition );
 
 1310    if ( ( e->key() == Qt::Key_P ) )
 
 1312      myLightPositionFixToCamera = !myLightPositionFixToCamera;
 
 1313      setLightModeFixToCamera(myLightPositionFixToCamera);
 
 1316  if ( ( e->key() ==Qt::Key_O ) )
 
 1318      myUseGLPointsForBalls = !myUseGLPointsForBalls;
 
 1323  if ( ( e->key() ==Qt::Key_R ) )
 
 1325      myGLScaleFactorX=1.0f;
 
 1326      myGLScaleFactorY=1.0f;
 
 1327      myGLScaleFactorZ=1.0f;
 
 1331  if ( ( e->key() ==Qt::Key_T ) )
 
 1334      DGtal::trace.info() << "sorting surfel according camera position....";
 
 1335      sortSurfelFromCamera();
 
 1336      sortTriangleFromCamera();
 
 1337      sortQuadFromCamera();
 
 1338      sortPolygonFromCamera();
 
 1339      DGtal::trace.info() << " [done]"<< std::endl;
 
 1343  if ( ( e->key() ==Qt::Key_B ) )
 
 1346      myIsBackgroundDefault=!myIsBackgroundDefault;
 
 1347      glUpdateBackground();
 
 1351 if ( ( e->key() ==Qt::Key_L ) )
 
 1353      if(e->modifiers()==Qt::ShiftModifier){
 
 1356        restoreStateFromFile();
 
 1360  if ( ( e->key() ==Qt::Key_C ) )
 
 1364      GLdouble Projection[16], Modelview[16];
 
 1366      glGetIntegerv ( GL_VIEWPORT , Viewport );
 
 1367      glGetDoublev ( GL_MODELVIEW_MATRIX , Modelview );
 
 1368      glGetDoublev ( GL_PROJECTION_MATRIX, Projection );
 
 1370      for ( unsigned short m=0; m<4; ++m )
 
 1372          for ( unsigned short l=0; l<4; ++l )
 
 1375              for ( unsigned short k=0; k<4; ++k )
 
 1376                sum += Projection[l+4*k]*Modelview[k+4*m];
 
 1380      DGtal::trace.info() << "Viewport: ";
 
 1381      for ( unsigned short l=0; l<4; ++l )
 
 1382        DGtal::trace.info() << Viewport[l] << ", ";
 
 1383      DGtal::trace.info() << std::endl;
 
 1385      Vec cp = camera()->position();
 
 1386      Vec cd = camera()->viewDirection();
 
 1387      Vec cup = camera()->upVector();
 
 1389      DGtal::trace.info() << "camera.position: " ;
 
 1390      for ( unsigned short l=0; l<3; ++l )
 
 1391        DGtal::trace.info() << cp[l] << ", ";
 
 1392      DGtal::trace.info() << std::endl;
 
 1394      DGtal::trace.info() << "camera.direction: ";
 
 1395      for ( unsigned short l=0; l<3; ++l )
 
 1396        DGtal::trace.info() << cd[l] << ", ";
 
 1397      DGtal::trace.info() << std::endl;
 
 1399      DGtal::trace.info() << "camera.upVector: ";
 
 1400      for ( unsigned short l=0; l<3; ++l )
 
 1401        DGtal::trace.info() << cup[l] << ", ";
 
 1402      DGtal::trace.info() << std::endl;
 
 1404      DGtal::trace.info() << "zNear: " << camera()->zNear() << " - zFar: " << camera()->zFar() << std::endl;
 
 1408    QGLViewer::keyPressEvent ( e );
 
 1411template <typename TSpace, typename TKSpace>
 
 1412QString DGtal::Viewer3D<TSpace, TKSpace>::helpString() const
 
 1415  if ( myExtension != 0 )
 
 1416    text += myExtension->helpString( *this );
 
 1418  text += "<h2> Viewer3D</h2>";
 
 1419  text += "Use the mouse to move the camera around the object. ";
 
 1420  text += "You can respectively revolve around, zoom and translate with the three mouse buttons. ";
 
 1421  text += "Left and middle buttons pressed together rotate around the camera view direction axis<br><br>";
 
 1422  text += "Pressing <b>Alt</b> and one of the function keys (<b>F1</b>..<b>F12</b>) defines a camera keyFrame. ";
 
 1423  text += "Simply press the function key again to restore it-> Several keyFrames define a ";
 
 1424  text += "camera path. Paths are saved when you quit the application and restored at next start.<br><br>";
 
 1425  text += "Press <b>F</b> to display the frame rate, <b>A</b> for the world axis, ";
 
 1426  text += "<b>Alt+Return</b> for full screen mode and <b>Control+S</b> to save a snapshot. ";
 
 1427  text += "See the <b>Keyboard</b> tab in this window for a complete shortcut list.<br><br>";
 
 1428  text += "Double clicks automates single click actions: A left button double click aligns the closer axis with the camera (if close enough). ";
 
 1429  text += "A middle button double click fits the zoom of the camera and the right button re-centers the scene.<br><br>";
 
 1430  text += "A left button double click while holding right button pressed defines the camera <i>Revolve Around Ball</i>. ";
 
 1431  text += "See the <b>Mouse</b> tab and the documentation web pages for details.<br><br>";
 
 1432  text += "Press <b>Escape</b> to exit the viewer.";
 
 1436template <typename TSpace, typename TKSpace>
 
 1437void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListCubesMaps(
 
 1438const typename DGtal::Display3D<TSpace, TKSpace>::CubesMap & aCubeMap,
 
 1439unsigned int idList )
 
 1441  glNewList ( idList , GL_COMPILE );
 
 1443  for (auto &mapElem: aCubeMap)
 
 1445      glPushName ( mapElem.first );
 
 1446      glEnable ( GL_LIGHTING );
 
 1447      glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
 
 1448      glBegin ( GL_QUADS );      
 
 1449      bool useColorSelection = false;
 
 1450      if(mySelectedElementId == mapElem.first)
 
 1451        useColorSelection = true;
 
 1453      for (auto   &cube: mapElem.second)
 
 1455          if(useColorSelection)
 
 1457              unsigned char m =  (cube.color.red()+ cube.color.green()+ cube.color.blue())/3;
 
 1460                  glColor4ub ( std::max((int)(cube.color.red())-mySelectionColorShift, 0),
 
 1461                               std::max((int)(cube.color.green())-mySelectionColorShift, 0),
 
 1462                               std::max((int)(cube.color.blue())-mySelectionColorShift, 0),
 
 1463                               cube.color.alpha());              
 
 1466                glColor4ub ( std::min(cube.color.red()+mySelectionColorShift, 255),
 
 1467                             std::min(cube.color.green()+mySelectionColorShift, 255),
 
 1468                             std::min(cube.color.blue()+mySelectionColorShift, 255),
 
 1469                             cube.color.alpha());              
 
 1474              glColor4ub ( cube.color.red(), cube.color.green(), cube.color.blue(),cube.color.alpha());
 
 1476          double _width= cube.width;
 
 1478          glNormal3f ( 0.0, 0.0, 1.0 );
 
 1479          glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
 
 1480          glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
 
 1481          glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
 
 1482          glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]+_width );
 
 1484          glNormal3f ( 0.0, 0.0, -1.0 );
 
 1485          glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
 
 1486          glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]-_width );
 
 1487          glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]-_width );
 
 1488          glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]-_width );
 
 1490          glNormal3f ( 1.0, 0.0, 0.0 );
 
 1491          glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
 
 1492          glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]-_width );
 
 1493          glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]-_width );
 
 1494          glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]+_width );
 
 1496          glNormal3f ( -1.0, 0.0, 0.0 );
 
 1497          glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
 
 1498          glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
 
 1499          glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
 
 1500          glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]-_width );
 
 1502          glNormal3f ( 0.0, 1.0, 0.0 );
 
 1503          glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
 
 1504          glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]+_width );
 
 1505          glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]-_width );
 
 1506          glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
 
 1508          glNormal3f ( 0.0, -1.0, 0.0 );
 
 1509          glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
 
 1510          glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]-_width );
 
 1511          glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]-_width );
 
 1512          glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
 
 1518  glUpdateLightRenderingMode();
 
 1522template <typename TSpace, typename TKSpace>
 
 1523void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListQuadD3D(
 
 1524const VectorQuad & aVectQuad, unsigned int idList )
 
 1526  glNewList ( idList, GL_COMPILE );
 
 1527  glPushName ( myNbListe );
 
 1528  glEnable ( GL_DEPTH_TEST );
 
 1529  glEnable ( GL_BLEND );
 
 1530  glEnable ( GL_MULTISAMPLE_ARB );
 
 1531  glEnable ( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
 
 1532  glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
 1534  glBegin ( GL_QUADS );
 
 1535  for ( auto const &q: aVectQuad )
 
 1537      glColor4ub ( q.color.red(), q.color.green(),
 
 1538                   q.color.blue(), q.color.alpha() );
 
 1539      glNormal3f ( q.nx, q.ny, q.nz );
 
 1540      glVertex3f ( q.point1[0], q.point1[1] , q.point1[2] );
 
 1541      glVertex3f ( q.point2[0], q.point2[1] , q.point2[2] );
 
 1542      glVertex3f ( q.point3[0], q.point3[1] , q.point3[2] );
 
 1543      glVertex3f ( q.point4[0], q.point4[1] , q.point4[2] );
 
 1549template <typename TSpace, typename TKSpace>
 
 1550void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListLines(
 
 1551const VectorLine & aVectLine, unsigned int idList )
 
 1553  glNewList ( idList, GL_COMPILE );
 
 1554  glDisable ( GL_LIGHTING );
 
 1555  glPushName ( myNbListe );
 
 1556  glBegin ( GL_LINES );
 
 1557  for (auto const &l: aVectLine )
 
 1559      glColor4ub ( l.color.red(), l.color.green(),
 
 1560                   l.color.blue(), l.color.alpha() );
 
 1561      glVertex3f ( l.point1[0], l.point1[1], l.point1[2] );
 
 1562      glVertex3f ( l.point2[0], l.point2[1], l.point2[2] );
 
 1565  glEnable ( GL_LIGHTING );
 
 1569template <typename TSpace, typename TKSpace>
 
 1570void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListBalls(
 
 1571const VectorBall & aVectBall, unsigned int idList )
 
 1573  if(myUseGLPointsForBalls)
 
 1575      glNewList ( idList, GL_COMPILE );
 
 1576      glDepthMask ( GL_TRUE );
 
 1577      glDisable ( GL_TEXTURE_2D );
 
 1578      glDisable ( GL_POINT_SMOOTH );
 
 1579      glDisable ( GL_LIGHTING );
 
 1580      glPushName ( myNbListe );
 
 1581      glBegin ( GL_POINTS );
 
 1582      for ( auto const &ball: aVectBall )
 
 1584          glColor4ub ( ball.color.red(), ball.color.green(),
 
 1585                       ball.color.blue(), ball.color.alpha() );
 
 1586          glVertex3f ( ball.center[0], ball.center[1], ball.center[2] );
 
 1589      glEnable ( GL_LIGHTING );
 
 1594      glNewList ( idList, GL_COMPILE );
 
 1595      glPushName ( myNbListe );
 
 1596      glDepthMask ( GL_TRUE );
 
 1597      glDisable ( GL_TEXTURE_2D );
 
 1598      glDisable ( GL_POINT_SMOOTH );
 
 1599      for ( auto const & b: aVectBall)
 
 1608template <typename TSpace, typename TKSpace>
 
 1609void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListQuadMaps(
 
 1610const typename DGtal::Display3D<TSpace, TKSpace>::QuadsMap & aQuadMap,
 
 1611unsigned int idList )
 
 1613  glNewList ( idList, GL_COMPILE );
 
 1614  for (auto & mapElem: aQuadMap)
 
 1616      glPushName ( mapElem.first );
 
 1617      glEnable ( GL_LIGHTING );
 
 1618      glBegin ( GL_QUADS );
 
 1619      bool useColorSelection = false;
 
 1620      if(mySelectedElementId == mapElem.first)
 
 1621        useColorSelection = true;
 
 1623      for (auto &q: mapElem.second)
 
 1625          if(useColorSelection)
 
 1627              unsigned char m = (q.color.red()+ q.color.green()+ q.color.blue())/3;
 
 1630                  glColor4ub ( std::max((int)(q.color.red())-mySelectionColorShift, 0),
 
 1631                               std::max((int)(q.color.green())-mySelectionColorShift, 0),
 
 1632                               std::max((int)(q.color.blue())-mySelectionColorShift, 0),
 
 1636                glColor4ub ( std::min(q.color.red()+mySelectionColorShift, 255),
 
 1637                             std::min(q.color.green()+mySelectionColorShift, 255),
 
 1638                             std::min(q.color.blue()+mySelectionColorShift, 255),
 
 1644              glColor4ub ( q.color.red(), q.color.green(), q.color.blue(), q.color.alpha());              
 
 1648          glNormal3f ( q.nx, q.ny ,q.nz );
 
 1649          glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
 
 1650          glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
 
 1651          glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
 
 1652          glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
 
 1660template <typename TSpace, typename TKSpace>
 
 1661void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListQuadMapsWired(
 
 1662const typename DGtal::Display3D<TSpace, TKSpace>::QuadsMap & aQuadMap,
 
 1663unsigned int idList )
 
 1665  glNewList ( idList, GL_COMPILE );
 
 1666  glPushName ( myNbListe );
 
 1667  glDisable ( GL_LIGHTING );
 
 1668  glBegin ( GL_LINES );
 
 1670  for (auto const &mapElem: aQuadMap)
 
 1672      for(auto const &q: mapElem.second)
 
 1674          glColor4ub ( 150.0,150.0,150.0,255.0 );
 
 1675          glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
 
 1676                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
 
 1677                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
 
 1678                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
 
 1679          glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
 
 1680          glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
 
 1681          glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
 
 1682          glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
 
 1683                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
 
 1684                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
 
 1685                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
 
 1686          glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
 
 1687          glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
 
 1688          glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
 
 1689          glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
 
 1690                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
 
 1691                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
 
 1692                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
 
 1693          glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
 
 1694          glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
 
 1702template <typename TSpace, typename TKSpace>
 
 1703void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListTriangles(
 
 1704const std::vector<VectorTriangle> & aVectTriangle, unsigned int idList )
 
 1706  glNewList ( idList, GL_COMPILE );
 
 1707  glPushName ( myNbListe );
 
 1708  glEnable ( GL_LIGHTING );
 
 1709  glBegin ( GL_TRIANGLES );
 
 1710  for(auto const &tList: aVectTriangle)
 
 1712      for (auto const &t: tList)
 
 1714          glColor4ub (t.color.red(),t.color.green(),t.color.blue(),t.color.alpha() );
 
 1715          glNormal3f (t.nx,t.ny ,t.nz );
 
 1716          glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
 
 1717          glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
 
 1718          glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
 
 1725template <typename TSpace, typename TKSpace>
 
 1726void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListTrianglesWired(
 
 1727const std::vector<VectorTriangle> & aVectTriangle, unsigned int idList )
 
 1729  glNewList ( idList, GL_COMPILE );
 
 1730  glPushName ( myNbListe );
 
 1731  glDisable ( GL_LIGHTING );
 
 1732  glBegin ( GL_LINES );
 
 1733  for (auto const &tList: aVectTriangle)
 
 1735      for (auto const &t: tList)
 
 1737          glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
 
 1738                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
 
 1739                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
 
 1740                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
 
 1741          glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
 
 1742          glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
 
 1743          glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
 
 1744          glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
 
 1745          glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
 
 1746          glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
 
 1754template <typename TSpace, typename TKSpace>
 
 1755void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListPolygons(
 
 1756const std::vector<VectorPolygon> & aVectPolygon, unsigned int idList )
 
 1758  glNewList ( idList, GL_COMPILE );
 
 1759  glPushName ( myNbListe );
 
 1760  glEnable ( GL_LIGHTING );
 
 1762  for(auto const &pList: aVectPolygon)
 
 1764      for (auto const &p: pList)
 
 1766          glBegin ( GL_POLYGON );
 
 1767          glColor4ub ( p.color.red(), p.color.green(), p.color.blue(), p.color.alpha() );
 
 1768          glNormal3f ( p.nx, p.ny ,p.nz );
 
 1769          for(unsigned int j=0;j < (p.vertices).size();j++)
 
 1771              glVertex3f ( (p.vertices).at(j)[0], (p.vertices).at(j)[1], (p.vertices).at ( j )[2] );
 
 1779template <typename TSpace, typename TKSpace>
 
 1780void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListPolygonsWired(
 
 1781const std::vector<VectorPolygon> & aVectPolygon, unsigned int idList )
 
 1783  glNewList ( idList, GL_COMPILE );
 
 1784  glPushName ( myNbListe );
 
 1785  glDisable ( GL_LIGHTING );
 
 1786  glBegin ( GL_LINES );
 
 1787  for(auto const &pList: aVectPolygon)
 
 1789      for (auto const &p: pList)
 
 1791          glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
 
 1792                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
 
 1793                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
 
 1794                      Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
 
 1795          for(unsigned int j=0;j < (p.vertices).size();j++)
 
 1797              glVertex3f ( (p.vertices).at(j)[0], (p.vertices).at(j)[1], (p.vertices).at ( j )[2] );
 
 1798              glVertex3f ( (p.vertices).at((j+1)%(p.vertices).size())[0],
 
 1799                           (p.vertices).at((j+1)%(p.vertices).size())[1],
 
 1800                           (p.vertices).at ( (j+1)%(p.vertices).size() )[2] );
 
 1808template <typename TSpace, typename TKSpace>
 
 1809void DGtal::Viewer3D<TSpace, TKSpace>::glUpdateTextureImages(
 
 1810const VectorTextureImage & aVectImage )
 
 1813  for(unsigned int j=0; j<myVectTextureImage.size(); j++){
 
 1814    glDeleteTextures(1,&(myVectTextureImage[j].myTextureName));
 
 1816  myVectTextureImage.clear();
 
 1817  for(unsigned int j=0; j<aVectImage.size(); j++)
 
 1819      typename Viewer3D<TSpace, TKSpace>::TextureImage aGSImage =
 
 1821      GLTextureImage textureImg(aGSImage);
 
 1823      glGenTextures(1, &textureImg.myTextureName);
 
 1824      glBindTexture(GL_TEXTURE_2D, textureImg.myTextureName);
 
 1826      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 
 1827      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
 1828      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
 1829      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
 1830      if ( textureImg.myMode == Viewer3D<TSpace, TKSpace>::GrayScaleMode )
 
 1832        glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE, textureImg.myBufferWidth,
 
 1833                      textureImg.myBufferHeight, 0, GL_LUMINANCE,
 
 1834                      GL_UNSIGNED_BYTE, textureImg.myTextureImageBufferGS );
 
 1836      else if ( textureImg.myMode == Viewer3D<TSpace, TKSpace>::RGBMode )
 
 1838        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, textureImg.myBufferWidth,
 
 1839                      textureImg.myBufferHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
 
 1840                      textureImg.myTextureImageBufferRGB );
 
 1842      myVectTextureImage.push_back(textureImg);
 
 1846template <typename TSpace, typename TKSpace>
 
 1847void DGtal::Viewer3D<TSpace, TKSpace>::glUpdateLightRenderingMode() const
 
 1849  if(myIsDoubleFaceRendering)
 
 1850    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
 
 1852    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
 
 1856template <typename TSpace, typename TKSpace>
 
 1857void DGtal::Viewer3D<TSpace, TKSpace>::glUpdateBackground() 
 
 1860  if ( !myIsBackgroundDefault )
 
 1862    setBackgroundColor ( QColor ( 255, 255,255, 255 ) );
 
 1866    setBackgroundColor ( QColor ( myDefaultBackgroundColor.red(),
 
 1867                                  myDefaultBackgroundColor.green(),
 
 1868                                  myDefaultBackgroundColor.blue(),
 
 1869                                  myDefaultBackgroundColor.alpha()));
 
 1874template <typename TSpace, typename TKSpace>
 
 1876DGtal::Viewer3D<TSpace, TKSpace>::domElement( const QString & name,
 
 1877                                              QDomDocument & document ) const
 
 1879  // Creates a custom node for a light  position
 
 1880  QDomElement deRendering = document.createElement("Rendering");
 
 1881  deRendering.setAttribute("mode", myRenderingMode);
 
 1882  QDomElement de = document.createElement("Light");
 
 1883  de.setAttribute("pos_light_x", myLightPosition[0]);
 
 1884  de.setAttribute("pos_light_y", myLightPosition[1]);
 
 1885  de.setAttribute("pos_light_z", myLightPosition[2]);
 
 1886  // Get default state domElement and append custom node
 
 1887  QDomElement res = QGLViewer::domElement(name, document);
 
 1888  res.appendChild(de);
 
 1889  res.appendChild(deRendering);
 
 1893template <typename TSpace, typename TKSpace>
 
 1894void DGtal::Viewer3D<TSpace, TKSpace>::initFromDOMElement(
 
 1895const QDomElement & element )
 
 1897  // Restore standard state
 
 1898  QGLViewer::initFromDOMElement(element);
 
 1899  QDomElement child=element.firstChild().toElement();
 
 1900  while (!child.isNull())
 
 1902    if (child.tagName() == "Rendering")
 
 1904        myRenderingMode = (RenderingMode)(child.attribute("mode").toInt());
 
 1906    if (child.tagName() == "Light")
 
 1908      if (child.hasAttribute("pos_light_x"))
 
 1910          myLightPosition[0] = child.attribute("pos_light_x").toDouble();
 
 1913      if (child.hasAttribute("pos_light_y"))
 
 1915          myLightPosition[1] = child.attribute("pos_light_y").toDouble();
 
 1917      if (child.hasAttribute("pos_light_z"))
 
 1919          myLightPosition[2] = child.attribute("pos_light_z").toDouble();
 
 1922    child = child.nextSibling().toElement();
 
 1924  if(myLightPositionFixToCamera){
 
 1925    updateRelativeCameraFromLightPosition();
 
 1927  updateRenderingCoefficients(myRenderingMode, false);
 
 1931template <typename TSpace, typename TKSpace>
 
 1932void DGtal::Viewer3D<TSpace, TKSpace>::closeEvent( QCloseEvent * e )
 
 1934  if (myAutoSaveState)
 
 1938  QGLViewer::closeEvent(e);
 
 1941template <typename TSpace, typename TKSpace>
 
 1942void DGtal::Viewer3D<TSpace, TKSpace>::setGLDoubleRenderingMode(
 
 1943bool doubleSidedRendering )
 
 1945  myIsDoubleFaceRendering = doubleSidedRendering;
 
 1946  glUpdateLightRenderingMode();
 
 1949template <typename TSpace, typename TKSpace>
 
 1950void DGtal::Viewer3D<TSpace, TKSpace>::setGLMaterialShininessCoefficient(
 
 1951const GLfloat matShininessCoeff )
 
 1953  myMaterialShininessCoeff = matShininessCoeff;  
 
 1957template <typename TSpace, typename TKSpace>
 
 1958void DGtal::Viewer3D<TSpace, TKSpace>::setGLLightAmbientCoefficients(
 
 1959const GLfloat lightAmbientCoeffs[ 4 ] )
 
 1961  myLightAmbientCoeffs[0] =  lightAmbientCoeffs[0];
 
 1962  myLightAmbientCoeffs[1] =  lightAmbientCoeffs[1];
 
 1963  myLightAmbientCoeffs[2] =  lightAmbientCoeffs[2];
 
 1964  myLightAmbientCoeffs[3] =  lightAmbientCoeffs[3]; 
 
 1968template <typename TSpace, typename TKSpace>
 
 1969void DGtal::Viewer3D<TSpace, TKSpace>::setGLLightDiffuseCoefficients(
 
 1970const GLfloat lightDiffuseCoeffs[ 4 ] )
 
 1972  myLightDiffuseCoeffs[0] =  lightDiffuseCoeffs[0];
 
 1973  myLightDiffuseCoeffs[1] =  lightDiffuseCoeffs[1];
 
 1974  myLightDiffuseCoeffs[2] =  lightDiffuseCoeffs[2];
 
 1975  myLightDiffuseCoeffs[3] =  lightDiffuseCoeffs[3];
 
 1979template <typename TSpace, typename TKSpace>
 
 1980void DGtal::Viewer3D<TSpace, TKSpace>::setUseGLPointForBalls(
 
 1981const bool useOpenGLPt )
 
 1983  myUseGLPointsForBalls = useOpenGLPt;
 
 1986template <typename TSpace, typename TKSpace>
 
 1987void DGtal::Viewer3D<TSpace, TKSpace>::updateRenderingCoefficients(
 
 1988const RenderingMode aRenderMode, bool displayState )
 
 1990  std::stringstream ss;
 
 1991  ss << "Rendering mode ";
 
 1993  GLfloat newCoefDiff, newCoefSpec = 1.0f;
 
 1994  switch (aRenderMode) 
 
 1996    case RenderingMode::RenderingDefault :
 
 1997      newCoefDiff = myDefaultRenderDiff;
 
 1998      newCoefSpec = myDefaultRenderSpec;
 
 1999      ss << "Default (diffuse with few specular)";
 
 2001    case RenderingMode::RenderingMetallic :
 
 2002      newCoefDiff = myMetallicRenderDiff;
 
 2003      newCoefSpec = myMetallicRenderSpec;
 
 2004      ss << "Metallic (diffuse with specular)";
 
 2006    case RenderingMode::RenderingPlastic :
 
 2007      newCoefDiff = myPlasticRenderDiff;
 
 2008      newCoefSpec = myPlasticRenderSpec;
 
 2009      ss << "Plastic (few diffuse with large specular)";
 
 2011    case RenderingMode::RenderingLambertian :
 
 2012      newCoefDiff = myLambertRenderDiff;
 
 2013      newCoefSpec = myLambertRenderSpec;
 
 2014      ss << "Lambertian (only diffuse)";
 
 2017  for (unsigned int i = 0; i<3; i++) 
 
 2018    myLightDiffuseCoeffs[i] = newCoefDiff;
 
 2019  myLightDiffuseCoeffs[3] = 1.0;
 
 2020  for (unsigned int i = 0; i<3; i++) 
 
 2021    myLightSpecularCoeffs[i] = newCoefSpec;
 
 2022  myLightSpecularCoeffs[3] = 1.0;
 
 2025      displayMessage(QString(ss.str().c_str()), 3000);
 
 2030template <typename TSpace, typename TKSpace>
 
 2031void DGtal::Viewer3D<TSpace, TKSpace>::setGLLightSpecularCoefficients(
 
 2032const GLfloat lightSpecularCoeffs[ 4 ] )
 
 2034  myLightSpecularCoeffs[0] =  lightSpecularCoeffs[0];
 
 2035  myLightSpecularCoeffs[1] =  lightSpecularCoeffs[1];
 
 2036  myLightSpecularCoeffs[2] =  lightSpecularCoeffs[2];
 
 2037  myLightSpecularCoeffs[3] =  lightSpecularCoeffs[3];
 
 2041template <typename TSpace, typename TKSpace>
 
 2042inline void DGtal::Viewer3D<TSpace, TKSpace>::show()
 
 2048template <typename TSpace, typename TKSpace>
 
 2049inline void DGtal::Viewer3D<TSpace, TKSpace>::paintGL()
 
 2051  if ( displaysInStereo() )
 
 2053    for ( int view = 1; view >= 0; --view )
 
 2055      // Clears screen, set model view matrix with shifted matrix for ith buffer
 
 2056      preDrawStereo( view );
 
 2058      // Used defined method. Default is empty
 
 2059      if ( camera()->frame()->isManipulated() )
 
 2067    // Clears screen, set model view matrix...
 
 2070    // Used defined method. Default calls draw()
 
 2071    if ( camera()->frame()->isManipulated() )
 
 2075    // Add visual hints: axis, camera, grid...
 
 2077  Q_EMIT drawFinished( true );
 
 2080template <typename TSpace, typename TKSpace>
 
 2081void DGtal::Viewer3D<TSpace, TKSpace>::updateLightCoordsFromCamera()
 
 2084  posLCam[0] = myLightPositionRefCamera[0];
 
 2085  posLCam[1] = myLightPositionRefCamera[1];
 
 2086  posLCam[2] = myLightPositionRefCamera[2];  
 
 2087  Vec posL = camera()->worldCoordinatesOf(posLCam);
 
 2088  myLightPosition[0] = static_cast<GLfloat>(posL[0]);
 
 2089  myLightPosition[1] = static_cast<GLfloat>(posL[1]);
 
 2090  myLightPosition[2] = static_cast<GLfloat>(posL[2]);
 
 2091  myLightPosition[3] = 1.0f;
 
 2094template <typename TSpace, typename TKSpace>
 
 2095void DGtal::Viewer3D<TSpace, TKSpace>::updateRelativeCameraFromLightPosition()
 
 2098  posL[0] = myLightPosition[0];
 
 2099  posL[1] = myLightPosition[1];
 
 2100  posL[2] = myLightPosition[2];  
 
 2101  Vec posLCam = camera()->cameraCoordinatesOf(posL); 
 
 2102  myLightPositionRefCamera[0] = static_cast<GLfloat>(posLCam[0]);
 
 2103  myLightPositionRefCamera[1] = static_cast<GLfloat>(posLCam[1]);
 
 2104  myLightPositionRefCamera[2] = static_cast<GLfloat>(posLCam[2]);