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