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