Salome HOME
Copyrights update
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewPort3d.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 /***************************************************************************
20 **  Class:   OCCViewer_ViewPort3D
21 **  Descr:   Visualisation canvas with CasCade 3D view
22 **  Module:  OCCViewer
23 **  Created: UI team, 05.09.00
24 ****************************************************************************/
25
26 #include "OCCViewer_ViewPort3d.h"
27
28 #include "OCCViewer_VService.h"
29
30 #include <qrect.h>
31 #include <qevent.h>
32 #include <qapplication.h>
33
34 #include <Visual3d_View.hxx>
35 #include <V3d_PerspectiveView.hxx>
36 #include <V3d_OrthographicView.hxx>
37
38 #if defined WNT
39 #include <WNT_Window.hxx>
40 #else
41 #include <Xw_Window.hxx>
42 #endif
43
44 /*!
45     Constructor
46 */
47 OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_Viewer)& viewer, V3d_TypeOfView  type )
48 : OCCViewer_ViewPort( parent ),
49 myScale( 1.0 ),
50 myDegenerated( true ),
51 myAnimate( false )
52 {
53   selectVisualId();
54
55   if ( type == V3d_ORTHOGRAPHIC ) {
56     myOrthoView = new V3d_OrthographicView( viewer );
57     myActiveView = myOrthoView;
58     myPerspView = 0;
59   } else {
60     myPerspView = new V3d_PerspectiveView( viewer );
61     myActiveView = myPerspView;
62   }
63   if ( myDegenerated )
64     activeView()->SetDegenerateModeOn();
65 }
66
67 /*!
68     Destructor
69 */
70 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
71 {
72   Handle(V3d_View) aView = activeView();
73   if (!aView.IsNull())
74     aView->Remove();
75 }
76
77 /*!
78     Activates the desired 'type' of view in the viewer
79     ( view of 'type' is created if it doesn't exist ). [ public ]
80 */
81 /*void OCCViewer_ViewPort3d::setActive( V3d_TypeOfView type )
82 {
83     if ( activeView().IsNull() )
84         return;
85
86     if ( activeView()->Type() != type )
87     {
88         if ( type == V3d_ORTHOGRAPHIC )
89             setView( myOrthoView );
90         if ( type == V3d_PERSPECTIVE )
91             setView( myPerspView );
92     }
93 }*/
94
95 /*!
96     Maps CasCade 'view' to this viewport. [ private ]
97 */
98 bool OCCViewer_ViewPort3d::mapView( const Handle(V3d_View)& view )
99 {
100   if ( !setWindow( view ) )
101     return false;
102
103   if ( !mapped( view ) )
104         {
105                 view->SetWindow( myWindow );
106                 if ( view != activeView() )
107             view->View()->Deactivate();
108         }
109   return true;
110 }
111
112 /*!
113     Sets new CASCADE view on viewport. Returns the previous active view. [ public ]
114 */
115 Handle( V3d_View ) OCCViewer_ViewPort3d::setView( const Handle( V3d_View )& view )
116 {
117   /* map the new view */
118   if ( view == activeView() || !mapView( view ) )
119     return activeView();
120
121     /* activate the new view*/
122   Handle( V3d_View ) oldView = activeView();
123         if ( !oldView.IsNull() )
124   {
125                 oldView->View()->Deactivate();
126                 view->SetBackgroundColor( oldView->BackgroundColor() );
127         }
128   if ( myDegenerated )
129     view->SetDegenerateModeOn();
130   else
131     view->SetDegenerateModeOff();
132
133   view->View()->Activate();
134   activeView() = view;
135         return oldView;
136 }
137
138 /*!
139     Returns CasCade 3D view. [ public ]
140 */
141 Handle(V3d_View) OCCViewer_ViewPort3d::getView() const
142 {
143         return activeView();
144 }
145
146 /*!
147     Returns CasCade 3D viewer [ public ]
148 */
149 Handle(V3d_Viewer) OCCViewer_ViewPort3d::getViewer() const
150 {
151         Handle(V3d_Viewer) viewer;
152         if ( !activeView().IsNull() )
153     viewer = activeView()->Viewer();
154         return viewer;
155 }
156
157 /*!
158     Syncronizes visual state of this viewport with 'ref'
159     ( scale, projection, eye etc ) Returns 'true' if copied OK,
160     'false' otherwise. [ virtual public ]
161 */
162 bool OCCViewer_ViewPort3d::syncronize( const OCCViewer_ViewPort3d* ref )
163 {
164   OCCViewer_ViewPort3d* ref3d = (OCCViewer_ViewPort3d*)ref;
165   Handle(V3d_View) refView = ref3d->getView();
166   Handle(V3d_View) tgtView = getView();
167
168   /* Syncronize view types */
169 /*    if ( tgtView->Type() != refView->Type() )
170   {
171       setActive( refView->Type() );
172       tgtView = getView();
173   }*/
174
175   /*  The following params are copied:
176       - view type( ortho/persp )
177       - position of view point
178       - orientation of high point
179       - position of the eye
180       - projection vector
181       - view center ( 2D )
182       - view twist
183       - view scale
184   */
185
186   /* we'll update after setting all params */
187   tgtView->SetImmediateUpdate( Standard_False );
188
189   /* perspective */
190   if ( refView->Type() == V3d_PERSPECTIVE )
191       tgtView->SetFocale( refView->Focale() );
192
193   /* copy params */
194   Standard_Real x, y, z;
195   refView->At( x, y, z ); tgtView->SetAt( x, y, z );
196   refView->Up( x, y, z ); tgtView->SetUp( x, y, z );
197   refView->Eye( x, y, z ); tgtView->SetEye( x, y, z );
198   refView->Proj( x, y, z ); tgtView->SetProj( x, y, z );
199   refView->Center( x, y ); tgtView->SetCenter( x, y );
200   tgtView->SetScale( refView->Scale() );
201   tgtView->SetTwist( refView->Twist() );
202
203   /* update */
204   tgtView->Update();
205   tgtView->SetImmediateUpdate( Standard_True );
206   return true;
207 }
208
209 /*!
210     Returns Z-size of this view. [ public ]
211 */
212 double OCCViewer_ViewPort3d::getZSize() const
213 {
214   if ( !activeView().IsNull() )
215     return activeView()->ZSize();
216   return 0;
217 }
218
219 /*!
220     Sets Z-size of this view ( for both orthographic and perspective ). [ public ]
221 */
222 void OCCViewer_ViewPort3d::setZSize( double zsize )
223 {
224   myActiveView->SetZSize( zsize );
225 /*    if ( !myOrthoView.IsNull() )
226         myOrthoView->SetZSize( zsize );
227     if ( !myPerspView.IsNull() )
228         myPerspView->SetZSize( zsize );*/
229 }
230
231 /*!
232     Returns the background color [ virtual public ]
233 */
234 QColor OCCViewer_ViewPort3d::backgroundColor() const
235 {
236         if ( !activeView().IsNull() )
237         {
238                 Standard_Real aRed, aGreen, aBlue;
239                 activeView()->BackgroundColor( Quantity_TOC_RGB, aRed, aGreen, aBlue );
240                 int red = (int) (aRed * 255);
241                 int green = (int) (aGreen * 255);
242                 int blue = (int) (aBlue * 255);
243                 return QColor( red, green, blue );
244         }
245         return OCCViewer_ViewPort::backgroundColor();
246 }
247
248 /*!
249     Sets the background color [ virtual public ]
250 */
251 void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color )
252 {
253         if ( !activeView().IsNull() )
254         {
255                 activeView()->SetBackgroundColor( Quantity_TOC_RGB, color.red()/255.,
256                                                                                                   color.green()/255., color.blue()/255.);
257                 activeView()->Update();
258     emit vpChangeBGColor( color );
259         }
260 }
261
262 void OCCViewer_ViewPort3d::setAnimationMode(bool theDegenerated)
263 {
264         if ( !activeView().IsNull() )
265         {
266     myAnimate = theDegenerated;
267     activeView()->SetAnimationMode(true, theDegenerated);
268   }
269 }
270
271 /*!
272     Updates the active viewport. [ virtual public ]
273 */
274 void OCCViewer_ViewPort3d::onUpdate()
275 {
276   if ( !activeView().IsNull() )
277     activeView()->Update();
278 }
279
280 /*!
281     Called at 'window fit' transformation. [ virtual protected ]
282 */
283 void OCCViewer_ViewPort3d::fitRect( const QRect& rect )
284 {
285         if ( !activeView().IsNull() )
286           activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() );
287 }
288
289 /*!
290     Called at 'zoom' transformation. [ virtual protected ]
291 */
292 void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
293 {
294         if ( !activeView().IsNull() )
295             activeView()->Zoom( x0, y0, x, y );
296 }
297
298 /*!
299     Centers the viewport. [ virtual protected ]
300 */
301 void OCCViewer_ViewPort3d::setCenter( int x, int y )
302 {
303         if ( !activeView().IsNull() )
304             activeView()->Place( x, y, myScale );
305 }
306
307 /*!
308     Called at 'pan' transformation. [ virtual protected ]
309 */
310 void OCCViewer_ViewPort3d::pan( int dx, int dy )
311 {
312         if ( !activeView().IsNull() )
313         activeView()->Pan( dx, dy, 1.0 );
314 }
315
316 /*!
317     Inits 'rotation' transformation. [ protected ]
318 */
319 void OCCViewer_ViewPort3d::startRotation( int x, int y )
320 {
321         if ( !activeView().IsNull() )
322   {
323                 myDegenerated = activeView()->DegenerateModeIsOn();
324                 activeView()->SetDegenerateModeOn();
325     if (myAnimate) activeView()->SetAnimationModeOn();
326                 activeView()->StartRotation( x, y, 0.45 );
327         }
328 }
329
330 /*!
331     Rotates the viewport. [ protected ]
332 */
333 void OCCViewer_ViewPort3d::rotate( int x, int y )
334 {
335         if ( !activeView().IsNull() )
336             activeView()->Rotation( x, y );
337 //  setZSize( getZSize() );
338 }
339
340 /*!
341     Resets the viewport after 'rotation'. [ protected ]
342 */
343 void OCCViewer_ViewPort3d::endRotation()
344 {
345         if ( !activeView().IsNull() )
346   {
347     if (myAnimate) activeView()->SetAnimationModeOff();
348                 if ( !myDegenerated )
349       activeView()->SetDegenerateModeOff();
350     activeView()->ZFitAll(1.);
351         }
352 }
353
354 /*!
355     Repaints the viewport. [ virtual protected ]
356 */
357 void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e )
358 {
359 #ifndef WNT
360         /* X11 : map before show doesn't work */
361         if ( !mapped( activeView() ) )
362         mapView( activeView() );
363 #endif
364         if ( !myWindow.IsNull() )
365         {
366                 QApplication::syncX();
367                 QRect rc = e->rect();
368                 if ( !myPaintersRedrawing )
369                     activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() );
370         }
371         OCCViewer_ViewPort::paintEvent( e );
372 }
373
374 /*!
375     Resizes the viewport. [ virtual protected ]
376 */
377 void OCCViewer_ViewPort3d::resizeEvent( QResizeEvent* e )
378 {
379 #ifdef WNT
380         /* Win32 : map before first show to avoid flicker */
381         if ( !mapped( activeView() ) )
382             mapView( activeView() );
383 #endif
384         QApplication::syncX();
385     if ( !activeView().IsNull() )
386         activeView()->MustBeResized();
387 }
388
389 /*!
390     Fits all objects in view. [ virtual protected ]
391 */
392 void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd )
393 {
394         if ( activeView().IsNull() )
395     return;
396
397
398   if ( keepScale )
399     myScale = activeView()->Scale();
400
401   Standard_Real margin = 0.01;
402   activeView()->FitAll( margin, withZ, upd );
403 }
404
405 /*!
406     Resets the view. [ virtual protected ]
407 */
408 void OCCViewer_ViewPort3d::reset()
409 {
410 //  double zsize = getZSize();
411         if ( !activeView().IsNull() )
412         activeView()->Reset();
413 //    setZSize( zsize );
414 }
415
416 /*!
417     Passed the handle of native window of the component to CASCADE view. [ private ]
418 */
419 bool OCCViewer_ViewPort3d::setWindow( const Handle(V3d_View)& view )
420 {
421         if ( !myWindow.IsNull() )
422                 return true;
423
424         if ( view.IsNull() )
425                 return false;
426
427         int hwnd = (int)winId();
428         if ( !hwnd )
429         return false;
430
431         /* set this widget as the drawing window */
432         short lo = (short)hwnd;
433         short hi = (short)( hwnd >> 16 );
434         OCCViewer_VService::SetWindow( view, (int)hi, (int)lo, Xw_WQ_SAMEQUALITY );
435         myWindow = view->Window();
436         return !myWindow.IsNull();
437 }
438
439 /*!
440         Returns the current active view. [ private ]
441 */
442 Handle(V3d_View) OCCViewer_ViewPort3d::activeView() const
443 {
444         return myActiveView;
445 }
446
447 /*!
448         Returns the current inactive view [ private ]
449 */
450 /*Handle(V3d_View) OCCViewer_ViewPort3d::inactiveView() const
451 {
452         return ( activeView() == myOrthoView ? myPerspView : myOrthoView );
453 }*/
454
455 /*!
456         Returns 'true' if the given view is mapped to window. [ private ]
457 */
458 bool OCCViewer_ViewPort3d::mapped( const Handle(V3d_View)& view ) const
459 {
460         return ( !view.IsNull() && view->View()->IsDefined() );
461 }