Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[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 #include "OCCViewer_ViewPort3d.h"
21
22 #include "OCCViewer_VService.h"
23
24 #include <qrect.h>
25 #include <qevent.h>
26 #include <qapplication.h>
27
28 #include <Visual3d_View.hxx>
29 #include <V3d_PerspectiveView.hxx>
30 #include <V3d_OrthographicView.hxx>
31
32 #if defined WNT
33 #include <WNT_Window.hxx>
34 #else
35 #include <Xw_Window.hxx>
36 #endif
37
38 /*!
39     Constructor
40 */
41 OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_Viewer)& viewer, V3d_TypeOfView  type )
42 : OCCViewer_ViewPort( parent ),
43 myScale( 1.0 ),
44 myDegenerated( true ),
45 myAnimate( false )
46 {
47   selectVisualId();
48
49   if ( type == V3d_ORTHOGRAPHIC ) {
50     myOrthoView = new V3d_OrthographicView( viewer );
51     myActiveView = myOrthoView;
52     myPerspView = 0;
53   } else {
54     myPerspView = new V3d_PerspectiveView( viewer );
55     myActiveView = myPerspView;
56   }
57   if ( myDegenerated )
58     activeView()->SetDegenerateModeOn();
59 }
60
61 /*!
62     Destructor
63 */
64 OCCViewer_ViewPort3d::~OCCViewer_ViewPort3d()
65 {
66   Handle(V3d_View) aView = activeView();
67   if (!aView.IsNull())
68     aView->Remove();
69 }
70
71 /*!
72     Activates the desired 'type' of view in the viewer
73     ( view of 'type' is created if it doesn't exist ). [ public ]
74 */
75 /*void OCCViewer_ViewPort3d::setActive( V3d_TypeOfView type )
76 {
77     if ( activeView().IsNull() )
78         return;
79
80     if ( activeView()->Type() != type )
81     {
82         if ( type == V3d_ORTHOGRAPHIC )
83             setView( myOrthoView );
84         if ( type == V3d_PERSPECTIVE )
85             setView( myPerspView );
86     }
87 }*/
88
89 /*!
90     Maps CasCade 'view' to this viewport. [ private ]
91 */
92 bool OCCViewer_ViewPort3d::mapView( const Handle(V3d_View)& view )
93 {
94   if ( !setWindow( view ) )
95     return false;
96
97   if ( !mapped( view ) )
98         {
99                 view->SetWindow( myWindow );
100                 if ( view != activeView() )
101             view->View()->Deactivate();
102         }
103   return true;
104 }
105
106 /*!
107     Sets new CASCADE view on viewport. Returns the previous active view. [ public ]
108 */
109 Handle( V3d_View ) OCCViewer_ViewPort3d::setView( const Handle( V3d_View )& view )
110 {
111   /* map the new view */
112   if ( view == activeView() || !mapView( view ) )
113     return activeView();
114
115     /* activate the new view*/
116   Handle( V3d_View ) oldView = activeView();
117         if ( !oldView.IsNull() )
118   {
119                 oldView->View()->Deactivate();
120                 view->SetBackgroundColor( oldView->BackgroundColor() );
121         }
122   if ( myDegenerated )
123     view->SetDegenerateModeOn();
124   else
125     view->SetDegenerateModeOff();
126
127   view->View()->Activate();
128   activeView() = view;
129         return oldView;
130 }
131
132 /*!
133     Returns CasCade 3D view. [ public ]
134 */
135 Handle(V3d_View) OCCViewer_ViewPort3d::getView() const
136 {
137         return activeView();
138 }
139
140 /*!
141     Returns CasCade 3D viewer [ public ]
142 */
143 Handle(V3d_Viewer) OCCViewer_ViewPort3d::getViewer() const
144 {
145         Handle(V3d_Viewer) viewer;
146         if ( !activeView().IsNull() )
147     viewer = activeView()->Viewer();
148         return viewer;
149 }
150
151 /*!
152     Syncronizes visual state of this viewport with 'ref'
153     ( scale, projection, eye etc ) Returns 'true' if copied OK,
154     'false' otherwise. [ virtual public ]
155 */
156 bool OCCViewer_ViewPort3d::syncronize( const OCCViewer_ViewPort3d* ref )
157 {
158   OCCViewer_ViewPort3d* ref3d = (OCCViewer_ViewPort3d*)ref;
159   Handle(V3d_View) refView = ref3d->getView();
160   Handle(V3d_View) tgtView = getView();
161
162   /* Syncronize view types */
163 /*    if ( tgtView->Type() != refView->Type() )
164   {
165       setActive( refView->Type() );
166       tgtView = getView();
167   }*/
168
169   /*  The following params are copied:
170       - view type( ortho/persp )
171       - position of view point
172       - orientation of high point
173       - position of the eye
174       - projection vector
175       - view center ( 2D )
176       - view twist
177       - view scale
178   */
179
180   /* we'll update after setting all params */
181   tgtView->SetImmediateUpdate( Standard_False );
182
183   /* perspective */
184   if ( refView->Type() == V3d_PERSPECTIVE )
185       tgtView->SetFocale( refView->Focale() );
186
187   /* copy params */
188   Standard_Real x, y, z;
189   refView->At( x, y, z ); tgtView->SetAt( x, y, z );
190   refView->Up( x, y, z ); tgtView->SetUp( x, y, z );
191   refView->Eye( x, y, z ); tgtView->SetEye( x, y, z );
192   refView->Proj( x, y, z ); tgtView->SetProj( x, y, z );
193   refView->Center( x, y ); tgtView->SetCenter( x, y );
194   tgtView->SetScale( refView->Scale() );
195   tgtView->SetTwist( refView->Twist() );
196
197   /* update */
198   tgtView->Update();
199   tgtView->SetImmediateUpdate( Standard_True );
200   return true;
201 }
202
203 /*!
204     Returns Z-size of this view. [ public ]
205 */
206 double OCCViewer_ViewPort3d::getZSize() const
207 {
208   if ( !activeView().IsNull() )
209     return activeView()->ZSize();
210   return 0;
211 }
212
213 /*!
214     Sets Z-size of this view ( for both orthographic and perspective ). [ public ]
215 */
216 void OCCViewer_ViewPort3d::setZSize( double zsize )
217 {
218   myActiveView->SetZSize( zsize );
219 /*    if ( !myOrthoView.IsNull() )
220         myOrthoView->SetZSize( zsize );
221     if ( !myPerspView.IsNull() )
222         myPerspView->SetZSize( zsize );*/
223 }
224
225 /*!
226     Returns the background color [ virtual public ]
227 */
228 QColor OCCViewer_ViewPort3d::backgroundColor() const
229 {
230         if ( !activeView().IsNull() )
231         {
232                 Standard_Real aRed, aGreen, aBlue;
233                 activeView()->BackgroundColor( Quantity_TOC_RGB, aRed, aGreen, aBlue );
234                 int red = (int) (aRed * 255);
235                 int green = (int) (aGreen * 255);
236                 int blue = (int) (aBlue * 255);
237                 return QColor( red, green, blue );
238         }
239         return OCCViewer_ViewPort::backgroundColor();
240 }
241
242 /*!
243     Sets the background color [ virtual public ]
244 */
245 void OCCViewer_ViewPort3d::setBackgroundColor( const QColor& color )
246 {
247         if ( !activeView().IsNull() )
248         {
249                 activeView()->SetBackgroundColor( Quantity_TOC_RGB, color.red()/255.,
250                                                                                                   color.green()/255., color.blue()/255.);
251                 activeView()->Update();
252     emit vpChangeBGColor( color );
253         }
254 }
255
256 /*!
257   Set animation mode
258   \param theDegenerated - degenerated mode
259 */
260 void OCCViewer_ViewPort3d::setAnimationMode(bool theDegenerated)
261 {
262         if ( !activeView().IsNull() )
263         {
264     myAnimate = theDegenerated;
265     activeView()->SetAnimationMode(true, theDegenerated);
266   }
267 }
268
269 /*!
270     Updates the active viewport. [ virtual public ]
271 */
272 void OCCViewer_ViewPort3d::onUpdate()
273 {
274   if ( !activeView().IsNull() )
275     activeView()->Update();
276 }
277
278 /*!
279     Called at 'window fit' transformation. [ virtual protected ]
280 */
281 void OCCViewer_ViewPort3d::fitRect( const QRect& rect )
282 {
283         if ( !activeView().IsNull() )
284           activeView()->WindowFit( rect.left(), rect.top(), rect.right(), rect.bottom() );
285 }
286
287 /*!
288     Called at 'zoom' transformation. [ virtual protected ]
289 */
290 void OCCViewer_ViewPort3d::zoom( int x0, int y0, int x, int y )
291 {
292         if ( !activeView().IsNull() )
293             activeView()->Zoom( x0, y0, x, y );
294 }
295
296 /*!
297     Centers the viewport. [ virtual protected ]
298 */
299 void OCCViewer_ViewPort3d::setCenter( int x, int y )
300 {
301         if ( !activeView().IsNull() )
302             activeView()->Place( x, y, myScale );
303 }
304
305 /*!
306     Called at 'pan' transformation. [ virtual protected ]
307 */
308 void OCCViewer_ViewPort3d::pan( int dx, int dy )
309 {
310         if ( !activeView().IsNull() )
311         activeView()->Pan( dx, dy, 1.0 );
312 }
313
314 /*!
315     Inits 'rotation' transformation. [ protected ]
316 */
317 void OCCViewer_ViewPort3d::startRotation( int x, int y )
318 {
319         if ( !activeView().IsNull() )
320   {
321                 myDegenerated = activeView()->DegenerateModeIsOn();
322                 activeView()->SetDegenerateModeOn();
323     if (myAnimate) activeView()->SetAnimationModeOn();
324                 activeView()->StartRotation( x, y, 0.45 );
325         }
326 }
327
328 /*!
329     Rotates the viewport. [ protected ]
330 */
331 void OCCViewer_ViewPort3d::rotate( int x, int y )
332 {
333         if ( !activeView().IsNull() )
334             activeView()->Rotation( x, y );
335 //  setZSize( getZSize() );
336 }
337
338 /*!
339     Resets the viewport after 'rotation'. [ protected ]
340 */
341 void OCCViewer_ViewPort3d::endRotation()
342 {
343         if ( !activeView().IsNull() )
344   {
345     if (myAnimate) activeView()->SetAnimationModeOff();
346                 if ( !myDegenerated )
347       activeView()->SetDegenerateModeOff();
348     activeView()->ZFitAll(1.);
349     activeView()->SetZSize(0.);
350     activeView()->Update();
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   activeView()->SetZSize(0.);
404 }
405
406 /*!
407     Resets the view. [ virtual protected ]
408 */
409 void OCCViewer_ViewPort3d::reset()
410 {
411 //  double zsize = getZSize();
412         if ( !activeView().IsNull() )
413         activeView()->Reset();
414 //    setZSize( zsize );
415 }
416
417 /*!
418     Passed the handle of native window of the component to CASCADE view. [ private ]
419 */
420 bool OCCViewer_ViewPort3d::setWindow( const Handle(V3d_View)& view )
421 {
422         if ( !myWindow.IsNull() )
423                 return true;
424
425         if ( view.IsNull() )
426                 return false;
427
428         int hwnd = (int)winId();
429         if ( !hwnd )
430         return false;
431
432         /* set this widget as the drawing window */
433         short lo = (short)hwnd;
434         short hi = (short)( hwnd >> 16 );
435         OCCViewer_VService::SetWindow( view, (int)hi, (int)lo, Xw_WQ_SAMEQUALITY );
436         myWindow = view->Window();
437         return !myWindow.IsNull();
438 }
439
440 /*!
441         Returns the current active view. [ private ]
442 */
443 Handle(V3d_View) OCCViewer_ViewPort3d::activeView() const
444 {
445         return myActiveView;
446 }
447
448 /*!
449         Returns the current inactive view [ private ]
450 */
451 /*Handle(V3d_View) OCCViewer_ViewPort3d::inactiveView() const
452 {
453         return ( activeView() == myOrthoView ? myPerspView : myOrthoView );
454 }*/
455
456 /*!
457         Returns 'true' if the given view is mapped to window. [ private ]
458 */
459 bool OCCViewer_ViewPort3d::mapped( const Handle(V3d_View)& view ) const
460 {
461         return ( !view.IsNull() && view->View()->IsDefined() );
462 }