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