]> SALOME platform Git repositories - modules/gui.git/blob - src/OCCViewer/OCCViewer_ViewPort3d.cxx
Salome HOME
[bos #42871] Clipping plane remains applied after being deleted
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewPort3d.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, 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 #include <SUIT_Session.h>
32 #include <SUIT_ResourceMgr.h>
33
34 #include <QColor>
35 #include <QFileInfo>
36 #include <QString>
37 #include <QRect>
38 #include <QPaintEvent>
39 #include <QResizeEvent>
40 #include <QApplication>
41 #include <QTimer>
42 #include <QDateTime>
43
44 #include <gp_Quaternion.hxx>
45 #include <V3d_View.hxx>
46
47 #include "utilities.h"
48
49 #if defined WIN32
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 <Basics_OCCTVersion.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     myBusy( true ),
69     myScale( 1.0 ),
70     myIsAdvancedZoomingEnabled( false ),
71     myRotAngle( 0.0 ),
72     myIsRotating( false )
73 {
74   // VSR: 01/07/2010 commented to avoid SIGSEGV at SALOME exit
75   //selectVisualId();
76
77   myActiveView = new V3d_View( viewer, type );
78
79   setDefaultParams();
80
81   myCursor = NULL;
82   myRotTimer = NULL;
83 }
84
85 /*!
86   Destructor
87 */
88 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
89 {
90   if ( myRotTimer )
91   {
92     myRotTimer->stop();
93     delete myRotTimer;
94     myRotTimer = NULL;
95   }
96
97   if ( myCursor )
98   {
99     delete myCursor;
100     myCursor = NULL;
101   }
102
103   emit vpClosed(this);
104   Handle(V3d_View) aView = activeView();
105   if (!aView.IsNull())
106     aView->Remove();
107 }
108
109 /*!
110   Activates the desired 'type' of view in the viewer
111   ( view of 'type' is created if it doesn't exist ). [ public ]
112 */
113 /*void OCCViewer_ViewPort3d::setActive( V3d_TypeOfView type )
114 {
115   if ( activeView().IsNull() )
116   return;
117
118   if ( activeView()->Type() != type )
119   {
120   if ( type == V3d_ORTHOGRAPHIC )
121   setView( myOrthoView );
122   if ( type == V3d_PERSPECTIVE )
123   setView( myPerspView );
124   }
125 }*/
126
127 /*!
128   Maps CasCade 'view' to this viewport. [ private ]
129 */
130 bool OCCViewer_ViewPort3d::mapView( const Handle(V3d_View)& view )
131 {
132   if ( !setWindow( view ) )
133     return false;
134
135   if ( !mapped( view ) ) {
136     view->SetWindow( myWindow );
137     if ( view != activeView() )
138       view->View()->Deactivate();
139   }
140
141   emit( vpMapped(this) );
142
143   return true;
144 }
145
146
147
148 /*!
149   Sets new CASCADE view on viewport. Returns the previous active view. [ public ]
150 */
151 Handle( V3d_View ) OCCViewer_ViewPort3d::setView( const Handle( V3d_View )& view )
152 {
153   /* map the new view */
154   if ( view == activeView() || !mapView( view ) )
155     return activeView();
156
157   /* activate the new view*/
158   Handle( V3d_View ) oldView = activeView();
159   if ( !oldView.IsNull() ) {
160     if (oldView->View()->IsDefined())
161       oldView->View()->Deactivate();
162     view->SetBackgroundColor( oldView->BackgroundColor() );
163   }
164
165   view->View()->Activate();
166   activeView() = view;
167   return oldView;
168 }
169
170 /*!
171   Returns CasCade 3D view. [ public ]
172 */
173 Handle(V3d_View) OCCViewer_ViewPort3d::getView() const
174 {
175   return activeView();
176 }
177
178 /*!
179   Returns CasCade 3D viewer [ public ]
180 */
181 Handle(V3d_Viewer) OCCViewer_ViewPort3d::getViewer() const
182 {
183   Handle(V3d_Viewer) viewer;
184   if ( !activeView().IsNull() )
185     viewer = activeView()->Viewer();
186   return viewer;
187 }
188
189 /*!
190   Syncronizes visual state of this viewport with 'ref'
191   ( scale, projection, eye etc ) Returns 'true' if copied OK,
192   'false' otherwise. [ virtual public ]
193 */
194 bool OCCViewer_ViewPort3d::syncronize( const OCCViewer_ViewPort3d* ref )
195 {
196   OCCViewer_ViewPort3d* ref3d = (OCCViewer_ViewPort3d*)ref;
197   Handle(V3d_View) refView = ref3d->getView();
198   Handle(V3d_View) tgtView = getView();
199
200   /* Syncronize view types */
201   /*    if ( tgtView->Type() != refView->Type() )
202         {
203         setActive( refView->Type() );
204         tgtView = getView();
205         }*/
206
207   /*  The following params are copied:
208       - view type( ortho/persp )
209       - position of view point
210       - orientation of high point
211       - position of the eye
212       - projection vector
213       - view center ( 2D )
214       - view twist
215       - view scale
216   */
217
218   /* we'll update after setting all params */
219   tgtView->SetImmediateUpdate( Standard_False );
220
221   /* perspective */
222   if ( refView->Type() == V3d_PERSPECTIVE )
223     tgtView->SetFocale( refView->Focale() );
224
225   /* copy params */
226   Standard_Real x, y, z;
227   refView->At( x, y, z ); tgtView->SetAt( x, y, z );
228   refView->Up( x, y, z ); tgtView->SetUp( x, y, z );
229   refView->Eye( x, y, z ); tgtView->SetEye( x, y, z );
230   refView->Proj( x, y, z ); tgtView->SetProj( x, y, z );
231   tgtView->SetScale( refView->Scale() );
232   tgtView->SetTwist( refView->Twist() );
233
234   /* update */
235   tgtView->Update();
236   tgtView->SetImmediateUpdate( Standard_True );
237
238   return true;
239 }
240
241
242 /*!
243   Get axial scale to the view
244 */
245 void OCCViewer_ViewPort3d::getAxialScale( double& xScale, double& yScale, double& zScale )
246 {
247   xScale = yScale = zScale = 1.;
248
249   if ( !activeView().IsNull() )
250     activeView()->AxialScale( xScale, yScale, zScale );
251 }
252
253 /*!
254   Returns the background color [ virtual public ] [ obsolete ]
255 */
256 QColor OCCViewer_ViewPort3d::backgroundColor() const
257 {
258   return background().color();
259 }
260
261 /*!
262   Sets the background color [ virtual public ] [ obsolete ]
263 */
264 void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color )
265 {
266   Qtx::BackgroundData bg = background();
267   bg.setColor( color );
268   setBackground( bg );
269 }
270
271 /*!
272   Returns the background data
273 */
274 Qtx::BackgroundData OCCViewer_ViewPort3d::background() const
275 {
276   return myBackground;
277 }
278
279 /*!
280   Sets the background data
281 */
282 void OCCViewer_ViewPort3d::setBackground( const Qtx::BackgroundData& bgData )
283 {
284   if ( bgData.isValid() ) {
285     myBackground = bgData;
286     updateBackground();
287     emit vpChangeBackground( myBackground );
288   }
289 }
290
291 void OCCViewer_ViewPort3d::updateBackground()
292 {
293   if ( activeView().IsNull() ) return;
294   if ( !myBackground.isValid() ) return;
295
296   switch ( myBackground.mode() ) {
297   case Qtx::ColorBackground:
298     {
299       QColor c = myBackground.color();
300       if ( c.isValid() ) {
301         // Unset texture should be done here
302         // ...
303         Quantity_Color qCol( c.red()/255., c.green()/255., c.blue()/255., Quantity_TOC_RGB );
304         activeView()->SetBgGradientStyle( Aspect_GFM_NONE ); // cancel gradient background
305         activeView()->SetBgImageStyle( Aspect_FM_NONE );     // cancel texture background
306         // then change background color
307         activeView()->SetBackgroundColor( qCol );
308         // update viewer
309         activeView()->Update();
310       }
311       break;
312     }
313   case Qtx::SimpleGradientBackground:
314     {
315       QColor c1, c2;
316       int type = myBackground.gradient( c1, c2 );
317       if ( c1.isValid() && type >= OCCViewer_Viewer::HorizontalGradient && type <= OCCViewer_Viewer::LastGradient ) {
318         // Unset texture should be done here
319         // ...
320         // Get colors and set-up gradiented background
321         if ( !c2.isValid() ) c2 = c1;
322         Quantity_Color qCol1( c1.red()/255., c1.green()/255., c1.blue()/255., Quantity_TOC_RGB );
323         Quantity_Color qCol2( c2.red()/255., c2.green()/255., c2.blue()/255., Quantity_TOC_RGB );
324         activeView()->SetBgImageStyle( Aspect_FM_NONE );    // cancel texture background
325 #if OCC_VERSION_LARGE > 0x07070000
326         switch ( type ) {
327         case OCCViewer_Viewer::HorizontalGradient:
328           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GradientFillMethod_Horizontal, Standard_True );
329           break;
330         case OCCViewer_Viewer::VerticalGradient:
331           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GradientFillMethod_Vertical, Standard_True );
332           break;
333         case OCCViewer_Viewer::Diagonal1Gradient:
334           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GradientFillMethod_Diagonal1, Standard_True );
335           break;
336         case OCCViewer_Viewer::Diagonal2Gradient:
337           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GradientFillMethod_Diagonal2, Standard_True );
338           break;
339         case OCCViewer_Viewer::Corner1Gradient:
340           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GradientFillMethod_Corner1, Standard_True );
341           break;
342         case OCCViewer_Viewer::Corner2Gradient:
343           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GradientFillMethod_Corner2, Standard_True );
344           break;
345         case OCCViewer_Viewer::Corner3Gradient:
346           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GradientFillMethod_Corner3, Standard_True );
347           break;
348         case OCCViewer_Viewer::Corner4Gradient:
349           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GradientFillMethod_Corner4, Standard_True );
350           break;
351         default:
352           break;
353         }
354 #else
355         switch ( type ) {
356         case OCCViewer_Viewer::HorizontalGradient:
357           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_HOR, Standard_True );
358           break;
359         case OCCViewer_Viewer::VerticalGradient:
360           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_VER, Standard_True );
361           break;
362         case OCCViewer_Viewer::Diagonal1Gradient:
363           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG1, Standard_True );
364           break;
365         case OCCViewer_Viewer::Diagonal2Gradient:
366           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG2, Standard_True );
367           break;
368         case OCCViewer_Viewer::Corner1Gradient:
369           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER1, Standard_True );
370           break;
371         case OCCViewer_Viewer::Corner2Gradient:
372           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER2, Standard_True );
373           break;
374         case OCCViewer_Viewer::Corner3Gradient:
375           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER3, Standard_True );
376           break;
377         case OCCViewer_Viewer::Corner4Gradient:
378           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER4, Standard_True );
379           break;
380         default:
381           break;
382         }
383 #endif
384       }
385       break;
386     }
387   case Qtx::CustomGradientBackground:
388     {
389       // NOT IMPLEMENTED YET
390       break;
391     }
392   default:
393     break;
394   }
395   if ( myBackground.isTextureShown() ) {
396     QString fileName;
397     int textureMode = myBackground.texture( fileName );
398     QFileInfo fi( fileName );
399     if ( !fileName.isEmpty() && fi.exists() ) {
400       // set texture image: file name and fill mode
401       switch ( textureMode ) {
402       case Qtx::CenterTexture:
403         activeView()->SetBackgroundImage( fi.absoluteFilePath().toUtf8().constData(), Aspect_FM_CENTERED );
404         break;
405       case Qtx::TileTexture:
406         activeView()->SetBackgroundImage( fi.absoluteFilePath().toUtf8().constData(), Aspect_FM_TILED );
407         break;
408       case Qtx::StretchTexture:
409         activeView()->SetBackgroundImage( fi.absoluteFilePath().toUtf8().constData(), Aspect_FM_STRETCH );
410         break;
411       default:
412         break;
413       }
414       activeView()->Update();
415     }
416   }
417 }
418
419 /*!
420   Updates the active viewport. [ virtual public ]
421 */
422 void OCCViewer_ViewPort3d::onUpdate()
423 {
424   if ( !activeView().IsNull() )
425     activeView()->Update();
426 }
427
428 /*!
429   Called at 'window fit' transformation. [ virtual protected ]
430 */
431 void OCCViewer_ViewPort3d::fitRect( const QRect& rect )
432 {
433   if ( !activeView().IsNull() ) {
434     activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() );
435     emit vpTransformed( this );
436   }
437 }
438
439 /*!
440   Inits 'zoom' transformation. [ protected ]
441 */
442 void OCCViewer_ViewPort3d::startZoomAtPoint( int x, int y )
443 {
444   // if (myIsRotating)
445   //   stopRotation();
446
447   if ( !activeView().IsNull() && isAdvancedZoomingEnabled() )
448     activeView()->StartZoomAtPoint( x, y );
449 }
450
451 /*!
452   Called at 'zoom' transformation. [ virtual protected ]
453 */
454 void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
455 {
456   // if (myIsRotating)
457   //   stopRotation();
458
459   if ( !activeView().IsNull() ) {
460     // as OCCT respects a sign of only dx,
461     // but we want both signes to be taken into account
462     //activeView()->Zoom( x0, y0, x, y );
463     if ( isAdvancedZoomingEnabled() )
464       activeView()->ZoomAtPoint( x0, y0, x, y );
465     else
466       activeView()->Zoom( x0 + y0, 0, x + y, 0 );
467     emit vpTransformed( this );
468   }
469 }
470
471 /*!
472   Centers the viewport. [ virtual protected ]
473 */
474 void OCCViewer_ViewPort3d::setCenter( int x, int y )
475 {
476   if (myIsRotating)
477     stopRotation();
478
479   if ( !activeView().IsNull() ) {
480     activeView()->Place( x, y, myScale );
481     emit vpTransformed( this );
482   }
483 }
484
485 /*!
486   Called at 'pan' transformation. [ virtual protected ]
487 */
488 void OCCViewer_ViewPort3d::pan( int dx, int dy )
489 {
490   if (myIsRotating)
491     stopRotation();
492
493   if ( !activeView().IsNull() ) {
494     activeView()->Pan( dx, dy, 1.0 );
495     emit vpTransformed( this );
496   }
497 }
498
499 /*!
500   Inits 'rotation' transformation. [ protected ]
501 */
502 void OCCViewer_ViewPort3d::startRotation( int x, int y,
503                                           int theRotationPointType,
504                                           const gp_Pnt& theSelectedPoint )
505 {
506   if (myIsRotating)
507     stopRotation();
508
509   if ( !activeView().IsNull() ) {
510
511     Standard_Real zRotationThreshold, X, Y;
512     sx = x; sy = y;
513     activeView()->Size(X,Y);
514     rx = Standard_Real(activeView()->Convert(X));
515     ry = Standard_Real(activeView()->Convert(Y));
516     gp_Pnt centerPnt;
517
518     switch ( theRotationPointType ) {
519     case OCCViewer_ViewWindow::BBCENTER:
520       centerPnt = activeView()->GravityPoint();
521       zRotation = Standard_False;
522       zRotationThreshold = 0.45;
523       if( zRotationThreshold > 0. ) {
524         Standard_Real dx = Abs(sx - rx/2.);
525         Standard_Real dy = Abs(sy - ry/2.);
526         Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
527         if( dx > dd || dy > dd ) zRotation = Standard_True;
528       }
529       activeView()->StartRotation( x, y, 0.45 );
530       break;
531     case OCCViewer_ViewWindow::SELECTED:
532       activeView()->Rotate( 0., 0., 0.,
533                             theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
534                             Standard_True );
535
536       zRotation = Standard_False;
537       zRotationThreshold = 0.45;
538       if( zRotationThreshold > 0. ) {
539         Standard_Real dx = Abs(sx - rx/2.);
540         Standard_Real dy = Abs(sy - ry/2.);
541         Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
542         if( dx > dd || dy > dd ) zRotation = Standard_True;
543       }
544       break;
545     default:
546       break;
547     }
548     // VSR: 10.06.2015: next line commented out - causes ugly blinking on starting rotation with Perspective projection mode
549     //activeView()->DepthFitAll();
550   }
551 }
552
553 /*!
554   Rotates the viewport. [ protected ]
555 */
556 void OCCViewer_ViewPort3d::rotate( int x, int y,
557                                    int theRotationPointType,
558                                    const gp_Pnt& theSelectedPoint )
559 {
560   if ( !activeView().IsNull() ) {
561     switch ( theRotationPointType ) {
562     case OCCViewer_ViewWindow::BBCENTER:
563       activeView()->Rotation( x, y );
564       break;
565     case OCCViewer_ViewWindow::SELECTED:
566       double dx, dy, dz;
567       if( zRotation ) {
568         dz = atan2(Standard_Real(x)-rx/2., ry/2.-Standard_Real(y)) -
569           atan2(sx-rx/2.,ry/2.-sy);
570         dx = dy = 0.;
571       }
572       else {
573         dx = (Standard_Real(x) - sx) * M_PI/rx;
574         dy = (sy - Standard_Real(y)) * M_PI/ry;
575         dz = 0.;
576       }
577
578       activeView()->Rotate( dx, dy, dz,
579                             theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
580                             Standard_False );
581       break;
582     default:
583       break;
584     }
585     emit vpTransformed( this );
586   }
587   //  setZSize( getZSize() );
588 }
589
590 /*!
591   Resets the viewport after 'rotation'. [ protected ]
592 */
593 void OCCViewer_ViewPort3d::endRotation()
594 {
595   if ( !activeView().IsNull() ) {
596     activeView()->Update();
597     emit vpTransformed( this );
598   }
599 }
600
601 /*!
602   Set the rotation axis and start automatic rotation
603 */
604 void OCCViewer_ViewPort3d::setRotationAxis(const gp_Vec& theAxis, double theAngle, double theZAngle)
605 {
606   myRotAxis.SetLocation(activeView()->GravityPoint());
607   if (zRotation) {
608     gp_Dir anAxisDir = activeView()->Camera()->Direction();
609     myRotAxis.SetDirection(anAxisDir.Reversed());
610     myRotAngle = theZAngle;
611   }
612   else {
613     myRotAxis.SetDirection(gp_Dir(theAxis));
614     myRotAngle = theAngle;
615   }
616   if (!myRotTimer) {
617     myRotTimer = new QTimer(this);
618     myRotTimer->setSingleShot(true);
619     connect(myRotTimer, SIGNAL(timeout()), this, SLOT(updateRotation()));
620   }
621   else
622     myRotTimer->stop();
623
624   myIsRotating = true;
625   myLastRender = QDateTime::currentMSecsSinceEpoch();
626   Handle(Graphic3d_Camera) aCamera = activeView()->Camera();
627   gp_Trsf trsfRot;
628   trsfRot.SetRotation (myRotAxis, myRotAngle);
629   aCamera->Transform(trsfRot);
630   activeView()->SetCamera(aCamera);
631   myRotTimer->start(20);
632 }
633
634 /*!
635   Stop the automatic rotation
636 */
637 void OCCViewer_ViewPort3d::stopRotation()
638 {
639   myIsRotating = false;
640   if (myRotTimer)
641     myRotTimer->stop();
642 }
643
644 /*!
645   Update the automatic rotation animation
646 */
647 void OCCViewer_ViewPort3d::updateRotation()
648 {
649   if (!myIsRotating)
650     return;
651
652   qint64 curTime = QDateTime::currentMSecsSinceEpoch();
653   double angle = myRotAngle * (curTime - myLastRender) / 100.;
654   Handle(Graphic3d_Camera) aCamera = activeView()->Camera();
655   gp_Trsf trsfRot;
656   trsfRot.SetRotation(myRotAxis, angle);
657   aCamera->Transform(trsfRot);
658   activeView()->SetCamera(aCamera);
659
660   myLastRender = curTime;
661   if (myRotTimer)
662     myRotTimer->start(20);
663 }
664
665 /*!
666   Repaints the viewport. [ virtual protected ]
667 */
668 void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
669 {
670 #ifndef WIN32
671   /* X11 : map before show doesn't work */
672   if ( !mapped( activeView() ) )
673     mapView( activeView() );
674 #endif
675   if ( !myWindow.IsNull() ) {
676     if ( !myPaintersRedrawing ) {
677       activeView()->Redraw();
678     }
679   }
680   OCCViewer_ViewPort::paintEvent( e );
681   myBusy = false;
682 }
683
684 /*!
685   Resizes the viewport. [ virtual protected ]
686 */
687 void OCCViewer_ViewPort3d::resizeEvent( QResizeEvent* e )
688 {
689   /* Map before first show to avoid flicker */
690   if ( !mapped( activeView() ) )
691     mapView( activeView() );
692   QTimer::singleShot( 0, this, SLOT( repaintViewAfterMove() ) );
693   emit vpResizeEvent( e );
694 }
695
696 /*!
697   Moved the viewport
698 */
699 void OCCViewer_ViewPort3d::repaintViewAfterMove( )
700 {
701   if ( !activeView().IsNull() ){
702     activeView()->MustBeResized();
703   }
704 }
705
706 /*!
707   Fits all objects in view. [ virtual protected ]
708 */
709 void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool /*withZ*/, bool upd )
710 {
711   if ( activeView().IsNull() )
712     return;
713
714   if (myIsRotating)
715     stopRotation();
716
717   if ( keepScale )
718     myScale = activeView()->Scale();
719
720   Standard_Real margin = 0.01;
721   
722   activeView()->FitAll( margin, upd );
723
724   emit vpTransformed( this );
725 }
726
727 /*!
728   Resets the view. [ virtual protected ]
729 */
730 void OCCViewer_ViewPort3d::reset()
731 {
732   if (myIsRotating)
733     stopRotation();
734
735   //  double zsize = getZSize();
736   if ( !activeView().IsNull() ) {
737     activeView()->Reset();
738     emit vpTransformed( this );
739   //    setZSize( zsize );
740   }
741 }
742
743 /*!
744   Rotate the view in the view plane (orthogonal to the view vector)
745 */
746 void OCCViewer_ViewPort3d::rotateXY( double degrees )
747 {
748   if ( activeView().IsNull() )
749     return;
750
751   if (myIsRotating)
752     stopRotation();
753
754   int x = width()/2, y = height()/2;
755   double X, Y, Z;
756   activeView()->Convert( x, y, X, Y, Z );
757   activeView()->Rotate( 0, 0, degrees * M_PI / 180., X, Y, Z );
758   emit vpTransformed( this );
759 }
760
761 /*!
762   Set axial scale to the view
763 */
764 void OCCViewer_ViewPort3d::setAxialScale( double xScale, double yScale, double zScale )
765 {
766   if ( activeView().IsNull() )
767     return;
768
769   activeView()->SetAxialScale( xScale, yScale, zScale );
770   emit vpTransformed( this );
771 }
772
773 /*!
774   Passed the handle of native window of the component to CASCADE view. [ private ]
775 */
776 bool OCCViewer_ViewPort3d::setWindow( const Handle(V3d_View)& view )
777 {
778   if ( !myWindow.IsNull() )
779     return true;
780
781   if ( view.IsNull() )
782     return false;
783
784   attachWindow( view, OCCViewer_VService::CreateWindow( view, winId() ) );
785
786   myWindow = view->Window();
787   return !myWindow.IsNull();
788 }
789
790 void OCCViewer_ViewPort3d::attachWindow( const Handle(V3d_View)& view,
791                                          const Handle(Aspect_Window)& window)
792 {
793   if (!view.IsNull()) {
794 #if OCC_VERSION_LARGE > 0x07070000
795     // Workaround for OCCT bug 33647 (porting to OCCT 7.8.0 regression).
796     if (myBackground.isValid()) {
797       if (myBackground.mode() == Qtx::SimpleGradientBackground) {
798         QColor c1, c2;
799         int type = myBackground.gradient(c1, c2);
800         if (type >= OCCViewer_Viewer::Corner1Gradient &&
801             type <= OCCViewer_Viewer::Corner4Gradient) {
802           if (!c2.isValid()) c2 = c1;
803           Quantity_Color qCol1 (c1.red()/255., c1.green()/255., c1.blue()/255., Quantity_TOC_RGB);
804           Quantity_Color qCol2 (c2.red()/255., c2.green()/255., c2.blue()/255., Quantity_TOC_RGB);
805           view->SetBgImageStyle(Aspect_FM_NONE);    // cancel texture background
806           // Set first horizontal gradient background, as first
807           // initialization with corner gradient leads to a bug.
808           //view->SetBgGradientColors(qCol1, qCol2, Aspect_GradientFillMethod_Horizontal, Standard_True);
809           view->SetBgGradientColors(qCol1, qCol2, Aspect_GradientFillMethod_Horizontal);
810         }
811       }
812     }
813 #endif
814     view->SetWindow( window );
815     updateBackground();
816   }
817 }
818
819 /*!
820   Returns the current active view. [ private ]
821 */
822 Handle(V3d_View) OCCViewer_ViewPort3d::activeView() const
823 {
824   return myActiveView;
825 }
826
827 /*!
828   Returns the current inactive view [ private ]
829 */
830 /*Handle(V3d_View) OCCViewer_ViewPort3d::inactiveView() const
831   {
832   return ( activeView() == myOrthoView ? myPerspView : myOrthoView );
833   }*/
834
835 /*!
836   Returns 'true' if the given view is mapped to window. [ private ]
837 */
838 bool OCCViewer_ViewPort3d::mapped( const Handle(V3d_View)& view ) const
839 {
840   return ( !view.IsNull() && view->View()->IsDefined() );
841 }
842
843 /*!
844   Performs synchronization of view parameters with the specified view.
845   Returns \c true if synchronization is done successfully or \c false otherwise.
846   Default implementation does nothing (return \c false)
847 */
848 bool OCCViewer_ViewPort3d::synchronize( OCCViewer_ViewPort* view )
849 {
850   bool ok = false;
851   OCCViewer_ViewPort3d* vp3d = qobject_cast<OCCViewer_ViewPort3d*>( view );
852   if ( vp3d ) {
853     bool blocked = blockSignals( false );
854     Handle(V3d_View) aView3d = getView();
855     Handle(V3d_View) aRefView3d = vp3d->getView();
856     aView3d->SetImmediateUpdate( Standard_False );
857     aView3d->Camera()->Copy( aRefView3d->Camera() );
858     aView3d->SetImmediateUpdate( Standard_True );
859     aView3d->Update();
860     blockSignals( blocked );
861     ok = true;
862   }
863   return ok;
864 }
865
866 /*
867  * Show/Hide static triedron
868  */
869 void OCCViewer_ViewPort3d::showStaticTrihedron( bool on )
870 {
871   Handle(V3d_View) aView = activeView();
872   if ( !aView ) return;
873   
874   if ( on ) {
875     aView->ZBufferTriedronSetup();
876     aView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
877   } else {
878     aView->TriedronErase();
879   }
880   aView->Update();
881 }
882
883 /*
884  * Create default cursor with a specific shape
885  */
886 void OCCViewer_ViewPort3d::setDefaultCursor( Qt::CursorShape theCursorShape )
887 {
888   if ( !myCursor )
889     myCursor = new QCursor();
890
891   myCursor->setShape( theCursorShape );
892 }
893
894 /*
895  * Get default cursor with a specific shape
896  */
897 QCursor* OCCViewer_ViewPort3d::getDefaultCursor() const
898 {
899   return myCursor;
900 }
901
902 /*
903  * Set default parameters from preferences
904  */
905 void OCCViewer_ViewPort3d::setDefaultParams()
906 {
907   setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background
908
909   // get ray tracing parameters from preferences
910   int aDepth = SUIT_Session::session()->resourceMgr()->integerValue( "OCCViewer", "rt_depth", 3 );
911   bool aReflection = SUIT_Session::session()->resourceMgr()->booleanValue( "OCCViewer", "rt_reflection", true );
912   bool anAntialiasing = SUIT_Session::session()->resourceMgr()->booleanValue( "OCCViewer", "rt_antialiasing", false );
913   bool aShadow = SUIT_Session::session()->resourceMgr()->booleanValue( "OCCViewer", "rt_shadow", true );
914   bool aTransparentShadow = SUIT_Session::session()->resourceMgr()->booleanValue( "OCCViewer", "rt_trans_shadow", true );
915
916   Graphic3d_RenderingParams& aParams = myActiveView->ChangeRenderingParams();
917   aParams.RaytracingDepth = aDepth;
918   aParams.IsReflectionEnabled = aReflection;
919   aParams.IsAntialiasingEnabled = anAntialiasing;
920   aParams.IsShadowEnabled = aShadow;
921   aParams.IsTransparentShadowEnabled = aTransparentShadow;
922   myActiveView->Redraw();
923 }