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"
47 #include <QMessageBox>
48 #include <QTextStream>
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 //////////////////////////////////////////////////////////////////////////////
60 using namespace qglviewer;
62 ///////////////////////////////////////////////////////////////////////////////
63 // Implementation of inline methods //
67 template < typename Space ,typename KSpace >
70 DGtal::Viewer3D<Space, KSpace>::rotateDomain(Image2DDomainD3D &anDom, double angleRotation,
71 ImageDirection rotationDir){
72 DGtal::PointVector<3, int> pt;
73 pt[0] = (int) (anDom.point1[0]+anDom.point2[0]+anDom.point3[0]+anDom.point4[0])/4.0;
74 pt[1] = (int) (anDom.point1[1]+anDom.point2[1]+anDom.point3[1]+anDom.point4[1])/4.0;
75 pt[2] = (int) (anDom.point1[2]+anDom.point2[2]+anDom.point3[2]+anDom.point4[2])/4.0;
76 rotateImageVertex(anDom, angleRotation, rotationDir);
78 std::vector<typename DGtal::Display3D<Space, KSpace>::LineD3D> &aVectLine = Viewer3D<Space, KSpace>::myLineSetList.at(anDom.myLineSetIndex);
79 for(unsigned int i = 0; i< aVectLine.size();i++){
80 typename DGtal::Display3D<Space, KSpace>::LineD3D &aLine = aVectLine.at(i);
81 rotateLineD3D(aLine, pt, angleRotation, rotationDir );
87 template < typename Space ,typename KSpace >
88 template <typename TValues>
91 DGtal::Viewer3D<Space, KSpace>::rotatePoint(TValues &x, TValues &y, TValues &z,
92 double cx, double cy, double cz,
93 double angleRotation, ImageDirection rotationDir){
94 double dx = x-cx; double dy = y-cy; double dz = z-cz;
95 if(rotationDir == zDirection){
96 x = cx+dx*cos(angleRotation)-dy*sin(angleRotation);
97 y = cy+dx*sin(angleRotation)+dy*cos(angleRotation);
99 if(rotationDir == yDirection){
100 x = cx+dx*cos(angleRotation)-dz*sin(angleRotation);
101 z = cz+dx*sin(angleRotation)+dz*cos(angleRotation);
103 if(rotationDir == xDirection){
104 y = cy+dy*cos(angleRotation)-dz*sin(angleRotation);
105 z = cz+dy*sin(angleRotation)+dz*cos(angleRotation);
112 template < typename Space ,typename KSpace >
113 template < typename TContainer >
116 DGtal::Viewer3D<Space, KSpace>::rotateLineD3D(typename DGtal::Display3D<Space, KSpace>::LineD3D &aLine,
117 DGtal::PointVector<3, int, TContainer> pt,
118 double angleRotation, ImageDirection dirRotation){
119 double dx1 = aLine.point1[0] - pt[0]; double dy1 = aLine.point1[1] - pt[1]; double dz1 = aLine.point1[2] - pt[2];
120 double dx2 = aLine.point2[0] - pt[0]; double dy2 = aLine.point2[1] - pt[1]; double dz2 = aLine.point2[2] - pt[2];
121 if(dirRotation==zDirection){
122 aLine.point1[0]=pt[0]+dx1*std::cos(angleRotation)-dy1*std::sin(angleRotation);
123 aLine.point1[1]=pt[1]+dx1*std::sin(angleRotation)+dy1*std::cos(angleRotation);
125 aLine.point2[0]=pt[0]+dx2*std::cos(angleRotation)-dy2*std::sin(angleRotation);
126 aLine.point2[1]=pt[1]+dx2*std::sin(angleRotation)+dy2*std::cos(angleRotation);
128 }else if(dirRotation==xDirection){
129 aLine.point1[1]=pt[1]+dy1*std::cos(angleRotation)-dz1*std::sin(angleRotation);
130 aLine.point1[2]=pt[2]+dy1*std::sin(angleRotation)+dz1*std::cos(angleRotation);
132 aLine.point2[1]=pt[1]+dy2*std::cos(angleRotation)-dz2*std::sin(angleRotation);
133 aLine.point2[2]=pt[2]+dy2*std::sin(angleRotation)+dz2*std::cos(angleRotation);
134 }else if(dirRotation==yDirection){
135 aLine.point1[0]=pt[0]+dx1*std::cos(angleRotation)-dz1*std::sin(angleRotation);
136 aLine.point1[2]=pt[2]+dx1*std::sin(angleRotation)+dz1*std::cos(angleRotation);
138 aLine.point2[0]=pt[0]+dx2*std::cos(angleRotation)-dz2*std::sin(angleRotation);
139 aLine.point2[2]=pt[2]+dx2*std::sin(angleRotation)+dz2*std::cos(angleRotation);
141 trace.error() << "No direction!!"<< std::endl;
147 template < typename Space ,typename KSpace >
150 DGtal::Viewer3D< Space ,KSpace >::getCurrentDomainNumber()
152 return myImageDomainList.size();
155 template < typename Space ,typename KSpace >
158 DGtal::Viewer3D< Space ,KSpace >::getCurrentGLImageNumber()
160 return myGSImageList.size();
164 template < typename Space ,typename KSpace >
167 DGtal::Viewer3D< Space ,KSpace >::addTextureImage(const typename Viewer3D< Space ,KSpace >::TextureImage &image)
169 myGSImageList.push_back(image);
170 Display3D< Space, KSpace>::updateBoundingBox(image.point1);
171 Display3D< Space, KSpace>::updateBoundingBox(image.point2);
172 Display3D< Space, KSpace>::updateBoundingBox(image.point3);
173 Display3D< Space, KSpace>::updateBoundingBox(image.point4);
178 template < typename Space ,typename KSpace >
179 template < typename TImageType, typename TFunctor >
182 DGtal::Viewer3D< Space ,KSpace >::updateTextureImage(unsigned int imageIndex, const TImageType & image, const TFunctor & aFunctor,
183 double xTranslation, double yTranslation, double zTranslation,
184 double rotationAngle, ImageDirection rotationDir)
186 BOOST_CONCEPT_ASSERT(( concepts::CConstImage < TImageType > ));
187 assert ( imageIndex< myGSImageList.size());
188 typename Viewer3D< Space ,KSpace >::TextureImage &anImage = myGSImageList.at(imageIndex);
189 Display::updateBoundingBox(RealPoint(anImage.point1[0]+xTranslation,
190 anImage.point1[1]+yTranslation,
191 anImage.point1[2]+zTranslation));
192 Display::updateBoundingBox(RealPoint(anImage.point2[0]+xTranslation,
193 anImage.point2[1]+yTranslation,
194 anImage.point2[2]+zTranslation));
195 Display::updateBoundingBox(RealPoint(anImage.point3[0]+xTranslation,
196 anImage.point3[1]+yTranslation,
197 anImage.point3[2]+zTranslation));
198 Display::updateBoundingBox(RealPoint(anImage.point4[0]+xTranslation,
199 anImage.point4[1]+yTranslation,
200 anImage.point4[2]+zTranslation));
201 anImage.updateImageDataAndParam(image, aFunctor, xTranslation, yTranslation, zTranslation);
202 if(anImage.myDrawDomain)
204 *this << DGtal::Translate2DDomain(anImage.myIndexDomain, xTranslation, yTranslation, zTranslation);
207 if(rotationAngle!=0.0){
208 rotateDomain(myImageDomainList.at(anImage.myIndexDomain), rotationAngle, rotationDir);
209 rotateImageVertex(anImage, rotationAngle, rotationDir);
214 template < typename Space ,typename KSpace >
217 DGtal::Viewer3D< Space ,KSpace >::updateOrientationTextureImage(unsigned int imageIndex,
221 ImageDirection newDirection)
223 assert ( imageIndex< myGSImageList.size());
224 typename Viewer3D< Space ,KSpace >::TextureImage &anImage = myGSImageList.at(imageIndex);
225 Display3D< Space, KSpace>::updateBoundingBox(anImage.point1);
226 Display3D< Space, KSpace>::updateBoundingBox(anImage.point2);
227 Display3D< Space, KSpace>::updateBoundingBox(anImage.point3);
228 Display3D< Space, KSpace>::updateBoundingBox(anImage.point4);
229 anImage.updateImageOrientation(newDirection, xPosition, yPosition, zPosition);
230 if(anImage.myDrawDomain)
232 *this << DGtal::Update2DDomainPosition<Space ,KSpace >(anImage.myIndexDomain,
235 yPosition, zPosition);
239 template < typename Space ,typename KSpace >
242 DGtal::Viewer3D<Space, KSpace>::updateEmbeddingTextureImage(unsigned int anImageIndex,
243 typename Space::Point aPoint1, typename Space::Point aPoint2,
244 typename Space::Point aPoint3, typename Space::Point aPoint4)
246 assert ( anImageIndex< myGSImageList.size());
247 typename Viewer3D< Space ,KSpace >::TextureImage &anImage = myGSImageList.at(anImageIndex);
248 Display3D< Space, KSpace>::updateBoundingBox(aPoint1);
249 Display3D< Space, KSpace>::updateBoundingBox(aPoint2);
250 Display3D< Space, KSpace>::updateBoundingBox(aPoint3);
251 Display3D< Space, KSpace>::updateBoundingBox(aPoint4);
252 anImage.updateImage3DEmbedding(aPoint1, aPoint2, aPoint3, aPoint4);
258 template < typename Space ,typename KSpace >
261 DGtal::Viewer3D< Space ,KSpace >::TextureImage::updateImageOrientation( ImageDirection normalDir,
262 double xBottomLeft, double yBottomLeft, double zBottomLeft)
264 if(normalDir==zDirection)
266 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft-0.5; point1[2] = zBottomLeft;
267 point2[0] = xBottomLeft+myImageWidth-0.5; point2[1] = yBottomLeft-0.5; point2[2] = zBottomLeft;
268 point3[0] = xBottomLeft+myImageWidth-0.5; point3[1] = yBottomLeft+myImageHeight-0.5; point3[2] = zBottomLeft;
269 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft+myImageHeight-0.5; point4[2] = zBottomLeft;
270 }else if(normalDir==yDirection)
272 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft; point1[2] = zBottomLeft-0.5;
273 point2[0] = xBottomLeft+myImageWidth-0.5; point2[1] = yBottomLeft; point2[2] = zBottomLeft-0.5;
274 point3[0] = xBottomLeft+myImageWidth-0.5; point3[1] = yBottomLeft; point3[2] = zBottomLeft+myImageHeight-0.5;
275 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft; point4[2] = zBottomLeft+myImageHeight-0.5;
276 }else if(normalDir==xDirection)
278 point1[0] = xBottomLeft; point1[1] = yBottomLeft-0.5; point1[2]= zBottomLeft-0.5;
279 point2[0] = xBottomLeft; point2[1] = yBottomLeft+myImageWidth-0.5; point2[2] = zBottomLeft-0.5;
280 point3[0] = xBottomLeft; point3[1] = yBottomLeft+myImageWidth-0.5; point3[2] = zBottomLeft+myImageHeight-0.5;
281 point4[0] = xBottomLeft; point4[1] = yBottomLeft-0.5; point4[2] = zBottomLeft+myImageHeight-0.5;
283 myDirection=normalDir;
286 template < typename Space ,typename KSpace >
289 DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D::updateDomainOrientation(ImageDirection normalDir,
290 double xBottomLeft, double yBottomLeft, double zBottomLeft)
292 if(normalDir==zDirection)
294 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft-0.5; point1[2] = zBottomLeft;
295 point2[0] = xBottomLeft+myDomainWidth-0.5; point2[1] = yBottomLeft-0.5; point2[2] = zBottomLeft;
296 point3[0] = xBottomLeft+myDomainWidth-0.5; point3[1] = yBottomLeft+myDomainHeight-0.5; point3[2] = zBottomLeft;
297 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft+myDomainHeight-0.5; point4[2] = zBottomLeft;
298 }else if(normalDir==yDirection)
300 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft; point1[2] = zBottomLeft-0.5;
301 point2[0] = xBottomLeft+myDomainWidth-0.5; point2[1] = yBottomLeft; point2[2] = zBottomLeft-0.5;
302 point3[0] = xBottomLeft+myDomainWidth-0.5; point3[1] = yBottomLeft; point3[2] = zBottomLeft+myDomainHeight-0.5;
303 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft; point4[2] = zBottomLeft+myDomainHeight-0.5;
304 }else if(normalDir==xDirection)
306 point1[0] = xBottomLeft; point1[1] = yBottomLeft-0.5; point1[2]= zBottomLeft-0.5;
307 point2[0] = xBottomLeft; point2[1] = yBottomLeft+myDomainWidth-0.5; point2[2] = zBottomLeft-0.5;
308 point3[0] = xBottomLeft; point3[1] = yBottomLeft+myDomainWidth-0.5; point3[2] = zBottomLeft+myDomainHeight-0.5;
309 point4[0] = xBottomLeft; point4[1] = yBottomLeft-0.5; point4[2] = zBottomLeft+myDomainHeight-0.5;
311 myDirection=normalDir;
315 template < typename Space ,typename KSpace >
318 DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D::translateDomain (double xTranslation,
322 point1[0] += xTranslation; point1[1] += yTranslation; point1[2] += zTranslation;
323 point2[0] += xTranslation; point2[1] += yTranslation; point2[2] += zTranslation;
324 point3[0] += xTranslation; point3[1] += yTranslation; point3[2] += zTranslation;
325 point4[0] += xTranslation; point4[1] += yTranslation; point4[2] += zTranslation;
329 template < typename Space ,typename KSpace >
330 template < typename TDomain>
332 DGtal::Viewer3D< Space ,KSpace >::addImage2DDomainD3D(const TDomain &aDomain,
334 const DGtal::Color &aColor)
336 typename DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D anImageDomain(aDomain);
337 anImageDomain.color = aColor;
338 anImageDomain.myMode = mode;
339 anImageDomain.myLineSetIndex=Viewer3D<Space, KSpace>::myLineSetList.size();
341 myImageDomainList.push_back(anImageDomain);
342 Display3D< Space, KSpace>::updateBoundingBox(anImageDomain.point1);
343 Display3D< Space, KSpace>::updateBoundingBox(anImageDomain.point2);
344 Display3D< Space, KSpace>::updateBoundingBox(anImageDomain.point3);
345 Display3D< Space, KSpace>::updateBoundingBox(anImageDomain.point4);
347 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> vectLines= compute2DDomainLineRepresentation(anImageDomain);
348 Viewer3D<Space, KSpace>::myLineSetList.push_back(vectLines);
352 template < typename Space ,typename KSpace >
354 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D>
355 DGtal::Viewer3D< Space ,KSpace >::compute2DDomainLineRepresentation( typename DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D &anImageDomain )
357 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> vectLinesResu= compute2DDomainLineRepresentation(anImageDomain, 0.05);
358 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> vectLinesVerso= compute2DDomainLineRepresentation(anImageDomain, -0.05);
359 for(unsigned int i=0; i<vectLinesVerso.size(); i++)
361 vectLinesResu.push_back(vectLinesVerso.at(i));
363 return vectLinesResu;
367 template < typename Space ,typename KSpace >
369 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D>
370 DGtal::Viewer3D< Space ,KSpace >::compute2DDomainLineRepresentation(typename DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D &anImageDomain, double delta )
372 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> aLineSet;
373 typename Viewer3D<Space, KSpace>::LineD3D aLine;
374 aLine.color = anImageDomain.color;
377 if( anImageDomain.myMode=="BoundingBox")
379 aLine.point1[0]=anImageDomain.point1[0]; aLine.point1[1]=anImageDomain.point1[1]; aLine.point1[2]=anImageDomain.point1[2];
380 aLine.point2[0]=anImageDomain.point2[0]; aLine.point2[1]=anImageDomain.point2[1]; aLine.point2[2]=anImageDomain.point2[2];
381 aLineSet.push_back(aLine);
382 aLine.point1[0]=anImageDomain.point2[0]; aLine.point1[1]=anImageDomain.point2[1]; aLine.point1[2]=anImageDomain.point2[2];
383 aLine.point2[0]=anImageDomain.point3[0]; aLine.point2[1]=anImageDomain.point3[1]; aLine.point2[2]=anImageDomain.point3[2];
384 aLineSet.push_back(aLine);
385 aLine.point1[0]=anImageDomain.point3[0]; aLine.point1[1]=anImageDomain.point3[1]; aLine.point1[2]=anImageDomain.point3[2];
386 aLine.point2[0]=anImageDomain.point4[0]; aLine.point2[1]=anImageDomain.point4[1]; aLine.point2[2]=anImageDomain.point4[2];
387 aLineSet.push_back(aLine);
388 aLine.point1[0]=anImageDomain.point4[0]; aLine.point1[1]=anImageDomain.point4[1]; aLine.point1[2]=anImageDomain.point4[2];
389 aLine.point2[0]=anImageDomain.point1[0]; aLine.point2[1]=anImageDomain.point1[1]; aLine.point2[2]=anImageDomain.point1[2];
390 aLineSet.push_back(aLine);
391 }else if(anImageDomain.myMode=="InterGrid")
393 if(anImageDomain.myDirection==zDirection)
395 //lines align to the x direction
396 for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
398 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+i; aLine.point1[2] = anImageDomain.point1[2]+delta;
399 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point2[1]+i; aLine.point2[2] = anImageDomain.point2[2]+delta;
400 aLineSet.push_back(aLine);
402 //lines align to the y direction
403 for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
405 aLine.point1[0] = anImageDomain.point1[0]+i; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+delta;
406 aLine.point2[0] = anImageDomain.point4[0]+i; aLine.point2[1] = anImageDomain.point4[1]; aLine.point2[2] = anImageDomain.point4[2]+delta;
407 aLineSet.push_back(aLine);
409 }else if(anImageDomain.myDirection==xDirection)
411 //lines align to the y direction
412 for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
414 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+i;
415 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point2[1]; aLine.point2[2] = anImageDomain.point1[2]+i;
416 aLineSet.push_back(aLine);
419 //lines align to the z direction
420 for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
422 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]+i; aLine.point1[2] = anImageDomain.point1[2];
423 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point1[1]+i; aLine.point2[2] = anImageDomain.point4[2];
424 aLineSet.push_back(aLine);
426 }else if(anImageDomain.myDirection==yDirection)
428 //lines align to the x direction
429 for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
431 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2]+i;
432 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point1[2]+i;
433 aLineSet.push_back(aLine);
436 //lines align to the z direction
437 for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
439 aLine.point1[0] = anImageDomain.point1[0]+i; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2];
440 aLine.point2[0] = anImageDomain.point1[0]+i; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point4[2];
441 aLineSet.push_back(aLine);
444 }else if(anImageDomain.myMode=="Grid")
446 if(anImageDomain.myDirection==zDirection)
448 //lines align to the x direction
449 for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
451 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+i+0.5; aLine.point1[2] = anImageDomain.point1[2]+delta;
452 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point2[1]+i+0.5; aLine.point2[2] = anImageDomain.point2[2]+delta;
453 aLineSet.push_back(aLine);
455 //lines align to the y direction
456 for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
458 aLine.point1[0] = anImageDomain.point1[0]+i+0.5; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+delta;
459 aLine.point2[0] = anImageDomain.point4[0]+i+0.5; aLine.point2[1] = anImageDomain.point4[1]; aLine.point2[2] = anImageDomain.point4[2]+delta;
460 aLineSet.push_back(aLine);
462 }else if(anImageDomain.myDirection==xDirection)
464 //lines align to the y direction
465 for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
467 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+i+0.5;
468 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point2[1]; aLine.point2[2] = anImageDomain.point1[2]+i+0.5;
469 aLineSet.push_back(aLine);
472 //lines align to the z direction
473 for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
475 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]+i+0.5; aLine.point1[2] = anImageDomain.point1[2];
476 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point1[1]+i+0.5; aLine.point2[2] = anImageDomain.point4[2];
477 aLineSet.push_back(aLine);
479 }else if(anImageDomain.myDirection==yDirection)
481 //lines align to the x direction
482 for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
484 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2]+i+0.5;
485 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point1[2]+i+0.5;
486 aLineSet.push_back(aLine);
489 //lines align to the z direction
490 for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
492 aLine.point1[0] = anImageDomain.point1[0]+i+0.5; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2];
493 aLine.point2[0] = anImageDomain.point1[0]+i+0.5; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point4[2];
494 aLineSet.push_back(aLine);
502 template < typename Space ,typename KSpace >
505 DGtal::Viewer3D< Space ,KSpace >::updateAn2DDomainOrientation(unsigned int domainIndex,
506 double xPosition, double yPosition,
507 double zPosition, ImageDirection newDirection)
509 ASSERT( domainIndex < myImageDomainList.size());
510 typename Viewer3D< Space ,KSpace >::Image2DDomainD3D &aDomain = myImageDomainList.at(domainIndex);
512 Display3D< Space, KSpace>::updateBoundingBox(aDomain.point1);
513 Display3D< Space, KSpace>::updateBoundingBox(aDomain.point2);
514 Display3D< Space, KSpace>::updateBoundingBox(aDomain.point3);
515 Display3D< Space, KSpace>::updateBoundingBox(aDomain.point4);
516 aDomain.updateDomainOrientation(newDirection, xPosition, yPosition, zPosition);
518 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> vectNewLines= compute2DDomainLineRepresentation(aDomain);
519 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> &vectLines = Viewer3D<Space, KSpace>::myLineSetList.at(aDomain.myLineSetIndex);
521 for(unsigned int i=0; i<vectNewLines.size(); i++)
523 vectLines.push_back(vectNewLines.at(i));
529 template < typename Space ,typename KSpace >
532 DGtal::Viewer3D< Space ,KSpace >::translateAn2DDomain(unsigned int domainIndex, double xTranslation, double yTranslation, double zTranslation)
534 typename Viewer3D< Space ,KSpace >::Image2DDomainD3D &anDomain = myImageDomainList.at(domainIndex);
535 anDomain.translateDomain(xTranslation, yTranslation, zTranslation);
537 Display3D< Space, KSpace>::updateBoundingBox(anDomain.point1);
538 Display3D< Space, KSpace>::updateBoundingBox(anDomain.point2);
539 Display3D< Space, KSpace>::updateBoundingBox(anDomain.point3);
540 Display3D< Space, KSpace>::updateBoundingBox(anDomain.point4);
542 std::vector<typename DGtal::Display3D<Space, KSpace>::LineD3D> &vectLines = Viewer3D<Space,KSpace>::myLineSetList.at(anDomain.myLineSetIndex);
543 for(unsigned int i=0; i<vectLines.size(); i++){
544 typename DGtal::Display3D<Space,KSpace>::LineD3D &aLine = vectLines.at(i);
545 aLine.point1[0]=aLine.point1[0]+xTranslation; aLine.point1[1]=aLine.point1[1]+yTranslation; aLine.point1[2]=aLine.point1[2]+zTranslation;
546 aLine.point2[0]=aLine.point2[0]+xTranslation; aLine.point2[1]=aLine.point2[1]+yTranslation; aLine.point2[2]=aLine.point2[2]+zTranslation;
550 template < typename Space ,typename KSpace >
553 DGtal::Viewer3D< Space ,KSpace >::TextureImage::className() const
555 return "TextureImage";
558 template <typename Space, typename KSpace>
560 DGtal::Viewer3D<Space,KSpace> &
561 DGtal::Viewer3D<Space, KSpace>::operator<<(const DGtal::Color & aColor)
563 myDefaultColor=aColor;
567 template <typename Space, typename KSpace>
569 DGtal::Viewer3D<Space, KSpace> &
570 DGtal::Viewer3D<Space, KSpace>::operator<<(const typename Viewer3D<Space, KSpace>::StreamKey & key)
574 case Viewer3D<Space, KSpace>::updateDisplay:
575 Viewer3D<Space, KSpace>::updateList();
578 case Viewer3D<Space, KSpace>::addNewList:
579 Viewer3D<Space, KSpace>::createNewCubeList();
582 case Viewer3D<Space, KSpace>::shiftSurfelVisu:
583 Viewer3D<Space, KSpace>::myCurrentfShiftVisuPrisms+=0.3;
589 template <typename Space, typename KSpace>
590 template <typename TDrawableWithViewer3D>
592 DGtal::Viewer3D<Space, KSpace> &
593 DGtal::Viewer3D<Space, KSpace>::operator<<( const TDrawableWithViewer3D & object )
595 BOOST_CONCEPT_ASSERT((concepts::CDrawableWithViewer3D< TDrawableWithViewer3D, Space, KSpace >));
597 DGtal::Viewer3DFactory<Space,KSpace>::draw(*this, object);
602 ///////////////////////////////////////////////////////////////////////////////
603 // Implementation of inline functions and external operators //
605 template <typename Space, typename KSpace>
608 DGtal::operator<< ( std::ostream & out,
609 const Viewer3D<Space, KSpace> & object )
611 object.selfDisplay ( out );
616 ///////////////////////////////////////////////////////////////////////////////
619 ///////////////////////////////////////////////////////////////////////////////
621 // heritage of parents templates methods //
624 // end of heritage //
625 ///////////////////////////////////////////////////////////////////////////////
627 ///////////////////////////////////////////////////////////////////////////////
629 // surcharge of parents methods //
632 // end of surcharge //
633 ///////////////////////////////////////////////////////////////////////////////
635 template< typename Space, typename KSpace>
638 DGtal::Viewer3D<Space, KSpace>::drawWithNames()
640 // JOL: 2014/10/15. This method is called only when the user tries
641 // to select some graphic object through QGLViewer. By default,
642 // selection is left clic + shift key.
643 // JOL: 2014/10/15. This is my addition for interacting with
644 // quads. Seems to work well.
646 glCallList ( myQuadsMapId );
648 glCallList ( myCubesMapId );
651 for ( unsigned int i=0; i<Viewer3D<Space, KSpace>::myLineSetList.size(); i++ )
653 glCallList ( myLineSetListId+i );
656 for ( unsigned int i=0; i<Viewer3D<Space, KSpace>::myBallSetList.size(); i++ )
658 glCallList(myBallSetListId+i);
663 template< typename Space, typename KSpace>
666 DGtal::Viewer3D<Space, KSpace>::draw()
671 glMultMatrixd ( manipulatedFrame()->matrix() );
673 glScalef(myGLScaleFactorX, myGLScaleFactorY, myGLScaleFactorZ);
675 glLightfv(GL_LIGHT0, GL_SPECULAR, myLightSpecularCoeffs);
676 glLightfv(GL_LIGHT0, GL_DIFFUSE, myLightDiffuseCoeffs);
677 glLightfv(GL_LIGHT0, GL_AMBIENT, myLightAmbientCoeffs);
678 if( myLightPositionFixToCamera ){
679 updateLightCoordsFromCamera();
681 updateRelativeCameraFromLightPosition();
683 glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
686 typename vector< typename Viewer3D<Space, KSpace>::ClippingPlaneD3D >::const_iterator it = Viewer3D<Space, KSpace>::myClippingPlaneList.begin();
688 // OpenGL can't draw more than GL_MAX_CLIP_PLANES clipping plane
689 while ( i < GL_MAX_CLIP_PLANES && it !=Viewer3D<Space, KSpace>::myClippingPlaneList.end() )
696 glEnable ( GL_CLIP_PLANE0+i );
697 glClipPlane ( GL_CLIP_PLANE0+i, eq );
701 if (i == GL_MAX_CLIP_PLANES)
703 std::cerr <<"Warning maximal clipping plane added" << std::endl;
706 Vec centerS = sceneCenter();
707 Vec posCam = camera()->position();
708 double distCam =sqrt ( ( posCam.x-centerS.x ) * ( posCam.x-centerS.x ) +
709 ( posCam.y-centerS.y ) * ( posCam.y-centerS.y ) +
710 ( posCam.z-centerS.z ) * ( posCam.z-centerS.z ) );
711 for(unsigned int j=0; j< myVectTextureImage.size(); j++)
713 GLTextureImage &textureImg = myVectTextureImage.at(j);
714 glPushName ( textureImg.myTextureName );
715 glEnable(GL_TEXTURE_2D);
716 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
717 glBindTexture(GL_TEXTURE_2D, textureImg.myTextureName);
719 glColor4ub ( 255.0, 255.0, 255.0, 255.0 );
720 glNormal3d(textureImg.vectNormal[0], textureImg.vectNormal[1], textureImg.vectNormal[2]);
723 glVertex3f(textureImg.point1[0], textureImg.point1[1], textureImg.point1[2]);
724 glTexCoord2f(textureImg.myTextureFitX, 0.0);
725 glVertex3f(textureImg.point2[0], textureImg.point2[1], textureImg.point2[2]);
726 glTexCoord2f(textureImg.myTextureFitX, textureImg.myTextureFitY);
727 glVertex3f(textureImg.point3[0], textureImg.point3[1], textureImg.point3[2]);
728 glTexCoord2f(0.0, textureImg.myTextureFitY);
729 glVertex3f(textureImg.point4[0], textureImg.point4[1], textureImg.point4[2]);
731 glDisable(GL_TEXTURE_2D);
736 for ( unsigned int j=0; j< Viewer3D<Space, KSpace>::myLineSetList.size(); j++ )
738 if ( Viewer3D<Space, KSpace>::myLineSetList.at ( j ).size() !=0 )
740 glLineWidth ( max(myGLLineMinWidth,
741 Viewer3D<Space, KSpace>::myLineSetList.at ( j ).at ( 0 ).width )) ;
743 glCallList(myLineSetListId+j);
746 glCallList(myPrismListId);
748 glCallList( myCubesMapId );
751 for ( unsigned int j=0; j< Viewer3D<Space, KSpace>::myBallSetList.size(); j++ )
753 if(myUseGLPointsForBalls)
755 if ( Viewer3D<Space, KSpace>::myBallSetList.at ( j ).size() !=0 )
757 glPointSize ( max(myGLPointMinWidth,
758 ( Viewer3D<Space, KSpace>::myBallSetList.at ( j ).at ( 0 ).radius ) ));
762 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
764 glCallList(myBallSetListId+j);
765 glUpdateLightRenderingMode();
768 glDisable(GL_CULL_FACE);
769 glCallList(myQuadsMapId);
772 glLineWidth ( max(myGLLineMinWidth,Viewer3D<Space, KSpace>::myMeshDefaultLineWidth /distCam ));
773 glCallList(myQuadsMapWiredId);
776 glDisable(GL_CULL_FACE);
777 glCallList(myTriangleSetListId);
780 glLineWidth ( max(myGLLineMinWidth,
781 Viewer3D<Space, KSpace>::myMeshDefaultLineWidth /distCam ));
782 glCallList(myTriangleSetListWiredId);
785 glDisable(GL_CULL_FACE);
786 glCallList(myPolygonSetListId);
789 glLineWidth (max(myGLLineMinWidth,
790 Viewer3D<Space, KSpace>::myMeshDefaultLineWidth /distCam ));
791 glCallList(myPolygonSetListWiredId);
795 drawLight(GL_LIGHT0);
803 template< typename Space, typename KSpace>
805 DGtal::Viewer3D<Space, KSpace>::selfDisplay ( std::ostream & out ) const
811 template< typename Space, typename KSpace>
813 DGtal::Viewer3D<Space, KSpace>::isValid() const
818 template< typename Space, typename KSpace>
820 DGtal::Viewer3D<Space, KSpace>::init()
822 myAutoSaveState = false;
823 myIsMovingLight = false;
824 myLigthRotationStep = 0.01;
828 myLightPositionRefCamera[0] = myLightPositionRefCameraDefault[0];
829 myLightPositionRefCamera[1] = myLightPositionRefCameraDefault[1];
830 myLightPositionRefCamera[2] = myLightPositionRefCameraDefault[2];
831 updateLightCoordsFromCamera();
833 glClearColor (0.0, 0.0, 0.0, 0.0);
834 glShadeModel (GL_SMOOTH);
836 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, myMaterialShininessCoeff);
837 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, myMaterialSpecularCoeffs);
840 glLightfv(GL_LIGHT0, GL_SPECULAR, myLightSpecularCoeffs);
841 glLightfv(GL_LIGHT0, GL_DIFFUSE, myLightDiffuseCoeffs);
842 glLightfv(GL_LIGHT0, GL_AMBIENT, myLightAmbientCoeffs);
844 glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
846 glEnable(GL_LIGHTING);
848 glEnable(GL_DEPTH_TEST);
850 Viewer3D<Space, KSpace>::myMeshDefaultLineWidth=10.0;
853 setBackgroundColor ( QColor ( 217, 228, 255 ) );
854 setForegroundColor ( QColor ( 217, 22, 25 ) );
856 Viewer3D<Space, KSpace>::createNewCubeList ( );
857 vector<typename Viewer3D<Space, KSpace>::LineD3D> listeLine;
858 Viewer3D<Space, KSpace>::myLineSetList.push_back ( listeLine );
859 vector<typename Viewer3D<Space, KSpace>::BallD3D> listeBall;
860 Viewer3D<Space, KSpace>::myBallSetList.push_back ( listeBall );
861 Viewer3D<Space, KSpace>::myCurrentFillColor = Color ( 220, 220, 220 );
862 Viewer3D<Space, KSpace>::myCurrentLineColor = Color ( 22, 22, 222, 50 );
863 myDefaultBackgroundColor = Color ( backgroundColor().red(), backgroundColor().green(),
864 backgroundColor().blue() );
865 myIsBackgroundDefault=true;
866 Viewer3D<Space, KSpace>::myBoundingPtLow[0]=-10.0;//numeric_limits<double>::max( );
867 Viewer3D<Space, KSpace>::myBoundingPtLow[1]=-10.0;//numeric_limits<double>::max( );
868 Viewer3D<Space, KSpace>::myBoundingPtLow[2]=-10.0;//numeric_limits<double>::max( );
870 Viewer3D<Space, KSpace>::myBoundingPtUp[0]=-10.0;//numeric_limits<double>::min( );
871 Viewer3D<Space, KSpace>::myBoundingPtUp[1]=-10.0;//numeric_limits<double>::min( );
872 Viewer3D<Space, KSpace>:: myBoundingPtUp[2]=-10.0;//numeric_limits<double>::min( );
873 Viewer3D<Space, KSpace>::createNewCubeList ( );
874 typename std::vector< typename Viewer3D<Space, KSpace>::CubeD3D> aKSCubeList;
876 Viewer3D<Space, KSpace>::myCurrentfShiftVisuPrisms=0.0;
877 Viewer3D<Space, KSpace>::myDefaultColor= Color ( 255, 255, 255 );
878 camera()->showEntireScene();
879 setKeyDescription ( Qt::Key_E, "Export the current display into OFF file (just Cube, surfel and SurfelPrism for now)." );
880 setKeyDescription ( Qt::Key_W, "Switch display with and without wired view of triangle and quad faces." );
881 setKeyDescription ( Qt::Key_T, "Sort elements for display improvements." );
882 setKeyDescription ( Qt::Key_L, "Load last visualisation settings (from a .qglviewer.xml file generated by using SHIFT+L)");
883 setKeyDescription ( Qt::ShiftModifier+Qt::Key_L, "Save visualisation settings." );
884 setKeyDescription ( Qt::Key_B, "Switch background color with White/Black colors." );
885 setKeyDescription ( Qt::Key_C, "Show camera informations." );
886 setKeyDescription ( Qt::Key_R, "Reset default scale for 3 axes to 1.0f." );
887 setKeyDescription ( Qt::Key_D, "Enable/Disable the two side face rendering." );
888 setKeyDescription ( Qt::Key_O, "Switch the ball display mode (quad ball display (default) or OpenGL point)." );
889 setKeyDescription ( Qt::Key_R, "Reset default scale for 3 axes to 1.0f." );
890 setKeyDescription ( Qt::Key_M, "Switch the rendering mode bewteen Default, Metallic and Plastic mode." );
891 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)." );
892 #if !defined (QGLVIEWER_VERSION) || QGLVIEWER_VERSION < 0x020500
893 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).");
895 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).");
899 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
901 #if !defined (QGLVIEWER_VERSION) || QGLVIEWER_VERSION < 0x020500
902 setMouseBindingDescription ( Qt::ShiftModifier+Qt::RightButton, "Delete the mouse selected list." );
904 setMouseBindingDescription ( Qt::ShiftModifier, Qt::RightButton, "Delete the mouse selected list." );
907 setManipulatedFrame ( new ManipulatedFrame() );
911 template< typename Space, typename KSpace>
913 DGtal::Viewer3D<Space, KSpace>::sortSurfelFromCamera()
915 CompFarthestVoxelFromCamera comp;
916 comp.posCam= camera()->position();
918 for (auto &mapElem: Viewer3D<Space, KSpace>::myCubesMap)
921 DGtal::trace.info() << "sort quad size" << mapElem.second.size() << std::endl;
922 sort ( mapElem.second.begin(), mapElem.second.end(), comp );
924 CompFarthestSurfelFromCamera compSurf;
925 DGtal::trace.info() << "sort surfel size" << Viewer3D<Space, KSpace>::myPrismList.size() << std::endl;
926 sort ( Viewer3D<Space, KSpace>::myPrismList.begin(), Viewer3D<Space, KSpace>::myPrismList.end(), compSurf );
932 template< typename Space, typename KSpace>
934 DGtal::Viewer3D<Space, KSpace>::sortTriangleFromCamera()
936 CompFarthestTriangleFromCamera comp;
937 comp.posCam= camera()->position();
938 for (auto &listElem: Viewer3D<Space, KSpace>::myTriangleSetList)
940 sort ( listElem.begin(), listElem.end(), comp );
946 template< typename Space, typename KSpace>
948 DGtal::Viewer3D<Space, KSpace>::sortQuadFromCamera()
950 CompFarthestSurfelFromCamera comp;
951 comp.posCam= camera()->position();
953 for (auto &listElem: Viewer3D<Space, KSpace>::myQuadsMap)
955 DGtal::trace.info() << "sort quad size" << listElem.second.size() << std::endl;
956 sort ( listElem.second.begin(), listElem.second.end(), comp );
961 template< typename Space, typename KSpace>
963 DGtal::Viewer3D<Space, KSpace>::sortPolygonFromCamera()
965 CompFarthestPolygonFromCamera comp;
966 comp.posCam= camera()->position();
968 for (auto &listElem: Viewer3D<Space, KSpace>::myPolygonSetList)
970 DGtal::trace.info() << "sort polygon size" << listElem.size() << std::endl;
971 sort ( listElem.begin(), listElem.end(), comp );
979 template< typename Space, typename KSpace>
981 DGtal::Viewer3D<Space, KSpace>::postSelection ( const QPoint& point )
983 camera()->convertClickToLine ( point, myOrig, myDir );
985 this->myPosSelector= point;
986 mySelectedPoint = camera()->pointUnderPixel ( point, found );
989 DGtal::trace.info() << "Element of liste= " << selectedName() << "selected" << endl;
991 mySelectedElementId = selectedName();
993 SelectCallbackFct fct = getSelectCallback3D( selectedName(), aData );
994 if ( fct ) fct( this, selectedName(), aData );
995 // I leave the remaining code.
997 }else if (mySelectedElementId != -1)
999 mySelectedElementId = -1;
1006 template< typename Space, typename KSpace>
1008 DGtal::Viewer3D<Space, KSpace>::updateList ( bool needToUpdateBoundingBox )
1012 glDeleteLists(myCubesMapId, 1);
1013 glDeleteLists(myLineSetListId, myNbLineSetList);
1014 glDeleteLists(myBallSetListId, myNbBallSetList);
1015 glDeleteLists(myTriangleSetListId, 1);
1016 glDeleteLists(myTriangleSetListWiredId, 1);
1017 glDeleteLists(myPrismListId, 1);
1018 glDeleteLists(myPolygonSetListId, 1);
1019 glDeleteLists(myPolygonSetListWiredId, 1);
1020 glDeleteLists(myQuadsMapId, 1);
1021 glDeleteLists(myQuadsMapWiredId, 1);
1023 // Storing ID for each list
1024 myCubesMapId = glGenLists(1);
1025 myLineSetListId = glGenLists(Viewer3D<Space, KSpace>::myLineSetList.size());
1026 myNbLineSetList = Viewer3D<Space, KSpace>::myLineSetList.size();
1027 myBallSetListId = glGenLists(Viewer3D<Space, KSpace>::myBallSetList.size());
1028 myNbBallSetList = Viewer3D<Space, KSpace>::myBallSetList.size();
1029 myTriangleSetListId = glGenLists(1);
1030 myTriangleSetListWiredId = glGenLists(1);
1031 myCubeSetListWiredId = glGenLists(1);
1032 myPolygonSetListId = glGenLists(1);
1033 myPolygonSetListWiredId = glGenLists(1);
1034 myQuadsMapId = glGenLists(1);
1035 myQuadsMapWiredId = glGenLists(1);
1036 myPrismListId = glGenLists(1);
1041 glEnable ( GL_BLEND );
1042 glEnable ( GL_MULTISAMPLE_ARB );
1043 glEnable ( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
1044 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1048 glCreateListCubesMaps(Viewer3D<Space, KSpace>::myCubesMap, myCubesMapId);
1051 glCreateListQuadD3D(Viewer3D<Space, KSpace>::myPrismList, myPrismListId);
1054 for ( unsigned int j=0; j<Viewer3D<Space, KSpace>::myLineSetList.size(); j++ )
1056 glCreateListLines(Viewer3D<Space, KSpace>::myLineSetList.at(j), myLineSetListId+j);
1060 for ( unsigned int j=0; j<Viewer3D<Space, KSpace>::myBallSetList.size(); j++ )
1062 glCreateListBalls(Viewer3D<Space, KSpace>::myBallSetList.at (j), myBallSetListId+j);
1067 // First list: quad faces.
1068 glCreateListQuadMaps(Viewer3D<Space, KSpace>::myQuadsMap, myQuadsMapId);
1071 // Second list: Wired version of quad face.
1072 glCreateListQuadMapsWired(Viewer3D<Space, KSpace>::myQuadsMap,myQuadsMapWiredId);
1075 // Third list: Triangle faces.
1076 glCreateListTriangles( Viewer3D<Space, KSpace>::myTriangleSetList, myTriangleSetListId);
1079 // Fourth list: Wired version of triangle face.
1080 glCreateListTrianglesWired(Viewer3D<Space, KSpace>::myTriangleSetList, myTriangleSetListWiredId);
1083 // Fifth list: Polygonal faces.
1084 glCreateListPolygons(Viewer3D<Space, KSpace>::myPolygonSetList, myPolygonSetListId);
1087 // Sixth list: Wired version of polygonal face.
1088 glCreateListPolygonsWired(Viewer3D<Space, KSpace>::myPolygonSetList, myPolygonSetListWiredId);
1092 // Seventh list: Textured images.
1093 glUpdateTextureImages(myGSImageList);
1096 if ( needToUpdateBoundingBox )
1098 setSceneBoundingBox ( qglviewer::Vec ( Viewer3D<Space, KSpace>::myBoundingPtLow[0],
1099 Viewer3D<Space, KSpace>::myBoundingPtLow[1],
1100 Viewer3D<Space, KSpace>::myBoundingPtLow[2] ),
1101 qglviewer::Vec ( Viewer3D<Space, KSpace>::myBoundingPtUp[0],
1102 Viewer3D<Space, KSpace>::myBoundingPtUp[1],
1103 Viewer3D<Space, KSpace>::myBoundingPtUp[2] ) );
1111 template< typename Space, typename KSpace>
1113 DGtal::Viewer3D<Space, KSpace>::glDrawGLBall (const typename Viewer3D<Space, KSpace>::BallD3D &aBall )
1115 double thetaResolution = aBall.resolution;
1116 double thetaStep= (2.0*M_PI)/thetaResolution;
1117 double phiResolution = aBall.resolution;
1118 double phiStep= M_PI/phiResolution;
1120 double radius = aBall.radius;
1121 double xCenter = aBall.center[0];
1122 double yCenter = aBall.center[1];
1123 double zCenter = aBall.center[2];
1124 glBegin(GL_QUAD_STRIP);
1125 for(unsigned int j =0; j < phiResolution; j++)
1127 double phi0 = M_PI/2.0-j*phiStep;
1128 double phi1 = M_PI/2.0-(j+1)*phiStep;
1129 for(unsigned int i =0; i <= thetaResolution; i++)
1131 double theta0 = i * thetaStep;
1132 glColor4ub ( aBall.color.red(), aBall.color.green(), aBall.color.blue(), aBall.color.alpha() );
1133 glNormal3f(cos(phi0)*cos(theta0), cos(phi0)*sin(theta0), sin(phi0));
1134 glVertex3f(xCenter+cos(phi0)*cos(theta0)*radius,yCenter+ cos(phi0)*sin(theta0)*radius, zCenter+ sin(phi0)*radius);
1135 glNormal3f(cos(phi1)*cos(theta0), cos(phi1)*sin(theta0), sin(phi1));
1136 glVertex3f(xCenter+cos(phi1)*cos(theta0)*radius,yCenter+ cos(phi1)*sin(theta0)*radius, zCenter+ sin(phi1)*radius);
1143 template< typename Space, typename KSpace>
1145 DGtal::Viewer3D<Space, KSpace>::mousePressEvent ( QMouseEvent *e )
1147 if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier))
1149 myIsMovingLight=true;
1150 myRefMouseXPos = e->x();
1151 myRefMouseYPos = e->y();
1152 if( myLightPositionFixToCamera )
1154 updateLightCoordsFromCamera();
1156 myLightR = sqrt( myLightPosition[0]* myLightPosition[0]+
1157 myLightPosition[1]* myLightPosition[1]+
1158 myLightPosition[2]* myLightPosition[2]);
1159 myLightTheta = asin( myLightPosition[2]/myLightR);
1160 myLightPhi = atan2( myLightPosition[1], myLightPosition[0]);
1164 QGLViewer::mousePressEvent(e);
1168 template< typename Space, typename KSpace>
1170 DGtal::Viewer3D<Space, KSpace>::mouseReleaseEvent ( QMouseEvent *e )
1172 if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier) || myIsMovingLight){
1173 myIsMovingLight=false;
1176 QGLViewer::mouseReleaseEvent(e);
1180 template< typename Space, typename KSpace>
1182 DGtal::Viewer3D<Space, KSpace>::mouseMoveEvent ( QMouseEvent *e )
1184 if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier)){
1185 int varX = e->x() - myRefMouseXPos;
1186 int varY = e->y() - myRefMouseYPos;
1187 myLightPhi += varX*myLigthRotationStep;
1188 myLightTheta += varY*myLigthRotationStep/2.0;
1189 myLightPosition[0] = myLightR*cos(myLightTheta)*cos(myLightPhi);
1190 myLightPosition[1] = myLightR*cos(myLightTheta)*sin(myLightPhi);
1191 myLightPosition[2] = myLightR*sin(myLightTheta);
1192 if(myLightPositionFixToCamera){
1193 updateRelativeCameraFromLightPosition();
1195 glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
1196 myRefMouseXPos = e->x();
1197 myRefMouseYPos = e->y();
1200 QGLViewer::mouseMoveEvent(e);
1207 template< typename Space, typename KSpace>
1209 DGtal::Viewer3D<Space, KSpace>::keyPressEvent ( QKeyEvent *e )
1211 bool handled = false;
1213 if( e->key() == Qt::Key_D)
1215 myIsDoubleFaceRendering = !myIsDoubleFaceRendering;
1216 glUpdateLightRenderingMode();
1220 if( e->key() == Qt::Key_E)
1222 trace.info() << "Exporting mesh..." ;
1223 operator>> <Space, KSpace>(*this, "exportedMesh.off");
1224 trace.info() << "[done]"<< endl ;
1226 if( e->key() == Qt::Key_M)
1228 switch (myRenderingMode)
1230 case RenderingMode::RenderingDefault :
1231 myRenderingMode = RenderingMode::RenderingMetallic;
1233 case RenderingMode::RenderingMetallic :
1234 myRenderingMode = RenderingMode::RenderingPlastic;
1236 case RenderingMode::RenderingPlastic :
1237 myRenderingMode = RenderingMode::RenderingLambertian;
1239 case RenderingMode::RenderingLambertian :
1240 myRenderingMode = RenderingMode::RenderingDefault;
1243 updateRenderingCoefficients(myRenderingMode);
1248 if ( ( e->key() ==Qt::Key_W ) )
1250 myViewWire=!myViewWire;
1255 if ( ( e->key() ==Qt::Key_P ) )
1257 myLightPositionFixToCamera =! myLightPositionFixToCamera;
1258 updateLightCoordsFromCamera();
1259 if(myLightPositionFixToCamera)
1261 displayMessage(QString("Light source position fixed to camera."), 3000);
1262 updateRelativeCameraFromLightPosition();
1266 displayMessage(QString("Light source position fixed to main scene."), 3000);
1267 //updateLightCoordsFromCamera();
1272 if ( ( e->key() ==Qt::Key_O ) )
1274 myUseGLPointsForBalls = !myUseGLPointsForBalls;
1279 if ( ( e->key() ==Qt::Key_R ) )
1281 myGLScaleFactorX=1.0f;
1282 myGLScaleFactorY=1.0f;
1283 myGLScaleFactorZ=1.0f;
1287 if ( ( e->key() ==Qt::Key_T ) )
1290 DGtal::trace.info() << "sorting surfel according camera position....";
1291 sortSurfelFromCamera();
1292 sortTriangleFromCamera();
1293 sortQuadFromCamera();
1294 sortPolygonFromCamera();
1295 DGtal::trace.info() << " [done]"<< std::endl;
1299 if ( ( e->key() ==Qt::Key_B ) )
1302 myIsBackgroundDefault=!myIsBackgroundDefault;
1303 if ( !myIsBackgroundDefault )
1305 setBackgroundColor ( QColor ( 255, 255,255 ) );
1309 setBackgroundColor ( QColor ( 217, 228, 255 ) );
1314 if ( ( e->key() ==Qt::Key_L ) )
1316 if(e->modifiers()==Qt::ShiftModifier){
1319 restoreStateFromFile();
1323 if ( ( e->key() ==Qt::Key_C ) )
1327 GLdouble Projection[16], Modelview[16];
1329 glGetIntegerv ( GL_VIEWPORT , Viewport );
1330 glGetDoublev ( GL_MODELVIEW_MATRIX , Modelview );
1331 glGetDoublev ( GL_PROJECTION_MATRIX, Projection );
1333 for ( unsigned short m=0; m<4; ++m )
1335 for ( unsigned short l=0; l<4; ++l )
1338 for ( unsigned short k=0; k<4; ++k )
1339 sum += Projection[l+4*k]*Modelview[k+4*m];
1343 DGtal::trace.info() << "Viewport: ";
1344 for ( unsigned short l=0; l<4; ++l )
1345 DGtal::trace.info() << Viewport[l] << ", ";
1346 DGtal::trace.info() << std::endl;
1348 Vec cp = camera()->position();
1349 Vec cd = camera()->viewDirection();
1350 Vec cup = camera()->upVector();
1352 DGtal::trace.info() << "camera.position: " ;
1353 for ( unsigned short l=0; l<3; ++l )
1354 DGtal::trace.info() << cp[l] << ", ";
1355 DGtal::trace.info() << std::endl;
1357 DGtal::trace.info() << "camera.direction: ";
1358 for ( unsigned short l=0; l<3; ++l )
1359 DGtal::trace.info() << cd[l] << ", ";
1360 DGtal::trace.info() << std::endl;
1362 DGtal::trace.info() << "camera.upVector: ";
1363 for ( unsigned short l=0; l<3; ++l )
1364 DGtal::trace.info() << cup[l] << ", ";
1365 DGtal::trace.info() << std::endl;
1367 DGtal::trace.info() << "zNear: " << camera()->zNear() << " - zFar: " << camera()->zFar() << std::endl;
1371 QGLViewer::keyPressEvent ( e );
1377 template< typename Space, typename KSpace>
1379 DGtal::Viewer3D<Space, KSpace>::helpString() const
1381 QString text ( "<h2> Viewer3D</h2>" );
1382 text += "Use the mouse to move the camera around the object. ";
1383 text += "You can respectively revolve around, zoom and translate with the three mouse buttons. ";
1384 text += "Left and middle buttons pressed together rotate around the camera view direction axis<br><br>";
1385 text += "Pressing <b>Alt</b> and one of the function keys (<b>F1</b>..<b>F12</b>) defines a camera keyFrame. ";
1386 text += "Simply press the function key again to restore it-> Several keyFrames define a ";
1387 text += "camera path. Paths are saved when you quit the application and restored at next start.<br><br>";
1388 text += "Press <b>F</b> to display the frame rate, <b>A</b> for the world axis, ";
1389 text += "<b>Alt+Return</b> for full screen mode and <b>Control+S</b> to save a snapshot. ";
1390 text += "See the <b>Keyboard</b> tab in this window for a complete shortcut list.<br><br>";
1391 text += "Double clicks automates single click actions: A left button double click aligns the closer axis with the camera (if close enough). ";
1392 text += "A middle button double click fits the zoom of the camera and the right button re-centers the scene.<br><br>";
1393 text += "A left button double click while holding right button pressed defines the camera <i>Revolve Around Ball</i>. ";
1394 text += "See the <b>Mouse</b> tab and the documentation web pages for details.<br><br>";
1395 text += "Press <b>Escape</b> to exit the viewer.";
1402 template< typename Space, typename KSpace>
1404 DGtal::Viewer3D<Space, KSpace>::glCreateListCubesMaps(const typename DGtal::Display3D<Space, KSpace>::CubesMap &aCubeMap,
1405 unsigned int idList){
1406 glNewList ( idList , GL_COMPILE );
1408 for (auto &mapElem: aCubeMap)
1410 glPushName ( mapElem.first );
1411 glEnable ( GL_LIGHTING );
1412 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
1413 glBegin ( GL_QUADS );
1414 bool useColorSelection = false;
1415 if(mySelectedElementId == mapElem.first)
1416 useColorSelection = true;
1418 for (auto &cube: mapElem.second)
1420 if(useColorSelection)
1422 unsigned char m = (cube.color.red()+ cube.color.green()+ cube.color.blue())/3;
1425 glColor4ub ( std::max((int)(cube.color.red())-mySelectionColorShift, 0),
1426 std::max((int)(cube.color.green())-mySelectionColorShift, 0),
1427 std::max((int)(cube.color.blue())-mySelectionColorShift, 0),
1428 cube.color.alpha());
1431 glColor4ub ( std::min(cube.color.red()+mySelectionColorShift, 255),
1432 std::min(cube.color.green()+mySelectionColorShift, 255),
1433 std::min(cube.color.blue()+mySelectionColorShift, 255),
1434 cube.color.alpha());
1439 glColor4ub ( cube.color.red(), cube.color.green(), cube.color.blue(),cube.color.alpha());
1441 double _width= cube.width;
1443 glNormal3f ( 0.0, 0.0, 1.0 );
1444 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
1445 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
1446 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
1447 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]+_width );
1449 glNormal3f ( 0.0, 0.0, -1.0 );
1450 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
1451 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]-_width );
1452 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]-_width );
1453 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]-_width );
1455 glNormal3f ( 1.0, 0.0, 0.0 );
1456 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
1457 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]-_width );
1458 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]-_width );
1459 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]+_width );
1461 glNormal3f ( -1.0, 0.0, 0.0 );
1462 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
1463 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
1464 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
1465 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]-_width );
1467 glNormal3f ( 0.0, 1.0, 0.0 );
1468 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
1469 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]+_width );
1470 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]-_width );
1471 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
1473 glNormal3f ( 0.0, -1.0, 0.0 );
1474 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
1475 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]-_width );
1476 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]-_width );
1477 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
1483 glUpdateLightRenderingMode();
1489 template< typename Space, typename KSpace>
1491 DGtal::Viewer3D<Space, KSpace>::glCreateListQuadD3D(const VectorQuad &aVectQuad,
1492 unsigned int idList){
1493 glNewList ( idList, GL_COMPILE );
1494 glPushName ( myNbListe );
1495 glEnable ( GL_DEPTH_TEST );
1496 glEnable ( GL_BLEND );
1497 glEnable ( GL_MULTISAMPLE_ARB );
1498 glEnable ( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
1499 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1501 glBegin ( GL_QUADS );
1502 for ( auto const &q: aVectQuad )
1504 glColor4ub ( q.color.red(), q.color.green(),
1505 q.color.blue(), q.color.alpha() );
1506 glNormal3f ( q.nx, q.ny, q.nz );
1507 glVertex3f ( q.point1[0], q.point1[1] , q.point1[2] );
1508 glVertex3f ( q.point2[0], q.point2[1] , q.point2[2] );
1509 glVertex3f ( q.point3[0], q.point3[1] , q.point3[2] );
1510 glVertex3f ( q.point4[0], q.point4[1] , q.point4[2] );
1518 template< typename Space, typename KSpace>
1520 DGtal::Viewer3D<Space, KSpace>::glCreateListLines(const VectorLine &aVectLine,
1521 unsigned int idList){
1522 glNewList ( idList, GL_COMPILE );
1523 glDisable ( GL_LIGHTING );
1524 glPushName ( myNbListe );
1525 glBegin ( GL_LINES );
1526 for (auto const &l: aVectLine )
1528 glColor4ub ( l.color.red(), l.color.green(),
1529 l.color.blue(), l.color.alpha() );
1530 glVertex3f ( l.point1[0], l.point1[1], l.point1[2] );
1531 glVertex3f ( l.point2[0], l.point2[1], l.point2[2] );
1534 glEnable ( GL_LIGHTING );
1540 template< typename Space, typename KSpace>
1542 DGtal::Viewer3D<Space, KSpace>::glCreateListBalls(const VectorBall &aVectBall,
1543 unsigned int idList){
1544 if(myUseGLPointsForBalls)
1546 glNewList ( idList, GL_COMPILE );
1547 glDepthMask ( GL_TRUE );
1548 glDisable ( GL_TEXTURE_2D );
1549 glDisable ( GL_POINT_SMOOTH );
1550 glDisable ( GL_LIGHTING );
1551 glPushName ( myNbListe );
1552 glBegin ( GL_POINTS );
1553 for ( auto const &ball: aVectBall )
1555 glColor4ub ( ball.color.red(), ball.color.green(),
1556 ball.color.blue(), ball.color.alpha() );
1557 glVertex3f ( ball.center[0], ball.center[1], ball.center[2] );
1560 glEnable ( GL_LIGHTING );
1565 glNewList ( idList, GL_COMPILE );
1566 glPushName ( myNbListe );
1567 glDepthMask ( GL_TRUE );
1568 glDisable ( GL_TEXTURE_2D );
1569 glDisable ( GL_POINT_SMOOTH );
1570 for ( auto const & b: aVectBall)
1582 template< typename Space, typename KSpace>
1584 DGtal::Viewer3D<Space, KSpace>::glCreateListQuadMaps(const typename DGtal::Display3D<Space, KSpace>::QuadsMap &aQuadMap,
1585 unsigned int idList){
1586 glNewList ( idList, GL_COMPILE );
1587 for (auto & mapElem: aQuadMap)
1589 glPushName ( mapElem.first );
1590 glEnable ( GL_LIGHTING );
1591 glBegin ( GL_QUADS );
1592 bool useColorSelection = false;
1593 if(mySelectedElementId == mapElem.first)
1594 useColorSelection = true;
1596 for (auto &q: mapElem.second)
1598 if(useColorSelection)
1600 unsigned char m = (q.color.red()+ q.color.green()+ q.color.blue())/3;
1603 glColor4ub ( std::max((int)(q.color.red())-mySelectionColorShift, 0),
1604 std::max((int)(q.color.green())-mySelectionColorShift, 0),
1605 std::max((int)(q.color.blue())-mySelectionColorShift, 0),
1609 glColor4ub ( std::min(q.color.red()+mySelectionColorShift, 255),
1610 std::min(q.color.green()+mySelectionColorShift, 255),
1611 std::min(q.color.blue()+mySelectionColorShift, 255),
1617 glColor4ub ( q.color.red(), q.color.green(), q.color.blue(), q.color.alpha());
1621 glNormal3f ( q.nx, q.ny ,q.nz );
1622 glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
1623 glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
1624 glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
1625 glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
1636 template< typename Space, typename KSpace>
1638 DGtal::Viewer3D<Space, KSpace>::glCreateListQuadMapsWired(const typename DGtal::Display3D<Space, KSpace>::QuadsMap &aQuadMap,
1639 unsigned int idList){
1640 glNewList ( idList, GL_COMPILE );
1641 glPushName ( myNbListe );
1642 glDisable ( GL_LIGHTING );
1643 glBegin ( GL_LINES );
1645 for (auto const &mapElem: aQuadMap)
1647 for(auto const &q: mapElem.second)
1649 glColor4ub ( 150.0,150.0,150.0,255.0 );
1650 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1651 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1652 Viewer3D<Space, KSpace>::myCurrentLineColor.blue(),
1653 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1654 glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
1655 glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
1656 glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
1657 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1658 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1659 Viewer3D<Space, KSpace>::myCurrentLineColor.blue(),
1660 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1661 glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
1662 glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
1663 glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
1664 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1665 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1666 Viewer3D<Space, KSpace>::myCurrentLineColor.blue(),
1667 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1668 glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
1669 glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
1678 template< typename Space, typename KSpace>
1680 DGtal::Viewer3D<Space, KSpace>::glCreateListTriangles(const std::vector<VectorTriangle> &aVectTriangle,
1681 unsigned int idList){
1682 glNewList ( idList, GL_COMPILE );
1683 glPushName ( myNbListe );
1684 glEnable ( GL_LIGHTING );
1685 glBegin ( GL_TRIANGLES );
1686 for(auto const &tList: aVectTriangle)
1688 for (auto const &t: tList)
1690 glColor4ub (t.color.red(),t.color.green(),t.color.blue(),t.color.alpha() );
1691 glNormal3f (t.nx,t.ny ,t.nz );
1692 glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
1693 glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
1694 glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
1702 template< typename Space, typename KSpace>
1704 DGtal::Viewer3D<Space, KSpace>::glCreateListTrianglesWired(const std::vector<VectorTriangle> &aVectTriangle,
1705 unsigned int idList){
1706 glNewList ( idList, GL_COMPILE );
1707 glPushName ( myNbListe );
1708 glDisable ( GL_LIGHTING );
1709 glBegin ( GL_LINES );
1710 for (auto const &tList: aVectTriangle)
1712 for (auto const &t: tList)
1714 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1715 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1716 Viewer3D<Space, KSpace>::myCurrentLineColor.blue(),
1717 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1718 glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
1719 glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
1720 glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
1721 glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
1722 glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
1723 glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
1733 template< typename Space, typename KSpace>
1735 DGtal::Viewer3D<Space, KSpace>::glCreateListPolygons(const std::vector<VectorPolygon> &aVectPolygon,
1736 unsigned int idList){
1737 glNewList ( idList, GL_COMPILE );
1738 glPushName ( myNbListe );
1739 glEnable ( GL_LIGHTING );
1741 for(auto const &pList: aVectPolygon)
1743 for (auto const &p: pList)
1745 glBegin ( GL_POLYGON );
1746 glColor4ub ( p.color.red(), p.color.green(), p.color.blue(), p.color.alpha() );
1747 glNormal3f ( p.nx, p.ny ,p.nz );
1748 for(unsigned int j=0;j < (p.vertices).size();j++)
1750 glVertex3f ( (p.vertices).at(j)[0], (p.vertices).at(j)[1], (p.vertices).at ( j )[2] );
1760 template< typename Space, typename KSpace>
1762 DGtal::Viewer3D<Space, KSpace>::glCreateListPolygonsWired(const std::vector<VectorPolygon> &aVectPolygon,
1763 unsigned int idList){
1764 glNewList ( idList, GL_COMPILE );
1765 glPushName ( myNbListe );
1766 glDisable ( GL_LIGHTING );
1767 glBegin ( GL_LINES );
1768 for(auto const &pList: aVectPolygon)
1770 for (auto const &p: pList)
1772 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1773 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1774 Viewer3D<Space, KSpace>::myCurrentLineColor.blue() ,
1775 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1776 for(unsigned int j=0;j < (p.vertices).size();j++)
1778 glVertex3f ( (p.vertices).at(j)[0], (p.vertices).at(j)[1], (p.vertices).at ( j )[2] );
1779 glVertex3f ( (p.vertices).at((j+1)%(p.vertices).size())[0],
1780 (p.vertices).at((j+1)%(p.vertices).size())[1],
1781 (p.vertices).at ( (j+1)%(p.vertices).size() )[2] );
1791 template< typename Space, typename KSpace>
1793 DGtal::Viewer3D<Space, KSpace>::glUpdateTextureImages(const VectorTextureImage &aVectImage){
1795 for(unsigned int j=0; j<myVectTextureImage.size(); j++){
1796 glDeleteTextures(1,&(myVectTextureImage[j].myTextureName));
1798 myVectTextureImage.clear();
1799 for(unsigned int j=0; j<aVectImage.size(); j++)
1801 typename Viewer3D<Space, KSpace>::TextureImage aGSImage = aVectImage.at(j);
1802 GLTextureImage textureImg(aGSImage);
1804 glGenTextures(1, &textureImg.myTextureName);
1805 glBindTexture(GL_TEXTURE_2D, textureImg.myTextureName);
1807 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1808 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1809 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1810 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1811 if(textureImg.myMode==Viewer3D<Space, KSpace>::GrayScaleMode)
1813 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, textureImg.myBufferWidth, textureImg.myBufferHeight, 0,
1814 GL_LUMINANCE, GL_UNSIGNED_BYTE, textureImg.myTextureImageBufferGS);
1815 }else if(textureImg.myMode==Viewer3D<Space, KSpace>::RGBMode)
1817 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureImg.myBufferWidth, textureImg.myBufferHeight, 0,
1818 GL_RGB, GL_UNSIGNED_BYTE, textureImg.myTextureImageBufferRGB);
1820 myVectTextureImage.push_back(textureImg);
1824 template< typename Space, typename KSpace>
1826 DGtal::Viewer3D<Space, KSpace>::glUpdateLightRenderingMode() const
1828 if(myIsDoubleFaceRendering)
1829 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
1831 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
1836 template< typename Space, typename KSpace>
1838 DGtal::Viewer3D<Space, KSpace>::domElement(const QString& name, QDomDocument& document) const
1840 // Creates a custom node for a light position
1841 QDomElement deRendering = document.createElement("Rendering");
1842 deRendering.setAttribute("mode", myRenderingMode);
1843 QDomElement de = document.createElement("Light");
1844 de.setAttribute("pos_light_x", myLightPosition[0]);
1845 de.setAttribute("pos_light_y", myLightPosition[1]);
1846 de.setAttribute("pos_light_z", myLightPosition[2]);
1847 // Get default state domElement and append custom node
1848 QDomElement res = QGLViewer::domElement(name, document);
1849 res.appendChild(de);
1850 res.appendChild(deRendering);
1856 template< typename Space, typename KSpace>
1858 DGtal::Viewer3D<Space, KSpace>::initFromDOMElement(const QDomElement& element)
1860 // Restore standard state
1861 QGLViewer::initFromDOMElement(element);
1862 QDomElement child=element.firstChild().toElement();
1863 while (!child.isNull())
1865 if (child.tagName() == "Rendering")
1867 myRenderingMode = (RenderingMode)(child.attribute("mode").toInt());
1869 if (child.tagName() == "Light")
1871 if (child.hasAttribute("pos_light_x"))
1873 myLightPosition[0] = child.attribute("pos_light_x").toDouble();
1876 if (child.hasAttribute("pos_light_y"))
1878 myLightPosition[1] = child.attribute("pos_light_y").toDouble();
1880 if (child.hasAttribute("pos_light_z"))
1882 myLightPosition[2] = child.attribute("pos_light_z").toDouble();
1885 child = child.nextSibling().toElement();
1887 if(myLightPositionFixToCamera){
1888 updateRelativeCameraFromLightPosition();
1890 updateRenderingCoefficients(myRenderingMode, false);
1895 template< typename Space, typename KSpace>
1897 DGtal::Viewer3D<Space, KSpace>::closeEvent ( QCloseEvent * e ){
1898 if (myAutoSaveState)
1902 QGLWidget::closeEvent(e);
1905 template< typename Space, typename KSpace>
1907 DGtal::Viewer3D<Space, KSpace>::setGLDoubleRenderingMode(bool doubleSidedRendering)
1909 myIsDoubleFaceRendering = doubleSidedRendering;
1910 glUpdateLightRenderingMode();
1914 template< typename Space, typename KSpace>
1916 DGtal::Viewer3D<Space, KSpace>::setGLMaterialShininessCoefficient(const GLfloat matShininessCoeff)
1918 myMaterialShininessCoeff = matShininessCoeff;
1923 template< typename Space, typename KSpace>
1925 DGtal::Viewer3D<Space, KSpace>::setGLLightAmbientCoefficients(const GLfloat lightAmbientCoeffs [4])
1927 myLightAmbientCoeffs[0] = lightAmbientCoeffs[0];
1928 myLightAmbientCoeffs[1] = lightAmbientCoeffs[1];
1929 myLightAmbientCoeffs[2] = lightAmbientCoeffs[2];
1930 myLightAmbientCoeffs[3] = lightAmbientCoeffs[3];
1935 template< typename Space, typename KSpace>
1937 DGtal::Viewer3D<Space, KSpace>::setGLLightDiffuseCoefficients(const GLfloat lightDiffuseCoeffs [4])
1939 myLightDiffuseCoeffs[0] = lightDiffuseCoeffs[0];
1940 myLightDiffuseCoeffs[1] = lightDiffuseCoeffs[1];
1941 myLightDiffuseCoeffs[2] = lightDiffuseCoeffs[2];
1942 myLightDiffuseCoeffs[3] = lightDiffuseCoeffs[3];
1947 template< typename Space, typename KSpace>
1949 DGtal::Viewer3D<Space, KSpace>::setUseGLPointForBalls(const bool useOpenGLPt)
1951 myUseGLPointsForBalls = useOpenGLPt;
1956 template< typename Space, typename KSpace>
1958 DGtal::Viewer3D<Space, KSpace>::updateRenderingCoefficients(const RenderingMode aRenderMode, bool displayState)
1961 ss << "Rendering mode ";
1963 GLfloat newCoefDiff, newCoefSpec = 1.0f;
1964 switch (aRenderMode)
1966 case RenderingMode::RenderingDefault :
1967 newCoefDiff = myDefaultRenderDiff;
1968 newCoefSpec = myDefaultRenderSpec;
1969 ss << "Default (diffuse with few specular)";
1971 case RenderingMode::RenderingMetallic :
1972 newCoefDiff = myMetallicRenderDiff;
1973 newCoefSpec = myMetallicRenderSpec;
1974 ss << "Metallic (diffuse with specular)";
1976 case RenderingMode::RenderingPlastic :
1977 newCoefDiff = myPlasticRenderDiff;
1978 newCoefSpec = myPlasticRenderSpec;
1979 ss << "Plastic (few diffuse with large specular)";
1981 case RenderingMode::RenderingLambertian :
1982 newCoefDiff = myLambertRenderDiff;
1983 newCoefSpec = myLambertRenderSpec;
1984 ss << "Lambertian (only diffuse)";
1987 for (unsigned int i = 0; i<3; i++)
1988 myLightDiffuseCoeffs[i] = newCoefDiff;
1989 myLightDiffuseCoeffs[3] = 1.0;
1990 for (unsigned int i = 0; i<3; i++)
1991 myLightSpecularCoeffs[i] = newCoefSpec;
1992 myLightSpecularCoeffs[3] = 1.0;
1995 displayMessage(QString(ss.str().c_str()), 3000);
2002 template< typename Space, typename KSpace>
2004 DGtal::Viewer3D<Space, KSpace>::setGLLightSpecularCoefficients(const GLfloat lightSpecularCoeffs [4])
2006 myLightSpecularCoeffs[0] = lightSpecularCoeffs[0];
2007 myLightSpecularCoeffs[1] = lightSpecularCoeffs[1];
2008 myLightSpecularCoeffs[2] = lightSpecularCoeffs[2];
2009 myLightSpecularCoeffs[3] = lightSpecularCoeffs[3];
2014 template<typename Space, typename KSpace>
2017 DGtal::Viewer3D<Space, KSpace>::show(){
2023 template<typename Space, typename KSpace>
2026 DGtal::Viewer3D<Space, KSpace>::paintGL(){
2027 if (displaysInStereo())
2029 for (int view=1; view>=0; --view)
2031 // Clears screen, set model view matrix with shifted matrix for ith buffer
2032 preDrawStereo(view);
2034 // Used defined method. Default is empty
2035 if (camera()->frame()->isManipulated())
2044 // Clears screen, set model view matrix...
2047 // Used defined method. Default calls draw()
2048 if (camera()->frame()->isManipulated())
2052 // Add visual hints: axis, camera, grid...
2055 Q_EMIT drawFinished(true);
2059 template< typename Space, typename KSpace>
2060 void DGtal::Viewer3D<Space, KSpace>::updateLightCoordsFromCamera() {
2062 posLCam[0] = myLightPositionRefCamera[0];
2063 posLCam[1] = myLightPositionRefCamera[1];
2064 posLCam[2] = myLightPositionRefCamera[2];
2065 Vec posL = camera()->worldCoordinatesOf(posLCam);
2066 myLightPosition[0] = static_cast<GLfloat>(posL[0]);
2067 myLightPosition[1] = static_cast<GLfloat>(posL[1]);
2068 myLightPosition[2] = static_cast<GLfloat>(posL[2]);
2069 myLightPosition[3] = 1.0f;
2074 template< typename Space, typename KSpace>
2075 void DGtal::Viewer3D<Space, KSpace>::updateRelativeCameraFromLightPosition() {
2077 posL[0] = myLightPosition[0];
2078 posL[1] = myLightPosition[1];
2079 posL[2] = myLightPosition[2];
2080 Vec posLCam = camera()->cameraCoordinatesOf(posL);
2081 myLightPositionRefCamera[0] = static_cast<GLfloat>(posLCam[0]);
2082 myLightPositionRefCamera[1] = static_cast<GLfloat>(posLCam[1]);
2083 myLightPositionRefCamera[2] = static_cast<GLfloat>(posLCam[2]);