Salome HOME
Porting to DEV version of OpenCASCADE: AIS_InteractiveContext : default value for...
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewModel.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "OCCViewer_ViewModel.h"
24 #include "OCCViewer.h"
25 #include "OCCViewer_ViewWindow.h"
26 #include "OCCViewer_ViewFrame.h"
27 #include "OCCViewer_VService.h"
28 #include "OCCViewer_ViewPort3d.h"
29 #include "OCCViewer_ClippingDlg.h"
30 #include "OCCViewer_Utilities.h"
31
32 #include "SUIT_ViewWindow.h"
33 #include "SUIT_ViewManager.h"
34 #include "SUIT_Desktop.h"
35 #include "SUIT_Session.h"
36 #include "SUIT_ResourceMgr.h"
37
38 #include "ViewerData_AISShape.hxx"
39
40 #include <Basics_OCCTVersion.hxx>
41
42 #include "QtxActionToolMgr.h"
43 #include "QtxBackgroundTool.h"
44
45 #include <QPainter>
46 #include <QApplication>
47 #include <QColorDialog>
48 #include <QFileDialog>
49 #include <QPalette>
50 #include <QKeyEvent>
51 #include <QMenu>
52 #include <QMouseEvent>
53 #include <QToolBar>
54 #include <QDesktopWidget>
55
56 #include <AIS_Axis.hxx>
57 #if OCC_VERSION_LARGE > 0x06080000
58   #include <Prs3d_Drawer.hxx>
59 #else
60   #include <AIS_Drawer.hxx>
61 #endif
62 #include <AIS_ListIteratorOfListOfInteractive.hxx>
63
64 #include <Graphic3d_Texture2Dmanual.hxx>
65 #include <Graphic3d_MaterialAspect.hxx>
66 #include <Graphic3d_TextureParams.hxx>
67
68 #include <Geom_Axis2Placement.hxx>
69 #include <Prs3d_Drawer.hxx>
70 #include <Prs3d_DatumAspect.hxx>
71 #include <Prs3d_LineAspect.hxx>
72 #include <Prs3d_TextAspect.hxx>
73
74 #include <V3d_DirectionalLight.hxx>
75 #include <V3d_AmbientLight.hxx>
76
77 #if OCC_VERSION_MAJOR < 7
78   #include <Visual3d_View.hxx>
79 #endif
80
81 /*!
82   Get data for supported background modes: gradient types, identifiers and supported image formats
83 */
84 QString OCCViewer_Viewer::backgroundData( QStringList& gradList, QIntList& idList, QIntList& txtList )
85 {
86   gradList << tr("GT_HORIZONTALGRADIENT")    << tr("GT_VERTICALGRADIENT")       <<
87               tr("GT_FIRSTDIAGONALGRADIENT") << tr("GT_SECONDDIAGONALGRADIENT") <<
88               tr("GT_FIRSTCORNERGRADIENT")   << tr("GT_SECONDCORNERGRADIENT")   <<
89               tr("GT_THIRDCORNERGRADIENT")   << tr("GT_FORTHCORNERGRADIENT");
90   idList   << HorizontalGradient             << VerticalGradient  <<
91               Diagonal1Gradient              << Diagonal2Gradient <<
92               Corner1Gradient                << Corner2Gradient   <<
93               Corner3Gradient                << Corner4Gradient;
94   txtList  << Qtx::CenterTexture << Qtx::TileTexture << Qtx::StretchTexture;
95   return tr("BG_IMAGE_FILES");
96 }
97
98 /*!
99   Get data for supported stereo pair modes: stereo types and identifiers
100 */
101 void OCCViewer_Viewer::stereoData( QStringList& typeList, QIntList& idList)
102 {
103   typeList << tr("ST_QUADBUFFER")    << tr("ST_ANAGLYPH")         <<
104               tr("ST_ROWINTERLACED") << tr("ST_COLUMNINTERLACED") <<
105               tr("ST_CHESSBOARD")    << tr("ST_SIDEBYSIDE")       <<
106               tr("ST_OVERUNDER");
107   idList   << QuadBufferType    << AnaglyphType         <<
108               RowInterlacedType << ColumnInterlacedType <<
109               ChessBoardType    << SideBySideType       <<
110               OverUnderType;
111 }
112
113 /*!
114   Constructor
115   \param DisplayTrihedron - is trihedron displayed
116 */
117 OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron)
118 : SUIT_ViewModel(),
119   myBackgrounds(4, Qtx::BackgroundData( Qt::black )),
120   myIsRelative(true),
121   myTopLayerId( 0 ),
122   myTrihedronSize(100),
123   myClippingDlg (NULL)
124 {
125   // init CasCade viewers
126   myV3dViewer = OCCViewer_VService::CreateViewer( TCollection_ExtendedString("Viewer3d").ToExtString() );
127   //myV3dViewer->Init(); // to avoid creation of the useless perspective view (see OCCT issue 0024267)
128   setDefaultLights();
129
130   // init selector
131   myAISContext = new AIS_InteractiveContext( myV3dViewer );
132 #if OCC_VERSION_LARGE > 0x07000000
133     
134   const Handle(Graphic3d_HighlightStyle)& sStyle = myAISContext->SelectionStyle();
135   sStyle->SetColor( Quantity_NOC_WHITE ); 
136 #else  
137   myAISContext->SelectionColor( Quantity_NOC_WHITE );
138 #endif  
139   
140   // display isoline on planar faces (box for ex.)
141   myAISContext->IsoOnPlane( true );
142   
143   /* create trihedron */
144   if ( DisplayTrihedron )
145   {
146     Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(gp::XOY());
147     myTrihedron = new AIS_Trihedron(anAxis);
148     myTrihedron->SetInfiniteState( Standard_True );
149
150     Quantity_Color Col(193/255., 205/255., 193/255., Quantity_TOC_RGB);
151     //myTrihedron->SetColor( Col );
152     myTrihedron->SetArrowColor( Col.Name() );
153     myTrihedron->SetSize(100);
154 #if OCC_VERSION_LARGE > 0x06080000
155       Handle(Prs3d_Drawer) drawer = myTrihedron->Attributes();
156       if (drawer->HasOwnDatumAspect()) {
157 #else
158       Handle(AIS_Drawer) drawer = myTrihedron->Attributes();
159       if (drawer->HasDatumAspect()) {
160 #endif
161       Handle(Prs3d_DatumAspect) daspect = drawer->DatumAspect();
162       daspect->FirstAxisAspect()->SetColor(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB));
163       daspect->SecondAxisAspect()->SetColor(Quantity_Color(0.0, 1.0, 0.0, Quantity_TOC_RGB));
164       daspect->ThirdAxisAspect()->SetColor(Quantity_Color(0.0, 0.0, 1.0, Quantity_TOC_RGB));
165     }
166   }
167
168   // set interaction style to standard
169   myInteractionStyle = 0;
170
171   // set zooming style to standard
172   myZoomingStyle = 0;
173
174   // preselection
175   myPreselectionEnabled = true;
176
177   // selection
178   mySelectionEnabled = true;
179   myMultiSelectionEnabled = true;
180
181   // set projection type to orthographic
182   myProjectionType = 0;
183   // set stereo parameters
184   myStereoType = 0;
185   myAnaglyphFilter = 0;
186   myToReverseStereo = 0;
187   myVSyncMode = 1;
188   myQuadBufferSupport = 0;
189   myStereographicFocusType = 1;
190   myInterocularDistanceType = 1;
191   myStereographicFocusValue = 1.0;
192   myInterocularDistanceValue = 0.05;
193   //set clipping color and texture to standard
194   myClippingColor = QColor( 50, 50, 50 );
195   myDefaultTextureUsed = true;
196   myClippingTexture = QString();
197   myTextureModulated = true;
198   myClippingTextureScale = 1.0;
199
200 }
201
202 /*!
203   Destructor
204 */
205 OCCViewer_Viewer::~OCCViewer_Viewer() 
206 {
207   myAISContext.Nullify();
208   myV3dViewer.Nullify();
209 }
210
211 /*!
212   [obsolete]
213   \return background color of viewer
214 */
215 QColor OCCViewer_Viewer::backgroundColor() const
216 {
217   return backgroundColor(0);
218 }
219
220 /*!
221   \return background data of viewer
222 */
223 Qtx::BackgroundData OCCViewer_Viewer::background() const
224 {
225   return background(0);
226 }
227
228 /*!
229   Sets background color [obsolete]
230   \param c - new background color
231 */
232 void OCCViewer_Viewer::setBackgroundColor( const QColor& c )
233 {
234   setBackgroundColor( 0, c );
235 }
236
237 /*!
238   Sets background data
239   \param d - new background data
240 */
241 void OCCViewer_Viewer::setBackground( const Qtx::BackgroundData& theBackground )
242 {
243   setBackground( 0, theBackground );
244 }
245
246 /*!
247   Start initialization of view window
248   \param view - view window to be initialized
249 */
250 void OCCViewer_Viewer::initView( OCCViewer_ViewWindow* view )
251 {
252   if ( view ) {
253     view->initLayout();
254     view->initSketchers();
255     view->setInteractionStyle( interactionStyle() );
256     view->setProjectionType( projectionType() );
257     view->setStereoType( stereoType() );
258     view->setAnaglyphFilter( anaglyphFilter() );
259     view->setStereographicFocus( stereographicFocusType(), stereographicFocusValue() );
260     view->setInterocularDistance( interocularDistanceType(), interocularDistanceValue() );
261     view->setReverseStereo( isReverseStereo() );
262     view->setVSync( isVSync() );
263     view->setQuadBufferSupport( isQuadBufferSupport() );
264     view->setZoomingStyle( zoomingStyle() );
265     view->enablePreselection( isPreselectionEnabled() );
266     view->enableSelection( isSelectionEnabled() );
267
268     OCCViewer_ViewPort3d* vp3d = view->getViewPort();
269     if ( vp3d )
270     {
271 #if OCC_VERSION_LARGE <= 0x07000000
272       vp3d->getView()->SetSurfaceDetail(V3d_TEX_ALL);
273 #endif
274       // connect signal from viewport
275       connect(vp3d, SIGNAL(vpClosed(OCCViewer_ViewPort3d*)), this, SLOT(onViewClosed(OCCViewer_ViewPort3d*)));
276       connect(vp3d, SIGNAL(vpMapped(OCCViewer_ViewPort3d*)), this, SLOT(onViewMapped(OCCViewer_ViewPort3d*)));
277     }
278   }
279 }
280
281 /*!
282   Creates new view window
283   \param theDesktop - main window of application
284 */
285 SUIT_ViewWindow* OCCViewer_Viewer::createView( SUIT_Desktop* theDesktop )
286 {
287   // create view frame
288   OCCViewer_ViewFrame* view = new OCCViewer_ViewFrame(theDesktop, this);
289   // get main view window (created by view frame)
290   OCCViewer_ViewWindow* vw = view->getView(OCCViewer_ViewFrame::MAIN_VIEW);
291   // initialize main view window
292   initView( vw );
293   // set default background for view window
294   vw->setBackground( background(0) ); // 0 means MAIN_VIEW (other views are not yet created here)
295
296   return view;
297 }
298
299 /*!
300   Sets new view manager
301   \param theViewManager - new view manager
302 */
303 void OCCViewer_Viewer::setViewManager(SUIT_ViewManager* theViewManager)
304 {
305   SUIT_ViewModel::setViewManager(theViewManager);
306   if (theViewManager) {
307     connect(theViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
308             this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
309
310     connect(theViewManager, SIGNAL(mouseMove(SUIT_ViewWindow*, QMouseEvent*)), 
311             this, SLOT(onMouseMove(SUIT_ViewWindow*, QMouseEvent*)));
312
313     connect(theViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), 
314             this, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));
315
316     connect(theViewManager, SIGNAL(keyPress(SUIT_ViewWindow*, QKeyEvent*)), 
317             this, SLOT(onKeyPress(SUIT_ViewWindow*, QKeyEvent*)));
318   }
319 }
320
321 /*!
322   SLOT: called on mouse button press, stores current mouse position as start point for transformations
323 */
324 void OCCViewer_Viewer::onMousePress(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
325 {
326   myStartPnt.setX(theEvent->x()); myStartPnt.setY(theEvent->y());
327 }
328
329 /*!
330   SLOT: called on mouse move, processes transformation or hilighting
331 */
332 void OCCViewer_Viewer::onMouseMove(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
333 {
334   if (!mySelectionEnabled) return;
335   if (!theWindow->inherits("OCCViewer_ViewWindow")) return;
336
337   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow;
338
339   myCurPnt.setX(theEvent->x()); myCurPnt.setY(theEvent->y());
340
341   if ( isSelectionEnabled() && isPreselectionEnabled() ) {
342     if (aView->getViewPort()->isBusy()) {
343       QCoreApplication::processEvents();
344       return; // Check that the ViewPort initialization completed
345                                                 // To Prevent call move event if the View port is not initialized
346                                                 // IPAL 20883
347     }
348     Handle(V3d_View) aView3d = aView->getViewPort()->getView();
349     if ( !aView3d.IsNull() ) {
350       myAISContext->MoveTo( theEvent->x(), theEvent->y(), aView3d, Standard_True );
351     }
352   }
353 }
354
355
356 /*!
357   SLOT: called on mouse button release, finishes transformation or selection
358 */
359 void OCCViewer_Viewer::onMouseRelease(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
360 {
361   if (!mySelectionEnabled) return;
362   if (theEvent->button() != Qt::LeftButton) return;
363   if (!theWindow->inherits("OCCViewer_ViewWindow")) return;
364
365   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow;
366   if (!aView )
367     return;
368
369   myEndPnt.setX(theEvent->x()); myEndPnt.setY(theEvent->y());
370   bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
371   
372   if (!aHasShift) {
373     myAISContext->ClearCurrents( false );
374     emit deselection();
375   }
376
377   if (myStartPnt == myEndPnt)
378   {
379     if ( !isPreselectionEnabled() ) {
380       Handle(V3d_View) aView3d = aView->getViewPort()->getView();
381       if ( !aView3d.IsNull() ) {
382         myAISContext->MoveTo( myEndPnt.x(), myEndPnt.y(), aView3d, Standard_True );
383       }
384     }
385
386     if (aHasShift && myMultiSelectionEnabled)
387       myAISContext->ShiftSelect( Standard_True );
388     else 
389       myAISContext->Select( Standard_True );
390   }
391   else
392   {
393     if (aHasShift && myMultiSelectionEnabled)
394       myAISContext->ShiftSelect(myStartPnt.x(), myStartPnt.y(),
395                                 myEndPnt.x(), myEndPnt.y(),
396                                 aView->getViewPort()->getView(), Standard_False );
397     else
398       myAISContext->Select(myStartPnt.x(), myStartPnt.y(),
399                            myEndPnt.x(), myEndPnt.y(),
400                            aView->getViewPort()->getView(), Standard_False );
401
402     int Nb = myAISContext->NbSelected();
403     if( Nb>1 && !myMultiSelectionEnabled )
404     {
405         myAISContext->InitSelected();
406         Handle( SelectMgr_EntityOwner ) anOwner = myAISContext->SelectedOwner();
407         if( !anOwner.IsNull() )
408         {
409             myAISContext->ClearSelected( Standard_False );
410             myAISContext->AddOrRemoveSelected( anOwner, Standard_False );
411         }
412     }
413
414     myAISContext->UpdateCurrentViewer();
415   }
416   emit selectionChanged();
417 }
418
419 /*!
420   SLOT: called on key press, processes selection in "key free" interaction style
421 */
422 void OCCViewer_Viewer::onKeyPress(SUIT_ViewWindow* theWindow, QKeyEvent* theEvent)
423 {
424   if (!mySelectionEnabled) return;
425
426   OCCViewer_ViewWindow* aView = qobject_cast<OCCViewer_ViewWindow*>( theWindow );
427   if ( !aView ) return;
428
429   bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
430
431   switch ( theEvent->key() ) {
432   case  Qt::Key_S:
433     if (!aHasShift) {
434       myAISContext->ClearCurrents( false );
435       emit deselection();
436     }
437
438     if ( !isPreselectionEnabled() ) {
439       Handle(V3d_View) aView3d = aView->getViewPort()->getView();
440       if ( !aView3d.IsNull() ) {
441         myAISContext->MoveTo(myCurPnt.x(), myCurPnt.y(), aView3d, Standard_True );
442       }
443     }
444
445     if (aHasShift && myMultiSelectionEnabled)
446       myAISContext->ShiftSelect( Standard_True );
447     else
448       myAISContext->Select( Standard_True );
449
450     emit selectionChanged();
451
452     break;
453   case  Qt::Key_N:
454     if ( isPreselectionEnabled() ) {
455       if ( getAISContext()->HasOpenedContext() )
456         getAISContext()->HilightNextDetected( aView->getViewPort()->getView() );
457     }
458     break;
459   case  Qt::Key_P:
460     if ( isPreselectionEnabled() ) {
461       if ( getAISContext()->HasOpenedContext() )
462         getAISContext()->HilightPreviousDetected( aView->getViewPort()->getView() );
463     }
464     break;
465   default:
466     break;
467   }
468 }
469
470 void OCCViewer_Viewer::onViewClosed(OCCViewer_ViewPort3d*)
471 {
472   Standard_Integer aViewsNb = 0;
473   for ( myV3dViewer->InitActiveViews(); myV3dViewer->MoreActiveViews(); myV3dViewer->NextActiveViews())
474     ++aViewsNb;
475   if ( aViewsNb < 2 ) {
476     //clean up presentations before last view is closed
477     myAISContext->RemoveAll(Standard_False);
478   }
479 }
480
481 void OCCViewer_Viewer::onViewMapped(OCCViewer_ViewPort3d* viewPort)
482 {
483   setTrihedronShown( true );
484   bool showStaticTrihedron = true;
485   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
486   if ( resMgr ) showStaticTrihedron = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true );
487   viewPort->showStaticTrihedron( showStaticTrihedron );
488 }
489
490 int OCCViewer_Viewer::getTopLayerId()
491 {
492   if ( myTopLayerId == 0 && !myAISContext->CurrentViewer().IsNull() )    
493     myAISContext->CurrentViewer()->AddZLayer( myTopLayerId );
494
495   return myTopLayerId;
496 }
497
498 /*!
499   \return interaction style
500 */
501 int OCCViewer_Viewer::interactionStyle() const
502 {
503   return myInteractionStyle;
504 }
505
506 /*!
507   Sets interaction style: 0 - standard, 1 - keyboard free interaction
508   \param theStyle - new interaction style
509 */
510 void OCCViewer_Viewer::setInteractionStyle( const int theStyle )
511 {
512   myInteractionStyle = theStyle;
513   //!! To be done for view windows
514   if ( !myViewManager )
515     return;
516
517   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
518   for ( int i = 0; i < (int)wins.count(); i++ )
519   {
520     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
521     if ( win )
522       win->setInteractionStyle( theStyle );
523   }
524 }
525
526 /*!
527   \return projection type
528 */
529 int OCCViewer_Viewer::projectionType() const
530 {
531   return myProjectionType;
532 }
533
534 /*!
535   Sets projection type: 0 - orthographic, 1 - perspective
536   \param theType - new projection type
537 */
538 void OCCViewer_Viewer::setProjectionType( const int theType )
539 {
540   if ( myProjectionType != theType ) {
541     if ( theType != OCCViewer_ViewWindow::Stereo )
542       myProjectionType = theType;
543
544     if ( !myViewManager )
545       return;
546
547     QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
548     for ( int i = 0; i < (int)wins.count(); i++ )
549     {
550       OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
551       if ( win )
552         win->setProjectionType( (OCCViewer_ViewWindow::ProjectionType)theType );
553     }
554   }
555 }
556
557 /*!
558   \return stereo type
559 */
560 int OCCViewer_Viewer::stereoType() const
561 {
562   return myStereoType;
563 }
564
565 /*!
566   Sets stereo type
567   \param theType - new stereo type
568 */
569 void OCCViewer_Viewer::setStereoType( const int theType )
570 {
571   myStereoType = theType;
572
573   if ( !myViewManager )
574     return;
575
576   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
577   for ( int i = 0; i < (int)wins.count(); i++ )
578   {
579     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
580     if ( win )
581       win->setStereoType( (OCCViewer_ViewWindow::StereoType)theType );
582   }
583 }
584
585 /*!
586   \return stereographic focus type
587 */
588 int OCCViewer_Viewer::stereographicFocusType() const
589 {
590   return myStereographicFocusType;
591 }
592
593 /*!
594   \return stereographic focus value
595 */
596 double OCCViewer_Viewer::stereographicFocusValue() const
597 {
598   return myStereographicFocusValue;
599 }
600
601 /*!
602   Sets stereographic focus parameters
603   \param theType - new stereographic focus type
604   \param theValue - new stereographic focus value
605 */
606 void OCCViewer_Viewer::setStereographicFocus( const int theType, const double theValue )
607 {
608   myStereographicFocusType = theType;
609   myStereographicFocusValue = theValue;
610
611   if ( !myViewManager )
612     return;
613
614   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
615   for ( int i = 0; i < (int)wins.count(); i++ )
616   {
617     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
618     if ( win )
619       win->setStereographicFocus( (OCCViewer_ViewWindow::FocusIODType)theType, theValue );
620   }
621 }
622
623 /*!
624   \return stereographic focus type
625 */
626 int OCCViewer_Viewer::interocularDistanceType() const
627 {
628   return myInterocularDistanceType;
629 }
630
631 /*!
632   \return stereographic focus value
633 */
634 double OCCViewer_Viewer::interocularDistanceValue() const
635 {
636   return myInterocularDistanceValue;
637 }
638
639 /*!
640   Sets interocular distance parameters
641   \param theType - new IOD type
642   \param theValue - new IOD value
643 */
644 void OCCViewer_Viewer::setInterocularDistance( const int theType, const double theValue )
645 {
646   myInterocularDistanceType = theType;
647   myInterocularDistanceValue = theValue;
648
649   if ( !myViewManager )
650     return;
651
652   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
653   for ( int i = 0; i < (int)wins.count(); i++ )
654   {
655     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
656     if ( win )
657       win->setInterocularDistance( (OCCViewer_ViewWindow::FocusIODType)theType, theValue );
658   }
659 }
660
661 /*!
662   \return anaglyph filter
663 */
664 int OCCViewer_Viewer::anaglyphFilter() const
665 {
666   return myAnaglyphFilter;
667 }
668
669 /*!
670   Sets anaglyph filter
671   \param theType - new anaglyph filter
672 */
673 void OCCViewer_Viewer::setAnaglyphFilter( const int theType )
674 {
675   myAnaglyphFilter = theType;
676
677   if ( !myViewManager )
678     return;
679
680   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
681   for ( int i = 0; i < (int)wins.count(); i++ )
682   {
683     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
684     if ( win )
685       win->setAnaglyphFilter( (OCCViewer_ViewWindow::AnaglyphFilter)theType );
686   }
687 }
688
689 /*!
690   \return reverse stereo
691 */
692 bool OCCViewer_Viewer::isReverseStereo() const
693 {
694   return myToReverseStereo;
695 }
696
697 /*!
698   Sets reverse stereo
699   \param theReverse - enable/disable reverse mode
700 */
701 void OCCViewer_Viewer::setReverseStereo( const bool theReverse )
702 {
703   myToReverseStereo = theReverse;
704
705   if ( !myViewManager )
706     return;
707
708   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
709   for ( int i = 0; i < (int)wins.count(); i++ )
710   {
711     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
712     if ( win )
713       win->setReverseStereo( theReverse );
714   }
715 }
716
717 /*!
718   \return V-Sync mode
719 */
720 bool OCCViewer_Viewer::isVSync() const
721 {
722   return myVSyncMode;
723 }
724
725 /*!
726   Set V-Sync mode
727   \param theEnable - enable/disable V-Sync mode
728 */
729 void OCCViewer_Viewer::setVSync( const bool theEnable )
730 {
731   myVSyncMode = theEnable;
732
733   if ( !myViewManager )
734     return;
735
736   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
737   for ( int i = 0; i < (int)wins.count(); i++ )
738   {
739     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
740     if ( win )
741       win->setVSync( theEnable );
742   }
743 }
744
745 /*!
746   \return support quad-buffered stereo
747 */
748 bool OCCViewer_Viewer::isQuadBufferSupport() const
749 {
750   return myQuadBufferSupport;
751 }
752
753 /*!
754   Set support quad-buffered stereo
755   \param theEnable - enable/disable support quad-buffered stereo
756 */
757 void OCCViewer_Viewer::setQuadBufferSupport( const bool theEnable )
758 {
759   myQuadBufferSupport = theEnable;
760
761   if ( !myViewManager )
762     return;
763
764   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
765   for ( int i = 0; i < (int)wins.count(); i++ )
766   {
767     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
768     if ( win )
769       win->setQuadBufferSupport( theEnable );
770   }
771 }
772
773 /*!
774   \return zooming style
775 */
776 int OCCViewer_Viewer::zoomingStyle() const
777 {
778   return myZoomingStyle;
779 }
780
781 /*!
782   Sets zooming style: 0 - standard, 1 - advanced (at cursor)
783   \param theStyle - new zooming style
784 */
785 void OCCViewer_Viewer::setZoomingStyle( const int theStyle )
786 {
787   myZoomingStyle = theStyle;
788   //!! To be done for view windows
789   if ( !myViewManager )
790     return;
791
792   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
793   for ( int i = 0; i < (int)wins.count(); i++ )
794   {
795     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
796     if ( win )
797       win->setZoomingStyle( theStyle );
798   }
799 }
800
801 /*!
802   \return true if preselection is enabled
803 */
804 bool OCCViewer_Viewer::isPreselectionEnabled() const 
805
806   return myPreselectionEnabled; 
807 }
808
809 /*!
810   Enables/disables preselection
811   \param isEnabled - new status
812 */
813 void OCCViewer_Viewer::enablePreselection(bool isEnabled)
814 {
815   myPreselectionEnabled = isEnabled;
816
817   if ( !myViewManager )
818     return;
819
820   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
821   for ( int i = 0; i < (int)wins.count(); i++ )
822   {
823     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
824     if ( win ) {
825       win->enablePreselection( isEnabled );
826     }
827   }
828 }
829
830 /*!
831   \return true if selection is enabled
832 */
833 bool OCCViewer_Viewer::isSelectionEnabled() const 
834
835   return mySelectionEnabled; 
836 }
837
838 /*!
839   Enables/disables selection
840   \param isEnabled - new status
841 */
842 void OCCViewer_Viewer::enableSelection(bool isEnabled)
843 {
844   mySelectionEnabled = isEnabled;
845
846   //!! To be done for view windows
847   if ( !myViewManager )
848     return;
849
850   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
851   for ( int i = 0; i < (int)wins.count(); i++ )
852   {
853     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
854     if ( win ) {
855       win->updateEnabledDrawMode();
856       win->enableSelection( isEnabled );
857     }
858   }
859
860   
861   //clear current selection in the viewer
862   if(!isEnabled) {
863     myAISContext->ClearSelected( Standard_True );
864   }
865
866 }
867
868 /*!
869   Sets multiselection enabled status
870   \param isEnabled - new status
871 */
872 void OCCViewer_Viewer::enableMultiselection(bool isEnable)
873 {
874   myMultiSelectionEnabled = isEnable;
875   //!! To be done for view windows
876   if ( !myViewManager )
877     return;
878
879   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
880   for ( int i = 0; i < (int)wins.count(); i++ )
881   {
882     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
883     if ( win )
884       win->updateEnabledDrawMode();
885   }
886 }
887
888 /*!
889   Sets a color of the clipped region
890   \param theColor - a new color of the clipped region
891 */
892 void OCCViewer_Viewer::setClippingColor( const QColor& theColor )
893 {
894   myClippingColor = theColor;
895
896   if( myInternalClipPlanes.IsEmpty() )
897     return;
898
899   Graphic3d_MaterialAspect aMaterialAspect = Graphic3d_MaterialAspect();
900   aMaterialAspect.SetColor( Quantity_Color( theColor.redF(), theColor.greenF(),
901                                             theColor.blueF(), Quantity_TOC_RGB ) );
902
903   for( int i = 1; i <= myInternalClipPlanes.Size(); i++ )
904     myInternalClipPlanes.Value(i)->SetCappingMaterial( aMaterialAspect );
905
906   update();
907 }
908
909 /*!
910   \return clipping color
911 */
912 QColor OCCViewer_Viewer::clippingColor() const
913 {
914   return myClippingColor;
915 }
916
917 // initialize a texture for clipped region
918 Handle(Graphic3d_Texture2Dmanual) initClippingTexture( const bool isDefault, const QString& theTexture,
919                                                        const bool isModulate, const double theScale )
920 {
921   QString aTextureFile = isDefault ? ":images/hatch.png" : theTexture;
922   QPixmap px( aTextureFile );
923   const Handle(Image_PixMap) aPixmap = OCCViewer_Utilities::imageToPixmap( px.toImage() );
924   Handle(Graphic3d_Texture2Dmanual) aTexture = new Graphic3d_Texture2Dmanual( aPixmap );
925   if( aTexture->IsDone() ) {
926     aTexture->EnableRepeat();
927     isModulate ? aTexture->EnableModulate() : aTexture->DisableModulate();
928     aTexture->GetParams()->SetScale( Graphic3d_Vec2( 1/( theScale*100 ), -1 / ( theScale*100 ) ) );
929   }
930   return aTexture;
931 }
932
933 /*!
934   Sets default texture parameters
935   \param isDefault - use/non-use default texture
936   \param theTexture - new texture of the clipped region
937   \param isModulate - enable/disable texture modulate mode
938   \param theScale - scale factor.
939 */
940 void OCCViewer_Viewer::setClippingTextureParams( const bool isDefault, const QString& theTexture,
941                                                  const bool isModulate, const double theScale )
942 {
943   myDefaultTextureUsed = isDefault;
944   myClippingTexture = theTexture;
945   myTextureModulated = isModulate;
946   myClippingTextureScale = theScale;
947
948   if( myInternalClipPlanes.IsEmpty() )
949     return;
950
951   Handle(Graphic3d_Texture2Dmanual) aTexture =
952     initClippingTexture( myDefaultTextureUsed, myClippingTexture,
953                          myTextureModulated, myClippingTextureScale );
954
955   for( int i = 1; i <= myInternalClipPlanes.Size(); i++ )
956     myInternalClipPlanes.Value(i)->SetCappingTexture( aTexture );
957
958   update();
959 }
960
961 /*!
962   \return true if default texture is used
963 */
964 bool OCCViewer_Viewer::isDefaultTextureUsed() const
965 {
966   return myDefaultTextureUsed;
967 }
968
969 /*!
970   \return clipping texture
971 */
972 QString OCCViewer_Viewer::clippingTexture() const
973 {
974   return myClippingTexture;
975 }
976
977 /*!
978   \return true if texture is modulated
979 */
980 bool OCCViewer_Viewer::isTextureModulated() const
981 {
982   return myTextureModulated;
983 }
984
985 /*!
986   \return scale factor of texture
987 */
988 double OCCViewer_Viewer::clippingTextureScale() const
989 {
990   return myClippingTextureScale;
991 }
992
993 /*!
994   Builds popup for occ viewer
995 */
996 void OCCViewer_Viewer::contextMenuPopup(QMenu* thePopup)
997 {
998   thePopup->addAction( tr( "MEN_DUMP_VIEW" ), this, SLOT( onDumpView() ) );
999   thePopup->addAction( tr( "MEN_CHANGE_BACKGROUND" ), this, SLOT( onChangeBackground() ) );
1000
1001   thePopup->addSeparator();
1002
1003   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
1004
1005   //Support of several toolbars in the popup menu
1006   QList<QToolBar*> lst = aView->findChildren<QToolBar*>();
1007   QList<QToolBar*>::const_iterator it = lst.begin(), last = lst.end();
1008   for ( ; it!=last; it++ ) {
1009     if ( (*it)->parentWidget()->isVisible() )
1010       thePopup->addAction( (*it)->toggleViewAction() );
1011   }
1012 }
1013
1014 /*!
1015   SLOT: called on dump view operation is activated, stores scene to raster file
1016 */
1017 void OCCViewer_Viewer::onDumpView()
1018 {
1019   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
1020   if ( aView )
1021     aView->onDumpView();
1022 }
1023
1024 /*!
1025   SLOT: called if background color is to be changed changed, passes new color to view port
1026 */
1027 void OCCViewer_Viewer::onChangeBackground()
1028 {
1029   OCCViewer_ViewWindow* aView = dynamic_cast<OCCViewer_ViewWindow*>(myViewManager->getActiveView());
1030   if ( !aView )
1031     return;
1032
1033   // get supported gradient types
1034   QStringList gradList;
1035   QIntList    idList, txtList;
1036   QString     formats = backgroundData( gradList, idList, txtList );
1037
1038   // invoke dialog box
1039   Qtx::BackgroundData bgData = QtxBackgroundDialog::getBackground( aView->background(),  // initial background
1040                                                                    aView,                // parent for dialog box
1041                                                                    txtList,              // allowed texture modes
1042                                                                    true,                 // enable solid color mode
1043                                                                    true,                 // enable gradient mode
1044                                                                    false,                // disable custom gradient mode
1045                                                                    !txtList.isEmpty(),   // enable/disable texture mode
1046                                                                    gradList,             // gradient names
1047                                                                    idList,               // gradient identifiers
1048                                                                    formats );            // image formats
1049
1050   // set chosen background data to the viewer
1051   if ( bgData.isValid() )
1052     aView->setBackground( bgData );
1053 }
1054
1055 /*!
1056   Updates OCC 3D viewer
1057 */
1058 void OCCViewer_Viewer::update()
1059 {
1060   if (!myV3dViewer.IsNull())
1061     myV3dViewer->Update();
1062
1063   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
1064   if ( aView )
1065     aView->updateGravityCoords();
1066 }
1067
1068 /*!
1069   \return objects selected in 3D viewer
1070   \param theList - list to be filled with selected objects
1071 */
1072 void OCCViewer_Viewer::getSelectedObjects(AIS_ListOfInteractive& theList)
1073 {
1074   theList.Clear();
1075   for (myAISContext->InitSelected(); myAISContext->MoreSelected(); myAISContext->NextSelected())
1076     theList.Append(myAISContext->SelectedInteractive());
1077 }
1078
1079 /*!
1080   Selects objects in 3D viewer. Other selected objects are left as selected
1081   \param theList - list objects to be selected
1082 */
1083 void OCCViewer_Viewer::setObjectsSelected(const AIS_ListOfInteractive& theList)
1084 {
1085   AIS_ListIteratorOfListOfInteractive aIt;
1086   for (aIt.Initialize(theList); aIt.More(); aIt.Next())
1087     myAISContext->AddOrRemoveSelected(aIt.Value(), false);
1088   myAISContext->UpdateCurrentViewer();
1089 }
1090
1091 /*!
1092   Auxiliary method to emit signal selectionChanged()
1093 */
1094 void OCCViewer_Viewer::performSelectionChanged()
1095 {
1096     emit selectionChanged();
1097 }
1098
1099 /*
1100  * Defines default lights
1101  */
1102 void OCCViewer_Viewer::setDefaultLights()
1103 {
1104   // clear all light sources
1105   myV3dViewer->InitDefinedLights();
1106   while ( myV3dViewer->MoreDefinedLights() )
1107   {
1108     myV3dViewer->DelLight( myV3dViewer->DefinedLight() );
1109     myV3dViewer->InitDefinedLights();
1110   }
1111
1112   // get light source parameters from preferences
1113   QColor aColor = SUIT_Session::session()->resourceMgr()->colorValue( "OCCViewer", "light_color", QColor( 0, 0, 0 ) );
1114   double aDx = SUIT_Session::session()->resourceMgr()->doubleValue( "OCCViewer", "light_dx", 0.0 );
1115   double aDy = SUIT_Session::session()->resourceMgr()->doubleValue( "OCCViewer", "light_dy", 0.0 );
1116   double aDz = SUIT_Session::session()->resourceMgr()->doubleValue( "OCCViewer", "light_dz", -1.0 );
1117
1118   Handle(V3d_DirectionalLight) aLight =
1119     new V3d_DirectionalLight( myV3dViewer, V3d_Zneg, OCCViewer::color( aColor ).Name(), Standard_True );
1120   if( !( aDx == 0 && aDy == 0 && aDz == 0 ) )
1121     aLight->SetDirection( aDx, aDy, aDz );
1122   myV3dViewer->SetLightOn( aLight );
1123   myV3dViewer->SetLightOn( new V3d_AmbientLight( myV3dViewer ) );
1124 }
1125
1126 /*!
1127   Hilights/unhilights object in viewer
1128   \param obj - object to be updated
1129   \param hilight - if it is true, object will be hilighted, otherwise it will be unhilighted
1130   \param update - update current viewer
1131 */
1132 bool OCCViewer_Viewer::highlight( const Handle(AIS_InteractiveObject)& obj,
1133                                   bool hilight, bool update )
1134 {
1135   bool isInLocal = myAISContext->HasOpenedContext();
1136   if( !obj.IsNull() )
1137     if( !isInLocal )
1138     {
1139       if ( hilight && !myAISContext->IsSelected( obj ) )
1140         myAISContext->AddOrRemoveCurrentObject( obj, false );
1141       else if ( !hilight && myAISContext->IsSelected( obj ) )
1142         myAISContext->AddOrRemoveCurrentObject( obj, false );
1143     }
1144
1145   if ( update )
1146     myV3dViewer->Redraw();
1147     
1148   return false;
1149 }
1150
1151 /*!
1152   Unhilights all objects in viewer
1153   \param updateviewer - update current viewer
1154 */
1155 bool OCCViewer_Viewer::unHighlightAll( bool updateviewer, bool unselect )
1156 {
1157   if ( myAISContext->HasOpenedContext() ) {
1158     if ( unselect ) {
1159       myAISContext->ClearSelected( updateviewer );
1160     } else {
1161       myAISContext->UnhilightSelected( updateviewer );
1162     }
1163   } else {
1164     if ( unselect ) {
1165       myAISContext->ClearCurrents( updateviewer );
1166     } else {
1167       myAISContext->UnhilightCurrents( updateviewer );
1168     }
1169   }
1170
1171   return false;
1172 }
1173
1174 /*!
1175   \return true if object is in viewer or in collector
1176   \param obj - object to be checked
1177   \param onlyInViewer - search object only in viewer (so object must be displayed)
1178 */
1179 bool OCCViewer_Viewer::isInViewer( const Handle(AIS_InteractiveObject)& obj,
1180                                    bool onlyInViewer )
1181 {
1182   AIS_ListOfInteractive List;
1183   myAISContext->DisplayedObjects(List);
1184
1185   AIS_ListIteratorOfListOfInteractive ite(List);
1186   for ( ; ite.More(); ite.Next() )
1187     if( ite.Value()==obj )
1188       return true;
1189
1190   return false;
1191 }
1192
1193 /*!
1194   \return true if object is displayed in viewer
1195   \param obj - object to be checked
1196 */
1197 bool OCCViewer_Viewer::isVisible( const Handle(AIS_InteractiveObject)& obj )
1198 {
1199   return myAISContext->IsDisplayed( obj );
1200 }
1201
1202 /*!
1203   Sets color of object
1204   \param obj - object to be updated
1205   \param color - new color
1206   \param update - update current viewer
1207 */
1208 void OCCViewer_Viewer::setColor( const Handle(AIS_InteractiveObject)& obj,
1209                                  const QColor& color,
1210                                  bool update )
1211 {
1212   if( !obj.IsNull() )
1213   {
1214     Quantity_Color CSFColor = Quantity_Color ( color.red() / 255.,
1215                                                color.green() / 255.,
1216                                                color.blue() / 255.,
1217                                                Quantity_TOC_RGB );
1218     obj->SetColor( CSFColor );
1219   }
1220
1221   if( update )
1222     myV3dViewer->Update();
1223 }
1224
1225 /*!
1226   Changes display mode of object
1227   \param obj - object to be processed
1228   \param mode - new display mode
1229   \param update - update current viewer
1230 */
1231 void OCCViewer_Viewer::switchRepresentation( const Handle(AIS_InteractiveObject)& obj,
1232                                              int mode, bool update )
1233 {
1234   myAISContext->SetDisplayMode( obj, (Standard_Integer)mode, update );
1235   if( update )
1236     myV3dViewer->Update();
1237 }
1238
1239 /*!
1240   Changes transparency of object
1241   \param obj - object to be processed
1242   \param trans - new transparency
1243   \param update - update current viewer
1244 */
1245 void OCCViewer_Viewer::setTransparency( const Handle(AIS_InteractiveObject)& obj,
1246                                         float trans, bool update )
1247 {
1248   myAISContext->SetTransparency( obj, trans, false );
1249   myAISContext->Redisplay( obj, Standard_False, Standard_True );
1250   if( update )
1251     myV3dViewer->Update();
1252 }
1253
1254 /*!
1255   Changes visibility of trihedron to opposite
1256 */
1257 void OCCViewer_Viewer::toggleTrihedron()
1258 {
1259   setTrihedronShown( !isTrihedronVisible() );
1260 }
1261
1262 /*!
1263   \return true if trihedron is visible
1264 */
1265 bool OCCViewer_Viewer::isTrihedronVisible() const
1266 {
1267   return !myTrihedron.IsNull() && !myAISContext.IsNull() && myAISContext->IsDisplayed( myTrihedron );
1268 }
1269
1270 /*!
1271   Sets visibility state of trihedron
1272   \param on - new state
1273 */
1274
1275 void OCCViewer_Viewer::setTrihedronShown( const bool on )
1276 {
1277   if ( myTrihedron.IsNull() )
1278     return;
1279
1280   if ( on ) {
1281     myAISContext->Display( myTrihedron,
1282                            0 /*wireframe*/,
1283                            -1 /* selection mode */,
1284                            Standard_True /* update viewer*/,
1285                            Standard_False /* allow decomposition */,
1286                            AIS_DS_Displayed /* display status */);
1287     myAISContext->Deactivate( myTrihedron );
1288   }
1289   else {
1290     myAISContext->Erase( myTrihedron , Standard_True );
1291   }
1292 }
1293
1294 /*!
1295   \return trihedron size
1296 */
1297 double OCCViewer_Viewer::trihedronSize() const
1298 {
1299   double sz = 0;
1300   if ( !myTrihedron.IsNull() )
1301     sz = myTrihedron->Size();
1302   return sz;
1303 }
1304
1305 /*!
1306   Changes trihedron size
1307   \param sz - new size
1308 */
1309 void OCCViewer_Viewer::setTrihedronSize( const double sz, bool isRelative )
1310 {
1311   if ( myTrihedronSize != sz || isRelative != myIsRelative) {
1312     myTrihedronSize = sz; 
1313     myIsRelative = isRelative;
1314     updateTrihedron();
1315   }
1316 }
1317
1318 /*!
1319   Set number of isolines
1320   \param u - u-isolines (first parametric co-ordinate)
1321   \param v - v-isolines (second parametric co-ordinate)
1322 */
1323 void OCCViewer_Viewer::setIsos( const int u, const int v )
1324 {
1325   Handle(AIS_InteractiveContext) ic = getAISContext();
1326   if ( ic.IsNull() )
1327   return;
1328
1329   ic->SetIsoNumber( u, AIS_TOI_IsoU );
1330   ic->SetIsoNumber( v, AIS_TOI_IsoV );
1331 }
1332
1333 /*!
1334   \return number of isolines
1335   \param u - to return u-isolines (first parametric co-ordinate)
1336   \param v - to return v-isolines (second parametric co-ordinate)
1337 */
1338 void OCCViewer_Viewer::isos( int& u, int& v ) const
1339 {
1340   Handle(AIS_InteractiveContext) ic = getAISContext();
1341   if ( !ic.IsNull() )
1342   {
1343     u = ic->IsoNumber( AIS_TOI_IsoU );
1344     v = ic->IsoNumber( AIS_TOI_IsoV );
1345   }
1346 }
1347
1348 /* 
1349  * Returns a new OCCViewer_ViewWindow instance which will be placed as a sub window in ViewFrame
1350  */
1351 OCCViewer_ViewWindow* OCCViewer_Viewer::createSubWindow()
1352 {
1353   return new OCCViewer_ViewWindow(0,  this);
1354 }
1355
1356 // obsolete  
1357 QColor OCCViewer_Viewer::backgroundColor( int theViewId ) const
1358 {
1359   return background( theViewId ).color();
1360 }
1361
1362 Qtx::BackgroundData OCCViewer_Viewer::background( int theViewId ) const
1363 {
1364   return ( theViewId >= 0 && theViewId < myBackgrounds.count() ) ? myBackgrounds[theViewId] : Qtx::BackgroundData();
1365 }
1366
1367 // obsolete
1368 void OCCViewer_Viewer::setBackgroundColor( int theViewId, const QColor& theColor )
1369 {
1370   if ( theColor.isValid() ) {
1371     Qtx::BackgroundData bg = background( theViewId );
1372     bg.setColor( theColor );
1373     setBackground( theViewId, bg );
1374   }
1375 }
1376
1377 void OCCViewer_Viewer::setBackground( int theViewId, const Qtx::BackgroundData& theBackground )
1378 {
1379   if ( theBackground.isValid() && theViewId >= 0 && theViewId < myBackgrounds.count() )
1380     myBackgrounds[theViewId] = theBackground;    
1381 }
1382
1383
1384 /*!
1385   Set the show static trihedron flag
1386 */
1387 void OCCViewer_Viewer::setStaticTrihedronDisplayed(const bool on)
1388 {
1389   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
1390   if ( aView ) aView->showStaticTrihedron( on );
1391 }
1392
1393 /*!
1394   Get new and current trihedron size corresponding to the current model size
1395 */
1396 bool OCCViewer_Viewer::computeTrihedronSize( double& theNewSize, double& theSize )
1397 {
1398   theNewSize = 100;
1399   theSize = 100;
1400
1401   //SRN: BUG IPAL8996, a usage of method ActiveView without an initialization
1402   Handle(V3d_Viewer) viewer = getViewer3d();
1403   viewer->InitActiveViews();
1404   if(!viewer->MoreActiveViews()) return false;
1405
1406   Handle(V3d_View) view3d = viewer->ActiveView();
1407   //SRN: END of fix
1408
1409   if ( view3d.IsNull() )
1410     return false;
1411
1412   double aMaxSide = computeSceneSize( view3d );
1413
1414   // IPAL21687
1415   // The boundary box of the view may be initialized but nullified
1416   // (case of infinite objects)
1417   if ( aMaxSide < Precision::Confusion() )
1418     return false;
1419
1420   float aSizeInPercents = SUIT_Session::session()->resourceMgr()->doubleValue("3DViewer","trihedron_size", 100.);
1421
1422   static float EPS = 5.0E-3;
1423   theSize = getTrihedron()->Size();
1424   theNewSize = aMaxSide*aSizeInPercents / 100.0;
1425
1426   return fabs( theNewSize - theSize ) > theSize    * EPS ||
1427          fabs( theNewSize - theSize ) > theNewSize * EPS;
1428 }
1429
1430 /*!
1431  * Compute scene size
1432  */
1433 double OCCViewer_Viewer::computeSceneSize(const Handle(V3d_View)& view3d) const
1434 {
1435   double aMaxSide = 0;
1436   double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0;
1437
1438 #if OCC_VERSION_LARGE > 0x06070100
1439   Bnd_Box aBox = view3d->View()->MinMaxValues();
1440   Xmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X();
1441   Ymin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y();
1442   Zmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Z();
1443   Xmax = aBox.IsVoid() ? RealLast()  : aBox.CornerMax().X();
1444   Ymax = aBox.IsVoid() ? RealLast()  : aBox.CornerMax().Y();
1445   Zmax = aBox.IsVoid() ? RealLast()  : aBox.CornerMax().Z();
1446 #else
1447   view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
1448 #endif
1449
1450   if ( Xmin != RealFirst() && Ymin != RealFirst() && Zmin != RealFirst() &&
1451        Xmax != RealLast()  && Ymax != RealLast()  && Zmax != RealLast() )
1452   {
1453     aMaxSide = Xmax - Xmin;
1454     if ( aMaxSide < Ymax -Ymin ) aMaxSide = Ymax -Ymin;
1455     if ( aMaxSide < Zmax -Zmin ) aMaxSide = Zmax -Zmin;
1456   }
1457
1458   return aMaxSide;
1459 }
1460
1461 /*! 
1462  * Update the size of the trihedron
1463  */
1464 void OCCViewer_Viewer::updateTrihedron() {
1465   if ( myTrihedron.IsNull() )
1466     return;
1467
1468   if(myIsRelative){
1469     double newSz, oldSz;
1470     
1471     if(computeTrihedronSize(newSz, oldSz))
1472       myTrihedron->SetSize(newSz);
1473     
1474   } else if(myTrihedron->Size() != myTrihedronSize) {
1475     myTrihedron->SetSize(myTrihedronSize);
1476   }
1477 }
1478
1479 /*!
1480   Set number of isolines
1481   \param u - u-isolines (first parametric co-ordinate)
1482   \param v - v-isolines (second parametric co-ordinate)
1483 */
1484 void OCCViewer_Viewer::setSelectionOptions( bool isPreselectionEnabled, bool isSelectionEnabled )
1485 {
1486   myPreselectionEnabled = isPreselectionEnabled;
1487   mySelectionEnabled = isSelectionEnabled;
1488   //clear current selection in the viewer
1489   
1490   if(!mySelectionEnabled) {
1491     myAISContext->ClearSelected( Standard_True );
1492   }
1493 }
1494
1495 /*!
1496   Creates clipping plane based on the incoming plane
1497 */
1498 Handle(Graphic3d_ClipPlane) OCCViewer_Viewer::createClipPlane(const gp_Pln& thePlane, const Standard_Boolean theIsOn)
1499 {
1500   Handle(Graphic3d_ClipPlane) aGraphic3dPlane = new Graphic3d_ClipPlane( thePlane );
1501   aGraphic3dPlane->SetOn( theIsOn );
1502   aGraphic3dPlane->SetCapping( Standard_True );
1503
1504   // set capping color
1505   Graphic3d_MaterialAspect aMaterialAspect = Graphic3d_MaterialAspect();
1506   aMaterialAspect.SetColor( Quantity_Color( myClippingColor.redF(), myClippingColor.greenF(),
1507                                             myClippingColor.blueF(), Quantity_TOC_RGB ) );
1508   aGraphic3dPlane->SetCappingMaterial( aMaterialAspect );
1509
1510   // set capping texture
1511   aGraphic3dPlane->SetCappingTexture( initClippingTexture( myDefaultTextureUsed, myClippingTexture,
1512                                                            myTextureModulated, myClippingTextureScale ) );
1513
1514   return aGraphic3dPlane;
1515 }
1516 /*!
1517   Applies clipping planes to clippable objects
1518 */
1519 void OCCViewer_Viewer::setClipPlanes(ClipPlanesList theList)
1520 {
1521   // 1. Remove existing clipping planes
1522   myClipPlanes.clear();
1523   myInternalClipPlanes.Clear();
1524
1525   // 2. Create new clipping planes
1526   ClipPlanesList::iterator inIt = theList.begin();
1527   for (;inIt != theList.end(); inIt++ )
1528   {
1529     OCCViewer_ClipPlane aPlane = *inIt;
1530
1531     double aDx = 0.0, aDy = 0.0, aDz = 0.0;
1532     aPlane.OrientationToXYZ( aDx, aDy, aDz );
1533
1534     gp_Pnt anOrigin( aPlane.X, aPlane.Y, aPlane.Z );
1535     gp_Dir aDirection( aDx, aDy, aDz );
1536
1537     myInternalClipPlanes.Append( createClipPlane( gp_Pln( anOrigin, aDirection ), aPlane.IsOn ) );
1538     myClipPlanes.push_back( aPlane );
1539   }
1540
1541   // 3. Apply clipping planes
1542   AIS_ListOfInteractive aList;
1543   myAISContext->DisplayedObjects (aList);
1544   for ( AIS_ListIteratorOfListOfInteractive anIter (aList); anIter.More(); anIter.Next() ) {
1545     Handle(AIS_InteractiveObject) anObj = anIter.Value();
1546     Handle(ViewerData_AISShape) aShape = Handle(ViewerData_AISShape)::DownCast (anObj);
1547     if (!aShape.IsNull() && aShape->IsClippable()) {
1548       aShape->SetClipPlanes(myInternalClipPlanes);
1549     }
1550   }
1551 }
1552
1553 /*!
1554   Returns the clipping planes applied to the displayed objects.
1555 */
1556 ClipPlanesList OCCViewer_Viewer::getClipPlanes() const {
1557   return myClipPlanes;
1558 }
1559 /*!
1560   Applies clipping planes to given object objects
1561 */
1562 void OCCViewer_Viewer::applyExistingClipPlanesToObject (const Handle(AIS_InteractiveObject)& theObject)
1563 {
1564   Handle(ViewerData_AISShape) aShape = Handle(ViewerData_AISShape)::DownCast (theObject);
1565   if (!aShape.IsNull() && aShape->IsClippable())
1566   {
1567     aShape->SetClipPlanes (myInternalClipPlanes);
1568   }
1569 }
1570
1571 /*!
1572   Returns the pointer to the clipping dialog box.
1573 */
1574 OCCViewer_ClippingDlg* OCCViewer_Viewer::getClippingDlg() const{
1575   return myClippingDlg;
1576 }
1577
1578
1579 /*!
1580   Stores pointer to the clipping dialog box.
1581 */
1582 void OCCViewer_Viewer::setClippingDlg(OCCViewer_ClippingDlg* theDlg) {
1583   if(myClippingDlg != theDlg) {
1584     myClippingDlg = theDlg;
1585   }
1586 }
1587
1588
1589 bool OCCViewer_Viewer::enableDrawMode( bool on )
1590 {
1591   //!! To be done for view windows
1592   if ( !myViewManager )
1593     return false;
1594
1595   bool prev = false;
1596   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
1597   for ( int i = 0; i < (int)wins.count(); i++ )
1598   {
1599     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
1600     if ( win ) {
1601       prev = prev || win->enableDrawMode( on ); 
1602     }
1603   }
1604   return prev;
1605 }