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 <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 <V3d_View.hxx>
41 #include <Visual3d_View.hxx>
42 #include <Geom_Plane.hxx>
43 #include <Prs3d_Presentation.hxx>
44 #include <AIS_ListIteratorOfListOfInteractive.hxx>
45 #include <AIS_ListOfInteractive.hxx>
46 #include <AIS_InteractiveObject.hxx>
47 #include <AIS_InteractiveContext.hxx>
48 #include <IntAna_IntConicQuad.hxx>
54 #include <QApplication>
56 #include <QHBoxLayout>
57 #include <QVBoxLayout>
58 #include <QGridLayout>
60 #include <QPushButton>
63 #include <QStackedLayout>
67 /**********************************************************************************
68 ************************ Internal functions ************************
69 *********************************************************************************/
71 void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic,
72 double theDefaultSize,
80 double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
81 aXMin = aYMin = aZMin = DBL_MAX;
82 aXMax = aYMax = aZMax = -DBL_MAX;
85 AIS_ListOfInteractive aList;
86 ic->DisplayedObjects( aList );
87 for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) {
88 Handle(AIS_InteractiveObject) anObj = it.Value();
89 if ( !anObj.IsNull() && anObj->HasPresentation() &&
90 !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) {
91 Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
92 if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) {
94 double xmin, ymin, zmin, xmax, ymax, zmax;
95 aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );
96 aXMin = qMin( aXMin, xmin ); aXMax = qMax( aXMax, xmax );
97 aYMin = qMin( aYMin, ymin ); aYMax = qMax( aYMax, ymax );
98 aZMin = qMin( aZMin, zmin ); aZMax = qMax( aZMax, zmax );
104 if(theDefaultSize == 0.0)
105 theDefaultSize = 100.;
106 aXMin = aYMin = aZMin = -theDefaultSize;
107 aXMax = aYMax = aZMax = theDefaultSize;
109 theXMin = aXMin;theYMin = aYMin;theZMin = aZMin;
110 theXMax = aXMax;theYMax = aYMax;theZMax = aZMax;
114 Compute the point of bounding box and current clipping plane
116 void ComputeBoundsParam( double theBounds[6],
117 double theDirection[3],
119 double& theMaxBoundPrj,
120 double& theMinBoundPrj )
122 //Enlarge bounds in order to avoid conflicts of precision
123 for(int i = 0; i < 6; i += 2) {
124 static double EPS = 1.0E-3;
125 double aDelta = (theBounds[i+1] - theBounds[i])*EPS;
126 theBounds[i] -= aDelta;
127 theBounds[i+1] += aDelta;
130 double aBoundPoints[8][3] = { { theBounds[0], theBounds[2], theBounds[4] },
131 { theBounds[1], theBounds[2], theBounds[4] },
132 { theBounds[0], theBounds[3], theBounds[4] },
133 { theBounds[1], theBounds[3], theBounds[4] },
134 { theBounds[0], theBounds[2], theBounds[5] },
135 { theBounds[1], theBounds[2], theBounds[5] },
136 { theBounds[0], theBounds[3], theBounds[5] },
137 { theBounds[1], theBounds[3], theBounds[5] } };
140 theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1]
141 + theDirection[2] * aBoundPoints[aMaxId][2];
142 theMinBoundPrj = theMaxBoundPrj;
143 for(int i = 1; i < 8; i++) {
144 double aTmp = theDirection[0] * aBoundPoints[i][0] + theDirection[1] * aBoundPoints[i][1]
145 + theDirection[2] * aBoundPoints[i][2];
146 if(theMaxBoundPrj < aTmp) {
147 theMaxBoundPrj = aTmp;
150 if(theMinBoundPrj > aTmp) {
151 theMinBoundPrj = aTmp;
154 double *aMinPnt = aBoundPoints[aMaxId];
155 theMinPnt[0] = aMinPnt[0];
156 theMinPnt[1] = aMinPnt[1];
157 theMinPnt[2] = aMinPnt[2];
161 Compute the position of current plane by distance
163 void DistanceToPosition( double theBounds[6],
164 double theDirection[3],
168 double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
169 ComputeBoundsParam( theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj );
170 double aLength = (aMaxBoundPrj - aMinBoundPrj)*theDist;
171 thePos[0] = aMinPnt[0] - theDirection[0]*aLength;
172 thePos[1] = aMinPnt[1] - theDirection[1]*aLength;
173 thePos[2] = aMinPnt[2] - theDirection[2]*aLength;
177 Compute the parameters of clipping plane
179 bool ComputeClippingPlaneParameters( double theNormal[3],
182 Handle(AIS_InteractiveContext) ic,
183 double theDefaultSize)
185 double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
186 getMinMaxFromContext(ic,theDefaultSize,aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5]);
188 DistanceToPosition( aBounds, theNormal, theDist, theOrigin );
193 Cross product of two 3-vectors. Result vector in result[3].
195 void Cross(const double first[3], const double second[3], double result[3])
197 result[0] = first[1]*second[2] - first[2]*second[1];
198 result[1] = first[2]*second[0] - first[0]*second[2];
199 result[2] = first[0]*second[1] - first[1]*second[0];
203 Compute relative clipping plane in absolute coordinates
205 void relativePlaneToAbsolute (OCCViewer_ClipPlane& thePlane, Handle(AIS_InteractiveContext) ic, double theDefaultSize )
208 double aDir[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } };
210 static double aCoeff = M_PI/180.0;
212 double anU[2] = { cos( aCoeff * thePlane.RelativeMode.Rotation1 ), cos( aCoeff * thePlane.RelativeMode.Rotation2 ) };
213 double aV[2] = { sqrt( 1.0 - anU[0]*anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) };
214 aV[0] = thePlane.RelativeMode.Rotation1 > 0? aV[0]: -aV[0];
215 aV[1] = thePlane.RelativeMode.Rotation2 > 0? aV[1]: -aV[1];
217 switch ( thePlane.RelativeMode.Orientation ) {
238 Cross( aDir[1], aDir[0], aNormal );
241 den = sqrt( aNormal[0] * aNormal[0] + aNormal[1] * aNormal[1] + aNormal[2] * aNormal[2] );
243 for (int i=0; i < 3; i++) {
251 anOrigin[0] = anOrigin[1] = anOrigin[2] = 0;
254 anIsOk = ComputeClippingPlaneParameters( aNormal,
255 thePlane.RelativeMode.Distance,
261 thePlane.X = anOrigin[0];
262 thePlane.Y = anOrigin[1];
263 thePlane.Z = anOrigin[2];
264 thePlane.Dx = aNormal[0];
265 thePlane.Dy = aNormal[1];
266 thePlane.Dz = aNormal[2];
270 \brief Converts absolute plane definition to relative system.
271 \param thePlane [in/out] the plane to convert.
272 \param theIC [in] the interactive context.
273 \param theDefaultSize [in] the default trihedron size.
275 void absolutePlaneToRelative( OCCViewer_ClipPlane& thePlane, Handle(AIS_InteractiveContext) theIC, double theDefaultSize )
277 gp_Pnt aPlaneP( thePlane.X, thePlane.Y, thePlane.Z );
278 gp_Dir aPlaneN( thePlane.Dx, thePlane.Dy, thePlane.Dz );
280 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
282 getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
285 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
287 gp_Trsf aRelativeTransform;
288 aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) );
289 Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform );
291 aRelativeBounds.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
293 double aLength = aZmax - aZmin;
294 double aDistance = aZmax;
296 double aRelativeDistance = aLength > 0.01 ? aDistance / aLength : 0.0;
297 aRelativeDistance = qMin( aRelativeDistance, aLength );
298 aRelativeDistance = qMax( aRelativeDistance, 0.0 );
299 thePlane.RelativeMode.Distance = aRelativeDistance;
301 const gp_Dir& aDX = gp::DX();
302 const gp_Dir& aDY = gp::DY();
303 const gp_Dir& aDZ = gp::DZ();
306 switch ( thePlane.RelativeMode.Orientation )
310 if ( aDY.IsParallel( aPlaneN, Precision::Angular() ) )
317 if ( aDX.IsParallel( aPlaneN, Precision::Angular() ) )
324 gp_Dir aDir1 = aPlaneN ^ aDX;
325 gp_Dir aDir2 = aDY ^ aPlaneN;
326 gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDY ^ aPlaneN );
328 if ( aDir1 * aRightHand.YDirection() < 0.0 )
332 if ( aDir2 * aRightHand.XDirection() < 0.0 )
337 anAng1 = aDY.AngleWithRef( aDir1, aDX );
338 anAng2 = aDX.AngleWithRef( aDir2, -aDY );
343 if ( aDZ.IsParallel( aPlaneN, Precision::Angular() ) )
350 if ( aDY.IsParallel( aPlaneN, Precision::Angular() ) )
357 gp_Dir aDir1 = aPlaneN ^ aDY;
358 gp_Dir aDir2 = aDZ ^ aPlaneN;
359 gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDZ ^ aPlaneN );
361 if ( aDir1 * aRightHand.YDirection() < 0.0 )
365 if ( aDir2 * aRightHand.XDirection() < 0.0 )
370 anAng1 = aDZ.AngleWithRef( aDir1, aDY );
371 anAng2 = aDY.AngleWithRef( aDir2, -aDZ );
376 if ( aDX.IsParallel( aPlaneN, Precision::Angular() ) )
383 if ( aDZ.IsParallel( aPlaneN, Precision::Angular() ) )
390 gp_Dir aDir1 = aPlaneN ^ aDZ;
391 gp_Dir aDir2 = aDX ^ aPlaneN;
392 gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDX ^ aPlaneN );
394 if ( aDir1 * aRightHand.YDirection() < 0.0 )
398 if ( aDir2 * aRightHand.XDirection() < 0.0 )
403 anAng1 = aDX.AngleWithRef( aDir1, aDZ );
404 anAng2 = aDZ.AngleWithRef( aDir2, -aDX );
409 thePlane.RelativeMode.Rotation1 = anAng1 * ( 180.0 / M_PI );
410 thePlane.RelativeMode.Rotation2 = anAng2 * ( 180.0 / M_PI );
414 Compute clipping plane size base point and normal
417 void clipPlaneParams(OCCViewer_ClipPlane& theClipPlane, Handle(AIS_InteractiveContext) theContext,
418 double& theSize, gp_Pnt& theBasePnt, gp_Dir& theNormal, double defaultSize) {
419 double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
420 aXMin = aYMin = aZMin = DBL_MAX;
421 aXMax = aYMax = aZMax = -DBL_MAX;
423 getMinMaxFromContext(theContext,defaultSize,aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
427 gp_Pnt aBasePnt(theClipPlane.X , theClipPlane.Y , theClipPlane.Z);
428 gp_Dir aNormal(theClipPlane.Dx, theClipPlane.Dy, theClipPlane.Dz );
430 // compute clipping plane size
431 gp_Pnt aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
432 double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2;
435 // compute clipping plane center ( redefine the base point )
436 IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
438 intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
440 if ( intersector.IsDone() && intersector.NbPoints() == 1 )
441 aBasePnt = intersector.Point( 1 );
444 theBasePnt = aBasePnt;
449 /*********************************************************************************
450 ********************* class OCCViewer_ClippingDlg *********************
451 *********************************************************************************/
454 \param view - view window
455 \param parent - parent widget
457 OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model)
458 : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
459 myCurrentClipPlaneMode (Absolute)
461 setObjectName( "OCCViewer_ClippingDlg" );
464 setWindowTitle( tr( "Clipping" ) );
466 setAttribute (Qt::WA_DeleteOnClose, true);
468 QVBoxLayout* topLayout = new QVBoxLayout( this );
469 topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
471 /***************************************************************/
472 // Controls for selecting, creating, deleting planes
473 QGroupBox* GroupPlanes = new QGroupBox( tr("CLIPPING_PLANES"), this );
474 QHBoxLayout* GroupPlanesLayout = new QHBoxLayout( GroupPlanes );
475 ComboBoxPlanes = new QComboBox( GroupPlanes );
476 isActivePlane = new QCheckBox( tr("IS_ACTIVE_PLANE"), this );
477 buttonNew = new QPushButton( tr("BTN_NEW"), GroupPlanes );
478 buttonDelete = new QPushButton( tr("BTN_DELETE"), GroupPlanes );
479 buttonDisableAll = new QPushButton( tr("BTN_DISABLE_ALL"), GroupPlanes );
480 MenuMode = new QMenu( "MenuMode", buttonNew );
481 MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );
482 MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );
483 buttonNew->setMenu( MenuMode );
485 GroupPlanesLayout->addWidget( ComboBoxPlanes );
486 GroupPlanesLayout->addWidget( isActivePlane );
487 GroupPlanesLayout->addWidget( buttonNew );
488 GroupPlanesLayout->addWidget( buttonDelete );
489 GroupPlanesLayout->addWidget( buttonDisableAll );
491 ModeStackedLayout = new QStackedLayout();
493 /********************** Mode Absolute **********************/
494 /* Controls for absolute mode of clipping plane:
495 X, Y, Z - coordinates of the intersection of cutting plane and the three axes
496 Dx, Dy, Dz - components of normal to the cutting plane
497 Orientation - direction of cutting plane
499 const double min = -1e+7;
500 const double max = 1e+7;
501 const double step = 5;
502 const int precision = -7;
505 QGroupBox* GroupAbsolutePoint = new QGroupBox( this );
506 GroupAbsolutePoint->setObjectName( "GroupPoint" );
507 GroupAbsolutePoint->setTitle( tr("BASE_POINT") );
508 QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint );
509 GroupPointLayout->setAlignment( Qt::AlignTop );
510 GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 );
512 TextLabelX = new QLabel( GroupAbsolutePoint );
513 TextLabelX->setObjectName( "TextLabelX" );
514 TextLabelX->setText( tr("X:") );
515 GroupPointLayout->addWidget( TextLabelX, 0, 0 );
517 SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
518 SpinBox_X->setObjectName("SpinBox_X" );
519 SpinBox_X->setPrecision( precision );
520 GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
522 TextLabelY = new QLabel( GroupAbsolutePoint );
523 TextLabelY->setObjectName( "TextLabelY" );
524 TextLabelY->setText( tr("Y:") );
525 GroupPointLayout->addWidget( TextLabelY, 0, 2 );
527 SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
528 SpinBox_Y->setObjectName("SpinBox_Y" );
529 SpinBox_Y->setPrecision( precision );
530 GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
532 TextLabelZ = new QLabel( GroupAbsolutePoint );
533 TextLabelZ->setObjectName( "TextLabelZ" );
534 TextLabelZ->setText( tr("Z:") );
535 GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
537 SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
538 SpinBox_Z->setObjectName("SpinBox_Z" );
539 SpinBox_Z->setPrecision( precision );
540 GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
542 resetButton = new QPushButton( GroupAbsolutePoint );
543 resetButton->setObjectName( "resetButton" );
544 resetButton->setText( tr( "RESET" ) );
545 GroupPointLayout->addWidget( resetButton, 0, 6 );
548 GroupAbsoluteDirection = new QGroupBox( this );
549 GroupAbsoluteDirection->setObjectName( "GroupDirection" );
550 GroupAbsoluteDirection->setTitle( tr("DIRECTION") );
551 QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection );
552 GroupDirectionLayout->setAlignment( Qt::AlignTop );
553 GroupDirectionLayout->setSpacing( 6 );
554 GroupDirectionLayout->setMargin( 11 );
556 TextLabelDx = new QLabel( GroupAbsoluteDirection );
557 TextLabelDx->setObjectName( "TextLabelDx" );
558 TextLabelDx->setText( tr("Dx:") );
559 GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
561 SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
562 SpinBox_Dx->setObjectName("SpinBox_Dx" );
563 SpinBox_Dx->setPrecision( precision );
564 GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
566 TextLabelDy = new QLabel( GroupAbsoluteDirection );
567 TextLabelDy->setObjectName( "TextLabelDy" );
568 TextLabelDy->setText( tr("Dy:") );
569 GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
571 SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
572 SpinBox_Dy->setObjectName("SpinBox_Dy" );
573 SpinBox_Dy->setPrecision( precision );
574 GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
576 TextLabelDz = new QLabel( GroupAbsoluteDirection );
577 TextLabelDz->setObjectName( "TextLabelDz" );
578 TextLabelDz->setText( tr("Dz:") );
579 GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
581 SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
582 SpinBox_Dz->setObjectName("SpinBox_Dz" );
583 SpinBox_Dz->setPrecision( precision );
584 GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
586 invertButton = new QPushButton( GroupAbsoluteDirection );
587 invertButton->setObjectName( "invertButton" );
588 invertButton->setText( tr( "INVERT" ) );
589 GroupDirectionLayout->addWidget( invertButton, 0, 6 );
591 CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection );
592 CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" );
593 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) );
594 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) );
595 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) );
596 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) );
597 GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 );
599 QVBoxLayout* ModeActiveLayout = new QVBoxLayout();
600 ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 );
601 ModeActiveLayout->addWidget( GroupAbsolutePoint );
602 ModeActiveLayout->addWidget( GroupAbsoluteDirection );
604 QWidget* ModeActiveWidget = new QWidget( this );
605 ModeActiveWidget->setLayout( ModeActiveLayout );
607 /********************** Mode Relative **********************/
608 /* Controls for relative mode of clipping plane:
609 Distance - Value from 0 to 1.
610 Specifies the distance from the minimum value in a given direction of bounding box to the current position
611 Rotation1, Rotation2 - turn angles of cutting plane in given directions
612 Orientation - direction of cutting plane
614 QGroupBox* GroupParameters = new QGroupBox( tr("PARAMETERS"), this );
615 QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );
616 GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 );
618 TextLabelOrientation = new QLabel( tr("ORIENTATION"), GroupParameters);
619 TextLabelOrientation->setObjectName( "TextLabelOrientation" );
620 GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
622 CBRelativeOrientation = new QComboBox(GroupParameters);
623 CBRelativeOrientation->setObjectName( "RelativeOrientation" );
624 CBRelativeOrientation->addItem( tr("ALONG_XY") );
625 CBRelativeOrientation->addItem( tr("ALONG_YZ") );
626 CBRelativeOrientation->addItem( tr("ALONG_ZX") );
627 GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );
629 TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters );
630 TextLabelDistance->setObjectName( "TextLabelDistance" );
631 GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 );
633 SpinSliderDistance = new QtxDoubleSpinSlider( 0., 1., 0.01, GroupParameters );
634 SpinSliderDistance->setObjectName( "SpinSliderDistance" );
635 SpinSliderDistance->setPrecision( precision );
636 QFont fnt = SpinSliderDistance->font(); fnt.setBold( true ); SpinSliderDistance->setFont( fnt );
637 GroupParametersLayout->addWidget( SpinSliderDistance, 1, 1 );
639 QString aUnitRot = "\xB0";
641 TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters );
642 TextLabelRotation1->setObjectName( "TextLabelRotation1" );
643 GroupParametersLayout->addWidget( TextLabelRotation1, 2, 0 );
645 SpinSliderRotation1 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );
646 SpinSliderRotation1->setObjectName( "SpinSliderRotation1" );
647 SpinSliderRotation1->setUnit( aUnitRot );
648 SpinSliderRotation1->setFont( fnt );
649 GroupParametersLayout->addWidget( SpinSliderRotation1, 2, 1 );
651 TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);
652 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
653 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
654 GroupParametersLayout->addWidget( TextLabelRotation2, 3, 0 );
656 SpinSliderRotation2 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );
657 SpinSliderRotation2->setObjectName( "SpinSliderRotation2" );
658 SpinSliderRotation2->setUnit( aUnitRot );
659 SpinSliderRotation2->setFont( fnt );
660 GroupParametersLayout->addWidget( SpinSliderRotation2, 3, 1 );
662 /***************************************************************/
663 QGroupBox* CheckBoxWidget = new QGroupBox( this );
664 QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget );
666 PreviewCheckBox = new QCheckBox( tr("PREVIEW"), CheckBoxWidget );
667 PreviewCheckBox->setObjectName( "PreviewCheckBox" );
668 PreviewCheckBox->setChecked( true );
669 CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter );
671 AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget );
672 AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" );
673 CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter );
675 /***************************************************************/
676 QGroupBox* GroupButtons = new QGroupBox( this );
677 QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );
678 GroupButtonsLayout->setAlignment( Qt::AlignTop );
679 GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );
681 buttonOk = new QPushButton( GroupButtons );
682 buttonOk->setObjectName( "buttonOk" );
683 buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE" ) );
684 buttonOk->setAutoDefault( TRUE );
685 buttonOk->setDefault( TRUE );
686 GroupButtonsLayout->addWidget( buttonOk );
688 buttonApply = new QPushButton( GroupButtons );
689 buttonApply->setObjectName( "buttonApply" );
690 buttonApply->setText( tr( "BUT_APPLY" ) );
691 buttonApply->setAutoDefault( TRUE );
692 buttonApply->setDefault( TRUE );
693 GroupButtonsLayout->addWidget( buttonApply );
695 GroupButtonsLayout->addStretch();
697 buttonClose = new QPushButton( GroupButtons );
698 buttonClose->setObjectName( "buttonClose" );
699 buttonClose->setText( tr( "BUT_CLOSE" ) );
700 buttonClose->setAutoDefault( TRUE );
701 GroupButtonsLayout->addWidget( buttonClose );
703 QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons );
704 buttonHelp->setAutoDefault( TRUE );
705 GroupButtonsLayout->addWidget( buttonHelp );
707 /***************************************************************/
708 ModeStackedLayout->addWidget( ModeActiveWidget );
709 ModeStackedLayout->addWidget( GroupParameters );
711 topLayout->addWidget( GroupPlanes );
712 topLayout->addLayout( ModeStackedLayout );
713 topLayout->addWidget( CheckBoxWidget );
714 topLayout->addWidget( GroupButtons );
716 this->setLayout( topLayout );
721 // Signals and slots connections
722 connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) );
723 connect( isActivePlane, SIGNAL ( toggled ( bool ) ), this, SLOT( onValueChanged() ) );
724 connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) );
725 connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );
726 connect( buttonDisableAll, SIGNAL( clicked() ), this, SLOT( ClickOnDisableAll() ) );
728 connect( resetButton, SIGNAL (clicked() ), this, SLOT( onReset() ) );
729 connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
730 connect( SpinBox_X, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
731 connect( SpinBox_Y, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
732 connect( SpinBox_Z, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
733 connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
734 connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
735 connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
736 connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ;
738 connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( int ) ) );
739 connect( SpinSliderDistance, SIGNAL( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
740 connect( SpinSliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
741 connect( SpinSliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
743 connect( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;
744 connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) );
746 connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;
747 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
748 connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
749 connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
752 myIsSelectPlane = false;
753 myIsPlaneCreation = false;
754 myIsUpdatingControls = false;
757 myModel->getViewer3d()->InitActiveViews();
759 OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) myModel->getViewManager();
760 myInteractor = new OCCViewer_ClipPlaneInteractor( aViewMgr, this );
761 connect( myInteractor, SIGNAL( planeClicked( const Handle_AIS_Plane& ) ), SLOT( onPlaneClicked( const Handle_AIS_Plane& ) ) );
762 connect( myInteractor, SIGNAL( planeDragged( const Handle_AIS_Plane& ) ), SLOT( onPlaneDragged( const Handle_AIS_Plane& ) ) );
764 myLocalPlanes = myModel->getClipPlanes();
770 Destroys the object and frees any allocated resources
772 OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg()
774 myLocalPlanes.clear();
778 Custom handling of close event: erases preview
780 void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
783 QDialog::closeEvent( e );
784 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
786 v->onClipping(false);
790 Custom handling of show event: displays preview
792 void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )
794 QDialog::showEvent( e );
795 onPreview( PreviewCheckBox->isChecked() );
799 Custom handling of hide event: erases preview
801 void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
804 QDialog::hideEvent( e );
805 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
807 v->onClipping(false);
812 Initialization of initial values of widgets
814 void OCCViewer_ClippingDlg::initParam()
816 SpinBox_X->setValue( 0.0 );
817 SpinBox_Y->setValue( 0.0 );
818 SpinBox_Z->setValue( 0.0 );
820 SpinBox_Dx->setValue( 1.0 );
821 SpinBox_Dy->setValue( 1.0 );
822 SpinBox_Dz->setValue( 1.0 );
824 CBAbsoluteOrientation->setCurrentIndex(0);
826 SpinSliderDistance->setValue( 0.5 );
827 SpinSliderRotation1->setValue( 0 );
828 SpinSliderRotation2->setValue( 0 );
829 CBRelativeOrientation->setCurrentIndex( 0 );
833 Synchronize dialog's widgets with data
835 void OCCViewer_ClippingDlg::synchronize()
837 ComboBoxPlanes->clear();
838 int aNbPlanesAbsolute = myLocalPlanes.size();
841 for(int i = 1; i<=aNbPlanesAbsolute; i++ ) {
842 aName = QString("Plane %1").arg(i);
843 ComboBoxPlanes->addItem( aName );
846 int aPos = ComboBoxPlanes->count() - 1;
847 ComboBoxPlanes->setCurrentIndex( aPos );
849 bool anIsControlsEnable = ( aPos >= 0 );
850 if ( anIsControlsEnable ) {
851 onSelectPlane( aPos );
854 ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );
857 if ( myCurrentClipPlaneMode == Absolute ) {
858 SpinBox_X->setEnabled( anIsControlsEnable );
859 SpinBox_Y->setEnabled( anIsControlsEnable );
860 SpinBox_Z->setEnabled( anIsControlsEnable );
861 SpinBox_Dx->setEnabled( anIsControlsEnable );
862 SpinBox_Dy->setEnabled( anIsControlsEnable );
863 SpinBox_Dz->setEnabled( anIsControlsEnable );
864 CBAbsoluteOrientation->setEnabled( anIsControlsEnable );
865 invertButton->setEnabled( anIsControlsEnable );
866 resetButton->setEnabled( anIsControlsEnable );
868 else if( myCurrentClipPlaneMode == Relative ) {
869 CBRelativeOrientation->setEnabled( anIsControlsEnable );
870 SpinSliderDistance->setEnabled( anIsControlsEnable );
871 SpinSliderRotation1->setEnabled( anIsControlsEnable );
872 SpinSliderRotation2->setEnabled( anIsControlsEnable );
873 isActivePlane->setEnabled( anIsControlsEnable );
875 isActivePlane->setEnabled( anIsControlsEnable );
879 Displays preview of clipping plane
881 void OCCViewer_ClippingDlg::displayPreview()
883 if ( myBusy || !isValid() || !myModel)
886 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
888 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
890 for ( int i=0; i < clipPlanesCount(); i++ ) {
891 OCCViewer_ClipPlane& aClipPlane = getClipPlane(i);
892 if ( aClipPlane.IsOn ) {
893 Handle(AIS_Plane) myPreviewPlane;
897 clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
898 myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
899 myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
900 myPreviewPlane->SetSize( aSize, aSize );
901 ic->SetWidth( myPreviewPlane, 10, false );
902 ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
903 ic->SetTransparency( myPreviewPlane, 0.5, false );
904 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 );
905 ic->SetColor( myPreviewPlane, c , false );
906 ic->Display( myPreviewPlane, 1, 0, false );
907 myPreviewPlaneVector.push_back( myPreviewPlane );
912 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
913 getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
914 gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
915 (aYmax + aYmin) * 0.5,
916 (aZmax + aZmin) * 0.5 );
918 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
920 myInteractor->setPlanes( myPreviewPlaneVector );
921 myInteractor->setRotationCenter( aRotationCenter );
922 myInteractor->setMinMax( aMinMax );
923 myInteractor->setEnabled( true );
926 void OCCViewer_ClippingDlg::updatePreview() {
927 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
928 int count = clipPlanesCount();
934 (aCurPlaneIndex +1 > count) ||
935 !PreviewCheckBox->isChecked())
938 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
940 OCCViewer_ClipPlane& aClipPlane = getClipPlane(aCurPlaneIndex);
941 Handle(AIS_Plane) myPreviewPlane;
943 if (aClipPlane.IsOn) {
947 clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
948 if(myPreviewPlaneVector.size() < clipPlanesCount()) {
949 myPreviewPlaneVector.resize(clipPlanesCount());
951 myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
952 if(myPreviewPlane.IsNull()) {
953 //Plane was not created
954 myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
955 myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
956 myPreviewPlane->SetSize( aSize, aSize );
957 ic->Display( myPreviewPlane, 1, 0, false );
958 ic->SetWidth( myPreviewPlane, 10, false );
959 ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
960 ic->SetTransparency( myPreviewPlane, 0.5, false );
961 myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane;
963 myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) );
964 myPreviewPlane->SetCenter( aBasePnt );
965 myPreviewPlane->SetSize( aSize, aSize );
968 ic->SetColor( myPreviewPlane, Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ), false );
969 ic->Update( myPreviewPlane, Standard_False );
971 if(myPreviewPlaneVector.size() > aCurPlaneIndex ) {
972 myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
973 if(ic->IsDisplayed(myPreviewPlane)) {
974 ic->Erase( myPreviewPlane, false );
975 ic->Remove( myPreviewPlane, false );
977 myPreviewPlaneVector[aCurPlaneIndex].Nullify();
980 for(int i = 0; i < myPreviewPlaneVector.size(); i++) {
981 if( i == aCurPlaneIndex ) continue;
982 if(!myPreviewPlaneVector[i].IsNull())
983 ic->SetColor( myPreviewPlaneVector[i], Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
987 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
988 getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
989 gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
990 (aYmax + aYmin) * 0.5,
991 (aZmax + aZmin) * 0.5 );
993 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
995 myInteractor->setPlanes( myPreviewPlaneVector );
996 myInteractor->setRotationCenter( aRotationCenter );
997 myInteractor->setMinMax( aMinMax );
1001 Erases preview of clipping plane
1003 void OCCViewer_ClippingDlg::erasePreview()
1008 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
1010 for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) {
1011 Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i];
1012 if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
1013 ic->Erase( myPreviewPlane, false );
1014 ic->Remove( myPreviewPlane, false );
1015 myPreviewPlane.Nullify();
1018 myPreviewPlaneVector.clear();
1020 myInteractor->setEnabled( false );
1024 Return true if plane parameters are valid
1026 bool OCCViewer_ClippingDlg::isValid()
1028 return ( SpinBox_Dx->value() !=0 || SpinBox_Dy->value() !=0 || SpinBox_Dz->value() !=0 );
1032 Update view after changes
1034 void OCCViewer_ClippingDlg::updateClipping()
1036 if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked())
1038 if (AutoApplyCheckBox->isChecked()) {
1042 if (!PreviewCheckBox->isChecked())
1050 Updates state of user controls.
1052 void OCCViewer_ClippingDlg::updateControls()
1054 if ( clipPlanesCount() == 0 )
1060 int aPlaneIdx = ComboBoxPlanes->currentIndex();
1062 OCCViewer_ClipPlane& aPlane = getClipPlane( aPlaneIdx );
1064 if ( aPlane.PlaneMode == Absolute )
1066 ModeStackedLayout->setCurrentIndex( 0 );
1067 myCurrentClipPlaneMode = Absolute;
1068 int anOrientation = aPlane.Orientation;
1069 // Set plane parameters in the dialog
1070 SpinBox_X->setValue( aPlane.X );
1071 SpinBox_Y->setValue( aPlane.Y );
1072 SpinBox_Z->setValue( aPlane.Z );
1073 SpinBox_Dx->setValue( aPlane.Dx );
1074 SpinBox_Dy->setValue( aPlane.Dy );
1075 SpinBox_Dz->setValue( aPlane.Dz );
1076 CBAbsoluteOrientation->setCurrentIndex( anOrientation );
1077 onOrientationAbsoluteChanged( anOrientation );
1079 else if( aPlane.PlaneMode == Relative )
1081 ModeStackedLayout->setCurrentIndex( 1 );
1082 myCurrentClipPlaneMode = Relative;
1083 int anOrientation = aPlane.RelativeMode.Orientation;
1085 // Set plane parameters in the dialog
1086 double aFmtDistance = double(aPlane.RelativeMode.Distance);
1087 int aFmtRotation1 = int(aPlane.RelativeMode.Rotation1);
1088 int aFmtRotation2 = int(aPlane.RelativeMode.Rotation2);
1090 SpinSliderDistance->setValue( aFmtDistance );
1091 SpinSliderRotation1->setValue( aFmtRotation1 );
1092 SpinSliderRotation2->setValue( aFmtRotation2 );
1093 CBRelativeOrientation->setCurrentIndex( anOrientation );
1094 onOrientationRelativeChanged( anOrientation );
1097 isActivePlane->setChecked( aPlane.IsOn );
1101 SLOT on new button click: create a new clipping plane
1103 void OCCViewer_ClippingDlg::ClickOnNew()
1105 OCCViewer_ClipPlane aPlane;
1106 aPlane.PlaneMode = (ClipPlaneMode )myCurrentClipPlaneMode;
1107 myLocalPlanes.push_back(aPlane);
1112 SLOT on delete button click: Delete selected clipping plane
1114 void OCCViewer_ClippingDlg::ClickOnDelete()
1116 int aPlaneIndex = ComboBoxPlanes->currentIndex();
1117 if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount()))
1120 myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex);
1122 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
1124 if(aPlaneIndex+1 <= myPreviewPlaneVector.size()) {
1125 Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[aPlaneIndex];
1126 if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
1127 ic->Erase( myPreviewPlane, false );
1128 ic->Remove( myPreviewPlane, false );
1130 myPreviewPlaneVector.erase(myPreviewPlaneVector.begin() + aPlaneIndex);
1133 if (AutoApplyCheckBox->isChecked()) {
1140 SLOT on disable all button click: Restore initial state of viewer,
1141 erase all clipping planes
1143 void OCCViewer_ClippingDlg::ClickOnDisableAll()
1145 AutoApplyCheckBox->setChecked (false);
1146 int aClipPlanesCount = clipPlanesCount();
1147 for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++)
1149 OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex);
1150 aPlane.IsOn = false;
1153 isActivePlane->setChecked(false);
1154 myModel->setClipPlanes(myLocalPlanes);
1159 SLOT on ok button click: sets cutting plane and closes dialog
1161 void OCCViewer_ClippingDlg::ClickOnOk()
1168 SLOT on Apply button click: sets cutting plane and update viewer
1170 void OCCViewer_ClippingDlg::ClickOnApply()
1177 SLOT on close button click: erases preview and rejects dialog
1179 void OCCViewer_ClippingDlg::ClickOnClose()
1182 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
1184 v->onClipping(false);
1188 SLOT on help button click: opens a help page
1190 void OCCViewer_ClippingDlg::ClickOnHelp()
1192 SUIT_Application* app = SUIT_Session::session()->activeApplication();
1194 app->onHelpContextModule( "GUI", "occ_3d_viewer_page.html", "clipping_planes" );
1198 Set absolute mode of clipping plane
1200 void OCCViewer_ClippingDlg::onModeAbsolute()
1202 myIsPlaneCreation = true;
1203 ModeStackedLayout->setCurrentIndex(0);
1204 myCurrentClipPlaneMode = Absolute;
1206 myIsPlaneCreation = false;
1211 Set relative mode of clipping plane
1213 void OCCViewer_ClippingDlg::onModeRelative()
1215 myIsPlaneCreation = true;
1216 ModeStackedLayout->setCurrentIndex(1);
1217 myCurrentClipPlaneMode = Relative;
1219 myIsPlaneCreation = false;
1220 SetCurrentPlaneParam();
1225 SLOT: called on value of clipping plane changed
1227 void OCCViewer_ClippingDlg::onValueChanged()
1229 if ( myIsUpdatingControls )
1234 SetCurrentPlaneParam();
1236 if ( myIsSelectPlane )
1245 Set current parameters of selected plane
1247 void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )
1249 if ( clipPlanesCount() == 0 )
1254 OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex );
1256 myIsSelectPlane = true;
1258 ComboBoxPlanes->setCurrentIndex( theIndex );
1259 myIsSelectPlane = false;
1263 Restore parameters of selected plane
1265 void OCCViewer_ClippingDlg::SetCurrentPlaneParam()
1267 if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy)
1270 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1272 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
1274 if ( aPlane.PlaneMode == Absolute )
1276 if( qFuzzyIsNull( SpinBox_Dx->value() ) &&
1277 qFuzzyIsNull( SpinBox_Dy->value() ) &&
1278 qFuzzyIsNull( SpinBox_Dz->value() ) ) {
1281 aPlane.Orientation = CBAbsoluteOrientation->currentIndex();
1282 aPlane.X = SpinBox_X->value();
1283 aPlane.Y = SpinBox_Y->value();
1284 aPlane.Z = SpinBox_Z->value();
1285 aPlane.Dx = SpinBox_Dx->value();
1286 aPlane.Dy = SpinBox_Dy->value();
1287 aPlane.Dz = SpinBox_Dz->value();
1288 absolutePlaneToRelative( aPlane, myModel->getAISContext(),myModel->trihedronSize() );
1290 else if( aPlane.PlaneMode == Relative )
1292 aPlane.RelativeMode.Orientation = CBRelativeOrientation->currentIndex();
1293 aPlane.RelativeMode.Distance = SpinSliderDistance->value();
1294 aPlane.RelativeMode.Rotation1 = SpinSliderRotation1->value();
1295 aPlane.RelativeMode.Rotation2 = SpinSliderRotation2->value();
1296 relativePlaneToAbsolute( aPlane, myModel->getAISContext(),myModel->trihedronSize() );
1298 aPlane.IsOn = isActivePlane->isChecked();
1302 SLOT on reset button click: sets default values
1304 void OCCViewer_ClippingDlg::onReset()
1307 SpinBox_X->setValue(0);
1308 SpinBox_Y->setValue(0);
1309 SpinBox_Z->setValue(0);
1316 SLOT on invert button click: inverts normal of cutting plane
1318 void OCCViewer_ClippingDlg::onInvert()
1320 double Dx = SpinBox_Dx->value();
1321 double Dy = SpinBox_Dy->value();
1322 double Dz = SpinBox_Dz->value();
1325 SpinBox_Dx->setValue( -Dx );
1326 SpinBox_Dy->setValue( -Dy );
1327 SpinBox_Dz->setValue( -Dz );
1330 if ( clipPlanesCount() != 0 ) {
1331 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1332 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
1333 aPlane.IsInvert = !aPlane.IsInvert;
1339 SLOT: called on orientation of clipping plane in absolute mode changed
1341 void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )
1343 bool isUserMode = (mode==0);
1345 TextLabelX->setEnabled( isUserMode );
1346 TextLabelY->setEnabled( isUserMode );
1347 TextLabelZ->setEnabled( isUserMode );
1349 SpinBox_X->setEnabled( isUserMode );
1350 SpinBox_Y->setEnabled( isUserMode );
1351 SpinBox_Z->setEnabled( isUserMode );
1353 TextLabelDx->setEnabled( isUserMode );
1354 TextLabelDy->setEnabled( isUserMode );
1355 TextLabelDz->setEnabled( isUserMode );
1357 SpinBox_Dx->setEnabled( isUserMode );
1358 SpinBox_Dy->setEnabled( isUserMode );
1359 SpinBox_Dz->setEnabled( isUserMode );
1361 if ( !isUserMode ) {
1363 double aDx = 0, aDy = 0, aDz = 0;
1368 TextLabelZ->setEnabled( true );
1369 SpinBox_Z->setEnabled( true );
1370 SpinBox_Z->setFocus();
1372 else if ( mode == 2 )
1375 TextLabelX->setEnabled( true );
1376 SpinBox_X->setEnabled( true );
1377 SpinBox_X->setFocus();
1379 else if ( mode == 3 )
1382 TextLabelY->setEnabled( true );
1383 SpinBox_Y->setEnabled( true );
1384 SpinBox_Y->setFocus();
1387 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
1388 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
1389 if ( aPlane.IsInvert == true ) {
1390 aDx = -aDx; aDy = -aDy; aDz = -aDz;
1394 SpinBox_Dx->setValue( aDx );
1395 SpinBox_Dy->setValue( aDy );
1396 SpinBox_Dz->setValue( aDz );
1400 if ( !myIsUpdatingControls )
1402 SetCurrentPlaneParam();
1408 SLOT: called on orientation of clipping plane in relative mode changed
1410 void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)
1412 if ( clipPlanesCount() == 0 )
1415 if ( theItem == 0 ) {
1416 TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );
1417 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );
1419 else if ( theItem == 1 ) {
1420 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) );
1421 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) );
1423 else if ( theItem == 2 ) {
1424 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) );
1425 TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );
1428 if ( !myIsUpdatingControls )
1430 if( (QComboBox*)sender() == CBRelativeOrientation )
1432 SetCurrentPlaneParam();
1440 SLOT: called on preview check box toggled
1442 void OCCViewer_ClippingDlg::onPreview( bool on )
1450 SLOT: called on Auto Apply check box toggled
1452 void OCCViewer_ClippingDlg::onAutoApply( bool toggled )
1461 SLOT on Apply button click: sets cutting plane
1463 void OCCViewer_ClippingDlg::onApply()
1467 myIsSelectPlane = true;
1469 qApp->processEvents();
1470 QApplication::setOverrideCursor( Qt::WaitCursor );
1471 qApp->processEvents();
1473 myModel->setClipPlanes(myLocalPlanes);
1475 QApplication::restoreOverrideCursor();
1476 myIsSelectPlane = false;
1480 SLOT: Called when clip plane is clicked in viewer.
1482 void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane )
1484 for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
1486 Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
1487 if ( aPlane != thePlane )
1492 ComboBoxPlanes->setCurrentIndex( aPlaneIt );
1499 SLOT: Called when clip plane is changed by dragging in viewer.
1501 void OCCViewer_ClippingDlg::onPlaneDragged( const Handle(AIS_Plane)& thePlane )
1503 for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
1505 Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
1506 if ( aPlane != thePlane )
1511 OCCViewer_ClipPlane& aClipPlane = getClipPlane( aPlaneIt );
1513 gp_Pln aPln = thePlane->Component()->Pln();
1514 const gp_Pnt& aPlaneP = aPln.Location();
1515 const gp_Dir& aPlaneN = aPln.Axis().Direction();
1517 aClipPlane.X = aPlaneP.X();
1518 aClipPlane.Y = aPlaneP.Y();
1519 aClipPlane.Z = aPlaneP.Z();
1520 aClipPlane.Dx = aPlaneN.X();
1521 aClipPlane.Dy = aPlaneN.Y();
1522 aClipPlane.Dz = aPlaneN.Z();
1523 absolutePlaneToRelative( aClipPlane, myModel->getAISContext(), myModel->trihedronSize() );
1525 myIsUpdatingControls = true;
1527 myIsUpdatingControls = false;
1529 if ( AutoApplyCheckBox->isChecked() )
1538 OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx )
1540 return myLocalPlanes[theIdx];
1543 int OCCViewer_ClippingDlg::clipPlanesCount()
1545 return myLocalPlanes.size();