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