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