]> SALOME platform Git repositories - modules/gui.git/blob - src/OCCViewer/OCCViewer_ViewModel.cxx
Salome HOME
b728482f16e32c342b4c361e9ca408cf94221bd2
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewModel.cxx
1 // Copyright (C) 2007-2013  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.
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_ViewWindow.h"
25 #include "OCCViewer_ViewFrame.h"
26 #include "OCCViewer_VService.h"
27 #include "OCCViewer_ViewPort3d.h"
28
29 #include "SUIT_ViewWindow.h"
30 #include "SUIT_ViewManager.h"
31 #include "SUIT_Desktop.h"
32 #include "SUIT_Session.h"
33 #include "SUIT_ResourceMgr.h"
34
35 #include "QtxActionToolMgr.h"
36 #include "QtxBackgroundTool.h"
37
38 #include <QPainter>
39 #include <QApplication>
40 #include <QColorDialog>
41 #include <QFileDialog>
42 #include <QPalette>
43 #include <QKeyEvent>
44 #include <QMenu>
45 #include <QMouseEvent>
46 #include <QToolBar>
47 #include <QDesktopWidget>
48
49 #include <AIS_Axis.hxx>
50 #include <AIS_Drawer.hxx>
51 #include <AIS_ListOfInteractive.hxx>
52 #include <AIS_ListIteratorOfListOfInteractive.hxx>
53
54 #include <Geom_Axis2Placement.hxx>
55 #include <Prs3d_Drawer.hxx>
56 #include <Prs3d_DatumAspect.hxx>
57 #include <Prs3d_LineAspect.hxx>
58 #include <Prs3d_LengthAspect.hxx>
59 #include <Prs3d_AngleAspect.hxx>
60 #include <Prs3d_TextAspect.hxx>
61
62 #include <Visual3d_View.hxx>
63
64 #include <Basics_OCCTVersion.hxx>
65
66 // VSR: Uncomment below line to allow texture background support in OCC viewer
67 #define OCC_ENABLE_TEXTURED_BACKGROUND
68
69 /*!
70   Get data for supported background modes: gradient types, identifiers and supported image formats
71 */
72 QString OCCViewer_Viewer::backgroundData( QStringList& gradList, QIntList& idList, QIntList& txtList )
73 {
74   gradList << tr("GT_HORIZONTALGRADIENT")    << tr("GT_VERTICALGRADIENT")       <<
75               tr("GT_FIRSTDIAGONALGRADIENT") << tr("GT_SECONDDIAGONALGRADIENT") <<
76               tr("GT_FIRSTCORNERGRADIENT")   << tr("GT_SECONDCORNERGRADIENT")   <<
77               tr("GT_THIRDCORNERGRADIENT")   << tr("GT_FORTHCORNERGRADIENT");
78   idList   << HorizontalGradient             << VerticalGradient  <<
79               Diagonal1Gradient              << Diagonal2Gradient <<
80               Corner1Gradient                << Corner2Gradient   <<
81               Corner3Gradient                << Corner4Gradient;
82 #if OCC_VERSION_LARGE > 0x06050200 // enabled since OCCT 6.5.3, since in previous version this functionality is buggy
83 #ifdef OCC_ENABLE_TEXTURED_BACKGROUND
84   txtList  << Qtx::CenterTexture << Qtx::TileTexture << Qtx::StretchTexture;
85 #endif
86 #endif
87   return tr("BG_IMAGE_FILES");
88 }
89
90 /*!
91   Constructor
92   \param DisplayTrihedron - is trihedron displayed
93 */
94 OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron)
95 : SUIT_ViewModel(),
96   myBackgrounds(4, Qtx::BackgroundData( Qt::black )),
97   myIsRelative(true),
98   myTopLayerId( 0 ),
99   myTrihedronSize(100)
100 {
101   // init CasCade viewers
102   myV3dViewer = OCCViewer_VService::Viewer3d( "", (short*) "Viewer3d", "", 1000.,
103                                               V3d_XposYnegZpos, true, true );
104
105   myV3dViewer->Init();
106
107   myV3dCollector = OCCViewer_VService::Viewer3d( "", (short*) "Collector3d", "", 1000.,
108                                                  V3d_XposYnegZpos, true, true );
109   myV3dCollector->Init();
110
111   // init selector
112   myAISContext = new AIS_InteractiveContext( myV3dViewer, myV3dCollector);
113
114   myAISContext->SelectionColor( Quantity_NOC_WHITE );
115   
116   // display isoline on planar faces (box for ex.)
117   myAISContext->IsoOnPlane( true );
118
119   double h = QApplication::desktop()->screenGeometry( QApplication::desktop()->primaryScreen() ).height() / 300. ;
120   Handle(Prs3d_Drawer) drawer = myAISContext->DefaultDrawer();
121   Handle(Prs3d_TextAspect) ta = drawer->TextAspect();
122   ta->SetHeight(100); // VSR: workaround for CAS.CADE bug (is it really needed ???)
123   ta->SetHeight(h);
124   drawer->SetTextAspect(ta);
125   drawer->AngleAspect()->SetTextAspect(ta);
126   drawer->LengthAspect()->SetTextAspect(ta);
127   
128   /* create trihedron */
129   if( DisplayTrihedron )
130   {
131     Handle(Geom_Axis2Placement) anAxis = new Geom_Axis2Placement(gp::XOY());
132     myTrihedron = new AIS_Trihedron(anAxis);
133     myTrihedron->SetInfiniteState( Standard_True );
134
135     Quantity_Color Col(193/255., 205/255., 193/255., Quantity_TOC_RGB);
136     //myTrihedron->SetColor( Col );
137     myTrihedron->SetArrowColor( Col.Name() );
138     myTrihedron->SetSize(100);
139     Handle(AIS_Drawer) drawer = myTrihedron->Attributes();
140     if (drawer->HasDatumAspect()) {
141         Handle(Prs3d_DatumAspect) daspect = drawer->DatumAspect();
142         daspect->FirstAxisAspect()->SetColor(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB));
143         daspect->SecondAxisAspect()->SetColor(Quantity_Color(0.0, 1.0, 0.0, Quantity_TOC_RGB));
144         daspect->ThirdAxisAspect()->SetColor(Quantity_Color(0.0, 0.0, 1.0, Quantity_TOC_RGB));
145     }
146
147     myAISContext->Display(myTrihedron);
148     myAISContext->Deactivate(myTrihedron);
149     }
150
151   // set interaction style to standard
152   myInteractionStyle = 0;
153
154   // set zooming style to standard
155   myZoomingStyle = 0;
156
157   // preselection
158   myPreselectionEnabled = true;
159
160   // selection
161   mySelectionEnabled = true;
162   myMultiSelectionEnabled = true;
163   
164   
165   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
166   if(resMgr)
167     myShowStaticTrihedron = resMgr->booleanValue( "3DViewer", "show_static_trihedron", true );
168 }
169
170 /*!
171   Destructor
172 */
173 OCCViewer_Viewer::~OCCViewer_Viewer() 
174 {
175   myAISContext.Nullify();
176   myV3dViewer.Nullify();
177   myV3dCollector.Nullify();
178 }
179
180 /*!
181   [obsolete]
182   \return background color of viewer
183 */
184 QColor OCCViewer_Viewer::backgroundColor() const
185 {
186   return backgroundColor(0);
187 }
188
189 /*!
190   \return background data of viewer
191 */
192 Qtx::BackgroundData OCCViewer_Viewer::background() const
193 {
194   return background(0);
195 }
196
197 /*!
198   Sets background color [obsolete]
199   \param c - new background color
200 */
201 void OCCViewer_Viewer::setBackgroundColor( const QColor& c )
202 {
203   setBackgroundColor( 0, c );
204 }
205
206 /*!
207   Sets background data
208   \param d - new background data
209 */
210 void OCCViewer_Viewer::setBackground( const Qtx::BackgroundData& theBackground )
211 {
212   setBackground( 0, theBackground );
213 }
214
215 /*!
216   Start initialization of view window
217   \param view - view window to be initialized
218 */
219 void OCCViewer_Viewer::initView( OCCViewer_ViewWindow* view )
220 {
221   if ( view ) {
222     view->initLayout();
223     view->initSketchers();
224     view->setInteractionStyle( interactionStyle() );
225     view->setZoomingStyle( zoomingStyle() );
226     view->enablePreselection( isPreselectionEnabled() );
227     view->enableSelection( isSelectionEnabled() );
228     
229     OCCViewer_ViewPort3d* vp3d = view->getViewPort();
230     if ( vp3d )
231     {
232       vp3d->getView()->SetSurfaceDetail(V3d_TEX_ALL);
233     }
234   }
235 }
236
237 /*!
238   Creates new view window
239   \param theDesktop - main window of application
240 */
241 SUIT_ViewWindow* OCCViewer_Viewer::createView( SUIT_Desktop* theDesktop )
242 {
243   // create view frame
244   OCCViewer_ViewFrame* view = new OCCViewer_ViewFrame(theDesktop, this);
245   // get main view window (created by view frame)
246   OCCViewer_ViewWindow* vw = view->getView(OCCViewer_ViewFrame::MAIN_VIEW);
247   // initialize main view window
248   initView( vw );
249   // set default background for view window
250   vw->setBackground( background(0) ); // 0 means MAIN_VIEW (other views are not yet created here)
251   // connect signal from viewport
252   connect(view->getViewPort(), SIGNAL(vpClosed()), this, SLOT(onViewClosed()));
253   return view;
254 }
255
256 /*!
257   Sets new view manager
258   \param theViewManager - new view manager
259 */
260 void OCCViewer_Viewer::setViewManager(SUIT_ViewManager* theViewManager)
261 {
262   SUIT_ViewModel::setViewManager(theViewManager);
263   if (theViewManager) {
264     connect(theViewManager, SIGNAL(mousePress(SUIT_ViewWindow*, QMouseEvent*)), 
265             this, SLOT(onMousePress(SUIT_ViewWindow*, QMouseEvent*)));
266
267     connect(theViewManager, SIGNAL(mouseMove(SUIT_ViewWindow*, QMouseEvent*)), 
268             this, SLOT(onMouseMove(SUIT_ViewWindow*, QMouseEvent*)));
269
270     connect(theViewManager, SIGNAL(mouseRelease(SUIT_ViewWindow*, QMouseEvent*)), 
271             this, SLOT(onMouseRelease(SUIT_ViewWindow*, QMouseEvent*)));
272
273     connect(theViewManager, SIGNAL(keyPress(SUIT_ViewWindow*, QKeyEvent*)), 
274             this, SLOT(onKeyPress(SUIT_ViewWindow*, QKeyEvent*)));
275   }
276 }
277
278 /*!
279   SLOT: called on mouse button press, stores current mouse position as start point for transformations
280 */
281 void OCCViewer_Viewer::onMousePress(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
282 {
283   myStartPnt.setX(theEvent->x()); myStartPnt.setY(theEvent->y());
284 }
285
286 /*!
287   SLOT: called on mouse move, processes transformation or hilighting
288 */
289 void OCCViewer_Viewer::onMouseMove(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
290 {
291   if (!mySelectionEnabled) return;
292   if (!theWindow->inherits("OCCViewer_ViewWindow")) return;
293
294   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow;
295
296   myCurPnt.setX(theEvent->x()); myCurPnt.setY(theEvent->y());
297
298   if ( isSelectionEnabled() && isPreselectionEnabled() ) {
299     if (aView->getViewPort()->isBusy()) {
300       QCoreApplication::processEvents();
301       return; // Check that the ViewPort initialization completed
302                                                 // To Prevent call move event if the View port is not initialized
303                                                 // IPAL 20883
304     }
305     Handle(V3d_View) aView3d = aView->getViewPort()->getView();
306     if ( !aView3d.IsNull() ) {
307       myAISContext->MoveTo(theEvent->x(), theEvent->y(), aView3d);
308     }
309   }
310 }
311
312
313 /*!
314   SLOT: called on mouse button release, finishes transformation or selection
315 */
316 void OCCViewer_Viewer::onMouseRelease(SUIT_ViewWindow* theWindow, QMouseEvent* theEvent)
317 {
318   if (!mySelectionEnabled) return;
319   if (theEvent->button() != Qt::LeftButton) return;
320   if (!theWindow->inherits("OCCViewer_ViewWindow")) return;
321
322   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow;
323   if (!aView )
324     return;
325
326   myEndPnt.setX(theEvent->x()); myEndPnt.setY(theEvent->y());
327   bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
328   
329   if (!aHasShift) emit deselection();
330
331   if (myStartPnt == myEndPnt)
332   {
333     if ( !isPreselectionEnabled() ) {
334       Handle(V3d_View) aView3d = aView->getViewPort()->getView();
335       if ( !aView3d.IsNull() ) {
336         myAISContext->MoveTo(myEndPnt.x(), myEndPnt.y(), aView3d);
337       }
338     }
339
340     if (aHasShift && myMultiSelectionEnabled)
341       myAISContext->ShiftSelect();
342     else
343       myAISContext->Select();
344   }
345   else
346   {
347     if (aHasShift && myMultiSelectionEnabled)
348       myAISContext->ShiftSelect(myStartPnt.x(), myStartPnt.y(),
349                                 myEndPnt.x(), myEndPnt.y(),
350                                 aView->getViewPort()->getView(), Standard_False );
351     else
352       myAISContext->Select(myStartPnt.x(), myStartPnt.y(),
353                            myEndPnt.x(), myEndPnt.y(),
354                            aView->getViewPort()->getView(), Standard_False );
355
356     int Nb = myAISContext->NbSelected();
357     if( Nb>1 && !myMultiSelectionEnabled )
358     {
359         myAISContext->InitSelected();
360         Handle( SelectMgr_EntityOwner ) anOwner = myAISContext->SelectedOwner();
361         if( !anOwner.IsNull() )
362         {
363             myAISContext->ClearSelected( Standard_False );
364             myAISContext->AddOrRemoveSelected( anOwner, Standard_False );
365         }
366     }
367
368     myAISContext->UpdateCurrentViewer();
369   }
370   emit selectionChanged();
371 }
372
373 /*!
374   SLOT: called on key press, processes selection in "key free" interaction style
375 */
376 void OCCViewer_Viewer::onKeyPress(SUIT_ViewWindow* theWindow, QKeyEvent* theEvent)
377 {
378   if (!mySelectionEnabled) return;
379   if (theEvent->key() != Qt::Key_S) return;
380   if (!theWindow->inherits("OCCViewer_ViewWindow")) return;
381
382   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*) theWindow;
383   if (!aView || aView->interactionStyle() != SUIT_ViewModel::KEY_FREE)
384     return;
385
386   emit deselection();
387
388   if ( !isPreselectionEnabled() ) {
389     Handle(V3d_View) aView3d = aView->getViewPort()->getView();
390     if ( !aView3d.IsNull() ) {
391       myAISContext->MoveTo(myCurPnt.x(), myCurPnt.y(), aView3d);
392     }
393   }
394
395   myAISContext->Select();
396
397   emit selectionChanged();
398 }
399
400 void OCCViewer_Viewer::onViewClosed()
401 {
402   Standard_Integer aViewsNb = 0;
403   for ( myV3dViewer->InitActiveViews(); myV3dViewer->MoreActiveViews(); myV3dViewer->NextActiveViews())
404     ++aViewsNb;
405   if ( aViewsNb < 2 ) {
406     //clean up presentations before last view is closed
407     myAISContext->RemoveAll(Standard_False);
408   }
409 }
410
411 int OCCViewer_Viewer::getTopLayerId()
412 {
413 #if OCC_VERSION_LARGE > 0x06050200
414   if ( myTopLayerId == 0 && !myAISContext->CurrentViewer().IsNull() )    
415     myAISContext->CurrentViewer()->AddZLayer( myTopLayerId );
416 #endif
417
418   return myTopLayerId;
419 }
420
421 /*!
422   \return interaction style
423 */
424 int OCCViewer_Viewer::interactionStyle() const
425 {
426   return myInteractionStyle;
427 }
428
429 /*!
430   Sets interaction style: 0 - standard, 1 - keyboard free interaction
431   \param theStyle - new interaction style
432 */
433 void OCCViewer_Viewer::setInteractionStyle( const int theStyle )
434 {
435   myInteractionStyle = theStyle;
436   //!! To be done for view windows
437   if ( !myViewManager )
438     return;
439
440   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
441   for ( int i = 0; i < (int)wins.count(); i++ )
442   {
443     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
444     if ( win )
445       win->setInteractionStyle( theStyle );
446   }
447 }
448
449 /*!
450   \return zooming style
451 */
452 int OCCViewer_Viewer::zoomingStyle() const
453 {
454   return myZoomingStyle;
455 }
456
457 /*!
458   Sets zooming style: 0 - standard, 1 - advanced (at cursor)
459   \param theStyle - new zooming style
460 */
461 void OCCViewer_Viewer::setZoomingStyle( const int theStyle )
462 {
463   myZoomingStyle = theStyle;
464   //!! To be done for view windows
465   if ( !myViewManager )
466     return;
467
468   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
469   for ( int i = 0; i < (int)wins.count(); i++ )
470   {
471     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
472     if ( win )
473       win->setZoomingStyle( theStyle );
474   }
475 }
476
477 /*!
478   \return true if preselection is enabled
479 */
480 bool OCCViewer_Viewer::isPreselectionEnabled() const 
481
482   return myPreselectionEnabled; 
483 }
484
485 /*!
486   Enables/disables preselection
487   \param isEnabled - new status
488 */
489 void OCCViewer_Viewer::enablePreselection(bool isEnabled)
490 {
491   myPreselectionEnabled = isEnabled;
492
493   if ( !myViewManager )
494     return;
495
496   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
497   for ( int i = 0; i < (int)wins.count(); i++ )
498   {
499     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
500     if ( win ) {
501       win->enablePreselection( isEnabled );
502     }
503   }
504 }
505
506 /*!
507   \return true if selection is enabled
508 */
509 bool OCCViewer_Viewer::isSelectionEnabled() const 
510
511   return mySelectionEnabled; 
512 }
513
514 /*!
515   Enables/disables selection
516   \param isEnabled - new status
517 */
518 void OCCViewer_Viewer::enableSelection(bool isEnabled)
519 {
520   mySelectionEnabled = isEnabled;
521
522   //!! To be done for view windows
523   if ( !myViewManager )
524     return;
525
526   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
527   for ( int i = 0; i < (int)wins.count(); i++ )
528   {
529     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
530     if ( win ) {
531       win->updateEnabledDrawMode();
532       win->enableSelection( isEnabled );
533     }
534   }
535 }
536
537 /*!
538   Sets multiselection enabled status
539   \param isEnabled - new status
540 */
541 void OCCViewer_Viewer::enableMultiselection(bool isEnable)
542 {
543   myMultiSelectionEnabled = isEnable;
544   //!! To be done for view windows
545   if ( !myViewManager )
546     return;
547
548   QVector<SUIT_ViewWindow*> wins = myViewManager->getViews();
549   for ( int i = 0; i < (int)wins.count(); i++ )
550   {
551     OCCViewer_ViewWindow* win = ::qobject_cast<OCCViewer_ViewWindow*>( wins.at( i ) );
552     if ( win )
553       win->updateEnabledDrawMode();
554   }
555 }
556
557 /*!
558   Builds popup for occ viewer
559 */
560 void OCCViewer_Viewer::contextMenuPopup(QMenu* thePopup)
561 {
562   thePopup->addAction( tr( "MEN_DUMP_VIEW" ), this, SLOT( onDumpView() ) );
563   thePopup->addAction( tr( "MEN_CHANGE_BACKGROUND" ), this, SLOT( onChangeBackground() ) );
564
565   thePopup->addSeparator();
566
567   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
568
569   //Support of several toolbars in the popup menu
570   QList<QToolBar*> lst = qFindChildren<QToolBar*>( aView );
571   QList<QToolBar*>::const_iterator it = lst.begin(), last = lst.end();
572   for ( ; it!=last; it++ ) {
573     if ( (*it)->parentWidget()->isVisible() )
574       thePopup->addAction( (*it)->toggleViewAction() );
575   }
576 }
577
578 /*!
579   SLOT: called on dump view operation is activated, stores scene to raster file
580 */
581 void OCCViewer_Viewer::onDumpView()
582 {
583   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
584   if ( aView )
585     aView->onDumpView();
586 }
587
588 /*!
589   SLOT: called if background color is to be changed changed, passes new color to view port
590 */
591 void OCCViewer_Viewer::onChangeBackground()
592 {
593   OCCViewer_ViewWindow* aView = dynamic_cast<OCCViewer_ViewWindow*>(myViewManager->getActiveView());
594   if ( !aView )
595     return;
596
597   // get supported gradient types
598   QStringList gradList;
599   QIntList    idList, txtList;
600   QString     formats = backgroundData( gradList, idList, txtList );
601
602   // invoke dialog box
603   Qtx::BackgroundData bgData = QtxBackgroundDialog::getBackground( aView->background(),  // initial background
604                                                                    aView,                // parent for dialog box
605                                                                    txtList,              // allowed texture modes
606                                                                    true,                 // enable solid color mode
607                                                                    true,                 // enable gradient mode
608                                                                    false,                // disable custom gradient mode
609                                                                    !txtList.isEmpty(),   // enable/disable texture mode
610                                                                    gradList,             // gradient names
611                                                                    idList,               // gradient identifiers
612                                                                    formats );            // image formats
613
614   // set chosen background data to the viewer
615   if ( bgData.isValid() )
616     aView->setBackground( bgData );
617 }
618
619 /*!
620   Updates OCC 3D viewer
621 */
622 void OCCViewer_Viewer::update()
623 {
624   if (!myV3dViewer.IsNull())
625     myV3dViewer->Update();
626
627   OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
628   if ( aView )
629     aView->updateGravityCoords();
630 }
631
632 /*!
633   \return objects selected in 3D viewer
634   \param theList - list to be filled with selected objects
635 */
636 void OCCViewer_Viewer::getSelectedObjects(AIS_ListOfInteractive& theList)
637 {
638   theList.Clear();
639   for (myAISContext->InitSelected(); myAISContext->MoreSelected(); myAISContext->NextSelected())
640     theList.Append(myAISContext->SelectedInteractive());
641 }
642
643 /*!
644   Selects objects in 3D viewer. Other selected objects are left as selected
645   \param theList - list objects to be selected
646 */
647 void OCCViewer_Viewer::setObjectsSelected(const AIS_ListOfInteractive& theList)
648 {
649   AIS_ListIteratorOfListOfInteractive aIt;
650   for (aIt.Initialize(theList); aIt.More(); aIt.Next())
651     myAISContext->AddOrRemoveSelected(aIt.Value(), false);
652   myAISContext->UpdateCurrentViewer();
653 }
654
655 /*!
656   Auxiliary method to emit signal selectionChanged()
657 */
658 void OCCViewer_Viewer::performSelectionChanged()
659 {
660     emit selectionChanged();
661 }
662
663 /*!
664   Hilights/unhilights object in viewer
665   \param obj - object to be updated
666   \param hilight - if it is true, object will be hilighted, otherwise it will be unhilighted
667   \param update - update current viewer
668 */
669 bool OCCViewer_Viewer::highlight( const Handle(AIS_InteractiveObject)& obj,
670                                   bool hilight, bool update )
671 {
672   bool isInLocal = myAISContext->HasOpenedContext();
673   if( !obj.IsNull() )
674     if( !isInLocal )
675     {
676       if ( hilight && !myAISContext->IsSelected( obj ) )
677         myAISContext->AddOrRemoveCurrentObject( obj, false );
678       else if ( !hilight && myAISContext->IsSelected( obj ) )
679         myAISContext->AddOrRemoveCurrentObject( obj, false );
680     }
681
682   if ( update )
683     myV3dViewer->Redraw();
684     
685   return false;
686 }
687
688 /*!
689   Unhilights all objects in viewer
690   \param updateviewer - update current viewer
691 */
692 bool OCCViewer_Viewer::unHighlightAll( bool updateviewer, bool unselect )
693 {
694   if ( myAISContext->HasOpenedContext() ) {
695     if ( unselect ) {
696       myAISContext->ClearSelected( updateviewer );
697     } else {
698       myAISContext->UnhilightSelected( updateviewer );
699     }
700   } else {
701     if ( unselect ) {
702       myAISContext->ClearCurrents( updateviewer );
703     } else {
704       myAISContext->UnhilightCurrents( updateviewer );
705     }
706   }
707
708   return false;
709 }
710
711 /*!
712   \return true if object is in viewer or in collector
713   \param obj - object to be checked
714   \param onlyInViewer - search object only in viewer (so object must be displayed)
715 */
716 bool OCCViewer_Viewer::isInViewer( const Handle(AIS_InteractiveObject)& obj,
717                                    bool onlyInViewer )
718 {
719   AIS_ListOfInteractive List;
720   myAISContext->DisplayedObjects(List);
721
722   if( !onlyInViewer )
723   {
724     AIS_ListOfInteractive List1;
725     myAISContext->ObjectsInCollector(List1);
726     List.Append(List1);
727   }
728
729   AIS_ListIteratorOfListOfInteractive ite(List);
730   for ( ; ite.More(); ite.Next() )
731     if( ite.Value()==obj )
732       return true;
733
734   return false;
735 }
736
737 /*!
738   \return true if object is displayed in viewer
739   \param obj - object to be checked
740 */
741 bool OCCViewer_Viewer::isVisible( const Handle(AIS_InteractiveObject)& obj )
742 {
743   return myAISContext->IsDisplayed( obj );
744 }
745
746 /*!
747   Sets color of object
748   \param obj - object to be updated
749   \param color - new color
750   \param update - update current viewer
751 */
752 void OCCViewer_Viewer::setColor( const Handle(AIS_InteractiveObject)& obj,
753                                  const QColor& color,
754                                  bool update )
755 {
756   if( !obj.IsNull() )
757   {
758     Quantity_Color CSFColor = Quantity_Color ( color.red() / 255.,
759                                                color.green() / 255.,
760                                                color.blue() / 255.,
761                                                Quantity_TOC_RGB );
762     obj->SetColor( CSFColor );
763   }
764
765   if( update )
766     myV3dViewer->Update();
767 }
768
769 /*!
770   Changes display mode of object
771   \param obj - object to be processed
772   \param mode - new display mode
773   \param update - update current viewer
774 */
775 void OCCViewer_Viewer::switchRepresentation( const Handle(AIS_InteractiveObject)& obj,
776                                              int mode, bool update )
777 {
778   myAISContext->SetDisplayMode( obj, (Standard_Integer)mode, update );
779   if( update )
780     myV3dViewer->Update();
781 }
782
783 /*!
784   Changes transparency of object
785   \param obj - object to be processed
786   \param trans - new transparency
787   \param update - update current viewer
788 */
789 void OCCViewer_Viewer::setTransparency( const Handle(AIS_InteractiveObject)& obj,
790                                         float trans, bool update )
791 {
792   myAISContext->SetTransparency( obj, trans, false );
793   myAISContext->Redisplay( obj, Standard_False, Standard_True );
794   if( update )
795     myV3dViewer->Update();
796 }
797
798 /*!
799   Changes visibility of trihedron to opposite
800 */
801 void OCCViewer_Viewer::toggleTrihedron()
802 {
803   setTrihedronShown( !isTrihedronVisible() );
804 }
805
806 /*!
807   \return true if trihedron is visible
808 */
809 bool OCCViewer_Viewer::isTrihedronVisible() const
810 {
811   return !myTrihedron.IsNull() && !myAISContext.IsNull() && myAISContext->IsDisplayed( myTrihedron );
812 }
813
814 /*!
815   Sets visibility state of trihedron
816   \param on - new state
817 */
818
819 void OCCViewer_Viewer::setTrihedronShown( const bool on )
820 {
821   if ( myTrihedron.IsNull() )
822     return;
823
824   if ( on )
825     myAISContext->Display( myTrihedron );
826   else
827     myAISContext->Erase( myTrihedron );
828 }
829
830 /*!
831   \return trihedron size
832 */
833 double OCCViewer_Viewer::trihedronSize() const
834 {
835   double sz = 0;
836   if ( !myTrihedron.IsNull() )
837     sz = myTrihedron->Size();
838   return sz;
839 }
840
841 /*!
842   Changes trihedron size
843   \param sz - new size
844 */
845 void OCCViewer_Viewer::setTrihedronSize( const double sz, bool isRelative )
846 {
847   if ( myTrihedronSize != sz || isRelative != myIsRelative) {
848     myTrihedronSize = sz; 
849     myIsRelative = isRelative;
850     updateTrihedron();
851   }
852 }
853
854 /*!
855   Set number of isolines
856   \param u - u-isolines (first parametric co-ordinate)
857   \param v - v-isolines (second parametric co-ordinate)
858 */
859 void OCCViewer_Viewer::setIsos( const int u, const int v )
860 {
861   Handle(AIS_InteractiveContext) ic = getAISContext();
862   if ( ic.IsNull() )
863   return;
864
865   ic->SetIsoNumber( u, AIS_TOI_IsoU );
866   ic->SetIsoNumber( v, AIS_TOI_IsoV );
867 }
868
869 /*!
870   \return number of isolines
871   \param u - to return u-isolines (first parametric co-ordinate)
872   \param v - to return v-isolines (second parametric co-ordinate)
873 */
874 void OCCViewer_Viewer::isos( int& u, int& v ) const
875 {
876   Handle(AIS_InteractiveContext) ic = getAISContext();
877   if ( !ic.IsNull() )
878   {
879     u = ic->IsoNumber( AIS_TOI_IsoU );
880     v = ic->IsoNumber( AIS_TOI_IsoV );
881   }
882 }
883
884 /* 
885  * Returns a new OCCViewer_ViewWindow instance which will be placed as a sub window in ViewFrame
886  */
887 OCCViewer_ViewWindow* OCCViewer_Viewer::createSubWindow()
888 {
889   return new OCCViewer_ViewWindow( 0,  this);
890 }
891
892 // obsolete  
893 QColor OCCViewer_Viewer::backgroundColor( int theViewId ) const
894 {
895   return background( theViewId ).color();
896 }
897
898 Qtx::BackgroundData OCCViewer_Viewer::background( int theViewId ) const
899 {
900   return ( theViewId >= 0 && theViewId < myBackgrounds.count() ) ? myBackgrounds[theViewId] : Qtx::BackgroundData();
901 }
902
903 // obsolete
904 void OCCViewer_Viewer::setBackgroundColor( int theViewId, const QColor& theColor )
905 {
906   if ( theColor.isValid() ) {
907     Qtx::BackgroundData bg = background( theViewId );
908     bg.setColor( theColor );
909     setBackground( theViewId, bg );
910   }
911 }
912
913 void OCCViewer_Viewer::setBackground( int theViewId, const Qtx::BackgroundData& theBackground )
914 {
915   if ( theBackground.isValid() && theViewId >= 0 && theViewId < myBackgrounds.count() )
916     myBackgrounds[theViewId] = theBackground;    
917 }
918
919
920 /*!
921   Set the show static trihedron flag
922 */
923 void OCCViewer_Viewer::setStaticTrihedronDisplayed(const bool on) {
924   if(myShowStaticTrihedron != on) {
925     OCCViewer_ViewWindow* aView = (OCCViewer_ViewWindow*)(myViewManager->getActiveView());
926     if(!aView)
927       return;
928
929     OCCViewer_ViewPort3d* vp3d = aView->getViewPort();
930     if(vp3d) {
931       myShowStaticTrihedron = on;
932       vp3d->updateStaticTriedronVisibility();
933     }
934   }
935 }
936
937 /*!
938   Get new and current trihedron size corresponding to the current model size
939 */
940 bool OCCViewer_Viewer::computeTrihedronSize( double& theNewSize, double& theSize )
941 {
942   theNewSize = 100;
943   theSize = 100;
944
945   //SRN: BUG IPAL8996, a usage of method ActiveView without an initialization
946   Handle(V3d_Viewer) viewer = getViewer3d();
947   viewer->InitActiveViews();
948   if(!viewer->MoreActiveViews()) return false;
949
950   Handle(V3d_View) view3d = viewer->ActiveView();
951   //SRN: END of fix
952
953   if ( view3d.IsNull() )
954     return false;
955
956   double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0;
957   double aMaxSide;
958
959   view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax );
960
961   if ( Xmin == RealFirst() || Ymin == RealFirst() || Zmin == RealFirst() ||
962        Xmax == RealLast()  || Ymax == RealLast()  || Zmax == RealLast() )
963     return false;
964
965   aMaxSide = Xmax - Xmin;
966   if ( aMaxSide < Ymax -Ymin ) aMaxSide = Ymax -Ymin;
967   if ( aMaxSide < Zmax -Zmin ) aMaxSide = Zmax -Zmin;
968
969   // IPAL21687
970   // The boundary box of the view may be initialized but nullified
971   // (case of infinite objects)
972   if ( aMaxSide < Precision::Confusion() )
973     return false;
974
975   float aSizeInPercents = SUIT_Session::session()->resourceMgr()->doubleValue("3DViewer","trihedron_size", 100.);
976
977   static float EPS = 5.0E-3;
978   theSize = getTrihedron()->Size();
979   theNewSize = aMaxSide*aSizeInPercents / 100.0;
980
981   return fabs( theNewSize - theSize ) > theSize * EPS ||
982          fabs( theNewSize - theSize) > theNewSize * EPS;
983 }
984
985 /*! 
986  * Update the size of the trihedron
987  */
988 void OCCViewer_Viewer::updateTrihedron() {
989   if(myIsRelative){
990     double newSz, oldSz;
991     
992     if(computeTrihedronSize(newSz, oldSz))
993       myTrihedron->SetSize(newSz);
994     
995   } else if(myTrihedron->Size() != myTrihedronSize) {
996     myTrihedron->SetSize(myTrihedronSize);
997   }
998 }
999
1000 /*!
1001   Set number of isolines
1002   \param u - u-isolines (first parametric co-ordinate)
1003   \param v - v-isolines (second parametric co-ordinate)
1004 */
1005 void OCCViewer_Viewer::setSelectionOptions( bool isPreselectionEnabled, bool isSelectionEnabled )
1006 {
1007   myPreselectionEnabled = isPreselectionEnabled;
1008   mySelectionEnabled = isSelectionEnabled;
1009 }