1 // Copyright (C) 2007-2008 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.
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
22 #include "OCCViewer_ViewPort3d.h"
24 #include "OCCViewer_VService.h"
25 #include "OCCViewer_ViewWindow.h"
26 #include "OCCViewer_ViewModel.h"
28 #include <SUIT_ViewManager.h>
32 #include <QPaintEvent>
33 #include <QResizeEvent>
34 #include <QApplication>
36 #include <Visual3d_View.hxx>
37 #include <V3d_Viewer.hxx>
38 #include <V3d_PerspectiveView.hxx>
39 #include <V3d_OrthographicView.hxx>
42 #include <WNT_Window.hxx>
44 #include <Xw_Window.hxx>
47 static double rx = 0.;
48 static double ry = 0.;
51 static Standard_Boolean zRotation = Standard_False;
56 OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_Viewer)& viewer, V3d_TypeOfView type )
57 : OCCViewer_ViewPort( parent ),
59 myDegenerated( true ),
65 if ( type == V3d_ORTHOGRAPHIC ) {
66 myOrthoView = new V3d_OrthographicView( viewer );
67 myActiveView = myOrthoView;
70 myPerspView = new V3d_PerspectiveView( viewer );
71 myActiveView = myPerspView;
74 activeView()->SetDegenerateModeOn();
80 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
82 Handle(V3d_View) aView = activeView();
88 Activates the desired 'type' of view in the viewer
89 ( view of 'type' is created if it doesn't exist ). [ public ]
91 /*void OCCViewer_ViewPort3d::setActive( V3d_TypeOfView type )
93 if ( activeView().IsNull() )
96 if ( activeView()->Type() != type )
98 if ( type == V3d_ORTHOGRAPHIC )
99 setView( myOrthoView );
100 if ( type == V3d_PERSPECTIVE )
101 setView( myPerspView );
106 Maps CasCade 'view' to this viewport. [ private ]
108 bool OCCViewer_ViewPort3d::mapView( const Handle(V3d_View)& view )
110 if ( !setWindow( view ) )
113 if ( !mapped( view ) )
115 view->SetWindow( myWindow );
116 if ( view != activeView() )
117 view->View()->Deactivate();
120 /* create static trihedron (16551: EDF PAL 501) */
121 OCCViewer_ViewWindow* aVW = dynamic_cast<OCCViewer_ViewWindow*>( parentWidget() );
123 OCCViewer_Viewer* aViewModel = dynamic_cast<OCCViewer_Viewer*>( aVW->getViewManager()->getViewModel() );
124 if ( aViewModel && aViewModel->isStaticTrihedronDisplayed() ){
125 view->ZBufferTriedronSetup();
126 view->TriedronDisplay( Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.05, V3d_ZBUFFER );
133 Sets new CASCADE view on viewport. Returns the previous active view. [ public ]
135 Handle( V3d_View ) OCCViewer_ViewPort3d::setView( const Handle( V3d_View )& view )
137 /* map the new view */
138 if ( view == activeView() || !mapView( view ) )
141 /* activate the new view*/
142 Handle( V3d_View ) oldView = activeView();
143 if ( !oldView.IsNull() )
145 oldView->View()->Deactivate();
146 view->SetBackgroundColor( oldView->BackgroundColor() );
149 view->SetDegenerateModeOn();
151 view->SetDegenerateModeOff();
153 view->View()->Activate();
159 Returns CasCade 3D view. [ public ]
161 Handle(V3d_View) OCCViewer_ViewPort3d::getView() const
167 Returns CasCade 3D viewer [ public ]
169 Handle(V3d_Viewer) OCCViewer_ViewPort3d::getViewer() const
171 Handle(V3d_Viewer) viewer;
172 if ( !activeView().IsNull() )
173 viewer = activeView()->Viewer();
178 Syncronizes visual state of this viewport with 'ref'
179 ( scale, projection, eye etc ) Returns 'true' if copied OK,
180 'false' otherwise. [ virtual public ]
182 bool OCCViewer_ViewPort3d::syncronize( const OCCViewer_ViewPort3d* ref )
184 OCCViewer_ViewPort3d* ref3d = (OCCViewer_ViewPort3d*)ref;
185 Handle(V3d_View) refView = ref3d->getView();
186 Handle(V3d_View) tgtView = getView();
188 /* Syncronize view types */
189 /* if ( tgtView->Type() != refView->Type() )
191 setActive( refView->Type() );
195 /* The following params are copied:
196 - view type( ortho/persp )
197 - position of view point
198 - orientation of high point
199 - position of the eye
206 /* we'll update after setting all params */
207 tgtView->SetImmediateUpdate( Standard_False );
210 if ( refView->Type() == V3d_PERSPECTIVE )
211 tgtView->SetFocale( refView->Focale() );
214 Standard_Real x, y, z;
215 refView->At( x, y, z ); tgtView->SetAt( x, y, z );
216 refView->Up( x, y, z ); tgtView->SetUp( x, y, z );
217 refView->Eye( x, y, z ); tgtView->SetEye( x, y, z );
218 refView->Proj( x, y, z ); tgtView->SetProj( x, y, z );
219 refView->Center( x, y ); tgtView->SetCenter( x, y );
220 tgtView->SetScale( refView->Scale() );
221 tgtView->SetTwist( refView->Twist() );
225 tgtView->SetImmediateUpdate( Standard_True );
230 Returns Z-size of this view. [ public ]
232 double OCCViewer_ViewPort3d::getZSize() const
234 if ( !activeView().IsNull() )
235 return activeView()->ZSize();
240 Sets Z-size of this view ( for both orthographic and perspective ). [ public ]
242 void OCCViewer_ViewPort3d::setZSize( double zsize )
244 myActiveView->SetZSize( zsize );
245 /* if ( !myOrthoView.IsNull() )
246 myOrthoView->SetZSize( zsize );
247 if ( !myPerspView.IsNull() )
248 myPerspView->SetZSize( zsize );*/
252 Returns the background color [ virtual public ]
254 QColor OCCViewer_ViewPort3d::backgroundColor() const
256 if ( !activeView().IsNull() )
258 Standard_Real aRed, aGreen, aBlue;
259 activeView()->BackgroundColor( Quantity_TOC_RGB, aRed, aGreen, aBlue );
260 int red = (int) (aRed * 255);
261 int green = (int) (aGreen * 255);
262 int blue = (int) (aBlue * 255);
263 return QColor( red, green, blue );
265 return OCCViewer_ViewPort::backgroundColor();
269 Sets the background color [ virtual public ]
271 void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color )
273 if ( !activeView().IsNull() )
275 activeView()->SetBackgroundColor( Quantity_TOC_RGB, color.red()/255.,
276 color.green()/255., color.blue()/255.);
277 activeView()->Update();
278 emit vpChangeBGColor( color );
284 \param theDegenerated - degenerated mode
286 void OCCViewer_ViewPort3d::setAnimationMode(bool theDegenerated)
288 if ( !activeView().IsNull() )
290 myAnimate = theDegenerated;
291 activeView()->SetAnimationMode(true, theDegenerated);
296 Updates the active viewport. [ virtual public ]
298 void OCCViewer_ViewPort3d::onUpdate()
300 if ( !activeView().IsNull() )
301 activeView()->Update();
305 Called at 'window fit' transformation. [ virtual protected ]
307 void OCCViewer_ViewPort3d::fitRect( const QRect& rect )
309 if ( !activeView().IsNull() )
310 activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() );
314 Called at 'zoom' transformation. [ virtual protected ]
316 void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
318 if ( !activeView().IsNull() ) {
319 // as OCCT respects a sign of only dx,
320 // but we want both signes to be taken into account
321 //activeView()->Zoom( x0, y0, x, y );
322 activeView()->Zoom( x0 + y0, 0, x + y, 0 );
327 Centers the viewport. [ virtual protected ]
329 void OCCViewer_ViewPort3d::setCenter( int x, int y )
331 if ( !activeView().IsNull() )
332 activeView()->Place( x, y, myScale );
336 Called at 'pan' transformation. [ virtual protected ]
338 void OCCViewer_ViewPort3d::pan( int dx, int dy )
340 if ( !activeView().IsNull() )
341 activeView()->Pan( dx, dy, 1.0 );
345 Inits 'rotation' transformation. [ protected ]
347 void OCCViewer_ViewPort3d::startRotation( int x, int y,
348 int theRotationPointType,
349 const gp_Pnt& theSelectedPoint )
351 if ( !activeView().IsNull() )
353 myDegenerated = activeView()->DegenerateModeIsOn();
354 activeView()->SetDegenerateModeOn();
355 if (myAnimate) activeView()->SetAnimationModeOn();
358 //double gx = activeView()->gx;
359 //activeView()->Gravity(gx,gy,gz);
361 switch ( theRotationPointType ) {
362 case OCCViewer_ViewWindow::GRAVITY:
363 activeView()->StartRotation( x, y, 0.45 );
365 case OCCViewer_ViewWindow::SELECTED:
369 activeView()->Size(X,Y);
370 rx = Standard_Real(activeView()->Convert(X));
371 ry = Standard_Real(activeView()->Convert(Y));
373 activeView()->Rotate( 0., 0., 0.,
374 theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
377 Quantity_Ratio zRotationThreshold;
378 zRotation = Standard_False;
379 zRotationThreshold = 0.45;
380 if( zRotationThreshold > 0. ) {
381 Standard_Real dx = Abs(sx - rx/2.);
382 Standard_Real dy = Abs(sy - ry/2.);
383 Standard_Real dd = zRotationThreshold * (rx + ry)/2.;
384 if( dx > dd || dy > dd ) zRotation = Standard_True;
394 Rotates the viewport. [ protected ]
396 void OCCViewer_ViewPort3d::rotate( int x, int y,
397 int theRotationPointType,
398 const gp_Pnt& theSelectedPoint )
400 if ( !activeView().IsNull() ) {
401 switch ( theRotationPointType ) {
402 case OCCViewer_ViewWindow::GRAVITY:
403 activeView()->Rotation( x, y );
405 case OCCViewer_ViewWindow::SELECTED:
408 dz = atan2(Standard_Real(x)-rx/2., ry/2.-Standard_Real(y)) -
409 atan2(sx-rx/2.,ry/2.-sy);
413 dx = (Standard_Real(x) - sx) * Standard_PI/rx;
414 dy = (sy - Standard_Real(y)) * Standard_PI/ry;
418 activeView()->Rotate( dx, dy, dz,
419 theSelectedPoint.X(),theSelectedPoint.Y(), theSelectedPoint.Z(),
426 // setZSize( getZSize() );
430 Resets the viewport after 'rotation'. [ protected ]
432 void OCCViewer_ViewPort3d::endRotation()
434 if ( !activeView().IsNull() )
436 if (myAnimate) activeView()->SetAnimationModeOff();
437 if ( !myDegenerated )
438 activeView()->SetDegenerateModeOff();
439 activeView()->ZFitAll(1.);
440 activeView()->SetZSize(0.);
441 activeView()->Update();
446 Repaints the viewport. [ virtual protected ]
448 void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
451 /* X11 : map before show doesn't work */
452 if ( !mapped( activeView() ) )
453 mapView( activeView() );
455 if ( !myWindow.IsNull() )
457 QApplication::syncX();
458 QRect rc = e->rect();
459 if ( !myPaintersRedrawing )
460 activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() );
462 OCCViewer_ViewPort::paintEvent( e );
467 Resizes the viewport. [ virtual protected ]
469 void OCCViewer_ViewPort3d::resizeEvent( QResizeEvent* e )
472 /* Win32 : map before first show to avoid flicker */
473 if ( !mapped( activeView() ) )
474 mapView( activeView() );
476 QApplication::syncX();
477 if ( !activeView().IsNull() )
478 activeView()->MustBeResized();
482 Fits all objects in view. [ virtual protected ]
484 void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd )
486 if ( activeView().IsNull() )
491 myScale = activeView()->Scale();
493 Standard_Real margin = 0.01;
494 activeView()->FitAll( margin, withZ, upd );
495 activeView()->SetZSize(0.);
499 Resets the view. [ virtual protected ]
501 void OCCViewer_ViewPort3d::reset()
503 // double zsize = getZSize();
504 if ( !activeView().IsNull() )
505 activeView()->Reset();
506 // setZSize( zsize );
510 Passed the handle of native window of the component to CASCADE view. [ private ]
512 bool OCCViewer_ViewPort3d::setWindow( const Handle(V3d_View)& view )
514 if ( !myWindow.IsNull() )
520 int hwnd = (int)winId();
524 /* set this widget as the drawing window */
525 short lo = (short)hwnd;
526 short hi = (short)( hwnd >> 16 );
527 OCCViewer_VService::SetWindow( view, (int)hi, (int)lo, Xw_WQ_SAMEQUALITY );
528 myWindow = view->Window();
529 return !myWindow.IsNull();
533 Returns the current active view. [ private ]
535 Handle(V3d_View) OCCViewer_ViewPort3d::activeView() const
541 Returns the current inactive view [ private ]
543 /*Handle(V3d_View) OCCViewer_ViewPort3d::inactiveView() const
545 return ( activeView() == myOrthoView ? myPerspView : myOrthoView );
549 Returns 'true' if the given view is mapped to window. [ private ]
551 bool OCCViewer_ViewPort3d::mapped( const Handle(V3d_View)& view ) const
553 return ( !view.IsNull() && view->View()->IsDefined() );