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