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