Salome HOME
Issue 0022171:
[modules/gui.git] / src / OCCViewer / OCCViewer_ClippingDlg.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "OCCViewer_ClippingDlg.h"
24
25 #include <QtxDoubleSpinBox.h>
26 #include <QtxAction.h>
27
28 #include "SUIT_Session.h"
29 #include "SUIT_ViewWindow.h"
30 #include "SUIT_ViewManager.h"
31 #include "OCCViewer_ViewWindow.h"
32 #include "OCCViewer_ViewPort3d.h"
33 #include "OCCViewer_ViewModel.h"
34
35 #include <V3d_View.hxx>
36 #include <Visual3d_View.hxx>
37 #include <Geom_Plane.hxx>
38 #include <Prs3d_Presentation.hxx>
39 #include <AIS_ListIteratorOfListOfInteractive.hxx>
40 #include <AIS_ListOfInteractive.hxx>
41 #include <AIS_InteractiveObject.hxx>
42 #include <AIS_InteractiveContext.hxx>
43 #include <IntAna_IntConicQuad.hxx>
44 #include <gp_Lin.hxx>
45 #include <gp_Pln.hxx>
46 #include <math.h>
47
48 // QT Includes
49 #include <QApplication>
50 #include <QGroupBox>
51 #include <QHBoxLayout>
52 #include <QVBoxLayout>
53 #include <QGridLayout>
54 #include <QLabel>
55 #include <QPushButton>
56 #include <QComboBox>
57 #include <QCheckBox>
58 #include <QStackedLayout>
59 #include <QSlider>
60 #include <QMenu>
61
62 /*!
63   Constructor of class ClipPlane
64  */
65 ClipPlane::ClipPlane():
66   RelativeMode(),
67   X(0.0), Y(0.0), Z(0.0),
68   Dx(1.0), Dy(1.0), Dz(1.0),
69   Orientation(0),
70   IsActive( true ),
71   IsInvert( false ),
72   PlaneMode( Absolute )
73 {
74 }
75
76 /*!
77   Constructor of class OrientedPlane
78  */
79 OrientedPlane::OrientedPlane():
80   Orientation(0),
81   Distance(0.5),
82   Rotation1(0),
83   Rotation2(0)
84 {
85 }
86
87 /**********************************************************************************
88  ************************        Internal functions        ************************
89  *********************************************************************************/
90
91 /*!
92   Compute the point of bounding box and current clipping plane
93  */
94 void ComputeBoundsParam( double theBounds[6],
95                          double theDirection[3],
96                          double theMinPnt[3],
97                          double& theMaxBoundPrj,
98                          double& theMinBoundPrj )
99 {
100   //Enlarge bounds in order to avoid conflicts of precision
101   for(int i = 0; i < 6; i += 2) {
102     static double EPS = 1.0E-3;
103     double aDelta = (theBounds[i+1] - theBounds[i])*EPS;
104     theBounds[i] -= aDelta;
105     theBounds[i+1] += aDelta;
106   }
107
108   double aBoundPoints[8][3] = { { theBounds[0], theBounds[2], theBounds[4] },
109                                 { theBounds[1], theBounds[2], theBounds[4] },
110                                 { theBounds[0], theBounds[3], theBounds[4] },
111                                 { theBounds[1], theBounds[3], theBounds[4] },
112                                 { theBounds[0], theBounds[2], theBounds[5] },
113                                 { theBounds[1], theBounds[2], theBounds[5] },
114                                 { theBounds[0], theBounds[3], theBounds[5] },
115                                 { theBounds[1], theBounds[3], theBounds[5] } };
116
117   int aMaxId = 0;
118   theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1]
119                    + theDirection[2] * aBoundPoints[aMaxId][2];
120   theMinBoundPrj = theMaxBoundPrj;
121   for(int i = 1; i < 8; i++) {
122     double aTmp = theDirection[0] * aBoundPoints[i][0] + theDirection[1] * aBoundPoints[i][1]
123                   + theDirection[2] * aBoundPoints[i][2];
124     if(theMaxBoundPrj < aTmp) {
125       theMaxBoundPrj = aTmp;
126       aMaxId = i;
127     }
128     if(theMinBoundPrj > aTmp) {
129       theMinBoundPrj = aTmp;
130     }
131   }
132   double *aMinPnt = aBoundPoints[aMaxId];
133   theMinPnt[0] = aMinPnt[0];
134   theMinPnt[1] = aMinPnt[1];
135   theMinPnt[2] = aMinPnt[2];
136 }
137
138 /*!
139   Compute the position of current plane by distance
140  */
141 void DistanceToPosition( double theBounds[6],
142                          double theDirection[3],
143                          double theDist,
144                          double thePos[3] )
145 {
146   double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
147   ComputeBoundsParam( theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj );
148   double aLength = (aMaxBoundPrj - aMinBoundPrj)*theDist;
149   thePos[0] = aMinPnt[0] - theDirection[0]*aLength;
150   thePos[1] = aMinPnt[1] - theDirection[1]*aLength;
151   thePos[2] = aMinPnt[2] - theDirection[2]*aLength;
152 }
153
154 /*!
155   Compute the parameters of clipping plane
156  */
157 bool ComputeClippingPlaneParameters( double theNormal[3],
158                                      double theDist,
159                                      double theBounds[6],
160                                      double theOrigin[3],
161                                      Handle(V3d_View) theView3d )
162 {
163   bool anIsOk = false;
164   theBounds[0] = theBounds[2] = theBounds[4] = 999.99;
165   theBounds[1] = theBounds[3] = theBounds[5] = -999.99;
166   double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
167
168   theView3d->View()->MinMaxValues( aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5]);
169   if ( !theView3d->View()->ContainsFacet() ) {
170     aBounds[0] = aBounds[2] = aBounds[4] = 0.0;
171     aBounds[1] = aBounds[3] = aBounds[5] = 100.0;
172   }
173   anIsOk = true;
174
175   if( !anIsOk )
176     return false;
177
178   DistanceToPosition( aBounds, theNormal, theDist, theOrigin );
179   return true;
180 }
181
182 /*!
183   Cross product of two 3-vectors. Result vector in result[3].
184  */
185 void Cross(const double first[3], const double second[3], double result[3])
186 {
187   result[0] = first[1]*second[2] - first[2]*second[1];
188   result[1] = first[2]*second[0] - first[0]*second[2];
189   result[2] = first[0]*second[1] - first[1]*second[0];
190 }
191
192 /*!
193   Compute relative clipping plane in absolute coordinates
194  */
195 void RelativePlaneToAbsolute ( ClipPlane* thePlane, Handle(V3d_View) theView3d )
196 {
197   double aNormal[3];
198   double aDir[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } };
199   {
200     static double aCoeff = M_PI/180.0;
201
202     double anU[2] = { cos( aCoeff * thePlane->RelativeMode.Rotation1 ), cos( aCoeff * thePlane->RelativeMode.Rotation2 ) };
203     double aV[2] = { sqrt( 1.0 - anU[0]*anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) };
204     aV[0] = thePlane->RelativeMode.Rotation1 > 0? aV[0]: -aV[0];
205     aV[1] = thePlane->RelativeMode.Rotation2 > 0? aV[1]: -aV[1];
206
207     switch ( thePlane->RelativeMode.Orientation ) {
208     case 0:
209       aDir[0][1] = anU[0];
210       aDir[0][2] = aV[0];
211       aDir[1][0] = anU[1];
212       aDir[1][2] = aV[1];
213       break;
214     case 1:
215       aDir[0][2] = anU[0];
216       aDir[0][0] = aV[0];
217       aDir[1][1] = anU[1];
218       aDir[1][0] = aV[1];
219       break;
220     case 2:
221       aDir[0][0] = anU[0];
222       aDir[0][1] = aV[0];
223       aDir[1][2] = anU[1];
224       aDir[1][1] = aV[1];
225       break;
226     }
227
228     Cross( aDir[1], aDir[0], aNormal );
229     // Normalize
230     double den;
231     den = sqrt( aNormal[0] * aNormal[0] + aNormal[1] * aNormal[1] + aNormal[2] * aNormal[2] );
232     if ( den != 0.0 ) {
233       for (int i=0; i < 3; i++) {
234         aNormal[i] /= den;
235       }
236     }
237     Cross( aNormal, aDir[1], aDir[0] );
238   }
239
240   double aBounds[6];
241   double anOrigin[3];
242
243   bool anIsOk = false;
244
245   anOrigin[0] = anOrigin[1] = anOrigin[2] = 0;
246   aBounds[0] = aBounds[2] = aBounds[4] = 0;
247   aBounds[1] = aBounds[3] = aBounds[5] = 0;
248   anIsOk = true;
249
250   anIsOk = ComputeClippingPlaneParameters( aNormal,
251                                            thePlane->RelativeMode.Distance,
252                                            aBounds,
253                                            anOrigin,
254                                            theView3d );
255   if( !anIsOk )
256           return;
257
258   thePlane->Dx = aNormal[0];
259   thePlane->Dy = aNormal[1];
260   thePlane->Dz = aNormal[2];
261   thePlane->X = anOrigin[0];
262   thePlane->Y = anOrigin[1];
263   thePlane->Z = anOrigin[2];
264 }
265
266 /*********************************************************************************
267  *********************      class OCCViewer_ClippingDlg      *********************
268  *********************************************************************************/
269 /*!
270   Constructor
271   \param view - view window
272   \param parent - parent widget
273   \param name - dialog name
274   \param modal - is this dialog modal
275   \param fl - flags
276 */
277 OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const char* name, bool modal, Qt::WindowFlags fl )
278 : QDialog( view, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
279   myView( view )
280 {
281   setObjectName( "OCCViewer_ClippingDlg" );
282   setModal( modal );
283
284   setWindowTitle( tr( "Clipping" ) );
285   
286   QVBoxLayout* topLayout = new QVBoxLayout( this );
287   topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
288
289   /***************************************************************/
290   // Controls for selecting, creating, deleting planes
291   QGroupBox* GroupPlanes = new QGroupBox( tr("CLIPPING_PLANES"), this );
292   QHBoxLayout* GroupPlanesLayout = new QHBoxLayout( GroupPlanes );
293   ComboBoxPlanes = new QComboBox( GroupPlanes );
294   isActivePlane = new QCheckBox( tr("IS_ACTIVE_PLANE"), this );
295   buttonNew = new QPushButton( tr("BTN_NEW"), GroupPlanes );
296   buttonDelete = new QPushButton( tr("BTN_DELETE"), GroupPlanes );
297   buttonDisableAll = new QPushButton( tr("BTN_DISABLE_ALL"), GroupPlanes );
298   MenuMode = new QMenu( "MenuMode", buttonNew );
299   MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );
300   MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );
301   buttonNew->setMenu( MenuMode );
302   CurrentMode = Absolute;
303
304   GroupPlanesLayout->addWidget( ComboBoxPlanes );
305   GroupPlanesLayout->addWidget( isActivePlane );
306   GroupPlanesLayout->addWidget( buttonNew );
307   GroupPlanesLayout->addWidget( buttonDelete );
308   GroupPlanesLayout->addWidget( buttonDisableAll );
309
310   ModeStackedLayout = new QStackedLayout();
311
312   /**********************   Mode Absolute   **********************/
313   /* Controls for absolute mode of clipping plane:
314      X, Y, Z - coordinates of the intersection of cutting plane and the three axes
315      Dx, Dy, Dz - components of normal to the cutting plane
316      Orientation - direction of cutting plane
317    */
318   const double min = -1e+7;
319   const double max =  1e+7;
320   const double step = 5;
321   const int precision = -7;
322
323   // Croup Point
324   QGroupBox* GroupAbsolutePoint = new QGroupBox( this );
325   GroupAbsolutePoint->setObjectName( "GroupPoint" );
326   GroupAbsolutePoint->setTitle( tr("BASE_POINT") );
327   QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint );
328   GroupPointLayout->setAlignment( Qt::AlignTop );
329   GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 );
330
331   TextLabelX = new QLabel( GroupAbsolutePoint );
332   TextLabelX->setObjectName( "TextLabelX" );
333   TextLabelX->setText( tr("X:") );
334   GroupPointLayout->addWidget( TextLabelX, 0, 0 );
335   
336   SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
337   SpinBox_X->setObjectName("SpinBox_X" );
338   SpinBox_X->setPrecision( precision );
339   GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
340
341   TextLabelY = new QLabel( GroupAbsolutePoint );
342   TextLabelY->setObjectName( "TextLabelY" );
343   TextLabelY->setText( tr("Y:") );
344   GroupPointLayout->addWidget( TextLabelY, 0, 2 );
345
346   SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
347   SpinBox_Y->setObjectName("SpinBox_Y" );
348   SpinBox_Y->setPrecision( precision );
349   GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
350
351   TextLabelZ = new QLabel( GroupAbsolutePoint );
352   TextLabelZ->setObjectName( "TextLabelZ" );
353   TextLabelZ->setText( tr("Z:") );
354   GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
355
356   SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
357   SpinBox_Z->setObjectName("SpinBox_Z" );
358   SpinBox_Z->setPrecision( precision );
359   GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
360
361   resetButton  = new QPushButton( GroupAbsolutePoint );
362   resetButton->setObjectName( "resetButton" );
363   resetButton->setText( tr( "RESET"  ) );
364   GroupPointLayout->addWidget( resetButton, 0, 6 );
365
366   // Group Direction
367   GroupAbsoluteDirection = new QGroupBox( this );
368   GroupAbsoluteDirection->setObjectName( "GroupDirection" );
369   GroupAbsoluteDirection->setTitle( tr("DIRECTION") );
370   QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection );
371   GroupDirectionLayout->setAlignment( Qt::AlignTop );
372   GroupDirectionLayout->setSpacing( 6 );
373   GroupDirectionLayout->setMargin( 11 );
374   
375   TextLabelDx = new QLabel( GroupAbsoluteDirection );
376   TextLabelDx->setObjectName( "TextLabelDx" );
377   TextLabelDx->setText( tr("Dx:") );
378   GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
379   
380   SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
381   SpinBox_Dx->setObjectName("SpinBox_Dx" );
382   SpinBox_Dx->setPrecision( precision );
383   GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
384
385   TextLabelDy = new QLabel( GroupAbsoluteDirection );
386   TextLabelDy->setObjectName( "TextLabelDy" );
387   TextLabelDy->setText( tr("Dy:") );
388   GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
389   
390   SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
391   SpinBox_Dy->setObjectName("SpinBox_Dy" );
392   SpinBox_Dy->setPrecision( precision );
393   GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
394
395   TextLabelDz = new QLabel( GroupAbsoluteDirection );
396   TextLabelDz->setObjectName( "TextLabelDz" );
397   TextLabelDz->setText( tr("Dz:") );
398   GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
399   
400   SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
401   SpinBox_Dz->setObjectName("SpinBox_Dz" );
402   SpinBox_Dz->setPrecision( precision );
403   GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
404
405   invertButton  = new QPushButton( GroupAbsoluteDirection );
406   invertButton->setObjectName( "invertButton" );
407   invertButton->setText( tr( "INVERT"  ) );
408   GroupDirectionLayout->addWidget( invertButton, 0, 6 );
409  
410   CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection );
411   CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" );
412   CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) );
413   CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) );
414   CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) );
415   CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) );
416   GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 );
417
418   QVBoxLayout* ModeActiveLayout = new QVBoxLayout();
419   ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 );
420   ModeActiveLayout->addWidget( GroupAbsolutePoint );
421   ModeActiveLayout->addWidget( GroupAbsoluteDirection );
422
423   QWidget* ModeActiveWidget = new QWidget( this );
424   ModeActiveWidget->setLayout( ModeActiveLayout );
425
426   /**********************   Mode Relative   **********************/
427   /* Controls for relative mode of clipping plane:
428      Distance - Value from 0 to 1.
429      Specifies the distance from the minimum value in a given direction of bounding box to the current position
430      Rotation1, Rotation2 - turn angles of cutting plane in given directions
431      Orientation - direction of cutting plane
432    */
433   QGroupBox* GroupParameters = new QGroupBox( tr("PARAMETERS"), this );
434   QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );
435   GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 );
436
437   TextLabelOrientation = new QLabel( tr("ORIENTATION"), GroupParameters);
438   TextLabelOrientation->setObjectName( "TextLabelOrientation" );
439   GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
440
441   CBRelativeOrientation = new QComboBox(GroupParameters);
442   CBRelativeOrientation->setObjectName( "RelativeOrientation" );
443   CBRelativeOrientation->addItem( tr("ALONG_XY") );
444   CBRelativeOrientation->addItem( tr("ALONG_YZ") );
445   CBRelativeOrientation->addItem( tr("ALONG_ZX") );
446   GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );
447
448   TLValueDistance = new QLabel( GroupParameters );
449   TLValueDistance->setObjectName( "TLValueDistance" );
450   TLValueDistance->setAlignment( Qt::AlignCenter );
451   TLValueDistance->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
452   QFont fnt = TLValueDistance->font(); fnt.setBold( true ); TLValueDistance->setFont( fnt );
453   GroupParametersLayout->addWidget( TLValueDistance, 1, 1 );
454
455   TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters );
456   TextLabelDistance->setObjectName( "TextLabelDistance" );
457   GroupParametersLayout->addWidget( TextLabelDistance, 2, 0 );
458
459   SliderDistance = new QSlider( Qt::Horizontal, GroupParameters );
460   SliderDistance->setObjectName( "SliderDistance" );
461   SliderDistance->setFocusPolicy( Qt::NoFocus );
462   SliderDistance->setMinimumSize( 300, 0 );
463   SliderDistance->setMinimum( 0 );
464   SliderDistance->setMaximum( 100 );
465   SliderDistance->setSingleStep( 1 );
466   SliderDistance->setPageStep( 10 );
467   SliderDistance->setTracking( false );
468   GroupParametersLayout->addWidget( SliderDistance, 2, 1 );
469
470   TLValueRotation1 = new QLabel( GroupParameters );
471   TLValueRotation1->setObjectName( "TLValueRotation1" );
472   TLValueRotation1->setAlignment( Qt::AlignCenter );
473   TLValueRotation1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
474   TLValueRotation1->setFont( fnt );
475   GroupParametersLayout->addWidget( TLValueRotation1, 3, 1 );
476
477   TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters );
478   TextLabelRotation1->setObjectName( "TextLabelRotation1" );
479   GroupParametersLayout->addWidget( TextLabelRotation1, 4, 0 );
480
481   SliderRotation1 = new QSlider( Qt::Horizontal, GroupParameters );
482   SliderRotation1->setObjectName( "SliderRotation1" );
483   SliderRotation1->setFocusPolicy( Qt::NoFocus );
484   SliderRotation1->setMinimumSize( 300, 0 );
485   SliderRotation1->setMinimum( -180 );
486   SliderRotation1->setMaximum( 180 );
487   SliderRotation1->setSingleStep( 1 );
488   SliderRotation1->setPageStep( 10 );
489   SliderRotation1->setTracking(false);
490   GroupParametersLayout->addWidget( SliderRotation1, 4, 1 );
491
492   TLValueRotation2 = new QLabel( GroupParameters );
493   TLValueRotation2->setObjectName( "TLValueRotation2" );
494   TLValueRotation2->setAlignment( Qt::AlignCenter );
495   TLValueRotation2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
496   TLValueRotation2->setFont( fnt );
497   GroupParametersLayout->addWidget( TLValueRotation2, 5, 1 );
498
499   TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);
500   TextLabelRotation2->setObjectName( "TextLabelRotation2" );
501   TextLabelRotation2->setObjectName( "TextLabelRotation2" );
502   GroupParametersLayout->addWidget( TextLabelRotation2, 6, 0 );
503
504   SliderRotation2 = new QSlider( Qt::Horizontal, GroupParameters );
505   SliderRotation2->setObjectName( "SliderRotation2" );
506   SliderRotation2->setFocusPolicy( Qt::NoFocus );
507   SliderRotation2->setMinimumSize( 300, 0 );
508   SliderRotation2->setMinimum( -180 );
509   SliderRotation2->setMaximum( 180 );
510   SliderRotation2->setSingleStep( 1 );
511   SliderRotation2->setPageStep( 10 );
512   SliderRotation2->setTracking(false);
513   GroupParametersLayout->addWidget( SliderRotation2, 6, 1 );
514
515   /***************************************************************/
516   QGroupBox* CheckBoxWidget = new QGroupBox( this );
517   QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget );
518   
519   PreviewCheckBox = new QCheckBox( tr("PREVIEW"), CheckBoxWidget );
520   PreviewCheckBox->setObjectName( "PreviewCheckBox" );
521   PreviewCheckBox->setChecked( true );
522   CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter );
523   
524   AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget );
525   AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" );
526   CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter );
527
528   /***************************************************************/
529   QGroupBox* GroupButtons = new QGroupBox( this );
530   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );
531   GroupButtonsLayout->setAlignment( Qt::AlignTop );
532   GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );
533   
534   buttonOk = new QPushButton( GroupButtons );
535   buttonOk->setObjectName( "buttonOk" );
536   buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE"  ) );
537   buttonOk->setAutoDefault( TRUE );
538   buttonOk->setDefault( TRUE );
539   GroupButtonsLayout->addWidget( buttonOk );
540
541   buttonApply = new QPushButton( GroupButtons );
542   buttonApply->setObjectName( "buttonApply" );
543   buttonApply->setText( tr( "BUT_APPLY"  ) );
544   buttonApply->setAutoDefault( TRUE );
545   buttonApply->setDefault( TRUE );
546   GroupButtonsLayout->addWidget( buttonApply );
547
548   GroupButtonsLayout->addStretch();
549   
550   buttonClose = new QPushButton( GroupButtons );
551   buttonClose->setObjectName( "buttonClose" );
552   buttonClose->setText( tr( "BUT_CLOSE"  ) );
553   buttonClose->setAutoDefault( TRUE );
554   GroupButtonsLayout->addWidget( buttonClose );
555
556   QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons );
557   buttonHelp->setAutoDefault( TRUE );
558   GroupButtonsLayout->addWidget( buttonHelp );
559
560   /***************************************************************/
561   ModeStackedLayout->addWidget( ModeActiveWidget );
562   ModeStackedLayout->addWidget( GroupParameters );
563
564   topLayout->addWidget( GroupPlanes );
565   topLayout->addLayout( ModeStackedLayout );
566   topLayout->addWidget( CheckBoxWidget );
567   topLayout->addWidget( GroupButtons );
568
569   this->setLayout( topLayout );
570
571   // Initializations
572   initParam();
573
574   // Signals and slots connections
575   connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) );
576   connect( isActivePlane,  SIGNAL ( toggled ( bool ) ),  this, SLOT( onValueChanged() ) );
577   connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) );
578   connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );
579   connect( buttonDisableAll, SIGNAL( clicked() ), this, SLOT( ClickOnDisableAll() ) );
580
581   connect( resetButton,  SIGNAL (clicked() ), this, SLOT( onReset() ) );
582   connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
583   connect( SpinBox_X,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
584   connect( SpinBox_Y,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
585   connect( SpinBox_Z,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
586   connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
587   connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
588   connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );
589   connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ;
590
591   connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( int ) ) );
592   connect( SliderDistance,   SIGNAL( sliderMoved( int ) ),  this, SLOT( SliderDistanceHasMoved( int ) ) );
593   connect( SliderDistance,   SIGNAL( valueChanged( int ) ),  this, SLOT( SliderDistanceHasMoved( int ) ) );
594   connect( SliderRotation1,   SIGNAL( sliderMoved( int ) ),  this, SLOT( SliderRotation1HasMoved( int ) ) );
595   connect( SliderRotation1,   SIGNAL( valueChanged( int ) ),  this, SLOT( SliderRotation1HasMoved( int ) ) );
596   connect( SliderRotation2,   SIGNAL( sliderMoved( int ) ),  this, SLOT( SliderRotation2HasMoved( int ) ) );
597   connect( SliderRotation2,   SIGNAL( valueChanged( int ) ),  this, SLOT( SliderRotation2HasMoved( int ) ) );
598
599   connect( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;
600   connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) );
601   
602   connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;
603   connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
604   connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
605   connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
606   
607   connect(view, SIGNAL(Show( QShowEvent* ) ), this, SLOT( onViewShow() ) );
608   connect(view, SIGNAL(Hide( QHideEvent* ) ), this, SLOT( onViewHide() ) );
609
610   myBusy = false;
611   myIsSelectPlane = false;
612   myView3d = myView->getViewPort()->getView();
613
614   synchronize();
615 }
616
617 /*!
618   Destructor
619   Destroys the object and frees any allocated resources
620 */
621 OCCViewer_ClippingDlg::~ OCCViewer_ClippingDlg()
622 {
623   // no need to delete child widgets, Qt does it all for us
624   foreach( ClipPlane* aPlane, myClippingPlanes )
625     delete aPlane;
626 }
627
628 /*!
629   Custom handling of close event: erases preview
630 */
631 void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
632 {
633   erasePreview();
634   myAction->setChecked( false );
635   QDialog::closeEvent( e );
636 }
637
638 /*!
639   Custom handling of show event: displays preview
640 */
641 void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )
642 {
643   QDialog::showEvent( e );
644   onPreview( PreviewCheckBox->isChecked() );
645 }
646
647 /*!
648   Custom handling of hide event: erases preview
649 */
650 void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
651 {
652   erasePreview();
653   QDialog::hideEvent( e );
654 }
655
656 /*!
657   Initialization of initial values of widgets
658 */
659 void OCCViewer_ClippingDlg::initParam()
660 {
661   SpinBox_X->setValue( 0.0 );
662   SpinBox_Y->setValue( 0.0 );
663   SpinBox_Z->setValue( 0.0 );
664
665   SpinBox_Dx->setValue( 1.0 );
666   SpinBox_Dy->setValue( 1.0 );
667   SpinBox_Dz->setValue( 1.0 );
668
669   CBAbsoluteOrientation->setCurrentIndex(0);
670
671   TLValueDistance->setText( "0" );
672   TLValueRotation1->setText( "0\xB0" );
673   TLValueRotation2->setText( "0\xB0" );
674   CBRelativeOrientation->setCurrentIndex( 0 );
675   SliderDistance->setValue( 50 );
676   SliderRotation1->setValue( 0 );
677   SliderRotation2->setValue( 0 );
678 }
679
680 /*!
681   Synchronize dialog's widgets with data
682 */
683 void OCCViewer_ClippingDlg::synchronize()
684 {
685   ComboBoxPlanes->clear();
686   int aNbPlanesAbsolute = myClippingPlanes.size();
687
688   QString aName;
689   for(int i = 1; i<=aNbPlanesAbsolute; i++ ) {
690     aName = QString("Plane %1").arg(i);
691     ComboBoxPlanes->addItem( aName );
692   }
693
694   int aPos = ComboBoxPlanes->count() - 1;
695   ComboBoxPlanes->setCurrentIndex( aPos );
696
697   bool anIsControlsEnable = ( aPos >= 0 );
698   if ( anIsControlsEnable ) {
699     onSelectPlane( aPos );
700   }
701   else {
702     ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );
703     initParam();
704     ClickOnDisableAll();
705   }
706   if ( CurrentMode == Absolute ) {
707     SpinBox_X->setEnabled( anIsControlsEnable );
708     SpinBox_Y->setEnabled( anIsControlsEnable );
709     SpinBox_Z->setEnabled( anIsControlsEnable );
710     SpinBox_Dx->setEnabled( anIsControlsEnable );
711     SpinBox_Dy->setEnabled( anIsControlsEnable );
712     SpinBox_Dz->setEnabled( anIsControlsEnable );
713     CBAbsoluteOrientation->setEnabled( anIsControlsEnable );
714     invertButton->setEnabled( anIsControlsEnable );
715     resetButton->setEnabled( anIsControlsEnable );
716   }
717   else if( CurrentMode == Relative ) {
718     CBRelativeOrientation->setEnabled( anIsControlsEnable );
719     SliderDistance->setEnabled( anIsControlsEnable );
720     SliderRotation1->setEnabled( anIsControlsEnable );
721     SliderRotation2->setEnabled( anIsControlsEnable );
722     isActivePlane->setEnabled( anIsControlsEnable );
723   }
724   isActivePlane->setEnabled( anIsControlsEnable );
725 }
726
727 /*!
728   Displays preview of clipping plane
729 */
730 void OCCViewer_ClippingDlg::displayPreview()
731 {
732   if ( myBusy || !isValid() )
733     return;
734
735   OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
736   if ( !anOCCViewer )
737     return;
738
739   Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
740
741   double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
742   aXMin = aYMin = aZMin = DBL_MAX;
743   aXMax = aYMax = aZMax = -DBL_MAX;
744
745   bool isFound = false;
746   AIS_ListOfInteractive aList;
747   ic->DisplayedObjects( aList );
748   for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() )
749   {
750     Handle(AIS_InteractiveObject) anObj = it.Value();
751     if ( !anObj.IsNull() && anObj->HasPresentation() &&
752          !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) {
753       Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
754       if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) {
755         isFound = true;
756         double xmin, ymin, zmin, xmax, ymax, zmax;
757         aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );
758         aXMin = qMin( aXMin, xmin );  aXMax = qMax( aXMax, xmax );
759         aYMin = qMin( aYMin, ymin );  aYMax = qMax( aYMax, ymax );
760         aZMin = qMin( aZMin, zmin );  aZMax = qMax( aZMax, zmax );
761       }
762     }
763   }
764
765   double aSize = 50;
766
767   ClipPlane* aClipPlane;
768   for ( int i=0; i < myClippingPlanes.size(); i++ ) {
769   Pnt_ClipPlane aPlane = myClippingPlanes[i];
770   aClipPlane = aPlane;
771
772   double Epsilon = 0.0001;
773   double Epsilon_Dx = ( aClipPlane->Dx > 0 ) ? Epsilon: -Epsilon;
774   double Epsilon_Dy = ( aClipPlane->Dy > 0 ) ? Epsilon: -Epsilon;
775   double Epsilon_Dz = ( aClipPlane->Dz > 0 ) ? Epsilon: -Epsilon;
776
777   gp_Pnt aBasePnt( aClipPlane->X + Epsilon_Dx,  aClipPlane->Y + Epsilon_Dy,  aClipPlane->Z + Epsilon_Dz );
778   gp_Dir aNormal( aClipPlane->Dx, aClipPlane->Dy, aClipPlane->Dz );
779   gp_Pnt aCenter = aBasePnt;
780
781   if ( isFound )
782   {
783     // compute clipping plane size
784     aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
785     double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2;
786     aSize = aDiag * 1.1;
787
788     // compute clipping plane center ( redefine the base point )
789     IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
790
791     intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
792     if ( intersector.IsDone() && intersector.NbPoints() == 1 )
793       aBasePnt = intersector.Point( 1 );
794     }
795
796     if ( aClipPlane->IsActive == true ) {
797       Handle(AIS_Plane) myPreviewPlane;
798       myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ) );
799       myPreviewPlane->SetSize( aSize, aSize );
800
801       ic->Display( myPreviewPlane, 1, -1, false );
802       ic->SetWidth( myPreviewPlane, 10, false );
803       ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
804       ic->SetTransparency( myPreviewPlane, 0.5, false );
805       ic->SetColor( myPreviewPlane, Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
806
807       myPreviewPlaneVector.push_back( myPreviewPlane );
808     }
809   }
810   anOCCViewer->update();
811 }
812
813 /*!
814   Erases preview of clipping plane
815 */
816 void OCCViewer_ClippingDlg::erasePreview()
817 {
818   OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel();
819   if ( !anOCCViewer )
820     return;
821   
822   Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext();
823   
824   for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) {
825   Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i];
826     if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
827       ic->Erase( myPreviewPlane, false );
828       ic->Remove( myPreviewPlane, false );
829       myPreviewPlane.Nullify();
830     }
831   }
832   anOCCViewer->update();
833 }
834
835 /*!
836   Return true if plane parameters are valid
837 */
838 bool OCCViewer_ClippingDlg::isValid()
839 {
840   return ( SpinBox_Dx->value() !=0 || SpinBox_Dy->value() !=0 || SpinBox_Dz->value() !=0 );
841 }
842
843 /*!
844   Update view after changes
845 */
846 void OCCViewer_ClippingDlg::updateView()
847 {
848   if ( PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked() ) {
849     erasePreview();
850     if ( AutoApplyCheckBox->isChecked() )
851       onApply();
852     if ( PreviewCheckBox->isChecked() && !isRestore )
853       displayPreview();
854   }
855 }
856
857 /*!
858   SLOT on new button click: create a new clipping plane
859 */
860 void OCCViewer_ClippingDlg::ClickOnNew()
861 {
862   ClipPlane* aPlane = new ClipPlane();
863   aPlane->PlaneMode = CurrentMode;
864   myClippingPlanes.push_back( aPlane );
865   synchronize();
866 }
867
868 /*!
869   SLOT on delete button click: Delete selected clipping plane
870 */
871 void OCCViewer_ClippingDlg::ClickOnDelete()
872 {
873   if ( myClippingPlanes.empty() )
874     return;
875
876   int aPlaneIndex = ComboBoxPlanes->currentIndex();
877
878   ClipPlaneVector::iterator anIter = myClippingPlanes.begin() + aPlaneIndex;
879   myClippingPlanes.erase( anIter );
880   updateView();
881   synchronize();
882 }
883
884 /*!
885   SLOT on disable all button click: Restore initial state of viewer,
886   erase all clipping planes
887 */
888 void OCCViewer_ClippingDlg::ClickOnDisableAll()
889 {
890   AutoApplyCheckBox->setChecked( false );
891   Graphic3d_SetOfHClipPlane aPlanes = myView3d->GetClipPlanes();
892   Graphic3d_SetOfHClipPlane::Iterator anIter (aPlanes);
893   for( ;anIter.More();anIter.Next() ){
894     Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value();
895     aClipPlane->SetOn(Standard_False);
896   }
897   myView3d->Update();
898   myView3d->Redraw();
899 }
900
901 /*!
902   SLOT on ok button click: sets cutting plane and closes dialog
903 */
904 void OCCViewer_ClippingDlg::ClickOnOk()
905 {
906   onApply();
907   erasePreview();
908   myAction->setChecked( false );
909 }
910
911 /*!
912   SLOT on Apply button click: sets cutting plane and update viewer
913 */
914 void OCCViewer_ClippingDlg::ClickOnApply()
915 {
916   onApply();
917   myView3d->Update();
918   myView3d->Redraw();
919 }
920
921 /*!
922   SLOT on close button click: erases preview and rejects dialog
923 */
924 void OCCViewer_ClippingDlg::ClickOnClose()
925 {
926   erasePreview();
927   myAction->setChecked( false );
928 }
929
930 /*!
931   SLOT on help button click: opens a help page
932 */
933 void OCCViewer_ClippingDlg::ClickOnHelp()
934 {
935   SUIT_Application* app = SUIT_Session::session()->activeApplication();
936   if ( app )
937     app->onHelpContextModule( "GUI", "occ_3d_viewer_page.html", "clipping_planes" );
938 }
939
940 /*!
941   Set absolute mode of clipping plane
942 */
943 void OCCViewer_ClippingDlg::onModeAbsolute()
944 {
945   ModeStackedLayout->setCurrentIndex(0);
946   CurrentMode = Absolute;
947   ClickOnNew();
948   onValueChanged();
949 }
950
951 /*!
952   Set relative mode of clipping plane
953 */
954 void OCCViewer_ClippingDlg::onModeRelative()
955 {
956   ModeStackedLayout->setCurrentIndex(1);
957   CurrentMode = Relative;
958   ClickOnNew();
959   onValueChanged();
960 }
961
962 /*!
963   SLOT: called on value of clipping plane changed
964 */
965 void OCCViewer_ClippingDlg::onValueChanged()
966 {
967   SetCurrentPlaneParam();
968   if ( myIsSelectPlane )
969     return;
970   updateView();
971 }
972
973 /*!
974   Set current parameters of selected plane
975 */
976 void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )
977 {
978   if ( myClippingPlanes.empty() )
979     return;
980
981   Pnt_ClipPlane aPlane = myClippingPlanes[theIndex];
982   ClipPlane* aClipPlane = aPlane;
983
984   myIsSelectPlane = true;
985   if ( aClipPlane->PlaneMode == Absolute ) {
986     ModeStackedLayout->setCurrentIndex( 0 );
987     CurrentMode = Absolute;
988     int anOrientation = aClipPlane->Orientation;
989     // Set plane parameters in the dialog
990     SpinBox_X->setValue( aClipPlane->X );
991     SpinBox_Y->setValue( aClipPlane->Y );
992     SpinBox_Z->setValue( aClipPlane->Z );
993     SpinBox_Dx->setValue( aClipPlane->Dx );
994     SpinBox_Dy->setValue( aClipPlane->Dy );
995     SpinBox_Dz->setValue( aClipPlane->Dz );
996     CBAbsoluteOrientation->setCurrentIndex( anOrientation );
997     onOrientationAbsoluteChanged( anOrientation );
998   }
999   else if( aClipPlane->PlaneMode == Relative ) {
1000     ModeStackedLayout->setCurrentIndex( 1 );
1001     CurrentMode = Relative;
1002     int anOrientation = aClipPlane->RelativeMode.Orientation;
1003     // Set plane parameters in the dialog
1004     SliderDistance->setValue( aClipPlane->RelativeMode.Distance*100 );
1005     TLValueDistance->setText( QString::number(aClipPlane->RelativeMode.Distance ) );
1006     SliderRotation1->setValue( aClipPlane->RelativeMode.Rotation1 );
1007     TLValueRotation1->setText( QString( "%1\xB0" ).arg( aClipPlane->RelativeMode.Rotation1 ) );
1008     SliderRotation2->setValue( aClipPlane->RelativeMode.Rotation2 );
1009     TLValueRotation2->setText( QString( "%1\xB0" ).arg( aClipPlane->RelativeMode.Rotation2 ) );
1010     CBRelativeOrientation->setCurrentIndex( anOrientation );
1011     onOrientationRelativeChanged( anOrientation );
1012   }
1013   isActivePlane->setChecked( aClipPlane->IsActive );
1014   ComboBoxPlanes->setCurrentIndex( theIndex );
1015
1016   myIsSelectPlane = false;
1017 }
1018
1019 /*!
1020   Restore parameters of selected plane
1021 */
1022 void OCCViewer_ClippingDlg::SetCurrentPlaneParam()
1023 {
1024   if ( myClippingPlanes.empty() || myIsSelectPlane )
1025     return;
1026
1027   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1028
1029   Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex];
1030   ClipPlane* aPlaneData = aPlane;
1031
1032   if ( aPlaneData->PlaneMode == Absolute ) {
1033     aPlaneData->Orientation = CBAbsoluteOrientation->currentIndex();
1034     aPlaneData->X = SpinBox_X->value();
1035     aPlaneData->Y = SpinBox_Y->value();
1036     aPlaneData->Z = SpinBox_Z->value();
1037     aPlaneData->Dx = SpinBox_Dx->value();
1038     aPlaneData->Dy = SpinBox_Dy->value();
1039     aPlaneData->Dz = SpinBox_Dz->value();
1040   }
1041   else if( aPlaneData->PlaneMode == Relative ) {
1042     aPlaneData->RelativeMode.Orientation = CBRelativeOrientation->currentIndex();
1043     aPlaneData->RelativeMode.Distance = TLValueDistance->text().toDouble();
1044     aPlaneData->RelativeMode.Rotation1 = TLValueRotation1->text().remove("\xB0").toInt();
1045     aPlaneData->RelativeMode.Rotation2 = TLValueRotation2->text().remove("\xB0").toInt();
1046     erasePreview();
1047     RelativePlaneToAbsolute( aPlane, myView3d );
1048   }
1049   aPlaneData->IsActive = isActivePlane->isChecked();
1050 }
1051
1052 /*!
1053   SLOT on reset button click: sets default values
1054 */
1055 void OCCViewer_ClippingDlg::onReset()
1056 {
1057   myBusy = true;
1058   SpinBox_X->setValue(0);
1059   SpinBox_Y->setValue(0);
1060   SpinBox_Z->setValue(0);
1061   myBusy = false;
1062
1063   updateView();
1064 }
1065
1066 /*!
1067   SLOT on invert button click: inverts normal of cutting plane
1068 */
1069 void OCCViewer_ClippingDlg::onInvert()
1070 {
1071   double Dx = SpinBox_Dx->value();
1072   double Dy = SpinBox_Dy->value();
1073   double Dz = SpinBox_Dz->value();
1074
1075   myBusy = true;
1076   SpinBox_Dx->setValue( -Dx );
1077   SpinBox_Dy->setValue( -Dy );
1078   SpinBox_Dz->setValue( -Dz );
1079   myBusy = false;
1080
1081   if ( !myClippingPlanes.empty() ) {
1082     int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1083     Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex];
1084     ClipPlane* aPlaneData = aPlane;
1085     aPlaneData->IsInvert = !aPlaneData->IsInvert;
1086   }
1087   updateView();
1088 }
1089
1090 /*!
1091   SLOT: called on orientation of clipping plane in absolute mode changed
1092 */
1093 void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )
1094 {
1095   bool isUserMode = (mode==0);
1096
1097   TextLabelX->setEnabled( isUserMode );
1098   TextLabelY->setEnabled( isUserMode );
1099   TextLabelZ->setEnabled( isUserMode );
1100
1101   SpinBox_X->setEnabled( isUserMode );
1102   SpinBox_Y->setEnabled( isUserMode );
1103   SpinBox_Z->setEnabled( isUserMode );
1104
1105   TextLabelDx->setEnabled( isUserMode );
1106   TextLabelDy->setEnabled( isUserMode );
1107   TextLabelDz->setEnabled( isUserMode );
1108
1109   SpinBox_Dx->setEnabled( isUserMode );
1110   SpinBox_Dy->setEnabled( isUserMode );
1111   SpinBox_Dz->setEnabled( isUserMode );
1112
1113   if ( isUserMode )
1114     return;
1115
1116   double aDx = 0, aDy = 0, aDz = 0;
1117
1118   if ( mode == 1 )
1119   {
1120     aDz = 1;
1121     TextLabelZ->setEnabled( true );
1122     SpinBox_Z->setEnabled( true );
1123     SpinBox_Z->setFocus();
1124   }
1125   else if ( mode == 2 )
1126   {
1127     aDx = 1;
1128     TextLabelX->setEnabled( true );
1129     SpinBox_X->setEnabled( true );
1130     SpinBox_X->setFocus();
1131   }
1132   else if ( mode == 3 )
1133   {
1134     aDy = 1;
1135     TextLabelY->setEnabled( true );
1136     SpinBox_Y->setEnabled( true );
1137     SpinBox_Y->setFocus();
1138   }
1139
1140   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1141   Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex];
1142   ClipPlane* aPlaneData = aPlane;
1143   if ( aPlaneData->IsInvert == true ) {
1144     aDx = -aDx; aDy = -aDy; aDz = -aDz;
1145   }
1146
1147   myBusy = true;
1148   SpinBox_Dx->setValue( aDx );
1149   SpinBox_Dy->setValue( aDy );
1150   SpinBox_Dz->setValue( aDz );
1151   myBusy = false;
1152
1153   SetCurrentPlaneParam();
1154   updateView();
1155 }
1156
1157 /*!
1158   SLOT: called on orientation of clipping plane in relative mode changed
1159 */
1160 void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)
1161 {
1162   if ( myClippingPlanes.empty() )
1163     return;
1164
1165   if ( theItem == 0 ) {
1166     TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );
1167     TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );
1168   }
1169   else if ( theItem == 1 ) {
1170     TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) );
1171     TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) );
1172   }
1173   else if ( theItem == 2 ) {
1174     TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) );
1175     TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );
1176   }
1177
1178   if( (QComboBox*)sender() == CBRelativeOrientation )
1179     SetCurrentPlaneParam();
1180   updateView();
1181 }
1182
1183 /*!
1184   SLOT: called on preview check box toggled
1185 */
1186 void OCCViewer_ClippingDlg::onPreview( bool on )
1187 {
1188   erasePreview();
1189   if ( on ) 
1190     displayPreview();
1191 }
1192
1193 /*!
1194   SLOT: called on Auto Apply check box toggled
1195 */
1196 void OCCViewer_ClippingDlg::onAutoApply( bool toggled )
1197 {
1198   if ( toggled ) onApply();
1199   myView3d->Update();
1200   myView3d->Redraw();
1201 }
1202
1203 /*!
1204   SLOT on Apply button click: sets cutting plane
1205 */
1206 void OCCViewer_ClippingDlg::onApply()
1207 {
1208   if ( myBusy )
1209     return;
1210   myIsSelectPlane = true;
1211   Graphic3d_SetOfHClipPlane aPlanes = myView3d->GetClipPlanes();
1212   Graphic3d_SetOfHClipPlane::Iterator anIter (aPlanes);
1213   for( ;anIter.More();anIter.Next() ){
1214     Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value();
1215     aClipPlane->SetOn(Standard_False);
1216   }
1217
1218   qApp->processEvents();
1219   QApplication::setOverrideCursor( Qt::WaitCursor );
1220   qApp->processEvents();
1221
1222   for ( int i=0;i<myClippingPlanes.size();i++ ) {
1223     Pnt_ClipPlane aPlane = myClippingPlanes[i];
1224     ClipPlane* aClipPlane = aPlane;
1225     if ( aClipPlane->IsActive == true )
1226       myView->setCuttingPlane( true, aClipPlane->X , aClipPlane->Y , aClipPlane->Z,
1227                                aClipPlane->Dx, aClipPlane->Dy, aClipPlane->Dz );
1228   }
1229
1230   QApplication::restoreOverrideCursor();
1231   myIsSelectPlane = false;
1232 }
1233
1234 void OCCViewer_ClippingDlg::onViewShow()
1235 {
1236   if(myAction->isChecked())
1237     show();
1238   else
1239     hide();
1240 }
1241
1242 void OCCViewer_ClippingDlg::onViewHide()
1243 {
1244   hide();
1245 }
1246
1247 /*!
1248   SLOT: Called when value of slider distance change
1249 */
1250 void OCCViewer_ClippingDlg::SliderDistanceHasMoved( int value )
1251 {
1252   double new_value = value/100.;
1253   TLValueDistance->setText( QString("%1").arg( new_value ) );
1254   onValueChanged();
1255 }
1256
1257 /*!
1258   SLOT: Called when value of slider rotation1 change
1259 */
1260 void OCCViewer_ClippingDlg::SliderRotation1HasMoved( int value )
1261 {
1262   TLValueRotation1->setText( QString("%1\xB0").arg( value ) );
1263   onValueChanged();
1264 }
1265
1266 /*!
1267   SLOT: Called when value of slider rotation2 change
1268 */
1269 void OCCViewer_ClippingDlg::SliderRotation2HasMoved( int value )
1270 {
1271   TLValueRotation2->setText( QString("%1\xB0").arg( value ) );
1272   onValueChanged();
1273 }