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