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