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