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