Salome HOME
[HYDRO 514] Use specific cursors for edition operations.
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewPort3d.cxx
1 // Copyright (C) 2007-2015  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   myCursor = NULL;
94 }
95
96 /*!
97   Destructor
98 */
99 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
100 {
101   if ( myCursor )
102   {
103     delete myCursor;
104     myCursor = NULL;
105   }
106
107   emit vpClosed(this);
108   Handle(V3d_View) aView = activeView();
109   if (!aView.IsNull())
110     aView->Remove();
111 }
112
113 /*!
114   Activates the desired 'type' of view in the viewer
115   ( view of 'type' is created if it doesn't exist ). [ public ]
116 */
117 /*void OCCViewer_ViewPort3d::setActive( V3d_TypeOfView type )
118 {
119   if ( activeView().IsNull() )
120   return;
121
122   if ( activeView()->Type() != type )
123   {
124   if ( type == V3d_ORTHOGRAPHIC )
125   setView( myOrthoView );
126   if ( type == V3d_PERSPECTIVE )
127   setView( myPerspView );
128   }
129 }*/
130
131 /*!
132   Maps CasCade 'view' to this viewport. [ private ]
133 */
134 bool OCCViewer_ViewPort3d::mapView( const Handle(V3d_View)& view )
135 {
136   if ( !setWindow( view ) )
137     return false;
138
139   if ( !mapped( view ) ) {
140     view->SetWindow( myWindow );
141     if ( view != activeView() )
142       view->View()->Deactivate();
143   }
144
145   emit( vpMapped(this) );
146
147   return true;
148 }
149
150
151
152 /*!
153   Sets new CASCADE view on viewport. Returns the previous active view. [ public ]
154 */
155 Handle( V3d_View ) OCCViewer_ViewPort3d::setView( const Handle( V3d_View )& view )
156 {
157   /* map the new view */
158   if ( view == activeView() || !mapView( view ) )
159     return activeView();
160
161   /* activate the new view*/
162   Handle( V3d_View ) oldView = activeView();
163   if ( !oldView.IsNull() ) {
164     if (oldView->View()->IsDefined())
165       oldView->View()->Deactivate();
166     view->SetBackgroundColor( oldView->BackgroundColor() );
167   }
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 #if OCC_VERSION_LARGE <= 0x06070100
236   refView->Center( x, y ); tgtView->SetCenter( x, y );
237 #endif
238   tgtView->SetScale( refView->Scale() );
239   tgtView->SetTwist( refView->Twist() );
240
241   /* update */
242   tgtView->Update();
243   tgtView->SetImmediateUpdate( Standard_True );
244   tgtView->ZFitAll();
245   return true;
246 }
247
248 /*!
249   Returns Z-size of this view. [ public ]
250 */
251 double OCCViewer_ViewPort3d::getZSize() const
252 {
253   if ( !activeView().IsNull() )
254     return activeView()->ZSize();
255   return 0;
256 }
257
258 /*!
259   Sets Z-size of this view ( for both orthographic and perspective ). [ public ]
260 */
261 void OCCViewer_ViewPort3d::setZSize( double zsize )
262 {
263   myActiveView->SetZSize( zsize );
264   /*    if ( !myOrthoView.IsNull() )
265         myOrthoView->SetZSize( zsize );
266         if ( !myPerspView.IsNull() )
267         myPerspView->SetZSize( zsize );*/
268 }
269
270 /*!
271   Get axial scale to the view
272 */
273 void OCCViewer_ViewPort3d::getAxialScale( double& xScale, double& yScale, double& zScale )
274 {
275   xScale = yScale = zScale = 1.;
276
277   if ( !activeView().IsNull() )
278     activeView()->AxialScale( xScale, yScale, zScale );
279 }
280
281 /*!
282   Returns the background color [ virtual public ] [ obsolete ]
283 */
284 QColor OCCViewer_ViewPort3d::backgroundColor() const
285 {
286   return background().color();
287 }
288
289 /*!
290   Sets the background color [ virtual public ] [ obsolete ]
291 */
292 void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color )
293 {
294   Qtx::BackgroundData bg = background();
295   bg.setColor( color );
296   setBackground( bg );
297 }
298
299 /*!
300   Returns the background data
301 */
302 Qtx::BackgroundData OCCViewer_ViewPort3d::background() const
303 {
304   return myBackground;
305 }
306
307 /*!
308   Sets the background data
309 */
310 void OCCViewer_ViewPort3d::setBackground( const Qtx::BackgroundData& bgData )
311 {
312   if ( bgData.isValid() ) {
313     myBackground = bgData;
314     updateBackground();
315     emit vpChangeBackground( myBackground );
316   }
317 }
318
319 void OCCViewer_ViewPort3d::updateBackground()
320 {
321   if ( activeView().IsNull() ) return;
322   if ( !myBackground.isValid() ) return;
323
324   switch ( myBackground.mode() ) {
325   case Qtx::ColorBackground:
326     {
327       QColor c = myBackground.color();
328       if ( c.isValid() ) {
329         // Unset texture should be done here
330         // ...
331         Quantity_Color qCol( c.red()/255., c.green()/255., c.blue()/255., Quantity_TOC_RGB );
332         activeView()->SetBgGradientStyle( Aspect_GFM_NONE ); // cancel gradient background
333         activeView()->SetBgImageStyle( Aspect_FM_NONE );     // cancel texture background
334         // then change background color
335         activeView()->SetBackgroundColor( qCol );
336         // update viewer
337         activeView()->Update();
338       }
339       break;
340     }
341   case Qtx::SimpleGradientBackground:
342     {
343       QColor c1, c2;
344       int type = myBackground.gradient( c1, c2 );
345       if ( c1.isValid() && type >= OCCViewer_Viewer::HorizontalGradient && type <= OCCViewer_Viewer::LastGradient ) {
346         // Unset texture should be done here
347         // ...
348         // Get colors and set-up gradiented background
349         if ( !c2.isValid() ) c2 = c1;
350         Quantity_Color qCol1( c1.red()/255., c1.green()/255., c1.blue()/255., Quantity_TOC_RGB );
351         Quantity_Color qCol2( c2.red()/255., c2.green()/255., c2.blue()/255., Quantity_TOC_RGB );
352         activeView()->SetBgImageStyle( Aspect_FM_NONE );    // cancel texture background
353         switch ( type ) {
354         case OCCViewer_Viewer::HorizontalGradient:
355           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_HOR, Standard_True );
356           break;
357         case OCCViewer_Viewer::VerticalGradient:
358           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_VER, Standard_True );
359           break;
360         case OCCViewer_Viewer::Diagonal1Gradient:
361           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG1, Standard_True );
362           break;
363         case OCCViewer_Viewer::Diagonal2Gradient:
364           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG2, Standard_True );
365           break;
366         case OCCViewer_Viewer::Corner1Gradient:
367           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER1, Standard_True );
368           break;
369         case OCCViewer_Viewer::Corner2Gradient:
370           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER2, Standard_True );
371           break;
372         case OCCViewer_Viewer::Corner3Gradient:
373           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER3, Standard_True );
374           break;
375         case OCCViewer_Viewer::Corner4Gradient:
376           activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER4, Standard_True );
377           break;
378         default:
379           break;
380         }
381       }
382       break;
383     }
384   case Qtx::CustomGradientBackground:
385     {
386       // NOT IMPLEMENTED YET
387       break;
388     }
389   default:
390     break;
391   }
392   if ( myBackground.isTextureShown() ) {
393     QString fileName;
394     int textureMode = myBackground.texture( fileName );
395     QFileInfo fi( fileName );
396     if ( !fileName.isEmpty() && fi.exists() ) {
397       // set texture image: file name and fill mode
398       switch ( textureMode ) {
399       case Qtx::CenterTexture:
400         activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_CENTERED );
401         break;
402       case Qtx::TileTexture:
403         activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_TILED );
404         break;
405       case Qtx::StretchTexture:
406         activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_STRETCH );
407         break;
408       default:
409         break;
410       }
411       activeView()->Update();
412     }
413   }
414 }
415
416 /*!
417   Updates the active viewport. [ virtual public ]
418 */
419 void OCCViewer_ViewPort3d::onUpdate()
420 {
421   if ( !activeView().IsNull() )
422     activeView()->Update();
423 }
424
425 /*!
426   Called at 'window fit' transformation. [ virtual protected ]
427 */
428 void OCCViewer_ViewPort3d::fitRect( const QRect& rect )
429 {
430   if ( !activeView().IsNull() ) {
431     activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() );
432     emit vpTransformed( this );
433   }
434 }
435
436 /*!
437   Inits 'zoom' transformation. [ protected ]
438 */
439 void OCCViewer_ViewPort3d::startZoomAtPoint( int x, int y )
440 {
441   if ( !activeView().IsNull() && isAdvancedZoomingEnabled() )
442     activeView()->StartZoomAtPoint( x, y );
443 }
444
445 /*!
446   Called at 'zoom' transformation. [ virtual protected ]
447 */
448 void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
449 {
450   if ( !activeView().IsNull() ) {
451     // as OCCT respects a sign of only dx,
452     // but we want both signes to be taken into account
453     //activeView()->Zoom( x0, y0, x, y );
454     if ( isAdvancedZoomingEnabled() )
455       activeView()->ZoomAtPoint( x0, y0, x, y );
456     else
457       activeView()->Zoom( x0 + y0, 0, x + y, 0 );
458     emit vpTransformed( this );
459   }
460 }
461
462 /*!
463   Centers the viewport. [ virtual protected ]
464 */
465 void OCCViewer_ViewPort3d::setCenter( int x, int y )
466 {
467   if ( !activeView().IsNull() ) {
468     activeView()->Place( x, y, myScale );
469     emit vpTransformed( this );
470   }
471 }
472
473 /*!
474   Called at 'pan' transformation. [ virtual protected ]
475 */
476 void OCCViewer_ViewPort3d::pan( int dx, int dy )
477 {
478   if ( !activeView().IsNull() ) {
479     activeView()->Pan( dx, dy, 1.0 );
480     emit vpTransformed( this );
481   }
482 }
483
484 /*!
485   Inits 'rotation' transformation. [ protected ]
486 */
487 void OCCViewer_ViewPort3d::startRotation( int x, int y,
488                                           int theRotationPointType,
489                                           const gp_Pnt& theSelectedPoint )
490 {
491   if ( !activeView().IsNull() ) {
492     //double gx, gy, gz;
493     //double gx = activeView()->gx;
494     //activeView()->Gravity(gx,gy,gz);
495
496     switch ( theRotationPointType ) {
497     case OCCViewer_ViewWindow::GRAVITY:
498       activeView()->StartRotation( x, y, 0.45 );
499       break;
500     case OCCViewer_ViewWindow::SELECTED:
501       sx = x; sy = y;
502
503       double X,Y;
504       activeView()->Size(X,Y);
505       rx = Standard_Real(activeView()->Convert(X));
506       ry = Standard_Real(activeView()->Convert(Y));
507
508       activeView()->Rotate( 0., 0., 0.,
509                             theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
510                             Standard_True );
511
512       Quantity_Ratio zRotationThreshold;
513       zRotation = Standard_False;
514       zRotationThreshold = 0.45;
515       if( zRotationThreshold > 0. ) {
516         Standard_Real dx = Abs(sx - rx/2.);
517         Standard_Real dy = Abs(sy - ry/2.);
518         Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
519         if( dx > dd || dy > dd ) zRotation = Standard_True;
520       }
521       break;
522     default:
523       break;
524     }
525     activeView()->DepthFitAll();
526   }
527 }
528
529 /*!
530   Rotates the viewport. [ protected ]
531 */
532 void OCCViewer_ViewPort3d::rotate( int x, int y,
533                                    int theRotationPointType,
534                                    const gp_Pnt& theSelectedPoint )
535 {
536   if ( !activeView().IsNull() ) {
537     switch ( theRotationPointType ) {
538     case OCCViewer_ViewWindow::GRAVITY:
539       activeView()->Rotation( x, y );
540       break;
541     case OCCViewer_ViewWindow::SELECTED:
542       double dx, dy, dz;
543       if( zRotation ) {
544         dz = atan2(Standard_Real(x)-rx/2., ry/2.-Standard_Real(y)) -
545           atan2(sx-rx/2.,ry/2.-sy);
546         dx = dy = 0.;
547       }
548       else {
549         dx = (Standard_Real(x) - sx) * M_PI/rx;
550         dy = (sy - Standard_Real(y)) * M_PI/ry;
551         dz = 0.;
552       }
553
554       activeView()->Rotate( dx, dy, dz,
555                             theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
556                             Standard_False );
557       break;
558     default:
559       break;
560     }
561     emit vpTransformed( this );
562   }
563   //  setZSize( getZSize() );
564 }
565
566 /*!
567   Resets the viewport after 'rotation'. [ protected ]
568 */
569 void OCCViewer_ViewPort3d::endRotation()
570 {
571   if ( !activeView().IsNull() ) {
572     activeView()->ZFitAll( 1.0 );
573 #if OCC_VERSION_LARGE <= 0x06070100
574     activeView()->SetZSize( 0.0 );
575 #endif
576     activeView()->Update();
577     emit vpTransformed( this );
578   }
579 }
580
581 /*!
582   Repaints the viewport. [ virtual protected ]
583 */
584 void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
585 {
586 #ifndef WIN32
587   /* X11 : map before show doesn't work */
588   if ( !mapped( activeView() ) )
589     mapView( activeView() );
590 #endif
591   if ( !myWindow.IsNull() ) {
592     QApplication::syncX();
593     QRect rc = e->rect();
594     if ( !myPaintersRedrawing )
595       activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() );
596   }
597   OCCViewer_ViewPort::paintEvent( e );
598   myBusy = false;
599 }
600
601 /*!
602   Resizes the viewport. [ virtual protected ]
603 */
604 void OCCViewer_ViewPort3d::resizeEvent( QResizeEvent* e )
605 {
606 #ifdef WIN32
607   /* Win32 : map before first show to avoid flicker */
608   if ( !mapped( activeView() ) )
609     mapView( activeView() );
610 #endif
611   QApplication::syncX();
612   if ( !activeView().IsNull() )
613     activeView()->MustBeResized();
614 }
615
616 /*!
617   Fits all objects in view. [ virtual protected ]
618 */
619 void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd )
620 {
621   if ( activeView().IsNull() )
622     return;
623
624   if ( keepScale )
625     myScale = activeView()->Scale();
626
627   Standard_Real margin = 0.01;
628   
629 #if OCC_VERSION_LARGE > 0x06070100
630   activeView()->FitAll( margin, upd );
631   if(withZ)
632     activeView()->ZFitAll();
633 #else 
634   activeView()->FitAll( margin, withZ, upd );
635 #endif
636   activeView()->SetZSize(0.);
637   emit vpTransformed( this );
638 }
639
640 /*!
641   Resets the view. [ virtual protected ]
642 */
643 void OCCViewer_ViewPort3d::reset()
644 {
645   //  double zsize = getZSize();
646   if ( !activeView().IsNull() ) {
647     activeView()->Reset();
648     emit vpTransformed( this );
649   //    setZSize( zsize );
650   }
651 }
652
653 /*!
654   Rotate the view in the view plane (orthogonal to the view vector)
655 */
656 void OCCViewer_ViewPort3d::rotateXY( double degrees )
657 {
658   if ( activeView().IsNull() )
659     return;
660
661   int x = width()/2, y = height()/2;
662   double X, Y, Z;
663   activeView()->Convert( x, y, X, Y, Z );
664   activeView()->Rotate( 0, 0, degrees * M_PI / 180., X, Y, Z );
665   emit vpTransformed( this );
666 }
667
668 /*!
669   Set axial scale to the view
670 */
671 void OCCViewer_ViewPort3d::setAxialScale( double xScale, double yScale, double zScale )
672 {
673   if ( activeView().IsNull() )
674     return;
675
676   activeView()->SetAxialScale( xScale, yScale, zScale );
677   emit vpTransformed( this );
678 }
679
680 /*!
681   Passed the handle of native window of the component to CASCADE view. [ private ]
682 */
683 bool OCCViewer_ViewPort3d::setWindow( const Handle(V3d_View)& view )
684 {
685   if ( !myWindow.IsNull() )
686     return true;
687
688   if ( view.IsNull() )
689     return false;
690
691   attachWindow( view, OCCViewer_VService::CreateWindow( view, winId() ) );
692
693   myWindow = view->Window();
694   return !myWindow.IsNull();
695 }
696
697 void OCCViewer_ViewPort3d::attachWindow( const Handle(V3d_View)& view,
698                                          const Handle(Aspect_Window)& window)
699 {
700   if (!view.IsNull()) {
701     view->SetWindow( window );
702     updateBackground();
703   }
704 }
705
706 /*!
707   Returns the current active view. [ private ]
708 */
709 Handle(V3d_View) OCCViewer_ViewPort3d::activeView() const
710 {
711   return myActiveView;
712 }
713
714 /*!
715   Returns the current inactive view [ private ]
716 */
717 /*Handle(V3d_View) OCCViewer_ViewPort3d::inactiveView() const
718   {
719   return ( activeView() == myOrthoView ? myPerspView : myOrthoView );
720   }*/
721
722 /*!
723   Returns 'true' if the given view is mapped to window. [ private ]
724 */
725 bool OCCViewer_ViewPort3d::mapped( const Handle(V3d_View)& view ) const
726 {
727   return ( !view.IsNull() && view->View()->IsDefined() );
728 }
729
730 /*!
731   Performs synchronization of view parameters with the specified view.
732   Returns \c true if synchronization is done successfully or \c false otherwise.
733   Default implementation does nothing (return \c false)
734 */
735 bool OCCViewer_ViewPort3d::synchronize( OCCViewer_ViewPort* view )
736 {
737   bool ok = false;
738   OCCViewer_ViewPort3d* vp3d = qobject_cast<OCCViewer_ViewPort3d*>( view );
739   if ( vp3d ) {
740     bool blocked = blockSignals( false );
741     Handle(V3d_View) aView3d = getView();
742     Handle(V3d_View) aRefView3d = vp3d->getView();
743     aView3d->SetImmediateUpdate( Standard_False );
744 #if OCC_VERSION_LARGE > 0x06070100
745     aView3d->Camera()->Copy( aRefView3d->Camera() );
746 #else
747     aView3d->SetViewMapping( aRefView3d->ViewMapping() );
748     aView3d->SetViewOrientation( aRefView3d->ViewOrientation() );
749 #endif
750     aView3d->ZFitAll();
751     aView3d->SetImmediateUpdate( Standard_True );
752     aView3d->Update();
753     blockSignals( blocked );
754     ok = true;
755   }
756   return ok;
757 }
758
759 /*
760  * Show/Hide static triedron
761  */
762 void OCCViewer_ViewPort3d::showStaticTrihedron( bool on )
763 {
764   Handle(V3d_View) aView = activeView();
765   if ( !aView ) return;
766   
767   if ( on ) {
768     aView->ZBufferTriedronSetup();
769     aView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
770   } else {
771     aView->TriedronErase();
772   }
773   aView->Update();
774 }
775
776 /*
777  * Create default cursor with a specific shape
778  */
779 void OCCViewer_ViewPort3d::setDefaultCursor( Qt::CursorShape theCursorShape )
780 {
781   if ( !myCursor )
782     myCursor = new QCursor();
783
784   myCursor->setShape( theCursorShape );
785 }
786
787 /*
788  * Get default cursor with a specific shape
789  */
790 QCursor* OCCViewer_ViewPort3d::getDefaultCursor() const
791 {
792   return myCursor;
793 }