DGtal 1.3.0
Loading...
Searching...
No Matches
Viewer3D.ih
1/**
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.
6 *
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.
11 *
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/>.
14 *
15 **/
16
17/**
18 * @file Viewer3D.ih
19 * @author Bertrand Kerautret (\c kerautre@loria.fr )
20 * LORIA (CNRS, UMR 7503), University of Nancy, France
21 *
22 * @date 2011/01/03
23 *
24 * Implementation of inline methods defined in Viewer3D.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29///////////////////////////////////////////////////////////////////////////////
30// IMPLEMENTATION of inline methods.
31///////////////////////////////////////////////////////////////////////////////
32
33//////////////////////////////////////////////////////////////////////////////
34#ifdef _MSC_VER
35#define NOMINMAX
36#include <windows.h>
37#include <GL/gl.h>
38#include "DGtal/io/viewers/windows/GL/glext.h"
39#endif
40
41#include "DGtal/io/viewers/Viewer3D.h"
42
43#include <algorithm>
44#include <limits>
45#include <QColor>
46#include <QTextEdit>
47#include <QMessageBox>
48#include <QTextStream>
49#include <QDir>
50
51#include <cstdlib>
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//////////////////////////////////////////////////////////////////////////////
58
59using namespace qglviewer;
60
61///////////////////////////////////////////////////////////////////////////////
62// Implementation of inline methods //
63
64template <typename TSpace, typename TKSpace>
65inline void DGtal::Viewer3D<TSpace, TKSpace>::rotateDomain(
66Image2DDomainD3D & anDom, double angleRotation, ImageDirection rotationDir )
67{
68 DGtal::PointVector<3, int> pt;
69 pt[0] = (int) (anDom.point1[0]+anDom.point2[0]+anDom.point3[0]+anDom.point4[0])/4.0;
70 pt[1] = (int) (anDom.point1[1]+anDom.point2[1]+anDom.point3[1]+anDom.point4[1])/4.0;
71 pt[2] = (int) (anDom.point1[2]+anDom.point2[2]+anDom.point3[2]+anDom.point4[2])/4.0;
72 rotateImageVertex(anDom, angleRotation, rotationDir);
73
74 std::vector<typename DGtal::Display3D<TSpace, TKSpace>::LineD3D> & aVectLine =
75 Viewer3D<TSpace, TKSpace>::myLineSetList.at( anDom.myLineSetIndex );
76 for(unsigned int i = 0; i< aVectLine.size();i++){
77 typename DGtal::Display3D<TSpace, TKSpace>::LineD3D & aLine =
78 aVectLine.at( i );
79 rotateLineD3D(aLine, pt, angleRotation, rotationDir );
80 }
81
82}
83
84template <typename TSpace, typename TKSpace>
85template <typename TValues>
86inline void DGtal::Viewer3D<TSpace, TKSpace>::rotatePoint(
87TValues & x, TValues & y, TValues & z, double cx, double cy, double cz,
88double angleRotation, ImageDirection rotationDir )
89{
90 double dx = x-cx; double dy = y-cy; double dz = z-cz;
91 if(rotationDir == zDirection){
92 x = cx+dx*cos(angleRotation)-dy*sin(angleRotation);
93 y = cy+dx*sin(angleRotation)+dy*cos(angleRotation);
94 }
95 if(rotationDir == yDirection){
96 x = cx+dx*cos(angleRotation)-dz*sin(angleRotation);
97 z = cz+dx*sin(angleRotation)+dz*cos(angleRotation);
98 }
99 if(rotationDir == xDirection){
100 y = cy+dy*cos(angleRotation)-dz*sin(angleRotation);
101 z = cz+dy*sin(angleRotation)+dz*cos(angleRotation);
102 }
103}
104
105template <typename TSpace, typename TKSpace>
106template <typename TContainer>
107inline void DGtal::Viewer3D<TSpace, TKSpace>::rotateLineD3D(
108typename DGtal::Display3D<TSpace, TKSpace>::LineD3D & aLine,
109DGtal::PointVector<3, int, TContainer> pt, double angleRotation,
110ImageDirection dirRotation )
111{
112 double dx1 = aLine.point1[0] - pt[0]; double dy1 = aLine.point1[1] - pt[1]; double dz1 = aLine.point1[2] - pt[2];
113 double dx2 = aLine.point2[0] - pt[0]; double dy2 = aLine.point2[1] - pt[1]; double dz2 = aLine.point2[2] - pt[2];
114 if(dirRotation==zDirection){
115 aLine.point1[0]=pt[0]+dx1*std::cos(angleRotation)-dy1*std::sin(angleRotation);
116 aLine.point1[1]=pt[1]+dx1*std::sin(angleRotation)+dy1*std::cos(angleRotation);
117
118 aLine.point2[0]=pt[0]+dx2*std::cos(angleRotation)-dy2*std::sin(angleRotation);
119 aLine.point2[1]=pt[1]+dx2*std::sin(angleRotation)+dy2*std::cos(angleRotation);
120
121 }else if(dirRotation==xDirection){
122 aLine.point1[1]=pt[1]+dy1*std::cos(angleRotation)-dz1*std::sin(angleRotation);
123 aLine.point1[2]=pt[2]+dy1*std::sin(angleRotation)+dz1*std::cos(angleRotation);
124
125 aLine.point2[1]=pt[1]+dy2*std::cos(angleRotation)-dz2*std::sin(angleRotation);
126 aLine.point2[2]=pt[2]+dy2*std::sin(angleRotation)+dz2*std::cos(angleRotation);
127 }else if(dirRotation==yDirection){
128 aLine.point1[0]=pt[0]+dx1*std::cos(angleRotation)-dz1*std::sin(angleRotation);
129 aLine.point1[2]=pt[2]+dx1*std::sin(angleRotation)+dz1*std::cos(angleRotation);
130
131 aLine.point2[0]=pt[0]+dx2*std::cos(angleRotation)-dz2*std::sin(angleRotation);
132 aLine.point2[2]=pt[2]+dx2*std::sin(angleRotation)+dz2*std::cos(angleRotation);
133 }else{
134 trace.error() << "No direction!!"<< std::endl;
135 }
136
137}
138
139template <typename TSpace, typename TKSpace>
140inline unsigned int DGtal::Viewer3D<TSpace, TKSpace>::getCurrentDomainNumber()
141{
142 return static_cast<unsigned int>(myImageDomainList.size());
143}
144
145template <typename TSpace, typename TKSpace>
146inline unsigned int DGtal::Viewer3D<TSpace, TKSpace>::getCurrentGLImageNumber()
147{
148 return static_cast<unsigned int>(myGSImageList.size());
149}
150
151template <typename TSpace, typename TKSpace>
152inline void DGtal::Viewer3D<TSpace, TKSpace>::addTextureImage(
153const typename Viewer3D<TSpace, TKSpace>::TextureImage & image )
154{
155 myGSImageList.push_back(image);
156 Display3D<TSpace, TKSpace>::updateBoundingBox( image.point1 );
157 Display3D<TSpace, TKSpace>::updateBoundingBox( image.point2 );
158 Display3D<TSpace, TKSpace>::updateBoundingBox( image.point3 );
159 Display3D<TSpace, TKSpace>::updateBoundingBox( image.point4 );
160}
161
162template <typename TSpace, typename TKSpace>
163template <typename TImageType, typename TFunctor>
164inline void DGtal::Viewer3D<TSpace, TKSpace>::updateTextureImage(
165unsigned int imageIndex, const TImageType & image, const TFunctor & aFunctor,
166double xTranslation, double yTranslation, double zTranslation,
167double rotationAngle, ImageDirection rotationDir )
168{
169 BOOST_CONCEPT_ASSERT(( concepts::CConstImage < TImageType > ));
170 assert ( imageIndex< myGSImageList.size());
171 typename Viewer3D<TSpace, TKSpace>::TextureImage & anImage =
172 myGSImageList.at( imageIndex );
173 Display::updateBoundingBox(RealPoint(anImage.point1[0]+xTranslation,
174 anImage.point1[1]+yTranslation,
175 anImage.point1[2]+zTranslation));
176 Display::updateBoundingBox(RealPoint(anImage.point2[0]+xTranslation,
177 anImage.point2[1]+yTranslation,
178 anImage.point2[2]+zTranslation));
179 Display::updateBoundingBox(RealPoint(anImage.point3[0]+xTranslation,
180 anImage.point3[1]+yTranslation,
181 anImage.point3[2]+zTranslation));
182 Display::updateBoundingBox(RealPoint(anImage.point4[0]+xTranslation,
183 anImage.point4[1]+yTranslation,
184 anImage.point4[2]+zTranslation));
185 anImage.updateImageDataAndParam(image, aFunctor, xTranslation, yTranslation, zTranslation);
186 if(anImage.myDrawDomain)
187 {
188 *this << DGtal::Translate2DDomain(anImage.myIndexDomain, xTranslation, yTranslation, zTranslation);
189 }
190
191 if(rotationAngle!=0.0){
192 rotateDomain(myImageDomainList.at(anImage.myIndexDomain), rotationAngle, rotationDir);
193 rotateImageVertex(anImage, rotationAngle, rotationDir);
194 }
195}
196
197template <typename TSpace, typename TKSpace>
198inline void DGtal::Viewer3D<TSpace, TKSpace>::updateOrientationTextureImage(
199unsigned int imageIndex, double xPosition, double yPosition, double zPosition,
200ImageDirection newDirection )
201{
202 assert ( imageIndex< myGSImageList.size());
203 typename Viewer3D<TSpace, TKSpace>::TextureImage & anImage =
204 myGSImageList.at( imageIndex );
205 Display3D<TSpace, TKSpace>::updateBoundingBox( anImage.point1 );
206 Display3D<TSpace, TKSpace>::updateBoundingBox( anImage.point2 );
207 Display3D<TSpace, TKSpace>::updateBoundingBox( anImage.point3 );
208 Display3D<TSpace, TKSpace>::updateBoundingBox( anImage.point4 );
209 anImage.updateImageOrientation(newDirection, xPosition, yPosition, zPosition);
210 if(anImage.myDrawDomain)
211 {
212 *this << DGtal::Update2DDomainPosition<Space ,KSpace >(anImage.myIndexDomain,
213 newDirection,
214 xPosition,
215 yPosition, zPosition);
216 }
217}
218
219template <typename TSpace, typename TKSpace>
220inline void DGtal::Viewer3D<TSpace, TKSpace>::updateEmbeddingTextureImage(
221unsigned int anImageIndex, typename Space::Point aPoint1,
222typename Space::Point aPoint2, typename Space::Point aPoint3,
223typename Space::Point aPoint4 )
224{
225 assert ( anImageIndex< myGSImageList.size());
226 typename Viewer3D<TSpace, TKSpace>::TextureImage & anImage =
227 myGSImageList.at( anImageIndex );
228 Display3D<TSpace, TKSpace>::updateBoundingBox( aPoint1 );
229 Display3D<TSpace, TKSpace>::updateBoundingBox( aPoint2 );
230 Display3D<TSpace, TKSpace>::updateBoundingBox( aPoint3 );
231 Display3D<TSpace, TKSpace>::updateBoundingBox( aPoint4 );
232 anImage.updateImage3DEmbedding(aPoint1, aPoint2, aPoint3, aPoint4);
233}
234
235template <typename TSpace, typename TKSpace>
236inline void
237DGtal::Viewer3D<TSpace, TKSpace>::TextureImage::updateImageOrientation(
238ImageDirection normalDir, double xBottomLeft, double yBottomLeft,
239double zBottomLeft )
240{
241 if(normalDir==zDirection)
242 {
243 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft-0.5; point1[2] = zBottomLeft;
244 point2[0] = xBottomLeft+myImageWidth-0.5; point2[1] = yBottomLeft-0.5; point2[2] = zBottomLeft;
245 point3[0] = xBottomLeft+myImageWidth-0.5; point3[1] = yBottomLeft+myImageHeight-0.5; point3[2] = zBottomLeft;
246 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft+myImageHeight-0.5; point4[2] = zBottomLeft;
247 }else if(normalDir==yDirection)
248 {
249 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft; point1[2] = zBottomLeft-0.5;
250 point2[0] = xBottomLeft+myImageWidth-0.5; point2[1] = yBottomLeft; point2[2] = zBottomLeft-0.5;
251 point3[0] = xBottomLeft+myImageWidth-0.5; point3[1] = yBottomLeft; point3[2] = zBottomLeft+myImageHeight-0.5;
252 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft; point4[2] = zBottomLeft+myImageHeight-0.5;
253 }else if(normalDir==xDirection)
254 {
255 point1[0] = xBottomLeft; point1[1] = yBottomLeft-0.5; point1[2]= zBottomLeft-0.5;
256 point2[0] = xBottomLeft; point2[1] = yBottomLeft+myImageWidth-0.5; point2[2] = zBottomLeft-0.5;
257 point3[0] = xBottomLeft; point3[1] = yBottomLeft+myImageWidth-0.5; point3[2] = zBottomLeft+myImageHeight-0.5;
258 point4[0] = xBottomLeft; point4[1] = yBottomLeft-0.5; point4[2] = zBottomLeft+myImageHeight-0.5;
259 }
260 myDirection=normalDir;
261}
262
263template <typename TSpace, typename TKSpace>
264inline void
265DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D::updateDomainOrientation(
266ImageDirection normalDir, double xBottomLeft, double yBottomLeft,
267double zBottomLeft )
268{
269 if(normalDir==zDirection)
270 {
271 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft-0.5; point1[2] = zBottomLeft;
272 point2[0] = xBottomLeft+myDomainWidth-0.5; point2[1] = yBottomLeft-0.5; point2[2] = zBottomLeft;
273 point3[0] = xBottomLeft+myDomainWidth-0.5; point3[1] = yBottomLeft+myDomainHeight-0.5; point3[2] = zBottomLeft;
274 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft+myDomainHeight-0.5; point4[2] = zBottomLeft;
275 }else if(normalDir==yDirection)
276 {
277 point1[0] = xBottomLeft-0.5; point1[1] = yBottomLeft; point1[2] = zBottomLeft-0.5;
278 point2[0] = xBottomLeft+myDomainWidth-0.5; point2[1] = yBottomLeft; point2[2] = zBottomLeft-0.5;
279 point3[0] = xBottomLeft+myDomainWidth-0.5; point3[1] = yBottomLeft; point3[2] = zBottomLeft+myDomainHeight-0.5;
280 point4[0] = xBottomLeft-0.5; point4[1] = yBottomLeft; point4[2] = zBottomLeft+myDomainHeight-0.5;
281 }else if(normalDir==xDirection)
282 {
283 point1[0] = xBottomLeft; point1[1] = yBottomLeft-0.5; point1[2]= zBottomLeft-0.5;
284 point2[0] = xBottomLeft; point2[1] = yBottomLeft+myDomainWidth-0.5; point2[2] = zBottomLeft-0.5;
285 point3[0] = xBottomLeft; point3[1] = yBottomLeft+myDomainWidth-0.5; point3[2] = zBottomLeft+myDomainHeight-0.5;
286 point4[0] = xBottomLeft; point4[1] = yBottomLeft-0.5; point4[2] = zBottomLeft+myDomainHeight-0.5;
287 }
288 myDirection=normalDir;
289}
290
291template <typename TSpace, typename TKSpace>
292inline void DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D::translateDomain(
293double xTranslation, double yTranslation, double zTranslation )
294{
295 point1[0] += xTranslation; point1[1] += yTranslation; point1[2] += zTranslation;
296 point2[0] += xTranslation; point2[1] += yTranslation; point2[2] += zTranslation;
297 point3[0] += xTranslation; point3[1] += yTranslation; point3[2] += zTranslation;
298 point4[0] += xTranslation; point4[1] += yTranslation; point4[2] += zTranslation;
299}
300
301template <typename TSpace, typename TKSpace>
302template <typename TDomain>
303void DGtal::Viewer3D<TSpace, TKSpace>::addImage2DDomainD3D(
304const TDomain & aDomain, std::string mode, const DGtal::Color & aColor )
305{
306 typename DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D anImageDomain(
307 aDomain );
308 anImageDomain.color = aColor;
309 anImageDomain.myMode = mode;
310 anImageDomain.myLineSetIndex =
311 Viewer3D<TSpace, TKSpace>::myLineSetList.size();
312
313 myImageDomainList.push_back(anImageDomain);
314 Display3D<TSpace, TKSpace>::updateBoundingBox( anImageDomain.point1 );
315 Display3D<TSpace, TKSpace>::updateBoundingBox( anImageDomain.point2 );
316 Display3D<TSpace, TKSpace>::updateBoundingBox( anImageDomain.point3 );
317 Display3D<TSpace, TKSpace>::updateBoundingBox( anImageDomain.point4 );
318
319 std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D> vectLines =
320 compute2DDomainLineRepresentation( anImageDomain );
321 Viewer3D<TSpace, TKSpace>::myLineSetList.push_back( vectLines );
322}
323
324template <typename TSpace, typename TKSpace>
325inline std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D>
326DGtal::Viewer3D<TSpace, TKSpace>::compute2DDomainLineRepresentation(
327typename DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D & anImageDomain )
328{
329 std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D>
330 vectLinesResu = compute2DDomainLineRepresentation( anImageDomain, 0.05 );
331 std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D>
332 vectLinesVerso = compute2DDomainLineRepresentation( anImageDomain, -0.05 );
333 for(unsigned int i=0; i<vectLinesVerso.size(); i++)
334 {
335 vectLinesResu.push_back(vectLinesVerso.at(i));
336 }
337 return vectLinesResu;
338}
339
340template <typename TSpace, typename TKSpace>
341inline std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D>
342DGtal::Viewer3D<TSpace, TKSpace>::compute2DDomainLineRepresentation(
343typename DGtal::Viewer3D<TSpace, TKSpace>::Image2DDomainD3D & anImageDomain,
344double delta )
345{
346 std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D> aLineSet;
347 typename Viewer3D<TSpace, TKSpace>::LineD3D aLine;
348 aLine.color = anImageDomain.color;
349 aLine.width=0.1;
350
351 if( anImageDomain.myMode=="BoundingBox")
352 {
353 aLine.point1[0]=anImageDomain.point1[0]; aLine.point1[1]=anImageDomain.point1[1]; aLine.point1[2]=anImageDomain.point1[2];
354 aLine.point2[0]=anImageDomain.point2[0]; aLine.point2[1]=anImageDomain.point2[1]; aLine.point2[2]=anImageDomain.point2[2];
355 aLineSet.push_back(aLine);
356 aLine.point1[0]=anImageDomain.point2[0]; aLine.point1[1]=anImageDomain.point2[1]; aLine.point1[2]=anImageDomain.point2[2];
357 aLine.point2[0]=anImageDomain.point3[0]; aLine.point2[1]=anImageDomain.point3[1]; aLine.point2[2]=anImageDomain.point3[2];
358 aLineSet.push_back(aLine);
359 aLine.point1[0]=anImageDomain.point3[0]; aLine.point1[1]=anImageDomain.point3[1]; aLine.point1[2]=anImageDomain.point3[2];
360 aLine.point2[0]=anImageDomain.point4[0]; aLine.point2[1]=anImageDomain.point4[1]; aLine.point2[2]=anImageDomain.point4[2];
361 aLineSet.push_back(aLine);
362 aLine.point1[0]=anImageDomain.point4[0]; aLine.point1[1]=anImageDomain.point4[1]; aLine.point1[2]=anImageDomain.point4[2];
363 aLine.point2[0]=anImageDomain.point1[0]; aLine.point2[1]=anImageDomain.point1[1]; aLine.point2[2]=anImageDomain.point1[2];
364 aLineSet.push_back(aLine);
365 }else if(anImageDomain.myMode=="InterGrid")
366 {
367 if(anImageDomain.myDirection==zDirection)
368 {
369 //lines align to the x direction
370 for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
371 {
372 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+i; aLine.point1[2] = anImageDomain.point1[2]+delta;
373 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point2[1]+i; aLine.point2[2] = anImageDomain.point2[2]+delta;
374 aLineSet.push_back(aLine);
375 }
376 //lines align to the y direction
377 for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
378 {
379 aLine.point1[0] = anImageDomain.point1[0]+i; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+delta;
380 aLine.point2[0] = anImageDomain.point4[0]+i; aLine.point2[1] = anImageDomain.point4[1]; aLine.point2[2] = anImageDomain.point4[2]+delta;
381 aLineSet.push_back(aLine);
382 }
383 }else if(anImageDomain.myDirection==xDirection)
384 {
385 //lines align to the y direction
386 for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
387 {
388 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+i;
389 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point2[1]; aLine.point2[2] = anImageDomain.point1[2]+i;
390 aLineSet.push_back(aLine);
391 }
392
393 //lines align to the z direction
394 for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
395 {
396 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]+i; aLine.point1[2] = anImageDomain.point1[2];
397 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point1[1]+i; aLine.point2[2] = anImageDomain.point4[2];
398 aLineSet.push_back(aLine);
399 }
400 }else if(anImageDomain.myDirection==yDirection)
401 {
402 //lines align to the x direction
403 for(unsigned int i=0; i <= anImageDomain.myDomainHeight; i++)
404 {
405 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2]+i;
406 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point1[2]+i;
407 aLineSet.push_back(aLine);
408 }
409
410 //lines align to the z direction
411 for(unsigned int i=0; i <= anImageDomain.myDomainWidth; i++)
412 {
413 aLine.point1[0] = anImageDomain.point1[0]+i; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2];
414 aLine.point2[0] = anImageDomain.point1[0]+i; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point4[2];
415 aLineSet.push_back(aLine);
416 }
417 }
418 }else if(anImageDomain.myMode=="Grid")
419 {
420 if(anImageDomain.myDirection==zDirection)
421 {
422 //lines align to the x direction
423 for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
424 {
425 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+i+0.5; aLine.point1[2] = anImageDomain.point1[2]+delta;
426 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point2[1]+i+0.5; aLine.point2[2] = anImageDomain.point2[2]+delta;
427 aLineSet.push_back(aLine);
428 }
429 //lines align to the y direction
430 for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
431 {
432 aLine.point1[0] = anImageDomain.point1[0]+i+0.5; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+delta;
433 aLine.point2[0] = anImageDomain.point4[0]+i+0.5; aLine.point2[1] = anImageDomain.point4[1]; aLine.point2[2] = anImageDomain.point4[2]+delta;
434 aLineSet.push_back(aLine);
435 }
436 }else if(anImageDomain.myDirection==xDirection)
437 {
438 //lines align to the y direction
439 for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
440 {
441 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]; aLine.point1[2] = anImageDomain.point1[2]+i+0.5;
442 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point2[1]; aLine.point2[2] = anImageDomain.point1[2]+i+0.5;
443 aLineSet.push_back(aLine);
444 }
445
446 //lines align to the z direction
447 for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
448 {
449 aLine.point1[0] = anImageDomain.point1[0]+delta; aLine.point1[1] = anImageDomain.point1[1]+i+0.5; aLine.point1[2] = anImageDomain.point1[2];
450 aLine.point2[0] = anImageDomain.point1[0]+delta; aLine.point2[1] = anImageDomain.point1[1]+i+0.5; aLine.point2[2] = anImageDomain.point4[2];
451 aLineSet.push_back(aLine);
452 }
453 }else if(anImageDomain.myDirection==yDirection)
454 {
455 //lines align to the x direction
456 for(unsigned int i=0; i < anImageDomain.myDomainHeight; i++)
457 {
458 aLine.point1[0] = anImageDomain.point1[0]; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2]+i+0.5;
459 aLine.point2[0] = anImageDomain.point2[0]; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point1[2]+i+0.5;
460 aLineSet.push_back(aLine);
461 }
462
463 //lines align to the z direction
464 for(unsigned int i=0; i < anImageDomain.myDomainWidth; i++)
465 {
466 aLine.point1[0] = anImageDomain.point1[0]+i+0.5; aLine.point1[1] = anImageDomain.point1[1]+delta; aLine.point1[2] = anImageDomain.point1[2];
467 aLine.point2[0] = anImageDomain.point1[0]+i+0.5; aLine.point2[1] = anImageDomain.point1[1]+delta; aLine.point2[2] = anImageDomain.point4[2];
468 aLineSet.push_back(aLine);
469 }
470 }
471 }
472 return aLineSet;
473}
474
475template <typename TSpace, typename TKSpace>
476inline void DGtal::Viewer3D<TSpace, TKSpace>::updateAn2DDomainOrientation(
477unsigned int domainIndex, double xPosition, double yPosition, double zPosition,
478ImageDirection newDirection )
479{
480 ASSERT( domainIndex < myImageDomainList.size());
481 typename Viewer3D<TSpace, TKSpace>::Image2DDomainD3D & aDomain =
482 myImageDomainList.at( domainIndex );
483
484 Display3D<TSpace, TKSpace>::updateBoundingBox( aDomain.point1 );
485 Display3D<TSpace, TKSpace>::updateBoundingBox( aDomain.point2 );
486 Display3D<TSpace, TKSpace>::updateBoundingBox( aDomain.point3 );
487 Display3D<TSpace, TKSpace>::updateBoundingBox( aDomain.point4 );
488 aDomain.updateDomainOrientation(newDirection, xPosition, yPosition, zPosition);
489
490 std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D> vectNewLines =
491 compute2DDomainLineRepresentation( aDomain );
492 std::vector<typename DGtal::Viewer3D<TSpace, TKSpace>::LineD3D> & vectLines =
493 Viewer3D<TSpace, TKSpace>::myLineSetList.at( aDomain.myLineSetIndex );
494 vectLines.clear();
495 for(unsigned int i=0; i<vectNewLines.size(); i++)
496 {
497 vectLines.push_back(vectNewLines.at(i));
498 }
499
500}
501
502template <typename TSpace, typename TKSpace>
503inline void DGtal::Viewer3D<TSpace, TKSpace>::translateAn2DDomain(
504unsigned int domainIndex, double xTranslation, double yTranslation,
505double zTranslation )
506{
507 typename Viewer3D<TSpace, TKSpace>::Image2DDomainD3D & anDomain =
508 myImageDomainList.at( domainIndex );
509 anDomain.translateDomain(xTranslation, yTranslation, zTranslation);
510
511 Display3D<TSpace, TKSpace>::updateBoundingBox( anDomain.point1 );
512 Display3D<TSpace, TKSpace>::updateBoundingBox( anDomain.point2 );
513 Display3D<TSpace, TKSpace>::updateBoundingBox( anDomain.point3 );
514 Display3D<TSpace, TKSpace>::updateBoundingBox( anDomain.point4 );
515
516 std::vector<typename DGtal::Display3D<TSpace, TKSpace>::LineD3D> & vectLines =
517 Viewer3D<TSpace, TKSpace>::myLineSetList.at( anDomain.myLineSetIndex );
518 for(unsigned int i=0; i<vectLines.size(); i++){
519 typename DGtal::Display3D<TSpace, TKSpace>::LineD3D & aLine =
520 vectLines.at( i );
521 aLine.point1[0]=aLine.point1[0]+xTranslation; aLine.point1[1]=aLine.point1[1]+yTranslation; aLine.point1[2]=aLine.point1[2]+zTranslation;
522 aLine.point2[0]=aLine.point2[0]+xTranslation; aLine.point2[1]=aLine.point2[1]+yTranslation; aLine.point2[2]=aLine.point2[2]+zTranslation;
523 }
524}
525
526template <typename TSpace, typename TKSpace>
527inline std::string
528DGtal::Viewer3D<TSpace, TKSpace>::TextureImage::className() const
529{
530 return "TextureImage";
531}
532
533template <typename TSpace, typename TKSpace>
534inline DGtal::Viewer3D<TSpace, TKSpace> & DGtal::Viewer3D<TSpace, TKSpace>::
535operator<<( const DGtal::Color & aColor )
536{
537 myDefaultColor=aColor;
538 return *this;
539}
540
541template <typename TSpace, typename TKSpace>
542inline DGtal::Viewer3D<TSpace, TKSpace> & DGtal::Viewer3D<TSpace, TKSpace>::
543operator<<( const typename Viewer3D<TSpace, TKSpace>::StreamKey & key )
544{
545 switch (key)
546 {
547 case Viewer3D<TSpace, TKSpace>::updateDisplay:
548 Viewer3D<TSpace, TKSpace>::updateList();
549 break;
550
551 case Viewer3D<TSpace, TKSpace>::addNewList:
552 Viewer3D<TSpace, TKSpace>::createNewCubeList();
553 break;
554
555 case Viewer3D<TSpace, TKSpace>::shiftSurfelVisu:
556 Viewer3D<TSpace, TKSpace>::myCurrentfShiftVisuPrisms += 0.3;
557 break;
558 }
559 return *this;
560}
561
562template <typename TSpace, typename TKSpace>
563template <typename TDrawableWithViewer3D>
564inline DGtal::Viewer3D<TSpace, TKSpace> & DGtal::Viewer3D<TSpace, TKSpace>::
565operator<<( const TDrawableWithViewer3D & object )
566{
567 BOOST_CONCEPT_ASSERT((concepts::CDrawableWithViewer3D< TDrawableWithViewer3D, Space, KSpace >));
568
569 DGtal::Viewer3DFactory<TSpace, TKSpace>::draw( *this, object );
570 return *this;
571}
572
573
574///////////////////////////////////////////////////////////////////////////////
575// Implementation of inline functions and external operators //
576
577template <typename TSpace, typename TKSpace>
578inline std::ostream & DGtal::
579operator<<( std::ostream & out, const Viewer3D<TSpace, TKSpace> & object )
580{
581 object.selfDisplay ( out );
582 return out;
583}
584
585// //
586///////////////////////////////////////////////////////////////////////////////
587
588
589///////////////////////////////////////////////////////////////////////////////
590
591// heritage of parents templates methods //
592
593
594// end of heritage //
595///////////////////////////////////////////////////////////////////////////////
596
597///////////////////////////////////////////////////////////////////////////////
598
599// surcharge of parents methods //
600
601
602// end of surcharge //
603///////////////////////////////////////////////////////////////////////////////
604
605template <typename TSpace, typename TKSpace>
606inline void DGtal::Viewer3D<TSpace, TKSpace>::drawWithNames()
607{
608 // JOL: 2014/10/15. This method is called only when the user tries
609 // to select some graphic object through QGLViewer. By default,
610 // selection is left clic + shift key.
611 // JOL: 2014/10/15. This is my addition for interacting with
612 // quads. Seems to work well.
613 if ( myExtension != 0 )
614 myExtension->drawWithNames( *this );
615
616 glCallList ( myQuadsMapId );
617
618 glCallList ( myCubesMapId );
619
620 for ( unsigned int i = 0; i < Viewer3D<TSpace, TKSpace>::myLineSetList.size();
621 i++ )
622 {
623 glCallList( myLineSetListId + i );
624 }
625
626 for ( unsigned int i = 0;
627 i < Viewer3D<TSpace, TKSpace>::myBallSetList.size(); i++ )
628 {
629 glCallList(myBallSetListId+i);
630 }
631
632}
633
634template <typename TSpace, typename TKSpace>
635inline void DGtal::Viewer3D<TSpace, TKSpace>::draw()
636{
637
638 glUpdateBackground();
639
640 if ( myExtension != 0 )
641 myExtension->draw( *this );
642
643 glPushMatrix();
644 glMultMatrixd ( manipulatedFrame()->matrix() );
645 glPushMatrix();
646 glScalef(myGLScaleFactorX, myGLScaleFactorY, myGLScaleFactorZ);
647
648 glLightfv(GL_LIGHT0, GL_SPECULAR, myLightSpecularCoeffs);
649 glLightfv(GL_LIGHT0, GL_DIFFUSE, myLightDiffuseCoeffs);
650 glLightfv(GL_LIGHT0, GL_AMBIENT, myLightAmbientCoeffs);
651 if( myLightPositionFixToCamera ){
652 updateLightCoordsFromCamera();
653 }else{
654 updateRelativeCameraFromLightPosition();
655 }
656 glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
657
658 unsigned int i = 0;
659 typename std::vector<
660 typename Viewer3D<TSpace, TKSpace>::ClippingPlaneD3D>::const_iterator it =
661 Viewer3D<TSpace, TKSpace>::myClippingPlaneList.begin();
662
663 // OpenGL can't draw more than GL_MAX_CLIP_PLANES clipping plane
664 while ( i < GL_MAX_CLIP_PLANES &&
665 it != Viewer3D<TSpace, TKSpace>::myClippingPlaneList.end() )
666 {
667 double eq[ 4 ];
668 eq[ 0 ] = it->a;
669 eq[ 1 ] = it->b;
670 eq[ 2 ] = it->c;
671 eq[ 3 ] = it->d;
672 glEnable( GL_CLIP_PLANE0 + i );
673 glClipPlane( GL_CLIP_PLANE0 + i, eq );
674 i++;
675 it++;
676 }
677 if (i == GL_MAX_CLIP_PLANES)
678 {
679 std::cerr <<"Warning maximal clipping plane added" << std::endl;
680 }
681
682 Vec centerS = sceneCenter();
683 Vec posCam = camera()->position();
684 double distCam =sqrt ( ( posCam.x-centerS.x ) * ( posCam.x-centerS.x ) +
685 ( posCam.y-centerS.y ) * ( posCam.y-centerS.y ) +
686 ( posCam.z-centerS.z ) * ( posCam.z-centerS.z ) );
687 for(unsigned int j=0; j< myVectTextureImage.size(); j++)
688 {
689 GLTextureImage &textureImg = myVectTextureImage.at(j);
690 glPushName ( textureImg.myTextureName );
691 glEnable(GL_TEXTURE_2D);
692 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
693 glBindTexture(GL_TEXTURE_2D, textureImg.myTextureName);
694 glBegin(GL_QUADS);
695 glColor4ub ( 255.0, 255.0, 255.0, 255.0 );
696 glNormal3d(textureImg.vectNormal[0], textureImg.vectNormal[1], textureImg.vectNormal[2]);
697
698 glTexCoord2f(0, 0);
699 glVertex3f(textureImg.point1[0], textureImg.point1[1], textureImg.point1[2]);
700 glTexCoord2f(textureImg.myTextureFitX, 0.0);
701 glVertex3f(textureImg.point2[0], textureImg.point2[1], textureImg.point2[2]);
702 glTexCoord2f(textureImg.myTextureFitX, textureImg.myTextureFitY);
703 glVertex3f(textureImg.point3[0], textureImg.point3[1], textureImg.point3[2]);
704 glTexCoord2f(0.0, textureImg.myTextureFitY);
705 glVertex3f(textureImg.point4[0], textureImg.point4[1], textureImg.point4[2]);
706 glEnd();
707 glDisable(GL_TEXTURE_2D);
708
709 }
710
711 for ( unsigned int j = 0;
712 j < Viewer3D<TSpace, TKSpace>::myLineSetList.size(); j++ )
713 {
714 if ( Viewer3D<TSpace, TKSpace>::myLineSetList.at( j ).size() != 0 )
715 {
716 glLineWidth(
717 std::max( myGLLineMinWidth,
718 Viewer3D<TSpace, TKSpace>::myLineSetList.at( j ).at( 0 ).width ) );
719 }
720 glCallList(myLineSetListId+j);
721 }
722
723 glCallList(myPrismListId);
724
725 glCallList( myCubesMapId );
726
727 for ( unsigned int j = 0; j < Viewer3D<TSpace, TKSpace>::myBallSetList.size();
728 j++ )
729 {
730 if ( myUseGLPointsForBalls )
731 {
732 if ( Viewer3D<TSpace, TKSpace>::myBallSetList.at( j ).size() != 0 )
733 {
734 glPointSize( std::max(
735 myGLPointMinWidth,
736 ( Viewer3D<TSpace, TKSpace>::myBallSetList.at( j ).at( 0 ).radius ) ) );
737 }
738 }
739 else
740 glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
741
742 glCallList( myBallSetListId + j );
743 glUpdateLightRenderingMode();
744 }
745
746 glDisable(GL_CULL_FACE);
747 glCallList(myQuadsMapId);
748 if(myViewWire)
749 {
750 glLineWidth(
751 std::max( myGLLineMinWidth,
752 Viewer3D<TSpace, TKSpace>::myMeshDefaultLineWidth / distCam ) );
753 glCallList(myQuadsMapWiredId);
754 }
755
756 glDisable(GL_CULL_FACE);
757 glCallList(myTriangleSetListId);
758 if(myViewWire)
759 {
760 glLineWidth(
761 std::max( myGLLineMinWidth,
762 Viewer3D<TSpace, TKSpace>::myMeshDefaultLineWidth / distCam ) );
763 glCallList(myTriangleSetListWiredId);
764 }
765
766 glDisable(GL_CULL_FACE);
767 glCallList(myPolygonSetListId);
768 if(myViewWire)
769 {
770 glLineWidth(
771 std::max( myGLLineMinWidth,
772 Viewer3D<TSpace, TKSpace>::myMeshDefaultLineWidth / distCam ) );
773 glCallList(myPolygonSetListWiredId);
774 }
775
776 if(myIsMovingLight){
777 drawLight(GL_LIGHT0);
778 }
779
780 glPopMatrix();
781 glPopMatrix();
782}
783
784template <typename TSpace, typename TKSpace>
785void DGtal::Viewer3D<TSpace, TKSpace>::selfDisplay( std::ostream & out ) const
786{
787 out << "[Viewer3D]";
788}
789
790template <typename TSpace, typename TKSpace>
791bool DGtal::Viewer3D<TSpace, TKSpace>::isValid() const
792{
793 return true;
794}
795
796template <typename TSpace, typename TKSpace>
797void DGtal::Viewer3D<TSpace, TKSpace>::init()
798{
799 if ( myExtension != 0 )
800 myExtension->init( *this );
801 myAutoSaveState = false;
802 myIsMovingLight = false;
803 myLigthRotationStep = 0.01;
804 myRefMouseXPos = 0;
805 myRefMouseYPos = 0;
806
807 myLightPositionRefCamera[0] = myLightPositionRefCameraDefault[0];
808 myLightPositionRefCamera[1] = myLightPositionRefCameraDefault[1];
809 myLightPositionRefCamera[2] = myLightPositionRefCameraDefault[2];
810 updateLightCoordsFromCamera();
811
812 glClearColor (0.0, 0.0, 0.0, 0.0);
813 glShadeModel (GL_SMOOTH);
814
815 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, myMaterialShininessCoeff);
816 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, myMaterialSpecularCoeffs);
817
818
819 glLightfv(GL_LIGHT0, GL_SPECULAR, myLightSpecularCoeffs);
820 glLightfv(GL_LIGHT0, GL_DIFFUSE, myLightDiffuseCoeffs);
821 glLightfv(GL_LIGHT0, GL_AMBIENT, myLightAmbientCoeffs);
822
823 glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
824
825 glEnable(GL_LIGHTING);
826 glEnable(GL_LIGHT0);
827 glEnable(GL_DEPTH_TEST);
828
829 Viewer3D<TSpace, TKSpace>::myMeshDefaultLineWidth = 10.0;
830 myNbListe=0;
831 myViewWire=false;
832 setBackgroundColor ( QColor ( 217, 228, 255, 255 ) );
833 setForegroundColor ( QColor ( 217, 22, 25, 255 ) );
834
835 Viewer3D<TSpace, TKSpace>::createNewCubeList();
836 std::vector<typename Viewer3D<TSpace, TKSpace>::LineD3D> listeLine;
837 Viewer3D<TSpace, TKSpace>::myLineSetList.push_back( listeLine );
838 std::vector<typename Viewer3D<TSpace, TKSpace>::BallD3D> listeBall;
839 Viewer3D<TSpace, TKSpace>::myBallSetList.push_back( listeBall );
840 Viewer3D<TSpace, TKSpace>::myCurrentFillColor = Color( 220, 220, 220 );
841 Viewer3D<TSpace, TKSpace>::myCurrentLineColor = Color( 22, 22, 222, 50 );
842 myDefaultBackgroundColor = Color ( backgroundColor().red(), backgroundColor().green(),
843 backgroundColor().blue() );
844 myIsBackgroundDefault=true;
845 Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 0 ] =
846 -10.0; // numeric_limits<double>::max( );
847 Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 1 ] =
848 -10.0; // numeric_limits<double>::max( );
849 Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 2 ] =
850 -10.0; // numeric_limits<double>::max( );
851
852 Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 0 ] =
853 -10.0; // numeric_limits<double>::min( );
854 Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 1 ] =
855 -10.0; // numeric_limits<double>::min( );
856 Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 2 ] =
857 -10.0; // numeric_limits<double>::min( );
858 Viewer3D<TSpace, TKSpace>::createNewCubeList();
859 typename std::vector<typename Viewer3D<TSpace, TKSpace>::CubeD3D> aKSCubeList;
860
861 Viewer3D<TSpace, TKSpace>::myCurrentfShiftVisuPrisms = 0.0;
862 Viewer3D<TSpace, TKSpace>::myDefaultColor = Color( 255, 255, 255 );
863 camera()->showEntireScene();
864 setKeyDescription ( Qt::Key_E, "Export the current display into OFF file (just Cube, surfel and SurfelPrism for now)." );
865 setKeyDescription ( Qt::Key_W, "Switch display with and without wired view of triangle and quad faces." );
866 setKeyDescription ( Qt::Key_T, "Sort elements for display improvements." );
867 setKeyDescription ( Qt::Key_L, "Load last visualisation settings (from a .qglviewer.xml file generated by using SHIFT+L)");
868 setKeyDescription ( Qt::ShiftModifier+Qt::Key_L, "Save visualisation settings." );
869 setKeyDescription ( Qt::Key_B, "Switch background color with White/Black colors." );
870 setKeyDescription ( Qt::Key_C, "Show camera informations." );
871 setKeyDescription ( Qt::Key_R, "Reset default scale for 3 axes to 1.0f." );
872 setKeyDescription ( Qt::Key_D, "Enable/Disable the two side face rendering." );
873 setKeyDescription ( Qt::Key_O, "Switch the ball display mode (quad ball display (default) or OpenGL point)." );
874 setKeyDescription ( Qt::Key_M, "Switch the rendering mode bewteen Default, Metallic and Plastic mode." );
875 setKeyDescription ( Qt::Key_P, "Switch the light source position mode between the camera mode (default: the light source position is fixed according to the camera position) and scene mode (the light source position is fixed according the scene coordinate system)." );
876 setKeyDescription( Qt::Key_Z,
877 "Move away the light source according to the scence "
878 "center (move closer with SHIFT+Z)" );
879 setKeyDescription( Qt::ShiftModifier + Qt::Key_Z,
880 "Move closer the light source according to the scence "
881 "center (move awya with key Z)" );
882
883#if !defined (QGLVIEWER_VERSION) || QGLVIEWER_VERSION < 0x020500
884 setMouseBindingDescription((Qt::ControlModifier|Qt::ShiftModifier) + Qt::LeftButton, "move light source position defined in the main coordinate system (an x-axis (resp. y-axis) mouse move changes the azimuth (resp. inclination) angle of the light source). Note that light source is always looking at the center point (0,0,0).");
885#else
886 setMouseBindingDescription(Qt::KeyboardModifiers( Qt::ControlModifier|Qt::ShiftModifier ), Qt::LeftButton, "move light source position defined in the main coordinate system (an x-axis (resp. y-axis) mouse move changes the azimuth (resp. inclination) angle of the light source). Note that light source is always looking at the center point (0,0,0).");
887#endif
888
889
890 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
891
892#if !defined (QGLVIEWER_VERSION) || QGLVIEWER_VERSION < 0x020500
893 setMouseBindingDescription ( Qt::ShiftModifier+Qt::RightButton, "Delete the mouse selected list." );
894#else
895 setMouseBindingDescription ( Qt::ShiftModifier, Qt::RightButton, "Delete the mouse selected list." );
896#endif
897
898 setManipulatedFrame ( new ManipulatedFrame() );
899}
900
901template <typename TSpace, typename TKSpace>
902void DGtal::Viewer3D<TSpace, TKSpace>::sortSurfelFromCamera()
903{
904 CompFarthestVoxelFromCamera comp;
905 comp.posCam= camera()->position();
906
907 for ( auto & mapElem : Viewer3D<TSpace, TKSpace>::myCubesMap )
908
909 {
910 DGtal::trace.info() << "sort quad size" << mapElem.second.size()
911 << std::endl;
912 sort( mapElem.second.begin(), mapElem.second.end(), comp );
913 }
914 CompFarthestSurfelFromCamera compSurf;
915 DGtal::trace.info() << "sort surfel size"
916 << Viewer3D<TSpace, TKSpace>::myPrismList.size()
917 << std::endl;
918 sort( Viewer3D<TSpace, TKSpace>::myPrismList.begin(),
919 Viewer3D<TSpace, TKSpace>::myPrismList.end(), compSurf );
920}
921
922template <typename TSpace, typename TKSpace>
923void DGtal::Viewer3D<TSpace, TKSpace>::sortTriangleFromCamera()
924{
925 CompFarthestTriangleFromCamera comp;
926 comp.posCam= camera()->position();
927 for ( auto & listElem : Viewer3D<TSpace, TKSpace>::myTriangleSetList )
928 {
929 sort( listElem.begin(), listElem.end(), comp );
930 }
931}
932
933template <typename TSpace, typename TKSpace>
934void DGtal::Viewer3D<TSpace, TKSpace>::sortQuadFromCamera()
935{
936 CompFarthestSurfelFromCamera comp;
937 comp.posCam= camera()->position();
938
939 for ( auto & listElem : Viewer3D<TSpace, TKSpace>::myQuadsMap )
940 {
941 DGtal::trace.info() << "sort quad size" << listElem.second.size()
942 << std::endl;
943 sort( listElem.second.begin(), listElem.second.end(), comp );
944 }
945}
946
947template <typename TSpace, typename TKSpace>
948void DGtal::Viewer3D<TSpace, TKSpace>::sortPolygonFromCamera()
949{
950 CompFarthestPolygonFromCamera comp;
951 comp.posCam= camera()->position();
952
953 for ( auto & listElem : Viewer3D<TSpace, TKSpace>::myPolygonSetList )
954 {
955 DGtal::trace.info() << "sort polygon size" << listElem.size() << std::endl;
956 sort( listElem.begin(), listElem.end(), comp );
957 }
958
959}
960
961template <typename TSpace, typename TKSpace>
962void DGtal::Viewer3D<TSpace, TKSpace>::postSelection( const QPoint & point )
963{
964 bool handled = false;
965 if ( myExtension != 0 )
966 handled = myExtension->postSelection( *this, point );
967 if ( handled )
968 return;
969
970 camera()->convertClickToLine ( point, myOrig, myDir );
971 bool found;
972 this->myPosSelector= point;
973 mySelectedPoint = camera()->pointUnderPixel ( point, found );
974 if ( found )
975 {
976 DGtal::trace.info() << "Element of liste= " << selectedName() << "selected" << std::endl;
977 // JOL: 2014/10/15
978 mySelectedElementId = selectedName();
979 void* aData = 0;
980 SelectCallbackFct fct = getSelectCallback3D( selectedName(), aData );
981 if ( fct ) fct( this, selectedName(), aData );
982 // I leave the remaining code.
983 updateList(false);
984 }else if (mySelectedElementId != -1)
985 {
986 mySelectedElementId = -1;
987 updateList(false);
988 }
989}
990
991template <typename TSpace, typename TKSpace>
992void DGtal::Viewer3D<TSpace, TKSpace>::updateList(
993bool needToUpdateBoundingBox )
994{
995
996 // glDeleteLists
997 glDeleteLists(myCubesMapId, 1);
998 glDeleteLists(myLineSetListId, myNbLineSetList);
999 glDeleteLists(myBallSetListId, myNbBallSetList);
1000 glDeleteLists(myTriangleSetListId, 1);
1001 glDeleteLists(myTriangleSetListWiredId, 1);
1002 glDeleteLists(myPrismListId, 1);
1003 glDeleteLists(myPolygonSetListId, 1);
1004 glDeleteLists(myPolygonSetListWiredId, 1);
1005 glDeleteLists(myQuadsMapId, 1);
1006 glDeleteLists(myQuadsMapWiredId, 1);
1007
1008 // Storing ID for each list
1009 myCubesMapId = glGenLists(1);
1010 myLineSetListId =
1011 glGenLists( static_cast<GLsizei>(Viewer3D<TSpace, TKSpace>::myLineSetList.size() ));
1012 myNbLineSetList = static_cast<unsigned int>(Viewer3D<TSpace, TKSpace>::myLineSetList.size());
1013 myBallSetListId =
1014 glGenLists( static_cast<GLsizei>(Viewer3D<TSpace, TKSpace>::myBallSetList.size() ) );
1015 myNbBallSetList = static_cast<unsigned int>(Viewer3D<TSpace, TKSpace>::myBallSetList.size());
1016 myTriangleSetListId = glGenLists(1);
1017 myTriangleSetListWiredId = glGenLists(1);
1018 myCubeSetListWiredId = glGenLists(1);
1019 myPolygonSetListId = glGenLists(1);
1020 myPolygonSetListWiredId = glGenLists(1);
1021 myQuadsMapId = glGenLists(1);
1022 myQuadsMapWiredId = glGenLists(1);
1023 myPrismListId = glGenLists(1);
1024
1025
1026 myNbListe=0;
1027
1028 glEnable ( GL_BLEND );
1029 glEnable ( GL_MULTISAMPLE_ARB );
1030 glEnable ( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
1031 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1032
1033 glCreateListCubesMaps( Viewer3D<TSpace, TKSpace>::myCubesMap, myCubesMapId );
1034
1035 glCreateListQuadD3D( Viewer3D<TSpace, TKSpace>::myPrismList, myPrismListId );
1036 myNbListe++;
1037
1038 for ( unsigned int j = 0; j < Viewer3D<TSpace, TKSpace>::myLineSetList.size();
1039 j++ )
1040 {
1041 glCreateListLines( Viewer3D<TSpace, TKSpace>::myLineSetList.at( j ),
1042 myLineSetListId + j );
1043 myNbListe++;
1044 }
1045
1046 for ( unsigned int j = 0;
1047 j < Viewer3D<TSpace, TKSpace>::myBallSetList.size(); j++ )
1048 {
1049 glCreateListBalls( Viewer3D<TSpace, TKSpace>::myBallSetList.at( j ),
1050 myBallSetListId + j );
1051 myNbListe++;
1052 }
1053
1054
1055 // First list: quad faces.
1056 glCreateListQuadMaps( Viewer3D<TSpace, TKSpace>::myQuadsMap, myQuadsMapId );
1057 myNbListe++;
1058
1059 // Second list: Wired version of quad face.
1060 glCreateListQuadMapsWired( Viewer3D<TSpace, TKSpace>::myQuadsMap,
1061 myQuadsMapWiredId );
1062 myNbListe++;
1063
1064 // Third list: Triangle faces.
1065 glCreateListTriangles( Viewer3D<TSpace, TKSpace>::myTriangleSetList,
1066 myTriangleSetListId );
1067 myNbListe++;
1068
1069 // Fourth list: Wired version of triangle face.
1070 glCreateListTrianglesWired( Viewer3D<TSpace, TKSpace>::myTriangleSetList,
1071 myTriangleSetListWiredId );
1072 myNbListe++;
1073
1074 // Fifth list: Polygonal faces.
1075 glCreateListPolygons( Viewer3D<TSpace, TKSpace>::myPolygonSetList,
1076 myPolygonSetListId );
1077 myNbListe++;
1078
1079 // Sixth list: Wired version of polygonal face.
1080 glCreateListPolygonsWired( Viewer3D<TSpace, TKSpace>::myPolygonSetList,
1081 myPolygonSetListWiredId );
1082 myNbListe++;
1083
1084 // Seventh list: Textured images.
1085 glUpdateTextureImages( myGSImageList );
1086
1087 if ( needToUpdateBoundingBox &&
1088 Viewer3D<TSpace, TKSpace>::myBoundingPtChangedTag )
1089 {
1090 setSceneBoundingBox(
1091 qglviewer::Vec( Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 0 ],
1092 Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 1 ],
1093 Viewer3D<TSpace, TKSpace>::myBoundingPtLow[ 2 ] ),
1094 qglviewer::Vec( Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 0 ],
1095 Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 1 ],
1096 Viewer3D<TSpace, TKSpace>::myBoundingPtUp[ 2 ] ) );
1097 showEntireScene();
1098 Viewer3D<TSpace, TKSpace>::myBoundingPtChangedTag = false;
1099 }
1100 update();
1101 glPopMatrix();
1102}
1103
1104template <typename TSpace, typename TKSpace>
1105void DGtal::Viewer3D<TSpace, TKSpace>::glDrawGLBall(
1106const typename Viewer3D<TSpace, TKSpace>::BallD3D & aBall )
1107{
1108 double thetaResolution = aBall.resolution;
1109 double thetaStep= (2.0*M_PI)/thetaResolution;
1110 double phiResolution = aBall.resolution;
1111 double phiStep= M_PI/phiResolution;
1112
1113 double radius = aBall.radius;
1114 double xCenter = aBall.center[0];
1115 double yCenter = aBall.center[1];
1116 double zCenter = aBall.center[2];
1117 glBegin(GL_QUAD_STRIP);
1118 for(unsigned int j =0; j < phiResolution; j++)
1119 {
1120 double phi0 = M_PI/2.0-j*phiStep;
1121 double phi1 = M_PI/2.0-(j+1)*phiStep;
1122 for(unsigned int i =0; i <= thetaResolution; i++)
1123 {
1124 double theta0 = i * thetaStep;
1125 glColor4ub ( aBall.color.red(), aBall.color.green(), aBall.color.blue(), aBall.color.alpha() );
1126 glNormal3f(cos(phi0)*cos(theta0), cos(phi0)*sin(theta0), sin(phi0));
1127 glVertex3f(xCenter+cos(phi0)*cos(theta0)*radius,yCenter+ cos(phi0)*sin(theta0)*radius, zCenter+ sin(phi0)*radius);
1128 glNormal3f(cos(phi1)*cos(theta0), cos(phi1)*sin(theta0), sin(phi1));
1129 glVertex3f(xCenter+cos(phi1)*cos(theta0)*radius,yCenter+ cos(phi1)*sin(theta0)*radius, zCenter+ sin(phi1)*radius);
1130 }
1131 }
1132 glEnd();
1133
1134}
1135
1136template <typename TSpace, typename TKSpace>
1137void DGtal::Viewer3D<TSpace, TKSpace>::mousePressEvent( QMouseEvent * e )
1138{
1139 bool handled = false;
1140 // Checks if an extension is present.
1141 if ( myExtension != 0 )
1142 {
1143 handled = myExtension->mousePressEvent( *this, e );
1144 if ( handled )
1145 return;
1146 }
1147
1148 if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier))
1149 {
1150 myIsMovingLight=true;
1151 myRefMouseXPos = e->x();
1152 myRefMouseYPos = e->y();
1153 if( myLightPositionFixToCamera )
1154 {
1155 updateLightCoordsFromCamera();
1156 }
1157 myLightR = sqrt( myLightPosition[0]* myLightPosition[0]+
1158 myLightPosition[1]* myLightPosition[1]+
1159 myLightPosition[2]* myLightPosition[2]);
1160 myLightTheta = asin( myLightPosition[2]/myLightR);
1161 myLightPhi = atan2( myLightPosition[1], myLightPosition[0]);
1162 }
1163 else
1164 {
1165 QGLViewer::mousePressEvent(e);
1166 }
1167}
1168
1169template <typename TSpace, typename TKSpace>
1170void DGtal::Viewer3D<TSpace, TKSpace>::mouseReleaseEvent( QMouseEvent * e )
1171{
1172 bool handled = false;
1173 // Checks if an extension is present.
1174 if ( myExtension != 0 )
1175 {
1176 handled = myExtension->mouseReleaseEvent( *this, e );
1177 if ( handled )
1178 return;
1179 }
1180
1181 if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier) || myIsMovingLight){
1182 myIsMovingLight=false;
1183 update();
1184 }else{
1185 QGLViewer::mouseReleaseEvent(e);
1186 }
1187}
1188
1189template <typename TSpace, typename TKSpace>
1190void DGtal::Viewer3D<TSpace, TKSpace>::mouseMoveEvent( QMouseEvent * e )
1191{
1192 bool handled = false;
1193 // Checks if an extension is present.
1194 if ( myExtension != 0 )
1195 {
1196 handled = myExtension->mouseMoveEvent( *this, e );
1197 if ( handled )
1198 return;
1199 }
1200
1201 if(e->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier)){
1202 int varX = e->x() - myRefMouseXPos;
1203 int varY = e->y() - myRefMouseYPos;
1204 myLightPhi -= varY * myLigthRotationStep;
1205 myLightTheta -= varX * myLigthRotationStep / 2.0;
1206 myLightPosition[0] = myLightR*cos(myLightTheta)*cos(myLightPhi);
1207 myLightPosition[1] = myLightR*cos(myLightTheta)*sin(myLightPhi);
1208 myLightPosition[2] = myLightR*sin(myLightTheta);
1209 if(myLightPositionFixToCamera){
1210 updateRelativeCameraFromLightPosition();
1211 }
1212 glLightfv(GL_LIGHT0, GL_POSITION, myLightPosition);
1213 myRefMouseXPos = e->x();
1214 myRefMouseYPos = e->y();
1215 update();
1216 }else{
1217 QGLViewer::mouseMoveEvent(e);
1218 }
1219}
1220
1221template <typename TSpace, typename TKSpace>
1222void DGtal::Viewer3D<TSpace, TKSpace>::keyPressEvent( QKeyEvent * e )
1223{
1224 bool handled = false;
1225 // Checks if an extension is present.
1226 if ( myExtension != 0 )
1227 {
1228 handled = myExtension->keyPressEvent( *this, e );
1229 if ( handled )
1230 return;
1231 }
1232
1233 if( e->key() == Qt::Key_D)
1234 {
1235 myIsDoubleFaceRendering = !myIsDoubleFaceRendering;
1236 glUpdateLightRenderingMode();
1237 update();
1238
1239 }
1240 if( e->key() == Qt::Key_E)
1241 {
1242 trace.info() << "Exporting mesh..." ;
1243 operator>><TSpace, TKSpace>( *this, "exportedMesh.off" );
1244 trace.info() << "[done]"<< std::endl ;
1245 }
1246 if( e->key() == Qt::Key_M)
1247 {
1248 switch (myRenderingMode)
1249 {
1250 case RenderingMode::RenderingDefault :
1251 myRenderingMode = RenderingMode::RenderingMetallic;
1252 break;
1253 case RenderingMode::RenderingMetallic :
1254 myRenderingMode = RenderingMode::RenderingPlastic;
1255 break;
1256 case RenderingMode::RenderingPlastic :
1257 myRenderingMode = RenderingMode::RenderingLambertian;
1258 break;
1259 case RenderingMode::RenderingLambertian :
1260 myRenderingMode = RenderingMode::RenderingDefault;
1261 break;
1262 }
1263 updateRenderingCoefficients(myRenderingMode);
1264 }
1265
1266
1267
1268 if ( ( e->key() ==Qt::Key_W ) )
1269 {
1270 myViewWire=!myViewWire;
1271 updateList(false);
1272 update();
1273 }
1274 if ( e->key() == Qt::Key_Z )
1275 {
1276 if ( myLightPositionFixToCamera )
1277 {
1278 updateLightCoordsFromCamera();
1279 }
1280 myLightR = sqrt( myLightPosition[ 0 ] * myLightPosition[ 0 ] +
1281 myLightPosition[ 1 ] * myLightPosition[ 1 ] +
1282 myLightPosition[ 2 ] * myLightPosition[ 2 ] );
1283 myLightTheta = asin( myLightPosition[ 2 ] / myLightR );
1284 myLightPhi = atan2( myLightPosition[ 1 ], myLightPosition[ 0 ] );
1285
1286 std::stringstream ss;
1287 if ( e->modifiers() == Qt::ShiftModifier )
1288 {
1289 myLightR += 5.0;
1290 ss << "Move away light source at distance: " << myLightR;
1291 }
1292 else
1293 {
1294 myLightR -= 5.0;
1295 ss << "Move closer light source at distance: " << myLightR;
1296 }
1297 displayMessage( QString( ss.str().c_str() ), 3000 );
1298 myLightPosition[ 0 ] = myLightR * cos( myLightTheta ) * cos( myLightPhi );
1299 myLightPosition[ 1 ] = myLightR * cos( myLightTheta ) * sin( myLightPhi );
1300 myLightPosition[ 2 ] = myLightR * sin( myLightTheta );
1301 if ( myLightPositionFixToCamera )
1302 {
1303 updateRelativeCameraFromLightPosition();
1304 }
1305 myIsMovingLight = true;
1306 glLightfv( GL_LIGHT0, GL_POSITION, myLightPosition );
1307 update();
1308 }
1309
1310 if ( ( e->key() == Qt::Key_P ) )
1311 {
1312 myLightPositionFixToCamera =! myLightPositionFixToCamera;
1313 updateLightCoordsFromCamera();
1314 if(myLightPositionFixToCamera)
1315 {
1316 displayMessage(QString("Light source position fixed to camera."), 3000);
1317 updateRelativeCameraFromLightPosition();
1318 }
1319 else
1320 {
1321 displayMessage(QString("Light source position fixed to main scene."), 3000);
1322 //updateLightCoordsFromCamera();
1323 }
1324 update();
1325 }
1326
1327 if ( ( e->key() ==Qt::Key_O ) )
1328 {
1329 myUseGLPointsForBalls = !myUseGLPointsForBalls;
1330 updateList(false);
1331 update();
1332 }
1333
1334 if ( ( e->key() ==Qt::Key_R ) )
1335 {
1336 myGLScaleFactorX=1.0f;
1337 myGLScaleFactorY=1.0f;
1338 myGLScaleFactorZ=1.0f;
1339 update();
1340 }
1341
1342 if ( ( e->key() ==Qt::Key_T ) )
1343 {
1344 handled=true;
1345 DGtal::trace.info() << "sorting surfel according camera position....";
1346 sortSurfelFromCamera();
1347 sortTriangleFromCamera();
1348 sortQuadFromCamera();
1349 sortPolygonFromCamera();
1350 DGtal::trace.info() << " [done]"<< std::endl;
1351 updateList(false);
1352 update();
1353 }
1354 if ( ( e->key() ==Qt::Key_B ) )
1355 {
1356 handled=true;
1357 myIsBackgroundDefault=!myIsBackgroundDefault;
1358 glUpdateBackground();
1359 update();
1360 }
1361
1362 if ( ( e->key() ==Qt::Key_L ) )
1363 {
1364 if(e->modifiers()==Qt::ShiftModifier){
1365 saveStateToFile();
1366 }else{
1367 restoreStateFromFile();
1368 update();
1369 }
1370 }
1371 if ( ( e->key() ==Qt::Key_C ) )
1372 {
1373 handled=true;
1374 GLint Viewport[4];
1375 GLdouble Projection[16], Modelview[16];
1376
1377 glGetIntegerv ( GL_VIEWPORT , Viewport );
1378 glGetDoublev ( GL_MODELVIEW_MATRIX , Modelview );
1379 glGetDoublev ( GL_PROJECTION_MATRIX, Projection );
1380
1381 for ( unsigned short m=0; m<4; ++m )
1382 {
1383 for ( unsigned short l=0; l<4; ++l )
1384 {
1385 double sum = 0.0;
1386 for ( unsigned short k=0; k<4; ++k )
1387 sum += Projection[l+4*k]*Modelview[k+4*m];
1388 }
1389 }
1390
1391 DGtal::trace.info() << "Viewport: ";
1392 for ( unsigned short l=0; l<4; ++l )
1393 DGtal::trace.info() << Viewport[l] << ", ";
1394 DGtal::trace.info() << std::endl;
1395
1396 Vec cp = camera()->position();
1397 Vec cd = camera()->viewDirection();
1398 Vec cup = camera()->upVector();
1399
1400 DGtal::trace.info() << "camera.position: " ;
1401 for ( unsigned short l=0; l<3; ++l )
1402 DGtal::trace.info() << cp[l] << ", ";
1403 DGtal::trace.info() << std::endl;
1404
1405 DGtal::trace.info() << "camera.direction: ";
1406 for ( unsigned short l=0; l<3; ++l )
1407 DGtal::trace.info() << cd[l] << ", ";
1408 DGtal::trace.info() << std::endl;
1409
1410 DGtal::trace.info() << "camera.upVector: ";
1411 for ( unsigned short l=0; l<3; ++l )
1412 DGtal::trace.info() << cup[l] << ", ";
1413 DGtal::trace.info() << std::endl;
1414
1415 DGtal::trace.info() << "zNear: " << camera()->zNear() << " - zFar: " << camera()->zFar() << std::endl;
1416 }
1417
1418 if ( !handled )
1419 QGLViewer::keyPressEvent ( e );
1420}
1421
1422template <typename TSpace, typename TKSpace>
1423QString DGtal::Viewer3D<TSpace, TKSpace>::helpString() const
1424{
1425 QString text;
1426 if ( myExtension != 0 )
1427 text += myExtension->helpString( *this );
1428
1429 text += "<h2> Viewer3D</h2>";
1430 text += "Use the mouse to move the camera around the object. ";
1431 text += "You can respectively revolve around, zoom and translate with the three mouse buttons. ";
1432 text += "Left and middle buttons pressed together rotate around the camera view direction axis<br><br>";
1433 text += "Pressing <b>Alt</b> and one of the function keys (<b>F1</b>..<b>F12</b>) defines a camera keyFrame. ";
1434 text += "Simply press the function key again to restore it-> Several keyFrames define a ";
1435 text += "camera path. Paths are saved when you quit the application and restored at next start.<br><br>";
1436 text += "Press <b>F</b> to display the frame rate, <b>A</b> for the world axis, ";
1437 text += "<b>Alt+Return</b> for full screen mode and <b>Control+S</b> to save a snapshot. ";
1438 text += "See the <b>Keyboard</b> tab in this window for a complete shortcut list.<br><br>";
1439 text += "Double clicks automates single click actions: A left button double click aligns the closer axis with the camera (if close enough). ";
1440 text += "A middle button double click fits the zoom of the camera and the right button re-centers the scene.<br><br>";
1441 text += "A left button double click while holding right button pressed defines the camera <i>Revolve Around Ball</i>. ";
1442 text += "See the <b>Mouse</b> tab and the documentation web pages for details.<br><br>";
1443 text += "Press <b>Escape</b> to exit the viewer.";
1444 return text;
1445}
1446
1447template <typename TSpace, typename TKSpace>
1448void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListCubesMaps(
1449const typename DGtal::Display3D<TSpace, TKSpace>::CubesMap & aCubeMap,
1450unsigned int idList )
1451{
1452 glNewList ( idList , GL_COMPILE );
1453
1454 for (auto &mapElem: aCubeMap)
1455 {
1456 glPushName ( mapElem.first );
1457 glEnable ( GL_LIGHTING );
1458 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
1459 glBegin ( GL_QUADS );
1460 bool useColorSelection = false;
1461 if(mySelectedElementId == mapElem.first)
1462 useColorSelection = true;
1463
1464 for (auto &cube: mapElem.second)
1465 {
1466 if(useColorSelection)
1467 {
1468 unsigned char m = (cube.color.red()+ cube.color.green()+ cube.color.blue())/3;
1469 if(m>128)
1470 {
1471 glColor4ub ( std::max((int)(cube.color.red())-mySelectionColorShift, 0),
1472 std::max((int)(cube.color.green())-mySelectionColorShift, 0),
1473 std::max((int)(cube.color.blue())-mySelectionColorShift, 0),
1474 cube.color.alpha());
1475 }
1476 else{
1477 glColor4ub ( std::min(cube.color.red()+mySelectionColorShift, 255),
1478 std::min(cube.color.green()+mySelectionColorShift, 255),
1479 std::min(cube.color.blue()+mySelectionColorShift, 255),
1480 cube.color.alpha());
1481 }
1482 }
1483 else
1484 {
1485 glColor4ub ( cube.color.red(), cube.color.green(), cube.color.blue(),cube.color.alpha());
1486 }
1487 double _width= cube.width;
1488 //z+
1489 glNormal3f ( 0.0, 0.0, 1.0 );
1490 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
1491 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
1492 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
1493 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]+_width );
1494 //z-
1495 glNormal3f ( 0.0, 0.0, -1.0 );
1496 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
1497 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]-_width );
1498 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]-_width );
1499 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]-_width );
1500 //x+
1501 glNormal3f ( 1.0, 0.0, 0.0 );
1502 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
1503 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]-_width );
1504 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]-_width );
1505 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]+_width );
1506 //x-
1507 glNormal3f ( -1.0, 0.0, 0.0 );
1508 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
1509 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
1510 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
1511 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]-_width );
1512 //y+
1513 glNormal3f ( 0.0, 1.0, 0.0 );
1514 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]+_width );
1515 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]+_width );
1516 glVertex3f ( cube.center[0]+_width, cube.center[1]+_width, cube.center[2]-_width );
1517 glVertex3f ( cube.center[0]-_width, cube.center[1]+_width, cube.center[2]-_width );
1518 //y-
1519 glNormal3f ( 0.0, -1.0, 0.0 );
1520 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]+_width );
1521 glVertex3f ( cube.center[0]-_width, cube.center[1]-_width, cube.center[2]-_width );
1522 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]-_width );
1523 glVertex3f ( cube.center[0]+_width, cube.center[1]-_width, cube.center[2]+_width );
1524 }
1525 glEnd();
1526 glPopName();
1527 }
1528 glEndList();
1529 glUpdateLightRenderingMode();
1530
1531}
1532
1533template <typename TSpace, typename TKSpace>
1534void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListQuadD3D(
1535const VectorQuad & aVectQuad, unsigned int idList )
1536{
1537 glNewList ( idList, GL_COMPILE );
1538 glPushName ( myNbListe );
1539 glEnable ( GL_DEPTH_TEST );
1540 glEnable ( GL_BLEND );
1541 glEnable ( GL_MULTISAMPLE_ARB );
1542 glEnable ( GL_SAMPLE_ALPHA_TO_COVERAGE_ARB );
1543 glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1544
1545 glBegin ( GL_QUADS );
1546 for ( auto const &q: aVectQuad )
1547 {
1548 glColor4ub ( q.color.red(), q.color.green(),
1549 q.color.blue(), q.color.alpha() );
1550 glNormal3f ( q.nx, q.ny, q.nz );
1551 glVertex3f ( q.point1[0], q.point1[1] , q.point1[2] );
1552 glVertex3f ( q.point2[0], q.point2[1] , q.point2[2] );
1553 glVertex3f ( q.point3[0], q.point3[1] , q.point3[2] );
1554 glVertex3f ( q.point4[0], q.point4[1] , q.point4[2] );
1555 }
1556 glEnd();
1557 glEndList();
1558}
1559
1560template <typename TSpace, typename TKSpace>
1561void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListLines(
1562const VectorLine & aVectLine, unsigned int idList )
1563{
1564 glNewList ( idList, GL_COMPILE );
1565 glDisable ( GL_LIGHTING );
1566 glPushName ( myNbListe );
1567 glBegin ( GL_LINES );
1568 for (auto const &l: aVectLine )
1569 {
1570 glColor4ub ( l.color.red(), l.color.green(),
1571 l.color.blue(), l.color.alpha() );
1572 glVertex3f ( l.point1[0], l.point1[1], l.point1[2] );
1573 glVertex3f ( l.point2[0], l.point2[1], l.point2[2] );
1574 }
1575 glEnd();
1576 glEnable ( GL_LIGHTING );
1577 glEndList();
1578}
1579
1580template <typename TSpace, typename TKSpace>
1581void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListBalls(
1582const VectorBall & aVectBall, unsigned int idList )
1583{
1584 if(myUseGLPointsForBalls)
1585 {
1586 glNewList ( idList, GL_COMPILE );
1587 glDepthMask ( GL_TRUE );
1588 glDisable ( GL_TEXTURE_2D );
1589 glDisable ( GL_POINT_SMOOTH );
1590 glDisable ( GL_LIGHTING );
1591 glPushName ( myNbListe );
1592 glBegin ( GL_POINTS );
1593 for ( auto const &ball: aVectBall )
1594 {
1595 glColor4ub ( ball.color.red(), ball.color.green(),
1596 ball.color.blue(), ball.color.alpha() );
1597 glVertex3f ( ball.center[0], ball.center[1], ball.center[2] );
1598 }
1599 glEnd();
1600 glEnable ( GL_LIGHTING );
1601 glEndList();
1602 }
1603 else
1604 {
1605 glNewList ( idList, GL_COMPILE );
1606 glPushName ( myNbListe );
1607 glDepthMask ( GL_TRUE );
1608 glDisable ( GL_TEXTURE_2D );
1609 glDisable ( GL_POINT_SMOOTH );
1610 for ( auto const & b: aVectBall)
1611 {
1612 glDrawGLBall ( b );
1613 }
1614 glEnd();
1615 glEndList();
1616 }
1617}
1618
1619template <typename TSpace, typename TKSpace>
1620void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListQuadMaps(
1621const typename DGtal::Display3D<TSpace, TKSpace>::QuadsMap & aQuadMap,
1622unsigned int idList )
1623{
1624 glNewList ( idList, GL_COMPILE );
1625 for (auto & mapElem: aQuadMap)
1626 {
1627 glPushName ( mapElem.first );
1628 glEnable ( GL_LIGHTING );
1629 glBegin ( GL_QUADS );
1630 bool useColorSelection = false;
1631 if(mySelectedElementId == mapElem.first)
1632 useColorSelection = true;
1633
1634 for (auto &q: mapElem.second)
1635 {
1636 if(useColorSelection)
1637 {
1638 unsigned char m = (q.color.red()+ q.color.green()+ q.color.blue())/3;
1639 if(m>128)
1640 {
1641 glColor4ub ( std::max((int)(q.color.red())-mySelectionColorShift, 0),
1642 std::max((int)(q.color.green())-mySelectionColorShift, 0),
1643 std::max((int)(q.color.blue())-mySelectionColorShift, 0),
1644 q.color.alpha());
1645 }
1646 else{
1647 glColor4ub ( std::min(q.color.red()+mySelectionColorShift, 255),
1648 std::min(q.color.green()+mySelectionColorShift, 255),
1649 std::min(q.color.blue()+mySelectionColorShift, 255),
1650 q.color.alpha());
1651 }
1652 }
1653 else
1654 {
1655 glColor4ub ( q.color.red(), q.color.green(), q.color.blue(), q.color.alpha());
1656
1657 }
1658
1659 glNormal3f ( q.nx, q.ny ,q.nz );
1660 glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
1661 glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
1662 glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
1663 glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
1664 }
1665 glEnd();
1666 glPopName();
1667 }
1668 glEndList();
1669}
1670
1671template <typename TSpace, typename TKSpace>
1672void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListQuadMapsWired(
1673const typename DGtal::Display3D<TSpace, TKSpace>::QuadsMap & aQuadMap,
1674unsigned int idList )
1675{
1676 glNewList ( idList, GL_COMPILE );
1677 glPushName ( myNbListe );
1678 glDisable ( GL_LIGHTING );
1679 glBegin ( GL_LINES );
1680
1681 for (auto const &mapElem: aQuadMap)
1682 {
1683 for(auto const &q: mapElem.second)
1684 {
1685 glColor4ub ( 150.0,150.0,150.0,255.0 );
1686 glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
1687 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
1688 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
1689 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
1690 glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
1691 glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
1692 glVertex3f ( q.point2[0], q.point2[1], q.point2[2] );
1693 glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
1694 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
1695 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
1696 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
1697 glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
1698 glVertex3f ( q.point3[0], q.point3[1], q.point3[2] );
1699 glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
1700 glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
1701 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
1702 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
1703 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
1704 glVertex3f ( q.point4[0], q.point4[1], q.point4[2] );
1705 glVertex3f ( q.point1[0], q.point1[1], q.point1[2] );
1706 }
1707 }
1708 glEnd();
1709 glEndList();
1710
1711}
1712
1713template <typename TSpace, typename TKSpace>
1714void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListTriangles(
1715const std::vector<VectorTriangle> & aVectTriangle, unsigned int idList )
1716{
1717 glNewList ( idList, GL_COMPILE );
1718 glPushName ( myNbListe );
1719 glEnable ( GL_LIGHTING );
1720 glBegin ( GL_TRIANGLES );
1721 for(auto const &tList: aVectTriangle)
1722 {
1723 for (auto const &t: tList)
1724 {
1725 glColor4ub (t.color.red(),t.color.green(),t.color.blue(),t.color.alpha() );
1726 glNormal3f (t.nx,t.ny ,t.nz );
1727 glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
1728 glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
1729 glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
1730 }
1731 }
1732 glEnd();
1733 glEndList();
1734}
1735
1736template <typename TSpace, typename TKSpace>
1737void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListTrianglesWired(
1738const std::vector<VectorTriangle> & aVectTriangle, unsigned int idList )
1739{
1740 glNewList ( idList, GL_COMPILE );
1741 glPushName ( myNbListe );
1742 glDisable ( GL_LIGHTING );
1743 glBegin ( GL_LINES );
1744 for (auto const &tList: aVectTriangle)
1745 {
1746 for (auto const &t: tList)
1747 {
1748 glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
1749 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
1750 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
1751 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
1752 glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
1753 glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
1754 glVertex3f (t.point2[0],t.point2[1],t.point2[2] );
1755 glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
1756 glVertex3f (t.point3[0],t.point3[1],t.point3[2] );
1757 glVertex3f (t.point1[0],t.point1[1],t.point1[2] );
1758 }
1759 }
1760 glEnd();
1761 glEndList();
1762
1763}
1764
1765template <typename TSpace, typename TKSpace>
1766void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListPolygons(
1767const std::vector<VectorPolygon> & aVectPolygon, unsigned int idList )
1768{
1769 glNewList ( idList, GL_COMPILE );
1770 glPushName ( myNbListe );
1771 glEnable ( GL_LIGHTING );
1772
1773 for(auto const &pList: aVectPolygon)
1774 {
1775 for (auto const &p: pList)
1776 {
1777 glBegin ( GL_POLYGON );
1778 glColor4ub ( p.color.red(), p.color.green(), p.color.blue(), p.color.alpha() );
1779 glNormal3f ( p.nx, p.ny ,p.nz );
1780 for(unsigned int j=0;j < (p.vertices).size();j++)
1781 {
1782 glVertex3f ( (p.vertices).at(j)[0], (p.vertices).at(j)[1], (p.vertices).at ( j )[2] );
1783 }
1784 glEnd();
1785 }
1786 }
1787 glEndList();
1788}
1789
1790template <typename TSpace, typename TKSpace>
1791void DGtal::Viewer3D<TSpace, TKSpace>::glCreateListPolygonsWired(
1792const std::vector<VectorPolygon> & aVectPolygon, unsigned int idList )
1793{
1794 glNewList ( idList, GL_COMPILE );
1795 glPushName ( myNbListe );
1796 glDisable ( GL_LIGHTING );
1797 glBegin ( GL_LINES );
1798 for(auto const &pList: aVectPolygon)
1799 {
1800 for (auto const &p: pList)
1801 {
1802 glColor4ub( Viewer3D<TSpace, TKSpace>::myCurrentLineColor.red(),
1803 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.green(),
1804 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.blue(),
1805 Viewer3D<TSpace, TKSpace>::myCurrentLineColor.alpha() );
1806 for(unsigned int j=0;j < (p.vertices).size();j++)
1807 {
1808 glVertex3f ( (p.vertices).at(j)[0], (p.vertices).at(j)[1], (p.vertices).at ( j )[2] );
1809 glVertex3f ( (p.vertices).at((j+1)%(p.vertices).size())[0],
1810 (p.vertices).at((j+1)%(p.vertices).size())[1],
1811 (p.vertices).at ( (j+1)%(p.vertices).size() )[2] );
1812 }
1813 }
1814 }
1815 glEnd();
1816 glEndList();
1817}
1818
1819template <typename TSpace, typename TKSpace>
1820void DGtal::Viewer3D<TSpace, TKSpace>::glUpdateTextureImages(
1821const VectorTextureImage & aVectImage )
1822{
1823
1824 for(unsigned int j=0; j<myVectTextureImage.size(); j++){
1825 glDeleteTextures(1,&(myVectTextureImage[j].myTextureName));
1826 }
1827 myVectTextureImage.clear();
1828 for(unsigned int j=0; j<aVectImage.size(); j++)
1829 {
1830 typename Viewer3D<TSpace, TKSpace>::TextureImage aGSImage =
1831 aVectImage.at( j );
1832 GLTextureImage textureImg(aGSImage);
1833
1834 glGenTextures(1, &textureImg.myTextureName);
1835 glBindTexture(GL_TEXTURE_2D, textureImg.myTextureName);
1836
1837 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1838 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1839 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1840 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1841 if ( textureImg.myMode == Viewer3D<TSpace, TKSpace>::GrayScaleMode )
1842 {
1843 glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE, textureImg.myBufferWidth,
1844 textureImg.myBufferHeight, 0, GL_LUMINANCE,
1845 GL_UNSIGNED_BYTE, textureImg.myTextureImageBufferGS );
1846 }
1847 else if ( textureImg.myMode == Viewer3D<TSpace, TKSpace>::RGBMode )
1848 {
1849 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, textureImg.myBufferWidth,
1850 textureImg.myBufferHeight, 0, GL_RGB, GL_UNSIGNED_BYTE,
1851 textureImg.myTextureImageBufferRGB );
1852 }
1853 myVectTextureImage.push_back(textureImg);
1854 }
1855}
1856
1857template <typename TSpace, typename TKSpace>
1858void DGtal::Viewer3D<TSpace, TKSpace>::glUpdateLightRenderingMode() const
1859{
1860 if(myIsDoubleFaceRendering)
1861 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
1862 else
1863 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
1864}
1865
1866
1867template <typename TSpace, typename TKSpace>
1868void DGtal::Viewer3D<TSpace, TKSpace>::glUpdateBackground()
1869{
1870
1871 if ( !myIsBackgroundDefault )
1872 {
1873 setBackgroundColor ( QColor ( 255, 255,255, 255 ) );
1874 }
1875 else
1876 {
1877 setBackgroundColor ( QColor ( myDefaultBackgroundColor.red(),
1878 myDefaultBackgroundColor.green(),
1879 myDefaultBackgroundColor.blue(),
1880 myDefaultBackgroundColor.alpha()));
1881 }
1882}
1883
1884
1885template <typename TSpace, typename TKSpace>
1886QDomElement
1887DGtal::Viewer3D<TSpace, TKSpace>::domElement( const QString & name,
1888 QDomDocument & document ) const
1889{
1890 // Creates a custom node for a light position
1891 QDomElement deRendering = document.createElement("Rendering");
1892 deRendering.setAttribute("mode", myRenderingMode);
1893 QDomElement de = document.createElement("Light");
1894 de.setAttribute("pos_light_x", myLightPosition[0]);
1895 de.setAttribute("pos_light_y", myLightPosition[1]);
1896 de.setAttribute("pos_light_z", myLightPosition[2]);
1897 // Get default state domElement and append custom node
1898 QDomElement res = QGLViewer::domElement(name, document);
1899 res.appendChild(de);
1900 res.appendChild(deRendering);
1901 return res;
1902}
1903
1904template <typename TSpace, typename TKSpace>
1905void DGtal::Viewer3D<TSpace, TKSpace>::initFromDOMElement(
1906const QDomElement & element )
1907{
1908 // Restore standard state
1909 QGLViewer::initFromDOMElement(element);
1910 QDomElement child=element.firstChild().toElement();
1911 while (!child.isNull())
1912 {
1913 if (child.tagName() == "Rendering")
1914 {
1915 myRenderingMode = (RenderingMode)(child.attribute("mode").toInt());
1916 }
1917 if (child.tagName() == "Light")
1918 {
1919 if (child.hasAttribute("pos_light_x"))
1920 {
1921 myLightPosition[0] = child.attribute("pos_light_x").toDouble();
1922 }
1923
1924 if (child.hasAttribute("pos_light_y"))
1925 {
1926 myLightPosition[1] = child.attribute("pos_light_y").toDouble();
1927 }
1928 if (child.hasAttribute("pos_light_z"))
1929 {
1930 myLightPosition[2] = child.attribute("pos_light_z").toDouble();
1931 }
1932 }
1933 child = child.nextSibling().toElement();
1934 }
1935 if(myLightPositionFixToCamera){
1936 updateRelativeCameraFromLightPosition();
1937 }
1938 updateRenderingCoefficients(myRenderingMode, false);
1939 update();
1940}
1941
1942template <typename TSpace, typename TKSpace>
1943void DGtal::Viewer3D<TSpace, TKSpace>::closeEvent( QCloseEvent * e )
1944{
1945 if (myAutoSaveState)
1946 {
1947 saveStateToFile();
1948 }
1949 QGLViewer::closeEvent(e);
1950}
1951
1952template <typename TSpace, typename TKSpace>
1953void DGtal::Viewer3D<TSpace, TKSpace>::setGLDoubleRenderingMode(
1954bool doubleSidedRendering )
1955{
1956 myIsDoubleFaceRendering = doubleSidedRendering;
1957 glUpdateLightRenderingMode();
1958}
1959
1960template <typename TSpace, typename TKSpace>
1961void DGtal::Viewer3D<TSpace, TKSpace>::setGLMaterialShininessCoefficient(
1962const GLfloat matShininessCoeff )
1963{
1964 myMaterialShininessCoeff = matShininessCoeff;
1965 update();
1966}
1967
1968template <typename TSpace, typename TKSpace>
1969void DGtal::Viewer3D<TSpace, TKSpace>::setGLLightAmbientCoefficients(
1970const GLfloat lightAmbientCoeffs[ 4 ] )
1971{
1972 myLightAmbientCoeffs[0] = lightAmbientCoeffs[0];
1973 myLightAmbientCoeffs[1] = lightAmbientCoeffs[1];
1974 myLightAmbientCoeffs[2] = lightAmbientCoeffs[2];
1975 myLightAmbientCoeffs[3] = lightAmbientCoeffs[3];
1976 update();
1977}
1978
1979template <typename TSpace, typename TKSpace>
1980void DGtal::Viewer3D<TSpace, TKSpace>::setGLLightDiffuseCoefficients(
1981const GLfloat lightDiffuseCoeffs[ 4 ] )
1982{
1983 myLightDiffuseCoeffs[0] = lightDiffuseCoeffs[0];
1984 myLightDiffuseCoeffs[1] = lightDiffuseCoeffs[1];
1985 myLightDiffuseCoeffs[2] = lightDiffuseCoeffs[2];
1986 myLightDiffuseCoeffs[3] = lightDiffuseCoeffs[3];
1987 update();
1988}
1989
1990template <typename TSpace, typename TKSpace>
1991void DGtal::Viewer3D<TSpace, TKSpace>::setUseGLPointForBalls(
1992const bool useOpenGLPt )
1993{
1994 myUseGLPointsForBalls = useOpenGLPt;
1995}
1996
1997template <typename TSpace, typename TKSpace>
1998void DGtal::Viewer3D<TSpace, TKSpace>::updateRenderingCoefficients(
1999const RenderingMode aRenderMode, bool displayState )
2000{
2001 std::stringstream ss;
2002 ss << "Rendering mode ";
2003
2004 GLfloat newCoefDiff, newCoefSpec = 1.0f;
2005 switch (aRenderMode)
2006 {
2007 case RenderingMode::RenderingDefault :
2008 newCoefDiff = myDefaultRenderDiff;
2009 newCoefSpec = myDefaultRenderSpec;
2010 ss << "Default (diffuse with few specular)";
2011 break;
2012 case RenderingMode::RenderingMetallic :
2013 newCoefDiff = myMetallicRenderDiff;
2014 newCoefSpec = myMetallicRenderSpec;
2015 ss << "Metallic (diffuse with specular)";
2016 break;
2017 case RenderingMode::RenderingPlastic :
2018 newCoefDiff = myPlasticRenderDiff;
2019 newCoefSpec = myPlasticRenderSpec;
2020 ss << "Plastic (few diffuse with large specular)";
2021 break;
2022 case RenderingMode::RenderingLambertian :
2023 newCoefDiff = myLambertRenderDiff;
2024 newCoefSpec = myLambertRenderSpec;
2025 ss << "Lambertian (only diffuse)";
2026 break;
2027 }
2028 for (unsigned int i = 0; i<3; i++)
2029 myLightDiffuseCoeffs[i] = newCoefDiff;
2030 myLightDiffuseCoeffs[3] = 1.0;
2031 for (unsigned int i = 0; i<3; i++)
2032 myLightSpecularCoeffs[i] = newCoefSpec;
2033 myLightSpecularCoeffs[3] = 1.0;
2034 if (displayState)
2035 {
2036 displayMessage(QString(ss.str().c_str()), 3000);
2037 }
2038 update();
2039}
2040
2041template <typename TSpace, typename TKSpace>
2042void DGtal::Viewer3D<TSpace, TKSpace>::setGLLightSpecularCoefficients(
2043const GLfloat lightSpecularCoeffs[ 4 ] )
2044{
2045 myLightSpecularCoeffs[0] = lightSpecularCoeffs[0];
2046 myLightSpecularCoeffs[1] = lightSpecularCoeffs[1];
2047 myLightSpecularCoeffs[2] = lightSpecularCoeffs[2];
2048 myLightSpecularCoeffs[3] = lightSpecularCoeffs[3];
2049 update();
2050}
2051
2052template <typename TSpace, typename TKSpace>
2053inline void DGtal::Viewer3D<TSpace, TKSpace>::show()
2054{
2055 QGLViewer::show();
2056 updateList(false);
2057}
2058
2059template <typename TSpace, typename TKSpace>
2060inline void DGtal::Viewer3D<TSpace, TKSpace>::paintGL()
2061{
2062 if ( displaysInStereo() )
2063 {
2064 for ( int view = 1; view >= 0; --view )
2065 {
2066 // Clears screen, set model view matrix with shifted matrix for ith buffer
2067 preDrawStereo( view );
2068 postDraw();
2069 // Used defined method. Default is empty
2070 if ( camera()->frame()->isManipulated() )
2071 fastDraw();
2072 else
2073 draw();
2074 }
2075 }
2076 else
2077 {
2078 // Clears screen, set model view matrix...
2079 preDraw();
2080 postDraw();
2081 // Used defined method. Default calls draw()
2082 if ( camera()->frame()->isManipulated() )
2083 fastDraw();
2084 else
2085 draw();
2086 // Add visual hints: axis, camera, grid...
2087 }
2088 Q_EMIT drawFinished( true );
2089}
2090
2091template <typename TSpace, typename TKSpace>
2092void DGtal::Viewer3D<TSpace, TKSpace>::updateLightCoordsFromCamera()
2093{
2094 Vec posLCam;
2095 posLCam[0] = myLightPositionRefCamera[0];
2096 posLCam[1] = myLightPositionRefCamera[1];
2097 posLCam[2] = myLightPositionRefCamera[2];
2098 Vec posL = camera()->worldCoordinatesOf(posLCam);
2099 myLightPosition[0] = static_cast<GLfloat>(posL[0]);
2100 myLightPosition[1] = static_cast<GLfloat>(posL[1]);
2101 myLightPosition[2] = static_cast<GLfloat>(posL[2]);
2102 myLightPosition[3] = 1.0f;
2103}
2104
2105template <typename TSpace, typename TKSpace>
2106void DGtal::Viewer3D<TSpace, TKSpace>::updateRelativeCameraFromLightPosition()
2107{
2108 Vec posL;
2109 posL[0] = myLightPosition[0];
2110 posL[1] = myLightPosition[1];
2111 posL[2] = myLightPosition[2];
2112 Vec posLCam = camera()->cameraCoordinatesOf(posL);
2113 myLightPositionRefCamera[0] = static_cast<GLfloat>(posLCam[0]);
2114 myLightPositionRefCamera[1] = static_cast<GLfloat>(posLCam[1]);
2115 myLightPositionRefCamera[2] = static_cast<GLfloat>(posLCam[2]);
2116}
2117
2118
2119