1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "OCCViewer_ViewPort3d.h"
25 #include "OCCViewer_VService.h"
26 #include "OCCViewer_ViewWindow.h"
27 #include "OCCViewer_ViewModel.h"
29 #include <SUIT_ViewManager.h>
30 #include <SUIT_ViewModel.h>
36 #include <QPaintEvent>
37 #include <QResizeEvent>
38 #include <QApplication>
40 #include <Visual3d_View.hxx>
41 #include <V3d_Viewer.hxx>
43 #if OCC_VERSION_LARGE > 0x06070100
44 #include <V3d_View.hxx>
46 #include <V3d_PerspectiveView.hxx>
47 #include <V3d_OrthographicView.hxx>
50 #include "utilities.h"
53 #include <WNT_Window.hxx>
55 #include <Xw_Window.hxx>
58 static double rx = 0.;
59 static double ry = 0.;
62 static Standard_Boolean zRotation = Standard_False;
64 //#include <Standard_Version.hxx>
69 OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_Viewer)& viewer, V3d_TypeOfView type )
70 : OCCViewer_ViewPort( parent ),
73 myIsAdvancedZoomingEnabled( false )
75 // VSR: 01/07/2010 commented to avoid SIGSEGV at SALOME exit
78 #if OCC_VERSION_LARGE > 0x06070100
79 myActiveView = new V3d_View( viewer, type );
81 if ( type == V3d_ORTHOGRAPHIC ) {
82 myOrthoView = new V3d_OrthographicView( viewer );
83 myActiveView = myOrthoView;
86 myPerspView = new V3d_PerspectiveView( viewer );
87 myActiveView = myPerspView;
91 setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background
97 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
100 Handle(V3d_View) aView = activeView();
106 Activates the desired 'type' of view in the viewer
107 ( view of 'type' is created if it doesn't exist ). [ public ]
109 /*void OCCViewer_ViewPort3d::setActive( V3d_TypeOfView type )
111 if ( activeView().IsNull() )
114 if ( activeView()->Type() != type )
116 if ( type == V3d_ORTHOGRAPHIC )
117 setView( myOrthoView );
118 if ( type == V3d_PERSPECTIVE )
119 setView( myPerspView );
124 Maps CasCade 'view' to this viewport. [ private ]
126 bool OCCViewer_ViewPort3d::mapView( const Handle(V3d_View)& view )
128 if ( !setWindow( view ) )
131 if ( !mapped( view ) ) {
132 view->SetWindow( myWindow );
133 if ( view != activeView() )
134 view->View()->Deactivate();
137 emit( vpMapped(this) );
145 Sets new CASCADE view on viewport. Returns the previous active view. [ public ]
147 Handle( V3d_View ) OCCViewer_ViewPort3d::setView( const Handle( V3d_View )& view )
149 /* map the new view */
150 if ( view == activeView() || !mapView( view ) )
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() );
161 view->View()->Activate();
167 Returns CasCade 3D view. [ public ]
169 Handle(V3d_View) OCCViewer_ViewPort3d::getView() const
175 Returns CasCade 3D viewer [ public ]
177 Handle(V3d_Viewer) OCCViewer_ViewPort3d::getViewer() const
179 Handle(V3d_Viewer) viewer;
180 if ( !activeView().IsNull() )
181 viewer = activeView()->Viewer();
186 Syncronizes visual state of this viewport with 'ref'
187 ( scale, projection, eye etc ) Returns 'true' if copied OK,
188 'false' otherwise. [ virtual public ]
190 bool OCCViewer_ViewPort3d::syncronize( const OCCViewer_ViewPort3d* ref )
192 OCCViewer_ViewPort3d* ref3d = (OCCViewer_ViewPort3d*)ref;
193 Handle(V3d_View) refView = ref3d->getView();
194 Handle(V3d_View) tgtView = getView();
196 /* Syncronize view types */
197 /* if ( tgtView->Type() != refView->Type() )
199 setActive( refView->Type() );
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
214 /* we'll update after setting all params */
215 tgtView->SetImmediateUpdate( Standard_False );
218 if ( refView->Type() == V3d_PERSPECTIVE )
219 tgtView->SetFocale( refView->Focale() );
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 );
230 tgtView->SetScale( refView->Scale() );
231 tgtView->SetTwist( refView->Twist() );
235 tgtView->SetImmediateUpdate( Standard_True );
241 Returns Z-size of this view. [ public ]
243 double OCCViewer_ViewPort3d::getZSize() const
245 if ( !activeView().IsNull() )
246 return activeView()->ZSize();
251 Sets Z-size of this view ( for both orthographic and perspective ). [ public ]
253 void OCCViewer_ViewPort3d::setZSize( double zsize )
255 myActiveView->SetZSize( zsize );
256 /* if ( !myOrthoView.IsNull() )
257 myOrthoView->SetZSize( zsize );
258 if ( !myPerspView.IsNull() )
259 myPerspView->SetZSize( zsize );*/
263 Get axial scale to the view
265 void OCCViewer_ViewPort3d::getAxialScale( double& xScale, double& yScale, double& zScale )
267 xScale = yScale = zScale = 1.;
269 if ( !activeView().IsNull() )
270 activeView()->AxialScale( xScale, yScale, zScale );
274 Returns the background color [ virtual public ] [ obsolete ]
276 QColor OCCViewer_ViewPort3d::backgroundColor() const
278 return background().color();
282 Sets the background color [ virtual public ] [ obsolete ]
284 void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color )
286 Qtx::BackgroundData bg = background();
287 bg.setColor( color );
292 Returns the background data
294 Qtx::BackgroundData OCCViewer_ViewPort3d::background() const
300 Sets the background data
302 void OCCViewer_ViewPort3d::setBackground( const Qtx::BackgroundData& bgData )
304 if ( bgData.isValid() ) {
305 myBackground = bgData;
307 emit vpChangeBackground( myBackground );
311 void OCCViewer_ViewPort3d::updateBackground()
313 if ( activeView().IsNull() ) return;
314 if ( !myBackground.isValid() ) return;
316 switch ( myBackground.mode() ) {
317 case Qtx::ColorBackground:
319 QColor c = myBackground.color();
321 // Unset texture should be done here
323 Quantity_Color qCol( c.red()/255., c.green()/255., c.blue()/255., Quantity_TOC_RGB );
324 activeView()->SetBgGradientStyle( Aspect_GFM_NONE ); // cancel gradient background
325 activeView()->SetBgImageStyle( Aspect_FM_NONE ); // cancel texture background
326 // then change background color
327 activeView()->SetBackgroundColor( qCol );
329 activeView()->Update();
333 case Qtx::SimpleGradientBackground:
336 int type = myBackground.gradient( c1, c2 );
337 if ( c1.isValid() && type >= OCCViewer_Viewer::HorizontalGradient && type <= OCCViewer_Viewer::LastGradient ) {
338 // Unset texture should be done here
340 // Get colors and set-up gradiented background
341 if ( !c2.isValid() ) c2 = c1;
342 Quantity_Color qCol1( c1.red()/255., c1.green()/255., c1.blue()/255., Quantity_TOC_RGB );
343 Quantity_Color qCol2( c2.red()/255., c2.green()/255., c2.blue()/255., Quantity_TOC_RGB );
344 activeView()->SetBgImageStyle( Aspect_FM_NONE ); // cancel texture background
346 case OCCViewer_Viewer::HorizontalGradient:
347 activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_HOR, Standard_True );
349 case OCCViewer_Viewer::VerticalGradient:
350 activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_VER, Standard_True );
352 case OCCViewer_Viewer::Diagonal1Gradient:
353 activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG1, Standard_True );
355 case OCCViewer_Viewer::Diagonal2Gradient:
356 activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_DIAG2, Standard_True );
358 case OCCViewer_Viewer::Corner1Gradient:
359 activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER1, Standard_True );
361 case OCCViewer_Viewer::Corner2Gradient:
362 activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER2, Standard_True );
364 case OCCViewer_Viewer::Corner3Gradient:
365 activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER3, Standard_True );
367 case OCCViewer_Viewer::Corner4Gradient:
368 activeView()->SetBgGradientColors( qCol1, qCol2, Aspect_GFM_CORNER4, Standard_True );
376 case Qtx::CustomGradientBackground:
378 // NOT IMPLEMENTED YET
384 if ( myBackground.isTextureShown() ) {
386 int textureMode = myBackground.texture( fileName );
387 QFileInfo fi( fileName );
388 if ( !fileName.isEmpty() && fi.exists() ) {
389 // set texture image: file name and fill mode
390 switch ( textureMode ) {
391 case Qtx::CenterTexture:
392 activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_CENTERED );
394 case Qtx::TileTexture:
395 activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_TILED );
397 case Qtx::StretchTexture:
398 activeView()->SetBackgroundImage( fi.absoluteFilePath().toLatin1().constData(), Aspect_FM_STRETCH );
403 activeView()->Update();
409 Updates the active viewport. [ virtual public ]
411 void OCCViewer_ViewPort3d::onUpdate()
413 if ( !activeView().IsNull() )
414 activeView()->Update();
418 Called at 'window fit' transformation. [ virtual protected ]
420 void OCCViewer_ViewPort3d::fitRect( const QRect& rect )
422 if ( !activeView().IsNull() ) {
423 activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() );
424 emit vpTransformed( this );
429 Inits 'zoom' transformation. [ protected ]
431 void OCCViewer_ViewPort3d::startZoomAtPoint( int x, int y )
433 if ( !activeView().IsNull() && isAdvancedZoomingEnabled() )
434 activeView()->StartZoomAtPoint( x, y );
438 Called at 'zoom' transformation. [ virtual protected ]
440 void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
442 if ( !activeView().IsNull() ) {
443 // as OCCT respects a sign of only dx,
444 // but we want both signes to be taken into account
445 //activeView()->Zoom( x0, y0, x, y );
446 if ( isAdvancedZoomingEnabled() )
447 activeView()->ZoomAtPoint( x0, y0, x, y );
449 activeView()->Zoom( x0 + y0, 0, x + y, 0 );
450 emit vpTransformed( this );
455 Centers the viewport. [ virtual protected ]
457 void OCCViewer_ViewPort3d::setCenter( int x, int y )
459 if ( !activeView().IsNull() ) {
460 activeView()->Place( x, y, myScale );
461 emit vpTransformed( this );
466 Called at 'pan' transformation. [ virtual protected ]
468 void OCCViewer_ViewPort3d::pan( int dx, int dy )
470 if ( !activeView().IsNull() ) {
471 activeView()->Pan( dx, dy, 1.0 );
472 emit vpTransformed( this );
477 Inits 'rotation' transformation. [ protected ]
479 void OCCViewer_ViewPort3d::startRotation( int x, int y,
480 int theRotationPointType,
481 const gp_Pnt& theSelectedPoint )
483 if ( !activeView().IsNull() ) {
485 //double gx = activeView()->gx;
486 //activeView()->Gravity(gx,gy,gz);
488 switch ( theRotationPointType ) {
489 case OCCViewer_ViewWindow::GRAVITY:
490 activeView()->StartRotation( x, y, 0.45 );
492 case OCCViewer_ViewWindow::SELECTED:
496 activeView()->Size(X,Y);
497 rx = Standard_Real(activeView()->Convert(X));
498 ry = Standard_Real(activeView()->Convert(Y));
500 activeView()->Rotate( 0., 0., 0.,
501 theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
504 Quantity_Ratio zRotationThreshold;
505 zRotation = Standard_False;
506 zRotationThreshold = 0.45;
507 if( zRotationThreshold > 0. ) {
508 Standard_Real dx = Abs(sx - rx/2.);
509 Standard_Real dy = Abs(sy - ry/2.);
510 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
511 if( dx > dd || dy > dd ) zRotation = Standard_True;
517 activeView()->DepthFitAll();
522 Rotates the viewport. [ protected ]
524 void OCCViewer_ViewPort3d::rotate( int x, int y,
525 int theRotationPointType,
526 const gp_Pnt& theSelectedPoint )
528 if ( !activeView().IsNull() ) {
529 switch ( theRotationPointType ) {
530 case OCCViewer_ViewWindow::GRAVITY:
531 activeView()->Rotation( x, y );
533 case OCCViewer_ViewWindow::SELECTED:
536 dz = atan2(Standard_Real(x)-rx/2., ry/2.-Standard_Real(y)) -
537 atan2(sx-rx/2.,ry/2.-sy);
541 dx = (Standard_Real(x) - sx) * M_PI/rx;
542 dy = (sy - Standard_Real(y)) * M_PI/ry;
546 activeView()->Rotate( dx, dy, dz,
547 theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
553 emit vpTransformed( this );
555 // setZSize( getZSize() );
559 Resets the viewport after 'rotation'. [ protected ]
561 void OCCViewer_ViewPort3d::endRotation()
563 if ( !activeView().IsNull() ) {
564 activeView()->ZFitAll( 1.0 );
565 #if OCC_VERSION_LARGE <= 0x06070100
566 activeView()->SetZSize( 0.0 );
568 activeView()->Update();
569 emit vpTransformed( this );
574 Repaints the viewport. [ virtual protected ]
576 void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
579 /* X11 : map before show doesn't work */
580 if ( !mapped( activeView() ) )
581 mapView( activeView() );
583 if ( !myWindow.IsNull() ) {
584 QApplication::syncX();
585 QRect rc = e->rect();
586 if ( !myPaintersRedrawing )
587 activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() );
589 OCCViewer_ViewPort::paintEvent( e );
594 Resizes the viewport. [ virtual protected ]
596 void OCCViewer_ViewPort3d::resizeEvent( QResizeEvent* e )
599 /* Win32 : map before first show to avoid flicker */
600 if ( !mapped( activeView() ) )
601 mapView( activeView() );
603 QApplication::syncX();
604 if ( !activeView().IsNull() )
605 activeView()->MustBeResized();
609 Fits all objects in view. [ virtual protected ]
611 void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd )
613 if ( activeView().IsNull() )
617 myScale = activeView()->Scale();
619 Standard_Real margin = 0.01;
621 #if OCC_VERSION_LARGE > 0x06070100
622 activeView()->FitAll( margin, upd );
624 activeView()->ZFitAll();
626 activeView()->FitAll( margin, withZ, upd );
628 activeView()->SetZSize(0.);
629 emit vpTransformed( this );
633 Resets the view. [ virtual protected ]
635 void OCCViewer_ViewPort3d::reset()
637 // double zsize = getZSize();
638 if ( !activeView().IsNull() ) {
639 activeView()->Reset();
640 emit vpTransformed( this );
641 // setZSize( zsize );
646 Rotate the view in the view plane (orthogonal to the view vector)
648 void OCCViewer_ViewPort3d::rotateXY( double degrees )
650 if ( activeView().IsNull() )
653 int x = width()/2, y = height()/2;
655 activeView()->Convert( x, y, X, Y, Z );
656 activeView()->Rotate( 0, 0, degrees * M_PI / 180., X, Y, Z );
657 emit vpTransformed( this );
661 Set axial scale to the view
663 void OCCViewer_ViewPort3d::setAxialScale( double xScale, double yScale, double zScale )
665 if ( activeView().IsNull() )
668 activeView()->SetAxialScale( xScale, yScale, zScale );
669 emit vpTransformed( this );
673 Passed the handle of native window of the component to CASCADE view. [ private ]
675 bool OCCViewer_ViewPort3d::setWindow( const Handle(V3d_View)& view )
677 if ( !myWindow.IsNull() )
683 attachWindow( view, OCCViewer_VService::CreateWindow( view, winId() ) );
685 myWindow = view->Window();
686 return !myWindow.IsNull();
689 void OCCViewer_ViewPort3d::attachWindow( const Handle(V3d_View)& view,
690 const Handle(Aspect_Window)& window)
692 if (!view.IsNull()) {
693 view->SetWindow( window );
699 Returns the current active view. [ private ]
701 Handle(V3d_View) OCCViewer_ViewPort3d::activeView() const
707 Returns the current inactive view [ private ]
709 /*Handle(V3d_View) OCCViewer_ViewPort3d::inactiveView() const
711 return ( activeView() == myOrthoView ? myPerspView : myOrthoView );
715 Returns 'true' if the given view is mapped to window. [ private ]
717 bool OCCViewer_ViewPort3d::mapped( const Handle(V3d_View)& view ) const
719 return ( !view.IsNull() && view->View()->IsDefined() );
723 Performs synchronization of view parameters with the specified view.
724 Returns \c true if synchronization is done successfully or \c false otherwise.
725 Default implementation does nothing (return \c false)
727 bool OCCViewer_ViewPort3d::synchronize( OCCViewer_ViewPort* view )
730 OCCViewer_ViewPort3d* vp3d = qobject_cast<OCCViewer_ViewPort3d*>( view );
732 bool blocked = blockSignals( false );
733 Handle(V3d_View) aView3d = getView();
734 Handle(V3d_View) aRefView3d = vp3d->getView();
735 aView3d->SetImmediateUpdate( Standard_False );
736 #if OCC_VERSION_LARGE > 0x06070100
737 aView3d->Camera()->Copy( aRefView3d->Camera() );
739 aView3d->SetViewMapping( aRefView3d->ViewMapping() );
740 aView3d->SetViewOrientation( aRefView3d->ViewOrientation() );
743 aView3d->SetImmediateUpdate( Standard_True );
745 blockSignals( blocked );
752 * Show/Hide static triedron
754 void OCCViewer_ViewPort3d::showStaticTrihedron( bool on )
756 Handle(V3d_View) aView = activeView();
757 if ( !aView ) return;
760 aView->ZBufferTriedronSetup();
761 aView->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
763 aView->TriedronErase();