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