]> SALOME platform Git repositories - modules/kernel.git/blob - src/VTKViewer/VTKViewer_RenderWindow.cxx
Salome HOME
Initialisation de la base KERNEL avec la version operationnelle de KERNEL_SRC issue...
[modules/kernel.git] / src / VTKViewer / VTKViewer_RenderWindow.cxx
1 using namespace std;
2 //  File      : VTKViewer_RenderWindow.cxx
3 //  Created   : Wed Mar 20 11:34:28 2002
4 //  Author    : Nicolas REJNERI
5 //  Project   : SALOME
6 //  Module    : VTKViewer
7 //  Copyright : Open CASCADE 2002
8 //  $Header$
9
10 #include "VTKViewer_RenderWindow.h"
11 #include "utilities.h"
12 #include "QAD_Settings.h"
13 #include "QAD_Config.h"
14 #include "QAD_Desktop.h"
15 #include "QAD_Study.h"
16 #include "QAD_Tools.h"
17 #include "SALOME_Selection.h"
18
19 #include <qcolordialog.h>
20
21 #include <stdlib.h>
22 #include <math.h>
23 #include <iostream.h>
24
25 #include <vtkRenderWindowInteractor.h>
26
27 #include <GL/gl.h>
28 #include <GL/glu.h>
29 #include <qgl.h>
30
31 #if QT_VERSION > 300
32 #include <qcursor.h>
33 #endif
34
35 VTKViewer_RenderWindow::VTKViewer_RenderWindow(QWidget *parent, const char *name) :
36   QGLWidget(parent, name)
37 {
38   mInitialized = false ;
39   //NRI - 22/02/2002  setFocusPolicy(QWidget::StrongFocus) ;
40   //NRI - comment rev 1.6 - setFocus();
41 }
42
43 VTKViewer_RenderWindow::~VTKViewer_RenderWindow() {
44   this->ReferenceCount-- ;
45 }
46
47 void VTKViewer_RenderWindow::PrintSelf(ostream& os, vtkIndent indent) {
48   this->vtkRenderWindow::PrintSelf(os, indent);
49
50   QGLFormat myFormat = this->format() ;
51   os << indent << "qGLVersion: " << qGLVersion() << endl ;
52   os << indent << "doubleBuffer: " << myFormat.doubleBuffer() << endl ;
53   os << indent << "depth: " << myFormat.depth() << endl ;
54   os << indent << "rgba: " << myFormat.rgba() << endl ;
55   os << indent << "alpha: " << myFormat.alpha() << endl ;
56   os << indent << "accum: " << myFormat.accum() << endl ;
57   os << indent << "stencil: " << myFormat.stencil() << endl ;
58   os << indent << "stereo: " << myFormat.stereo() << endl ;
59   os << indent << "directRendering: " << myFormat.directRendering() << endl ;
60 }
61
62 void VTKViewer_RenderWindow::Start(void) {
63   // 
64   // Initialize the QGLWidget part of the widget if it has not
65   // been initialized so far. 
66   //
67   if( ! this->mInitialized ) {
68     this->WindowInitialize() ;
69   }
70   this->MakeCurrent() ;
71 }
72
73 // End the rendering process and display the image. 
74 void VTKViewer_RenderWindow::Frame(void) {
75   glFlush() ;
76   if( (! this->AbortRender) && // the render is not being aborted
77       (! autoBufferSwap() ) && // buffers are not switched automatically
78       doubleBuffer() &&        // double buffering is enabled on QGLWidget side
79       this->vtkRenderWindow::DoubleBuffer &&    // double buffering is enabled on VTK side
80       this->SwapBuffers ) {    // VTK wants us to swap buffers
81     QGLWidget::swapBuffers() ;
82   }
83 }
84 void* VTKViewer_RenderWindow::GetGenericDisplayId() {
85   return ((void*)x11Display());
86 }
87
88 void* VTKViewer_RenderWindow::GetGenericWindowId() {
89   return ((void*)winId());
90 }
91
92 void* VTKViewer_RenderWindow::GetGenericContext() {
93   return ((void*)(this->context())->currentContext());
94 }
95
96 // Initialize the window for rendering.
97 void VTKViewer_RenderWindow::WindowInitialize(void) {
98   if( ! this->mInitialized ) {
99     this->initializeGL() ;
100     this->MakeCurrent() ;
101
102     vtkDebugMacro(<< " glMatrixMode ModelView\n");
103     glMatrixMode( GL_MODELVIEW );
104
105     vtkDebugMacro(<< " zbuffer enabled\n");
106     glDepthFunc( GL_LEQUAL );
107     glEnable( GL_DEPTH_TEST );
108
109     vtkDebugMacro(" texture stuff\n");
110     glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
111
112     // initialize blending for transparency
113     vtkDebugMacro(<< " blend func stuff\n");
114     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
115     glEnable(GL_BLEND);
116   
117     if (this->PointSmoothing)
118       {
119         glEnable(GL_POINT_SMOOTH);
120       }
121     else
122       {
123         glDisable(GL_POINT_SMOOTH);
124       }
125
126     if (this->LineSmoothing)
127       {
128         glEnable(GL_LINE_SMOOTH);
129       }
130     else
131       {
132         glDisable(GL_LINE_SMOOTH);
133       }
134
135     if (this->PolygonSmoothing)
136       {
137         glEnable(GL_POLYGON_SMOOTH);
138       }
139     else
140       {
141         glDisable(GL_POLYGON_SMOOTH);
142       }
143
144     glEnable( GL_NORMALIZE );
145     glAlphaFunc(GL_GREATER,0);
146   
147     this->Mapped = 1;
148
149   }
150 }
151
152 void VTKViewer_RenderWindow::SetFullScreen(int arg) {
153   //
154   // We do not need to do anything if the FullScreen mode
155   // is already set to the specified value. 
156   //
157   if( this->FullScreen == arg ) return ;
158
159   //
160   // :TODO: Fri Apr 21 16:41:06 2000 Pagey
161   // This is not implemented in QGLWidget yet. Hence, we
162   // will ignore it.
163   //
164   vtkDebugMacro(<< " QGLWidget::SetFullScreen() not supported by QGLWidget yet.\n") ;
165 }
166
167 void VTKViewer_RenderWindow::WindowRemap(void) {
168   //
169   // :TODO: Fri Apr 21 16:44:35 2000 Pagey
170   // I am not sure why we would ever need to do this under Qt. 
171   // Hence, I have not done anything here yet. 
172   //
173   vtkDebugMacro(<< " QGLWidget::WindowRemap() not supported by QGLWidget yet.\n") ;
174 }
175
176 void VTKViewer_RenderWindow::PrefFullScreen(void) {
177   //
178   // :TODO: Fri Apr 21 16:46:30 2000 Pagey
179   // Since, SetFullScreen() is not supported yet, this is useless.
180   //
181   vtkDebugMacro(<< " QGLWidget::PrefFullScreen() not supported by QGLWidget yet.\n") ;
182 }
183
184 void VTKViewer_RenderWindow::SetSize(int w, int h) {
185   if ((this->Size[0] != w)||(this->Size[1] != h)) {
186     this->Modified();
187     this->Size[0] = w;
188     this->Size[1] = h;
189   }
190   
191   if( this->Interactor ) {
192     this->Interactor->SetSize(w, h) ;
193   }
194
195   // if we arent mappen then just set the ivars 
196   if (!this->Mapped) {
197     return;
198   }
199
200   glViewport( 0, 0, (GLint)w, (GLint)h ) ;
201 }
202
203 void VTKViewer_RenderWindow::StereoUpdate() {
204   //
205   // :NOTE: Fri Apr 21 16:55:32 2000 Pagey
206   // This routine is taken directly from vtkOpenGLRenderWindow.cxx. 
207   // I am not sure what it does. Hope it works. 
208   //
209   if (this->StereoRender && (!this->StereoStatus))
210     {
211       switch (this->StereoType) 
212         {
213         case VTK_STEREO_CRYSTAL_EYES:
214           {
215           }
216           break;
217         case VTK_STEREO_RED_BLUE:
218           {
219             this->StereoStatus = 1;
220           }
221         }
222     }
223   else if ((!this->StereoRender) && this->StereoStatus)
224     {
225       switch (this->StereoType) 
226         {
227         case VTK_STEREO_CRYSTAL_EYES:
228           {
229             this->StereoStatus = 0;
230           }
231           break;
232         case VTK_STEREO_RED_BLUE:
233           {
234             this->StereoStatus = 0;
235           }
236         }
237     }
238 }
239
240 unsigned char *VTKViewer_RenderWindow::GetPixelData(int x1, int y1, int x2, int y2, int front) {
241   //
242   // :NOTE: Fri Apr 21 16:58:53 2000 Pagey
243   // This routine is taken directly from vtkOpenGLRenderWindow.cxx. 
244   // I am not sure what it does. Hope it works. 
245   //
246   int     y_low, y_hi;
247   int     x_low, x_hi;
248   unsigned char   *data = NULL;
249
250   // set the current window 
251   this->MakeCurrent();
252
253   if (y1 < y2)
254     {
255       y_low = y1; 
256       y_hi  = y2;
257     }
258   else
259     {
260       y_low = y2; 
261       y_hi  = y1;
262     }
263
264   if (x1 < x2)
265     {
266       x_low = x1; 
267       x_hi  = x2;
268     }
269   else
270     {
271       x_low = x2; 
272       x_hi  = x1;
273     }
274
275   if (front)
276     {
277       glReadBuffer(GL_FRONT);
278     }
279   else
280     {
281       glReadBuffer(GL_BACK);
282     }
283
284   data = new unsigned char[(x_hi - x_low + 1)*(y_hi - y_low + 1)*3];
285
286 #ifdef sparc
287   // We need to read the image data one row at a time and convert it
288   // from RGBA to RGB to get around a bug in Sun OpenGL 1.1
289   long    xloop, yloop;
290   unsigned char *buffer;
291   unsigned char *p_data = NULL;
292   
293   buffer = new unsigned char [4*(x_hi - x_low + 1)];
294   p_data = data;
295   for (yloop = y_low; yloop <= y_hi; yloop++)
296     {
297       // read in a row of pixels
298       glReadPixels(x_low,yloop,(x_hi-x_low+1),1,
299                    GL_RGBA, GL_UNSIGNED_BYTE, buffer);
300       for (xloop = 0; xloop <= x_hi-x_low; xloop++)
301         {
302           *p_data = buffer[xloop*4]; p_data++;
303           *p_data = buffer[xloop*4+1]; p_data++;
304           *p_data = buffer[xloop*4+2]; p_data++;
305         }
306     }
307   
308   delete [] buffer;  
309 #else
310   // If the Sun bug is ever fixed, then we could use the following
311   // technique which provides a vast speed improvement on the SGI
312   
313   // Calling pack alignment ensures that we can grab the any size window
314   glPixelStorei( GL_PACK_ALIGNMENT, 1 );
315   glReadPixels(x_low, y_low, x_hi-x_low+1, y_hi-y_low+1, GL_RGB,
316                GL_UNSIGNED_BYTE, data);
317 #endif
318   
319   return data;
320 }
321
322 void VTKViewer_RenderWindow::SetPixelData(int x1, int y1, int x2, int y2,
323                                           unsigned char *data, int front) {
324
325   //
326   // :NOTE: Fri Apr 21 17:00:16 2000 Pagey
327   // This routine is taken directly from vtkOpenGLRenderWindow.cxx. 
328   // I am not sure what it does. Hope it works. 
329   //
330   int     y_low, y_hi;
331   int     x_low, x_hi;
332
333   // set the current window 
334   this->MakeCurrent();
335
336   if (front)
337     {
338       glDrawBuffer(GL_FRONT);
339     }
340   else
341     {
342       glDrawBuffer(GL_BACK);
343     }
344
345   if (y1 < y2)
346     {
347
348       y_low = y1; 
349       y_hi  = y2;
350     }
351   else
352     {
353       y_low = y2; 
354       y_hi  = y1;
355     }
356   
357   if (x1 < x2)
358     {
359       x_low = x1; 
360       x_hi  = x2;
361     }
362   else
363     {
364       x_low = x2; 
365       x_hi  = x1;
366     }
367
368 #ifdef sparc
369   // We need to read the image data one row at a time and convert it
370   // from RGBA to RGB to get around a bug in Sun OpenGL 1.1
371   long    xloop, yloop;
372   unsigned char *buffer;
373   unsigned char *p_data = NULL;
374   
375   buffer = new unsigned char [4*(x_hi - x_low + 1)];
376
377   // now write the binary info one row at a time
378   glDisable(GL_BLEND);
379   p_data = data;
380   for (yloop = y_low; yloop <= y_hi; yloop++)
381     {
382       for (xloop = 0; xloop <= x_hi - x_low; xloop++)
383         {
384           buffer[xloop*4] = *p_data; p_data++;
385           buffer[xloop*4+1] = *p_data; p_data++;
386           buffer[xloop*4+2] = *p_data; p_data++;
387           buffer[xloop*4+3] = 0xff;
388         }
389       /* write out a row of pixels */
390       glMatrixMode( GL_MODELVIEW );
391       glPushMatrix();
392       glLoadIdentity();
393       glMatrixMode( GL_PROJECTION );
394       glPushMatrix();
395       glLoadIdentity();
396       glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1),
397                      (2.0 * (GLfloat)(yloop) / this->Size[1] - 1),
398                      -1.0 );
399       glMatrixMode( GL_PROJECTION );
400       glPopMatrix();
401       glMatrixMode( GL_MODELVIEW );
402       glPopMatrix();
403
404       glDrawPixels((x_hi-x_low+1),1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
405     }
406   glEnable(GL_BLEND);
407 #else
408   // If the Sun bug is ever fixed, then we could use the following
409   // technique which provides a vast speed improvement on the SGI
410   
411   // now write the binary info
412   glMatrixMode( GL_MODELVIEW );
413   glPushMatrix();
414   glLoadIdentity();
415   glMatrixMode( GL_PROJECTION );
416   glPushMatrix();
417   glLoadIdentity();
418   glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1), 
419                  (2.0 * (GLfloat)(y_low) / this->Size[1] - 1),
420                  -1.0 );
421   glMatrixMode( GL_PROJECTION );
422   glPopMatrix();
423   glMatrixMode( GL_MODELVIEW );
424   glPopMatrix();
425
426   glPixelStorei( GL_UNPACK_ALIGNMENT, 1);
427   glDisable(GL_BLEND);
428   glDrawPixels((x_hi-x_low+1), (y_hi - y_low + 1),
429                GL_RGB, GL_UNSIGNED_BYTE, data);
430   glEnable(GL_BLEND);
431 #endif
432 }
433
434 float *VTKViewer_RenderWindow::GetRGBAPixelData(int x1, int y1, int x2, int y2, int front)
435 {
436   //
437   // :NOTE: Fri Apr 21 17:00:16 2000 Pagey
438   // This routine is taken directly from VTKViewer_RenderWindow.cxx. 
439   // I am not sure what it does. Hope it works. 
440   //
441   int     y_low, y_hi;
442   int     x_low, x_hi;
443   int     width, height;
444   float   *data = NULL;
445
446   // set the current window 
447   this->MakeCurrent();
448
449   if (y1 < y2)
450     {
451       y_low = y1; 
452       y_hi  = y2;
453     }
454   else
455     {
456       y_low = y2; 
457       y_hi  = y1;
458     }
459
460   if (x1 < x2)
461     {
462       x_low = x1; 
463       x_hi  = x2;
464     }
465   else
466     {
467       x_low = x2; 
468       x_hi  = x1;
469     }
470
471   if (front)
472     {
473       glReadBuffer(GL_FRONT);
474     }
475   else
476     {
477       glReadBuffer(GL_BACK);
478     }
479
480   width  = abs(x_hi - x_low) + 1;
481   height = abs(y_hi - y_low) + 1;
482
483   data = new float[ (width*height*4) ];
484
485   glReadPixels( x_low, y_low, width, height, GL_RGBA, GL_FLOAT, data);
486
487   return data;
488 }
489
490 void VTKViewer_RenderWindow::SetRGBAPixelData(int x1, int y1, int x2, int y2,
491                                               float *data, int front, int blend)
492 {
493   //
494   // :NOTE: Fri Apr 21 17:00:16 2000 Pagey
495   // This routine is taken directly from VTKViewer_RenderWindow.cxx. 
496   // I am not sure what it does. Hope it works. 
497   //
498   int     y_low, y_hi;
499   int     x_low, x_hi;
500   int     width, height;
501
502   // set the current window 
503   this->MakeCurrent();
504
505   if (front)
506     {
507       glDrawBuffer(GL_FRONT);
508     }
509   else
510     {
511       glDrawBuffer(GL_BACK);
512     }
513
514   if (y1 < y2)
515     {
516       y_low = y1; 
517       y_hi  = y2;
518     }
519   else
520     {
521       y_low = y2; 
522       y_hi  = y1;
523     }
524   
525   if (x1 < x2)
526     {
527       x_low = x1; 
528       x_hi  = x2;
529     }
530   else
531     {
532       x_low = x2; 
533       x_hi  = x1;
534     }
535   
536   width  = abs(x_hi-x_low) + 1;
537   height = abs(y_hi-y_low) + 1;
538
539   /* write out a row of pixels */
540   glMatrixMode( GL_MODELVIEW );
541   glPushMatrix();
542   glLoadIdentity();
543   glMatrixMode( GL_PROJECTION );
544   glPushMatrix();
545   glLoadIdentity();
546   glRasterPos3f( (2.0 * (GLfloat)(x_low) / this->Size[0] - 1), 
547                  (2.0 * (GLfloat)(y_low) / this->Size[1] - 1),
548                  -1.0 );
549   glMatrixMode( GL_PROJECTION );
550   glPopMatrix();
551   glMatrixMode( GL_MODELVIEW );
552   glPopMatrix();
553
554   if (!blend)
555     {
556       glDisable(GL_BLEND);
557       glDrawPixels( width, height, GL_RGBA, GL_FLOAT, data);
558       glEnable(GL_BLEND);
559     }
560   else
561     {
562       glDrawPixels( width, height, GL_RGBA, GL_FLOAT, data);
563     }
564 }
565
566 float *VTKViewer_RenderWindow::GetZbufferData( int x1, int y1, int x2, int y2  )
567 {
568   int             y_low, y_hi;
569   int             x_low, x_hi;
570   int             width, height;
571   float           *z_data = NULL;
572
573   // set the current window 
574   this->MakeCurrent();
575
576   if (y1 < y2)
577     {
578       y_low = y1; 
579       y_hi  = y2;
580     }
581   else
582     {
583       y_low = y2; 
584       y_hi  = y1;
585     }
586
587   if (x1 < x2)
588     {
589       x_low = x1; 
590       x_hi  = x2;
591     }
592   else
593     {
594       x_low = x2; 
595       x_hi  = x1;
596     }
597
598   width =  abs(x2 - x1)+1;
599   height = abs(y2 - y1)+1;
600
601   z_data = new float[width*height];
602
603   glReadPixels( x_low, y_low, 
604                 width, height,
605                 GL_DEPTH_COMPONENT, GL_FLOAT,
606                 z_data );
607
608   return z_data;
609 }
610
611 void VTKViewer_RenderWindow::SetZbufferData( int x1, int y1, int x2, int y2,
612                                              float *buffer )
613 {
614   int             y_low, y_hi;
615   int             x_low, x_hi;
616   int             width, height;
617
618   // set the current window 
619   this->MakeCurrent();
620
621   if (y1 < y2)
622     {
623       y_low = y1; 
624       y_hi  = y2;
625     }
626   else
627     {
628       y_low = y2; 
629       y_hi  = y1;
630     }
631
632   if (x1 < x2)
633     {
634       x_low = x1; 
635       x_hi  = x2;
636     }
637   else
638     {
639       x_low = x2; 
640       x_hi  = x1;
641     }
642
643   width =  abs(x2 - x1)+1;
644   height = abs(y2 - y1)+1;
645
646   glMatrixMode( GL_MODELVIEW );
647   glPushMatrix();
648   glLoadIdentity();
649   glMatrixMode( GL_PROJECTION );
650   glPushMatrix();
651   glLoadIdentity();
652   glRasterPos2f( 2.0 * (GLfloat)(x_low) / this->Size[0] - 1, 
653                  2.0 * (GLfloat)(y_low) / this->Size[1] - 1);
654   glMatrixMode( GL_PROJECTION );
655   glPopMatrix();
656   glMatrixMode( GL_MODELVIEW );
657   glPopMatrix();
658
659   glDrawPixels( width, height, GL_DEPTH_COMPONENT, GL_FLOAT, buffer);
660
661 }
662
663 void VTKViewer_RenderWindow::MakeCurrent() {
664   if( this->mInitialized ) {
665     //const QGLContext* current = this->context()->currentContext();
666     //if(!current)
667     this->makeCurrent();
668   }
669 }
670
671 void VTKViewer_RenderWindow::initializeGL() {
672   if ( ! this->mInitialized ) {
673     //
674     // Construct a format which is similar to the
675     // format set by vtkOpenGLRenderWindow.cxx
676     //
677     QGLFormat myFormat ;
678     if( this->vtkRenderWindow::DoubleBuffer ) {
679       myFormat.setDoubleBuffer(true) ;
680     } else {
681       myFormat.setDoubleBuffer(false) ;
682     }
683     if( this->StereoCapableWindow ) {
684       myFormat.setStereo(true) ;
685     } else {
686       myFormat.setStereo(false) ;
687     }
688     myFormat.setRgba(true) ;
689     myFormat.setDepth(true) ;
690     myFormat.setDirectRendering(true) ;
691
692     setFormat(myFormat) ;
693
694     glClearColor(0.0, 0.0, 0.0, 0.0) ;
695     this->mInitialized = true ;
696
697     setMouseTracking(true);
698   }
699 }
700
701 void VTKViewer_RenderWindow::paintGL() {
702   Render() ;
703 }
704
705 void VTKViewer_RenderWindow::resizeGL(int w, int h) {
706   SetSize(w, h) ;
707 }
708
709 void VTKViewer_RenderWindow::setContext( QGLContext *context, 
710                                          const QGLContext *shareContext, 
711                                          bool deleteOldContex ) {
712   mInitialized = false ;
713   QGLWidget::setContext(context, shareContext, deleteOldContex) ;
714 }
715
716 void VTKViewer_RenderWindow::mouseMoveEvent( QMouseEvent *event ) {
717   emit MouseMove(event) ;
718 }
719
720 void VTKViewer_RenderWindow::mousePressEvent( QMouseEvent *event ) {
721   //NRI - comment rev 1.6 - setFocus() ;
722   //
723   // Emit a ButtonPressed signal for all mouse presses.
724   //
725   emit ButtonPressed(event) ;
726   //
727   // Emit a signal for the button which was pressed.
728   //
729   switch(event->button()) {
730   case LeftButton:
731     emit LeftButtonPressed(event) ;
732     break ;
733   case MidButton:
734     emit MiddleButtonPressed(event) ;
735     break ;
736   case RightButton:
737     if ( event->state() == Qt::ControlButton ) {
738       emit RightButtonPressed(event) ;
739     } else {
740       QPopupMenu* popup = createPopup();
741       if ( popup ) {
742         QAD_Tools::checkPopup( popup );
743         if ( popup->count()>0 ) {
744           popup->exec( QCursor::pos() );
745         }
746         destroyPopup();
747       }
748     }
749     break;
750   default:
751     break ;
752   }
753   return ;
754 }
755
756
757 void VTKViewer_RenderWindow::mouseReleaseEvent( QMouseEvent *event ) {
758   //
759   // Emit a ButtonPressed signal for all mouse releases.
760   //
761   emit ButtonReleased(event) ;
762   //
763   // Emit a signal for the the mouse button which was
764   // released.
765   //
766   switch(event->button()) {
767   case LeftButton:
768     emit LeftButtonReleased(event) ;
769     break ;
770   case MidButton:
771     emit MiddleButtonReleased(event) ;
772     break ;
773   case RightButton:
774     emit RightButtonReleased(event) ;
775     break;
776   default:
777     break ;
778   }
779   return ;
780 }
781
782 void VTKViewer_RenderWindow::keyPressEvent (QKeyEvent * event) {
783   //
784   // Let the interactor handle this.
785   //
786   emit KeyPressed(event) ;
787 }
788
789 /*!
790     Creates the popup 
791 */
792 void VTKViewer_RenderWindow::onCreatePopup() 
793 {
794   if ( myPopup ) {      
795     QAD_Desktop*     Desktop = (QAD_Desktop*) QAD_Application::getDesktop();
796     QAD_Study*   myActiveStudy = Desktop->getActiveStudy();
797     SALOME_Selection*      Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
798     
799     QString theContext;
800     QString theParent("Viewer");
801     QString theObject;
802     
803     Desktop->definePopup( theContext, theParent, theObject );
804     Desktop->createPopup( myPopup, theContext, theParent, theObject);
805     Desktop->customPopup( myPopup, theContext, theParent, theObject );
806
807 //    if (Sel->IObjectCount() == 0 && myPopup->count()<1) {
808     if ( myPopup->count() > 0 )
809       myIDs.append ( myPopup->insertSeparator() );      
810     int id;
811     myIDs.append ( id = myPopup->insertItem (tr ("MEN_VP3D_CHANGEBGR")) );      
812     QAD_ASSERT ( myPopup->connectItem ( id, this, SLOT(onChangeBackgroundColor())) );
813 //    }
814   }
815 }
816
817
818 void VTKViewer_RenderWindow::onChangeBackgroundColor()
819 {
820   float red, green, blue;
821   float backint[3];
822
823   vtkRendererCollection * theRenderers = GetRenderers();
824   theRenderers->InitTraversal();
825   vtkRenderer * theRenderer = theRenderers->GetNextItem();
826   theRenderer->GetBackground(backint);
827
828   QColor selColor = QColorDialog::getColor ( QColor(int(backint[0]*255), int(backint[1]*255), int(backint[2]*255)), NULL );     
829   if ( selColor.isValid() ) {
830     theRenderer->SetBackground( selColor.red()/255., selColor.green()/255., selColor.blue()/255. ); 
831     QAD_CONFIG->addSetting( "VTKViewer:BackgroundColorRed",   selColor.red() );
832     QAD_CONFIG->addSetting( "VTKViewer:BackgroundColorGreen", selColor.green() );
833     QAD_CONFIG->addSetting( "VTKViewer:BackgroundColorBlue",  selColor.blue() );
834   }
835 }