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