Salome HOME
Merge from BR_new_bop4 (porting to new OCCT BOP) 13/09/2013
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewPort3d.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_ViewPort3d.h"
24
25 #include "OCCViewer_VService.h"
26 #include "OCCViewer_ViewWindow.h"
27 #include "OCCViewer_ViewModel.h"
28
29 #include <Basics_OCCTVersion.hxx>
30
31 #include <SUIT_ViewManager.h>
32 #include <SUIT_ViewModel.h>
33
34 #include <QColor>
35 #include <QFileInfo>
36 #include <QString>
37 #include <QRect>
38 #include <QPaintEvent>
39 #include <QResizeEvent>
40 #include <QApplication>
41
42 #include <Visual3d_View.hxx>
43 #include <V3d_Viewer.hxx>
44 #include <V3d_PerspectiveView.hxx>
45 #include <V3d_OrthographicView.hxx>
46
47 #include "utilities.h"
48
49 #if defined WNT
50 #include <WNT_Window.hxx>
51 #else
52 #include <Xw_Window.hxx>
53 #endif
54
55 static double rx = 0.;
56 static double ry = 0.;
57 static int sx = 0;
58 static int sy = 0;
59 static Standard_Boolean zRotation = Standard_False;
60
61 //#include <Standard_Version.hxx>
62
63 /*!
64   Constructor
65 */
66 OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_Viewer)& viewer, V3d_TypeOfView  type )
67   : OCCViewer_ViewPort( parent ),
68     myScale( 1.0 ),
69     myBusy( true ),
70     myIsAdvancedZoomingEnabled( false )
71 {
72   // VSR: 01/07/2010 commented to avoid SIGSEGV at SALOME exit
73   //selectVisualId();
74
75   if ( type == V3d_ORTHOGRAPHIC ) {
76     myOrthoView = new V3d_OrthographicView( viewer );
77     myActiveView = myOrthoView;
78     myPerspView = 0;
79   } else {
80     myPerspView = new V3d_PerspectiveView( viewer );
81     myActiveView = myPerspView;
82   }
83   setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background
84 }
85
86 /*!
87   Destructor
88 */
89 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
90 {
91   emit vpClosed();
92   Handle(V3d_View) aView = activeView();
93   if (!aView.IsNull())
94     aView->Remove();
95 }
96
97 /*!
98   Activates the desired 'type' of view in the viewer
99   ( view of 'type' is created if it doesn't exist ). [ public ]
100 */
101 /*void OCCViewer_ViewPort3d::setActive( V3d_TypeOfView type )
102 {
103   if ( activeView().IsNull() )
104   return;
105
106   if ( activeView()->Type() != type )
107   {
108   if ( type == V3d_ORTHOGRAPHIC )
109   setView( myOrthoView );
110   if ( type == V3d_PERSPECTIVE )
111   setView( myPerspView );
112   }
113 }*/
114
115 /*!
116   Maps CasCade 'view' to this viewport. [ private ]
117 */
118 bool OCCViewer_ViewPort3d::mapView( const Handle(V3d_View)& view )
119 {
120   if ( !setWindow( view ) )
121     return false;
122
123   if ( !mapped( view ) ) {
124     view->SetWindow( myWindow );
125     if ( view != activeView() )
126       view->View()->Deactivate();
127   }
128
129   /* create static trihedron (16551: EDF PAL 501) */
130   OCCViewer_ViewWindow* aVW = dynamic_cast<OCCViewer_ViewWindow*>( parentWidget()->parentWidget()->parentWidget() );
131   if ( aVW ) {
132     OCCViewer_Viewer* aViewModel = dynamic_cast<OCCViewer_Viewer*>( aVW->getViewManager()->getViewModel() );
133     if ( aViewModel && aViewModel->isStaticTrihedronDisplayed() ){
134       view->ZBufferTriedronSetup();
135       view->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
136     }
137   }
138
139   emit( vpMapped() );
140
141   return true;
142 }
143
144
145
146 /*!
147   Sets new CASCADE view on viewport. Returns the previous active view. [ public ]
148 */
149 Handle( V3d_View ) OCCViewer_ViewPort3d::setView( const Handle( V3d_View )& view )
150 {
151   /* map the new view */
152   if ( view == activeView() || !mapView( view ) )
153     return activeView();
154
155   /* activate the new view*/
156   Handle( V3d_View ) oldView = activeView();
157   if ( !oldView.IsNull() ) {
158     if (oldView->View()->IsDefined())
159       oldView->View()->Deactivate();
160     view->SetBackgroundColor( oldView->BackgroundColor() );
161   }
162
163   view->View()->Activate();
164   activeView() = view;
165   return oldView;
166 }
167
168 /*!
169   Returns CasCade 3D view. [ public ]
170 */
171 Handle(V3d_View) OCCViewer_ViewPort3d::getView() const
172 {
173   return activeView();
174 }
175
176 /*!
177   Returns CasCade 3D viewer [ public ]
178 */
179 Handle(V3d_Viewer) OCCViewer_ViewPort3d::getViewer() const
180 {
181   Handle(V3d_Viewer) viewer;
182   if ( !activeView().IsNull() )
183     viewer = activeView()->Viewer();
184   return viewer;
185 }
186
187 /*!
188   Syncronizes visual state of this viewport with 'ref'
189   ( scale, projection, eye etc ) Returns 'true' if copied OK,
190   'false' otherwise. [ virtual public ]
191 */
192 bool OCCViewer_ViewPort3d::syncronize( const OCCViewer_ViewPort3d* ref )
193 {
194   OCCViewer_ViewPort3d* ref3d = (OCCViewer_ViewPort3d*)ref;
195   Handle(V3d_View) refView = ref3d->getView();
196   Handle(V3d_View) tgtView = getView();
197
198   /* Syncronize view types */
199   /*    if ( tgtView->Type() != refView->Type() )
200         {
201         setActive( refView->Type() );
202         tgtView = getView();
203         }*/
204
205   /*  The following params are copied:
206       - view type( ortho/persp )
207       - position of view point
208       - orientation of high point
209       - position of the eye
210       - projection vector
211       - view center ( 2D )
212       - view twist
213       - view scale
214   */
215
216   /* we'll update after setting all params */
217   tgtView->SetImmediateUpdate( Standard_False );
218
219   /* perspective */
220   if ( refView->Type() == V3d_PERSPECTIVE )
221     tgtView->SetFocale( refView->Focale() );
222
223   /* copy params */
224   Standard_Real x, y, z;
225   refView->At( x, y, z ); tgtView->SetAt( x, y, z );
226   refView->Up( x, y, z ); tgtView->SetUp( x, y, z );
227   refView->Eye( x, y, z ); tgtView->SetEye( x, y, z );
228   refView->Proj( x, y, z ); tgtView->SetProj( x, y, z );
229   refView->Center( x, y ); tgtView->SetCenter( x, y );
230   tgtView->SetScale( refView->Scale() );
231   tgtView->SetTwist( refView->Twist() );
232
233   /* update */
234   tgtView->Update();
235   tgtView->SetImmediateUpdate( Standard_True );
236   return true;
237 }
238
239 /*!
240   Returns Z-size of this view. [ public ]
241 */
242 double OCCViewer_ViewPort3d::getZSize() const
243 {
244   if ( !activeView().IsNull() )
245     return activeView()->ZSize();
246   return 0;
247 }
248
249 /*!
250   Sets Z-size of this view ( for both orthographic and perspective ). [ public ]
251 */
252 void OCCViewer_ViewPort3d::setZSize( double zsize )
253 {
254   myActiveView->SetZSize( zsize );
255   /*    if ( !myOrthoView.IsNull() )
256         myOrthoView->SetZSize( zsize );
257         if ( !myPerspView.IsNull() )
258         myPerspView->SetZSize( zsize );*/
259 }
260
261 /*!
262   Get axial scale to the view
263 */
264 void OCCViewer_ViewPort3d::getAxialScale( double& xScale, double& yScale, double& zScale )
265 {
266   xScale = yScale = zScale = 1.;
267
268   if ( !activeView().IsNull() )
269     activeView()->AxialScale( xScale, yScale, zScale );
270 }
271
272 /*!
273   Returns the background color [ virtual public ] [ obsolete ]
274 */
275 QColor OCCViewer_ViewPort3d::backgroundColor() const
276 {
277   return background().color();
278 }
279
280 /*!
281   Sets the background color [ virtual public ] [ obsolete ]
282 */
283 void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color )
284 {
285   Qtx::BackgroundData bg = background();
286   bg.setColor( color );
287   setBackground( bg );
288 }
289
290 /*!
291   Returns the background data
292 */
293 Qtx::BackgroundData OCCViewer_ViewPort3d::background() const
294 {
295   return myBackground;
296 }
297
298 /*!
299   Sets the background data
300 */
301 void OCCViewer_ViewPort3d::setBackground( const Qtx::BackgroundData& bgData )
302 {
303   if ( bgData.isValid() ) {
304     myBackground = bgData;
305     updateBackground();
306     emit vpChangeBackground( myBackground );
307   }
308 }
309
310 void OCCViewer_ViewPort3d::updateBackground()
311 {
312   if ( activeView().IsNull() ) return;
313   if ( !myBackground.isValid() ) return;
314
315   // VSR: Important note on below code.
316   // In OCCT (in version 6.5.2), things about the background drawing
317   // are not straightforward and not clearly understandable:
318   // - Horizontal gradient is drawn vertically (!), well ok, from top side to bottom one.
319   // - Vertical gradient is drawn horizontally (!), from right side to left one (!!!).
320   // - First and second diagonal gradients are confused.
321   // - Image texture, once set, can not be removed (!).
322   // - Texture image fill mode Aspect_FM_NONE is not taken into account (and means the same
323   //   as Aspect_FM_CENTERED).
324   // - The only way to cancel gradient background (and get back to single colored) is to
325   //   set gradient background style to Aspect_GFM_NONE while passing two colors is also needed
326   //   (see V3d_View::SetBgGradientColors() function).
327   // - Also, it is impossible to draw texture image above the gradiented background (only above
328   //   single-colored).
329   // In OCCT 6.5.3 all above mentioned problems are fixed; so, above comment should be removed as soon
330   // as SALOME is migrated to OCCT 6.5.3. The same concerns #ifdef statements in the below code
331   switch ( myBackground.mode() ) {
332   case Qtx::ColorBackground:
333     {
334       QColor c = myBackground.color();
335       if ( c.isValid() ) {
336         // Unset texture should be done here
337         // ...
338         Quantity_Color qCol( c.red()/255., c.green()/255., c.blue()/255., Quantity_TOC_RGB );
339 #if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
340         activeView()->SetBgGradientStyle( Aspect_GFM_NONE ); // cancel gradient background
341         activeView()->SetBgImageStyle( Aspect_FM_NONE );     // cancel texture background
342 #else
343         // cancel gradient background (in OCC before v6.5.3 the only way to do this is to set it to NONE type passing arbitrary colors as parameters)
344         activeView()->SetBgGradientColors( qCol, qCol, Aspect_GFM_NONE );
345 #endif
346         // then change background color
347         activeView()->SetBackgroundColor( qCol );
348         // update viewer
349         activeView()->Update();
350       }
351       break;
352     }
353   case Qtx::SimpleGradientBackground:
354     {
355       QColor c1, c2;
356       int type = myBackground.gradient( c1, c2 );
357       if ( c1.isValid() && type >= OCCViewer_Viewer::HorizontalGradient && type <= OCCViewer_Viewer::LastGradient ) {
358         // Unset texture should be done here
359         // ...
360         // Get colors and set-up gradiented background
361         if ( !c2.isValid() ) c2 = c1;
362         Quantity_Color qCol1( c1.red()/255., c1.green()/255., c1.blue()/255., Quantity_TOC_RGB );
363         Quantity_Color qCol2( c2.red()/255., c2.green()/255., c2.blue()/255., Quantity_TOC_RGB );
364         activeView()->SetBgImageStyle( Aspect_FM_NONE );    // cancel texture background
365         switch ( type ) {
366         case OCCViewer_Viewer::HorizontalGradient:
367 #if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
368           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_HOR, Standard_True );
369 #else
370           // in OCCT before v6.5.3, to draw horizontal gradient it's necessary to use Aspect_GFM_VER type
371           // and interchange the colors
372           activeView()->SetBgGradientColors( qCol2, qCol1, Aspect_GFM_VER, Standard_True );
373 #endif
374           break;
375         case OCCViewer_Viewer::VerticalGradient:
376 #if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
377           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_VER, Standard_True );
378 #else
379           // in OCCT before v6.5.3, to draw vertical gradient it's necessary to use Aspect_GFM_HOR type
380           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_HOR, Standard_True );
381 #endif
382           break;
383         case OCCViewer_Viewer::Diagonal1Gradient:
384 #if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
385           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG1, Standard_True );
386 #else
387           // in OCCT before v6.5.3, to draw 1st dialognal gradient it's necessary to use Aspect_GFM_DIAG2 type
388           // and interchange the colors
389           activeView()->SetBgGradientColors( qCol2, qCol1, Aspect_GFM_DIAG2, Standard_True );
390 #endif
391           break;
392         case OCCViewer_Viewer::Diagonal2Gradient:
393 #if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
394           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG2, Standard_True );
395 #else
396           // in OCCT before v6.5.3, to draw 2nd dialognal gradient it's necessary to use Aspect_GFM_DIAG1 type
397           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG1, Standard_True );
398 #endif
399           break;
400         case OCCViewer_Viewer::Corner1Gradient:
401           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER1, Standard_True );
402           break;
403         case OCCViewer_Viewer::Corner2Gradient:
404           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER2, Standard_True );
405           break;
406         case OCCViewer_Viewer::Corner3Gradient:
407           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER3, Standard_True );
408           break;
409         case OCCViewer_Viewer::Corner4Gradient:
410           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER4, Standard_True );
411           break;
412         default:
413           break;
414         }
415       }
416       break;
417     }
418   case Qtx::CustomGradientBackground:
419     {
420       // NOT IMPLEMENTED YET
421       break;
422     }
423   default:
424     break;
425   }
426 #if OCC_VERSION_LARGE > 0x06050200 // available since OCCT 6.5.3
427   // VSR: In OCCT before v6.5.3 below code can't be used because of very ugly bug - it has been impossible to
428   // clear the background texture image as soon as it was once set to the viewer.
429   if ( myBackground.isTextureShown() ) {
430     QString fileName;
431     int textureMode = myBackground.texture( fileName );
432     QFileInfo fi( fileName );
433     if ( !fileName.isEmpty() && fi.exists() ) {
434       // set texture image: file name and fill mode
435       switch ( textureMode ) {
436       case Qtx::CenterTexture:
437         activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_CENTERED );
438         break;
439       case Qtx::TileTexture:
440         activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_TILED );
441         break;
442       case Qtx::StretchTexture:
443         activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_STRETCH );
444         break;
445       default:
446         break;
447       }
448       activeView()->Update();
449     }
450   }
451 #endif
452 }
453
454 /*!
455   Updates the active viewport. [ virtual public ]
456 */
457 void OCCViewer_ViewPort3d::onUpdate()
458 {
459   if ( !activeView().IsNull() )
460     activeView()->Update();
461 }
462
463 /*!
464   Called at 'window fit' transformation. [ virtual protected ]
465 */
466 void OCCViewer_ViewPort3d::fitRect( const QRect& rect )
467 {
468   if ( !activeView().IsNull() ) {
469     activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() );
470     emit vpTransformed( this );
471   }
472 }
473
474 /*!
475   Inits 'zoom' transformation. [ protected ]
476 */
477 void OCCViewer_ViewPort3d::startZoomAtPoint( int x, int y )
478 {
479 #if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version
480   if ( !activeView().IsNull() && isAdvancedZoomingEnabled() )
481     activeView()->StartZoomAtPoint( x, y );
482 #endif
483 }
484
485 /*!
486   Called at 'zoom' transformation. [ virtual protected ]
487 */
488 void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
489 {
490   if ( !activeView().IsNull() ) {
491     // as OCCT respects a sign of only dx,
492     // but we want both signes to be taken into account
493     //activeView()->Zoom( x0, y0, x, y );
494 #if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version
495     if ( isAdvancedZoomingEnabled() )
496       activeView()->ZoomAtPoint( x0, y0, x, y );
497     else
498 #endif
499       activeView()->Zoom( x0 + y0, 0, x + y, 0 );
500     emit vpTransformed( this );
501   }
502 }
503
504 /*!
505   Centers the viewport. [ virtual protected ]
506 */
507 void OCCViewer_ViewPort3d::setCenter( int x, int y )
508 {
509   if ( !activeView().IsNull() ) {
510     activeView()->Place( x, y, myScale );
511     emit vpTransformed( this );
512   }
513 }
514
515 /*!
516   Called at 'pan' transformation. [ virtual protected ]
517 */
518 void OCCViewer_ViewPort3d::pan( int dx, int dy )
519 {
520   if ( !activeView().IsNull() ) {
521     activeView()->Pan( dx, dy, 1.0 );
522     emit vpTransformed( this );
523   }
524 }
525
526 /*!
527   Inits 'rotation' transformation. [ protected ]
528 */
529 void OCCViewer_ViewPort3d::startRotation( int x, int y,
530                                           int theRotationPointType,
531                                           const gp_Pnt& theSelectedPoint )
532 {
533   if ( !activeView().IsNull() ) {
534     //double gx, gy, gz;
535     //double gx = activeView()->gx;
536     //activeView()->Gravity(gx,gy,gz);
537
538     switch ( theRotationPointType ) {
539     case OCCViewer_ViewWindow::GRAVITY:
540       activeView()->StartRotation( x, y, 0.45 );
541       break;
542     case OCCViewer_ViewWindow::SELECTED:
543       sx = x; sy = y;
544
545       double X,Y;
546       activeView()->Size(X,Y);
547       rx = Standard_Real(activeView()->Convert(X));
548       ry = Standard_Real(activeView()->Convert(Y));
549
550       activeView()->Rotate( 0., 0., 0.,
551                             theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
552                             Standard_True );
553
554       Quantity_Ratio zRotationThreshold;
555       zRotation = Standard_False;
556       zRotationThreshold = 0.45;
557       if( zRotationThreshold > 0. ) {
558         Standard_Real dx = Abs(sx - rx/2.);
559         Standard_Real dy = Abs(sy - ry/2.);
560         Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
561         if( dx > dd || dy > dd ) zRotation = Standard_True;
562       }
563       break;
564     default:
565       break;
566     }
567     activeView()->DepthFitAll();
568   }
569 }
570
571 /*!
572   Rotates the viewport. [ protected ]
573 */
574 void OCCViewer_ViewPort3d::rotate( int x, int y,
575                                    int theRotationPointType,
576                                    const gp_Pnt& theSelectedPoint )
577 {
578   if ( !activeView().IsNull() ) {
579     switch ( theRotationPointType ) {
580     case OCCViewer_ViewWindow::GRAVITY:
581       activeView()->Rotation( x, y );
582       break;
583     case OCCViewer_ViewWindow::SELECTED:
584       double dx, dy, dz;
585       if( zRotation ) {
586         dz = atan2(Standard_Real(x)-rx/2., ry/2.-Standard_Real(y)) -
587           atan2(sx-rx/2.,ry/2.-sy);
588         dx = dy = 0.;
589       }
590       else {
591         dx = (Standard_Real(x) - sx) * M_PI/rx;
592         dy = (sy - Standard_Real(y)) * M_PI/ry;
593         dz = 0.;
594       }
595
596       activeView()->Rotate( dx, dy, dz,
597                             theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
598                             Standard_False );
599       break;
600     default:
601       break;
602     }
603     emit vpTransformed( this );
604   }
605   //  setZSize( getZSize() );
606 }
607
608 /*!
609   Resets the viewport after 'rotation'. [ protected ]
610 */
611 void OCCViewer_ViewPort3d::endRotation()
612 {
613   if ( !activeView().IsNull() ) {
614     activeView()->ZFitAll(1.);
615     activeView()->SetZSize(0.);
616     activeView()->Update();
617     emit vpTransformed( this );
618   }
619 }
620
621 /*!
622   Repaints the viewport. [ virtual protected ]
623 */
624 void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
625 {
626 #ifndef WNT
627   /* X11 : map before show doesn't work */
628   if ( !mapped( activeView() ) )
629     mapView( activeView() );
630 #endif
631   if ( !myWindow.IsNull() ) {
632     QApplication::syncX();
633     QRect rc = e->rect();
634     if ( !myPaintersRedrawing )
635       activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() );
636   }
637   OCCViewer_ViewPort::paintEvent( e );
638   myBusy = false;
639 }
640
641 /*!
642   Resizes the viewport. [ virtual protected ]
643 */
644 void OCCViewer_ViewPort3d::resizeEvent( QResizeEvent* e )
645 {
646 #ifdef WNT
647   /* Win32 : map before first show to avoid flicker */
648   if ( !mapped( activeView() ) )
649     mapView( activeView() );
650 #endif
651   QApplication::syncX();
652   if ( !activeView().IsNull() )
653     activeView()->MustBeResized();
654 }
655
656 /*!
657   Fits all objects in view. [ virtual protected ]
658 */
659 void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd )
660 {
661   if ( activeView().IsNull() )
662     return;
663
664   if ( keepScale )
665     myScale = activeView()->Scale();
666
667   Standard_Real margin = 0.01;
668   activeView()->FitAll( margin, withZ, upd );
669   activeView()->SetZSize(0.);
670   emit vpTransformed( this );
671 }
672
673 /*!
674   Resets the view. [ virtual protected ]
675 */
676 void OCCViewer_ViewPort3d::reset()
677 {
678   //  double zsize = getZSize();
679   if ( !activeView().IsNull() ) {
680     activeView()->Reset();
681     emit vpTransformed( this );
682   //    setZSize( zsize );
683   }
684 }
685
686 /*!
687   Rotate the view in the view plane (orthogonal to the view vector)
688 */
689 void OCCViewer_ViewPort3d::rotateXY( double degrees )
690 {
691   if ( activeView().IsNull() )
692     return;
693
694   int x = width()/2, y = height()/2;
695   double X, Y, Z;
696   activeView()->Convert( x, y, X, Y, Z );
697   activeView()->Rotate( 0, 0, degrees * M_PI / 180., X, Y, Z );
698   emit vpTransformed( this );
699 }
700
701 /*!
702   Set axial scale to the view
703 */
704 void OCCViewer_ViewPort3d::setAxialScale( double xScale, double yScale, double zScale )
705 {
706   if ( activeView().IsNull() )
707     return;
708
709   activeView()->SetAxialScale( xScale, yScale, zScale );
710   emit vpTransformed( this );
711 }
712
713 /*!
714   Passed the handle of native window of the component to CASCADE view. [ private ]
715 */
716 bool OCCViewer_ViewPort3d::setWindow( const Handle(V3d_View)& view )
717 {
718   if ( !myWindow.IsNull() )
719     return true;
720
721   if ( view.IsNull() )
722     return false;
723
724   attachWindow( view, OCCViewer_VService::CreateWindow( view, winId() ) );
725
726   myWindow = view->Window();
727   return !myWindow.IsNull();
728 }
729
730 void OCCViewer_ViewPort3d::attachWindow( const Handle(V3d_View)& view,
731                                          const Handle(Aspect_Window)& window)
732 {
733   if (!view.IsNull()) {
734     view->SetWindow( window );
735     updateBackground();
736   }
737 }
738
739 /*!
740   Returns the current active view. [ private ]
741 */
742 Handle(V3d_View) OCCViewer_ViewPort3d::activeView() const
743 {
744   return myActiveView;
745 }
746
747 /*!
748   Returns the current inactive view [ private ]
749 */
750 /*Handle(V3d_View) OCCViewer_ViewPort3d::inactiveView() const
751   {
752   return ( activeView() == myOrthoView ? myPerspView : myOrthoView );
753   }*/
754
755 /*!
756   Returns 'true' if the given view is mapped to window. [ private ]
757 */
758 bool OCCViewer_ViewPort3d::mapped( const Handle(V3d_View)& view ) const
759 {
760   return ( !view.IsNull() && view->View()->IsDefined() );
761 }
762
763 /*!
764   Performs synchronization of view parameters with the specified view.
765   Returns \c true if synchronization is done successfully or \c false otherwise.
766   Default implementation does nothing (return \c false)
767 */
768 bool OCCViewer_ViewPort3d::synchronize( OCCViewer_ViewPort* view )
769 {
770   bool ok = false;
771   OCCViewer_ViewPort3d* vp3d = qobject_cast<OCCViewer_ViewPort3d*>( view );
772   if ( vp3d ) {
773     bool blocked = blockSignals( false );
774     Handle(V3d_View) aView3d = getView();
775     Handle(V3d_View) aRefView3d = vp3d->getView();
776     aView3d->SetImmediateUpdate( Standard_False );
777     aView3d->SetViewMapping( aRefView3d->ViewMapping() );
778     aView3d->SetViewOrientation( aRefView3d->ViewOrientation() );
779     aView3d->ZFitAll();
780     aView3d->SetImmediateUpdate( Standard_True );
781     aView3d->Update();
782     blockSignals( blocked );
783     ok = true;
784   }
785   return ok;
786 }
787
788 /*
789  * Show/Hide static triedron
790  */
791 void OCCViewer_ViewPort3d::updateStaticTriedronVisibility() {
792   OCCViewer_ViewWindow* aVW = dynamic_cast<OCCViewer_ViewWindow*>( parentWidget()->parentWidget()->parentWidget() );
793   if ( aVW ) {
794     OCCViewer_Viewer* aViewModel = dynamic_cast<OCCViewer_Viewer*>( aVW->getViewManager()->getViewModel() );
795     Handle(V3d_View) aView = activeView();
796     if ( aViewModel ){
797       if(aViewModel->isStaticTrihedronDisplayed()) {
798         aView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
799       } else {
800         aView->TriedronErase();
801       }
802       aView->Update();
803     }
804   }
805 }