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