Salome HOME
2b2d6d866b4f9d28e58667cb31635c2739676dad
[modules/gui.git] / src / OCCViewer / OCCViewer_ViewWindow.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File   : OCCViewer_ViewWindow.cxx
24 // Author :
25
26 #include "OCCViewer_ViewWindow.h"
27 #include "OCCViewer_ViewModel.h"
28 #include "OCCViewer_ViewPort3d.h"
29 #include "OCCViewer_ViewManager.h"
30 #include "OCCViewer_ViewSketcher.h"
31 #include "OCCViewer_CreateRestoreViewDlg.h"
32 #include "OCCViewer_ClippingDlg.h"
33 #include "OCCViewer_SetRotationPointDlg.h"
34 #include "OCCViewer_AxialScaleDlg.h"
35 #include "OCCViewer_CubeAxesDlg.h"
36
37 #include <Basics_OCCTVersion.hxx>
38
39 #include <SUIT_Desktop.h>
40 #include <SUIT_Session.h>
41 #include <SUIT_ViewManager.h>
42 #include <SUIT_Tools.h>
43 #include <SUIT_ResourceMgr.h>
44 #include <SUIT_MessageBox.h>
45 #include <SUIT_Application.h>
46
47 #include <QtxActionToolMgr.h>
48 #include <QtxMultiAction.h>
49 #include <QtxRubberBand.h>
50
51 #include <OpenGLUtils_FrameBuffer.h>
52
53 #include <QPainter>
54 #include <QTime>
55 #include <QImage>
56 #include <QKeyEvent>
57 #include <QMouseEvent>
58 #include <QApplication>
59 #include <QMenu>
60
61 #include <AIS_ListOfInteractive.hxx>
62 #include <AIS_ListIteratorOfListOfInteractive.hxx>
63 #include <AIS_Shape.hxx>
64
65 #include <BRep_Tool.hxx>
66 #include <BRepBndLib.hxx>
67 #include <TopoDS.hxx>
68
69 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
70 #include <Graphic3d_MapOfStructure.hxx>
71 #include <Graphic3d_Structure.hxx>
72 #include <Graphic3d_ExportFormat.hxx>
73
74 #include <Visual3d_View.hxx>
75 #include <V3d_Plane.hxx>
76 #include <V3d_Light.hxx>
77
78 #include <gp_Dir.hxx>
79 #include <gp_Pln.hxx>
80 #include <TColgp_Array1OfPnt2d.hxx>
81
82 #include <Standard_Version.hxx>
83
84 #include "utilities.h"
85
86 // // OpenCV includes
87 // #include <cv.h>
88 // #include <highgui.h>
89
90 static QEvent* l_mbPressEvent = 0;
91
92 #ifdef WIN32
93 # include <QWindowsStyle>
94 #endif
95
96 #include <GL/gl.h>
97
98 const char* imageZoomCursor[] = {
99 "32 32 3 1",
100 ". c None",
101 "a c #000000",
102 "# c #ffffff",
103 "................................",
104 "................................",
105 ".#######........................",
106 "..aaaaaaa.......................",
107 "................................",
108 ".............#####..............",
109 "...........##.aaaa##............",
110 "..........#.aa.....a#...........",
111 ".........#.a.........#..........",
112 ".........#a..........#a.........",
113 "........#.a...........#.........",
114 "........#a............#a........",
115 "........#a............#a........",
116 "........#a............#a........",
117 "........#a............#a........",
118 ".........#...........#.a........",
119 ".........#a..........#a.........",
120 ".........##.........#.a.........",
121 "........#####.....##.a..........",
122 ".......###aaa#####.aa...........",
123 "......###aa...aaaaa.......#.....",
124 ".....###aa................#a....",
125 "....###aa.................#a....",
126 "...###aa...............#######..",
127 "....#aa.................aa#aaaa.",
128 ".....a....................#a....",
129 "..........................#a....",
130 "...........................a....",
131 "................................",
132 "................................",
133 "................................",
134 "................................"};
135
136 const char* imageRotateCursor[] = {
137 "32 32 3 1",
138 ". c None",
139 "a c #000000",
140 "# c #ffffff",
141 "................................",
142 "................................",
143 "................................",
144 "................................",
145 "........#.......................",
146 ".......#.a......................",
147 "......#######...................",
148 ".......#aaaaa#####..............",
149 "........#..##.a#aa##........##..",
150 ".........a#.aa..#..a#.....##.aa.",
151 ".........#.a.....#...#..##.aa...",
152 ".........#a.......#..###.aa.....",
153 "........#.a.......#a..#aa.......",
154 "........#a.........#..#a........",
155 "........#a.........#a.#a........",
156 "........#a.........#a.#a........",
157 "........#a.........#a.#a........",
158 ".........#.........#a#.a........",
159 "........##a........#a#a.........",
160 "......##.a#.......#.#.a.........",
161 "....##.aa..##.....##.a..........",
162 "..##.aa.....a#####.aa...........",
163 "...aa.........aaa#a.............",
164 "................#.a.............",
165 "...............#.a..............",
166 "..............#.a...............",
167 "...............a................",
168 "................................",
169 "................................",
170 "................................",
171 "................................",
172 "................................"};
173
174 const char* imageCrossCursor[] = {
175   "32 32 3 1",
176   ". c None",
177   "a c #000000",
178   "# c #ffffff",
179   "................................",
180   "................................",
181   "................................",
182   "................................",
183   "................................",
184   "................................",
185   "................................",
186   "...............#................",
187   "...............#a...............",
188   "...............#a...............",
189   "...............#a...............",
190   "...............#a...............",
191   "...............#a...............",
192   "...............#a...............",
193   "...............#a...............",
194   ".......#################........",
195   "........aaaaaaa#aaaaaaaaa.......",
196   "...............#a...............",
197   "...............#a...............",
198   "...............#a...............",
199   "...............#a...............",
200   "...............#a...............",
201   "...............#a...............",
202   "...............#a...............",
203   "................a...............",
204   "................................",
205   "................................",
206   "................................",
207   "................................",
208   "................................",
209   "................................",
210   "................................"};
211
212
213 /*!
214   \brief Constructor
215   \param theDesktop main window of application
216   \param theModel OCC 3D viewer
217 */
218 OCCViewer_ViewWindow::OCCViewer_ViewWindow( SUIT_Desktop*     theDesktop,
219                                             OCCViewer_Viewer* theModel )
220 : SUIT_ViewWindow( theDesktop )
221 {
222   myModel = theModel;
223   myRestoreFlag = 0;
224   myEnableDrawMode = false;
225   myDrawRect=false;
226   updateEnabledDrawMode();
227   myClippingDlg = 0;
228   myScalingDlg = 0;
229   mySetRotationPointDlg = 0;
230   myRectBand = 0;
231   
232   IsSketcherStyle = false;
233
234   mypSketcher = 0;
235   myCurSketch = -1;
236   my2dMode = No2dMode;
237
238   myInteractionStyle = SUIT_ViewModel::STANDARD;
239
240   clearViewAspects();
241   
242 }
243
244 /*!
245   \brief Destructor.
246 */
247 OCCViewer_ViewWindow::~OCCViewer_ViewWindow()
248 {
249   endDrawRect();
250   qDeleteAll( mySketchers );
251 }
252
253 /*!
254   \brief Internal initialization.
255 */
256 void OCCViewer_ViewWindow::initLayout()
257 {
258   myViewPort = new OCCViewer_ViewPort3d( this, myModel->getViewer3d(), V3d_ORTHOGRAPHIC );
259   myViewPort->installEventFilter(this);
260   setCentralWidget(myViewPort);
261   myOperation = NOTHING;
262
263   myCurrPointType = GRAVITY;
264   myPrevPointType = GRAVITY;
265   mySelectedPoint = gp_Pnt(0.,0.,0.);
266   myRotationPointSelection = false;
267
268   setTransformRequested ( NOTHING );
269   setTransformInProcess ( false );
270
271   createActions();
272   createToolBar();
273
274   switch (my2dMode) {
275   case XYPlane:
276     onTopView();
277     break;
278   case XZPlane:
279     onLeftView();
280     break;
281   case YZPlane:
282     onFrontView();
283     break;
284   }
285
286   // Graduated axes dialog
287   QtxAction* anAction = dynamic_cast<QtxAction*>( toolMgr()->action( GraduatedAxesId ) );
288   myCubeAxesDlg = new OCCViewer_CubeAxesDlg( anAction, this, "OCCViewer_CubeAxesDlg" );
289   myCubeAxesDlg->initialize();
290   
291   connect( myViewPort, SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), this, SLOT( emitViewModified() ) );
292 }
293
294 OCCViewer_ViewWindow* OCCViewer_ViewWindow::getView( const int mode ) const
295 {
296   return mode == get2dMode() ? const_cast<OCCViewer_ViewWindow*>( this ) : 0;
297 }
298
299 /*!
300   \brief Detect viewer operation according the the mouse button pressed
301   and key modifiers used.
302   \param theEvent mouse event
303   \return type of the operation
304 */
305 OCCViewer_ViewWindow::OperationType
306 OCCViewer_ViewWindow::getButtonState( QMouseEvent* theEvent, int theInteractionStyle )
307 {
308   OperationType aOp = NOTHING;
309   SUIT_ViewModel::InteractionStyle aStyle = (SUIT_ViewModel::InteractionStyle)theInteractionStyle;
310   if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::ZOOM]) &&
311       (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::ZOOM]) )
312     aOp = ZOOMVIEW;
313   else if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::PAN]) &&
314            (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::PAN]) )
315     aOp = PANVIEW;
316   else if( (theEvent->modifiers()  == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::ROTATE]) &&
317            (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::ROTATE]) &&
318            (my2dMode == No2dMode))
319     aOp = ROTATE;
320
321   return aOp;
322 }
323
324 /*!
325   \brief Customize event handling
326   \param watched event receiver object
327   \param e event
328   \return \c true if the event processing should be stopped
329 */
330 bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e )
331 {
332   if ( watched == myViewPort ) {
333     int aType = e->type();
334     switch(aType) {
335     case QEvent::MouseButtonPress:
336       vpMousePressEvent((QMouseEvent*) e);
337       return true;
338
339     case QEvent::MouseButtonRelease:
340       vpMouseReleaseEvent((QMouseEvent*) e);
341       return true;
342
343     case QEvent::MouseMove:
344       vpMouseMoveEvent((QMouseEvent*) e);
345       return true;
346
347     case QEvent::MouseButtonDblClick:
348       emit mouseDoubleClicked(this, (QMouseEvent*)e);
349       return true;
350
351     case QEvent::Wheel:
352       {
353         QWheelEvent* aEvent = (QWheelEvent*) e;
354         myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() );
355         double delta = (double)( aEvent->delta() ) / ( 15 * 8 );
356         int x  = aEvent->x();
357         int y  = aEvent->y();
358         int x1 = (int)( aEvent->x() + width()*delta/100 );
359         int y1 = (int)( aEvent->y() + height()*delta/100 );
360         myViewPort->zoom( x, y, x1, y1 );
361       }
362       return true;
363
364     case QEvent::ContextMenu:
365       {
366         QContextMenuEvent * aEvent = (QContextMenuEvent*)e;
367         if ( aEvent->reason() != QContextMenuEvent::Mouse )
368           emit contextMenuRequested( aEvent );
369       }
370       return true;
371
372     case QEvent::KeyPress:
373       emit keyPressed(this, (QKeyEvent*) e);
374       return true;
375
376     default:
377       break;
378     }
379   }
380   return SUIT_ViewWindow::eventFilter(watched, e);
381 }
382
383 /*!
384   \brief Update state of enable draw mode state.
385 */
386 void OCCViewer_ViewWindow::updateEnabledDrawMode()
387 {
388   if ( myModel )
389     myEnableDrawMode = myModel->isSelectionEnabled() && myModel->isMultiSelectionEnabled();
390 }
391
392 /*!
393   \brief Handle mouse press event
394   \param theEvent mouse event
395 */
396 void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent )
397 {
398   myStartX = theEvent->x();
399   myStartY = theEvent->y();
400   int anInteractionStyle = interactionStyle();
401
402   // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed),
403   // which are assigned for pan and rotate - these operations are activated immediately after pressing 
404   // of the first button, so it is necessary to switch to zoom when the second button is pressed
405   bool aSwitchToZoom = false;
406   if ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && 
407        ( myOperation == PANVIEW || myOperation == ROTATE ) ) {
408     aSwitchToZoom = getButtonState( theEvent, anInteractionStyle ) == ZOOMVIEW;
409   }
410
411   switch ( myOperation ) {
412   case WINDOWFIT:
413     if ( theEvent->button() == Qt::LeftButton )
414       emit vpTransformationStarted ( WINDOWFIT );
415     break;
416
417   case PANGLOBAL:
418     if ( theEvent->button() == Qt::LeftButton )
419       emit vpTransformationStarted ( PANGLOBAL );
420     break;
421
422   case ZOOMVIEW:
423     if ( theEvent->button() == Qt::LeftButton ) {
424       myViewPort->startZoomAtPoint( myStartX, myStartY );
425       emit vpTransformationStarted ( ZOOMVIEW );
426     }
427     break;
428
429   case PANVIEW:
430     if ( aSwitchToZoom ) {
431       myViewPort->startZoomAtPoint( myStartX, myStartY );
432       activateZoom();
433     }
434     else if ( theEvent->button() == Qt::LeftButton )
435       emit vpTransformationStarted ( PANVIEW );
436     break;
437
438   case ROTATE:
439     if ( aSwitchToZoom ) {
440       myViewPort->startZoomAtPoint( myStartX, myStartY );
441       activateZoom();
442     }
443     else if ( theEvent->button() == Qt::LeftButton ) {
444       myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
445       emit vpTransformationStarted ( ROTATE );
446     }
447     break;
448
449   default:
450   /*  Try to activate a transformation */
451     switch ( getButtonState(theEvent, anInteractionStyle) ) {
452     case ZOOMVIEW:
453       myViewPort->startZoomAtPoint( myStartX, myStartY );
454       activateZoom();
455       break;
456     case PANVIEW:
457             activatePanning();
458       break;
459     case ROTATE:
460             activateRotation();
461             myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint);
462       break;
463     default:
464       if ( myRotationPointSelection )
465       {
466         if ( theEvent->button() == Qt::LeftButton )
467         {
468           Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
469           ic->Select();
470           for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() )
471           {
472             TopoDS_Shape aShape = ic->SelectedShape();
473             if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX )
474             {
475               gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) );
476               if ( mySetRotationPointDlg )
477               {
478                 myRotationPointSelection = false;
479                 mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z());
480               }
481             }
482             else
483             {
484               myCurrPointType = myPrevPointType;
485               break;
486             }
487           }
488           if ( ic->NbSelected() == 0 ) myCurrPointType = myPrevPointType;
489           if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange();
490           ic->CloseAllContexts();
491           myOperation = NOTHING;
492           myViewPort->setCursor( myCursor );
493           myCursorIsHand = false;
494           myRotationPointSelection = false;
495         }
496       }
497       else
498         emit mousePressed(this, theEvent);
499       break;
500     }
501     /* notify that we start a transformation */
502     if ( transformRequested() )
503             emit vpTransformationStarted ( myOperation );
504   }
505   if ( transformRequested() )
506     setTransformInProcess( true );
507
508   /* we may need it for sketching... */
509   if ( l_mbPressEvent )
510     delete l_mbPressEvent;
511   l_mbPressEvent = new QMouseEvent( *theEvent );
512 }
513
514
515 /*!
516   \brief Start zooming operation.
517
518   Sets the corresponding cursor for the widget.
519 */
520 void OCCViewer_ViewWindow::activateZoom()
521 {
522   if ( !transformRequested() && !myCursorIsHand )
523     myCursor = cursor();                /* save old cursor */
524
525   if ( myOperation != ZOOMVIEW ) {
526     QPixmap zoomPixmap (imageZoomCursor);
527     QCursor zoomCursor (zoomPixmap);
528     if( setTransformRequested ( ZOOMVIEW ) )
529       myViewPort->setCursor( zoomCursor );
530   }
531 }
532
533
534 /*!
535   \brief Start panning operation.
536
537   Sets the corresponding cursor for the widget.
538 */
539 void OCCViewer_ViewWindow::activatePanning()
540 {
541   if ( !transformRequested() && !myCursorIsHand )
542     myCursor = cursor();                // save old cursor
543
544   if ( myOperation != PANVIEW ) {
545     QCursor panCursor (Qt::SizeAllCursor);
546     if( setTransformRequested ( PANVIEW ) )
547       myViewPort->setCursor( panCursor );
548   }
549 }
550
551 /*!
552   \brief Start rotation operation
553
554   Sets the corresponding cursor for the widget.
555 */
556 void OCCViewer_ViewWindow::activateRotation()
557 {
558   if ( !transformRequested() && !myCursorIsHand )
559     myCursor = cursor();                // save old cursor
560
561   if ( myOperation != ROTATE ) {
562     QPixmap rotatePixmap (imageRotateCursor);
563     QCursor rotCursor (rotatePixmap);
564     if( setTransformRequested ( ROTATE ) )
565       myViewPort->setCursor( rotCursor );
566   }
567 }
568
569 /*!
570   \brief Compute the gravity center.
571   \param theX used to return X coordinate of the gravity center
572   \param theY used to return Y coordinate of the gravity center
573   \param theZ used to return Z coordinate of the gravity center
574   \return \c true if the gravity center is computed
575 */
576 bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, double& theZ )
577 {
578   Handle(Visual3d_View) aView = myViewPort->getView()->View();
579
580   Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W ;
581   Standard_Real Umin,Vmin,Umax,Vmax ;
582   Standard_Integer Nstruct,Npoint ;
583   Graphic3d_MapOfStructure MySetOfStructures;
584
585   aView->DisplayedStructures (MySetOfStructures);
586   Nstruct = MySetOfStructures.Extent() ;
587
588   Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ;
589   aView->ViewMapping().WindowLimit(Umin,Vmin,Umax,Vmax) ;
590   Npoint = 0 ; theX = theY = theZ = 0. ;
591   for( ; MyIterator.More(); MyIterator.Next()) {
592     if (!(MyIterator.Key())->IsEmpty()) {
593       (MyIterator.Key())->MinMaxValues(Xmin,Ymin,Zmin,
594                                          Xmax,Ymax,Zmax) ;
595
596       Standard_Real LIM = ShortRealLast() -1.;
597       if (!    (fabs(Xmin) > LIM || fabs(Ymin) > LIM || fabs(Zmin) > LIM
598                 ||  fabs(Xmax) > LIM || fabs(Ymax) > LIM || fabs(Zmax) > LIM )) {
599
600         aView->Projects(Xmin,Ymin,Zmin,U,V,W) ;
601         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
602           Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmin ;
603         }
604         aView->Projects(Xmax,Ymin,Zmin,U,V,W) ;
605         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
606           Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmin ;
607         }
608         aView->Projects(Xmin,Ymax,Zmin,U,V,W) ;
609         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
610           Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmin ;
611         }
612         aView->Projects(Xmax,Ymax,Zmin,U,V,W) ;
613         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
614           Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmin ;
615         }
616         aView->Projects(Xmin,Ymin,Zmax,U,V,W) ;
617         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
618           Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmax ;
619         }
620         aView->Projects(Xmax,Ymin,Zmax,U,V,W) ;
621         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
622           Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmax ;
623         }
624         aView->Projects(Xmin,Ymax,Zmax,U,V,W) ;
625         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
626           Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmax ;
627         }
628         aView->Projects(Xmax,Ymax,Zmax,U,V,W) ;
629         if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) {
630           Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmax ;
631         }
632       }
633     }
634   }
635   if( Npoint > 0 ) {
636     theX /= Npoint ; theY /= Npoint ; theZ /= Npoint ;
637   }
638   return true;
639 }
640
641 /*!
642   \brief Set the gravity center as a rotation point.
643 */
644 void OCCViewer_ViewWindow::activateSetRotationGravity()
645 {
646   if ( myRotationPointSelection )
647   {
648     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
649     ic->CloseAllContexts();
650     myOperation = NOTHING;
651     myViewPort->setCursor( myCursor );
652     myCursorIsHand = false;
653     myRotationPointSelection = false;
654   }
655
656   myPrevPointType = myCurrPointType;
657   myCurrPointType = GRAVITY;
658
659   Standard_Real Xcenter, Ycenter, Zcenter;
660   if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) )
661     mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter );
662 }
663
664 /*!
665   \brief Update gravity center in the "Set Rotation Point" dialog box.
666   \sa OCCViewer_SetRotationPointDlg class
667 */
668 void OCCViewer_ViewWindow::updateGravityCoords()
669 {
670   if ( mySetRotationPointDlg && mySetRotationPointDlg->isVisible() && myCurrPointType == GRAVITY )
671   {
672     Standard_Real Xcenter, Ycenter, Zcenter;
673     if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) )
674       mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter );
675   }
676 }
677
678 /*!
679   \brief Set the point selected by the user as a rotation point.
680   \param theX X coordinate of the rotation point
681   \param theY Y coordinate of the rotation point
682   \param theZ Z coordinate of the rotation point
683 */
684 void OCCViewer_ViewWindow::activateSetRotationSelected( double theX, double theY, double theZ )
685 {
686   if ( myRotationPointSelection )
687   {
688     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
689     ic->CloseAllContexts();
690     myOperation = NOTHING;
691     myViewPort->setCursor( myCursor );
692     myCursorIsHand = false;
693     myRotationPointSelection = false;
694   }
695
696   myPrevPointType = myCurrPointType;
697   myCurrPointType = SELECTED;
698   mySelectedPoint.SetCoord(theX,theY,theZ);
699 }
700
701 /*!
702   \brief Start the point selection process.
703 */
704 void OCCViewer_ViewWindow::activateStartPointSelection()
705 {
706   myPrevPointType = myCurrPointType;
707   myCurrPointType = SELECTED;
708
709   // activate selection ------>
710   Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
711
712   ic->OpenLocalContext();
713
714   AIS_ListOfInteractive aList;
715   ic->DisplayedObjects( aList );
716   for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
717   {
718     Handle(AIS_InteractiveObject) anObj = it.Value();
719     if ( !anObj.IsNull() && anObj->HasPresentation() &&
720          anObj->IsKind( STANDARD_TYPE(AIS_Shape) ) )
721     {
722       ic->Load(anObj,-1);
723       ic->Activate(anObj,AIS_Shape::SelectionMode(TopAbs_VERTEX));
724      }
725   }
726   // activate selection <------
727
728   if ( !myCursorIsHand )
729   {
730     QCursor handCursor (Qt::PointingHandCursor);
731     myCursorIsHand = true;
732     myCursor = cursor();
733     myViewPort->setCursor( handCursor );
734   }
735   myRotationPointSelection = true;
736 }
737
738 /*!
739   \brief Start global panning operation
740
741   Sets the corresponding cursor for the widget.
742 */
743 void OCCViewer_ViewWindow::activateGlobalPanning()
744 {
745   Handle(V3d_View) aView3d = myViewPort->getView();
746   if ( !aView3d.IsNull() ) {
747     QPixmap globalPanPixmap (imageCrossCursor);
748     QCursor glPanCursor (globalPanPixmap);
749     myCurScale = aView3d->Scale();
750     aView3d->FitAll(0.01, false);
751     myCursor = cursor();                // save old cursor
752     myViewPort->fitAll(); // fits view before selecting a new scene center
753     if( setTransformRequested( PANGLOBAL ) )
754       myViewPort->setCursor( glPanCursor );
755   }
756 }
757
758 /*!
759   \brief Starts fit operation.
760
761   Sets the corresponding cursor for the widget.
762 */
763 void OCCViewer_ViewWindow::activateWindowFit()
764 {
765   if ( !transformRequested() && !myCursorIsHand )
766     myCursor = cursor();                /* save old cursor */
767
768   if ( myOperation != WINDOWFIT ) {
769     QCursor handCursor (Qt::PointingHandCursor);
770     if( setTransformRequested ( WINDOWFIT ) )
771     {
772       myViewPort->setCursor ( handCursor );
773       myCursorIsHand = true;
774     }
775   }
776 }
777
778 /*!
779   \brief Start delayed viewer operation.
780 */
781 bool OCCViewer_ViewWindow::setTransformRequested( OperationType op )
782 {
783   bool ok = transformEnabled( op );
784   myOperation = ok ? op : NOTHING;
785   myViewPort->setMouseTracking( myOperation == NOTHING );  
786   return ok;
787 }
788
789 /*!
790   \brief Handle mouse move event.
791   \param theEvent mouse event
792 */
793 void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent )
794 {
795   myCurrX = theEvent->x();
796   myCurrY = theEvent->y();
797   switch (myOperation) {
798   case ROTATE:
799     myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint);
800     break;
801
802   case ZOOMVIEW:
803     myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY);
804     myStartX = myCurrX;
805     myStartY = myCurrY;
806     break;
807
808   case PANVIEW:
809     myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY);
810     myStartX = myCurrX;
811     myStartY = myCurrY;
812     break;
813
814 /*    case WINDOWFIT:
815     myDrawRect = true;
816     repaint();
817     break;
818 */
819   case PANGLOBAL:
820     break;
821
822   default:
823     if ( myRotationPointSelection || isSketcherStyle() )
824     {
825       emit mouseMoving( this, theEvent );
826     }
827     else
828     {
829       int aState = theEvent->modifiers();
830       int aButton = theEvent->buttons();
831       int anInteractionStyle = interactionStyle();
832       if ( anInteractionStyle == SUIT_ViewModel::STANDARD && 
833            aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) {
834         myDrawRect = myEnableDrawMode;
835         if ( myDrawRect ) {
836           drawRect();
837           if ( !myCursorIsHand )        {   // we are going to sketch a rectangle
838             QCursor handCursor (Qt::PointingHandCursor);
839             myCursorIsHand = true;
840             myCursor = cursor();
841             myViewPort->setCursor( handCursor );
842           }
843         }
844         emit mouseMoving( this, theEvent );
845       }
846       else if ( anInteractionStyle == SUIT_ViewModel::STANDARD && 
847                 aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) {
848         OCCViewer_ViewSketcher* sketcher = 0;
849         QList<OCCViewer_ViewSketcher*>::Iterator it;
850         for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it )
851         {
852           OCCViewer_ViewSketcher* sk = (*it);
853           if( sk->isDefault() && sk->sketchButton() == aButton )
854             sketcher = sk;
855         }
856         if ( sketcher && myCurSketch == -1 )
857         {
858           activateSketching( sketcher->type() );
859           if ( mypSketcher )
860           {
861             myCurSketch = mypSketcher->sketchButton();
862
863             if ( l_mbPressEvent )
864             {
865               QApplication::sendEvent( getViewPort(), l_mbPressEvent );
866               delete l_mbPressEvent;
867               l_mbPressEvent = 0;
868             }
869             QApplication::sendEvent( getViewPort(), theEvent );
870           }
871         }
872       }
873       else
874         emit mouseMoving( this, theEvent );
875     }
876   }
877 }
878
879 /*!
880   \brief Handle mouse release event.
881   \param theEvent mouse event
882 */
883 void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent)
884 {
885   switch ( myOperation ) {
886   case NOTHING:
887     {
888       int prevState = myCurSketch;
889       if(theEvent->button() == Qt::RightButton)
890       {
891         QList<OCCViewer_ViewSketcher*>::Iterator it;
892         for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it )
893         {
894           OCCViewer_ViewSketcher* sk = (*it);
895           if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch )
896             myCurSketch = -1;
897         }
898       }
899
900       emit mouseReleased(this, theEvent);
901       if(theEvent->button() == Qt::RightButton && prevState == -1)
902       {
903         QContextMenuEvent aEvent( QContextMenuEvent::Mouse,
904                                   theEvent->pos(), theEvent->globalPos() );
905         emit contextMenuRequested( &aEvent );
906       }
907     }
908     break;
909   case ROTATE:
910     myViewPort->endRotation();
911     resetState();
912     break;
913
914   case PANVIEW:
915   case ZOOMVIEW:
916     resetState();
917     break;
918
919   case PANGLOBAL:
920     if ( theEvent->button() == Qt::LeftButton ) {
921       myViewPort->setCenter( theEvent->x(), theEvent->y() );
922       myViewPort->getView()->SetScale(myCurScale);
923       resetState();
924     }
925     break;
926
927   case WINDOWFIT:
928     if ( theEvent->button() == Qt::LeftButton ) {
929       myCurrX = theEvent->x();
930       myCurrY = theEvent->y();
931       drawRect();
932       QRect rect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
933       if ( !rect.isEmpty() ) myViewPort->fitRect(rect);
934       endDrawRect();
935       resetState();
936     }
937     break;
938   }
939
940   // NOTE: viewer 3D detects a rectangle of selection using this event
941   // so we must emit it BEFORE resetting the selection rectangle
942
943   if ( theEvent->button() == Qt::LeftButton && myDrawRect ) {
944     drawRect();
945     endDrawRect();
946     resetState();
947     myViewPort->update();
948   }
949
950   if ( l_mbPressEvent )
951   {
952     delete l_mbPressEvent;
953     l_mbPressEvent = 0;
954   }
955 }
956
957 /*!
958   \brief Reset the viewport to its initial state
959   ( no transformations in process etc. )
960 */
961 void OCCViewer_ViewWindow::resetState()
962 {
963   myDrawRect = false;
964
965   if ( myRotationPointSelection )
966   {
967     QCursor handCursor (Qt::PointingHandCursor);
968     myViewPort->setCursor( handCursor );
969   }
970   else
971   {
972     if ( transformRequested() || myCursorIsHand )
973       myViewPort->setCursor( myCursor );
974     myCursorIsHand = false;
975   }
976
977   if ( transformRequested() )
978     emit vpTransformationFinished (myOperation);
979
980   setTransformInProcess( false );
981   setTransformRequested( NOTHING );
982 }
983
984
985 /*!
986   \brief Draw rubber band rectangle.
987 */
988 void OCCViewer_ViewWindow::drawRect()
989 {
990   if ( !myRectBand ) {
991     myRectBand = new QtxRectRubberBand( myViewPort );
992     //QPalette palette;
993     //palette.setColor(myRectBand->foregroundRole(), Qt::white);
994     //myRectBand->setPalette(palette);
995   }
996   //myRectBand->hide();
997   
998   myRectBand->setUpdatesEnabled ( false );
999   QRect aRect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
1000   myRectBand->initGeometry( aRect );
1001
1002   if ( !myRectBand->isVisible() )
1003     myRectBand->show();
1004
1005   myRectBand->setUpdatesEnabled ( true );
1006   //myRectBand->repaint();
1007
1008   //myRectBand->setVisible( aRect.isValid() );
1009   //if ( myRectBand->isVisible() )
1010   //  myRectBand->repaint();
1011   //else
1012   //  myRectBand->show();
1013   //myRectBand->repaint();
1014 }
1015
1016 /*!
1017   \brief Clear rubber band rectangle on the end on the dragging operation.
1018 */
1019 void OCCViewer_ViewWindow::endDrawRect()
1020 {
1021   //delete myRectBand;
1022   //myRectBand = 0;
1023   if ( myRectBand )
1024     {
1025       myRectBand->clearGeometry();
1026       myRectBand->hide();
1027     }
1028 }
1029
1030 /*!
1031   \brief Create actions.
1032 */
1033 void OCCViewer_ViewWindow::createActions()
1034 {
1035   if( !toolMgr()->isEmpty() )
1036     return;
1037   
1038   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
1039
1040   QtxAction* aAction;
1041
1042   // Dump view
1043   aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_DUMP" ) ),
1044                            tr( "MNU_DUMP_VIEW" ), 0, this);
1045   aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
1046   connect(aAction, SIGNAL(triggered()), this, SLOT(onDumpView()));
1047   toolMgr()->registerAction( aAction, DumpId );
1048
1049   // FitAll
1050   aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITALL" ) ),
1051                            tr( "MNU_FITALL" ), 0, this);
1052   aAction->setStatusTip(tr("DSC_FITALL"));
1053   connect(aAction, SIGNAL(triggered()), this, SLOT(onFitAll()));
1054   toolMgr()->registerAction( aAction, FitAllId );
1055
1056   // FitRect
1057   aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITAREA" ) ),
1058                            tr( "MNU_FITRECT" ), 0, this);
1059   aAction->setStatusTip(tr("DSC_FITRECT"));
1060   connect(aAction, SIGNAL(triggered()), this, SLOT(activateWindowFit()));
1061   toolMgr()->registerAction( aAction, FitRectId );
1062   
1063   // Zoom
1064   aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ZOOM" ) ),
1065                            tr( "MNU_ZOOM_VIEW" ), 0, this);
1066   aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
1067   connect(aAction, SIGNAL(triggered()), this, SLOT(activateZoom()));
1068   toolMgr()->registerAction( aAction, ZoomId );
1069
1070   // Panning
1071   aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_PAN" ) ),
1072                            tr( "MNU_PAN_VIEW" ), 0, this);
1073   aAction->setStatusTip(tr("DSC_PAN_VIEW"));
1074   connect(aAction, SIGNAL(triggered()), this, SLOT(activatePanning()));
1075   toolMgr()->registerAction( aAction, PanId );
1076
1077   // Global Panning
1078   aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_GLOBALPAN" ) ),
1079                            tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
1080   aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
1081   connect(aAction, SIGNAL(triggered()), this, SLOT(activateGlobalPanning()));
1082   toolMgr()->registerAction( aAction, GlobalPanId );
1083
1084   // Rotation Point
1085   mySetRotationPointAction = new QtxAction(tr("MNU_CHANGINGROTATIONPOINT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATION_POINT" ) ),
1086                            tr( "MNU_CHANGINGROTATIONPOINT_VIEW" ), 0, this);
1087   mySetRotationPointAction->setStatusTip(tr("DSC_CHANGINGROTATIONPOINT_VIEW"));
1088   mySetRotationPointAction->setCheckable( true );
1089   connect(mySetRotationPointAction, SIGNAL(toggled( bool )), this, SLOT(onSetRotationPoint( bool )));
1090   toolMgr()->registerAction( mySetRotationPointAction, ChangeRotationPointId );
1091
1092   // Rotation
1093   aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATE" ) ),
1094                            tr( "MNU_ROTATE_VIEW" ), 0, this);
1095   aAction->setStatusTip(tr("DSC_ROTATE_VIEW"));
1096   connect(aAction, SIGNAL(triggered()), this, SLOT(activateRotation()));
1097   toolMgr()->registerAction( aAction, RotationId );
1098
1099   // Projections
1100   aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FRONT" ) ),
1101                            tr( "MNU_FRONT_VIEW" ), 0, this, false, "Viewers:Front view");
1102   aAction->setStatusTip(tr("DSC_FRONT_VIEW"));
1103   connect(aAction, SIGNAL(triggered()), this, SLOT(onFrontView()));
1104   this->addAction(aAction);
1105   toolMgr()->registerAction( aAction, FrontId );
1106
1107   aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BACK" ) ),
1108                            tr( "MNU_BACK_VIEW" ), 0, this, false, "Viewers:Back view");
1109   aAction->setStatusTip(tr("DSC_BACK_VIEW"));
1110   connect(aAction, SIGNAL(triggered()), this, SLOT(onBackView()));
1111   this->addAction(aAction);
1112   toolMgr()->registerAction( aAction, BackId );
1113
1114   aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TOP" ) ),
1115                            tr( "MNU_TOP_VIEW" ), 0, this, false, "Viewers:Top view");
1116   aAction->setStatusTip(tr("DSC_TOP_VIEW"));
1117   connect(aAction, SIGNAL(triggered()), this, SLOT(onTopView()));
1118   this->addAction(aAction);
1119   toolMgr()->registerAction( aAction, TopId );
1120
1121   aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BOTTOM" ) ),
1122                            tr( "MNU_BOTTOM_VIEW" ), 0, this, false, "Viewers:Bottom view");
1123   aAction->setStatusTip(tr("DSC_BOTTOM_VIEW"));
1124   connect(aAction, SIGNAL(triggered()), this, SLOT(onBottomView()));
1125   this->addAction(aAction);
1126   toolMgr()->registerAction( aAction, BottomId );
1127   
1128   aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_LEFT" ) ),
1129                            tr( "MNU_LEFT_VIEW" ), 0, this, false, "Viewers:Left view");
1130   aAction->setStatusTip(tr("DSC_LEFT_VIEW"));
1131   connect(aAction, SIGNAL(triggered()), this, SLOT(onLeftView()));
1132   this->addAction(aAction);
1133   toolMgr()->registerAction( aAction, LeftId );
1134
1135   aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RIGHT" ) ),
1136                            tr( "MNU_RIGHT_VIEW" ), 0, this, false, "Viewers:Right view");
1137   aAction->setStatusTip(tr("DSC_RIGHT_VIEW"));
1138   connect(aAction, SIGNAL(triggered()), this, SLOT(onRightView()));
1139   this->addAction(aAction);
1140   toolMgr()->registerAction( aAction, RightId );
1141
1142   // rotate anticlockwise
1143   aAction = new QtxAction(tr("MNU_ANTICLOCKWISE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ANTICLOCKWISE" ) ),
1144                            tr( "MNU_ANTICLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate anticlockwise");
1145   aAction->setStatusTip(tr("DSC_ANTICLOCKWISE_VIEW"));
1146   connect(aAction, SIGNAL(triggered()), this, SLOT(onAntiClockWiseView()));
1147   this->addAction(aAction);
1148   toolMgr()->registerAction( aAction, AntiClockWiseId );
1149
1150   // rotate clockwise
1151   aAction = new QtxAction(tr("MNU_CLOCKWISE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_CLOCKWISE" ) ),
1152                            tr( "MNU_CLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate clockwise");
1153   aAction->setStatusTip(tr("DSC_CLOCKWISE_VIEW"));
1154   connect(aAction, SIGNAL(triggered()), this, SLOT(onClockWiseView()));
1155   this->addAction(aAction);
1156   toolMgr()->registerAction( aAction, ClockWiseId );
1157
1158   // Reset
1159   aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RESET" ) ),
1160                            tr( "MNU_RESET_VIEW" ), 0, this, false, "Viewers:Reset view");
1161   aAction->setStatusTip(tr("DSC_RESET_VIEW"));
1162   connect(aAction, SIGNAL(triggered()), this, SLOT(onResetView()));
1163   this->addAction(aAction);
1164   toolMgr()->registerAction( aAction, ResetId );
1165
1166   // Clone
1167   aAction = new QtxAction(tr("MNU_CLONE_VIEW"),
1168                           aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_CLONE_VIEW")),
1169                           tr("MNU_CLONE_VIEW"), 0, this);
1170   aAction->setStatusTip(tr("DSC_CLONE_VIEW"));
1171   connect(aAction, SIGNAL(triggered()), this, SLOT(onCloneView()));
1172   toolMgr()->registerAction( aAction, CloneId );
1173
1174   myClippingAction = new QtxAction(tr("MNU_CLIPPING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" ) ),
1175                            tr( "MNU_CLIPPING" ), 0, this);
1176   myClippingAction->setStatusTip(tr("DSC_CLIPPING"));
1177   myClippingAction->setCheckable( true );
1178   connect(myClippingAction, SIGNAL(toggled( bool )), this, SLOT(onClipping( bool )));
1179   toolMgr()->registerAction( myClippingAction, ClippingId );
1180
1181   aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ),
1182                            tr( "MNU_SHOOT_VIEW" ), 0, this);
1183   aAction->setStatusTip(tr("DSC_SHOOT_VIEW"));
1184   connect(aAction, SIGNAL(triggered()), this, SLOT(onMemorizeView()));
1185   toolMgr()->registerAction( aAction, MemId );
1186
1187   aAction = new QtxAction(tr("MNU_PRESETS_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESETS_VIEW" ) ),
1188                            tr( "MNU_PRESETS_VIEW" ), 0, this);
1189   aAction->setStatusTip(tr("DSC_PRESETS_VIEW"));
1190   connect(aAction, SIGNAL(triggered()), this, SLOT(onRestoreView()));
1191   toolMgr()->registerAction( aAction, RestoreId );
1192
1193   if (myModel->trihedronActivated()) {
1194     aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TRIHEDRON" ) ),
1195                              tr( "MNU_SHOW_TRIHEDRE" ), 0, this);
1196     aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRE"));
1197     connect(aAction, SIGNAL(triggered()), this, SLOT(onTrihedronShow()));
1198     toolMgr()->registerAction( aAction, TrihedronShowId );
1199   }
1200
1201   // Scale
1202   aAction = new QtxAction(tr("MNU_SCALING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SCALING" ) ),
1203                            tr( "MNU_SCALING" ), 0, this);
1204   aAction->setStatusTip(tr("DSC_SCALING"));
1205   connect(aAction, SIGNAL(triggered()), this, SLOT(onAxialScale()));
1206   toolMgr()->registerAction( aAction, AxialScaleId );
1207
1208   // Graduated axes 
1209   aAction = new QtxAction(tr("MNU_GRADUATED_AXES"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_GRADUATED_AXES" ) ),
1210                            tr( "MNU_GRADUATED_AXES" ), 0, this);
1211   aAction->setStatusTip(tr("DSC_GRADUATED_AXES"));
1212   connect(aAction, SIGNAL(triggered()), this, SLOT(onGraduatedAxes()));
1213   toolMgr()->registerAction( aAction, GraduatedAxesId );
1214
1215   // Active only ambient light or not
1216   aAction = new QtxAction(tr("MNU_AMBIENT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_AMBIENT" ) ),
1217                            tr( "MNU_AMBIENT" ), 0, this);
1218   aAction->setStatusTip(tr("DSC_AMBIENT"));
1219   connect(aAction, SIGNAL(triggered()), this, SLOT(onAmbientToogle()));
1220   toolMgr()->registerAction( aAction, AmbientId );
1221
1222   // Switch between interaction styles
1223   aAction = new QtxAction(tr("MNU_STYLE_SWITCH"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_STYLE_SWITCH" ) ),
1224                           tr( "MNU_STYLE_SWITCH" ), 0, this);
1225   aAction->setStatusTip(tr("DSC_STYLE_SWITCH"));
1226   aAction->setCheckable(true);
1227   connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchInteractionStyle(bool)));
1228   toolMgr()->registerAction( aAction, SwitchInteractionStyleId );
1229
1230   // Switch between zooming styles
1231   aAction = new QtxAction(tr("MNU_ZOOMING_STYLE_SWITCH"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_ZOOMING_STYLE_SWITCH" ) ),
1232                           tr( "MNU_ZOOMING_STYLE_SWITCH" ), 0, this);
1233   aAction->setStatusTip(tr("DSC_ZOOMING_STYLE_SWITCH"));
1234   aAction->setCheckable(true);
1235   connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchZoomingStyle(bool)));
1236   toolMgr()->registerAction( aAction, SwitchZoomingStyleId );
1237
1238   // Maximized view
1239   aAction = new QtxAction(tr("MNU_MINIMIZE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ),
1240                           tr( "MNU_MINIMIZE_VIEW" ), 0, this );
1241   aAction->setStatusTip(tr("DSC_MINIMIZE_VIEW"));
1242   connect(aAction, SIGNAL(triggered()), this, SLOT(onMaximizedView()));
1243   toolMgr()->registerAction( aAction, MaximizedId );
1244
1245   // Synchronize View 
1246   toolMgr()->registerAction( synchronizeAction(), SynchronizeId );
1247 }
1248
1249 /*!
1250   \brief Create toolbar.
1251 */
1252 void OCCViewer_ViewWindow::createToolBar()
1253 {
1254   QString aToolbarName;
1255   switch (my2dMode) {
1256   case XYPlane:
1257     aToolbarName = tr( "LBL_XYTOOLBAR_LABEL" );
1258     break;
1259   case XZPlane:
1260     aToolbarName = tr( "LBL_XZTOOLBAR_LABEL" );
1261     break;
1262   case YZPlane:
1263     aToolbarName = tr( "LBL_YZTOOLBAR_LABEL" );
1264     break;
1265   default:
1266     aToolbarName = tr( "LBL_3DTOOLBAR_LABEL" );
1267   }
1268   
1269   int tid = toolMgr()->createToolBar( aToolbarName, false );
1270
1271   toolMgr()->append( DumpId, tid );
1272   toolMgr()->append( SwitchInteractionStyleId, tid );
1273 #if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version
1274   toolMgr()->append( SwitchZoomingStyleId, tid );
1275 #endif
1276   if( myModel->trihedronActivated() )
1277     toolMgr()->append( TrihedronShowId, tid );
1278
1279   QtxMultiAction* aScaleAction = new QtxMultiAction( this );
1280   aScaleAction->insertAction( toolMgr()->action( FitAllId ) );
1281   aScaleAction->insertAction( toolMgr()->action( FitRectId ) );
1282   aScaleAction->insertAction( toolMgr()->action( ZoomId ) );
1283   toolMgr()->append( aScaleAction, tid );
1284
1285   QtxMultiAction* aPanningAction = new QtxMultiAction( this );
1286   aPanningAction->insertAction( toolMgr()->action( PanId ) );
1287   aPanningAction->insertAction( toolMgr()->action( GlobalPanId ) );
1288   toolMgr()->append( aPanningAction, tid );
1289
1290   if (my2dMode == No2dMode) {
1291     toolMgr()->append( ChangeRotationPointId, tid );
1292     toolMgr()->append( RotationId, tid );
1293
1294     QtxMultiAction* aViewsAction = new QtxMultiAction( this );
1295     aViewsAction->insertAction( toolMgr()->action( FrontId ) );
1296     aViewsAction->insertAction( toolMgr()->action( BackId ) );
1297     aViewsAction->insertAction( toolMgr()->action( TopId ) );
1298     aViewsAction->insertAction( toolMgr()->action( BottomId ) );
1299     aViewsAction->insertAction( toolMgr()->action( LeftId ) );
1300     aViewsAction->insertAction( toolMgr()->action( RightId ) );
1301     toolMgr()->append( aViewsAction, tid );
1302
1303     toolMgr()->append( AntiClockWiseId, tid );
1304     toolMgr()->append( ClockWiseId, tid );
1305
1306     toolMgr()->append( ResetId, tid );
1307   }
1308
1309   QtxMultiAction* aMemAction = new QtxMultiAction( this );
1310   aMemAction->insertAction( toolMgr()->action( MemId ) );
1311   aMemAction->insertAction( toolMgr()->action( RestoreId ) );
1312   toolMgr()->append( aMemAction, tid );
1313
1314   toolMgr()->append( toolMgr()->separator(), tid );
1315   toolMgr()->append( CloneId, tid );
1316   
1317   toolMgr()->append( toolMgr()->separator(), tid );
1318   toolMgr()->append( ClippingId, tid );
1319   toolMgr()->append( AxialScaleId, tid );
1320 #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version
1321   toolMgr()->append( GraduatedAxesId, tid );
1322 #endif
1323   toolMgr()->append( AmbientId, tid );
1324
1325   toolMgr()->append( MaximizedId, tid );
1326   toolMgr()->append( SynchronizeId, tid );
1327 }
1328
1329 /*!
1330   \brief Perform 'fit all' operation.
1331 */
1332 void OCCViewer_ViewWindow::onViewFitAll()
1333 {
1334   myViewPort->fitAll();
1335 }
1336
1337 /*!
1338   \brief Perform "front view" transformation.
1339 */
1340 void OCCViewer_ViewWindow::onFrontView()
1341 {
1342   emit vpTransformationStarted ( FRONTVIEW );
1343   Handle(V3d_View) aView3d = myViewPort->getView();
1344   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xpos);
1345   onViewFitAll();
1346   emit vpTransformationFinished ( FRONTVIEW );
1347 }
1348
1349 /*!
1350   \brief Perform "back view" transformation.
1351 */
1352 void OCCViewer_ViewWindow::onBackView()
1353 {
1354   emit vpTransformationStarted ( BACKVIEW );
1355   Handle(V3d_View) aView3d = myViewPort->getView();
1356   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xneg);
1357   onViewFitAll();
1358   emit vpTransformationFinished ( BACKVIEW );
1359 }
1360
1361 /*!
1362   \brief Perform "top view" transformation.
1363 */
1364 void OCCViewer_ViewWindow::onTopView()
1365 {
1366   emit vpTransformationStarted ( TOPVIEW );
1367   Handle(V3d_View) aView3d = myViewPort->getView();
1368   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zpos);
1369   onViewFitAll();
1370   emit vpTransformationFinished ( TOPVIEW );
1371 }
1372
1373 /*!
1374   \brief Perform "bottom view" transformation.
1375 */
1376 void OCCViewer_ViewWindow::onBottomView()
1377 {
1378   emit vpTransformationStarted ( BOTTOMVIEW );
1379   Handle(V3d_View) aView3d = myViewPort->getView();
1380   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zneg);
1381   onViewFitAll();
1382   emit vpTransformationFinished ( BOTTOMVIEW );
1383 }
1384
1385 /*!
1386   \brief Perform "left view" transformation.
1387 */
1388 void OCCViewer_ViewWindow::onLeftView()
1389 {
1390   emit vpTransformationStarted ( LEFTVIEW );
1391   Handle(V3d_View) aView3d = myViewPort->getView();
1392   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Yneg);
1393   onViewFitAll();
1394   emit vpTransformationFinished ( LEFTVIEW );
1395 }
1396
1397 /*!
1398   \brief Perform "right view" transformation.
1399 */
1400 void OCCViewer_ViewWindow::onRightView()
1401 {
1402   emit vpTransformationStarted ( RIGHTVIEW );
1403   Handle(V3d_View) aView3d = myViewPort->getView();
1404   if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Ypos);
1405   onViewFitAll();
1406   emit vpTransformationFinished ( RIGHTVIEW );
1407 }
1408
1409 /*!
1410   \brief Rotate view 90 degrees clockwise
1411 */
1412 void OCCViewer_ViewWindow::onClockWiseView()
1413 {
1414   emit vpTransformationStarted ( CLOCKWISEVIEW );
1415   myViewPort->rotateXY( 90. );
1416   emit vpTransformationFinished ( CLOCKWISEVIEW );
1417 }
1418
1419 /*!
1420   \brief Rotate view 90 degrees conterclockwise
1421 */
1422 void OCCViewer_ViewWindow::onAntiClockWiseView()
1423 {
1424   emit vpTransformationStarted ( ANTICLOCKWISEVIEW );
1425   myViewPort->rotateXY( -90. );
1426   emit vpTransformationFinished ( ANTICLOCKWISEVIEW );
1427 }
1428
1429 /*!
1430   \brief Perform "reset view" transformation.
1431
1432   Sets default orientation of the viewport camera.
1433 */
1434 void OCCViewer_ViewWindow::onResetView()
1435 {
1436   emit vpTransformationStarted( RESETVIEW );
1437   bool upd = myViewPort->getView()->SetImmediateUpdate( false );
1438   myViewPort->getView()->Reset( false );
1439   myViewPort->fitAll( false, true, false );
1440   myViewPort->getView()->SetImmediateUpdate( upd );
1441   myViewPort->getView()->Update();
1442   emit vpTransformationFinished( RESETVIEW );
1443 }
1444
1445 /*!
1446   \brief Perform "fit all" transformation.
1447 */
1448 void OCCViewer_ViewWindow::onFitAll()
1449 {
1450   emit vpTransformationStarted( FITALLVIEW );
1451   myViewPort->fitAll();
1452   emit vpTransformationFinished( FITALLVIEW );
1453 }
1454
1455 /*!
1456   \brief Called if 'change rotation point' operation is activated.
1457   \param on action state
1458 */
1459 void OCCViewer_ViewWindow::onSetRotationPoint( bool on )
1460 {
1461   if (on)
1462   {
1463     if (!mySetRotationPointDlg)
1464     {
1465       mySetRotationPointDlg = new OCCViewer_SetRotationPointDlg (this);
1466       mySetRotationPointDlg->SetAction(mySetRotationPointAction);
1467     }
1468
1469     if (!mySetRotationPointDlg->isVisible())
1470     {
1471       //if (mySetRotationPointDlg->IsFirstShown())
1472       if (myCurrPointType == GRAVITY)
1473       {
1474         Standard_Real Xcenter, Ycenter, Zcenter;
1475         if (computeGravityCenter(Xcenter, Ycenter, Zcenter))
1476           mySetRotationPointDlg->setCoords(Xcenter, Ycenter, Zcenter);
1477       }
1478       mySetRotationPointDlg->show();
1479     }
1480   }
1481   else
1482   {
1483     if (mySetRotationPointDlg->isVisible())
1484       mySetRotationPointDlg->hide();
1485   }
1486 }
1487
1488 /*!
1489    \brief Create one more window with same content.
1490 */
1491 void OCCViewer_ViewWindow::onCloneView()
1492 {
1493   SUIT_ViewWindow* vw = myManager->createViewWindow();
1494   //vw->show();
1495   emit viewCloned( vw );
1496 }
1497
1498 /*!
1499   \brief called if clipping operation is activated.
1500
1501   Enables/disables clipping plane displaying.
1502
1503   \parma on action state
1504 */
1505 void OCCViewer_ViewWindow::onClipping( bool on )
1506 {
1507   /*
1508   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
1509   if ( on )
1510     myActionsMap[ ClippingId ]->setIcon(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING_PRESSED" )));
1511   else
1512     myActionsMap[ ClippingId ]->setIcon(aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_CLIPPING" )));
1513   */
1514   OCCViewer_ViewWindow* aParent = dynamic_cast<OCCViewer_ViewWindow*>(parent()->parent());
1515   if (!aParent)
1516     aParent = this;
1517   if ( on )
1518     {
1519       if ( !myClippingDlg )
1520         {
1521           myClippingDlg = new OCCViewer_ClippingDlg( aParent );
1522           myClippingDlg->SetAction( myClippingAction );
1523         }
1524     
1525       if ( !myClippingDlg->isVisible() )
1526         myClippingDlg->show();
1527     }
1528   else
1529     {
1530       if ( myClippingDlg->isVisible() )
1531         myClippingDlg->hide();
1532       aParent->setCuttingPlane(false);
1533     }
1534 }
1535
1536 /*!
1537   Creates one more window with same content
1538 */
1539 void OCCViewer_ViewWindow::onAxialScale()
1540 {
1541   if ( !myScalingDlg )
1542     myScalingDlg = new OCCViewer_AxialScaleDlg( this );
1543   
1544   if ( !myScalingDlg->isVisible() )
1545   {
1546     myScalingDlg->Update();
1547     myScalingDlg->show();
1548   }
1549 }
1550
1551 /*!
1552   Shows Graduated Axes dialog
1553 */
1554 void OCCViewer_ViewWindow::onGraduatedAxes()
1555 {
1556   myCubeAxesDlg->Update();
1557   myCubeAxesDlg->show();
1558 }
1559
1560 void OCCViewer_ViewWindow::onAmbientToogle()
1561 {
1562   Handle(V3d_Viewer) viewer = myViewPort->getViewer();
1563   viewer->InitDefinedLights();
1564   while(viewer->MoreDefinedLights())
1565     {
1566       Handle(V3d_Light) light = viewer->DefinedLight();
1567       if(light->Type() != V3d_AMBIENT)
1568         {
1569           Handle(V3d_View) aView3d = myViewPort->getView();
1570           if( aView3d->IsActiveLight(light) ) viewer->SetLightOff(light);
1571           else viewer->SetLightOn(light);
1572         }
1573       viewer->NextDefinedLights();
1574     }
1575   viewer->Update();
1576 }
1577
1578 /*!
1579   \brief Store view parameters.
1580 */
1581 void OCCViewer_ViewWindow::onMemorizeView()
1582 {
1583   appendViewAspect( getViewParams() );
1584 }
1585
1586 /*!
1587   \brief Restore view parameters.
1588 */
1589 void OCCViewer_ViewWindow::onRestoreView()
1590 {
1591   OCCViewer_CreateRestoreViewDlg* aDlg = new OCCViewer_CreateRestoreViewDlg( centralWidget(), this );
1592   connect( aDlg, SIGNAL( dlgOk() ), this, SLOT( setRestoreFlag() ) );
1593   aDlg->exec();
1594   updateViewAspects( aDlg->parameters() );
1595   if( myRestoreFlag && aDlg->parameters().count() )
1596     performRestoring( aDlg->currentItem() );
1597 }
1598
1599 /*!
1600   \brief Restore view parameters.
1601   \param anItem view parameters
1602 */
1603 void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool baseParamsOnly )
1604 {
1605   Handle(V3d_View) aView3d = myViewPort->getView();
1606
1607   Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False );
1608   aView3d->SetScale( anItem.scale );
1609   aView3d->SetCenter( anItem.centerX, anItem.centerY );
1610   aView3d->SetTwist( anItem.twist );
1611   aView3d->SetAt( anItem.atX, anItem.atY, anItem.atZ );
1612   aView3d->SetImmediateUpdate( prev );
1613   aView3d->SetEye( anItem.eyeX, anItem.eyeY, anItem.eyeZ );
1614   aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ );
1615   aView3d->SetAxialScale( anItem.scaleX, anItem.scaleY, anItem.scaleZ );
1616
1617   if ( !baseParamsOnly ) {
1618
1619     myModel->setTrihedronShown( anItem.isVisible );
1620     myModel->setTrihedronSize( anItem.size );
1621         
1622 #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version
1623     // graduated trihedron
1624     bool anIsVisible = anItem.gtIsVisible;
1625     OCCViewer_AxisWidget::AxisData anAxisData[3];
1626     anAxisData[0].DrawName = anItem.gtDrawNameX;
1627     anAxisData[1].DrawName = anItem.gtDrawNameZ;
1628     anAxisData[2].DrawName = anItem.gtDrawNameZ;
1629     anAxisData[0].Name = anItem.gtNameX;
1630     anAxisData[1].Name = anItem.gtNameZ;
1631     anAxisData[2].Name = anItem.gtNameZ;
1632     anAxisData[0].NameColor = QColor( anItem.gtNameColorRX,
1633                                       anItem.gtNameColorGX,
1634                                       anItem.gtNameColorBX );
1635     anAxisData[1].NameColor = QColor( anItem.gtNameColorRY,
1636                                       anItem.gtNameColorGY,
1637                                       anItem.gtNameColorBY );
1638     anAxisData[2].NameColor = QColor( anItem.gtNameColorRZ,
1639                                       anItem.gtNameColorGZ,
1640                                       anItem.gtNameColorBZ );
1641     anAxisData[0].DrawValues = anItem.gtDrawValuesX;
1642     anAxisData[1].DrawValues = anItem.gtDrawValuesY;
1643     anAxisData[2].DrawValues = anItem.gtDrawValuesZ;
1644     anAxisData[0].NbValues = anItem.gtNbValuesX;
1645     anAxisData[1].NbValues = anItem.gtNbValuesY;
1646     anAxisData[2].NbValues = anItem.gtNbValuesZ;
1647     anAxisData[0].Offset = anItem.gtOffsetX;
1648     anAxisData[1].Offset = anItem.gtOffsetY;
1649     anAxisData[2].Offset = anItem.gtOffsetZ;
1650     anAxisData[0].Color = QColor( anItem.gtColorRX,
1651                                   anItem.gtColorGX,
1652                                   anItem.gtColorBX );
1653     anAxisData[1].Color = QColor( anItem.gtColorRY,
1654                                   anItem.gtColorGY,
1655                                   anItem.gtColorBY );
1656     anAxisData[2].Color = QColor( anItem.gtColorRZ,
1657                                   anItem.gtColorGZ,
1658                                   anItem.gtColorBZ );
1659     anAxisData[0].DrawTickmarks = anItem.gtDrawTickmarksX;
1660     anAxisData[1].DrawTickmarks = anItem.gtDrawTickmarksY;
1661     anAxisData[2].DrawTickmarks = anItem.gtDrawTickmarksZ;
1662     anAxisData[0].TickmarkLength = anItem.gtTickmarkLengthX;
1663     anAxisData[1].TickmarkLength = anItem.gtTickmarkLengthY;
1664     anAxisData[2].TickmarkLength = anItem.gtTickmarkLengthZ;
1665
1666     myCubeAxesDlg->SetData( anIsVisible, anAxisData );
1667     myCubeAxesDlg->ApplyData( aView3d );
1668 #endif
1669
1670   } // if ( !baseParamsOnly )
1671
1672   myRestoreFlag = 0;
1673 }
1674
1675 /*!
1676   \brief Set restore flag.
1677 */
1678 void OCCViewer_ViewWindow::setRestoreFlag()
1679 {
1680   myRestoreFlag = 1;
1681 }
1682
1683 /*!
1684   \brief Called when action "show/hide trihedron" is activated.
1685 */
1686 void OCCViewer_ViewWindow::onTrihedronShow()
1687 {
1688   myModel->toggleTrihedron();
1689 }
1690
1691 /*!
1692   \brief Switches "keyboard free" interaction style on/off
1693 */
1694 void OCCViewer_ViewWindow::onSwitchInteractionStyle( bool on )
1695 {
1696   myInteractionStyle = on ? (int)SUIT_ViewModel::KEY_FREE : (int)SUIT_ViewModel::STANDARD;
1697
1698   // update action state if method is called outside
1699   QtxAction* a = dynamic_cast<QtxAction*>( toolMgr()->action( SwitchInteractionStyleId ) );
1700   if ( a->isChecked() != on )
1701     a->setChecked( on );
1702 }
1703
1704 /*!
1705   \brief Toogles advanced zooming style (relatively to the cursor position) on/off
1706 */
1707 void OCCViewer_ViewWindow::onSwitchZoomingStyle( bool on )
1708 {
1709   myViewPort->setAdvancedZoomingEnabled( on );
1710
1711   // update action state if method is called outside
1712   QtxAction* a = dynamic_cast<QtxAction*>( toolMgr()->action( SwitchZoomingStyleId ) );
1713   if ( a->isChecked() != on )
1714     a->setChecked( on );
1715 }
1716
1717 /*!
1718   \brief Get current interaction style
1719   \return interaction style
1720 */
1721 int OCCViewer_ViewWindow::interactionStyle() const
1722 {
1723   return myInteractionStyle;
1724 }
1725
1726 /*!
1727   \brief Set current interaction style
1728   \param theStyle interaction style
1729 */
1730 void OCCViewer_ViewWindow::setInteractionStyle( const int theStyle )
1731 {
1732   onSwitchInteractionStyle( theStyle == (int)SUIT_ViewModel::KEY_FREE );
1733 }
1734
1735 /*!
1736   \brief Get current zooming style
1737   \return zooming style
1738 */
1739 int OCCViewer_ViewWindow::zoomingStyle() const
1740 {
1741   return myViewPort->isAdvancedZoomingEnabled() ? 1 : 0;
1742 }
1743
1744 /*!
1745   \brief Set current zooming style
1746   \param theStyle zooming style
1747 */
1748 void OCCViewer_ViewWindow::setZoomingStyle( const int theStyle )
1749 {
1750   onSwitchZoomingStyle( theStyle == 1 );
1751 }
1752
1753 /*!
1754   \brief Dump view window contents to the pixmap.
1755   \return pixmap containing all scene rendered in the window
1756 */
1757 QImage OCCViewer_ViewWindow::dumpView()
1758 {
1759   Handle(V3d_View) view = myViewPort->getView();
1760   if ( view.IsNull() )
1761     return QImage();
1762   
1763   int aWidth = myViewPort->width();
1764   int aHeight = myViewPort->height();
1765   QApplication::syncX();
1766   view->Redraw(); // In order to reactivate GL context
1767   //view->Update();
1768
1769   OpenGLUtils_FrameBuffer aFrameBuffer;
1770   if( aFrameBuffer.init( aWidth, aHeight ) )
1771   {
1772     QImage anImage( aWidth, aHeight, QImage::Format_RGB32 );
1773    
1774     glPushAttrib( GL_VIEWPORT_BIT );
1775     glViewport( 0, 0, aWidth, aHeight );
1776     aFrameBuffer.bind();
1777
1778     // draw scene
1779     view->Redraw();
1780
1781     aFrameBuffer.unbind();
1782     glPopAttrib();
1783
1784     aFrameBuffer.bind();
1785     glReadPixels( 0, 0, aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() );
1786     aFrameBuffer.unbind();
1787
1788     anImage = anImage.rgbSwapped();
1789     anImage = anImage.mirrored();
1790     return anImage;
1791   }
1792   // if frame buffers are unsupported, use old functionality
1793   //view->Redraw();
1794
1795   unsigned char* data = new unsigned char[ aWidth*aHeight*4 ];
1796
1797   QPoint p = myViewPort->mapFromParent(myViewPort->geometry().topLeft());
1798
1799   glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE,
1800                 data);
1801
1802   QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 );
1803   anImage = anImage.mirrored();
1804   anImage = anImage.rgbSwapped();
1805   return anImage;
1806 }
1807
1808 bool OCCViewer_ViewWindow::dumpViewToFormat( const QImage& img, 
1809                                              const QString& fileName, 
1810                                              const QString& format )
1811 {
1812   if ( format != "PS" && format != "EPS")
1813     return SUIT_ViewWindow::dumpViewToFormat( img, fileName, format );
1814
1815   Handle(Visual3d_View) a3dView = myViewPort->getView()->View();
1816
1817   if (format == "PS")
1818     a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_PostScript);
1819   else if (format == "EPS")
1820     a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_EnhPostScript);
1821
1822   return true;
1823 }
1824
1825
1826 QString OCCViewer_ViewWindow::filter() const
1827 {
1828   return tr( "OCC_IMAGE_FILES" );
1829 }
1830
1831
1832 /*!
1833   \brief Set parameters of the cutting plane
1834   \param on if \c true, cutting plane is enabled
1835   \param x X position of plane point
1836   \param y Y position of plane point
1837   \param z Z position of plane point
1838   \param dx X coordinate of plane normal
1839   \param dy Y coordinate of plane normal
1840   \param dz Z coordinate of plane normal
1841 */
1842 void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x,  const double y,  const double z,
1843                                             const double dx, const double dy, const double dz )
1844 {
1845   Handle(V3d_View) view = myViewPort->getView();
1846   if ( view.IsNull() )
1847     return;
1848
1849   if ( on ) {
1850     Handle(V3d_Viewer) viewer = myViewPort->getViewer();
1851
1852     // try to use already existing plane or create a new one
1853     Handle(V3d_Plane) clipPlane;
1854     view->InitActivePlanes();
1855
1856     // calculate new a,b,c,d values for the plane
1857     gp_Pln pln (gp_Pnt(x, y, z), gp_Dir(dx, dy, dz));
1858     double a, b, c, d;
1859     pln.Coefficients(a, b, c, d);
1860
1861 #if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
1862     if (view->MoreActivePlanes()) {
1863       clipPlane = view->ActivePlane();
1864       clipPlane->SetPlane(a, b, c, d);
1865     }
1866     else
1867       clipPlane = new V3d_Plane (a, b, c, d);
1868 #else
1869     if (view->MoreActivePlanes())
1870       clipPlane = view->ActivePlane();
1871     else
1872       clipPlane = new V3d_Plane (viewer);
1873
1874     clipPlane->SetPlane(a, b, c, d);
1875 #endif
1876
1877     view->SetPlaneOn(clipPlane);
1878   }
1879   else
1880     view->SetPlaneOff();
1881
1882   view->Update();
1883   view->Redraw();
1884 }
1885
1886 void OCCViewer_ViewWindow::setCuttingPlane( bool on, const gp_Pln pln )
1887 {
1888   gp_Dir aDir = pln.Axis().Direction();
1889   gp_Pnt aPnt = pln.Location();
1890   setCuttingPlane(on, aPnt.X(), aPnt.Y(), aPnt.Z(), aDir.X(), aDir.Y(), aDir.Z());
1891 }
1892
1893
1894 /*!
1895   \brief Check if any cutting plane is enabled
1896   \return \c true if at least one cutting plane is enabled
1897 */
1898 bool OCCViewer_ViewWindow::isCuttingPlane()
1899 {
1900   Handle(V3d_View) view = myViewPort->getView();
1901   view->InitActivePlanes();
1902   return (view->MoreActivePlanes());
1903 }
1904
1905 /*!
1906   \brief Get the visual parameters of the view window.
1907   \return visual parameters of view window
1908 */
1909 viewAspect OCCViewer_ViewWindow::getViewParams() const
1910 {
1911   double centerX, centerY, projX, projY, projZ, twist;
1912   double atX, atY, atZ, eyeX, eyeY, eyeZ;
1913   double aScaleX, aScaleY, aScaleZ;
1914
1915   Handle(V3d_View) aView3d = myViewPort->getView();
1916
1917   aView3d->Center( centerX, centerY );
1918   aView3d->Proj( projX, projY, projZ );
1919   aView3d->At( atX, atY, atZ );
1920   aView3d->Eye( eyeX, eyeY, eyeZ );
1921   twist = aView3d->Twist();
1922
1923   aView3d->AxialScale(aScaleX,aScaleY,aScaleZ);
1924
1925   bool isShown = myModel->isTrihedronVisible();
1926   double size = myModel->trihedronSize();
1927
1928   QString aName = QTime::currentTime().toString() + QString::fromLatin1( " h:m:s" );
1929
1930   viewAspect params;
1931   params.scale    = aView3d->Scale();
1932   params.centerX  = centerX;
1933   params.centerY  = centerY;
1934   params.projX    = projX;
1935   params.projY    = projY;
1936   params.projZ    = projZ;
1937   params.twist    = twist;
1938   params.atX      = atX;
1939   params.atY      = atY;
1940   params.atZ      = atZ;
1941   params.eyeX     = eyeX;
1942   params.eyeY     = eyeY;
1943   params.eyeZ     = eyeZ;
1944   params.scaleX   = aScaleX;
1945   params.scaleY   = aScaleY;
1946   params.scaleZ   = aScaleZ;
1947   params.name     = aName;
1948   params.isVisible= isShown;
1949   params.size     = size;
1950
1951 #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version
1952   // graduated trihedron
1953   bool anIsVisible = false;
1954   OCCViewer_AxisWidget::AxisData anAxisData[3];
1955   myCubeAxesDlg->GetData( anIsVisible, anAxisData );
1956
1957   params.gtIsVisible = anIsVisible;
1958   params.gtDrawNameX = anAxisData[0].DrawName;
1959   params.gtDrawNameY = anAxisData[1].DrawName;
1960   params.gtDrawNameZ = anAxisData[2].DrawName;
1961   params.gtNameX = anAxisData[0].Name;
1962   params.gtNameY = anAxisData[1].Name;
1963   params.gtNameZ = anAxisData[2].Name;
1964   params.gtNameColorRX = anAxisData[0].NameColor.red();
1965   params.gtNameColorGX = anAxisData[0].NameColor.green();
1966   params.gtNameColorBX = anAxisData[0].NameColor.blue();
1967   params.gtNameColorRY = anAxisData[1].NameColor.red();
1968   params.gtNameColorGY = anAxisData[1].NameColor.green();
1969   params.gtNameColorBY = anAxisData[1].NameColor.blue();
1970   params.gtNameColorRZ = anAxisData[2].NameColor.red();
1971   params.gtNameColorGZ = anAxisData[2].NameColor.green();
1972   params.gtNameColorBZ = anAxisData[2].NameColor.blue();
1973   params.gtDrawValuesX = anAxisData[0].DrawValues;
1974   params.gtDrawValuesY = anAxisData[1].DrawValues;
1975   params.gtDrawValuesZ = anAxisData[2].DrawValues;
1976   params.gtNbValuesX = anAxisData[0].NbValues;
1977   params.gtNbValuesY = anAxisData[1].NbValues;
1978   params.gtNbValuesZ = anAxisData[2].NbValues;
1979   params.gtOffsetX = anAxisData[0].Offset;
1980   params.gtOffsetY = anAxisData[1].Offset;
1981   params.gtOffsetZ = anAxisData[2].Offset;
1982   params.gtColorRX = anAxisData[0].Color.red();
1983   params.gtColorGX = anAxisData[0].Color.green();
1984   params.gtColorBX = anAxisData[0].Color.blue();
1985   params.gtColorRY = anAxisData[1].Color.red();
1986   params.gtColorGY = anAxisData[1].Color.green();
1987   params.gtColorBY = anAxisData[1].Color.blue();
1988   params.gtColorRZ = anAxisData[2].Color.red();
1989   params.gtColorGZ = anAxisData[2].Color.green();
1990   params.gtColorBZ = anAxisData[2].Color.blue();
1991   params.gtDrawTickmarksX = anAxisData[0].DrawTickmarks;
1992   params.gtDrawTickmarksY = anAxisData[1].DrawTickmarks;
1993   params.gtDrawTickmarksZ = anAxisData[2].DrawTickmarks;
1994   params.gtTickmarkLengthX = anAxisData[0].TickmarkLength;
1995   params.gtTickmarkLengthY = anAxisData[1].TickmarkLength;
1996   params.gtTickmarkLengthZ = anAxisData[2].TickmarkLength;
1997 #endif
1998
1999   return params;
2000 }
2001
2002
2003 /*!
2004   \brief Get visual parameters of this view window.
2005   \return visual parameters of view window
2006 */
2007 QString OCCViewer_ViewWindow::getVisualParameters()
2008 {
2009   viewAspect params = getViewParams();
2010
2011   QStringList data;
2012
2013   data << QString( "scale=%1" )    .arg( params.scale,   0, 'e', 12 );
2014   data << QString( "centerX=%1" )  .arg( params.centerX, 0, 'e', 12 );
2015   data << QString( "centerY=%1" )  .arg( params.centerY, 0, 'e', 12 );
2016   data << QString( "projX=%1" )    .arg( params.projX,   0, 'e', 12 );
2017   data << QString( "projY=%1" )    .arg( params.projY,   0, 'e', 12 );
2018   data << QString( "projZ=%1" )    .arg( params.projZ,   0, 'e', 12 );
2019   data << QString( "twist=%1" )    .arg( params.twist,   0, 'e', 12 );
2020   data << QString( "atX=%1" )      .arg( params.atX,     0, 'e', 12 );
2021   data << QString( "atY=%1" )      .arg( params.atY,     0, 'e', 12 );
2022   data << QString( "atZ=%1" )      .arg( params.atZ,     0, 'e', 12 );
2023   data << QString( "eyeX=%1" )     .arg( params.eyeX,    0, 'e', 12 );
2024   data << QString( "eyeY=%1" )     .arg( params.eyeY,    0, 'e', 12 );
2025   data << QString( "eyeZ=%1" )     .arg( params.eyeZ,    0, 'e', 12 );
2026   data << QString( "scaleX=%1" )   .arg( params.scaleX,  0, 'e', 12 );
2027   data << QString( "scaleY=%1" )   .arg( params.scaleY,  0, 'e', 12 );
2028   data << QString( "scaleZ=%1" )   .arg( params.scaleZ,  0, 'e', 12 );
2029   data << QString( "isVisible=%1" ).arg( params.isVisible );
2030   data << QString( "size=%1" )     .arg( params.size,    0, 'f',  2 );
2031
2032 #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 or newer version
2033   // graduated trihedron
2034   data << QString( "gtIsVisible=%1" )      .arg( params.gtIsVisible );
2035   data << QString( "gtDrawNameX=%1" )      .arg( params.gtDrawNameX );
2036   data << QString( "gtDrawNameY=%1" )      .arg( params.gtDrawNameY );
2037   data << QString( "gtDrawNameZ=%1" )      .arg( params.gtDrawNameZ );
2038   data << QString( "gtNameX=%1" )          .arg( params.gtNameX );
2039   data << QString( "gtNameY=%1" )          .arg( params.gtNameY );
2040   data << QString( "gtNameZ=%1" )          .arg( params.gtNameZ );
2041   data << QString( "gtNameColorRX=%1" )    .arg( params.gtNameColorRX );
2042   data << QString( "gtNameColorGX=%1" )    .arg( params.gtNameColorGX );
2043   data << QString( "gtNameColorBX=%1" )    .arg( params.gtNameColorBX );
2044   data << QString( "gtNameColorRY=%1" )    .arg( params.gtNameColorRY );
2045   data << QString( "gtNameColorGY=%1" )    .arg( params.gtNameColorGY );
2046   data << QString( "gtNameColorBY=%1" )    .arg( params.gtNameColorBY );
2047   data << QString( "gtNameColorRZ=%1" )    .arg( params.gtNameColorRZ );
2048   data << QString( "gtNameColorGZ=%1" )    .arg( params.gtNameColorGZ );
2049   data << QString( "gtNameColorBZ=%1" )    .arg( params.gtNameColorBZ );
2050   data << QString( "gtDrawValuesX=%1" )    .arg( params.gtDrawValuesX );
2051   data << QString( "gtDrawValuesY=%1" )    .arg( params.gtDrawValuesY );
2052   data << QString( "gtDrawValuesZ=%1" )    .arg( params.gtDrawValuesZ );
2053   data << QString( "gtNbValuesX=%1" )      .arg( params.gtNbValuesX );
2054   data << QString( "gtNbValuesY=%1" )      .arg( params.gtNbValuesY );
2055   data << QString( "gtNbValuesZ=%1" )      .arg( params.gtNbValuesZ );
2056   data << QString( "gtOffsetX=%1" )        .arg( params.gtOffsetX );
2057   data << QString( "gtOffsetY=%1" )        .arg( params.gtOffsetY );
2058   data << QString( "gtOffsetZ=%1" )        .arg( params.gtOffsetZ );
2059   data << QString( "gtColorRX=%1" )        .arg( params.gtColorRX );
2060   data << QString( "gtColorGX=%1" )        .arg( params.gtColorGX );
2061   data << QString( "gtColorBX=%1" )        .arg( params.gtColorBX );
2062   data << QString( "gtColorRY=%1" )        .arg( params.gtColorRY );
2063   data << QString( "gtColorGY=%1" )        .arg( params.gtColorGY );
2064   data << QString( "gtColorBY=%1" )        .arg( params.gtColorBY );
2065   data << QString( "gtColorRZ=%1" )        .arg( params.gtColorRZ );
2066   data << QString( "gtColorGZ=%1" )        .arg( params.gtColorGZ );
2067   data << QString( "gtColorBZ=%1" )        .arg( params.gtColorBZ );
2068   data << QString( "gtDrawTickmarksX=%1" ) .arg( params.gtDrawTickmarksX );
2069   data << QString( "gtDrawTickmarksY=%1" ) .arg( params.gtDrawTickmarksY );
2070   data << QString( "gtDrawTickmarksZ=%1" ) .arg( params.gtDrawTickmarksZ );
2071   data << QString( "gtTickmarkLengthX=%1" ).arg( params.gtTickmarkLengthX );
2072   data << QString( "gtTickmarkLengthY=%1" ).arg( params.gtTickmarkLengthY );
2073   data << QString( "gtTickmarkLengthZ=%1" ).arg( params.gtTickmarkLengthZ );
2074 #endif
2075   QString bg = Qtx::backgroundToString( background() ).replace( "=", "$" );
2076   data << QString( "background=%1" ).arg( bg );
2077
2078   return data.join("*");
2079 }
2080
2081 /*!
2082   \brief Restore visual parameters of the view window.
2083   \param parameters visual parameters of view window
2084 */
2085 void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters )
2086 {
2087   viewAspect params;
2088
2089   QStringList data = parameters.split( '*' );
2090   Qtx::BackgroundData bgData;
2091   if ( parameters.contains( '=' )  ) // new format - "scale=1.000e+00*centerX=0.000e+00..."
2092   {
2093     foreach( QString param, data ) {
2094       QString paramName  = param.section( '=', 0, 0 ).trimmed();
2095       QString paramValue = param.section( '=', 1, 1 ).trimmed();
2096       if      ( paramName == "scale" )             params.scale             = paramValue.toDouble();
2097       else if ( paramName == "centerX" )           params.centerX           = paramValue.toDouble();
2098       else if ( paramName == "centerY" )           params.centerY           = paramValue.toDouble();
2099       else if ( paramName == "projX" )             params.projX             = paramValue.toDouble();
2100       else if ( paramName == "projY" )             params.projY             = paramValue.toDouble();
2101       else if ( paramName == "projZ" )             params.projZ             = paramValue.toDouble();
2102       else if ( paramName == "twist" )             params.twist             = paramValue.toDouble();
2103       else if ( paramName == "atX" )               params.atX               = paramValue.toDouble();
2104       else if ( paramName == "atY" )               params.atY               = paramValue.toDouble();
2105       else if ( paramName == "atZ" )               params.atZ               = paramValue.toDouble();
2106       else if ( paramName == "eyeX" )              params.eyeX              = paramValue.toDouble();
2107       else if ( paramName == "eyeY" )              params.eyeY              = paramValue.toDouble();
2108       else if ( paramName == "eyeZ" )              params.eyeZ              = paramValue.toDouble();
2109       else if ( paramName == "scaleX" )            params.scaleX            = paramValue.toDouble();
2110       else if ( paramName == "scaleY" )            params.scaleY            = paramValue.toDouble();
2111       else if ( paramName == "scaleZ" )            params.scaleZ            = paramValue.toDouble();
2112       else if ( paramName == "isVisible" )         params.isVisible         = paramValue.toInt();
2113       else if ( paramName == "size" )              params.size              = paramValue.toDouble();
2114       // graduated trihedron
2115       else if ( paramName == "gtIsVisible" )       params.gtIsVisible       = paramValue.toInt();
2116       else if ( paramName == "gtDrawNameX" )       params.gtDrawNameX       = paramValue.toInt();
2117       else if ( paramName == "gtDrawNameY" )       params.gtDrawNameY       = paramValue.toInt();
2118       else if ( paramName == "gtDrawNameZ" )       params.gtDrawNameZ       = paramValue.toInt();
2119       else if ( paramName == "gtNameX" )           params.gtNameX           = paramValue;
2120       else if ( paramName == "gtNameY" )           params.gtNameY           = paramValue;
2121       else if ( paramName == "gtNameZ" )           params.gtNameZ           = paramValue;
2122       else if ( paramName == "gtNameColorRX" )     params.gtNameColorRX     = paramValue.toInt();
2123       else if ( paramName == "gtNameColorGX" )     params.gtNameColorGX     = paramValue.toInt();
2124       else if ( paramName == "gtNameColorBX" )     params.gtNameColorBX     = paramValue.toInt();
2125       else if ( paramName == "gtNameColorRY" )     params.gtNameColorRY     = paramValue.toInt();
2126       else if ( paramName == "gtNameColorGY" )     params.gtNameColorGY     = paramValue.toInt();
2127       else if ( paramName == "gtNameColorBY" )     params.gtNameColorBY     = paramValue.toInt();
2128       else if ( paramName == "gtNameColorRZ" )     params.gtNameColorRZ     = paramValue.toInt();
2129       else if ( paramName == "gtNameColorGZ" )     params.gtNameColorGZ     = paramValue.toInt();
2130       else if ( paramName == "gtNameColorBZ" )     params.gtNameColorBZ     = paramValue.toInt();
2131       else if ( paramName == "gtDrawValuesX" )     params.gtDrawValuesX     = paramValue.toInt();
2132       else if ( paramName == "gtDrawValuesY" )     params.gtDrawValuesY     = paramValue.toInt();
2133       else if ( paramName == "gtDrawValuesZ" )     params.gtDrawValuesZ     = paramValue.toInt();
2134       else if ( paramName == "gtNbValuesX" )       params.gtNbValuesX       = paramValue.toInt();
2135       else if ( paramName == "gtNbValuesY" )       params.gtNbValuesY       = paramValue.toInt();
2136       else if ( paramName == "gtNbValuesZ" )       params.gtNbValuesZ       = paramValue.toInt();
2137       else if ( paramName == "gtOffsetX" )         params.gtOffsetX         = paramValue.toInt();
2138       else if ( paramName == "gtOffsetY" )         params.gtOffsetY         = paramValue.toInt();
2139       else if ( paramName == "gtOffsetZ" )         params.gtOffsetZ         = paramValue.toInt();
2140       else if ( paramName == "gtColorRX" )         params.gtColorRX         = paramValue.toInt();
2141       else if ( paramName == "gtColorGX" )         params.gtColorGX         = paramValue.toInt();
2142       else if ( paramName == "gtColorBX" )         params.gtColorBX         = paramValue.toInt();
2143       else if ( paramName == "gtColorRY" )         params.gtColorRY         = paramValue.toInt();
2144       else if ( paramName == "gtColorGY" )         params.gtColorGY         = paramValue.toInt();
2145       else if ( paramName == "gtColorBY" )         params.gtColorBY         = paramValue.toInt();
2146       else if ( paramName == "gtColorRZ" )         params.gtColorRZ         = paramValue.toInt();
2147       else if ( paramName == "gtColorGZ" )         params.gtColorGZ         = paramValue.toInt();
2148       else if ( paramName == "gtColorBZ" )         params.gtColorBZ         = paramValue.toInt();
2149       else if ( paramName == "gtDrawTickmarksX" )  params.gtDrawTickmarksX  = paramValue.toInt();
2150       else if ( paramName == "gtDrawTickmarksY" )  params.gtDrawTickmarksY  = paramValue.toInt();
2151       else if ( paramName == "gtDrawTickmarksZ" )  params.gtDrawTickmarksZ  = paramValue.toInt();
2152       else if ( paramName == "gtTickmarkLengthX" ) params.gtTickmarkLengthX = paramValue.toInt();
2153       else if ( paramName == "gtTickmarkLengthY" ) params.gtTickmarkLengthY = paramValue.toInt();
2154       else if ( paramName == "gtTickmarkLengthZ" ) params.gtTickmarkLengthZ = paramValue.toInt();
2155       else if ( paramName == "background" )        {
2156         QString bg = paramValue.replace( "$", "=" );
2157         bgData = Qtx::stringToBackground( bg );
2158       }
2159     }
2160   }
2161   else // old format - "1.000e+00*0.000e+00..."
2162   {
2163     int idx = 0;
2164     params.scale     = data.count() > idx ? data[idx++].toDouble() : 1.0;
2165     params.centerX   = data.count() > idx ? data[idx++].toDouble() : 0.0;
2166     params.centerY   = data.count() > idx ? data[idx++].toDouble() : 0.0;
2167     params.projX     = data.count() > idx ? data[idx++].toDouble() : sqrt(1./3);
2168     params.projY     = data.count() > idx ? data[idx++].toDouble() : -sqrt(1./3);
2169     params.projZ     = data.count() > idx ? data[idx++].toDouble() : sqrt(1./3);
2170     params.twist     = data.count() > idx ? data[idx++].toDouble() : 0.0;
2171     params.atX       = data.count() > idx ? data[idx++].toDouble() : 0.0;
2172     params.atY       = data.count() > idx ? data[idx++].toDouble() : 0.0;
2173     params.atZ       = data.count() > idx ? data[idx++].toDouble() : 0.0;
2174     params.eyeX      = data.count() > idx ? data[idx++].toDouble() : sqrt(250000./3);
2175     params.eyeY      = data.count() > idx ? data[idx++].toDouble() : -sqrt(250000./3);
2176     params.eyeZ      = data.count() > idx ? data[idx++].toDouble() : sqrt(250000./3);
2177     params.scaleX    = data.count() > idx ? data[idx++].toDouble() : 1.0;
2178     params.scaleY    = data.count() > idx ? data[idx++].toDouble() : 1.0;
2179     params.scaleZ    = data.count() > idx ? data[idx++].toDouble() : 1.0;
2180     params.isVisible = data.count() > idx ? data[idx++].toInt()    : 1;
2181     params.size      = data.count() > idx ? data[idx++].toDouble() : 100.0;
2182   }
2183   performRestoring( params );
2184   setBackground( bgData );
2185 }
2186
2187 /*!
2188   \brief Handle show event.
2189
2190   Emits Show() signal.
2191
2192   \param theEvent show event
2193 */
2194 void OCCViewer_ViewWindow::showEvent( QShowEvent* theEvent )
2195 {
2196   emit Show( theEvent );
2197 }
2198
2199 /*!
2200   \brief Handle hide event.
2201
2202   Emits Hide() signal.
2203
2204   \param theEvent hide event
2205 */
2206 void OCCViewer_ViewWindow::hideEvent( QHideEvent* theEvent )
2207 {
2208   emit Hide( theEvent );
2209 }
2210
2211
2212 /*!
2213     Creates default sketcher. [ virtual protected ]
2214 */
2215 OCCViewer_ViewSketcher* OCCViewer_ViewWindow::createSketcher( int type )
2216 {
2217   if ( type == Rect )
2218     return new OCCViewer_RectSketcher( this, type );
2219   if ( type == Polygon )
2220     return new OCCViewer_PolygonSketcher( this, type );
2221   return 0;
2222 }
2223
2224 void OCCViewer_ViewWindow::initSketchers()
2225 {
2226   if ( mySketchers.isEmpty() )
2227   {
2228     mySketchers.append( createSketcher( Rect ) );
2229     mySketchers.append( createSketcher( Polygon ) );
2230   }
2231 }
2232
2233 OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ )
2234 {
2235   OCCViewer_ViewSketcher* sketcher = 0;
2236   QList<OCCViewer_ViewSketcher*>::Iterator it;
2237   for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it )
2238   {
2239     OCCViewer_ViewSketcher* sk = (*it);
2240     if ( sk->type() == typ )
2241       sketcher = sk;
2242   }
2243   return sketcher;
2244 }
2245
2246 /*!
2247     Handles requests for sketching in the active view. [ virtual public ]
2248 */
2249 void OCCViewer_ViewWindow::activateSketching( int type )
2250 {
2251   OCCViewer_ViewPort3d* vp = getViewPort();
2252   if ( !vp )
2253     return;
2254
2255   if ( !vp->isSketchingEnabled() )
2256     return;
2257
2258   /* Finish current sketching */
2259   if ( type == NoSketching )
2260   {
2261     if ( mypSketcher )
2262     {
2263       onSketchingFinished();
2264       mypSketcher->deactivate();
2265       mypSketcher = 0;
2266     }
2267   }
2268   /* Activate new sketching */
2269   else
2270   {
2271     activateSketching( NoSketching );  /* concurrency not suported */
2272     mypSketcher = getSketcher( type );
2273     if ( mypSketcher )
2274     {
2275       mypSketcher->activate();
2276       onSketchingStarted();
2277     }
2278   }
2279 }
2280
2281 /*!
2282     Unhilights detected entities. [ virtual protected ]
2283 */
2284 void OCCViewer_ViewWindow::onSketchingStarted()
2285 {
2286 }
2287
2288 /*!
2289     Selection by rectangle or polygon. [ virtual protected ]
2290 */
2291 void OCCViewer_ViewWindow::onSketchingFinished()
2292 {
2293   MESSAGE("OCCViewer_ViewWindow::onSketchingFinished()")
2294   if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept )
2295   {
2296     Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
2297     bool append = bool( mypSketcher->buttonState() & Qt::ShiftModifier );
2298     switch( mypSketcher->type() )
2299     {
2300     case Rect:
2301       {
2302         QRect* aRect = (QRect*)mypSketcher->data();
2303         if( aRect )
2304         {
2305           int aLeft = aRect->left();
2306           int aRight = aRect->right();
2307           int aTop = aRect->top();
2308           int aBottom = aRect->bottom();
2309 //           myRect = aRect;
2310
2311           if( append )
2312             ic->ShiftSelect( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False );
2313           else
2314             ic->Select( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False );
2315         }
2316       }
2317       break;
2318     case Polygon:
2319       {
2320         QPolygon* aPolygon = (QPolygon*)mypSketcher->data();
2321         if( aPolygon )
2322         {
2323           int size = aPolygon->size();
2324           TColgp_Array1OfPnt2d anArray( 1, size );
2325
2326           QPolygon::Iterator it = aPolygon->begin();
2327           QPolygon::Iterator itEnd = aPolygon->end();
2328           for( int index = 1; it != itEnd; ++it, index++ )
2329           {
2330             QPoint aPoint = *it;
2331             anArray.SetValue( index, gp_Pnt2d( aPoint.x(), aPoint.y() ) );
2332           }
2333
2334           if( append )
2335             ic->ShiftSelect( anArray, getViewPort()->getView(), Standard_False );
2336           else
2337             ic->Select( anArray, getViewPort()->getView(), Standard_False );
2338         }
2339       }
2340       break;
2341     default:
2342       break;
2343     }
2344
2345     OCCViewer_ViewManager* aViewMgr = ( OCCViewer_ViewManager* )getViewManager();
2346     aViewMgr->getOCCViewer()->performSelectionChanged();
2347   }
2348 }
2349
2350 OCCViewer_ViewPort3d* OCCViewer_ViewWindow::getViewPort()
2351 {
2352   return myViewPort;
2353 }
2354
2355 bool OCCViewer_ViewWindow::transformRequested() const
2356 {
2357   return ( myOperation != NOTHING );
2358 }
2359
2360 bool OCCViewer_ViewWindow::transformInProcess() const
2361 {
2362   return myEventStarted;
2363 }
2364
2365 void OCCViewer_ViewWindow::setTransformInProcess( bool bOn )
2366 {
2367   myEventStarted = bOn;
2368 }
2369
2370 /*!
2371   Set enabled state of transformation (rotate, zoom, etc)
2372 */
2373 void OCCViewer_ViewWindow::setTransformEnabled( const OperationType id, const bool on )
2374 {
2375   if ( id != NOTHING ) myStatus.insert( id, on );
2376 }
2377
2378 /*!
2379   \return enabled state of transformation (rotate, zoom, etc)
2380 */
2381 bool OCCViewer_ViewWindow::transformEnabled( const OperationType id ) const
2382 {
2383   return myStatus.contains( id ) ? myStatus[ id ] : true;
2384 }
2385
2386 void OCCViewer_ViewWindow::onMaximizedView()
2387 {
2388   setMaximized(!isMaximized());
2389 }
2390
2391
2392 void OCCViewer_ViewWindow::setMaximized(bool toMaximize, bool toSendSignal)
2393 {
2394   QAction* anAction =  toolMgr()->action( MaximizedId );
2395   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
2396   if ( toMaximize ) {
2397     anAction->setText( tr( "MNU_MINIMIZE_VIEW" ) );  
2398     anAction->setToolTip( tr( "MNU_MINIMIZE_VIEW" ) );  
2399     anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ) );
2400     anAction->setStatusTip( tr( "DSC_MINIMIZE_VIEW" ) );
2401     if (toSendSignal) {
2402       emit maximized( this, true );
2403     }
2404   }
2405   else {
2406     anAction->setText( tr( "MNU_MAXIMIZE_VIEW" ) );  
2407     anAction->setToolTip( tr( "MNU_MAXIMIZE_VIEW" ) );  
2408     anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MAXIMIZE" ) ) );
2409     anAction->setStatusTip( tr( "DSC_MAXIMIZE_VIEW" ) );
2410     if (toSendSignal) {
2411       emit maximized( this, false );
2412     }
2413   }
2414 }
2415
2416
2417 bool OCCViewer_ViewWindow::isMaximized() const
2418 {
2419   return !(toolMgr()->action( MaximizedId )->text() == tr( "MNU_MAXIMIZE_VIEW" ));
2420 }
2421
2422 void OCCViewer_ViewWindow::setSketcherStyle( bool enable )
2423
2424   IsSketcherStyle = enable; 
2425 }
2426
2427 bool OCCViewer_ViewWindow::isSketcherStyle() const 
2428
2429   return IsSketcherStyle; 
2430 }
2431
2432
2433 void OCCViewer_ViewWindow::set2dMode(Mode2dType theType)
2434 {
2435   my2dMode = theType;
2436 }
2437
2438 // obsolete   
2439 QColor OCCViewer_ViewWindow::backgroundColor() const
2440 {
2441   return myViewPort ? myViewPort->backgroundColor() : Qt::black;
2442 }
2443    
2444 // obsolete
2445 void OCCViewer_ViewWindow::setBackgroundColor( const QColor& theColor )
2446 {
2447   if ( myViewPort ) myViewPort->setBackgroundColor( theColor );
2448 }
2449
2450 Qtx::BackgroundData OCCViewer_ViewWindow::background() const
2451 {
2452   return myViewPort ? myViewPort->background() : Qtx::BackgroundData();
2453 }
2454    
2455 void OCCViewer_ViewWindow::setBackground( const Qtx::BackgroundData& theBackground )
2456 {
2457   if ( myViewPort ) myViewPort->setBackground( theBackground );
2458 }
2459
2460 /*!
2461   Clears view aspects
2462 */
2463 void OCCViewer_ViewWindow::clearViewAspects()
2464 {
2465   myViewAspects.clear();
2466 }
2467
2468 /*!
2469   \return const reference to list of view aspects
2470 */
2471 const viewAspectList& OCCViewer_ViewWindow::getViewAspects()
2472 {
2473   return myViewAspects;
2474 }
2475
2476 /*!
2477   Appends new view aspect
2478   \param aParams - new view aspects
2479 */
2480 void OCCViewer_ViewWindow::appendViewAspect( const viewAspect& aParams )
2481 {
2482   myViewAspects.append( aParams );
2483 }
2484
2485 /*!
2486   Replaces old view aspects by new ones
2487   \param aViewList - list of new view aspects
2488 */
2489 void OCCViewer_ViewWindow::updateViewAspects( const viewAspectList& aViewList )
2490 {
2491   myViewAspects = aViewList;
2492 }
2493
2494 /*!
2495   Get camera properties for the OCC view window.
2496   \return shared pointer on camera properties.
2497 */
2498 SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties()
2499 {
2500   SUIT_CameraProperties aProps;
2501
2502   Handle(V3d_View) aSourceView = getViewPort()->getView();
2503   if ( aSourceView.IsNull() )
2504     return aProps;
2505
2506   if ( get2dMode() == No2dMode ) {
2507     aProps.setDimension( SUIT_CameraProperties::Dim3D );
2508   }
2509   else {
2510     aProps.setDimension( SUIT_CameraProperties::Dim2D );
2511     aProps.setViewSide( (SUIT_CameraProperties::ViewSide)(int)get2dMode() );
2512   }
2513   
2514   // read common properites of the view
2515   Standard_Real anUpDir[3];
2516   Standard_Real aPrjDir[3];
2517   Standard_Real aMapScale[2];
2518   Standard_Real aTranslation[3];
2519   Standard_Real anAxialScale[3];
2520   
2521   aSourceView->Up(anUpDir[0], anUpDir[1], anUpDir[2]);
2522   aSourceView->Proj(aPrjDir[0], aPrjDir[1], aPrjDir[2]);
2523   aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]);
2524   aSourceView->Size(aMapScale[0], aMapScale[1]);
2525
2526   getViewPort()->getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
2527
2528   // we use similar depth to the one used in perspective projection 
2529   // to proivde a convinience synchronization with other camera views that
2530   // can switch between orthogonal & perspective projection. otherwise,
2531   // the camera will get to close when switching from orthogonal to perspective.
2532   Standard_Real aCameraDepth = aSourceView->Depth() + aSourceView->ZSize() * 0.5;
2533
2534   // store common props
2535   aProps.setViewUp(anUpDir[0], anUpDir[1], anUpDir[2]);
2536   aProps.setMappingScale(aMapScale[1] / 2.0);
2537   aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
2538   
2539   // generate view orientation matrix for transforming OCC projection reference point
2540   // into a camera (eye) position.
2541   gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed(
2542     gp_Dir(aPrjDir[0], aPrjDir[1], aPrjDir[2]));
2543
2544   gp_Trsf aTrsf;
2545   aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aPrjDir[0], aTranslation[0],
2546                    aLeftDir.Y(), anUpDir[1], aPrjDir[1], aTranslation[1],
2547                    aLeftDir.Z(), anUpDir[2], aPrjDir[2], aTranslation[2],
2548                    Precision::Confusion(),
2549                    Precision::Confusion() );
2550
2551   // get projection reference point in view coordinates
2552   Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint();
2553   
2554   // transform to world-space coordinate system
2555   gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aCameraDepth).Transformed(aTrsf);
2556   
2557   // compute focal point
2558   double aFocalPoint[3];
2559
2560   aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aCameraDepth;
2561   aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aCameraDepth;
2562   aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aCameraDepth;
2563
2564   aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
2565   aProps.setPosition(aPosition.X(), aPosition.Y(), aPosition.Z());
2566
2567   return aProps;
2568 }
2569
2570 /*!
2571   Synchronize views.
2572   This implementation synchronizes OCC view's camera propreties.
2573 */
2574 void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView )
2575 {
2576   bool blocked = blockSignals( true );
2577
2578   SUIT_CameraProperties aProps = theView->cameraProperties();
2579   if ( !cameraProperties().isCompatible( aProps ) ) {
2580     // other view, this one is being currently synchronized to, seems has become incompatible
2581     // we have to break synchronization
2582     updateSyncViews();
2583     return;
2584   }
2585
2586   Handle(V3d_View) aDestView = getViewPort()->getView();
2587
2588   aDestView->SetImmediateUpdate( Standard_False );
2589
2590   double anUpDir[3];
2591   double aPosition[3];
2592   double aFocalPoint[3];
2593   double aMapScaling;
2594   double anAxialScale[3];
2595
2596   // get common properties
2597   aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]);
2598   aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]);
2599   aProps.getViewUp(anUpDir[0], anUpDir[1], anUpDir[2]);
2600   aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
2601   aMapScaling = aProps.getMappingScale() * 2.0;
2602
2603   gp_Dir aProjDir(aPosition[0] - aFocalPoint[0],
2604                   aPosition[1] - aFocalPoint[1],
2605                   aPosition[2] - aFocalPoint[2]);
2606   
2607   // get custom view translation
2608   Standard_Real aTranslation[3];
2609   aDestView->At(aTranslation[0], aTranslation[1], aTranslation[2]);
2610
2611   gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed(
2612     gp_Dir(aProjDir.X(), aProjDir.Y(), aProjDir.Z()));
2613
2614   // convert camera position into a view reference point
2615   gp_Trsf aTrsf;
2616   aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aProjDir.X(), aTranslation[0],
2617                    aLeftDir.Y(), anUpDir[1], aProjDir.Y(), aTranslation[1],
2618                    aLeftDir.Z(), anUpDir[2], aProjDir.Z(), aTranslation[2], 
2619                    Precision::Confusion(),
2620                    Precision::Confusion() );
2621   aTrsf.Invert();
2622
2623   // transform to view-space coordinate system
2624   gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]);
2625   aProjRef.Transform(aTrsf);
2626
2627   // set view camera properties using low-level approach. this is done
2628   // in order to avoid interference with static variables in v3d view used
2629   // when rotation is in process in another view.
2630   Visual3d_ViewMapping aMapping = aDestView->View()->ViewMapping();
2631   Visual3d_ViewOrientation anOrientation = aDestView->View()->ViewOrientation();
2632
2633   Graphic3d_Vector aMappingProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z());
2634   Graphic3d_Vector aMappingUp(anUpDir[0], anUpDir[1], anUpDir[2]);
2635
2636   aMappingProj.Normalize();
2637   aMappingUp.Normalize();
2638
2639   anOrientation.SetViewReferencePlane(aMappingProj);
2640   anOrientation.SetViewReferenceUp(aMappingUp);
2641
2642   aDestView->SetViewMapping(aMapping);
2643   aDestView->SetViewOrientation(anOrientation);
2644
2645   // set panning
2646   aDestView->SetCenter(aProjRef.X(), aProjRef.Y());
2647
2648   // set mapping scale
2649   Standard_Real aWidth, aHeight;
2650   aDestView->Size(aWidth, aHeight);
2651   
2652   if ( aWidth > aHeight )
2653     aDestView->SetSize (aMapScaling * (aWidth / aHeight));
2654   else
2655     aDestView->SetSize (aMapScaling);
2656
2657   getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]);
2658
2659   aDestView->ZFitAll();
2660   aDestView->SetImmediateUpdate( Standard_True );
2661   aDestView->Redraw();
2662
2663   blockSignals( blocked );
2664 }