]> SALOME platform Git repositories - modules/gui.git/blob - src/OCCViewer/OCCViewer_ClippingDlg.cxx
Salome HOME
Fix pb with persistence of "light" modules: SaveAs operation leads to loss of non...
[modules/gui.git] / src / OCCViewer / OCCViewer_ClippingDlg.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE\r
2 //\r
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,\r
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS\r
5 //\r
6 // This library is free software; you can redistribute it and/or\r
7 // modify it under the terms of the GNU Lesser General Public\r
8 // License as published by the Free Software Foundation; either\r
9 // version 2.1 of the License, or (at your option) any later version.\r
10 //\r
11 // This library is distributed in the hope that it will be useful,\r
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
14 // Lesser General Public License for more details.\r
15 //\r
16 // You should have received a copy of the GNU Lesser General Public\r
17 // License along with this library; if not, write to the Free Software\r
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\r
19 //\r
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com\r
21 //\r
22 \r
23 #include "OCCViewer_ClippingDlg.h"\r
24 \r
25 #include <QtxDoubleSpinBox.h>\r
26 #include <QtxDoubleSpinSlider.h>\r
27 #include <QtxIntSpinSlider.h>\r
28 #include <QtxAction.h>\r
29 \r
30 #include "SUIT_Session.h"\r
31 #include "SUIT_ViewWindow.h"\r
32 #include "SUIT_ViewManager.h"\r
33 #include "OCCViewer_ClipPlane.h"\r
34 #include "OCCViewer_ViewWindow.h"\r
35 #include "OCCViewer_ViewPort3d.h"\r
36 #include "OCCViewer_ViewModel.h"\r
37 #include "OCCViewer_ViewManager.h"\r
38 #include "OCCViewer_ClipPlaneInteractor.h"\r
39 \r
40 #include <V3d_View.hxx>\r
41 #include <Visual3d_View.hxx>\r
42 #include <Geom_Plane.hxx>\r
43 #include <Prs3d_Presentation.hxx>\r
44 #include <AIS_ListIteratorOfListOfInteractive.hxx>\r
45 #include <AIS_ListOfInteractive.hxx>\r
46 #include <AIS_InteractiveObject.hxx>\r
47 #include <AIS_InteractiveContext.hxx>\r
48 #include <IntAna_IntConicQuad.hxx>\r
49 #include <gp_Lin.hxx>\r
50 #include <gp_Pln.hxx>\r
51 #include <math.h>\r
52 \r
53 // QT Includes\r
54 #include <QApplication>\r
55 #include <QGroupBox>\r
56 #include <QHBoxLayout>\r
57 #include <QVBoxLayout>\r
58 #include <QGridLayout>\r
59 #include <QLabel>\r
60 #include <QPushButton>\r
61 #include <QComboBox>\r
62 #include <QCheckBox>\r
63 #include <QStackedLayout>\r
64 #include <QSlider>\r
65 #include <QMenu>\r
66 \r
67 /**********************************************************************************\r
68  ************************        Internal functions        ************************\r
69  *********************************************************************************/\r
70 \r
71 void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic,\r
72                            double  theDefaultSize,\r
73                            double& theXMin,\r
74                            double& theYMin,\r
75                            double& theZMin,\r
76                            double& theXMax,\r
77                            double& theYMax,\r
78                            double& theZMax) {\r
79 \r
80   double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;\r
81   aXMin = aYMin = aZMin = DBL_MAX;\r
82   aXMax = aYMax = aZMax = -DBL_MAX;\r
83   \r
84   bool isFound = false;\r
85   AIS_ListOfInteractive aList;\r
86   ic->DisplayedObjects( aList );\r
87   for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) {\r
88     Handle(AIS_InteractiveObject) anObj = it.Value();\r
89     if ( !anObj.IsNull() && anObj->HasPresentation() &&\r
90          !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) {\r
91       Handle(Prs3d_Presentation) aPrs = anObj->Presentation();\r
92       if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) {\r
93         isFound = true;\r
94         double xmin, ymin, zmin, xmax, ymax, zmax;\r
95         aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );\r
96         aXMin = qMin( aXMin, xmin );  aXMax = qMax( aXMax, xmax );\r
97         aYMin = qMin( aYMin, ymin );  aYMax = qMax( aYMax, ymax );\r
98         aZMin = qMin( aZMin, zmin );  aZMax = qMax( aZMax, zmax );\r
99       }\r
100     }\r
101   }\r
102 \r
103   if(!isFound) {\r
104     if(theDefaultSize == 0.0)\r
105       theDefaultSize = 100.;\r
106     aXMin = aYMin = aZMin = -theDefaultSize;\r
107     aXMax = aYMax = aZMax = theDefaultSize;\r
108   }\r
109   theXMin = aXMin;theYMin = aYMin;theZMin = aZMin;\r
110   theXMax = aXMax;theYMax = aYMax;theZMax = aZMax;\r
111 }\r
112 \r
113 /*!\r
114   Compute the point of bounding box and current clipping plane\r
115  */\r
116 void ComputeBoundsParam( const double theBounds[6],\r
117                          const double theDirection[3],\r
118                          double theMinPnt[3],\r
119                          double& theMaxBoundPrj,\r
120                          double& theMinBoundPrj )\r
121 {\r
122   double aEnlargeBounds[6];\r
123 \r
124   // Enlarge bounds in order to avoid conflicts of precision\r
125   for(int i = 0; i < 6; i += 2)\r
126   {\r
127     static double EPS = 1.0E-3;\r
128     double aDelta = (theBounds[i+1] - theBounds[i])*EPS;\r
129     aEnlargeBounds[i  ] = theBounds[i  ] - aDelta;\r
130     aEnlargeBounds[i+1] = theBounds[i+1] + aDelta;\r
131   }\r
132 \r
133   double aBoundPoints[8][3] = { { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[4] },\r
134                                 { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[4] },\r
135                                 { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[4] },\r
136                                 { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[4] },\r
137                                 { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[5] },\r
138                                 { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[5] },\r
139                                 { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[5] },\r
140                                 { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[5] } };\r
141 \r
142   int aMaxId = 0;\r
143   theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1]\r
144                    + theDirection[2] * aBoundPoints[aMaxId][2];\r
145   theMinBoundPrj = theMaxBoundPrj;\r
146   for(int i = 1; i < 8; i++) {\r
147     double aTmp = theDirection[0] * aBoundPoints[i][0] + theDirection[1] * aBoundPoints[i][1]\r
148                   + theDirection[2] * aBoundPoints[i][2];\r
149     if(theMaxBoundPrj < aTmp) {\r
150       theMaxBoundPrj = aTmp;\r
151       aMaxId = i;\r
152     }\r
153     if(theMinBoundPrj > aTmp) {\r
154       theMinBoundPrj = aTmp;\r
155     }\r
156   }\r
157   double *aMinPnt = aBoundPoints[aMaxId];\r
158   theMinPnt[0] = aMinPnt[0];\r
159   theMinPnt[1] = aMinPnt[1];\r
160   theMinPnt[2] = aMinPnt[2];\r
161 }\r
162 \r
163 /*!\r
164   Compute the position of current plane by distance\r
165  */\r
166 void DistanceToPosition( const double theBounds[6],\r
167                          const double theDirection[3],\r
168                          const double theDist,\r
169                          double thePos[3] )\r
170 {\r
171   double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];\r
172   ComputeBoundsParam( theBounds, theDirection, aMinPnt, aMaxBoundPrj, aMinBoundPrj );\r
173   double aLength = (aMaxBoundPrj - aMinBoundPrj) * theDist;\r
174   thePos[0] = aMinPnt[0] - theDirection[0] * aLength;\r
175   thePos[1] = aMinPnt[1] - theDirection[1] * aLength;\r
176   thePos[2] = aMinPnt[2] - theDirection[2] * aLength;\r
177 }\r
178 \r
179 /*!\r
180   Compute the parameters of clipping plane\r
181  */\r
182 bool ComputeClippingPlaneParameters( const Handle(AIS_InteractiveContext)& theIC,\r
183                                      const double theDefaultSize,\r
184                                      const double theNormal[3],\r
185                                      const double theDist,\r
186                                      double theOrigin[3] )\r
187 {\r
188   double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };\r
189 \r
190   getMinMaxFromContext( theIC, theDefaultSize, aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5] );\r
191 \r
192   DistanceToPosition( aBounds, theNormal, theDist, theOrigin );\r
193   return true;\r
194 }\r
195 \r
196 /*!\r
197   \brief Converts relative plane parameters to absolute.\r
198   \param theIC [in] the interactive context.\r
199   \param theDefaultSize [in] the default trihedron size.\r
200   \param theDistance [in] the plane distance relative to minimum corner of model boundaries.\r
201   \param theDX [in] x component of plane direction.\r
202   \param theDY [in] y component of plane direction.\r
203   \param theDZ [in] z component of plane direction.\r
204   \param theX [out] x coordinate of plane origin.\r
205   \param theY [out] y coordinate of plane origin.\r
206   \param theZ [out] z coordinate of plane origin.\r
207  */\r
208 bool DistanceToXYZ ( const Handle(AIS_InteractiveContext)& theIC,\r
209                      const double theDefaultSize,\r
210                      const double theDistance,\r
211                      const double theDX,\r
212                      const double theDY,\r
213                      const double theDZ,\r
214                      double& theX,\r
215                      double& theY,\r
216                      double& theZ )\r
217 {\r
218   double aNormal[3] = { theDX, theDY, theDZ };\r
219   double anOrigin[3] = { 0.0, 0.0, 0.0 };\r
220 \r
221   bool anIsOk = ComputeClippingPlaneParameters( theIC, theDefaultSize, aNormal, theDistance, anOrigin );\r
222 \r
223   if( !anIsOk )\r
224   {\r
225     return false;\r
226   }\r
227 \r
228   theX = anOrigin[0];\r
229   theY = anOrigin[1];\r
230   theZ = anOrigin[2];\r
231 \r
232   return true;\r
233 }\r
234 \r
235 /*!\r
236   \brief Converts absolute position and direction to bounding box distance.\r
237   \param theIC [in] the interactive context.\r
238   \param theDefaultSize [in] the default trihedron size.\r
239   \param theX [in] x coordinate of plane origin.\r
240   \param theY [in] y coordinate of plane origin.\r
241   \param theZ [in] z coordinate of plane origin.\r
242   \param theDX [in] x component of plane direction.\r
243   \param theDY [in] y component of plane direction.\r
244   \param theDZ [in] z component of plane direction.\r
245   \param theDistance [out] the plane distance relative to minimum corner of model boundaries.\r
246  */\r
247 void XYZToDistance ( const Handle(AIS_InteractiveContext)& theIC,\r
248                      const double theDefaultSize,\r
249                      const double theX,\r
250                      const double theY,\r
251                      const double theZ,\r
252                      const double theDX,\r
253                      const double theDY,\r
254                      const double theDZ,\r
255                      double& theDistance )\r
256 {\r
257   gp_Pnt aPlaneP( theX, theY, theZ );\r
258   gp_Dir aPlaneN( theDX, theDY, theDZ );\r
259 \r
260   double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;\r
261 \r
262   getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
263 \r
264   Bnd_Box aMinMax;\r
265   aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
266 \r
267   gp_Trsf aRelativeTransform;\r
268   aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) );\r
269   Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform );\r
270 \r
271   aRelativeBounds.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
272 \r
273   double aLength   = aZmax - aZmin;\r
274   double aDistance = aZmax;\r
275 \r
276   double aRelativeDistance = aLength > 0.01 ? aDistance / aLength : 0.0;\r
277   aRelativeDistance = qMin( aRelativeDistance, aLength );\r
278   aRelativeDistance = qMax( aRelativeDistance, 0.0 );\r
279   theDistance = aRelativeDistance;\r
280 }\r
281 \r
282 /*!\r
283   Compute clipping plane size base point and normal\r
284  */\r
285 \r
286 void clipPlaneParams(OCCViewer_ClipPlane& theClipPlane, Handle(AIS_InteractiveContext) theContext,\r
287                      double& theSize, gp_Pnt& theBasePnt, gp_Dir& theNormal, double defaultSize) {\r
288   double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;\r
289   aXMin = aYMin = aZMin = DBL_MAX;\r
290   aXMax = aYMax = aZMax = -DBL_MAX;\r
291   \r
292   getMinMaxFromContext(theContext,defaultSize,aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);\r
293   double aSize = 50;\r
294 \r
295   double aNormalX = 0.0;\r
296   double aNormalY = 0.0;\r
297   double aNormalZ = 0.0;\r
298   theClipPlane.OrientationToXYZ( aNormalX, aNormalY, aNormalZ );\r
299   gp_Pnt aBasePnt( theClipPlane.X, theClipPlane.Y, theClipPlane.Z );\r
300   gp_Dir aNormal( aNormalX, aNormalY, aNormalZ );\r
301 \r
302   // compute clipping plane size\r
303   gp_Pnt aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );\r
304   double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2;\r
305   aSize = aDiag * 1.1;\r
306   \r
307   // compute clipping plane center ( redefine the base point )\r
308   IntAna_IntConicQuad intersector = IntAna_IntConicQuad();\r
309   \r
310   intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );\r
311 \r
312   if ( intersector.IsDone() && intersector.NbPoints() == 1 )\r
313     aBasePnt = intersector.Point( 1 );\r
314   \r
315   theSize = aSize;\r
316   theBasePnt = aBasePnt;\r
317   theNormal = aNormal;\r
318 }\r
319 \r
320 \r
321 /*********************************************************************************\r
322  *********************      class OCCViewer_ClippingDlg      *********************\r
323  *********************************************************************************/\r
324 /*!\r
325   Constructor\r
326   \param view - view window\r
327   \param parent - parent widget\r
328 */\r
329 OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model)\r
330   : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint )\r
331 {\r
332   setObjectName( "OCCViewer_ClippingDlg" );\r
333   setModal( false );\r
334 \r
335   setWindowTitle( tr( "Clipping" ) );\r
336 \r
337   setAttribute (Qt::WA_DeleteOnClose, true);\r
338   \r
339   QVBoxLayout* topLayout = new QVBoxLayout( this );\r
340   topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );\r
341 \r
342   /***************************************************************/\r
343   // Controls for selecting, creating, deleting planes\r
344   QGroupBox* GroupPlanes = new QGroupBox( tr("CLIPPING_PLANES"), this );\r
345   QHBoxLayout* GroupPlanesLayout = new QHBoxLayout( GroupPlanes );\r
346   ComboBoxPlanes = new QComboBox( GroupPlanes );\r
347   isActivePlane = new QCheckBox( tr("IS_ACTIVE_PLANE"), this );\r
348   buttonNew = new QPushButton( tr("BTN_NEW"), GroupPlanes );\r
349   buttonDelete = new QPushButton( tr("BTN_DELETE"), GroupPlanes );\r
350   buttonDisableAll = new QPushButton( tr("BTN_DISABLE_ALL"), GroupPlanes );\r
351   MenuMode = new QMenu( "MenuMode", buttonNew );\r
352   MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );\r
353   MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );\r
354   buttonNew->setMenu( MenuMode );\r
355 \r
356   GroupPlanesLayout->addWidget( ComboBoxPlanes );\r
357   GroupPlanesLayout->addWidget( isActivePlane );\r
358   GroupPlanesLayout->addWidget( buttonNew );\r
359   GroupPlanesLayout->addWidget( buttonDelete );\r
360   GroupPlanesLayout->addWidget( buttonDisableAll );\r
361 \r
362   ModeStackedLayout = new QStackedLayout();\r
363 \r
364   /**********************   Mode Absolute   **********************/\r
365   /* Controls for absolute mode of clipping plane:\r
366      X, Y, Z - coordinates of the intersection of cutting plane and the three axes\r
367      Dx, Dy, Dz - components of normal to the cutting plane\r
368      Orientation - direction of cutting plane\r
369    */\r
370   const double min = -1e+7;\r
371   const double max =  1e+7;\r
372   const double step = 5;\r
373   const int precision = -7;\r
374 \r
375   // Croup Point\r
376   QGroupBox* GroupAbsolutePoint = new QGroupBox( this );\r
377   GroupAbsolutePoint->setObjectName( "GroupPoint" );\r
378   GroupAbsolutePoint->setTitle( tr("BASE_POINT") );\r
379   QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint );\r
380   GroupPointLayout->setAlignment( Qt::AlignTop );\r
381   GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 );\r
382 \r
383   TextLabelX = new QLabel( GroupAbsolutePoint );\r
384   TextLabelX->setObjectName( "TextLabelX" );\r
385   TextLabelX->setText( tr("X:") );\r
386   GroupPointLayout->addWidget( TextLabelX, 0, 0 );\r
387   \r
388   SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );\r
389   SpinBox_X->setObjectName("SpinBox_X" );\r
390   SpinBox_X->setPrecision( precision );\r
391   GroupPointLayout->addWidget( SpinBox_X, 0, 1 );\r
392 \r
393   TextLabelY = new QLabel( GroupAbsolutePoint );\r
394   TextLabelY->setObjectName( "TextLabelY" );\r
395   TextLabelY->setText( tr("Y:") );\r
396   GroupPointLayout->addWidget( TextLabelY, 0, 2 );\r
397 \r
398   SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );\r
399   SpinBox_Y->setObjectName("SpinBox_Y" );\r
400   SpinBox_Y->setPrecision( precision );\r
401   GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );\r
402 \r
403   TextLabelZ = new QLabel( GroupAbsolutePoint );\r
404   TextLabelZ->setObjectName( "TextLabelZ" );\r
405   TextLabelZ->setText( tr("Z:") );\r
406   GroupPointLayout->addWidget( TextLabelZ, 0, 4 );\r
407 \r
408   SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );\r
409   SpinBox_Z->setObjectName("SpinBox_Z" );\r
410   SpinBox_Z->setPrecision( precision );\r
411   GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );\r
412 \r
413   resetButton  = new QPushButton( GroupAbsolutePoint );\r
414   resetButton->setObjectName( "resetButton" );\r
415   resetButton->setText( tr( "RESET"  ) );\r
416   GroupPointLayout->addWidget( resetButton, 0, 6 );\r
417 \r
418   // Group Direction\r
419   GroupAbsoluteDirection = new QGroupBox( this );\r
420   GroupAbsoluteDirection->setObjectName( "GroupDirection" );\r
421   GroupAbsoluteDirection->setTitle( tr("DIRECTION") );\r
422   QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection );\r
423   GroupDirectionLayout->setAlignment( Qt::AlignTop );\r
424   GroupDirectionLayout->setSpacing( 6 );\r
425   GroupDirectionLayout->setMargin( 11 );\r
426   \r
427   TextLabelDx = new QLabel( GroupAbsoluteDirection );\r
428   TextLabelDx->setObjectName( "TextLabelDx" );\r
429   TextLabelDx->setText( tr("Dx:") );\r
430   GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );\r
431   \r
432   SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );\r
433   SpinBox_Dx->setObjectName("SpinBox_Dx" );\r
434   SpinBox_Dx->setPrecision( precision );\r
435   GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );\r
436 \r
437   TextLabelDy = new QLabel( GroupAbsoluteDirection );\r
438   TextLabelDy->setObjectName( "TextLabelDy" );\r
439   TextLabelDy->setText( tr("Dy:") );\r
440   GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );\r
441   \r
442   SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );\r
443   SpinBox_Dy->setObjectName("SpinBox_Dy" );\r
444   SpinBox_Dy->setPrecision( precision );\r
445   GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );\r
446 \r
447   TextLabelDz = new QLabel( GroupAbsoluteDirection );\r
448   TextLabelDz->setObjectName( "TextLabelDz" );\r
449   TextLabelDz->setText( tr("Dz:") );\r
450   GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );\r
451   \r
452   SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );\r
453   SpinBox_Dz->setObjectName("SpinBox_Dz" );\r
454   SpinBox_Dz->setPrecision( precision );\r
455   GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );\r
456 \r
457   invertButton  = new QPushButton( GroupAbsoluteDirection );\r
458   invertButton->setObjectName( "invertButton" );\r
459   invertButton->setText( tr( "INVERT"  ) );\r
460   GroupDirectionLayout->addWidget( invertButton, 0, 6 );\r
461  \r
462   CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection );\r
463   CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" );\r
464   CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) );\r
465   CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) );\r
466   CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) );\r
467   CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) );\r
468   GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 );\r
469 \r
470   QVBoxLayout* ModeActiveLayout = new QVBoxLayout();\r
471   ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 );\r
472   ModeActiveLayout->addWidget( GroupAbsolutePoint );\r
473   ModeActiveLayout->addWidget( GroupAbsoluteDirection );\r
474 \r
475   QWidget* ModeActiveWidget = new QWidget( this );\r
476   ModeActiveWidget->setLayout( ModeActiveLayout );\r
477 \r
478   /**********************   Mode Relative   **********************/\r
479   /* Controls for relative mode of clipping plane:\r
480      Distance - Value from 0 to 1.\r
481      Specifies the distance from the minimum value in a given direction of bounding box to the current position\r
482      Rotation1, Rotation2 - turn angles of cutting plane in given directions\r
483      Orientation - direction of cutting plane\r
484    */\r
485   QGroupBox* GroupParameters = new QGroupBox( tr("PARAMETERS"), this );\r
486   QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );\r
487   GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 );\r
488 \r
489   TextLabelOrientation = new QLabel( tr("ORIENTATION"), GroupParameters);\r
490   TextLabelOrientation->setObjectName( "TextLabelOrientation" );\r
491   GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );\r
492 \r
493   CBRelativeOrientation = new QComboBox(GroupParameters);\r
494   CBRelativeOrientation->setObjectName( "RelativeOrientation" );\r
495   CBRelativeOrientation->addItem( tr("ALONG_XY") );\r
496   CBRelativeOrientation->addItem( tr("ALONG_YZ") );\r
497   CBRelativeOrientation->addItem( tr("ALONG_ZX") );\r
498   GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );\r
499 \r
500   TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters );\r
501   TextLabelDistance->setObjectName( "TextLabelDistance" );\r
502   GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 );\r
503   \r
504   SpinSliderDistance = new QtxDoubleSpinSlider( 0., 1., 0.01, GroupParameters );\r
505   SpinSliderDistance->setObjectName( "SpinSliderDistance" );\r
506   SpinSliderDistance->setPrecision( precision );\r
507   QFont fnt = SpinSliderDistance->font(); fnt.setBold( true ); SpinSliderDistance->setFont( fnt );\r
508   GroupParametersLayout->addWidget( SpinSliderDistance, 1, 1 );\r
509 \r
510   QString aUnitRot = "\xB0";\r
511 \r
512   TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters );\r
513   TextLabelRotation1->setObjectName( "TextLabelRotation1" );\r
514   GroupParametersLayout->addWidget( TextLabelRotation1, 2, 0 );\r
515   \r
516   SpinSliderRotation1 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );\r
517   SpinSliderRotation1->setObjectName( "SpinSliderRotation1" );\r
518   SpinSliderRotation1->setUnit( aUnitRot );\r
519   SpinSliderRotation1->setFont( fnt );\r
520   GroupParametersLayout->addWidget( SpinSliderRotation1, 2, 1 );\r
521 \r
522   TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);\r
523   TextLabelRotation2->setObjectName( "TextLabelRotation2" );\r
524   TextLabelRotation2->setObjectName( "TextLabelRotation2" );\r
525   GroupParametersLayout->addWidget( TextLabelRotation2, 3, 0 );\r
526 \r
527   SpinSliderRotation2 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );\r
528   SpinSliderRotation2->setObjectName( "SpinSliderRotation2" );\r
529   SpinSliderRotation2->setUnit( aUnitRot );\r
530   SpinSliderRotation2->setFont( fnt );\r
531   GroupParametersLayout->addWidget( SpinSliderRotation2, 3, 1 );\r
532 \r
533   /***************************************************************/\r
534   QGroupBox* CheckBoxWidget = new QGroupBox( this );\r
535   QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget );\r
536   \r
537   PreviewCheckBox = new QCheckBox( tr("PREVIEW"), CheckBoxWidget );\r
538   PreviewCheckBox->setObjectName( "PreviewCheckBox" );\r
539   PreviewCheckBox->setChecked( true );\r
540   CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter );\r
541   \r
542   AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget );\r
543   AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" );\r
544   CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter );\r
545 \r
546   /***************************************************************/\r
547   QGroupBox* GroupButtons = new QGroupBox( this );\r
548   QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );\r
549   GroupButtonsLayout->setAlignment( Qt::AlignTop );\r
550   GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );\r
551   \r
552   buttonOk = new QPushButton( GroupButtons );\r
553   buttonOk->setObjectName( "buttonOk" );\r
554   buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE"  ) );\r
555   buttonOk->setAutoDefault( TRUE );\r
556   buttonOk->setDefault( TRUE );\r
557   GroupButtonsLayout->addWidget( buttonOk );\r
558 \r
559   buttonApply = new QPushButton( GroupButtons );\r
560   buttonApply->setObjectName( "buttonApply" );\r
561   buttonApply->setText( tr( "BUT_APPLY"  ) );\r
562   buttonApply->setAutoDefault( TRUE );\r
563   buttonApply->setDefault( TRUE );\r
564   GroupButtonsLayout->addWidget( buttonApply );\r
565 \r
566   GroupButtonsLayout->addStretch();\r
567   \r
568   buttonClose = new QPushButton( GroupButtons );\r
569   buttonClose->setObjectName( "buttonClose" );\r
570   buttonClose->setText( tr( "BUT_CLOSE"  ) );\r
571   buttonClose->setAutoDefault( TRUE );\r
572   GroupButtonsLayout->addWidget( buttonClose );\r
573 \r
574   QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons );\r
575   buttonHelp->setAutoDefault( TRUE );\r
576   GroupButtonsLayout->addWidget( buttonHelp );\r
577 \r
578   /***************************************************************/\r
579   ModeStackedLayout->addWidget( ModeActiveWidget );\r
580   ModeStackedLayout->addWidget( GroupParameters );\r
581 \r
582   topLayout->addWidget( GroupPlanes );\r
583   topLayout->addLayout( ModeStackedLayout );\r
584   topLayout->addWidget( CheckBoxWidget );\r
585   topLayout->addWidget( GroupButtons );\r
586 \r
587   this->setLayout( topLayout );\r
588 \r
589   // Initializations\r
590   initParam();\r
591 \r
592   // Signals and slots connections\r
593   connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) );\r
594   connect( isActivePlane,  SIGNAL ( toggled ( bool ) ),  this, SLOT( onValueChanged() ) );\r
595   connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) );\r
596   connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );\r
597   connect( buttonDisableAll, SIGNAL( clicked() ), this, SLOT( ClickOnDisableAll() ) );\r
598 \r
599   connect( resetButton,  SIGNAL (clicked() ), this, SLOT( onReset() ) );\r
600   connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;\r
601   connect( SpinBox_X,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
602   connect( SpinBox_Y,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
603   connect( SpinBox_Z,  SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
604   connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
605   connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
606   connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
607   connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ;\r
608 \r
609   connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( int ) ) );\r
610   connect( SpinSliderDistance, SIGNAL( valueChanged( double ) ),  this, SLOT( onValueChanged() ) );\r
611   connect( SpinSliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );\r
612   connect( SpinSliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );\r
613 \r
614   connect( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;\r
615   connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) );\r
616   \r
617   connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;\r
618   connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );\r
619   connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );\r
620   connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );\r
621 \r
622   myBusy = false;\r
623   myIsSelectPlane = false;\r
624   myIsPlaneCreation = false;\r
625   myIsUpdatingControls = false;\r
626   myModel = model;\r
627 \r
628   myModel->getViewer3d()->InitActiveViews();\r
629 \r
630   OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) myModel->getViewManager();\r
631   myInteractor = new OCCViewer_ClipPlaneInteractor( aViewMgr, this );\r
632   connect( myInteractor, SIGNAL( planeClicked( const Handle_AIS_Plane& ) ), SLOT( onPlaneClicked( const Handle_AIS_Plane& ) ) );\r
633   connect( myInteractor, SIGNAL( planeDragged( const Handle_AIS_Plane& ) ), SLOT( onPlaneDragged( const Handle_AIS_Plane& ) ) );\r
634 \r
635   myLocalPlanes = myModel->getClipPlanes();\r
636   synchronize();\r
637 }\r
638 \r
639 /*!\r
640   Destructor\r
641   Destroys the object and frees any allocated resources\r
642 */\r
643 OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg()\r
644 {\r
645   myLocalPlanes.clear();\r
646 }\r
647 \r
648 /*!\r
649   Custom handling of close event: erases preview\r
650 */\r
651 void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )\r
652 {\r
653   erasePreview();\r
654   QDialog::closeEvent( e );\r
655   OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());\r
656   if(v)\r
657     v->onClipping(false);\r
658 }\r
659 \r
660 /*!\r
661   Custom handling of show event: displays preview\r
662 */\r
663 void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )\r
664 {\r
665   QDialog::showEvent( e );\r
666   onPreview( PreviewCheckBox->isChecked() );\r
667 }\r
668 \r
669 /*!\r
670   Custom handling of hide event: erases preview\r
671 */\r
672 void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )\r
673 {\r
674   erasePreview();\r
675   QDialog::hideEvent( e );\r
676   OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());\r
677   if(v)\r
678     v->onClipping(false);\r
679 \r
680 }\r
681 \r
682 /*!\r
683   Initialization of initial values of widgets\r
684 */\r
685 void OCCViewer_ClippingDlg::initParam()\r
686 {\r
687   SpinBox_X->setValue( 0.0 );\r
688   SpinBox_Y->setValue( 0.0 );\r
689   SpinBox_Z->setValue( 0.0 );\r
690 \r
691   SpinBox_Dx->setValue( 1.0 );\r
692   SpinBox_Dy->setValue( 1.0 );\r
693   SpinBox_Dz->setValue( 1.0 );\r
694 \r
695   CBAbsoluteOrientation->setCurrentIndex(0);\r
696 \r
697   SpinSliderDistance->setValue( 0.5 );\r
698   SpinSliderRotation1->setValue( 0 );\r
699   SpinSliderRotation2->setValue( 0 );\r
700   CBRelativeOrientation->setCurrentIndex( 0 );\r
701 \r
702   isActivePlane->setChecked( true );\r
703 }\r
704 \r
705 /*!\r
706   Set plane parameters from widgets.\r
707 */\r
708 void OCCViewer_ClippingDlg::setPlaneParam( OCCViewer_ClipPlane& thePlane )\r
709 {\r
710   OCCViewer_ClipPlane::PlaneMode aMode = currentPlaneMode();\r
711 \r
712   thePlane.Mode = aMode;\r
713 \r
714   if ( aMode == OCCViewer_ClipPlane::Absolute )\r
715   {\r
716     if( qFuzzyIsNull( SpinBox_Dx->value() ) && \r
717         qFuzzyIsNull( SpinBox_Dy->value() ) && \r
718         qFuzzyIsNull( SpinBox_Dz->value() ) ) {\r
719       return;\r
720     }\r
721   }\r
722 \r
723   thePlane.OrientationType = (aMode == OCCViewer_ClipPlane::Absolute)\r
724     ? CBAbsoluteOrientation->currentIndex()\r
725     : CBRelativeOrientation->currentIndex();\r
726 \r
727   // Get XYZ, DXYZ\r
728   if ( aMode == OCCViewer_ClipPlane::Absolute )\r
729   {\r
730     if ( thePlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )\r
731     {\r
732       thePlane.AbsoluteOrientation.Dx = SpinBox_Dx->value();\r
733       thePlane.AbsoluteOrientation.Dy = SpinBox_Dy->value();\r
734       thePlane.AbsoluteOrientation.Dz = SpinBox_Dz->value();\r
735     }\r
736     else\r
737     {\r
738       thePlane.AbsoluteOrientation.IsInvert = SpinBox_Dx->value() < 0.0\r
739                                            || SpinBox_Dy->value() < 0.0\r
740                                            || SpinBox_Dz->value() < 0.0;\r
741     }\r
742 \r
743     thePlane.X = SpinBox_X->value();\r
744     thePlane.Y = SpinBox_Y->value();\r
745     thePlane.Z = SpinBox_Z->value();\r
746   }\r
747   else\r
748   {\r
749     thePlane.RelativeOrientation.Rotation1 = SpinSliderRotation1->value();\r
750     thePlane.RelativeOrientation.Rotation2 = SpinSliderRotation2->value();\r
751 \r
752     double aPlaneDx = 0.0;\r
753     double aPlaneDy = 0.0;\r
754     double aPlaneDz = 0.0;\r
755     double aX = 0.0;\r
756     double aY = 0.0;\r
757     double aZ = 0.0;\r
758 \r
759     OCCViewer_ClipPlane::RelativeToDXYZ( thePlane.OrientationType,\r
760                                          thePlane.RelativeOrientation.Rotation1,\r
761                                          thePlane.RelativeOrientation.Rotation2,\r
762                                          aPlaneDx, aPlaneDy, aPlaneDz );\r
763 \r
764     DistanceToXYZ( myModel->getAISContext(),\r
765                    myModel->trihedronSize(),\r
766                    SpinSliderDistance->value(),\r
767                    aPlaneDx, aPlaneDy, aPlaneDz,\r
768                    aX, aY, aZ );\r
769 \r
770     thePlane.X = aX;\r
771     thePlane.Y = aY;\r
772     thePlane.Z = aZ;\r
773   }\r
774 \r
775   thePlane.IsOn = isActivePlane->isChecked();\r
776 }\r
777 \r
778 /*!\r
779   Synchronize dialog's widgets with data\r
780 */\r
781 void OCCViewer_ClippingDlg::synchronize()\r
782 {\r
783   ComboBoxPlanes->clear();\r
784   int aNbPlanesAbsolute = myLocalPlanes.size();\r
785 \r
786   QString aName;\r
787   for(int i = 1; i<=aNbPlanesAbsolute; i++ ) {\r
788     aName = QString("Plane %1").arg(i);\r
789     ComboBoxPlanes->addItem( aName );\r
790   }\r
791 \r
792   int aPos = ComboBoxPlanes->count() - 1;\r
793   ComboBoxPlanes->setCurrentIndex( aPos );\r
794 \r
795   bool anIsControlsEnable = ( aPos >= 0 );\r
796   if ( anIsControlsEnable ) {\r
797     onSelectPlane( aPos );\r
798   }\r
799   else {\r
800     ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );\r
801     initParam();\r
802   }\r
803   if ( currentPlaneMode() == OCCViewer_ClipPlane::Absolute )\r
804   {\r
805     SpinBox_X->setEnabled( anIsControlsEnable );\r
806     SpinBox_Y->setEnabled( anIsControlsEnable );\r
807     SpinBox_Z->setEnabled( anIsControlsEnable );\r
808     SpinBox_Dx->setEnabled( anIsControlsEnable );\r
809     SpinBox_Dy->setEnabled( anIsControlsEnable );\r
810     SpinBox_Dz->setEnabled( anIsControlsEnable );\r
811     CBAbsoluteOrientation->setEnabled( anIsControlsEnable );\r
812     invertButton->setEnabled( anIsControlsEnable );\r
813     resetButton->setEnabled( anIsControlsEnable );\r
814   }\r
815   else if ( currentPlaneMode() == OCCViewer_ClipPlane::Relative )\r
816   {\r
817     CBRelativeOrientation->setEnabled( anIsControlsEnable );\r
818     SpinSliderDistance->setEnabled( anIsControlsEnable );\r
819     SpinSliderRotation1->setEnabled( anIsControlsEnable );\r
820     SpinSliderRotation2->setEnabled( anIsControlsEnable );\r
821     isActivePlane->setEnabled( anIsControlsEnable );\r
822   }\r
823   isActivePlane->setEnabled( anIsControlsEnable );\r
824 }\r
825 \r
826 /*!\r
827   Displays preview of clipping plane\r
828 */\r
829 void OCCViewer_ClippingDlg::displayPreview()\r
830 {\r
831   if ( myBusy || !isValid() || !myModel)\r
832     return;\r
833 \r
834   Handle(AIS_InteractiveContext) ic = myModel->getAISContext();\r
835   \r
836   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
837 \r
838   for ( int i=0; i < clipPlanesCount(); i++ ) {\r
839     OCCViewer_ClipPlane& aClipPlane = getClipPlane(i);\r
840     if ( aClipPlane.IsOn ) {\r
841       Handle(AIS_Plane) myPreviewPlane;\r
842       double aSize;\r
843       gp_Pnt aBasePnt;\r
844       gp_Dir aNormal;\r
845       clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());\r
846       myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );\r
847       myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );\r
848       myPreviewPlane->SetSize( aSize, aSize );\r
849       ic->SetWidth( myPreviewPlane, 10, false );\r
850       ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );\r
851       ic->SetTransparency( myPreviewPlane, 0.5, false );\r
852       Quantity_Color c = (aCurPlaneIndex == i) ? Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ) : Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB );\r
853       ic->SetColor( myPreviewPlane, c , false );\r
854       ic->Display( myPreviewPlane, 1, 0, false );\r
855       myPreviewPlaneVector.push_back( myPreviewPlane );\r
856     }\r
857   }\r
858   myModel->update();\r
859 \r
860   double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;\r
861   getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);\r
862   gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,\r
863                           (aYmax + aYmin) * 0.5,\r
864                           (aZmax + aZmin) * 0.5 );\r
865   Bnd_Box aMinMax;\r
866   aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
867 \r
868   myInteractor->setPlanes( myPreviewPlaneVector );\r
869   myInteractor->setRotationCenter( aRotationCenter );\r
870   myInteractor->setMinMax( aMinMax );\r
871   myInteractor->setEnabled( true );\r
872 }\r
873 \r
874 void OCCViewer_ClippingDlg::updatePreview() {\r
875   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
876   int count = clipPlanesCount();\r
877   if ( myBusy || \r
878        !isValid() || \r
879        myIsPlaneCreation ||\r
880        !myModel || \r
881        count == 0 || \r
882        (aCurPlaneIndex +1 > count) ||\r
883        !PreviewCheckBox->isChecked())\r
884     return;\r
885   \r
886   Handle(AIS_InteractiveContext) ic = myModel->getAISContext();\r
887   \r
888   OCCViewer_ClipPlane& aClipPlane = getClipPlane(aCurPlaneIndex);\r
889   Handle(AIS_Plane) myPreviewPlane;\r
890 \r
891   if (aClipPlane.IsOn) {\r
892     double aSize;\r
893     gp_Pnt aBasePnt;\r
894     gp_Dir aNormal;\r
895     clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());\r
896     if(myPreviewPlaneVector.size() < clipPlanesCount()) {\r
897       myPreviewPlaneVector.resize(clipPlanesCount());\r
898     }\r
899     myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];\r
900     if(myPreviewPlane.IsNull()) {\r
901       //Plane was not created\r
902       myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );\r
903       myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );\r
904       myPreviewPlane->SetSize( aSize, aSize );\r
905       ic->Display( myPreviewPlane, 1, 0, false );\r
906       ic->SetWidth( myPreviewPlane, 10, false );\r
907       ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );\r
908       ic->SetTransparency( myPreviewPlane, 0.5, false );\r
909       myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane;\r
910     } else {      \r
911       myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) );\r
912       myPreviewPlane->SetCenter( aBasePnt );\r
913       myPreviewPlane->SetSize( aSize, aSize );  \r
914     }\r
915 \r
916     ic->SetColor( myPreviewPlane, Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ), false );\r
917     ic->Update( myPreviewPlane, Standard_False );\r
918   } else {\r
919     if(myPreviewPlaneVector.size() > aCurPlaneIndex ) {\r
920       myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];\r
921       if(ic->IsDisplayed(myPreviewPlane)) {\r
922         ic->Erase( myPreviewPlane, false );\r
923         ic->Remove( myPreviewPlane, false );\r
924       }\r
925       myPreviewPlaneVector[aCurPlaneIndex].Nullify();\r
926     }\r
927   }\r
928   for(int i = 0; i < myPreviewPlaneVector.size(); i++) {\r
929     if( i == aCurPlaneIndex ) continue;\r
930     if(!myPreviewPlaneVector[i].IsNull())\r
931       ic->SetColor( myPreviewPlaneVector[i], Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );\r
932   }\r
933   myModel->update();\r
934 \r
935   double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;\r
936   getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);\r
937   gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,\r
938                           (aYmax + aYmin) * 0.5,\r
939                           (aZmax + aZmin) * 0.5 );\r
940   Bnd_Box aMinMax;\r
941   aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );\r
942 \r
943   myInteractor->setPlanes( myPreviewPlaneVector );\r
944   myInteractor->setRotationCenter( aRotationCenter );\r
945   myInteractor->setMinMax( aMinMax );\r
946 }\r
947 \r
948 /*!\r
949   Erases preview of clipping plane\r
950 */\r
951 void OCCViewer_ClippingDlg::erasePreview()\r
952 {\r
953   if ( !myModel )\r
954     return;\r
955 \r
956   Handle(AIS_InteractiveContext) ic = myModel->getAISContext();\r
957 \r
958   for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) {\r
959   Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i];\r
960     if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {\r
961       ic->Erase( myPreviewPlane, false );\r
962       ic->Remove( myPreviewPlane, false );\r
963       myPreviewPlane.Nullify();\r
964     }\r
965   }\r
966   myPreviewPlaneVector.clear();\r
967   myModel->update();\r
968   myInteractor->setEnabled( false );\r
969 }\r
970 \r
971 /*!\r
972   Return true if plane parameters are valid\r
973 */\r
974 bool OCCViewer_ClippingDlg::isValid()\r
975 {\r
976   return ( SpinBox_Dx->value() !=0 || SpinBox_Dy->value() !=0 || SpinBox_Dz->value() !=0 );\r
977 }\r
978 \r
979 /*!\r
980   Update view after changes\r
981 */\r
982 void OCCViewer_ClippingDlg::updateClipping()\r
983 {\r
984   if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked())\r
985   {\r
986     if (AutoApplyCheckBox->isChecked()) {\r
987       onApply();\r
988     }\r
989     \r
990     if (!PreviewCheckBox->isChecked())\r
991       myModel->update();\r
992     else \r
993       updatePreview();\r
994   }\r
995 }\r
996 \r
997 /*!\r
998   Updates state of user controls.\r
999 */\r
1000 void OCCViewer_ClippingDlg::updateControls()\r
1001 {\r
1002   if ( clipPlanesCount() == 0 )\r
1003   {\r
1004     initParam();\r
1005     return;\r
1006   }\r
1007 \r
1008   int aPlaneIdx = ComboBoxPlanes->currentIndex();\r
1009 \r
1010   OCCViewer_ClipPlane& aPlane = getClipPlane( aPlaneIdx );\r
1011 \r
1012   double aPlaneDx  = 0.0;\r
1013   double aPlaneDy  = 0.0;\r
1014   double aPlaneDz  = 0.0;\r
1015   double aDistance = 0.0;\r
1016   aPlane.OrientationToXYZ( aPlaneDx, aPlaneDy, aPlaneDz );\r
1017 \r
1018   if ( aPlane.Mode == OCCViewer_ClipPlane::Absolute )\r
1019   {\r
1020     ModeStackedLayout->setCurrentIndex( 0 );\r
1021 \r
1022     // Set plane parameters in the dialog\r
1023     SpinBox_X->setValue( aPlane.X );\r
1024     SpinBox_Y->setValue( aPlane.Y );\r
1025     SpinBox_Z->setValue( aPlane.Z );\r
1026     SpinBox_Dx->setValue( aPlaneDx );\r
1027     SpinBox_Dy->setValue( aPlaneDy );\r
1028     SpinBox_Dz->setValue( aPlaneDz );\r
1029     CBAbsoluteOrientation->setCurrentIndex( aPlane.OrientationType );\r
1030     onOrientationAbsoluteChanged( aPlane.OrientationType );\r
1031   }\r
1032   else if( aPlane.Mode == OCCViewer_ClipPlane::Relative )\r
1033   {\r
1034     ModeStackedLayout->setCurrentIndex( 1 );\r
1035 \r
1036     // Set plane parameters in the dialog\r
1037     SpinSliderRotation1->setValue( int( aPlane.RelativeOrientation.Rotation1 ) );\r
1038     SpinSliderRotation2->setValue( int( aPlane.RelativeOrientation.Rotation2 ) );\r
1039 \r
1040     XYZToDistance( myModel->getAISContext(),\r
1041                    myModel->trihedronSize(),\r
1042                    aPlane.X, aPlane.Y, aPlane.Z,\r
1043                    aPlaneDx, aPlaneDy, aPlaneDz,\r
1044                    aDistance );\r
1045 \r
1046     SpinSliderDistance->setValue( aDistance );\r
1047 \r
1048     CBRelativeOrientation->setCurrentIndex( aPlane.OrientationType );\r
1049     onOrientationRelativeChanged( aPlane.OrientationType );\r
1050   }\r
1051 \r
1052   isActivePlane->setChecked( aPlane.IsOn );\r
1053 }\r
1054 \r
1055 /*!\r
1056   SLOT on new button click: create a new clipping plane\r
1057 */\r
1058 void OCCViewer_ClippingDlg::ClickOnNew()\r
1059 {\r
1060   OCCViewer_ClipPlane aClipPlane;\r
1061 \r
1062   // init controls state\r
1063   myIsUpdatingControls = true;\r
1064   initParam();\r
1065   myIsUpdatingControls = false;\r
1066 \r
1067   // init plane according to the state of controls\r
1068   setPlaneParam( aClipPlane );\r
1069 \r
1070   // add plane\r
1071   myLocalPlanes.push_back( aClipPlane );\r
1072   synchronize();\r
1073 }\r
1074 \r
1075 /*!\r
1076   SLOT on delete button click: Delete selected clipping plane\r
1077 */\r
1078 void OCCViewer_ClippingDlg::ClickOnDelete()\r
1079 {\r
1080   int aPlaneIndex = ComboBoxPlanes->currentIndex();\r
1081   if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount()))\r
1082     return;\r
1083 \r
1084   myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex);\r
1085 \r
1086   Handle(AIS_InteractiveContext) ic = myModel->getAISContext();\r
1087 \r
1088   if(aPlaneIndex+1 <= myPreviewPlaneVector.size()) {\r
1089     Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[aPlaneIndex];\r
1090     if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {\r
1091       ic->Erase( myPreviewPlane, false );\r
1092       ic->Remove( myPreviewPlane, false );\r
1093     }\r
1094     myPreviewPlaneVector.erase(myPreviewPlaneVector.begin() + aPlaneIndex);\r
1095   }\r
1096   synchronize();\r
1097   if (AutoApplyCheckBox->isChecked()) {\r
1098     onApply();\r
1099   }\r
1100   myModel->update();\r
1101 }\r
1102 \r
1103 /*!\r
1104   SLOT on disable all button click: Restore initial state of viewer,\r
1105   erase all clipping planes\r
1106 */\r
1107 void OCCViewer_ClippingDlg::ClickOnDisableAll()\r
1108 {\r
1109   AutoApplyCheckBox->setChecked (false);\r
1110   int aClipPlanesCount = clipPlanesCount();\r
1111   for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++)\r
1112   {\r
1113     OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex);\r
1114     aPlane.IsOn = false;\r
1115   }\r
1116   erasePreview();\r
1117   isActivePlane->setChecked(false);\r
1118   myModel->setClipPlanes(myLocalPlanes);\r
1119   myModel->update();\r
1120 }\r
1121 \r
1122 /*!\r
1123   SLOT on ok button click: sets cutting plane and closes dialog\r
1124 */\r
1125 void OCCViewer_ClippingDlg::ClickOnOk()\r
1126 {\r
1127   onApply();\r
1128   ClickOnClose();\r
1129 }\r
1130 \r
1131 /*!\r
1132   SLOT on Apply button click: sets cutting plane and update viewer\r
1133 */\r
1134 void OCCViewer_ClippingDlg::ClickOnApply()\r
1135 {\r
1136   onApply();\r
1137   myModel->update();\r
1138 }\r
1139 \r
1140 /*!\r
1141   SLOT on close button click: erases preview and rejects dialog\r
1142 */\r
1143 void OCCViewer_ClippingDlg::ClickOnClose()\r
1144 {\r
1145   erasePreview();\r
1146   OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());\r
1147   if(v)\r
1148     v->onClipping(false);\r
1149 }\r
1150 \r
1151 /*!\r
1152   SLOT on help button click: opens a help page\r
1153 */\r
1154 void OCCViewer_ClippingDlg::ClickOnHelp()\r
1155 {\r
1156   SUIT_Application* app = SUIT_Session::session()->activeApplication();\r
1157   if ( app )\r
1158     app->onHelpContextModule( "GUI", "occ_3d_viewer_page.html", "clipping_planes" );\r
1159 }\r
1160 \r
1161 /*!\r
1162   Set absolute mode of clipping plane\r
1163 */\r
1164 void OCCViewer_ClippingDlg::onModeAbsolute()\r
1165 {\r
1166   myIsPlaneCreation = true;\r
1167   ModeStackedLayout->setCurrentIndex(0);\r
1168   ClickOnNew();\r
1169   myIsPlaneCreation = false;\r
1170   updateClipping();\r
1171 }\r
1172 \r
1173 /*!\r
1174   Set relative mode of clipping plane\r
1175 */\r
1176 void OCCViewer_ClippingDlg::onModeRelative()\r
1177 {\r
1178   myIsPlaneCreation = true;\r
1179   ModeStackedLayout->setCurrentIndex(1);\r
1180   ClickOnNew();\r
1181   myIsPlaneCreation = false;\r
1182   SetCurrentPlaneParam();\r
1183   updateClipping();\r
1184 }\r
1185 \r
1186 /*!\r
1187   SLOT: called on value of clipping plane changed\r
1188 */\r
1189 void OCCViewer_ClippingDlg::onValueChanged()\r
1190 {\r
1191   if ( myIsUpdatingControls )\r
1192   {\r
1193     return;\r
1194   }\r
1195 \r
1196   SetCurrentPlaneParam();\r
1197 \r
1198   if ( myIsSelectPlane )\r
1199   {\r
1200     return;\r
1201   }\r
1202 \r
1203   updateClipping();\r
1204 }\r
1205 \r
1206 /*!\r
1207   Set current parameters of selected plane\r
1208 */\r
1209 void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )\r
1210 {\r
1211   if ( clipPlanesCount() == 0 )\r
1212   {\r
1213     return;\r
1214   }\r
1215 \r
1216   OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex );\r
1217 \r
1218   myIsSelectPlane = true;\r
1219   updateControls();\r
1220   ComboBoxPlanes->setCurrentIndex( theIndex );\r
1221   myIsSelectPlane = false;\r
1222 }\r
1223 \r
1224 /*!\r
1225   Restore parameters of selected plane\r
1226 */\r
1227 void OCCViewer_ClippingDlg::SetCurrentPlaneParam()\r
1228 {\r
1229   if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy )\r
1230   {\r
1231     return;\r
1232   }\r
1233 \r
1234   int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
1235 \r
1236   OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );\r
1237 \r
1238   setPlaneParam( aPlane );\r
1239 }\r
1240 \r
1241 /*!\r
1242   SLOT on reset button click: sets default values\r
1243 */\r
1244 void OCCViewer_ClippingDlg::onReset()\r
1245 {\r
1246   myBusy = true;\r
1247   SpinBox_X->setValue(0);\r
1248   SpinBox_Y->setValue(0);\r
1249   SpinBox_Z->setValue(0);\r
1250   myBusy = false;\r
1251 \r
1252   updateClipping();\r
1253 }\r
1254 \r
1255 /*!\r
1256   SLOT on invert button click: inverts normal of cutting plane\r
1257 */\r
1258 void OCCViewer_ClippingDlg::onInvert()\r
1259 {\r
1260   double Dx = SpinBox_Dx->value();\r
1261   double Dy = SpinBox_Dy->value();\r
1262   double Dz = SpinBox_Dz->value();\r
1263 \r
1264   myBusy = true;\r
1265   SpinBox_Dx->setValue( -Dx );\r
1266   SpinBox_Dy->setValue( -Dy );\r
1267   SpinBox_Dz->setValue( -Dz );\r
1268   myBusy = false;\r
1269 \r
1270   if ( clipPlanesCount() != 0 )\r
1271   {\r
1272     int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
1273     OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );\r
1274     aPlane.AbsoluteOrientation.IsInvert = !aPlane.AbsoluteOrientation.IsInvert;\r
1275   }\r
1276   updateClipping();\r
1277 }\r
1278 \r
1279 /*!\r
1280   SLOT: called on orientation of clipping plane in absolute mode changed\r
1281 */\r
1282 void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )\r
1283 {\r
1284   bool isUserMode = (mode==0);\r
1285 \r
1286   TextLabelX->setEnabled( isUserMode );\r
1287   TextLabelY->setEnabled( isUserMode );\r
1288   TextLabelZ->setEnabled( isUserMode );\r
1289 \r
1290   SpinBox_X->setEnabled( isUserMode );\r
1291   SpinBox_Y->setEnabled( isUserMode );\r
1292   SpinBox_Z->setEnabled( isUserMode );\r
1293 \r
1294   TextLabelDx->setEnabled( isUserMode );\r
1295   TextLabelDy->setEnabled( isUserMode );\r
1296   TextLabelDz->setEnabled( isUserMode );\r
1297 \r
1298   SpinBox_Dx->setEnabled( isUserMode );\r
1299   SpinBox_Dy->setEnabled( isUserMode );\r
1300   SpinBox_Dz->setEnabled( isUserMode );\r
1301 \r
1302   if ( !isUserMode ) {\r
1303 \r
1304     double aDx = 0, aDy = 0, aDz = 0;\r
1305 \r
1306     if ( mode == 1 )\r
1307     {\r
1308       aDz = 1;\r
1309       TextLabelZ->setEnabled( true );\r
1310       SpinBox_Z->setEnabled( true );\r
1311       SpinBox_Z->setFocus();\r
1312     }\r
1313     else if ( mode == 2 )\r
1314     {\r
1315       aDx = 1;\r
1316       TextLabelX->setEnabled( true );\r
1317       SpinBox_X->setEnabled( true );\r
1318       SpinBox_X->setFocus();\r
1319     }\r
1320     else if ( mode == 3 )\r
1321     {\r
1322       aDy = 1;\r
1323       TextLabelY->setEnabled( true );\r
1324       SpinBox_Y->setEnabled( true );\r
1325       SpinBox_Y->setFocus();\r
1326     }\r
1327     \r
1328     int aCurPlaneIndex = ComboBoxPlanes->currentIndex();\r
1329     OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );\r
1330     if ( aPlane.AbsoluteOrientation.IsInvert == true )\r
1331     {\r
1332       aDx = -aDx;\r
1333       aDy = -aDy;\r
1334       aDz = -aDz;\r
1335     }\r
1336     \r
1337     myBusy = true;\r
1338     SpinBox_Dx->setValue( aDx );\r
1339     SpinBox_Dy->setValue( aDy );\r
1340     SpinBox_Dz->setValue( aDz );\r
1341     myBusy = false;\r
1342   }\r
1343 \r
1344   if ( !myIsUpdatingControls )\r
1345   {\r
1346     SetCurrentPlaneParam();\r
1347     updateClipping();\r
1348   }\r
1349 }\r
1350 \r
1351 /*!\r
1352   SLOT: called on orientation of clipping plane in relative mode changed\r
1353 */\r
1354 void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)\r
1355 {\r
1356   if ( clipPlanesCount() == 0 )\r
1357     return;\r
1358   \r
1359   if ( theItem == 0 ) {\r
1360     TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );\r
1361     TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );\r
1362   }\r
1363   else if ( theItem == 1 ) {\r
1364     TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) );\r
1365     TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) );\r
1366   }\r
1367   else if ( theItem == 2 ) {\r
1368     TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) );\r
1369     TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );\r
1370   }\r
1371 \r
1372   if ( !myIsUpdatingControls )\r
1373   {\r
1374     if( (QComboBox*)sender() == CBRelativeOrientation )\r
1375     {\r
1376       SetCurrentPlaneParam();\r
1377     }\r
1378 \r
1379     updateClipping();\r
1380   }\r
1381 }\r
1382 \r
1383 /*!\r
1384   SLOT: called on preview check box toggled\r
1385 */\r
1386 void OCCViewer_ClippingDlg::onPreview( bool on )\r
1387 {\r
1388   erasePreview();\r
1389   if ( on ) \r
1390     displayPreview();\r
1391 }\r
1392 \r
1393 /*!\r
1394   SLOT: called on Auto Apply check box toggled\r
1395 */\r
1396 void OCCViewer_ClippingDlg::onAutoApply( bool toggled )\r
1397 {\r
1398   if ( toggled ) {\r
1399     onApply();\r
1400     myModel->update();\r
1401   }  \r
1402 }\r
1403 \r
1404 /*!\r
1405   SLOT on Apply button click: sets cutting plane\r
1406 */\r
1407 void OCCViewer_ClippingDlg::onApply()\r
1408 {\r
1409   if ( myBusy )\r
1410     return;\r
1411   myIsSelectPlane = true;\r
1412 \r
1413   qApp->processEvents();\r
1414   QApplication::setOverrideCursor( Qt::WaitCursor );\r
1415   qApp->processEvents();\r
1416 \r
1417   myModel->setClipPlanes(myLocalPlanes);\r
1418 \r
1419   QApplication::restoreOverrideCursor();\r
1420   myIsSelectPlane = false;\r
1421 }\r
1422 \r
1423 /*!\r
1424   SLOT: Called when clip plane is clicked in viewer.\r
1425 */\r
1426 void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane )\r
1427 {\r
1428   for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )\r
1429   {\r
1430     Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );\r
1431     if ( aPlane != thePlane )\r
1432     {\r
1433       continue;\r
1434     }\r
1435 \r
1436     ComboBoxPlanes->setCurrentIndex( aPlaneIt );\r
1437 \r
1438     break;\r
1439   }\r
1440 }\r
1441 \r
1442 /*!\r
1443   SLOT: Called when clip plane is changed by dragging in viewer.\r
1444 */\r
1445 void OCCViewer_ClippingDlg::onPlaneDragged( const Handle(AIS_Plane)& thePlane )\r
1446 {\r
1447   for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )\r
1448   {\r
1449     Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );\r
1450     if ( aPlane != thePlane )\r
1451     {\r
1452       continue;\r
1453     }\r
1454 \r
1455     OCCViewer_ClipPlane& aClipPlane = getClipPlane( aPlaneIt );\r
1456 \r
1457     gp_Pln aPln = thePlane->Component()->Pln();\r
1458     const gp_Pnt& aPlaneP = aPln.Location();\r
1459     const gp_Dir& aPlaneN = aPln.Axis().Direction();\r
1460 \r
1461     aClipPlane.X  = aPlaneP.X();\r
1462     aClipPlane.Y  = aPlaneP.Y();\r
1463     aClipPlane.Z  = aPlaneP.Z();\r
1464 \r
1465     if ( aClipPlane.Mode == OCCViewer_ClipPlane::Absolute )\r
1466     {\r
1467       if ( aClipPlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )\r
1468       {\r
1469         aClipPlane.AbsoluteOrientation.Dx = aPlaneN.X();\r
1470         aClipPlane.AbsoluteOrientation.Dy = aPlaneN.Y();\r
1471         aClipPlane.AbsoluteOrientation.Dz = aPlaneN.Z();\r
1472       }\r
1473     }\r
1474     else\r
1475     {\r
1476       OCCViewer_ClipPlane::DXYZToRelative( aPlaneN.X(), aPlaneN.Y(), aPlaneN.Z(),\r
1477                                            aClipPlane.OrientationType,\r
1478                                            aClipPlane.RelativeOrientation.Rotation1,\r
1479                                            aClipPlane.RelativeOrientation.Rotation2 );\r
1480     }\r
1481 \r
1482     myIsUpdatingControls = true;\r
1483     updateControls();\r
1484     myIsUpdatingControls = false;\r
1485 \r
1486     if ( AutoApplyCheckBox->isChecked() )\r
1487     {\r
1488       onApply();\r
1489     }\r
1490 \r
1491     break;\r
1492   }\r
1493 }\r
1494 \r
1495 OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx )\r
1496 {\r
1497   return myLocalPlanes[theIdx];\r
1498 }\r
1499 \r
1500 int OCCViewer_ClippingDlg::clipPlanesCount()\r
1501 {\r
1502   return myLocalPlanes.size();\r
1503 }\r
1504 \r
1505 OCCViewer_ClipPlane::PlaneMode OCCViewer_ClippingDlg::currentPlaneMode() const
1506 {
1507   return ModeStackedLayout->currentIndex() == 0
1508     ? OCCViewer_ClipPlane::Absolute 
1509     : OCCViewer_ClipPlane::Relative;
1510 }