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 >
115 DGtal::Viewer3D<Space, KSpace>::rotateLineD3D(typename DGtal::Display3D<Space, KSpace>::LineD3D &aLine,
116 DGtal::PointVector<3, int> pt,
117 double angleRotation, ImageDirection dirRotation){
118 double dx1 = aLine.point1[0] - pt[0]; double dy1 = aLine.point1[1] - pt[1]; double dz1 = aLine.point1[2] - pt[2];
119 double dx2 = aLine.point2[0] - pt[0]; double dy2 = aLine.point2[1] - pt[1]; double dz2 = aLine.point2[2] - pt[2];
120 if(dirRotation==zDirection){
121 aLine.point1[0]=pt[0]+dx1*std::cos(angleRotation)-dy1*std::sin(angleRotation);
122 aLine.point1[1]=pt[1]+dx1*std::sin(angleRotation)+dy1*std::cos(angleRotation);
124 aLine.point2[0]=pt[0]+dx2*std::cos(angleRotation)-dy2*std::sin(angleRotation);
125 aLine.point2[1]=pt[1]+dx2*std::sin(angleRotation)+dy2*std::cos(angleRotation);
127 }else if(dirRotation==xDirection){
128 aLine.point1[1]=pt[1]+dy1*std::cos(angleRotation)-dz1*std::sin(angleRotation);
129 aLine.point1[2]=pt[2]+dy1*std::sin(angleRotation)+dz1*std::cos(angleRotation);
131 aLine.point2[1]=pt[1]+dy2*std::cos(angleRotation)-dz2*std::sin(angleRotation);
132 aLine.point2[2]=pt[2]+dy2*std::sin(angleRotation)+dz2*std::cos(angleRotation);
133 }else if(dirRotation==yDirection){
134 aLine.point1[0]=pt[0]+dx1*std::cos(angleRotation)-dz1*std::sin(angleRotation);
135 aLine.point1[2]=pt[2]+dx1*std::sin(angleRotation)+dz1*std::cos(angleRotation);
137 aLine.point2[0]=pt[0]+dx2*std::cos(angleRotation)-dz2*std::sin(angleRotation);
138 aLine.point2[2]=pt[2]+dx2*std::sin(angleRotation)+dz2*std::cos(angleRotation);
140 trace.error() << "No direction!!"<< std::endl;
146 template < typename Space ,typename KSpace >
149 DGtal::Viewer3D< Space ,KSpace >::getCurrentDomainNumber()
151 return myImageDomainList.size();
154 template < typename Space ,typename KSpace >
157 DGtal::Viewer3D< Space ,KSpace >::getCurrentGLImageNumber()
159 return myGSImageList.size();
163 template < typename Space ,typename KSpace >
166 DGtal::Viewer3D< Space ,KSpace >::addTextureImage(const typename Viewer3D< Space ,KSpace >::TextureImage &image)
168 myGSImageList.push_back(image);
169 Display3D< Space, KSpace>::updateBoundingBox(image.point1);
170 Display3D< Space, KSpace>::updateBoundingBox(image.point2);
171 Display3D< Space, KSpace>::updateBoundingBox(image.point3);
172 Display3D< Space, KSpace>::updateBoundingBox(image.point4);
177 template < typename Space ,typename KSpace >
178 template < typename TImageType, typename TFunctor >
181 DGtal::Viewer3D< Space ,KSpace >::updateTextureImage(unsigned int imageIndex, const TImageType & image, const TFunctor & aFunctor,
182 double xTranslation, double yTranslation, double zTranslation,
183 double rotationAngle, ImageDirection rotationDir)
185 BOOST_CONCEPT_ASSERT(( concepts::CConstImage < TImageType > ));
186 assert ( imageIndex< myGSImageList.size());
187 typename Viewer3D< Space ,KSpace >::TextureImage &anImage = myGSImageList.at(imageIndex);
188 Display::updateBoundingBox(RealPoint(anImage.point1[0]+xTranslation,
189 anImage.point1[1]+yTranslation,
190 anImage.point1[2]+zTranslation));
191 Display::updateBoundingBox(RealPoint(anImage.point2[0]+xTranslation,
192 anImage.point2[1]+yTranslation,
193 anImage.point2[2]+zTranslation));
194 Display::updateBoundingBox(RealPoint(anImage.point3[0]+xTranslation,
195 anImage.point3[1]+yTranslation,
196 anImage.point3[2]+zTranslation));
197 Display::updateBoundingBox(RealPoint(anImage.point4[0]+xTranslation,
198 anImage.point4[1]+yTranslation,
199 anImage.point4[2]+zTranslation));
200 anImage.updateImageDataAndParam(image, aFunctor, xTranslation, yTranslation, zTranslation);
201 if(anImage.myDrawDomain)
203 *this << DGtal::Translate2DDomain(anImage.myIndexDomain, xTranslation, yTranslation, zTranslation);
206 if(rotationAngle!=0.0){
207 rotateDomain(myImageDomainList.at(anImage.myIndexDomain), rotationAngle, rotationDir);
208 rotateImageVertex(anImage, rotationAngle, rotationDir);
213 template < typename Space ,typename KSpace >
216 DGtal::Viewer3D< Space ,KSpace >::updateOrientationTextureImage(unsigned int imageIndex,
220 ImageDirection newDirection)
222 assert ( imageIndex< myGSImageList.size());
223 typename Viewer3D< Space ,KSpace >::TextureImage &anImage = myGSImageList.at(imageIndex);
224 Display3D< Space, KSpace>::updateBoundingBox(anImage.point1);
225 Display3D< Space, KSpace>::updateBoundingBox(anImage.point2);
226 Display3D< Space, KSpace>::updateBoundingBox(anImage.point3);
227 Display3D< Space, KSpace>::updateBoundingBox(anImage.point4);
228 anImage.updateImageOrientation(newDirection, xPosition, yPosition, zPosition);
229 if(anImage.myDrawDomain)
231 *this << DGtal::Update2DDomainPosition<Space ,KSpace >(anImage.myIndexDomain,
234 yPosition, zPosition);
238 template < typename Space ,typename KSpace >
241 DGtal::Viewer3D<Space, KSpace>::updateEmbeddingTextureImage(unsigned int anImageIndex,
242 typename Space::Point aPoint1, typename Space::Point aPoint2,
243 typename Space::Point aPoint3, typename Space::Point aPoint4)
245 assert ( anImageIndex< myGSImageList.size());
246 typename Viewer3D< Space ,KSpace >::TextureImage &anImage = myGSImageList.at(anImageIndex);
247 Display3D< Space, KSpace>::updateBoundingBox(aPoint1);
248 Display3D< Space, KSpace>::updateBoundingBox(aPoint2);
249 Display3D< Space, KSpace>::updateBoundingBox(aPoint3);
250 Display3D< Space, KSpace>::updateBoundingBox(aPoint4);
251 anImage.updateImage3DEmbedding(aPoint1, aPoint2, aPoint3, aPoint4);
257 template < typename Space ,typename KSpace >
260 DGtal::Viewer3D< Space ,KSpace >::TextureImage::updateImageOrientation( ImageDirection normalDir,
261 double xBottomLeft, double yBottomLeft, double zBottomLeft)
263 if(normalDir==zDirection)
265 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft-0.5; point1[2] = zBottomLeft;
266 point2[0] = xBottomLeft+myImageWidth-0.5; point2[1] = yBottomLeft-0.5; point2[2] = zBottomLeft;
267 point3[0] = xBottomLeft+myImageWidth-0.5; point3[1] = yBottomLeft+myImageHeight-0.5; point3[2] = zBottomLeft;
268 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft+myImageHeight-0.5; point4[2] = zBottomLeft;
269 }else if(normalDir==yDirection)
271 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft; point1[2] = zBottomLeft-0.5;
272 point2[0] = xBottomLeft+myImageWidth-0.5; point2[1] = yBottomLeft; point2[2] = zBottomLeft-0.5;
273 point3[0] = xBottomLeft+myImageWidth-0.5; point3[1] = yBottomLeft; point3[2] = zBottomLeft+myImageHeight-0.5;
274 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft; point4[2] = zBottomLeft+myImageHeight-0.5;
275 }else if(normalDir==xDirection)
277 point1[0] = xBottomLeft; point1[1] = yBottomLeft-0.5; point1[2]= zBottomLeft-0.5;
278 point2[0] = xBottomLeft; point2[1] = yBottomLeft+myImageWidth-0.5; point2[2] = zBottomLeft-0.5;
279 point3[0] = xBottomLeft; point3[1] = yBottomLeft+myImageWidth-0.5; point3[2] = zBottomLeft+myImageHeight-0.5;
280 point4[0] = xBottomLeft; point4[1] = yBottomLeft-0.5; point4[2] = zBottomLeft+myImageHeight-0.5;
282 myDirection=normalDir;
285 template < typename Space ,typename KSpace >
288 DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D::updateDomainOrientation(ImageDirection normalDir,
289 double xBottomLeft, double yBottomLeft, double zBottomLeft)
291 if(normalDir==zDirection)
293 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft-0.5; point1[2] = zBottomLeft;
294 point2[0] = xBottomLeft+myDomainWidth-0.5; point2[1] = yBottomLeft-0.5; point2[2] = zBottomLeft;
295 point3[0] = xBottomLeft+myDomainWidth-0.5; point3[1] = yBottomLeft+myDomainHeight-0.5; point3[2] = zBottomLeft;
296 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft+myDomainHeight-0.5; point4[2] = zBottomLeft;
297 }else if(normalDir==yDirection)
299 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft; point1[2] = zBottomLeft-0.5;
300 point2[0] = xBottomLeft+myDomainWidth-0.5; point2[1] = yBottomLeft; point2[2] = zBottomLeft-0.5;
301 point3[0] = xBottomLeft+myDomainWidth-0.5; point3[1] = yBottomLeft; point3[2] = zBottomLeft+myDomainHeight-0.5;
302 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft; point4[2] = zBottomLeft+myDomainHeight-0.5;
303 }else if(normalDir==xDirection)
305 point1[0] = xBottomLeft; point1[1] = yBottomLeft-0.5; point1[2]= zBottomLeft-0.5;
306 point2[0] = xBottomLeft; point2[1] = yBottomLeft+myDomainWidth-0.5; point2[2] = zBottomLeft-0.5;
307 point3[0] = xBottomLeft; point3[1] = yBottomLeft+myDomainWidth-0.5; point3[2] = zBottomLeft+myDomainHeight-0.5;
308 point4[0] = xBottomLeft; point4[1] = yBottomLeft-0.5; point4[2] = zBottomLeft+myDomainHeight-0.5;
310 myDirection=normalDir;
314 template < typename Space ,typename KSpace >
317 DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D::translateDomain (double xTranslation,
321 point1[0] += xTranslation; point1[1] += yTranslation; point1[2] += zTranslation;
322 point2[0] += xTranslation; point2[1] += yTranslation; point2[2] += zTranslation;
323 point3[0] += xTranslation; point3[1] += yTranslation; point3[2] += zTranslation;
324 point4[0] += xTranslation; point4[1] += yTranslation; point4[2] += zTranslation;
328 template < typename Space ,typename KSpace >
329 template < typename TDomain>
331 DGtal::Viewer3D< Space ,KSpace >::addImage2DDomainD3D(const TDomain &aDomain,
333 const DGtal::Color &aColor)
335 typename DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D anImageDomain(aDomain);
336 anImageDomain.color = aColor;
337 anImageDomain.myMode = mode;
338 anImageDomain.myLineSetIndex=Viewer3D<Space, KSpace>::myLineSetList.size();
340 myImageDomainList.push_back(anImageDomain);
341 Display3D< Space, KSpace>::updateBoundingBox(anImageDomain.point1);
342 Display3D< Space, KSpace>::updateBoundingBox(anImageDomain.point2);
343 Display3D< Space, KSpace>::updateBoundingBox(anImageDomain.point3);
344 Display3D< Space, KSpace>::updateBoundingBox(anImageDomain.point4);
346 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> vectLines= compute2DDomainLineRepresentation(anImageDomain);
347 Viewer3D<Space, KSpace>::myLineSetList.push_back(vectLines);
351 template < typename Space ,typename KSpace >
353 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D>
354 DGtal::Viewer3D< Space ,KSpace >::compute2DDomainLineRepresentation( typename DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D &anImageDomain )
356 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> vectLinesResu= compute2DDomainLineRepresentation(anImageDomain, 0.05);
357 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> vectLinesVerso= compute2DDomainLineRepresentation(anImageDomain, -0.05);
358 for(unsigned int i=0; i<vectLinesVerso.size(); i++)
360 vectLinesResu.push_back(vectLinesVerso.at(i));
362 return vectLinesResu;
366 template < typename Space ,typename KSpace >
368 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D>
369 DGtal::Viewer3D< Space ,KSpace >::compute2DDomainLineRepresentation(typename DGtal::Viewer3D< Space ,KSpace >::Image2DDomainD3D &anImageDomain, double delta )
371 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> aLineSet;
372 typename Viewer3D<Space, KSpace>::LineD3D aLine;
373 aLine.color = anImageDomain.color;
376 if( anImageDomain.myMode=="BoundingBox")
378 aLine.point1[0]=anImageDomain.point1[0]; aLine.point1[1]=anImageDomain.point1[1]; aLine.point1[2]=anImageDomain.point1[2];
379 aLine.point2[0]=anImageDomain.point2[0]; aLine.point2[1]=anImageDomain.point2[1]; aLine.point2[2]=anImageDomain.point2[2];
380 aLineSet.push_back(aLine);
381 aLine.point1[0]=anImageDomain.point2[0]; aLine.point1[1]=anImageDomain.point2[1]; aLine.point1[2]=anImageDomain.point2[2];
382 aLine.point2[0]=anImageDomain.point3[0]; aLine.point2[1]=anImageDomain.point3[1]; aLine.point2[2]=anImageDomain.point3[2];
383 aLineSet.push_back(aLine);
384 aLine.point1[0]=anImageDomain.point3[0]; aLine.point1[1]=anImageDomain.point3[1]; aLine.point1[2]=anImageDomain.point3[2];
385 aLine.point2[0]=anImageDomain.point4[0]; aLine.point2[1]=anImageDomain.point4[1]; aLine.point2[2]=anImageDomain.point4[2];
386 aLineSet.push_back(aLine);
387 aLine.point1[0]=anImageDomain.point4[0]; aLine.point1[1]=anImageDomain.point4[1]; aLine.point1[2]=anImageDomain.point4[2];
388 aLine.point2[0]=anImageDomain.point1[0]; aLine.point2[1]=anImageDomain.point1[1]; aLine.point2[2]=anImageDomain.point1[2];
389 aLineSet.push_back(aLine);
390 }else if(anImageDomain.myMode=="InterGrid")
392 if(anImageDomain.myDirection==zDirection)
394 //lines align to the x direction
395 for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
397 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+i; aLine.point1[2] = anImageDomain.point1[2]+delta;
398 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point2[1]+i; aLine.point2[2] = anImageDomain.point2[2]+delta;
399 aLineSet.push_back(aLine);
401 //lines align to the y direction
402 for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
404 aLine.point1[0] = anImageDomain.point1[0]+i; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+delta;
405 aLine.point2[0] = anImageDomain.point4[0]+i; aLine.point2[1] = anImageDomain.point4[1]; aLine.point2[2] = anImageDomain.point4[2]+delta;
406 aLineSet.push_back(aLine);
408 }else if(anImageDomain.myDirection==xDirection)
410 //lines align to the y direction
411 for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
413 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+i;
414 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point2[1]; aLine.point2[2] = anImageDomain.point1[2]+i;
415 aLineSet.push_back(aLine);
418 //lines align to the z direction
419 for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
421 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]+i; aLine.point1[2] = anImageDomain.point1[2];
422 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point1[1]+i; aLine.point2[2] = anImageDomain.point4[2];
423 aLineSet.push_back(aLine);
425 }else if(anImageDomain.myDirection==yDirection)
427 //lines align to the x direction
428 for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
430 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2]+i;
431 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point1[2]+i;
432 aLineSet.push_back(aLine);
435 //lines align to the z direction
436 for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
438 aLine.point1[0] = anImageDomain.point1[0]+i; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2];
439 aLine.point2[0] = anImageDomain.point1[0]+i; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point4[2];
440 aLineSet.push_back(aLine);
443 }else if(anImageDomain.myMode=="Grid")
445 if(anImageDomain.myDirection==zDirection)
447 //lines align to the x direction
448 for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
450 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+i+0.5; aLine.point1[2] = anImageDomain.point1[2]+delta;
451 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point2[1]+i+0.5; aLine.point2[2] = anImageDomain.point2[2]+delta;
452 aLineSet.push_back(aLine);
454 //lines align to the y direction
455 for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
457 aLine.point1[0] = anImageDomain.point1[0]+i+0.5; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+delta;
458 aLine.point2[0] = anImageDomain.point4[0]+i+0.5; aLine.point2[1] = anImageDomain.point4[1]; aLine.point2[2] = anImageDomain.point4[2]+delta;
459 aLineSet.push_back(aLine);
461 }else if(anImageDomain.myDirection==xDirection)
463 //lines align to the y direction
464 for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
466 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+i+0.5;
467 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point2[1]; aLine.point2[2] = anImageDomain.point1[2]+i+0.5;
468 aLineSet.push_back(aLine);
471 //lines align to the z direction
472 for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
474 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]+i+0.5; aLine.point1[2] = anImageDomain.point1[2];
475 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point1[1]+i+0.5; aLine.point2[2] = anImageDomain.point4[2];
476 aLineSet.push_back(aLine);
478 }else if(anImageDomain.myDirection==yDirection)
480 //lines align to the x direction
481 for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
483 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2]+i+0.5;
484 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point1[2]+i+0.5;
485 aLineSet.push_back(aLine);
488 //lines align to the z direction
489 for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
491 aLine.point1[0] = anImageDomain.point1[0]+i+0.5; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2];
492 aLine.point2[0] = anImageDomain.point1[0]+i+0.5; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point4[2];
493 aLineSet.push_back(aLine);
501 template < typename Space ,typename KSpace >
504 DGtal::Viewer3D< Space ,KSpace >::updateAn2DDomainOrientation(unsigned int domainIndex,
505 double xPosition, double yPosition,
506 double zPosition, ImageDirection newDirection)
508 ASSERT( domainIndex < myImageDomainList.size());
509 typename Viewer3D< Space ,KSpace >::Image2DDomainD3D &aDomain = myImageDomainList.at(domainIndex);
511 Display3D< Space, KSpace>::updateBoundingBox(aDomain.point1);
512 Display3D< Space, KSpace>::updateBoundingBox(aDomain.point2);
513 Display3D< Space, KSpace>::updateBoundingBox(aDomain.point3);
514 Display3D< Space, KSpace>::updateBoundingBox(aDomain.point4);
515 aDomain.updateDomainOrientation(newDirection, xPosition, yPosition, zPosition);
517 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> vectNewLines= compute2DDomainLineRepresentation(aDomain);
518 std::vector<typename DGtal::Viewer3D< Space ,KSpace >::LineD3D> &vectLines = Viewer3D<Space, KSpace>::myLineSetList.at(aDomain.myLineSetIndex);
520 for(unsigned int i=0; i<vectNewLines.size(); i++)
522 vectLines.push_back(vectNewLines.at(i));
528 template < typename Space ,typename KSpace >
531 DGtal::Viewer3D< Space ,KSpace >::translateAn2DDomain(unsigned int domainIndex, double xTranslation, double yTranslation, double zTranslation)
533 typename Viewer3D< Space ,KSpace >::Image2DDomainD3D &anDomain = myImageDomainList.at(domainIndex);
534 anDomain.translateDomain(xTranslation, yTranslation, zTranslation);
536 Display3D< Space, KSpace>::updateBoundingBox(anDomain.point1);
537 Display3D< Space, KSpace>::updateBoundingBox(anDomain.point2);
538 Display3D< Space, KSpace>::updateBoundingBox(anDomain.point3);
539 Display3D< Space, KSpace>::updateBoundingBox(anDomain.point4);
541 std::vector<typename DGtal::Display3D<Space, KSpace>::LineD3D> &vectLines = Viewer3D<Space,KSpace>::myLineSetList.at(anDomain.myLineSetIndex);
542 for(unsigned int i=0; i<vectLines.size(); i++){
543 typename DGtal::Display3D<Space,KSpace>::LineD3D &aLine = vectLines.at(i);
544 aLine.point1[0]=aLine.point1[0]+xTranslation; aLine.point1[1]=aLine.point1[1]+yTranslation; aLine.point1[2]=aLine.point1[2]+zTranslation;
545 aLine.point2[0]=aLine.point2[0]+xTranslation; aLine.point2[1]=aLine.point2[1]+yTranslation; aLine.point2[2]=aLine.point2[2]+zTranslation;
549 template < typename Space ,typename KSpace >
552 DGtal::Viewer3D< Space ,KSpace >::TextureImage::className() const
554 return "TextureImage";
557 template <typename Space, typename KSpace>
559 DGtal::Viewer3D<Space,KSpace> &
560 DGtal::Viewer3D<Space, KSpace>::operator<<(const DGtal::Color & aColor)
562 myDefaultColor=aColor;
566 template <typename Space, typename KSpace>
568 DGtal::Viewer3D<Space, KSpace> &
569 DGtal::Viewer3D<Space, KSpace>::operator<<(const typename Viewer3D<Space, KSpace>::StreamKey & key)
573 case Viewer3D<Space, KSpace>::updateDisplay:
574 Viewer3D<Space, KSpace>::updateList();
577 case Viewer3D<Space, KSpace>::addNewList:
578 Viewer3D<Space, KSpace>::createNewCubeList();
581 case Viewer3D<Space, KSpace>::shiftSurfelVisu:
582 Viewer3D<Space, KSpace>::myCurrentfShiftVisuPrisms+=0.3;
588 template <typename Space, typename KSpace>
589 template <typename TDrawableWithViewer3D>
591 DGtal::Viewer3D<Space, KSpace> &
592 DGtal::Viewer3D<Space, KSpace>::operator<<( const TDrawableWithViewer3D & object )
594 BOOST_CONCEPT_ASSERT((concepts::CDrawableWithViewer3D< TDrawableWithViewer3D, Space, KSpace >));
596 DGtal::Viewer3DFactory<Space,KSpace>::draw(*this, object);
601 ///////////////////////////////////////////////////////////////////////////////
602 // Implementation of inline functions and external operators //
604 template <typename Space, typename KSpace>
607 DGtal::operator<< ( std::ostream & out,
608 const Viewer3D<Space, KSpace> & object )
610 object.selfDisplay ( out );
615 ///////////////////////////////////////////////////////////////////////////////
618 ///////////////////////////////////////////////////////////////////////////////
620 // heritage of parents templates methods //
623 // end of heritage //
624 ///////////////////////////////////////////////////////////////////////////////
626 ///////////////////////////////////////////////////////////////////////////////
628 // surcharge of parents methods //
631 // end of surcharge //
632 ///////////////////////////////////////////////////////////////////////////////
634 template< typename Space, typename KSpace>
637 DGtal::Viewer3D<Space, KSpace>::drawWithNames()
639 // JOL: 2014/10/15. This method is called only when the user tries
640 // to select some graphic object through QGLViewer. By default,
641 // selection is left clic + shift key.
642 // JOL: 2014/10/15. This is my addition for interacting with
643 // quads. Seems to work well.
645 glCallList ( myQuadsMapId );
647 glCallList ( myCubesMapId );
650 for ( unsigned int i=0; i<Viewer3D<Space, KSpace>::myLineSetList.size(); i++ )
652 glCallList ( myLineSetListId+i );
655 for ( unsigned int i=0; i<Viewer3D<Space, KSpace>::myBallSetList.size(); i++ )
657 glCallList(myBallSetListId+i);
662 template< typename Space, typename KSpace>
665 DGtal::Viewer3D<Space, KSpace>::draw()
670 glMultMatrixd ( manipulatedFrame()->matrix() );
672 glScalef(myGLScaleFactorX, myGLScaleFactorY, myGLScaleFactorZ);
674 glLightfv(GL_LIGHT0, GL_SPECULAR, myLightSpecularCoeffs);
675 glLightfv(GL_LIGHT0, GL_DIFFUSE, myLightDiffuseCoeffs);
676 glLightfv(GL_LIGHT0, GL_AMBIENT, myLightAmbientCoeffs);
677 if( myLightPositionFixToCamera ){
678 updateLightCoordsFromCamera();
680 updateRelativeCameraFromLightPosition();
682 glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
685 typename vector< typename Viewer3D<Space, KSpace>::ClippingPlaneD3D >::const_iterator it = Viewer3D<Space, KSpace>::myClippingPlaneList.begin();
687 // OpenGL can't draw more than GL_MAX_CLIP_PLANES clipping plane
688 while ( i < GL_MAX_CLIP_PLANES && it !=Viewer3D<Space, KSpace>::myClippingPlaneList.end() )
695 glEnable ( GL_CLIP_PLANE0+i );
696 glClipPlane ( GL_CLIP_PLANE0+i, eq );
700 if (i == GL_MAX_CLIP_PLANES)
702 std::cerr <<"Warning maximal clipping plane added" << std::endl;
705 Vec centerS = sceneCenter();
706 Vec posCam = camera()->position();
707 double distCam =sqrt ( ( posCam.x-centerS.x ) * ( posCam.x-centerS.x ) +
708 ( posCam.y-centerS.y ) * ( posCam.y-centerS.y ) +
709 ( posCam.z-centerS.z ) * ( posCam.z-centerS.z ) );
710 for(unsigned int j=0; j< myVectTextureImage.size(); j++)
712 GLTextureImage &textureImg = myVectTextureImage.at(j);
713 glPushName ( textureImg.myTextureName );
714 glEnable(GL_TEXTURE_2D);
715 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
716 glBindTexture(GL_TEXTURE_2D, textureImg.myTextureName);
718 glColor4ub ( 255.0, 255.0, 255.0, 255.0 );
719 glNormal3d(textureImg.vectNormal[0], textureImg.vectNormal[1], textureImg.vectNormal[2]);
722 glVertex3f(textureImg.point1[0], textureImg.point1[1], textureImg.point1[2]);
723 glTexCoord2f(textureImg.myTextureFitX, 0.0);
724 glVertex3f(textureImg.point2[0], textureImg.point2[1], textureImg.point2[2]);
725 glTexCoord2f(textureImg.myTextureFitX, textureImg.myTextureFitY);
726 glVertex3f(textureImg.point3[0], textureImg.point3[1], textureImg.point3[2]);
727 glTexCoord2f(0.0, textureImg.myTextureFitY);
728 glVertex3f(textureImg.point4[0], textureImg.point4[1], textureImg.point4[2]);
730 glDisable(GL_TEXTURE_2D);
735 for ( unsigned int j=0; j< Viewer3D<Space, KSpace>::myLineSetList.size(); j++ )
737 if ( Viewer3D<Space, KSpace>::myLineSetList.at ( j ).size() !=0 )
739 glLineWidth ( max(myGLLineMinWidth,
740 Viewer3D<Space, KSpace>::myLineSetList.at ( j ).at ( 0 ).width )) ;
742 glCallList(myLineSetListId+j);
745 glCallList(myPrismListId);
747 glCallList( myCubesMapId );
750 for ( unsigned int j=0; j< Viewer3D<Space, KSpace>::myBallSetList.size(); j++ )
752 if(myUseGLPointsForBalls)
754 if ( Viewer3D<Space, KSpace>::myBallSetList.at ( j ).size() !=0 )
756 glPointSize ( max(myGLPointMinWidth,
757 ( Viewer3D<Space, KSpace>::myBallSetList.at ( j ).at ( 0 ).radius ) ));
761 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
763 glCallList(myBallSetListId+j);
764 glUpdateLightRenderingMode();
767 glDisable(GL_CULL_FACE);
768 glCallList(myQuadsMapId);
771 glLineWidth ( max(myGLLineMinWidth,Viewer3D<Space, KSpace>::myMeshDefaultLineWidth /distCam ));
772 glCallList(myQuadsMapWiredId);
775 glDisable(GL_CULL_FACE);
776 glCallList(myTriangleSetListId);
779 glLineWidth ( max(myGLLineMinWidth,
780 Viewer3D<Space, KSpace>::myMeshDefaultLineWidth /distCam ));
781 glCallList(myTriangleSetListWiredId);
784 glDisable(GL_CULL_FACE);
785 glCallList(myPolygonSetListId);
788 glLineWidth (max(myGLLineMinWidth,
789 Viewer3D<Space, KSpace>::myMeshDefaultLineWidth /distCam ));
790 glCallList(myPolygonSetListWiredId);
794 drawLight(GL_LIGHT0);
802 template< typename Space, typename KSpace>
804 DGtal::Viewer3D<Space, KSpace>::selfDisplay ( std::ostream & out ) const
810 template< typename Space, typename KSpace>
812 DGtal::Viewer3D<Space, KSpace>::isValid() const
817 template< typename Space, typename KSpace>
819 DGtal::Viewer3D<Space, KSpace>::init()
821 myAutoSaveState = false;
822 myIsMovingLight = false;
823 myLigthRotationStep = 0.01;
827 myLightPositionRefCamera[0] = myLightPositionRefCameraDefault[0];
828 myLightPositionRefCamera[1] = myLightPositionRefCameraDefault[1];
829 myLightPositionRefCamera[2] = myLightPositionRefCameraDefault[2];
830 updateLightCoordsFromCamera();
832 glClearColor (0.0, 0.0, 0.0, 0.0);
833 glShadeModel (GL_SMOOTH);
835 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, myMaterialShininessCoeff);
836 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, myMaterialSpecularCoeffs);
839 glLightfv(GL_LIGHT0, GL_SPECULAR, myLightSpecularCoeffs);
840 glLightfv(GL_LIGHT0, GL_DIFFUSE, myLightDiffuseCoeffs);
841 glLightfv(GL_LIGHT0, GL_AMBIENT, myLightAmbientCoeffs);
843 glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
845 glEnable(GL_LIGHTING);
847 glEnable(GL_DEPTH_TEST);
849 Viewer3D<Space, KSpace>::myMeshDefaultLineWidth=10.0;
852 setBackgroundColor ( QColor ( 217, 228, 255 ) );
853 setForegroundColor ( QColor ( 217, 22, 25 ) );
855 Viewer3D<Space, KSpace>::createNewCubeList ( );
856 vector<typename Viewer3D<Space, KSpace>::LineD3D> listeLine;
857 Viewer3D<Space, KSpace>::myLineSetList.push_back ( listeLine );
858 vector<typename Viewer3D<Space, KSpace>::BallD3D> listeBall;
859 Viewer3D<Space, KSpace>::myBallSetList.push_back ( listeBall );
860 Viewer3D<Space, KSpace>::myCurrentFillColor = Color ( 220, 220, 220 );
861 Viewer3D<Space, KSpace>::myCurrentLineColor = Color ( 22, 22, 222, 50 );
862 myDefaultBackgroundColor = Color ( backgroundColor().red(), backgroundColor().green(),
863 backgroundColor().blue() );
864 myIsBackgroundDefault=true;
865 Viewer3D<Space, KSpace>::myBoundingPtLow[0]=-10.0;//numeric_limits<double>::max( );
866 Viewer3D<Space, KSpace>::myBoundingPtLow[1]=-10.0;//numeric_limits<double>::max( );
867 Viewer3D<Space, KSpace>::myBoundingPtLow[2]=-10.0;//numeric_limits<double>::max( );
869 Viewer3D<Space, KSpace>::myBoundingPtUp[0]=-10.0;//numeric_limits<double>::min( );
870 Viewer3D<Space, KSpace>::myBoundingPtUp[1]=-10.0;//numeric_limits<double>::min( );
871 Viewer3D<Space, KSpace>:: myBoundingPtUp[2]=-10.0;//numeric_limits<double>::min( );
872 Viewer3D<Space, KSpace>::createNewCubeList ( );
873 typename std::vector< typename Viewer3D<Space, KSpace>::CubeD3D> aKSCubeList;
875 Viewer3D<Space, KSpace>::myCurrentfShiftVisuPrisms=0.0;
876 Viewer3D<Space, KSpace>::myDefaultColor= Color ( 255, 255, 255 );
877 camera()->showEntireScene();
878 setKeyDescription ( Qt::Key_E, "Export the current display into OFF file (just Cube, surfel and SurfelPrism for now)." );
879 setKeyDescription ( Qt::Key_W, "Switch display with and without wired view of triangle and quad faces." );
880 setKeyDescription ( Qt::Key_T, "Sort elements for display improvements." );
881 setKeyDescription ( Qt::Key_L, "Load last visualisation settings (from a .qglviewer.xml file generated by using SHIFT+L)");
882 setKeyDescription ( Qt::ShiftModifier+Qt::Key_L, "Save visualisation settings." );
883 setKeyDescription ( Qt::Key_B, "Switch background color with White/Black colors." );
884 setKeyDescription ( Qt::Key_C, "Show camera informations." );
885 setKeyDescription ( Qt::Key_R, "Reset default scale for 3 axes to 1.0f." );
886 setKeyDescription ( Qt::Key_D, "Enable/Disable the two side face rendering." );
887 setKeyDescription ( Qt::Key_O, "Switch the ball display mode (quad ball display (default) or OpenGL point)." );
888 setKeyDescription ( Qt::Key_R, "Reset default scale for 3 axes to 1.0f." );
889 setKeyDescription ( Qt::Key_M, "Switch the rendering mode bewteen Default, Metallic and Plastic mode." );
890 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)." );
891 #if !defined (QGLVIEWER_VERSION) || QGLVIEWER_VERSION < 0x020500
892 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).");
894 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).");
898 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
900 #if !defined (QGLVIEWER_VERSION) || QGLVIEWER_VERSION < 0x020500
901 setMouseBindingDescription ( Qt::ShiftModifier+Qt::RightButton, "Delete the mouse selected list." );
903 setMouseBindingDescription ( Qt::ShiftModifier, Qt::RightButton, "Delete the mouse selected list." );
906 setManipulatedFrame ( new ManipulatedFrame() );
910 template< typename Space, typename KSpace>
912 DGtal::Viewer3D<Space, KSpace>::sortSurfelFromCamera()
914 CompFarthestVoxelFromCamera comp;
915 comp.posCam= camera()->position();
917 for (auto &mapElem: Viewer3D<Space, KSpace>::myCubesMap)
920 DGtal::trace.info() << "sort quad size" << mapElem.second.size() << std::endl;
921 sort ( mapElem.second.begin(), mapElem.second.end(), comp );
923 CompFarthestSurfelFromCamera compSurf;
924 DGtal::trace.info() << "sort surfel size" << Viewer3D<Space, KSpace>::myPrismList.size() << std::endl;
925 sort ( Viewer3D<Space, KSpace>::myPrismList.begin(), Viewer3D<Space, KSpace>::myPrismList.end(), compSurf );
931 template< typename Space, typename KSpace>
933 DGtal::Viewer3D<Space, KSpace>::sortTriangleFromCamera()
935 CompFarthestTriangleFromCamera comp;
936 comp.posCam= camera()->position();
937 for (auto &listElem: Viewer3D<Space, KSpace>::myTriangleSetList)
939 sort ( listElem.begin(), listElem.end(), comp );
945 template< typename Space, typename KSpace>
947 DGtal::Viewer3D<Space, KSpace>::sortQuadFromCamera()
949 CompFarthestSurfelFromCamera comp;
950 comp.posCam= camera()->position();
952 for (auto &listElem: Viewer3D<Space, KSpace>::myQuadsMap)
954 DGtal::trace.info() << "sort quad size" << listElem.second.size() << std::endl;
955 sort ( listElem.second.begin(), listElem.second.end(), comp );
960 template< typename Space, typename KSpace>
962 DGtal::Viewer3D<Space, KSpace>::sortPolygonFromCamera()
964 CompFarthestPolygonFromCamera comp;
965 comp.posCam= camera()->position();
967 for (auto &listElem: Viewer3D<Space, KSpace>::myPolygonSetList)
969 DGtal::trace.info() << "sort polygon size" << listElem.size() << std::endl;
970 sort ( listElem.begin(), listElem.end(), comp );
978 template< typename Space, typename KSpace>
980 DGtal::Viewer3D<Space, KSpace>::postSelection ( const QPoint& point )
982 camera()->convertClickToLine ( point, myOrig, myDir );
984 this->myPosSelector= point;
985 mySelectedPoint = camera()->pointUnderPixel ( point, found );
988 DGtal::trace.info() << "Element of liste= " << selectedName() << "selected" << endl;
990 mySelectedElementId = selectedName();
992 SelectCallbackFct fct = getSelectCallback3D( selectedName(), aData );
993 if ( fct ) fct( this, selectedName(), aData );
994 // I leave the remaining code.
996 }else if (mySelectedElementId != -1)
998 mySelectedElementId = -1;
1005 template< typename Space, typename KSpace>
1007 DGtal::Viewer3D<Space, KSpace>::updateList ( bool needToUpdateBoundingBox )
1011 glDeleteLists(myCubesMapId, 1);
1012 glDeleteLists(myLineSetListId, myNbLineSetList);
1013 glDeleteLists(myBallSetListId, myNbBallSetList);
1014 glDeleteLists(myTriangleSetListId, 1);
1015 glDeleteLists(myTriangleSetListWiredId, 1);
1016 glDeleteLists(myPrismListId, 1);
1017 glDeleteLists(myPolygonSetListId, 1);
1018 glDeleteLists(myPolygonSetListWiredId, 1);
1019 glDeleteLists(myQuadsMapId, 1);
1020 glDeleteLists(myQuadsMapWiredId, 1);
1022 // Storing ID for each list
1023 myCubesMapId = glGenLists(1);
1024 myLineSetListId = glGenLists(Viewer3D<Space, KSpace>::myLineSetList.size());
1025 myNbLineSetList = Viewer3D<Space, KSpace>::myLineSetList.size();
1026 myBallSetListId = glGenLists(Viewer3D<Space, KSpace>::myBallSetList.size());
1027 myNbBallSetList = Viewer3D<Space, KSpace>::myBallSetList.size();
1028 myTriangleSetListId = glGenLists(1);
1029 myTriangleSetListWiredId = glGenLists(1);
1030 myCubeSetListWiredId = glGenLists(1);
1031 myPolygonSetListId = glGenLists(1);
1032 myPolygonSetListWiredId = glGenLists(1);
1033 myQuadsMapId = glGenLists(1);
1034 myQuadsMapWiredId = glGenLists(1);
1035 myPrismListId = glGenLists(1);
1040 glEnable ( GL_BLEND );
1041 glEnable ( GL_MULTISAMPLE_ARB );
1042 glEnable ( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
1043 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1047 glCreateListCubesMaps(Viewer3D<Space, KSpace>::myCubesMap, myCubesMapId);
1050 glCreateListQuadD3D(Viewer3D<Space, KSpace>::myPrismList, myPrismListId);
1053 for ( unsigned int j=0; j<Viewer3D<Space, KSpace>::myLineSetList.size(); j++ )
1055 glCreateListLines(Viewer3D<Space, KSpace>::myLineSetList.at(j), myLineSetListId+j);
1059 for ( unsigned int j=0; j<Viewer3D<Space, KSpace>::myBallSetList.size(); j++ )
1061 glCreateListBalls(Viewer3D<Space, KSpace>::myBallSetList.at (j), myBallSetListId+j);
1066 // First list: quad faces.
1067 glCreateListQuadMaps(Viewer3D<Space, KSpace>::myQuadsMap, myQuadsMapId);
1070 // Second list: Wired version of quad face.
1071 glCreateListQuadMapsWired(Viewer3D<Space, KSpace>::myQuadsMap,myQuadsMapWiredId);
1074 // Third list: Triangle faces.
1075 glCreateListTriangles( Viewer3D<Space, KSpace>::myTriangleSetList, myTriangleSetListId);
1078 // Fourth list: Wired version of triangle face.
1079 glCreateListTrianglesWired(Viewer3D<Space, KSpace>::myTriangleSetList, myTriangleSetListWiredId);
1082 // Fifth list: Polygonal faces.
1083 glCreateListPolygons(Viewer3D<Space, KSpace>::myPolygonSetList, myPolygonSetListId);
1086 // Sixth list: Wired version of polygonal face.
1087 glCreateListPolygonsWired(Viewer3D<Space, KSpace>::myPolygonSetList, myPolygonSetListWiredId);
1091 // Seventh list: Textured images.
1092 glUpdateTextureImages(myGSImageList);
1095 if ( needToUpdateBoundingBox )
1097 setSceneBoundingBox ( qglviewer::Vec ( Viewer3D<Space, KSpace>::myBoundingPtLow[0],
1098 Viewer3D<Space, KSpace>::myBoundingPtLow[1],
1099 Viewer3D<Space, KSpace>::myBoundingPtLow[2] ),
1100 qglviewer::Vec ( Viewer3D<Space, KSpace>::myBoundingPtUp[0],
1101 Viewer3D<Space, KSpace>::myBoundingPtUp[1],
1102 Viewer3D<Space, KSpace>::myBoundingPtUp[2] ) );
1110 template< typename Space, typename KSpace>
1112 DGtal::Viewer3D<Space, KSpace>::glDrawGLBall (const typename Viewer3D<Space, KSpace>::BallD3D &aBall )
1114 double thetaResolution = aBall.resolution;
1115 double thetaStep= (2.0*M_PI)/thetaResolution;
1116 double phiResolution = aBall.resolution;
1117 double phiStep= M_PI/phiResolution;
1119 double radius = aBall.radius;
1120 double xCenter = aBall.center[0];
1121 double yCenter = aBall.center[1];
1122 double zCenter = aBall.center[2];
1123 glBegin(GL_QUAD_STRIP);
1124 for(unsigned int j =0; j < phiResolution; j++)
1126 double phi0 = M_PI/2.0-j*phiStep;
1127 double phi1 = M_PI/2.0-(j+1)*phiStep;
1128 for(unsigned int i =0; i <= thetaResolution; i++)
1130 double theta0 = i * thetaStep;
1131 glColor4ub ( aBall.color.red(), aBall.color.green(), aBall.color.blue(), aBall.color.alpha() );
1132 glNormal3f(cos(phi0)*cos(theta0), cos(phi0)*sin(theta0), sin(phi0));
1133 glVertex3f(xCenter+cos(phi0)*cos(theta0)*radius,yCenter+ cos(phi0)*sin(theta0)*radius, zCenter+ sin(phi0)*radius);
1134 glNormal3f(cos(phi1)*cos(theta0), cos(phi1)*sin(theta0), sin(phi1));
1135 glVertex3f(xCenter+cos(phi1)*cos(theta0)*radius,yCenter+ cos(phi1)*sin(theta0)*radius, zCenter+ sin(phi1)*radius);
1142 template< typename Space, typename KSpace>
1144 DGtal::Viewer3D<Space, KSpace>::mousePressEvent ( QMouseEvent *e )
1146 if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier))
1148 myIsMovingLight=true;
1149 myRefMouseXPos = e->x();
1150 myRefMouseYPos = e->y();
1151 if( myLightPositionFixToCamera )
1153 updateLightCoordsFromCamera();
1155 myLightR = sqrt( myLightPosition[0]* myLightPosition[0]+
1156 myLightPosition[1]* myLightPosition[1]+
1157 myLightPosition[2]* myLightPosition[2]);
1158 myLightTheta = asin( myLightPosition[2]/myLightR);
1159 myLightPhi = atan2( myLightPosition[1], myLightPosition[0]);
1163 QGLViewer::mousePressEvent(e);
1167 template< typename Space, typename KSpace>
1169 DGtal::Viewer3D<Space, KSpace>::mouseReleaseEvent ( QMouseEvent *e )
1171 if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier) || myIsMovingLight){
1172 myIsMovingLight=false;
1175 QGLViewer::mouseReleaseEvent(e);
1179 template< typename Space, typename KSpace>
1181 DGtal::Viewer3D<Space, KSpace>::mouseMoveEvent ( QMouseEvent *e )
1183 if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier)){
1184 int varX = e->x() - myRefMouseXPos;
1185 int varY = e->y() - myRefMouseYPos;
1186 myLightPhi += varX*myLigthRotationStep;
1187 myLightTheta += varY*myLigthRotationStep/2.0;
1188 myLightPosition[0] = myLightR*cos(myLightTheta)*cos(myLightPhi);
1189 myLightPosition[1] = myLightR*cos(myLightTheta)*sin(myLightPhi);
1190 myLightPosition[2] = myLightR*sin(myLightTheta);
1191 if(myLightPositionFixToCamera){
1192 updateRelativeCameraFromLightPosition();
1194 glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
1195 myRefMouseXPos = e->x();
1196 myRefMouseYPos = e->y();
1199 QGLViewer::mouseMoveEvent(e);
1206 template< typename Space, typename KSpace>
1208 DGtal::Viewer3D<Space, KSpace>::keyPressEvent ( QKeyEvent *e )
1210 bool handled = false;
1212 if( e->key() == Qt::Key_D)
1214 myIsDoubleFaceRendering = !myIsDoubleFaceRendering;
1215 glUpdateLightRenderingMode();
1219 if( e->key() == Qt::Key_E)
1221 trace.info() << "Exporting mesh..." ;
1222 operator>> <Space, KSpace>(*this, "exportedMesh.off");
1223 trace.info() << "[done]"<< endl ;
1225 if( e->key() == Qt::Key_M)
1227 switch (myRenderingMode)
1229 case RenderingMode::RenderingDefault :
1230 myRenderingMode = RenderingMode::RenderingMetallic;
1232 case RenderingMode::RenderingMetallic :
1233 myRenderingMode = RenderingMode::RenderingPlastic;
1235 case RenderingMode::RenderingPlastic :
1236 myRenderingMode = RenderingMode::RenderingLambertian;
1238 case RenderingMode::RenderingLambertian :
1239 myRenderingMode = RenderingMode::RenderingDefault;
1242 updateRenderingCoefficients(myRenderingMode);
1247 if ( ( e->key() ==Qt::Key_W ) )
1249 myViewWire=!myViewWire;
1254 if ( ( e->key() ==Qt::Key_P ) )
1256 myLightPositionFixToCamera =! myLightPositionFixToCamera;
1257 updateLightCoordsFromCamera();
1258 if(myLightPositionFixToCamera)
1260 displayMessage(QString("Light source position fixed to camera."), 3000);
1261 updateRelativeCameraFromLightPosition();
1265 displayMessage(QString("Light source position fixed to main scene."), 3000);
1266 //updateLightCoordsFromCamera();
1271 if ( ( e->key() ==Qt::Key_O ) )
1273 myUseGLPointsForBalls = !myUseGLPointsForBalls;
1278 if ( ( e->key() ==Qt::Key_R ) )
1280 myGLScaleFactorX=1.0f;
1281 myGLScaleFactorY=1.0f;
1282 myGLScaleFactorZ=1.0f;
1286 if ( ( e->key() ==Qt::Key_T ) )
1289 DGtal::trace.info() << "sorting surfel according camera position....";
1290 sortSurfelFromCamera();
1291 sortTriangleFromCamera();
1292 sortQuadFromCamera();
1293 sortPolygonFromCamera();
1294 DGtal::trace.info() << " [done]"<< std::endl;
1298 if ( ( e->key() ==Qt::Key_B ) )
1301 myIsBackgroundDefault=!myIsBackgroundDefault;
1302 if ( !myIsBackgroundDefault )
1304 setBackgroundColor ( QColor ( 255, 255,255 ) );
1308 setBackgroundColor ( QColor ( 217, 228, 255 ) );
1313 if ( ( e->key() ==Qt::Key_L ) )
1315 if(e->modifiers()==Qt::ShiftModifier){
1318 restoreStateFromFile();
1322 if ( ( e->key() ==Qt::Key_C ) )
1326 GLdouble Projection[16], Modelview[16];
1328 glGetIntegerv ( GL_VIEWPORT , Viewport );
1329 glGetDoublev ( GL_MODELVIEW_MATRIX , Modelview );
1330 glGetDoublev ( GL_PROJECTION_MATRIX, Projection );
1332 for ( unsigned short m=0; m<4; ++m )
1334 for ( unsigned short l=0; l<4; ++l )
1337 for ( unsigned short k=0; k<4; ++k )
1338 sum += Projection[l+4*k]*Modelview[k+4*m];
1342 DGtal::trace.info() << "Viewport: ";
1343 for ( unsigned short l=0; l<4; ++l )
1344 DGtal::trace.info() << Viewport[l] << ", ";
1345 DGtal::trace.info() << std::endl;
1347 Vec cp = camera()->position();
1348 Vec cd = camera()->viewDirection();
1349 Vec cup = camera()->upVector();
1351 DGtal::trace.info() << "camera.position: " ;
1352 for ( unsigned short l=0; l<3; ++l )
1353 DGtal::trace.info() << cp[l] << ", ";
1354 DGtal::trace.info() << std::endl;
1356 DGtal::trace.info() << "camera.direction: ";
1357 for ( unsigned short l=0; l<3; ++l )
1358 DGtal::trace.info() << cd[l] << ", ";
1359 DGtal::trace.info() << std::endl;
1361 DGtal::trace.info() << "camera.upVector: ";
1362 for ( unsigned short l=0; l<3; ++l )
1363 DGtal::trace.info() << cup[l] << ", ";
1364 DGtal::trace.info() << std::endl;
1366 DGtal::trace.info() << "zNear: " << camera()->zNear() << " - zFar: " << camera()->zFar() << std::endl;
1370 QGLViewer::keyPressEvent ( e );
1376 template< typename Space, typename KSpace>
1378 DGtal::Viewer3D<Space, KSpace>::helpString() const
1380 QString text ( "<h2> Viewer3D</h2>" );
1381 text += "Use the mouse to move the camera around the object. ";
1382 text += "You can respectively revolve around, zoom and translate with the three mouse buttons. ";
1383 text += "Left and middle buttons pressed together rotate around the camera view direction axis<br><br>";
1384 text += "Pressing <b>Alt</b> and one of the function keys (<b>F1</b>..<b>F12</b>) defines a camera keyFrame. ";
1385 text += "Simply press the function key again to restore it-> Several keyFrames define a ";
1386 text += "camera path. Paths are saved when you quit the application and restored at next start.<br><br>";
1387 text += "Press <b>F</b> to display the frame rate, <b>A</b> for the world axis, ";
1388 text += "<b>Alt+Return</b> for full screen mode and <b>Control+S</b> to save a snapshot. ";
1389 text += "See the <b>Keyboard</b> tab in this window for a complete shortcut list.<br><br>";
1390 text += "Double clicks automates single click actions: A left button double click aligns the closer axis with the camera (if close enough). ";
1391 text += "A middle button double click fits the zoom of the camera and the right button re-centers the scene.<br><br>";
1392 text += "A left button double click while holding right button pressed defines the camera <i>Revolve Around Ball</i>. ";
1393 text += "See the <b>Mouse</b> tab and the documentation web pages for details.<br><br>";
1394 text += "Press <b>Escape</b> to exit the viewer.";
1401 template< typename Space, typename KSpace>
1403 DGtal::Viewer3D<Space, KSpace>::glCreateListCubesMaps(const typename DGtal::Display3D<Space, KSpace>::CubesMap &aCubeMap,
1404 unsigned int idList){
1405 glNewList ( idList , GL_COMPILE );
1407 for (auto &mapElem: aCubeMap)
1409 glPushName ( mapElem.first );
1410 glEnable ( GL_LIGHTING );
1411 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
1412 glBegin ( GL_QUADS );
1413 bool useColorSelection = false;
1414 if(mySelectedElementId == mapElem.first)
1415 useColorSelection = true;
1417 for (auto &cube: mapElem.second)
1419 if(useColorSelection)
1421 unsigned char m = (cube.color.red()+ cube.color.green()+ cube.color.blue())/3;
1424 glColor4ub ( std::max((int)(cube.color.red())-mySelectionColorShift, 0),
1425 std::max((int)(cube.color.green())-mySelectionColorShift, 0),
1426 std::max((int)(cube.color.blue())-mySelectionColorShift, 0),
1427 cube.color.alpha());
1430 glColor4ub ( std::min(cube.color.red()+mySelectionColorShift, 255),
1431 std::min(cube.color.green()+mySelectionColorShift, 255),
1432 std::min(cube.color.blue()+mySelectionColorShift, 255),
1433 cube.color.alpha());
1438 glColor4ub ( cube.color.red(), cube.color.green(), cube.color.blue(),cube.color.alpha());
1440 double _width= cube.width;
1442 glNormal3f ( 0.0, 0.0, 1.0 );
1443 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
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 );
1448 glNormal3f ( 0.0, 0.0, -1.0 );
1449 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
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 );
1454 glNormal3f ( 1.0, 0.0, 0.0 );
1455 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
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 );
1460 glNormal3f ( -1.0, 0.0, 0.0 );
1461 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
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 );
1466 glNormal3f ( 0.0, 1.0, 0.0 );
1467 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
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 );
1472 glNormal3f ( 0.0, -1.0, 0.0 );
1473 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
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 );
1482 glUpdateLightRenderingMode();
1488 template< typename Space, typename KSpace>
1490 DGtal::Viewer3D<Space, KSpace>::glCreateListQuadD3D(const VectorQuad &aVectQuad,
1491 unsigned int idList){
1492 glNewList ( idList, GL_COMPILE );
1493 glPushName ( myNbListe );
1494 glEnable ( GL_DEPTH_TEST );
1495 glEnable ( GL_BLEND );
1496 glEnable ( GL_MULTISAMPLE_ARB );
1497 glEnable ( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
1498 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1500 glBegin ( GL_QUADS );
1501 for ( auto const &q: aVectQuad )
1503 glColor4ub ( q.color.red(), q.color.green(),
1504 q.color.blue(), q.color.alpha() );
1505 glNormal3f ( q.nx, q.ny, q.nz );
1506 glVertex3f ( q.point1[0], q.point1[1] , q.point1[2] );
1507 glVertex3f ( q.point2[0], q.point2[1] , q.point2[2] );
1508 glVertex3f ( q.point3[0], q.point3[1] , q.point3[2] );
1509 glVertex3f ( q.point4[0], q.point4[1] , q.point4[2] );
1517 template< typename Space, typename KSpace>
1519 DGtal::Viewer3D<Space, KSpace>::glCreateListLines(const VectorLine &aVectLine,
1520 unsigned int idList){
1521 glNewList ( idList, GL_COMPILE );
1522 glDisable ( GL_LIGHTING );
1523 glPushName ( myNbListe );
1524 glBegin ( GL_LINES );
1525 for (auto const &l: aVectLine )
1527 glColor4ub ( l.color.red(), l.color.green(),
1528 l.color.blue(), l.color.alpha() );
1529 glVertex3f ( l.point1[0], l.point1[1], l.point1[2] );
1530 glVertex3f ( l.point2[0], l.point2[1], l.point2[2] );
1533 glEnable ( GL_LIGHTING );
1539 template< typename Space, typename KSpace>
1541 DGtal::Viewer3D<Space, KSpace>::glCreateListBalls(const VectorBall &aVectBall,
1542 unsigned int idList){
1543 if(myUseGLPointsForBalls)
1545 glNewList ( idList, GL_COMPILE );
1546 glDepthMask ( GL_TRUE );
1547 glDisable ( GL_TEXTURE_2D );
1548 glDisable ( GL_POINT_SMOOTH );
1549 glDisable ( GL_LIGHTING );
1550 glPushName ( myNbListe );
1551 glBegin ( GL_POINTS );
1552 for ( auto const &ball: aVectBall )
1554 glColor4ub ( ball.color.red(), ball.color.green(),
1555 ball.color.blue(), ball.color.alpha() );
1556 glVertex3f ( ball.center[0], ball.center[1], ball.center[2] );
1559 glEnable ( GL_LIGHTING );
1564 glNewList ( idList, GL_COMPILE );
1565 glPushName ( myNbListe );
1566 glDepthMask ( GL_TRUE );
1567 glDisable ( GL_TEXTURE_2D );
1568 glDisable ( GL_POINT_SMOOTH );
1569 for ( auto const & b: aVectBall)
1581 template< typename Space, typename KSpace>
1583 DGtal::Viewer3D<Space, KSpace>::glCreateListQuadMaps(const typename DGtal::Display3D<Space, KSpace>::QuadsMap &aQuadMap,
1584 unsigned int idList){
1585 glNewList ( idList, GL_COMPILE );
1586 for (auto & mapElem: aQuadMap)
1588 glPushName ( mapElem.first );
1589 glEnable ( GL_LIGHTING );
1590 glBegin ( GL_QUADS );
1591 bool useColorSelection = false;
1592 if(mySelectedElementId == mapElem.first)
1593 useColorSelection = true;
1595 for (auto &q: mapElem.second)
1597 if(useColorSelection)
1599 unsigned char m = (q.color.red()+ q.color.green()+ q.color.blue())/3;
1602 glColor4ub ( std::max((int)(q.color.red())-mySelectionColorShift, 0),
1603 std::max((int)(q.color.green())-mySelectionColorShift, 0),
1604 std::max((int)(q.color.blue())-mySelectionColorShift, 0),
1608 glColor4ub ( std::min(q.color.red()+mySelectionColorShift, 255),
1609 std::min(q.color.green()+mySelectionColorShift, 255),
1610 std::min(q.color.blue()+mySelectionColorShift, 255),
1616 glColor4ub ( q.color.red(), q.color.green(), q.color.blue(), q.color.alpha());
1620 glNormal3f ( q.nx, q.ny ,q.nz );
1621 glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
1622 glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
1623 glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
1624 glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
1635 template< typename Space, typename KSpace>
1637 DGtal::Viewer3D<Space, KSpace>::glCreateListQuadMapsWired(const typename DGtal::Display3D<Space, KSpace>::QuadsMap &aQuadMap,
1638 unsigned int idList){
1639 glNewList ( idList, GL_COMPILE );
1640 glPushName ( myNbListe );
1641 glDisable ( GL_LIGHTING );
1642 glBegin ( GL_LINES );
1644 for (auto const &mapElem: aQuadMap)
1646 for(auto const &q: mapElem.second)
1648 glColor4ub ( 150.0,150.0,150.0,255.0 );
1649 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1650 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1651 Viewer3D<Space, KSpace>::myCurrentLineColor.blue(),
1652 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1653 glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
1654 glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
1655 glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
1656 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1657 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1658 Viewer3D<Space, KSpace>::myCurrentLineColor.blue(),
1659 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1660 glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
1661 glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
1662 glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
1663 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1664 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1665 Viewer3D<Space, KSpace>::myCurrentLineColor.blue(),
1666 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1667 glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
1668 glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
1677 template< typename Space, typename KSpace>
1679 DGtal::Viewer3D<Space, KSpace>::glCreateListTriangles(const std::vector<VectorTriangle> &aVectTriangle,
1680 unsigned int idList){
1681 glNewList ( idList, GL_COMPILE );
1682 glPushName ( myNbListe );
1683 glEnable ( GL_LIGHTING );
1684 glBegin ( GL_TRIANGLES );
1685 for(auto const &tList: aVectTriangle)
1687 for (auto const &t: tList)
1689 glColor4ub (t.color.red(),t.color.green(),t.color.blue(),t.color.alpha() );
1690 glNormal3f (t.nx,t.ny ,t.nz );
1691 glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
1692 glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
1693 glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
1701 template< typename Space, typename KSpace>
1703 DGtal::Viewer3D<Space, KSpace>::glCreateListTrianglesWired(const std::vector<VectorTriangle> &aVectTriangle,
1704 unsigned int idList){
1705 glNewList ( idList, GL_COMPILE );
1706 glPushName ( myNbListe );
1707 glDisable ( GL_LIGHTING );
1708 glBegin ( GL_LINES );
1709 for (auto const &tList: aVectTriangle)
1711 for (auto const &t: tList)
1713 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1714 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1715 Viewer3D<Space, KSpace>::myCurrentLineColor.blue(),
1716 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1717 glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
1718 glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
1719 glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
1720 glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
1721 glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
1722 glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
1732 template< typename Space, typename KSpace>
1734 DGtal::Viewer3D<Space, KSpace>::glCreateListPolygons(const std::vector<VectorPolygon> &aVectPolygon,
1735 unsigned int idList){
1736 glNewList ( idList, GL_COMPILE );
1737 glPushName ( myNbListe );
1738 glEnable ( GL_LIGHTING );
1740 for(auto const &pList: aVectPolygon)
1742 for (auto const &p: pList)
1744 glBegin ( GL_POLYGON );
1745 glColor4ub ( p.color.red(), p.color.green(), p.color.blue(), p.color.alpha() );
1746 glNormal3f ( p.nx, p.ny ,p.nz );
1747 for(unsigned int j=0;j < (p.vertices).size();j++)
1749 glVertex3f ( (p.vertices).at(j)[0], (p.vertices).at(j)[1], (p.vertices).at ( j )[2] );
1759 template< typename Space, typename KSpace>
1761 DGtal::Viewer3D<Space, KSpace>::glCreateListPolygonsWired(const std::vector<VectorPolygon> &aVectPolygon,
1762 unsigned int idList){
1763 glNewList ( idList, GL_COMPILE );
1764 glPushName ( myNbListe );
1765 glDisable ( GL_LIGHTING );
1766 glBegin ( GL_LINES );
1767 for(auto const &pList: aVectPolygon)
1769 for (auto const &p: pList)
1771 glColor4ub ( Viewer3D<Space, KSpace>::myCurrentLineColor.red(),
1772 Viewer3D<Space, KSpace>::myCurrentLineColor.green(),
1773 Viewer3D<Space, KSpace>::myCurrentLineColor.blue() ,
1774 Viewer3D<Space, KSpace>::myCurrentLineColor.alpha() );
1775 for(unsigned int j=0;j < (p.vertices).size();j++)
1777 glVertex3f ( (p.vertices).at(j)[0], (p.vertices).at(j)[1], (p.vertices).at ( j )[2] );
1778 glVertex3f ( (p.vertices).at((j+1)%(p.vertices).size())[0],
1779 (p.vertices).at((j+1)%(p.vertices).size())[1],
1780 (p.vertices).at ( (j+1)%(p.vertices).size() )[2] );
1790 template< typename Space, typename KSpace>
1792 DGtal::Viewer3D<Space, KSpace>::glUpdateTextureImages(const VectorTextureImage &aVectImage){
1794 for(unsigned int j=0; j<myVectTextureImage.size(); j++){
1795 glDeleteTextures(1,&(myVectTextureImage[j].myTextureName));
1797 myVectTextureImage.clear();
1798 for(unsigned int j=0; j<aVectImage.size(); j++)
1800 typename Viewer3D<Space, KSpace>::TextureImage aGSImage = aVectImage.at(j);
1801 GLTextureImage textureImg(aGSImage);
1803 glGenTextures(1, &textureImg.myTextureName);
1804 glBindTexture(GL_TEXTURE_2D, textureImg.myTextureName);
1806 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1807 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1808 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1809 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1810 if(textureImg.myMode==Viewer3D<Space, KSpace>::GrayScaleMode)
1812 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, textureImg.myBufferWidth, textureImg.myBufferHeight, 0,
1813 GL_LUMINANCE, GL_UNSIGNED_BYTE, textureImg.myTextureImageBufferGS);
1814 }else if(textureImg.myMode==Viewer3D<Space, KSpace>::RGBMode)
1816 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureImg.myBufferWidth, textureImg.myBufferHeight, 0,
1817 GL_RGB, GL_UNSIGNED_BYTE, textureImg.myTextureImageBufferRGB);
1819 myVectTextureImage.push_back(textureImg);
1823 template< typename Space, typename KSpace>
1825 DGtal::Viewer3D<Space, KSpace>::glUpdateLightRenderingMode() const
1827 if(myIsDoubleFaceRendering)
1828 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
1830 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
1835 template< typename Space, typename KSpace>
1837 DGtal::Viewer3D<Space, KSpace>::domElement(const QString& name, QDomDocument& document) const
1839 // Creates a custom node for a light position
1840 QDomElement deRendering = document.createElement("Rendering");
1841 deRendering.setAttribute("mode", myRenderingMode);
1842 QDomElement de = document.createElement("Light");
1843 de.setAttribute("pos_light_x", myLightPosition[0]);
1844 de.setAttribute("pos_light_y", myLightPosition[1]);
1845 de.setAttribute("pos_light_z", myLightPosition[2]);
1846 // Get default state domElement and append custom node
1847 QDomElement res = QGLViewer::domElement(name, document);
1848 res.appendChild(de);
1849 res.appendChild(deRendering);
1855 template< typename Space, typename KSpace>
1857 DGtal::Viewer3D<Space, KSpace>::initFromDOMElement(const QDomElement& element)
1859 // Restore standard state
1860 QGLViewer::initFromDOMElement(element);
1861 QDomElement child=element.firstChild().toElement();
1862 while (!child.isNull())
1864 if (child.tagName() == "Rendering")
1866 myRenderingMode = (RenderingMode)(child.attribute("mode").toInt());
1868 if (child.tagName() == "Light")
1870 if (child.hasAttribute("pos_light_x"))
1872 myLightPosition[0] = child.attribute("pos_light_x").toDouble();
1875 if (child.hasAttribute("pos_light_y"))
1877 myLightPosition[1] = child.attribute("pos_light_y").toDouble();
1879 if (child.hasAttribute("pos_light_z"))
1881 myLightPosition[2] = child.attribute("pos_light_z").toDouble();
1884 child = child.nextSibling().toElement();
1886 if(myLightPositionFixToCamera){
1887 updateRelativeCameraFromLightPosition();
1889 updateRenderingCoefficients(myRenderingMode, false);
1894 template< typename Space, typename KSpace>
1896 DGtal::Viewer3D<Space, KSpace>::closeEvent ( QCloseEvent * e ){
1897 if (myAutoSaveState)
1901 QGLWidget::closeEvent(e);
1904 template< typename Space, typename KSpace>
1906 DGtal::Viewer3D<Space, KSpace>::setGLDoubleRenderingMode(bool doubleSidedRendering)
1908 myIsDoubleFaceRendering = doubleSidedRendering;
1909 glUpdateLightRenderingMode();
1913 template< typename Space, typename KSpace>
1915 DGtal::Viewer3D<Space, KSpace>::setGLMaterialShininessCoefficient(const GLfloat matShininessCoeff)
1917 myMaterialShininessCoeff = matShininessCoeff;
1922 template< typename Space, typename KSpace>
1924 DGtal::Viewer3D<Space, KSpace>::setGLLightAmbientCoefficients(const GLfloat lightAmbientCoeffs [4])
1926 myLightAmbientCoeffs[0] = lightAmbientCoeffs[0];
1927 myLightAmbientCoeffs[1] = lightAmbientCoeffs[1];
1928 myLightAmbientCoeffs[2] = lightAmbientCoeffs[2];
1929 myLightAmbientCoeffs[3] = lightAmbientCoeffs[3];
1934 template< typename Space, typename KSpace>
1936 DGtal::Viewer3D<Space, KSpace>::setGLLightDiffuseCoefficients(const GLfloat lightDiffuseCoeffs [4])
1938 myLightDiffuseCoeffs[0] = lightDiffuseCoeffs[0];
1939 myLightDiffuseCoeffs[1] = lightDiffuseCoeffs[1];
1940 myLightDiffuseCoeffs[2] = lightDiffuseCoeffs[2];
1941 myLightDiffuseCoeffs[3] = lightDiffuseCoeffs[3];
1946 template< typename Space, typename KSpace>
1948 DGtal::Viewer3D<Space, KSpace>::setUseGLPointForBalls(const bool useOpenGLPt)
1950 myUseGLPointsForBalls = useOpenGLPt;
1955 template< typename Space, typename KSpace>
1957 DGtal::Viewer3D<Space, KSpace>::updateRenderingCoefficients(const RenderingMode aRenderMode, bool displayState)
1960 ss << "Rendering mode ";
1962 GLfloat newCoefDiff, newCoefSpec = 1.0f;
1963 switch (aRenderMode)
1965 case RenderingMode::RenderingDefault :
1966 newCoefDiff = myDefaultRenderDiff;
1967 newCoefSpec = myDefaultRenderSpec;
1968 ss << "Default (diffuse with few specular)";
1970 case RenderingMode::RenderingMetallic :
1971 newCoefDiff = myMetallicRenderDiff;
1972 newCoefSpec = myMetallicRenderSpec;
1973 ss << "Metallic (diffuse with specular)";
1975 case RenderingMode::RenderingPlastic :
1976 newCoefDiff = myPlasticRenderDiff;
1977 newCoefSpec = myPlasticRenderSpec;
1978 ss << "Plastic (few diffuse with large specular)";
1980 case RenderingMode::RenderingLambertian :
1981 newCoefDiff = myLambertRenderDiff;
1982 newCoefSpec = myLambertRenderSpec;
1983 ss << "Lambertian (only diffuse)";
1986 for (unsigned int i = 0; i<3; i++)
1987 myLightDiffuseCoeffs[i] = newCoefDiff;
1988 myLightDiffuseCoeffs[3] = 1.0;
1989 for (unsigned int i = 0; i<3; i++)
1990 myLightSpecularCoeffs[i] = newCoefSpec;
1991 myLightSpecularCoeffs[3] = 1.0;
1994 displayMessage(QString(ss.str().c_str()), 3000);
2001 template< typename Space, typename KSpace>
2003 DGtal::Viewer3D<Space, KSpace>::setGLLightSpecularCoefficients(const GLfloat lightSpecularCoeffs [4])
2005 myLightSpecularCoeffs[0] = lightSpecularCoeffs[0];
2006 myLightSpecularCoeffs[1] = lightSpecularCoeffs[1];
2007 myLightSpecularCoeffs[2] = lightSpecularCoeffs[2];
2008 myLightSpecularCoeffs[3] = lightSpecularCoeffs[3];
2013 template<typename Space, typename KSpace>
2016 DGtal::Viewer3D<Space, KSpace>::show(){
2022 template<typename Space, typename KSpace>
2025 DGtal::Viewer3D<Space, KSpace>::paintGL(){
2026 if (displaysInStereo())
2028 for (int view=1; view>=0; --view)
2030 // Clears screen, set model view matrix with shifted matrix for ith buffer
2031 preDrawStereo(view);
2033 // Used defined method. Default is empty
2034 if (camera()->frame()->isManipulated())
2043 // Clears screen, set model view matrix...
2046 // Used defined method. Default calls draw()
2047 if (camera()->frame()->isManipulated())
2051 // Add visual hints: axis, camera, grid...
2054 Q_EMIT drawFinished(true);
2058 template< typename Space, typename KSpace>
2059 void DGtal::Viewer3D<Space, KSpace>::updateLightCoordsFromCamera() {
2061 posLCam[0] = myLightPositionRefCamera[0];
2062 posLCam[1] = myLightPositionRefCamera[1];
2063 posLCam[2] = myLightPositionRefCamera[2];
2064 Vec posL = camera()->worldCoordinatesOf(posLCam);
2065 myLightPosition[0] = static_cast<GLfloat>(posL[0]);
2066 myLightPosition[1] = static_cast<GLfloat>(posL[1]);
2067 myLightPosition[2] = static_cast<GLfloat>(posL[2]);
2068 myLightPosition[3] = 1.0f;
2073 template< typename Space, typename KSpace>
2074 void DGtal::Viewer3D<Space, KSpace>::updateRelativeCameraFromLightPosition() {
2076 posL[0] = myLightPosition[0];
2077 posL[1] = myLightPosition[1];
2078 posL[2] = myLightPosition[2];
2079 Vec posLCam = camera()->cameraCoordinatesOf(posL);
2080 myLightPositionRefCamera[0] = static_cast<GLfloat>(posLCam[0]);
2081 myLightPositionRefCamera[1] = static_cast<GLfloat>(posLCam[1]);
2082 myLightPositionRefCamera[2] = static_cast<GLfloat>(posLCam[2]);