1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "OCCViewer_ClippingDlg.h"
25 #include <QtxDoubleSpinBox.h>
26 #include <QtxDoubleSpinSlider.h>
27 #include <QtxIntSpinSlider.h>
28 #include <QtxAction.h>
30 #include "SUIT_Session.h"
31 #include "SUIT_ViewWindow.h"
32 #include "SUIT_ViewManager.h"
33 #include "OCCViewer_ClipPlane.h"
34 #include "OCCViewer_ViewWindow.h"
35 #include "OCCViewer_ViewPort3d.h"
36 #include "OCCViewer_ViewModel.h"
37 #include "OCCViewer_ViewManager.h"
38 #include "OCCViewer_ClipPlaneInteractor.h"
40 #include <Basics_OCCTVersion.hxx>
42 #include <V3d_View.hxx>
43 #include <Visual3d_View.hxx>
44 #include <Geom_Plane.hxx>
45 #include <Prs3d_Presentation.hxx>
46 #include <Prs3d_PlaneAspect.hxx>
47 #include <AIS_ListIteratorOfListOfInteractive.hxx>
48 #include <AIS_ListOfInteractive.hxx>
49 #include <AIS_InteractiveObject.hxx>
50 #include <AIS_InteractiveContext.hxx>
51 #if OCC_VERSION_LARGE > 0x06080000
52 #include <Prs3d_Drawer.hxx>
54 #include <AIS_Drawer.hxx>
56 #include <IntAna_IntConicQuad.hxx>
62 #include <QApplication>
64 #include <QHBoxLayout>
65 #include <QVBoxLayout>
66 #include <QGridLayout>
68 #include <QPushButton>
71 #include <QStackedLayout>
75 /**********************************************************************************
76 ************************ Internal functions ************************
77 *********************************************************************************/
79 void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic,
80 double theDefaultSize,
88 double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
89 aXMin = aYMin = aZMin = DBL_MAX;
90 aXMax = aYMax = aZMax = -DBL_MAX;
93 AIS_ListOfInteractive aList;
94 ic->DisplayedObjects( aList );
95 for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) {
96 Handle(AIS_InteractiveObject) anObj = it.Value();
97 if ( !anObj.IsNull() && anObj->HasPresentation() &&
98 !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) {
99 Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
100 if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) {
102 double xmin, ymin, zmin, xmax, ymax, zmax;
103 #if OCC_VERSION_LARGE > 0x06070100
104 Bnd_Box aBox = aPrs->MinMaxValues();
105 xmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X();
106 ymin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y();
107 zmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Z();
108 xmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().X();
109 ymax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Y();
110 zmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Z();
112 aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );
114 aXMin = qMin( aXMin, xmin ); aXMax = qMax( aXMax, xmax );
115 aYMin = qMin( aYMin, ymin ); aYMax = qMax( aYMax, ymax );
116 aZMin = qMin( aZMin, zmin ); aZMax = qMax( aZMax, zmax );
122 if(theDefaultSize == 0.0)
123 theDefaultSize = 100.;
124 aXMin = aYMin = aZMin = -theDefaultSize;
125 aXMax = aYMax = aZMax = theDefaultSize;
127 theXMin = aXMin;theYMin = aYMin;theZMin = aZMin;
128 theXMax = aXMax;theYMax = aYMax;theZMax = aZMax;
132 Compute the point of bounding box and current clipping plane
134 void ComputeBoundsParam( const double theBounds[6],
135 const double theDirection[3],
137 double& theMaxBoundPrj,
138 double& theMinBoundPrj )
140 double aEnlargeBounds[6];
142 // Enlarge bounds in order to avoid conflicts of precision
143 for(int i = 0; i < 6; i += 2)
145 static double EPS = 1.0E-3;
146 double aDelta = (theBounds[i+1] - theBounds[i])*EPS;
147 aEnlargeBounds[i ] = theBounds[i ] - aDelta;
148 aEnlargeBounds[i+1] = theBounds[i+1] + aDelta;
151 double aBoundPoints[8][3] = { { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[4] },
152 { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[4] },
153 { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[4] },
154 { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[4] },
155 { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[5] },
156 { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[5] },
157 { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[5] },
158 { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[5] } };
161 theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1]
162 + theDirection[2] * aBoundPoints[aMaxId][2];
163 theMinBoundPrj = theMaxBoundPrj;
164 for(int i = 1; i < 8; i++) {
165 double aTmp = theDirection[0] * aBoundPoints[i][0] + theDirection[1] * aBoundPoints[i][1]
166 + theDirection[2] * aBoundPoints[i][2];
167 if(theMaxBoundPrj < aTmp) {
168 theMaxBoundPrj = aTmp;
171 if(theMinBoundPrj > aTmp) {
172 theMinBoundPrj = aTmp;
175 double *aMinPnt = aBoundPoints[aMaxId];
176 theMinPnt[0] = aMinPnt[0];
177 theMinPnt[1] = aMinPnt[1];
178 theMinPnt[2] = aMinPnt[2];
182 Compute the position of current plane by distance
184 void DistanceToPosition( const double theBounds[6],
185 const double theDirection[3],
186 const double theDist,
189 double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
190 ComputeBoundsParam( theBounds, theDirection, aMinPnt, aMaxBoundPrj, aMinBoundPrj );
191 double aLength = (aMaxBoundPrj - aMinBoundPrj) * theDist;
192 thePos[0] = aMinPnt[0] - theDirection[0] * aLength;
193 thePos[1] = aMinPnt[1] - theDirection[1] * aLength;
194 thePos[2] = aMinPnt[2] - theDirection[2] * aLength;
198 Compute the parameters of clipping plane
200 bool ComputeClippingPlaneParameters( const Handle(AIS_InteractiveContext)& theIC,
201 const double theDefaultSize,
202 const double theNormal[3],
203 const double theDist,
204 double theOrigin[3] )
206 double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
208 getMinMaxFromContext( theIC, theDefaultSize, aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5] );
210 DistanceToPosition( aBounds, theNormal, theDist, theOrigin );
215 \brief Converts relative plane parameters to absolute.
216 \param theIC [in] the interactive context.
217 \param theDefaultSize [in] the default trihedron size.
218 \param theDistance [in] the plane distance relative to minimum corner of model boundaries.
219 \param theDX [in] x component of plane direction.
220 \param theDY [in] y component of plane direction.
221 \param theDZ [in] z component of plane direction.
222 \param theX [out] x coordinate of plane origin.
223 \param theY [out] y coordinate of plane origin.
224 \param theZ [out] z coordinate of plane origin.
226 bool DistanceToXYZ ( const Handle(AIS_InteractiveContext)& theIC,
227 const double theDefaultSize,
228 const double theDistance,
236 double aNormal[3] = { theDX, theDY, theDZ };
237 double anOrigin[3] = { 0.0, 0.0, 0.0 };
239 bool anIsOk = ComputeClippingPlaneParameters( theIC, theDefaultSize, aNormal, theDistance, anOrigin );
254 \brief Converts absolute position and direction to bounding box distance.
255 \param theIC [in] the interactive context.
256 \param theDefaultSize [in] the default trihedron size.
257 \param theX [in] x coordinate of plane origin.
258 \param theY [in] y coordinate of plane origin.
259 \param theZ [in] z coordinate of plane origin.
260 \param theDX [in] x component of plane direction.
261 \param theDY [in] y component of plane direction.
262 \param theDZ [in] z component of plane direction.
263 \param theDistance [out] the plane distance relative to minimum corner of model boundaries.
265 void XYZToDistance ( const Handle(AIS_InteractiveContext)& theIC,
266 const double theDefaultSize,
273 double& theDistance )
275 gp_Pnt aPlaneP( theX, theY, theZ );
276 gp_Dir aPlaneN( theDX, theDY, theDZ );
278 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
280 getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
283 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
285 gp_Trsf aRelativeTransform;
286 aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) );
287 Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform );
289 aRelativeBounds.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
291 double aLength = aZmax - aZmin;
292 double aDistance = aZmax;
294 double aRelativeDistance = aLength > 0.01 ? aDistance / aLength : 0.0;
295 aRelativeDistance = qMin( aRelativeDistance, aLength );
296 aRelativeDistance = qMax( aRelativeDistance, 0.0 );
297 theDistance = aRelativeDistance;
301 Compute clipping plane size base point and normal
304 void clipPlaneParams(OCCViewer_ClipPlane& theClipPlane, Handle(AIS_InteractiveContext) theContext,
305 double& theSize, gp_Pnt& theBasePnt, gp_Dir& theNormal, double defaultSize) {
306 double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
307 aXMin = aYMin = aZMin = DBL_MAX;
308 aXMax = aYMax = aZMax = -DBL_MAX;
310 getMinMaxFromContext(theContext,defaultSize,aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
313 double aNormalX = 0.0;
314 double aNormalY = 0.0;
315 double aNormalZ = 0.0;
316 theClipPlane.OrientationToXYZ( aNormalX, aNormalY, aNormalZ );
317 gp_Pnt aBasePnt( theClipPlane.X, theClipPlane.Y, theClipPlane.Z );
318 gp_Dir aNormal( aNormalX, aNormalY, aNormalZ );
320 // compute clipping plane size
321 gp_Pnt aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
322 double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2;
325 // compute clipping plane center ( redefine the base point )
326 IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
328 intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
330 if ( intersector.IsDone() && intersector.NbPoints() == 1 )
331 aBasePnt = intersector.Point( 1 );
334 theBasePnt = aBasePnt;
339 /*********************************************************************************
340 ********************* class OCCViewer_ClippingDlg *********************
341 *********************************************************************************/
344 \param view - view window
345 \param parent - parent widget
347 OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model)
348 : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint )
350 setObjectName( "OCCViewer_ClippingDlg" );
353 setWindowTitle( tr( "Clipping" ) );
355 setAttribute (Qt::WA_DeleteOnClose, true);
357 QVBoxLayout* topLayout = new QVBoxLayout( this );
358 topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
360 /***************************************************************/
361 // Controls for selecting, creating, deleting planes
362 QGroupBox* GroupPlanes = new QGroupBox( tr("CLIPPING_PLANES"), this );
363 QHBoxLayout* GroupPlanesLayout = new QHBoxLayout( GroupPlanes );
364 ComboBoxPlanes = new QComboBox( GroupPlanes );
365 isActivePlane = new QCheckBox( tr("IS_ACTIVE_PLANE"), this );
366 buttonNew = new QPushButton( tr("BTN_NEW"), GroupPlanes );
367 buttonDelete = new QPushButton( tr("BTN_DELETE"), GroupPlanes );
368 buttonDisableAll = new QPushButton( tr("BTN_DISABLE_ALL"), GroupPlanes );
369 MenuMode = new QMenu( "MenuMode", buttonNew );
370 MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );
371 MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );
372 buttonNew->setMenu( MenuMode );
374 GroupPlanesLayout->addWidget( ComboBoxPlanes );
375 GroupPlanesLayout->addWidget( isActivePlane );
376 GroupPlanesLayout->addWidget( buttonNew );
377 GroupPlanesLayout->addWidget( buttonDelete );
378 GroupPlanesLayout->addWidget( buttonDisableAll );
380 ModeStackedLayout = new QStackedLayout();
382 /********************** Mode Absolute **********************/
383 /* Controls for absolute mode of clipping plane:
384 X, Y, Z - coordinates of the intersection of cutting plane and the three axes
385 Dx, Dy, Dz - components of normal to the cutting plane
386 Orientation - direction of cutting plane
388 const double min = -1e+7;
389 const double max = 1e+7;
390 const double step = 5;
391 const int precision = -7;
394 QGroupBox* GroupAbsolutePoint = new QGroupBox( this );
395 GroupAbsolutePoint->setObjectName( "GroupPoint" );
396 GroupAbsolutePoint->setTitle( tr("BASE_POINT") );
397 QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint );
398 GroupPointLayout->setAlignment( Qt::AlignTop );
399 GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 );
401 TextLabelX = new QLabel( GroupAbsolutePoint );
402 TextLabelX->setObjectName( "TextLabelX" );
403 TextLabelX->setText( tr("X:") );
404 GroupPointLayout->addWidget( TextLabelX, 0, 0 );
406 SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
407 SpinBox_X->setObjectName("SpinBox_X" );
408 SpinBox_X->setPrecision( precision );
409 GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
411 TextLabelY = new QLabel( GroupAbsolutePoint );
412 TextLabelY->setObjectName( "TextLabelY" );
413 TextLabelY->setText( tr("Y:") );
414 GroupPointLayout->addWidget( TextLabelY, 0, 2 );
416 SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
417 SpinBox_Y->setObjectName("SpinBox_Y" );
418 SpinBox_Y->setPrecision( precision );
419 GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
421 TextLabelZ = new QLabel( GroupAbsolutePoint );
422 TextLabelZ->setObjectName( "TextLabelZ" );
423 TextLabelZ->setText( tr("Z:") );
424 GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
426 SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
427 SpinBox_Z->setObjectName("SpinBox_Z" );
428 SpinBox_Z->setPrecision( precision );
429 GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
431 resetButton = new QPushButton( GroupAbsolutePoint );
432 resetButton->setObjectName( "resetButton" );
433 resetButton->setText( tr( "RESET" ) );
434 GroupPointLayout->addWidget( resetButton, 0, 6 );
437 GroupAbsoluteDirection = new QGroupBox( this );
438 GroupAbsoluteDirection->setObjectName( "GroupDirection" );
439 GroupAbsoluteDirection->setTitle( tr("DIRECTION") );
440 QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection );
441 GroupDirectionLayout->setAlignment( Qt::AlignTop );
442 GroupDirectionLayout->setSpacing( 6 );
443 GroupDirectionLayout->setMargin( 11 );
445 TextLabelDx = new QLabel( GroupAbsoluteDirection );
446 TextLabelDx->setObjectName( "TextLabelDx" );
447 TextLabelDx->setText( tr("Dx:") );
448 GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
450 SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
451 SpinBox_Dx->setObjectName("SpinBox_Dx" );
452 SpinBox_Dx->setPrecision( precision );
453 GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
455 TextLabelDy = new QLabel( GroupAbsoluteDirection );
456 TextLabelDy->setObjectName( "TextLabelDy" );
457 TextLabelDy->setText( tr("Dy:") );
458 GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
460 SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
461 SpinBox_Dy->setObjectName("SpinBox_Dy" );
462 SpinBox_Dy->setPrecision( precision );
463 GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
465 TextLabelDz = new QLabel( GroupAbsoluteDirection );
466 TextLabelDz->setObjectName( "TextLabelDz" );
467 TextLabelDz->setText( tr("Dz:") );
468 GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
470 SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
471 SpinBox_Dz->setObjectName("SpinBox_Dz" );
472 SpinBox_Dz->setPrecision( precision );
473 GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
475 invertButton = new QPushButton( GroupAbsoluteDirection );
476 invertButton->setObjectName( "invertButton" );
477 invertButton->setText( tr( "INVERT" ) );
478 GroupDirectionLayout->addWidget( invertButton, 0, 6 );
480 CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection );
481 CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" );
482 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) );
483 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) );
484 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) );
485 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) );
486 GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 );
488 QVBoxLayout* ModeActiveLayout = new QVBoxLayout();
489 ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 );
490 ModeActiveLayout->addWidget( GroupAbsolutePoint );
491 ModeActiveLayout->addWidget( GroupAbsoluteDirection );
493 QWidget* ModeActiveWidget = new QWidget( this );
494 ModeActiveWidget->setLayout( ModeActiveLayout );
496 /********************** Mode Relative **********************/
497 /* Controls for relative mode of clipping plane:
498 Distance - Value from 0 to 1.
499 Specifies the distance from the minimum value in a given direction of bounding box to the current position
500 Rotation1, Rotation2 - turn angles of cutting plane in given directions
501 Orientation - direction of cutting plane
503 QGroupBox* GroupParameters = new QGroupBox( tr("PARAMETERS"), this );
504 QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );
505 GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 );
507 TextLabelOrientation = new QLabel( tr("ORIENTATION"), GroupParameters);
508 TextLabelOrientation->setObjectName( "TextLabelOrientation" );
509 GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
511 CBRelativeOrientation = new QComboBox(GroupParameters);
512 CBRelativeOrientation->setObjectName( "RelativeOrientation" );
513 CBRelativeOrientation->addItem( tr("ALONG_XY") );
514 CBRelativeOrientation->addItem( tr("ALONG_YZ") );
515 CBRelativeOrientation->addItem( tr("ALONG_ZX") );
516 GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );
518 TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters );
519 TextLabelDistance->setObjectName( "TextLabelDistance" );
520 GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 );
522 SpinSliderDistance = new QtxDoubleSpinSlider( 0., 1., 0.01, GroupParameters );
523 SpinSliderDistance->setObjectName( "SpinSliderDistance" );
524 SpinSliderDistance->setPrecision( precision );
525 QFont fnt = SpinSliderDistance->font(); fnt.setBold( true ); SpinSliderDistance->setFont( fnt );
526 GroupParametersLayout->addWidget( SpinSliderDistance, 1, 1 );
528 QString aUnitRot = "\xB0";
530 TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters );
531 TextLabelRotation1->setObjectName( "TextLabelRotation1" );
532 GroupParametersLayout->addWidget( TextLabelRotation1, 2, 0 );
534 SpinSliderRotation1 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );
535 SpinSliderRotation1->setObjectName( "SpinSliderRotation1" );
536 SpinSliderRotation1->setUnit( aUnitRot );
537 SpinSliderRotation1->setFont( fnt );
538 GroupParametersLayout->addWidget( SpinSliderRotation1, 2, 1 );
540 TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);
541 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
542 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
543 GroupParametersLayout->addWidget( TextLabelRotation2, 3, 0 );
545 SpinSliderRotation2 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );
546 SpinSliderRotation2->setObjectName( "SpinSliderRotation2" );
547 SpinSliderRotation2->setUnit( aUnitRot );
548 SpinSliderRotation2->setFont( fnt );
549 GroupParametersLayout->addWidget( SpinSliderRotation2, 3, 1 );
551 /***************************************************************/
552 QGroupBox* CheckBoxWidget = new QGroupBox( this );
553 QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget );
555 PreviewCheckBox = new QCheckBox( tr("PREVIEW"), CheckBoxWidget );
556 PreviewCheckBox->setObjectName( "PreviewCheckBox" );
557 PreviewCheckBox->setChecked( true );
558 CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter );
560 AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget );
561 AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" );
562 CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter );
564 /***************************************************************/
565 QGroupBox* GroupButtons = new QGroupBox( this );
566 QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );
567 GroupButtonsLayout->setAlignment( Qt::AlignTop );
568 GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );
570 buttonOk = new QPushButton( GroupButtons );
571 buttonOk->setObjectName( "buttonOk" );
572 buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE" ) );
573 buttonOk->setAutoDefault( TRUE );
574 buttonOk->setDefault( TRUE );
575 GroupButtonsLayout->addWidget( buttonOk );
577 buttonApply = new QPushButton( GroupButtons );
578 buttonApply->setObjectName( "buttonApply" );
579 buttonApply->setText( tr( "BUT_APPLY" ) );
580 buttonApply->setAutoDefault( TRUE );
581 buttonApply->setDefault( TRUE );
582 GroupButtonsLayout->addWidget( buttonApply );
584 GroupButtonsLayout->addStretch();
586 buttonClose = new QPushButton( GroupButtons );
587 buttonClose->setObjectName( "buttonClose" );
588 buttonClose->setText( tr( "BUT_CLOSE" ) );
589 buttonClose->setAutoDefault( TRUE );
590 GroupButtonsLayout->addWidget( buttonClose );
592 QPushButton* buttonHelp = new QPushButton( tr( "HELP" ), GroupButtons );
593 buttonHelp->setAutoDefault( TRUE );
594 GroupButtonsLayout->addWidget( buttonHelp );
596 /***************************************************************/
597 ModeStackedLayout->addWidget( ModeActiveWidget );
598 ModeStackedLayout->addWidget( GroupParameters );
600 topLayout->addWidget( GroupPlanes );
601 topLayout->addLayout( ModeStackedLayout );
602 topLayout->addWidget( CheckBoxWidget );
603 topLayout->addWidget( GroupButtons );
605 this->setLayout( topLayout );
610 // Signals and slots connections
611 connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) );
612 connect( isActivePlane, SIGNAL ( toggled ( bool ) ), this, SLOT( onValueChanged() ) );
613 connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) );
614 connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );
615 connect( buttonDisableAll, SIGNAL( clicked() ), this, SLOT( ClickOnDisableAll() ) );
617 connect( resetButton, SIGNAL (clicked() ), this, SLOT( onReset() ) );
618 connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
619 connect( SpinBox_X, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
620 connect( SpinBox_Y, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
621 connect( SpinBox_Z, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
622 connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
623 connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
624 connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
625 connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ;
627 connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( int ) ) );
628 connect( SpinSliderDistance, SIGNAL( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
629 connect( SpinSliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
630 connect( SpinSliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
632 connect( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;
633 connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) );
635 connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;
636 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
637 connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
638 connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
641 myIsSelectPlane = false;
642 myIsPlaneCreation = false;
643 myIsUpdatingControls = false;
646 myModel->getViewer3d()->InitActiveViews();
648 OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) myModel->getViewManager();
649 myInteractor = new OCCViewer_ClipPlaneInteractor( aViewMgr, this );
650 connect( myInteractor, SIGNAL( planeClicked( const Handle_AIS_Plane& ) ), SLOT( onPlaneClicked( const Handle_AIS_Plane& ) ) );
651 connect( myInteractor, SIGNAL( planeDragged( const Handle_AIS_Plane& ) ), SLOT( onPlaneDragged( const Handle_AIS_Plane& ) ) );
653 myLocalPlanes = myModel->getClipPlanes();
659 Destroys the object and frees any allocated resources
661 OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg()
663 myLocalPlanes.clear();
667 Custom handling of close event: erases preview
669 void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
672 QDialog::closeEvent( e );
673 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
675 v->onClipping(false);
679 Custom handling of show event: displays preview
681 void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )
683 QDialog::showEvent( e );
684 onPreview( PreviewCheckBox->isChecked() );
688 Custom handling of hide event: erases preview
690 void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
693 QDialog::hideEvent( e );
694 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
696 v->onClipping(false);
701 Initialization of initial values of widgets
703 void OCCViewer_ClippingDlg::initParam()
705 SpinBox_X->setValue( 0.0 );
706 SpinBox_Y->setValue( 0.0 );
707 SpinBox_Z->setValue( 0.0 );
709 SpinBox_Dx->setValue( 1.0 );
710 SpinBox_Dy->setValue( 1.0 );
711 SpinBox_Dz->setValue( 1.0 );
713 CBAbsoluteOrientation->setCurrentIndex(0);
715 SpinSliderDistance->setValue( 0.5 );
716 SpinSliderRotation1->setValue( 0 );
717 SpinSliderRotation2->setValue( 0 );
718 CBRelativeOrientation->setCurrentIndex( 0 );
720 isActivePlane->setChecked( true );
724 Set plane parameters from widgets.
726 void OCCViewer_ClippingDlg::setPlaneParam( OCCViewer_ClipPlane& thePlane )
728 OCCViewer_ClipPlane::PlaneMode aMode = currentPlaneMode();
730 thePlane.Mode = aMode;
732 if ( aMode == OCCViewer_ClipPlane::Absolute )
734 if( qFuzzyIsNull( SpinBox_Dx->value() ) &&
735 qFuzzyIsNull( SpinBox_Dy->value() ) &&
736 qFuzzyIsNull( SpinBox_Dz->value() ) ) {
741 thePlane.OrientationType = (aMode == OCCViewer_ClipPlane::Absolute)
742 ? CBAbsoluteOrientation->currentIndex()
743 : CBRelativeOrientation->currentIndex();
746 if ( aMode == OCCViewer_ClipPlane::Absolute )
748 if ( thePlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )
750 thePlane.AbsoluteOrientation.Dx = SpinBox_Dx->value();
751 thePlane.AbsoluteOrientation.Dy = SpinBox_Dy->value();
752 thePlane.AbsoluteOrientation.Dz = SpinBox_Dz->value();
753 thePlane.AbsoluteOrientation.IsInvert = false;
757 thePlane.AbsoluteOrientation.IsInvert = SpinBox_Dx->value() < 0.0
758 || SpinBox_Dy->value() < 0.0
759 || SpinBox_Dz->value() < 0.0;
762 thePlane.X = SpinBox_X->value();
763 thePlane.Y = SpinBox_Y->value();
764 thePlane.Z = SpinBox_Z->value();
768 thePlane.RelativeOrientation.Rotation1 = SpinSliderRotation1->value();
769 thePlane.RelativeOrientation.Rotation2 = SpinSliderRotation2->value();
771 double aPlaneDx = 0.0;
772 double aPlaneDy = 0.0;
773 double aPlaneDz = 0.0;
778 OCCViewer_ClipPlane::RelativeToDXYZ( thePlane.OrientationType,
779 thePlane.RelativeOrientation.Rotation1,
780 thePlane.RelativeOrientation.Rotation2,
781 aPlaneDx, aPlaneDy, aPlaneDz );
783 DistanceToXYZ( myModel->getAISContext(),
784 myModel->trihedronSize(),
785 SpinSliderDistance->value(),
786 aPlaneDx, aPlaneDy, aPlaneDz,
794 thePlane.IsOn = isActivePlane->isChecked();
798 Synchronize dialog's widgets with data
800 void OCCViewer_ClippingDlg::synchronize()
802 ComboBoxPlanes->clear();
803 int aNbPlanesAbsolute = myLocalPlanes.size();
806 for(int i = 1; i<=aNbPlanesAbsolute; i++ ) {
807 aName = QString("Plane %1").arg(i);
808 ComboBoxPlanes->addItem( aName );
811 int aPos = ComboBoxPlanes->count() - 1;
812 ComboBoxPlanes->setCurrentIndex( aPos );
814 bool anIsControlsEnable = ( aPos >= 0 );
815 if ( anIsControlsEnable ) {
816 onSelectPlane( aPos );
819 ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );
822 if ( currentPlaneMode() == OCCViewer_ClipPlane::Absolute )
824 SpinBox_X->setEnabled( anIsControlsEnable );
825 SpinBox_Y->setEnabled( anIsControlsEnable );
826 SpinBox_Z->setEnabled( anIsControlsEnable );
827 SpinBox_Dx->setEnabled( anIsControlsEnable );
828 SpinBox_Dy->setEnabled( anIsControlsEnable );
829 SpinBox_Dz->setEnabled( anIsControlsEnable );
830 CBAbsoluteOrientation->setEnabled( anIsControlsEnable );
831 invertButton->setEnabled( anIsControlsEnable );
832 resetButton->setEnabled( anIsControlsEnable );
834 else if ( currentPlaneMode() == OCCViewer_ClipPlane::Relative )
836 CBRelativeOrientation->setEnabled( anIsControlsEnable );
837 SpinSliderDistance->setEnabled( anIsControlsEnable );
838 SpinSliderRotation1->setEnabled( anIsControlsEnable );
839 SpinSliderRotation2->setEnabled( anIsControlsEnable );
840 isActivePlane->setEnabled( anIsControlsEnable );
842 isActivePlane->setEnabled( anIsControlsEnable );
846 Displays preview of clipping plane
848 void OCCViewer_ClippingDlg::displayPreview()
850 if ( myBusy || !isValid() || !myModel)
853 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
855 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
857 for ( int i=0; i < clipPlanesCount(); i++ ) {
858 OCCViewer_ClipPlane& aClipPlane = getClipPlane(i);
859 if ( aClipPlane.IsOn ) {
860 Handle(AIS_Plane) myPreviewPlane;
864 clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
865 myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
866 myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
867 Handle(Prs3d_PlaneAspect) aPlaneAspect = new Prs3d_PlaneAspect();
868 aPlaneAspect->SetPlaneLength( aSize, aSize );
869 myPreviewPlane->Attributes()->SetPlaneAspect( aPlaneAspect );
870 ic->SetWidth( myPreviewPlane, 10, false );
871 ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
872 ic->SetTransparency( myPreviewPlane, 0.5, false );
873 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 );
874 ic->SetColor( myPreviewPlane, c , false );
875 ic->Display( myPreviewPlane, 1, 0, false );
876 myPreviewPlaneVector.push_back( myPreviewPlane );
881 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
882 getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
883 gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
884 (aYmax + aYmin) * 0.5,
885 (aZmax + aZmin) * 0.5 );
887 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
889 myInteractor->setPlanes( myPreviewPlaneVector );
890 myInteractor->setRotationCenter( aRotationCenter );
891 myInteractor->setMinMax( aMinMax );
892 myInteractor->setEnabled( true );
895 void OCCViewer_ClippingDlg::updatePreview() {
896 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
897 int count = clipPlanesCount();
903 (aCurPlaneIndex +1 > count) ||
904 !PreviewCheckBox->isChecked())
907 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
909 OCCViewer_ClipPlane& aClipPlane = getClipPlane(aCurPlaneIndex);
910 Handle(AIS_Plane) myPreviewPlane;
912 if (aClipPlane.IsOn) {
916 clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
917 if(myPreviewPlaneVector.size() < clipPlanesCount()) {
918 myPreviewPlaneVector.resize(clipPlanesCount());
920 myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
921 if(myPreviewPlane.IsNull()) {
922 //Plane was not created
923 myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
924 myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
925 Handle(Prs3d_PlaneAspect) aPlaneAspect = new Prs3d_PlaneAspect();
926 aPlaneAspect->SetPlaneLength( aSize, aSize );
927 myPreviewPlane->Attributes()->SetPlaneAspect( aPlaneAspect );
928 ic->Display( myPreviewPlane, 1, 0, false );
929 ic->SetWidth( myPreviewPlane, 10, false );
930 ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
931 ic->SetTransparency( myPreviewPlane, 0.5, false );
932 myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane;
934 myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) );
935 myPreviewPlane->SetCenter( aBasePnt );
936 myPreviewPlane->SetSize( aSize, aSize );
939 ic->SetColor( myPreviewPlane, Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ), false );
940 ic->Update( myPreviewPlane, Standard_False );
942 if(myPreviewPlaneVector.size() > aCurPlaneIndex ) {
943 myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
944 if(ic->IsDisplayed(myPreviewPlane)) {
945 ic->Erase( myPreviewPlane, false );
946 ic->Remove( myPreviewPlane, false );
948 myPreviewPlaneVector[aCurPlaneIndex].Nullify();
951 for(int i = 0; i < myPreviewPlaneVector.size(); i++) {
952 if( i == aCurPlaneIndex ) continue;
953 if(!myPreviewPlaneVector[i].IsNull())
954 ic->SetColor( myPreviewPlaneVector[i], Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
958 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
959 getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
960 gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
961 (aYmax + aYmin) * 0.5,
962 (aZmax + aZmin) * 0.5 );
964 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
966 myInteractor->setPlanes( myPreviewPlaneVector );
967 myInteractor->setRotationCenter( aRotationCenter );
968 myInteractor->setMinMax( aMinMax );
972 Erases preview of clipping plane
974 void OCCViewer_ClippingDlg::erasePreview()
979 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
981 for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) {
982 Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i];
983 if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
984 ic->Erase( myPreviewPlane, false );
985 ic->Remove( myPreviewPlane, false );
986 myPreviewPlane.Nullify();
989 myPreviewPlaneVector.clear();
991 myInteractor->setEnabled( false );
995 Return true if plane parameters are valid
997 bool OCCViewer_ClippingDlg::isValid()
999 return ( SpinBox_Dx->value() !=0 || SpinBox_Dy->value() !=0 || SpinBox_Dz->value() !=0 );
1003 Update view after changes
1005 void OCCViewer_ClippingDlg::updateClipping()
1007 if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked())
1009 if (AutoApplyCheckBox->isChecked()) {
1013 if (!PreviewCheckBox->isChecked())
1021 Updates state of user controls.
1023 void OCCViewer_ClippingDlg::updateControls()
1025 if ( clipPlanesCount() == 0 )
1031 int aPlaneIdx = ComboBoxPlanes->currentIndex();
1033 OCCViewer_ClipPlane& aPlane = getClipPlane( aPlaneIdx );
1035 double aPlaneDx = 0.0;
1036 double aPlaneDy = 0.0;
1037 double aPlaneDz = 0.0;
1038 double aDistance = 0.0;
1039 aPlane.OrientationToXYZ( aPlaneDx, aPlaneDy, aPlaneDz );
1041 if ( aPlane.Mode == OCCViewer_ClipPlane::Absolute )
1043 ModeStackedLayout->setCurrentIndex( 0 );
1045 // Set plane parameters in the dialog
1046 SpinBox_X->setValue( aPlane.X );
1047 SpinBox_Y->setValue( aPlane.Y );
1048 SpinBox_Z->setValue( aPlane.Z );
1049 SpinBox_Dx->setValue( aPlaneDx );
1050 SpinBox_Dy->setValue( aPlaneDy );
1051 SpinBox_Dz->setValue( aPlaneDz );
1052 CBAbsoluteOrientation->setCurrentIndex( aPlane.OrientationType );
1053 onOrientationAbsoluteChanged( aPlane.OrientationType );
1055 else if( aPlane.Mode == OCCViewer_ClipPlane::Relative )
1057 ModeStackedLayout->setCurrentIndex( 1 );
1059 // Set plane parameters in the dialog
1060 SpinSliderRotation1->setValue( int( aPlane.RelativeOrientation.Rotation1 ) );
1061 SpinSliderRotation2->setValue( int( aPlane.RelativeOrientation.Rotation2 ) );
1063 XYZToDistance( myModel->getAISContext(),
1064 myModel->trihedronSize(),
1065 aPlane.X, aPlane.Y, aPlane.Z,
1066 aPlaneDx, aPlaneDy, aPlaneDz,
1069 SpinSliderDistance->setValue( aDistance );
1071 CBRelativeOrientation->setCurrentIndex( aPlane.OrientationType );
1072 onOrientationRelativeChanged( aPlane.OrientationType );
1075 isActivePlane->setChecked( aPlane.IsOn );
1079 SLOT on new button click: create a new clipping plane
1081 void OCCViewer_ClippingDlg::ClickOnNew()
1083 OCCViewer_ClipPlane aClipPlane;
1085 // init controls state
1086 myIsUpdatingControls = true;
1088 myIsUpdatingControls = false;
1090 // init plane according to the state of controls
1091 setPlaneParam( aClipPlane );
1094 myLocalPlanes.push_back( aClipPlane );
1099 SLOT on delete button click: Delete selected clipping plane
1101 void OCCViewer_ClippingDlg::ClickOnDelete()
1103 int aPlaneIndex = ComboBoxPlanes->currentIndex();
1104 if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount()))
1107 myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex);
1109 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
1111 if(aPlaneIndex+1 <= myPreviewPlaneVector.size()) {
1112 Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[aPlaneIndex];
1113 if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
1114 ic->Erase( myPreviewPlane, false );
1115 ic->Remove( myPreviewPlane, false );
1117 myPreviewPlaneVector.erase(myPreviewPlaneVector.begin() + aPlaneIndex);
1120 if (AutoApplyCheckBox->isChecked()) {
1127 SLOT on disable all button click: Restore initial state of viewer,
1128 erase all clipping planes
1130 void OCCViewer_ClippingDlg::ClickOnDisableAll()
1132 AutoApplyCheckBox->setChecked (false);
1133 int aClipPlanesCount = clipPlanesCount();
1134 for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++)
1136 OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex);
1137 aPlane.IsOn = false;
1140 isActivePlane->setChecked(false);
1141 myModel->setClipPlanes(myLocalPlanes);
1146 SLOT on ok button click: sets cutting plane and closes dialog
1148 void OCCViewer_ClippingDlg::ClickOnOk()
1155 SLOT on Apply button click: sets cutting plane and update viewer
1157 void OCCViewer_ClippingDlg::ClickOnApply()
1164 SLOT on close button click: erases preview and rejects dialog
1166 void OCCViewer_ClippingDlg::ClickOnClose()
1169 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
1171 v->onClipping(false);
1175 SLOT on help button click: opens a help page
1177 void OCCViewer_ClippingDlg::ClickOnHelp()
1179 SUIT_Application* app = SUIT_Session::session()->activeApplication();
1181 app->onHelpContextModule( "GUI", "occ_3d_viewer_page.html", "clipping_planes" );
1185 Set absolute mode of clipping plane
1187 void OCCViewer_ClippingDlg::onModeAbsolute()
1189 myIsPlaneCreation = true;
1190 ModeStackedLayout->setCurrentIndex(0);
1192 myIsPlaneCreation = false;
1197 Set relative mode of clipping plane
1199 void OCCViewer_ClippingDlg::onModeRelative()
1201 myIsPlaneCreation = true;
1202 ModeStackedLayout->setCurrentIndex(1);
1204 myIsPlaneCreation = false;
1205 SetCurrentPlaneParam();
1210 SLOT: called on value of clipping plane changed
1212 void OCCViewer_ClippingDlg::onValueChanged()
1214 if ( myIsUpdatingControls )
1219 SetCurrentPlaneParam();
1221 if ( myIsSelectPlane )
1230 Set current parameters of selected plane
1232 void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )
1234 if ( clipPlanesCount() == 0 )
1239 OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex );
1241 myIsSelectPlane = true;
1243 ComboBoxPlanes->setCurrentIndex( theIndex );
1244 myIsSelectPlane = false;
1248 Restore parameters of selected plane
1250 void OCCViewer_ClippingDlg::SetCurrentPlaneParam()
1252 if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy )
1257 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1259 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
1261 setPlaneParam( aPlane );
1265 SLOT on reset button click: sets default values
1267 void OCCViewer_ClippingDlg::onReset()
1270 SpinBox_X->setValue(0);
1271 SpinBox_Y->setValue(0);
1272 SpinBox_Z->setValue(0);
1275 SetCurrentPlaneParam();
1280 SLOT on invert button click: inverts normal of cutting plane
1282 void OCCViewer_ClippingDlg::onInvert()
1284 double Dx = SpinBox_Dx->value();
1285 double Dy = SpinBox_Dy->value();
1286 double Dz = SpinBox_Dz->value();
1289 SpinBox_Dx->setValue( -Dx );
1290 SpinBox_Dy->setValue( -Dy );
1291 SpinBox_Dz->setValue( -Dz );
1294 if ( clipPlanesCount() != 0 )
1296 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1297 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
1298 aPlane.AbsoluteOrientation.IsInvert = !aPlane.AbsoluteOrientation.IsInvert;
1304 SLOT: called on orientation of clipping plane in absolute mode changed
1306 void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )
1308 bool isUserMode = (mode==0);
1310 TextLabelX->setEnabled( isUserMode );
1311 TextLabelY->setEnabled( isUserMode );
1312 TextLabelZ->setEnabled( isUserMode );
1314 SpinBox_X->setEnabled( isUserMode );
1315 SpinBox_Y->setEnabled( isUserMode );
1316 SpinBox_Z->setEnabled( isUserMode );
1318 TextLabelDx->setEnabled( isUserMode );
1319 TextLabelDy->setEnabled( isUserMode );
1320 TextLabelDz->setEnabled( isUserMode );
1322 SpinBox_Dx->setEnabled( isUserMode );
1323 SpinBox_Dy->setEnabled( isUserMode );
1324 SpinBox_Dz->setEnabled( isUserMode );
1326 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1327 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
1328 double aDx = 0, aDy = 0, aDz = 0;
1332 aDx = aPlane.AbsoluteOrientation.Dx;
1333 aDy = aPlane.AbsoluteOrientation.Dy;
1334 aDz = aPlane.AbsoluteOrientation.Dz;
1336 else if ( mode == 1 )
1339 TextLabelZ->setEnabled( true );
1340 SpinBox_Z->setEnabled( true );
1341 SpinBox_Z->setFocus();
1343 else if ( mode == 2 )
1346 TextLabelX->setEnabled( true );
1347 SpinBox_X->setEnabled( true );
1348 SpinBox_X->setFocus();
1350 else if ( mode == 3 )
1353 TextLabelY->setEnabled( true );
1354 SpinBox_Y->setEnabled( true );
1355 SpinBox_Y->setFocus();
1358 if ( aPlane.AbsoluteOrientation.IsInvert == true )
1366 SpinBox_Dx->setValue( aDx );
1367 SpinBox_Dy->setValue( aDy );
1368 SpinBox_Dz->setValue( aDz );
1371 if ( !myIsUpdatingControls )
1373 SetCurrentPlaneParam();
1379 SLOT: called on orientation of clipping plane in relative mode changed
1381 void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)
1383 if ( clipPlanesCount() == 0 )
1386 if ( theItem == 0 ) {
1387 TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );
1388 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );
1390 else if ( theItem == 1 ) {
1391 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) );
1392 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) );
1394 else if ( theItem == 2 ) {
1395 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) );
1396 TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );
1399 if ( !myIsUpdatingControls )
1401 if( (QComboBox*)sender() == CBRelativeOrientation )
1403 SetCurrentPlaneParam();
1411 SLOT: called on preview check box toggled
1413 void OCCViewer_ClippingDlg::onPreview( bool on )
1421 SLOT: called on Auto Apply check box toggled
1423 void OCCViewer_ClippingDlg::onAutoApply( bool toggled )
1432 SLOT on Apply button click: sets cutting plane
1434 void OCCViewer_ClippingDlg::onApply()
1438 myIsSelectPlane = true;
1440 qApp->processEvents();
1441 QApplication::setOverrideCursor( Qt::WaitCursor );
1442 qApp->processEvents();
1444 myModel->setClipPlanes(myLocalPlanes);
1446 QApplication::restoreOverrideCursor();
1447 myIsSelectPlane = false;
1451 SLOT: Called when clip plane is clicked in viewer.
1453 void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane )
1455 for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
1457 Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
1458 if ( aPlane != thePlane )
1463 ComboBoxPlanes->setCurrentIndex( aPlaneIt );
1470 SLOT: Called when clip plane is changed by dragging in viewer.
1472 void OCCViewer_ClippingDlg::onPlaneDragged( const Handle(AIS_Plane)& thePlane )
1474 for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
1476 Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
1477 if ( aPlane != thePlane )
1482 OCCViewer_ClipPlane& aClipPlane = getClipPlane( aPlaneIt );
1484 gp_Pln aPln = thePlane->Component()->Pln();
1485 const gp_Pnt& aPlaneP = aPln.Location();
1486 const gp_Dir& aPlaneN = aPln.Axis().Direction();
1488 aClipPlane.X = aPlaneP.X();
1489 aClipPlane.Y = aPlaneP.Y();
1490 aClipPlane.Z = aPlaneP.Z();
1492 if ( aClipPlane.Mode == OCCViewer_ClipPlane::Absolute )
1494 if ( aClipPlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )
1496 int anInvertCoeff = aClipPlane.AbsoluteOrientation.IsInvert ? 1 : -1;
1497 aClipPlane.AbsoluteOrientation.Dx = anInvertCoeff * aPlaneN.X();
1498 aClipPlane.AbsoluteOrientation.Dy = anInvertCoeff * aPlaneN.Y();
1499 aClipPlane.AbsoluteOrientation.Dz = anInvertCoeff * aPlaneN.Z();
1504 OCCViewer_ClipPlane::DXYZToRelative( aPlaneN.X(), aPlaneN.Y(), aPlaneN.Z(),
1505 aClipPlane.OrientationType,
1506 aClipPlane.RelativeOrientation.Rotation1,
1507 aClipPlane.RelativeOrientation.Rotation2 );
1510 myIsUpdatingControls = true;
1512 myIsUpdatingControls = false;
1514 if ( AutoApplyCheckBox->isChecked() )
1523 OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx )
1525 return myLocalPlanes[theIdx];
1528 int OCCViewer_ClippingDlg::clipPlanesCount()
1530 return myLocalPlanes.size();
1533 OCCViewer_ClipPlane::PlaneMode OCCViewer_ClippingDlg::currentPlaneMode() const
1535 return ModeStackedLayout->currentIndex() == 0
1536 ? OCCViewer_ClipPlane::Absolute
1537 : OCCViewer_ClipPlane::Relative;