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