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