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