1 // Copyright (C) 2007-2014 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 <QtxAction.h>
28 #include "SUIT_Session.h"
29 #include "SUIT_ViewWindow.h"
30 #include "SUIT_ViewManager.h"
31 #include "OCCViewer_ClipPlane.h"
32 #include "OCCViewer_ViewWindow.h"
33 #include "OCCViewer_ViewPort3d.h"
34 #include "OCCViewer_ViewModel.h"
35 #include "OCCViewer_ViewManager.h"
36 #include "OCCViewer_ClipPlaneInteractor.h"
38 #include <V3d_View.hxx>
39 #include <Visual3d_View.hxx>
40 #include <Geom_Plane.hxx>
41 #include <Prs3d_Presentation.hxx>
42 #include <AIS_ListIteratorOfListOfInteractive.hxx>
43 #include <AIS_ListOfInteractive.hxx>
44 #include <AIS_InteractiveObject.hxx>
45 #include <AIS_InteractiveContext.hxx>
46 #include <IntAna_IntConicQuad.hxx>
52 #include <QApplication>
54 #include <QHBoxLayout>
55 #include <QVBoxLayout>
56 #include <QGridLayout>
58 #include <QPushButton>
61 #include <QStackedLayout>
65 /**********************************************************************************
66 ************************ Internal functions ************************
67 *********************************************************************************/
69 void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic,
70 double theDefaultSize,
78 double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
79 aXMin = aYMin = aZMin = DBL_MAX;
80 aXMax = aYMax = aZMax = -DBL_MAX;
83 AIS_ListOfInteractive aList;
84 ic->DisplayedObjects( aList );
85 for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) {
86 Handle(AIS_InteractiveObject) anObj = it.Value();
87 if ( !anObj.IsNull() && anObj->HasPresentation() &&
88 !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) {
89 Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
90 if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) {
92 double xmin, ymin, zmin, xmax, ymax, zmax;
93 aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );
94 aXMin = qMin( aXMin, xmin ); aXMax = qMax( aXMax, xmax );
95 aYMin = qMin( aYMin, ymin ); aYMax = qMax( aYMax, ymax );
96 aZMin = qMin( aZMin, zmin ); aZMax = qMax( aZMax, zmax );
102 if(theDefaultSize == 0.0)
103 theDefaultSize = 100.;
104 aXMin = aYMin = aZMin = -theDefaultSize;
105 aXMax = aYMax = aZMax = theDefaultSize;
107 theXMin = aXMin;theYMin = aYMin;theZMin = aZMin;
108 theXMax = aXMax;theYMax = aYMax;theZMax = aZMax;
112 Compute the point of bounding box and current clipping plane
114 void ComputeBoundsParam( double theBounds[6],
115 double theDirection[3],
117 double& theMaxBoundPrj,
118 double& theMinBoundPrj )
120 //Enlarge bounds in order to avoid conflicts of precision
121 for(int i = 0; i < 6; i += 2) {
122 static double EPS = 1.0E-3;
123 double aDelta = (theBounds[i+1] - theBounds[i])*EPS;
124 theBounds[i] -= aDelta;
125 theBounds[i+1] += aDelta;
128 double aBoundPoints[8][3] = { { theBounds[0], theBounds[2], theBounds[4] },
129 { theBounds[1], theBounds[2], theBounds[4] },
130 { theBounds[0], theBounds[3], theBounds[4] },
131 { theBounds[1], theBounds[3], theBounds[4] },
132 { theBounds[0], theBounds[2], theBounds[5] },
133 { theBounds[1], theBounds[2], theBounds[5] },
134 { theBounds[0], theBounds[3], theBounds[5] },
135 { theBounds[1], theBounds[3], theBounds[5] } };
138 theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1]
139 + theDirection[2] * aBoundPoints[aMaxId][2];
140 theMinBoundPrj = theMaxBoundPrj;
141 for(int i = 1; i < 8; i++) {
142 double aTmp = theDirection[0] * aBoundPoints[i][0] + theDirection[1] * aBoundPoints[i][1]
143 + theDirection[2] * aBoundPoints[i][2];
144 if(theMaxBoundPrj < aTmp) {
145 theMaxBoundPrj = aTmp;
148 if(theMinBoundPrj > aTmp) {
149 theMinBoundPrj = aTmp;
152 double *aMinPnt = aBoundPoints[aMaxId];
153 theMinPnt[0] = aMinPnt[0];
154 theMinPnt[1] = aMinPnt[1];
155 theMinPnt[2] = aMinPnt[2];
159 Compute the position of current plane by distance
161 void DistanceToPosition( double theBounds[6],
162 double theDirection[3],
166 double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
167 ComputeBoundsParam( theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj );
168 double aLength = (aMaxBoundPrj - aMinBoundPrj)*theDist;
169 thePos[0] = aMinPnt[0] - theDirection[0]*aLength;
170 thePos[1] = aMinPnt[1] - theDirection[1]*aLength;
171 thePos[2] = aMinPnt[2] - theDirection[2]*aLength;
175 Compute the parameters of clipping plane
177 bool ComputeClippingPlaneParameters( double theNormal[3],
180 Handle(AIS_InteractiveContext) ic,
181 double theDefaultSize)
183 double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
184 getMinMaxFromContext(ic,theDefaultSize,aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5]);
186 DistanceToPosition( aBounds, theNormal, theDist, theOrigin );
191 Cross product of two 3-vectors. Result vector in result[3].
193 void Cross(const double first[3], const double second[3], double result[3])
195 result[0] = first[1]*second[2] - first[2]*second[1];
196 result[1] = first[2]*second[0] - first[0]*second[2];
197 result[2] = first[0]*second[1] - first[1]*second[0];
201 Compute relative clipping plane in absolute coordinates
203 void relativePlaneToAbsolute (OCCViewer_ClipPlane& thePlane, Handle(AIS_InteractiveContext) ic, double theDefaultSize )
206 double aDir[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } };
208 static double aCoeff = M_PI/180.0;
210 double anU[2] = { cos( aCoeff * thePlane.RelativeMode.Rotation1 ), cos( aCoeff * thePlane.RelativeMode.Rotation2 ) };
211 double aV[2] = { sqrt( 1.0 - anU[0]*anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) };
212 aV[0] = thePlane.RelativeMode.Rotation1 > 0? aV[0]: -aV[0];
213 aV[1] = thePlane.RelativeMode.Rotation2 > 0? aV[1]: -aV[1];
215 switch ( thePlane.RelativeMode.Orientation ) {
236 Cross( aDir[1], aDir[0], aNormal );
239 den = sqrt( aNormal[0] * aNormal[0] + aNormal[1] * aNormal[1] + aNormal[2] * aNormal[2] );
241 for (int i=0; i < 3; i++) {
249 anOrigin[0] = anOrigin[1] = anOrigin[2] = 0;
252 anIsOk = ComputeClippingPlaneParameters( aNormal,
253 thePlane.RelativeMode.Distance,
259 thePlane.X = anOrigin[0];
260 thePlane.Y = anOrigin[1];
261 thePlane.Z = anOrigin[2];
262 thePlane.Dx = aNormal[0];
263 thePlane.Dy = aNormal[1];
264 thePlane.Dz = aNormal[2];
268 \brief Converts absolute plane definition to relative system.
269 \param thePlane [in/out] the plane to convert.
270 \param theIC [in] the interactive context.
271 \param theDefaultSize [in] the default trihedron size.
273 void absolutePlaneToRelative( OCCViewer_ClipPlane& thePlane, Handle(AIS_InteractiveContext) theIC, double theDefaultSize )
275 gp_Pnt aPlaneP( thePlane.X, thePlane.Y, thePlane.Z );
276 gp_Dir aPlaneN( thePlane.Dx, thePlane.Dy, thePlane.Dz );
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 thePlane.RelativeMode.Distance = aRelativeDistance;
299 const gp_Dir& aDX = gp::DX();
300 const gp_Dir& aDY = gp::DY();
301 const gp_Dir& aDZ = gp::DZ();
304 switch ( thePlane.RelativeMode.Orientation )
308 if ( aDY.IsEqual( aPlaneN, Precision::Angular() ) )
315 gp_Dir aDir1 = aPlaneN ^ aDX;
316 gp_Dir aDir2 = aDY ^ aPlaneN;
317 gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDY ^ aPlaneN );
319 if ( aDir1 * aRightHand.YDirection() < 0.0 )
323 if ( aDir2 * aRightHand.XDirection() < 0.0 )
328 anAng1 = aDY.AngleWithRef( aDir1, aDX );
329 anAng2 = aDX.AngleWithRef( aDir2, -aDY );
334 if ( aDZ.IsEqual( aPlaneN, Precision::Angular() ) )
341 gp_Dir aDir1 = aPlaneN ^ aDY;
342 gp_Dir aDir2 = aDZ ^ aPlaneN;
343 gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDZ ^ aPlaneN );
345 if ( aDir1 * aRightHand.YDirection() < 0.0 )
349 if ( aDir2 * aRightHand.XDirection() < 0.0 )
354 anAng1 = aDZ.AngleWithRef( aDir1, aDY );
355 anAng2 = aDY.AngleWithRef( aDir2, -aDZ );
360 if ( aDX.IsEqual( aPlaneN, Precision::Angular() ) )
367 gp_Dir aDir1 = aPlaneN ^ aDZ;
368 gp_Dir aDir2 = aDX ^ aPlaneN;
369 gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDX ^ aPlaneN );
371 if ( aDir1 * aRightHand.YDirection() < 0.0 )
375 if ( aDir2 * aRightHand.XDirection() < 0.0 )
380 anAng1 = aDX.AngleWithRef( aDir1, aDZ );
381 anAng2 = aDZ.AngleWithRef( aDir2, -aDX );
386 thePlane.RelativeMode.Rotation1 = anAng1 * ( 180.0 / M_PI );
387 thePlane.RelativeMode.Rotation2 = anAng2 * ( 180.0 / M_PI );
391 Compute clipping plane size base point and normal
394 void clipPlaneParams(OCCViewer_ClipPlane& theClipPlane, Handle(AIS_InteractiveContext) theContext,
395 double& theSize, gp_Pnt& theBasePnt, gp_Dir& theNormal, double defaultSize) {
396 double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
397 aXMin = aYMin = aZMin = DBL_MAX;
398 aXMax = aYMax = aZMax = -DBL_MAX;
400 getMinMaxFromContext(theContext,defaultSize,aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
404 gp_Pnt aBasePnt(theClipPlane.X , theClipPlane.Y , theClipPlane.Z);
405 gp_Dir aNormal(theClipPlane.Dx, theClipPlane.Dy, theClipPlane.Dz );
407 // compute clipping plane size
408 gp_Pnt aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
409 double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2;
412 // compute clipping plane center ( redefine the base point )
413 IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
415 intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
417 if ( intersector.IsDone() && intersector.NbPoints() == 1 )
418 aBasePnt = intersector.Point( 1 );
421 theBasePnt = aBasePnt;
426 /*********************************************************************************
427 ********************* class OCCViewer_ClippingDlg *********************
428 *********************************************************************************/
431 \param view - view window
432 \param parent - parent widget
434 OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model)
435 : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
436 myCurrentClipPlaneMode (Absolute)
438 setObjectName( "OCCViewer_ClippingDlg" );
441 setWindowTitle( tr( "Clipping" ) );
443 setAttribute (Qt::WA_DeleteOnClose, true);
445 QVBoxLayout* topLayout = new QVBoxLayout( this );
446 topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
448 /***************************************************************/
449 // Controls for selecting, creating, deleting planes
450 QGroupBox* GroupPlanes = new QGroupBox( tr("CLIPPING_PLANES"), this );
451 QHBoxLayout* GroupPlanesLayout = new QHBoxLayout( GroupPlanes );
452 ComboBoxPlanes = new QComboBox( GroupPlanes );
453 isActivePlane = new QCheckBox( tr("IS_ACTIVE_PLANE"), this );
454 buttonNew = new QPushButton( tr("BTN_NEW"), GroupPlanes );
455 buttonDelete = new QPushButton( tr("BTN_DELETE"), GroupPlanes );
456 buttonDisableAll = new QPushButton( tr("BTN_DISABLE_ALL"), GroupPlanes );
457 MenuMode = new QMenu( "MenuMode", buttonNew );
458 MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );
459 MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );
460 buttonNew->setMenu( MenuMode );
462 GroupPlanesLayout->addWidget( ComboBoxPlanes );
463 GroupPlanesLayout->addWidget( isActivePlane );
464 GroupPlanesLayout->addWidget( buttonNew );
465 GroupPlanesLayout->addWidget( buttonDelete );
466 GroupPlanesLayout->addWidget( buttonDisableAll );
468 ModeStackedLayout = new QStackedLayout();
470 /********************** Mode Absolute **********************/
471 /* Controls for absolute mode of clipping plane:
472 X, Y, Z - coordinates of the intersection of cutting plane and the three axes
473 Dx, Dy, Dz - components of normal to the cutting plane
474 Orientation - direction of cutting plane
476 const double min = -1e+7;
477 const double max = 1e+7;
478 const double step = 5;
479 const int precision = -7;
482 QGroupBox* GroupAbsolutePoint = new QGroupBox( this );
483 GroupAbsolutePoint->setObjectName( "GroupPoint" );
484 GroupAbsolutePoint->setTitle( tr("BASE_POINT") );
485 QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint );
486 GroupPointLayout->setAlignment( Qt::AlignTop );
487 GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 );
489 TextLabelX = new QLabel( GroupAbsolutePoint );
490 TextLabelX->setObjectName( "TextLabelX" );
491 TextLabelX->setText( tr("X:") );
492 GroupPointLayout->addWidget( TextLabelX, 0, 0 );
494 SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
495 SpinBox_X->setObjectName("SpinBox_X" );
496 SpinBox_X->setPrecision( precision );
497 GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
499 TextLabelY = new QLabel( GroupAbsolutePoint );
500 TextLabelY->setObjectName( "TextLabelY" );
501 TextLabelY->setText( tr("Y:") );
502 GroupPointLayout->addWidget( TextLabelY, 0, 2 );
504 SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
505 SpinBox_Y->setObjectName("SpinBox_Y" );
506 SpinBox_Y->setPrecision( precision );
507 GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
509 TextLabelZ = new QLabel( GroupAbsolutePoint );
510 TextLabelZ->setObjectName( "TextLabelZ" );
511 TextLabelZ->setText( tr("Z:") );
512 GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
514 SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
515 SpinBox_Z->setObjectName("SpinBox_Z" );
516 SpinBox_Z->setPrecision( precision );
517 GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
519 resetButton = new QPushButton( GroupAbsolutePoint );
520 resetButton->setObjectName( "resetButton" );
521 resetButton->setText( tr( "RESET" ) );
522 GroupPointLayout->addWidget( resetButton, 0, 6 );
525 GroupAbsoluteDirection = new QGroupBox( this );
526 GroupAbsoluteDirection->setObjectName( "GroupDirection" );
527 GroupAbsoluteDirection->setTitle( tr("DIRECTION") );
528 QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection );
529 GroupDirectionLayout->setAlignment( Qt::AlignTop );
530 GroupDirectionLayout->setSpacing( 6 );
531 GroupDirectionLayout->setMargin( 11 );
533 TextLabelDx = new QLabel( GroupAbsoluteDirection );
534 TextLabelDx->setObjectName( "TextLabelDx" );
535 TextLabelDx->setText( tr("Dx:") );
536 GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
538 SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
539 SpinBox_Dx->setObjectName("SpinBox_Dx" );
540 SpinBox_Dx->setPrecision( precision );
541 GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
543 TextLabelDy = new QLabel( GroupAbsoluteDirection );
544 TextLabelDy->setObjectName( "TextLabelDy" );
545 TextLabelDy->setText( tr("Dy:") );
546 GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
548 SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
549 SpinBox_Dy->setObjectName("SpinBox_Dy" );
550 SpinBox_Dy->setPrecision( precision );
551 GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
553 TextLabelDz = new QLabel( GroupAbsoluteDirection );
554 TextLabelDz->setObjectName( "TextLabelDz" );
555 TextLabelDz->setText( tr("Dz:") );
556 GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
558 SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
559 SpinBox_Dz->setObjectName("SpinBox_Dz" );
560 SpinBox_Dz->setPrecision( precision );
561 GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
563 invertButton = new QPushButton( GroupAbsoluteDirection );
564 invertButton->setObjectName( "invertButton" );
565 invertButton->setText( tr( "INVERT" ) );
566 GroupDirectionLayout->addWidget( invertButton, 0, 6 );
568 CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection );
569 CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" );
570 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) );
571 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) );
572 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) );
573 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) );
574 GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 );
576 QVBoxLayout* ModeActiveLayout = new QVBoxLayout();
577 ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 );
578 ModeActiveLayout->addWidget( GroupAbsolutePoint );
579 ModeActiveLayout->addWidget( GroupAbsoluteDirection );
581 QWidget* ModeActiveWidget = new QWidget( this );
582 ModeActiveWidget->setLayout( ModeActiveLayout );
584 /********************** Mode Relative **********************/
585 /* Controls for relative mode of clipping plane:
586 Distance - Value from 0 to 1.
587 Specifies the distance from the minimum value in a given direction of bounding box to the current position
588 Rotation1, Rotation2 - turn angles of cutting plane in given directions
589 Orientation - direction of cutting plane
591 QGroupBox* GroupParameters = new QGroupBox( tr("PARAMETERS"), this );
592 QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );
593 GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 );
595 TextLabelOrientation = new QLabel( tr("ORIENTATION"), GroupParameters);
596 TextLabelOrientation->setObjectName( "TextLabelOrientation" );
597 GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
599 CBRelativeOrientation = new QComboBox(GroupParameters);
600 CBRelativeOrientation->setObjectName( "RelativeOrientation" );
601 CBRelativeOrientation->addItem( tr("ALONG_XY") );
602 CBRelativeOrientation->addItem( tr("ALONG_YZ") );
603 CBRelativeOrientation->addItem( tr("ALONG_ZX") );
604 GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );
606 TLValueDistance = new QLabel( GroupParameters );
607 TLValueDistance->setObjectName( "TLValueDistance" );
608 TLValueDistance->setAlignment( Qt::AlignCenter );
609 TLValueDistance->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
610 QFont fnt = TLValueDistance->font(); fnt.setBold( true ); TLValueDistance->setFont( fnt );
611 GroupParametersLayout->addWidget( TLValueDistance, 1, 1 );
613 TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters );
614 TextLabelDistance->setObjectName( "TextLabelDistance" );
615 GroupParametersLayout->addWidget( TextLabelDistance, 2, 0 );
617 SliderDistance = new QSlider( Qt::Horizontal, GroupParameters );
618 SliderDistance->setObjectName( "SliderDistance" );
619 SliderDistance->setFocusPolicy( Qt::NoFocus );
620 SliderDistance->setMinimumSize( 300, 0 );
621 SliderDistance->setMinimum( 0 );
622 SliderDistance->setMaximum( 100 );
623 SliderDistance->setSingleStep( 1 );
624 SliderDistance->setPageStep( 10 );
625 SliderDistance->setTracking( false );
626 GroupParametersLayout->addWidget( SliderDistance, 2, 1 );
628 TLValueRotation1 = new QLabel( GroupParameters );
629 TLValueRotation1->setObjectName( "TLValueRotation1" );
630 TLValueRotation1->setAlignment( Qt::AlignCenter );
631 TLValueRotation1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
632 TLValueRotation1->setFont( fnt );
633 GroupParametersLayout->addWidget( TLValueRotation1, 3, 1 );
635 TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters );
636 TextLabelRotation1->setObjectName( "TextLabelRotation1" );
637 GroupParametersLayout->addWidget( TextLabelRotation1, 4, 0 );
639 SliderRotation1 = new QSlider( Qt::Horizontal, GroupParameters );
640 SliderRotation1->setObjectName( "SliderRotation1" );
641 SliderRotation1->setFocusPolicy( Qt::NoFocus );
642 SliderRotation1->setMinimumSize( 300, 0 );
643 SliderRotation1->setMinimum( -180 );
644 SliderRotation1->setMaximum( 180 );
645 SliderRotation1->setSingleStep( 1 );
646 SliderRotation1->setPageStep( 10 );
647 SliderRotation1->setTracking(false);
648 GroupParametersLayout->addWidget( SliderRotation1, 4, 1 );
650 TLValueRotation2 = new QLabel( GroupParameters );
651 TLValueRotation2->setObjectName( "TLValueRotation2" );
652 TLValueRotation2->setAlignment( Qt::AlignCenter );
653 TLValueRotation2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
654 TLValueRotation2->setFont( fnt );
655 GroupParametersLayout->addWidget( TLValueRotation2, 5, 1 );
657 TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);
658 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
659 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
660 GroupParametersLayout->addWidget( TextLabelRotation2, 6, 0 );
662 SliderRotation2 = new QSlider( Qt::Horizontal, GroupParameters );
663 SliderRotation2->setObjectName( "SliderRotation2" );
664 SliderRotation2->setFocusPolicy( Qt::NoFocus );
665 SliderRotation2->setMinimumSize( 300, 0 );
666 SliderRotation2->setMinimum( -180 );
667 SliderRotation2->setMaximum( 180 );
668 SliderRotation2->setSingleStep( 1 );
669 SliderRotation2->setPageStep( 10 );
670 SliderRotation2->setTracking(false);
671 GroupParametersLayout->addWidget( SliderRotation2, 6, 1 );
673 /***************************************************************/
674 QGroupBox* CheckBoxWidget = new QGroupBox( this );
675 QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget );
677 PreviewCheckBox = new QCheckBox( tr("PREVIEW"), CheckBoxWidget );
678 PreviewCheckBox->setObjectName( "PreviewCheckBox" );
679 PreviewCheckBox->setChecked( true );
680 CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter );
682 AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget );
683 AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" );
684 CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter );
686 /***************************************************************/
687 QGroupBox* GroupButtons = new QGroupBox( this );
688 QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );
689 GroupButtonsLayout->setAlignment( Qt::AlignTop );
690 GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );
692 buttonOk = new QPushButton( GroupButtons );
693 buttonOk->setObjectName( "buttonOk" );
694 buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE" ) );
695 buttonOk->setAutoDefault( TRUE );
696 buttonOk->setDefault( TRUE );
697 GroupButtonsLayout->addWidget( buttonOk );
699 buttonApply = new QPushButton( GroupButtons );
700 buttonApply->setObjectName( "buttonApply" );
701 buttonApply->setText( tr( "BUT_APPLY" ) );
702 buttonApply->setAutoDefault( TRUE );
703 buttonApply->setDefault( TRUE );
704 GroupButtonsLayout->addWidget( buttonApply );
706 GroupButtonsLayout->addStretch();
708 buttonClose = new QPushButton( GroupButtons );
709 buttonClose->setObjectName( "buttonClose" );
710 buttonClose->setText( tr( "BUT_CLOSE" ) );
711 buttonClose->setAutoDefault( TRUE );
712 GroupButtonsLayout->addWidget( buttonClose );
714 QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons );
715 buttonHelp->setAutoDefault( TRUE );
716 GroupButtonsLayout->addWidget( buttonHelp );
718 /***************************************************************/
719 ModeStackedLayout->addWidget( ModeActiveWidget );
720 ModeStackedLayout->addWidget( GroupParameters );
722 topLayout->addWidget( GroupPlanes );
723 topLayout->addLayout( ModeStackedLayout );
724 topLayout->addWidget( CheckBoxWidget );
725 topLayout->addWidget( GroupButtons );
727 this->setLayout( topLayout );
732 // Signals and slots connections
733 connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) );
734 connect( isActivePlane, SIGNAL ( toggled ( bool ) ), this, SLOT( onValueChanged() ) );
735 connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) );
736 connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );
737 connect( buttonDisableAll, SIGNAL( clicked() ), this, SLOT( ClickOnDisableAll() ) );
739 connect( resetButton, SIGNAL (clicked() ), this, SLOT( onReset() ) );
740 connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
741 connect( SpinBox_X, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
742 connect( SpinBox_Y, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
743 connect( SpinBox_Z, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
744 connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
745 connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
746 connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
747 connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ;
749 connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( int ) ) );
750 connect( SliderDistance, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderDistanceHasMoved( int ) ) );
751 connect( SliderDistance, SIGNAL( valueChanged( int ) ), this, SLOT( SliderDistanceHasMoved( int ) ) );
752 connect( SliderRotation1, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderRotation1HasMoved( int ) ) );
753 connect( SliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( SliderRotation1HasMoved( int ) ) );
754 connect( SliderRotation2, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderRotation2HasMoved( int ) ) );
755 connect( SliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( SliderRotation2HasMoved( int ) ) );
757 connect( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;
758 connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) );
760 connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;
761 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
762 connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
763 connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
766 myIsSelectPlane = false;
767 myIsPlaneCreation = false;
768 myIsUpdatingControls = false;
771 myModel->getViewer3d()->InitActiveViews();
773 OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) myModel->getViewManager();
774 myInteractor = new OCCViewer_ClipPlaneInteractor( aViewMgr, this );
775 connect( myInteractor, SIGNAL( planeClicked( const Handle_AIS_Plane& ) ), SLOT( onPlaneClicked( const Handle_AIS_Plane& ) ) );
776 connect( myInteractor, SIGNAL( planeDragged( const Handle_AIS_Plane& ) ), SLOT( onPlaneDragged( const Handle_AIS_Plane& ) ) );
778 myLocalPlanes = myModel->getClipPlanes();
784 Destroys the object and frees any allocated resources
786 OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg()
788 myLocalPlanes.clear();
792 Custom handling of close event: erases preview
794 void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
797 QDialog::closeEvent( e );
798 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
800 v->onClipping(false);
804 Custom handling of show event: displays preview
806 void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )
808 QDialog::showEvent( e );
809 onPreview( PreviewCheckBox->isChecked() );
813 Custom handling of hide event: erases preview
815 void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
818 QDialog::hideEvent( e );
819 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
821 v->onClipping(false);
826 Initialization of initial values of widgets
828 void OCCViewer_ClippingDlg::initParam()
830 SpinBox_X->setValue( 0.0 );
831 SpinBox_Y->setValue( 0.0 );
832 SpinBox_Z->setValue( 0.0 );
834 SpinBox_Dx->setValue( 1.0 );
835 SpinBox_Dy->setValue( 1.0 );
836 SpinBox_Dz->setValue( 1.0 );
838 CBAbsoluteOrientation->setCurrentIndex(0);
840 TLValueDistance->setText( "0.5" );
841 TLValueRotation1->setText( "0\xB0" );
842 TLValueRotation2->setText( "0\xB0" );
843 CBRelativeOrientation->setCurrentIndex( 0 );
844 SliderDistance->setValue( 50 );
845 SliderRotation1->setValue( 0 );
846 SliderRotation2->setValue( 0 );
850 Synchronize dialog's widgets with data
852 void OCCViewer_ClippingDlg::synchronize()
854 ComboBoxPlanes->clear();
855 int aNbPlanesAbsolute = myLocalPlanes.size();
858 for(int i = 1; i<=aNbPlanesAbsolute; i++ ) {
859 aName = QString("Plane %1").arg(i);
860 ComboBoxPlanes->addItem( aName );
863 int aPos = ComboBoxPlanes->count() - 1;
864 ComboBoxPlanes->setCurrentIndex( aPos );
866 bool anIsControlsEnable = ( aPos >= 0 );
867 if ( anIsControlsEnable ) {
868 onSelectPlane( aPos );
871 ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );
874 if ( myCurrentClipPlaneMode == Absolute ) {
875 SpinBox_X->setEnabled( anIsControlsEnable );
876 SpinBox_Y->setEnabled( anIsControlsEnable );
877 SpinBox_Z->setEnabled( anIsControlsEnable );
878 SpinBox_Dx->setEnabled( anIsControlsEnable );
879 SpinBox_Dy->setEnabled( anIsControlsEnable );
880 SpinBox_Dz->setEnabled( anIsControlsEnable );
881 CBAbsoluteOrientation->setEnabled( anIsControlsEnable );
882 invertButton->setEnabled( anIsControlsEnable );
883 resetButton->setEnabled( anIsControlsEnable );
885 else if( myCurrentClipPlaneMode == Relative ) {
886 CBRelativeOrientation->setEnabled( anIsControlsEnable );
887 SliderDistance->setEnabled( anIsControlsEnable );
888 SliderRotation1->setEnabled( anIsControlsEnable );
889 SliderRotation2->setEnabled( anIsControlsEnable );
890 isActivePlane->setEnabled( anIsControlsEnable );
892 isActivePlane->setEnabled( anIsControlsEnable );
896 Displays preview of clipping plane
898 void OCCViewer_ClippingDlg::displayPreview()
900 if ( myBusy || !isValid() || !myModel)
903 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
905 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
907 for ( int i=0; i < clipPlanesCount(); i++ ) {
908 OCCViewer_ClipPlane& aClipPlane = getClipPlane(i);
909 if ( aClipPlane.IsOn ) {
910 Handle(AIS_Plane) myPreviewPlane;
914 clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
915 myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
916 myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
917 myPreviewPlane->SetSize( aSize, aSize );
918 ic->SetWidth( myPreviewPlane, 10, false );
919 ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
920 ic->SetTransparency( myPreviewPlane, 0.5, false );
921 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 );
922 ic->SetColor( myPreviewPlane, c , false );
923 ic->Display( myPreviewPlane, 1, 0, false );
924 myPreviewPlaneVector.push_back( myPreviewPlane );
929 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
930 getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
931 gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
932 (aYmax + aYmin) * 0.5,
933 (aZmax + aZmin) * 0.5 );
935 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
937 myInteractor->setPlanes( myPreviewPlaneVector );
938 myInteractor->setRotationCenter( aRotationCenter );
939 myInteractor->setMinMax( aMinMax );
940 myInteractor->setEnabled( true );
943 void OCCViewer_ClippingDlg::updatePreview() {
944 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
945 int count = clipPlanesCount();
951 (aCurPlaneIndex +1 > count) ||
952 !PreviewCheckBox->isChecked())
955 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
957 OCCViewer_ClipPlane& aClipPlane = getClipPlane(aCurPlaneIndex);
958 Handle(AIS_Plane) myPreviewPlane;
960 if (aClipPlane.IsOn) {
964 clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
965 if(myPreviewPlaneVector.size() < clipPlanesCount()) {
966 myPreviewPlaneVector.resize(clipPlanesCount());
968 myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
969 if(myPreviewPlane.IsNull()) {
970 //Plane was not created
971 myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
972 myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
973 myPreviewPlane->SetSize( aSize, aSize );
974 ic->Display( myPreviewPlane, 1, 0, false );
975 ic->SetWidth( myPreviewPlane, 10, false );
976 ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
977 ic->SetTransparency( myPreviewPlane, 0.5, false );
978 myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane;
980 myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) );
981 myPreviewPlane->SetCenter( aBasePnt );
982 myPreviewPlane->SetSize( aSize, aSize );
985 ic->SetColor( myPreviewPlane, Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ), false );
986 ic->Update( myPreviewPlane, Standard_False );
988 if(myPreviewPlaneVector.size() > aCurPlaneIndex ) {
989 myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
990 if(ic->IsDisplayed(myPreviewPlane)) {
991 ic->Erase( myPreviewPlane, false );
992 ic->Remove( myPreviewPlane, false );
994 myPreviewPlaneVector[aCurPlaneIndex].Nullify();
997 for(int i = 0; i < myPreviewPlaneVector.size(); i++) {
998 if( i == aCurPlaneIndex ) continue;
999 if(!myPreviewPlaneVector[i].IsNull())
1000 ic->SetColor( myPreviewPlaneVector[i], Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
1004 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
1005 getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1006 gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
1007 (aYmax + aYmin) * 0.5,
1008 (aZmax + aZmin) * 0.5 );
1010 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
1012 myInteractor->setPlanes( myPreviewPlaneVector );
1013 myInteractor->setRotationCenter( aRotationCenter );
1014 myInteractor->setMinMax( aMinMax );
1018 Erases preview of clipping plane
1020 void OCCViewer_ClippingDlg::erasePreview()
1025 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
1027 for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) {
1028 Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i];
1029 if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
1030 ic->Erase( myPreviewPlane, false );
1031 ic->Remove( myPreviewPlane, false );
1032 myPreviewPlane.Nullify();
1035 myPreviewPlaneVector.clear();
1037 myInteractor->setEnabled( false );
1041 Return true if plane parameters are valid
1043 bool OCCViewer_ClippingDlg::isValid()
1045 return ( SpinBox_Dx->value() !=0 || SpinBox_Dy->value() !=0 || SpinBox_Dz->value() !=0 );
1049 Update view after changes
1051 void OCCViewer_ClippingDlg::updateClipping()
1053 if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked())
1055 if (AutoApplyCheckBox->isChecked()) {
1059 if (!PreviewCheckBox->isChecked())
1067 Updates state of user controls.
1069 void OCCViewer_ClippingDlg::updateControls()
1071 if ( clipPlanesCount() == 0 )
1077 int aPlaneIdx = ComboBoxPlanes->currentIndex();
1079 OCCViewer_ClipPlane& aPlane = getClipPlane( aPlaneIdx );
1081 if ( aPlane.PlaneMode == Absolute )
1083 ModeStackedLayout->setCurrentIndex( 0 );
1084 myCurrentClipPlaneMode = Absolute;
1085 int anOrientation = aPlane.Orientation;
1086 // Set plane parameters in the dialog
1087 SpinBox_X->setValue( aPlane.X );
1088 SpinBox_Y->setValue( aPlane.Y );
1089 SpinBox_Z->setValue( aPlane.Z );
1090 SpinBox_Dx->setValue( aPlane.Dx );
1091 SpinBox_Dy->setValue( aPlane.Dy );
1092 SpinBox_Dz->setValue( aPlane.Dz );
1093 CBAbsoluteOrientation->setCurrentIndex( anOrientation );
1094 onOrientationAbsoluteChanged( anOrientation );
1096 else if( aPlane.PlaneMode == Relative )
1098 ModeStackedLayout->setCurrentIndex( 1 );
1099 myCurrentClipPlaneMode = Relative;
1100 int anOrientation = aPlane.RelativeMode.Orientation;
1102 // Set plane parameters in the dialog
1103 QString aFmtDistance = QString::number( aPlane.RelativeMode.Distance, '.', 2 );
1104 QString aFmtRotation1 = QString::number( floor( aPlane.RelativeMode.Rotation1 ) );
1105 QString aFmtRotation2 = QString::number( floor( aPlane.RelativeMode.Rotation2 ) );
1106 aFmtRotation1 = QString( "%1\xB0" ).arg( aFmtRotation1 );
1107 aFmtRotation2 = QString( "%1\xB0" ).arg( aFmtRotation2 );
1109 SliderDistance->setValue( aPlane.RelativeMode.Distance * 100 );
1110 TLValueDistance->setText( aFmtDistance );
1111 SliderRotation1->setValue( floor( aPlane.RelativeMode.Rotation1 ) );
1112 TLValueRotation1->setText( aFmtRotation1 );
1113 SliderRotation2->setValue( floor( aPlane.RelativeMode.Rotation2 ) );
1114 TLValueRotation2->setText( aFmtRotation2 );
1115 CBRelativeOrientation->setCurrentIndex( anOrientation );
1116 onOrientationRelativeChanged( anOrientation );
1119 isActivePlane->setChecked( aPlane.IsOn );
1123 SLOT on new button click: create a new clipping plane
1125 void OCCViewer_ClippingDlg::ClickOnNew()
1127 OCCViewer_ClipPlane aPlane;
1128 aPlane.PlaneMode = (ClipPlaneMode )myCurrentClipPlaneMode;
1129 myLocalPlanes.push_back(aPlane);
1134 SLOT on delete button click: Delete selected clipping plane
1136 void OCCViewer_ClippingDlg::ClickOnDelete()
1138 int aPlaneIndex = ComboBoxPlanes->currentIndex();
1139 if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount()))
1142 myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex);
1144 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
1146 if(aPlaneIndex+1 <= myPreviewPlaneVector.size()) {
1147 Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[aPlaneIndex];
1148 if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
1149 ic->Erase( myPreviewPlane, false );
1150 ic->Remove( myPreviewPlane, false );
1152 myPreviewPlaneVector.erase(myPreviewPlaneVector.begin() + aPlaneIndex);
1155 if (AutoApplyCheckBox->isChecked()) {
1162 SLOT on disable all button click: Restore initial state of viewer,
1163 erase all clipping planes
1165 void OCCViewer_ClippingDlg::ClickOnDisableAll()
1167 AutoApplyCheckBox->setChecked (false);
1168 int aClipPlanesCount = clipPlanesCount();
1169 for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++)
1171 OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex);
1172 aPlane.IsOn = false;
1175 isActivePlane->setChecked(false);
1176 myModel->setClipPlanes(myLocalPlanes);
1181 SLOT on ok button click: sets cutting plane and closes dialog
1183 void OCCViewer_ClippingDlg::ClickOnOk()
1190 SLOT on Apply button click: sets cutting plane and update viewer
1192 void OCCViewer_ClippingDlg::ClickOnApply()
1199 SLOT on close button click: erases preview and rejects dialog
1201 void OCCViewer_ClippingDlg::ClickOnClose()
1204 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
1206 v->onClipping(false);
1210 SLOT on help button click: opens a help page
1212 void OCCViewer_ClippingDlg::ClickOnHelp()
1214 SUIT_Application* app = SUIT_Session::session()->activeApplication();
1216 app->onHelpContextModule( "GUI", "occ_3d_viewer_page.html", "clipping_planes" );
1220 Set absolute mode of clipping plane
1222 void OCCViewer_ClippingDlg::onModeAbsolute()
1224 myIsPlaneCreation = true;
1225 ModeStackedLayout->setCurrentIndex(0);
1226 myCurrentClipPlaneMode = Absolute;
1228 myIsPlaneCreation = false;
1233 Set relative mode of clipping plane
1235 void OCCViewer_ClippingDlg::onModeRelative()
1237 myIsPlaneCreation = true;
1238 ModeStackedLayout->setCurrentIndex(1);
1239 myCurrentClipPlaneMode = Relative;
1241 myIsPlaneCreation = false;
1242 SetCurrentPlaneParam();
1247 SLOT: called on value of clipping plane changed
1249 void OCCViewer_ClippingDlg::onValueChanged()
1251 if ( myIsUpdatingControls )
1256 SetCurrentPlaneParam();
1258 if ( myIsSelectPlane )
1267 Set current parameters of selected plane
1269 void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )
1271 if ( clipPlanesCount() == 0 )
1276 OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex );
1278 myIsSelectPlane = true;
1280 ComboBoxPlanes->setCurrentIndex( theIndex );
1281 myIsSelectPlane = false;
1285 Restore parameters of selected plane
1287 void OCCViewer_ClippingDlg::SetCurrentPlaneParam()
1289 if ( clipPlanesCount() == 0 || myIsSelectPlane )
1292 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1294 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
1296 if ( aPlane.PlaneMode == Absolute )
1298 aPlane.Orientation = CBAbsoluteOrientation->currentIndex();
1299 aPlane.X = SpinBox_X->value();
1300 aPlane.Y = SpinBox_Y->value();
1301 aPlane.Z = SpinBox_Z->value();
1302 aPlane.Dx = SpinBox_Dx->value();
1303 aPlane.Dy = SpinBox_Dy->value();
1304 aPlane.Dz = SpinBox_Dz->value();
1305 absolutePlaneToRelative( aPlane, myModel->getAISContext(),myModel->trihedronSize() );
1307 else if( aPlane.PlaneMode == Relative )
1309 aPlane.RelativeMode.Orientation = CBRelativeOrientation->currentIndex();
1310 aPlane.RelativeMode.Distance = TLValueDistance->text().toDouble();
1311 aPlane.RelativeMode.Rotation1 = TLValueRotation1->text().remove("\xB0").toInt();
1312 aPlane.RelativeMode.Rotation2 = TLValueRotation2->text().remove("\xB0").toInt();
1313 relativePlaneToAbsolute( aPlane, myModel->getAISContext(),myModel->trihedronSize() );
1315 aPlane.IsOn = isActivePlane->isChecked();
1319 SLOT on reset button click: sets default values
1321 void OCCViewer_ClippingDlg::onReset()
1324 SpinBox_X->setValue(0);
1325 SpinBox_Y->setValue(0);
1326 SpinBox_Z->setValue(0);
1333 SLOT on invert button click: inverts normal of cutting plane
1335 void OCCViewer_ClippingDlg::onInvert()
1337 double Dx = SpinBox_Dx->value();
1338 double Dy = SpinBox_Dy->value();
1339 double Dz = SpinBox_Dz->value();
1342 SpinBox_Dx->setValue( -Dx );
1343 SpinBox_Dy->setValue( -Dy );
1344 SpinBox_Dz->setValue( -Dz );
1347 if ( clipPlanesCount() != 0 ) {
1348 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1349 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
1350 aPlane.IsInvert = !aPlane.IsInvert;
1356 SLOT: called on orientation of clipping plane in absolute mode changed
1358 void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )
1360 bool isUserMode = (mode==0);
1362 TextLabelX->setEnabled( isUserMode );
1363 TextLabelY->setEnabled( isUserMode );
1364 TextLabelZ->setEnabled( isUserMode );
1366 SpinBox_X->setEnabled( isUserMode );
1367 SpinBox_Y->setEnabled( isUserMode );
1368 SpinBox_Z->setEnabled( isUserMode );
1370 TextLabelDx->setEnabled( isUserMode );
1371 TextLabelDy->setEnabled( isUserMode );
1372 TextLabelDz->setEnabled( isUserMode );
1374 SpinBox_Dx->setEnabled( isUserMode );
1375 SpinBox_Dy->setEnabled( isUserMode );
1376 SpinBox_Dz->setEnabled( isUserMode );
1378 if ( !isUserMode ) {
1380 double aDx = 0, aDy = 0, aDz = 0;
1385 TextLabelZ->setEnabled( true );
1386 SpinBox_Z->setEnabled( true );
1387 SpinBox_Z->setFocus();
1389 else if ( mode == 2 )
1392 TextLabelX->setEnabled( true );
1393 SpinBox_X->setEnabled( true );
1394 SpinBox_X->setFocus();
1396 else if ( mode == 3 )
1399 TextLabelY->setEnabled( true );
1400 SpinBox_Y->setEnabled( true );
1401 SpinBox_Y->setFocus();
1404 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1405 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
1406 if ( aPlane.IsInvert == true ) {
1407 aDx = -aDx; aDy = -aDy; aDz = -aDz;
1411 SpinBox_Dx->setValue( aDx );
1412 SpinBox_Dy->setValue( aDy );
1413 SpinBox_Dz->setValue( aDz );
1417 if ( !myIsUpdatingControls )
1419 SetCurrentPlaneParam();
1425 SLOT: called on orientation of clipping plane in relative mode changed
1427 void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)
1429 if ( clipPlanesCount() == 0 )
1432 if ( theItem == 0 ) {
1433 TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );
1434 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );
1436 else if ( theItem == 1 ) {
1437 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) );
1438 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) );
1440 else if ( theItem == 2 ) {
1441 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) );
1442 TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );
1445 if ( !myIsUpdatingControls )
1447 if( (QComboBox*)sender() == CBRelativeOrientation )
1449 SetCurrentPlaneParam();
1457 SLOT: called on preview check box toggled
1459 void OCCViewer_ClippingDlg::onPreview( bool on )
1467 SLOT: called on Auto Apply check box toggled
1469 void OCCViewer_ClippingDlg::onAutoApply( bool toggled )
1478 SLOT on Apply button click: sets cutting plane
1480 void OCCViewer_ClippingDlg::onApply()
1484 myIsSelectPlane = true;
1486 qApp->processEvents();
1487 QApplication::setOverrideCursor( Qt::WaitCursor );
1488 qApp->processEvents();
1490 myModel->setClipPlanes(myLocalPlanes);
1492 QApplication::restoreOverrideCursor();
1493 myIsSelectPlane = false;
1497 SLOT: Called when clip plane is clicked in viewer.
1499 void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane )
1501 for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
1503 Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
1504 if ( aPlane != thePlane )
1509 ComboBoxPlanes->setCurrentIndex( aPlaneIt );
1516 SLOT: Called when clip plane is changed by dragging in viewer.
1518 void OCCViewer_ClippingDlg::onPlaneDragged( const Handle(AIS_Plane)& thePlane )
1520 for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
1522 Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
1523 if ( aPlane != thePlane )
1528 OCCViewer_ClipPlane& aClipPlane = getClipPlane( aPlaneIt );
1530 gp_Pln aPln = thePlane->Component()->Pln();
1531 const gp_Pnt& aPlaneP = aPln.Location();
1532 const gp_Dir& aPlaneN = aPln.Axis().Direction();
1534 aClipPlane.X = aPlaneP.X();
1535 aClipPlane.Y = aPlaneP.Y();
1536 aClipPlane.Z = aPlaneP.Z();
1537 aClipPlane.Dx = aPlaneN.X();
1538 aClipPlane.Dy = aPlaneN.Y();
1539 aClipPlane.Dz = aPlaneN.Z();
1540 absolutePlaneToRelative( aClipPlane, myModel->getAISContext(), myModel->trihedronSize() );
1542 myIsUpdatingControls = true;
1544 myIsUpdatingControls = false;
1546 if ( AutoApplyCheckBox->isChecked() )
1556 SLOT: Called when value of slider distance change
1558 void OCCViewer_ClippingDlg::SliderDistanceHasMoved( int value )
1560 double new_value = value/100.;
1561 TLValueDistance->setText( QString("%1").arg( new_value ) );
1566 SLOT: Called when value of slider rotation1 change
1568 void OCCViewer_ClippingDlg::SliderRotation1HasMoved( int value )
1570 TLValueRotation1->setText( QString("%1\xB0").arg( value ) );
1575 SLOT: Called when value of slider rotation2 change
1577 void OCCViewer_ClippingDlg::SliderRotation2HasMoved( int value )
1579 TLValueRotation2->setText( QString("%1\xB0").arg( value ) );
1583 OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx )
1585 return myLocalPlanes[theIdx];
1588 int OCCViewer_ClippingDlg::clipPlanesCount()
1590 return myLocalPlanes.size();