1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
\r
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
\r
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
\r
6 // This library is free software; you can redistribute it and/or
\r
7 // modify it under the terms of the GNU Lesser General Public
\r
8 // License as published by the Free Software Foundation; either
\r
9 // version 2.1 of the License, or (at your option) any later version.
\r
11 // This library is distributed in the hope that it will be useful,
\r
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
\r
14 // Lesser General Public License for more details.
\r
16 // You should have received a copy of the GNU Lesser General Public
\r
17 // License along with this library; if not, write to the Free Software
\r
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
\r
23 #include "OCCViewer_ClippingDlg.h"
\r
25 #include <QtxDoubleSpinBox.h>
\r
26 #include <QtxDoubleSpinSlider.h>
\r
27 #include <QtxIntSpinSlider.h>
\r
28 #include <QtxAction.h>
\r
30 #include "SUIT_Session.h"
\r
31 #include "SUIT_ViewWindow.h"
\r
32 #include "SUIT_ViewManager.h"
\r
33 #include "OCCViewer_ClipPlane.h"
\r
34 #include "OCCViewer_ViewWindow.h"
\r
35 #include "OCCViewer_ViewPort3d.h"
\r
36 #include "OCCViewer_ViewModel.h"
\r
37 #include "OCCViewer_ViewManager.h"
\r
38 #include "OCCViewer_ClipPlaneInteractor.h"
\r
40 #include <V3d_View.hxx>
\r
41 #include <Visual3d_View.hxx>
\r
42 #include <Geom_Plane.hxx>
\r
43 #include <Prs3d_Presentation.hxx>
\r
44 #include <AIS_ListIteratorOfListOfInteractive.hxx>
\r
45 #include <AIS_ListOfInteractive.hxx>
\r
46 #include <AIS_InteractiveObject.hxx>
\r
47 #include <AIS_InteractiveContext.hxx>
\r
48 #include <IntAna_IntConicQuad.hxx>
\r
49 #include <gp_Lin.hxx>
\r
50 #include <gp_Pln.hxx>
\r
54 #include <QApplication>
\r
55 #include <QGroupBox>
\r
56 #include <QHBoxLayout>
\r
57 #include <QVBoxLayout>
\r
58 #include <QGridLayout>
\r
60 #include <QPushButton>
\r
61 #include <QComboBox>
\r
62 #include <QCheckBox>
\r
63 #include <QStackedLayout>
\r
67 /**********************************************************************************
\r
68 ************************ Internal functions ************************
\r
69 *********************************************************************************/
\r
71 void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic,
\r
72 double theDefaultSize,
\r
80 double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
\r
81 aXMin = aYMin = aZMin = DBL_MAX;
\r
82 aXMax = aYMax = aZMax = -DBL_MAX;
\r
84 bool isFound = false;
\r
85 AIS_ListOfInteractive aList;
\r
86 ic->DisplayedObjects( aList );
\r
87 for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) {
\r
88 Handle(AIS_InteractiveObject) anObj = it.Value();
\r
89 if ( !anObj.IsNull() && anObj->HasPresentation() &&
\r
90 !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) {
\r
91 Handle(Prs3d_Presentation) aPrs = anObj->Presentation();
\r
92 if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) {
\r
94 double xmin, ymin, zmin, xmax, ymax, zmax;
\r
95 aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax );
\r
96 aXMin = qMin( aXMin, xmin ); aXMax = qMax( aXMax, xmax );
\r
97 aYMin = qMin( aYMin, ymin ); aYMax = qMax( aYMax, ymax );
\r
98 aZMin = qMin( aZMin, zmin ); aZMax = qMax( aZMax, zmax );
\r
104 if(theDefaultSize == 0.0)
\r
105 theDefaultSize = 100.;
\r
106 aXMin = aYMin = aZMin = -theDefaultSize;
\r
107 aXMax = aYMax = aZMax = theDefaultSize;
\r
109 theXMin = aXMin;theYMin = aYMin;theZMin = aZMin;
\r
110 theXMax = aXMax;theYMax = aYMax;theZMax = aZMax;
\r
114 Compute the point of bounding box and current clipping plane
\r
116 void ComputeBoundsParam( const double theBounds[6],
\r
117 const double theDirection[3],
\r
118 double theMinPnt[3],
\r
119 double& theMaxBoundPrj,
\r
120 double& theMinBoundPrj )
\r
122 double aEnlargeBounds[6];
\r
124 // Enlarge bounds in order to avoid conflicts of precision
\r
125 for(int i = 0; i < 6; i += 2)
\r
127 static double EPS = 1.0E-3;
\r
128 double aDelta = (theBounds[i+1] - theBounds[i])*EPS;
\r
129 aEnlargeBounds[i ] = theBounds[i ] - aDelta;
\r
130 aEnlargeBounds[i+1] = theBounds[i+1] + aDelta;
\r
133 double aBoundPoints[8][3] = { { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[4] },
\r
134 { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[4] },
\r
135 { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[4] },
\r
136 { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[4] },
\r
137 { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[5] },
\r
138 { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[5] },
\r
139 { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[5] },
\r
140 { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[5] } };
\r
143 theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1]
\r
144 + theDirection[2] * aBoundPoints[aMaxId][2];
\r
145 theMinBoundPrj = theMaxBoundPrj;
\r
146 for(int i = 1; i < 8; i++) {
\r
147 double aTmp = theDirection[0] * aBoundPoints[i][0] + theDirection[1] * aBoundPoints[i][1]
\r
148 + theDirection[2] * aBoundPoints[i][2];
\r
149 if(theMaxBoundPrj < aTmp) {
\r
150 theMaxBoundPrj = aTmp;
\r
153 if(theMinBoundPrj > aTmp) {
\r
154 theMinBoundPrj = aTmp;
\r
157 double *aMinPnt = aBoundPoints[aMaxId];
\r
158 theMinPnt[0] = aMinPnt[0];
\r
159 theMinPnt[1] = aMinPnt[1];
\r
160 theMinPnt[2] = aMinPnt[2];
\r
164 Compute the position of current plane by distance
\r
166 void DistanceToPosition( const double theBounds[6],
\r
167 const double theDirection[3],
\r
168 const double theDist,
\r
171 double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
\r
172 ComputeBoundsParam( theBounds, theDirection, aMinPnt, aMaxBoundPrj, aMinBoundPrj );
\r
173 double aLength = (aMaxBoundPrj - aMinBoundPrj) * theDist;
\r
174 thePos[0] = aMinPnt[0] - theDirection[0] * aLength;
\r
175 thePos[1] = aMinPnt[1] - theDirection[1] * aLength;
\r
176 thePos[2] = aMinPnt[2] - theDirection[2] * aLength;
\r
180 Compute the parameters of clipping plane
\r
182 bool ComputeClippingPlaneParameters( const Handle(AIS_InteractiveContext)& theIC,
\r
183 const double theDefaultSize,
\r
184 const double theNormal[3],
\r
185 const double theDist,
\r
186 double theOrigin[3] )
\r
188 double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
\r
190 getMinMaxFromContext( theIC, theDefaultSize, aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5] );
\r
192 DistanceToPosition( aBounds, theNormal, theDist, theOrigin );
\r
197 \brief Converts relative plane parameters to absolute.
\r
198 \param theIC [in] the interactive context.
\r
199 \param theDefaultSize [in] the default trihedron size.
\r
200 \param theDistance [in] the plane distance relative to minimum corner of model boundaries.
\r
201 \param theDX [in] x component of plane direction.
\r
202 \param theDY [in] y component of plane direction.
\r
203 \param theDZ [in] z component of plane direction.
\r
204 \param theX [out] x coordinate of plane origin.
\r
205 \param theY [out] y coordinate of plane origin.
\r
206 \param theZ [out] z coordinate of plane origin.
\r
208 bool DistanceToXYZ ( const Handle(AIS_InteractiveContext)& theIC,
\r
209 const double theDefaultSize,
\r
210 const double theDistance,
\r
211 const double theDX,
\r
212 const double theDY,
\r
213 const double theDZ,
\r
218 double aNormal[3] = { theDX, theDY, theDZ };
\r
219 double anOrigin[3] = { 0.0, 0.0, 0.0 };
\r
221 bool anIsOk = ComputeClippingPlaneParameters( theIC, theDefaultSize, aNormal, theDistance, anOrigin );
\r
228 theX = anOrigin[0];
\r
229 theY = anOrigin[1];
\r
230 theZ = anOrigin[2];
\r
236 \brief Converts absolute position and direction to bounding box distance.
\r
237 \param theIC [in] the interactive context.
\r
238 \param theDefaultSize [in] the default trihedron size.
\r
239 \param theX [in] x coordinate of plane origin.
\r
240 \param theY [in] y coordinate of plane origin.
\r
241 \param theZ [in] z coordinate of plane origin.
\r
242 \param theDX [in] x component of plane direction.
\r
243 \param theDY [in] y component of plane direction.
\r
244 \param theDZ [in] z component of plane direction.
\r
245 \param theDistance [out] the plane distance relative to minimum corner of model boundaries.
\r
247 void XYZToDistance ( const Handle(AIS_InteractiveContext)& theIC,
\r
248 const double theDefaultSize,
\r
252 const double theDX,
\r
253 const double theDY,
\r
254 const double theDZ,
\r
255 double& theDistance )
\r
257 gp_Pnt aPlaneP( theX, theY, theZ );
\r
258 gp_Dir aPlaneN( theDX, theDY, theDZ );
\r
260 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
\r
262 getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
\r
265 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
\r
267 gp_Trsf aRelativeTransform;
\r
268 aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) );
\r
269 Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform );
\r
271 aRelativeBounds.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
\r
273 double aLength = aZmax - aZmin;
\r
274 double aDistance = aZmax;
\r
276 double aRelativeDistance = aLength > 0.01 ? aDistance / aLength : 0.0;
\r
277 aRelativeDistance = qMin( aRelativeDistance, aLength );
\r
278 aRelativeDistance = qMax( aRelativeDistance, 0.0 );
\r
279 theDistance = aRelativeDistance;
\r
283 Compute clipping plane size base point and normal
\r
286 void clipPlaneParams(OCCViewer_ClipPlane& theClipPlane, Handle(AIS_InteractiveContext) theContext,
\r
287 double& theSize, gp_Pnt& theBasePnt, gp_Dir& theNormal, double defaultSize) {
\r
288 double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax;
\r
289 aXMin = aYMin = aZMin = DBL_MAX;
\r
290 aXMax = aYMax = aZMax = -DBL_MAX;
\r
292 getMinMaxFromContext(theContext,defaultSize,aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
\r
295 double aNormalX = 0.0;
\r
296 double aNormalY = 0.0;
\r
297 double aNormalZ = 0.0;
\r
298 theClipPlane.OrientationToXYZ( aNormalX, aNormalY, aNormalZ );
\r
299 gp_Pnt aBasePnt( theClipPlane.X, theClipPlane.Y, theClipPlane.Z );
\r
300 gp_Dir aNormal( aNormalX, aNormalY, aNormalZ );
\r
302 // compute clipping plane size
\r
303 gp_Pnt aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 );
\r
304 double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2;
\r
305 aSize = aDiag * 1.1;
\r
307 // compute clipping plane center ( redefine the base point )
\r
308 IntAna_IntConicQuad intersector = IntAna_IntConicQuad();
\r
310 intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() );
\r
312 if ( intersector.IsDone() && intersector.NbPoints() == 1 )
\r
313 aBasePnt = intersector.Point( 1 );
\r
316 theBasePnt = aBasePnt;
\r
317 theNormal = aNormal;
\r
321 /*********************************************************************************
\r
322 ********************* class OCCViewer_ClippingDlg *********************
\r
323 *********************************************************************************/
\r
326 \param view - view window
\r
327 \param parent - parent widget
\r
329 OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model)
\r
330 : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint )
\r
332 setObjectName( "OCCViewer_ClippingDlg" );
\r
335 setWindowTitle( tr( "Clipping" ) );
\r
337 setAttribute (Qt::WA_DeleteOnClose, true);
\r
339 QVBoxLayout* topLayout = new QVBoxLayout( this );
\r
340 topLayout->setMargin( 11 ); topLayout->setSpacing( 6 );
\r
342 /***************************************************************/
\r
343 // Controls for selecting, creating, deleting planes
\r
344 QGroupBox* GroupPlanes = new QGroupBox( tr("CLIPPING_PLANES"), this );
\r
345 QHBoxLayout* GroupPlanesLayout = new QHBoxLayout( GroupPlanes );
\r
346 ComboBoxPlanes = new QComboBox( GroupPlanes );
\r
347 isActivePlane = new QCheckBox( tr("IS_ACTIVE_PLANE"), this );
\r
348 buttonNew = new QPushButton( tr("BTN_NEW"), GroupPlanes );
\r
349 buttonDelete = new QPushButton( tr("BTN_DELETE"), GroupPlanes );
\r
350 buttonDisableAll = new QPushButton( tr("BTN_DISABLE_ALL"), GroupPlanes );
\r
351 MenuMode = new QMenu( "MenuMode", buttonNew );
\r
352 MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) );
\r
353 MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) );
\r
354 buttonNew->setMenu( MenuMode );
\r
356 GroupPlanesLayout->addWidget( ComboBoxPlanes );
\r
357 GroupPlanesLayout->addWidget( isActivePlane );
\r
358 GroupPlanesLayout->addWidget( buttonNew );
\r
359 GroupPlanesLayout->addWidget( buttonDelete );
\r
360 GroupPlanesLayout->addWidget( buttonDisableAll );
\r
362 ModeStackedLayout = new QStackedLayout();
\r
364 /********************** Mode Absolute **********************/
\r
365 /* Controls for absolute mode of clipping plane:
\r
366 X, Y, Z - coordinates of the intersection of cutting plane and the three axes
\r
367 Dx, Dy, Dz - components of normal to the cutting plane
\r
368 Orientation - direction of cutting plane
\r
370 const double min = -1e+7;
\r
371 const double max = 1e+7;
\r
372 const double step = 5;
\r
373 const int precision = -7;
\r
376 QGroupBox* GroupAbsolutePoint = new QGroupBox( this );
\r
377 GroupAbsolutePoint->setObjectName( "GroupPoint" );
\r
378 GroupAbsolutePoint->setTitle( tr("BASE_POINT") );
\r
379 QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint );
\r
380 GroupPointLayout->setAlignment( Qt::AlignTop );
\r
381 GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 );
\r
383 TextLabelX = new QLabel( GroupAbsolutePoint );
\r
384 TextLabelX->setObjectName( "TextLabelX" );
\r
385 TextLabelX->setText( tr("X:") );
\r
386 GroupPointLayout->addWidget( TextLabelX, 0, 0 );
\r
388 SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
\r
389 SpinBox_X->setObjectName("SpinBox_X" );
\r
390 SpinBox_X->setPrecision( precision );
\r
391 GroupPointLayout->addWidget( SpinBox_X, 0, 1 );
\r
393 TextLabelY = new QLabel( GroupAbsolutePoint );
\r
394 TextLabelY->setObjectName( "TextLabelY" );
\r
395 TextLabelY->setText( tr("Y:") );
\r
396 GroupPointLayout->addWidget( TextLabelY, 0, 2 );
\r
398 SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
\r
399 SpinBox_Y->setObjectName("SpinBox_Y" );
\r
400 SpinBox_Y->setPrecision( precision );
\r
401 GroupPointLayout->addWidget( SpinBox_Y, 0, 3 );
\r
403 TextLabelZ = new QLabel( GroupAbsolutePoint );
\r
404 TextLabelZ->setObjectName( "TextLabelZ" );
\r
405 TextLabelZ->setText( tr("Z:") );
\r
406 GroupPointLayout->addWidget( TextLabelZ, 0, 4 );
\r
408 SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint );
\r
409 SpinBox_Z->setObjectName("SpinBox_Z" );
\r
410 SpinBox_Z->setPrecision( precision );
\r
411 GroupPointLayout->addWidget( SpinBox_Z, 0, 5 );
\r
413 resetButton = new QPushButton( GroupAbsolutePoint );
\r
414 resetButton->setObjectName( "resetButton" );
\r
415 resetButton->setText( tr( "RESET" ) );
\r
416 GroupPointLayout->addWidget( resetButton, 0, 6 );
\r
419 GroupAbsoluteDirection = new QGroupBox( this );
\r
420 GroupAbsoluteDirection->setObjectName( "GroupDirection" );
\r
421 GroupAbsoluteDirection->setTitle( tr("DIRECTION") );
\r
422 QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection );
\r
423 GroupDirectionLayout->setAlignment( Qt::AlignTop );
\r
424 GroupDirectionLayout->setSpacing( 6 );
\r
425 GroupDirectionLayout->setMargin( 11 );
\r
427 TextLabelDx = new QLabel( GroupAbsoluteDirection );
\r
428 TextLabelDx->setObjectName( "TextLabelDx" );
\r
429 TextLabelDx->setText( tr("Dx:") );
\r
430 GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 );
\r
432 SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
\r
433 SpinBox_Dx->setObjectName("SpinBox_Dx" );
\r
434 SpinBox_Dx->setPrecision( precision );
\r
435 GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 );
\r
437 TextLabelDy = new QLabel( GroupAbsoluteDirection );
\r
438 TextLabelDy->setObjectName( "TextLabelDy" );
\r
439 TextLabelDy->setText( tr("Dy:") );
\r
440 GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 );
\r
442 SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
\r
443 SpinBox_Dy->setObjectName("SpinBox_Dy" );
\r
444 SpinBox_Dy->setPrecision( precision );
\r
445 GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 );
\r
447 TextLabelDz = new QLabel( GroupAbsoluteDirection );
\r
448 TextLabelDz->setObjectName( "TextLabelDz" );
\r
449 TextLabelDz->setText( tr("Dz:") );
\r
450 GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 );
\r
452 SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection );
\r
453 SpinBox_Dz->setObjectName("SpinBox_Dz" );
\r
454 SpinBox_Dz->setPrecision( precision );
\r
455 GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 );
\r
457 invertButton = new QPushButton( GroupAbsoluteDirection );
\r
458 invertButton->setObjectName( "invertButton" );
\r
459 invertButton->setText( tr( "INVERT" ) );
\r
460 GroupDirectionLayout->addWidget( invertButton, 0, 6 );
\r
462 CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection );
\r
463 CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" );
\r
464 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) );
\r
465 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) );
\r
466 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) );
\r
467 CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) );
\r
468 GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 );
\r
470 QVBoxLayout* ModeActiveLayout = new QVBoxLayout();
\r
471 ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 );
\r
472 ModeActiveLayout->addWidget( GroupAbsolutePoint );
\r
473 ModeActiveLayout->addWidget( GroupAbsoluteDirection );
\r
475 QWidget* ModeActiveWidget = new QWidget( this );
\r
476 ModeActiveWidget->setLayout( ModeActiveLayout );
\r
478 /********************** Mode Relative **********************/
\r
479 /* Controls for relative mode of clipping plane:
\r
480 Distance - Value from 0 to 1.
\r
481 Specifies the distance from the minimum value in a given direction of bounding box to the current position
\r
482 Rotation1, Rotation2 - turn angles of cutting plane in given directions
\r
483 Orientation - direction of cutting plane
\r
485 QGroupBox* GroupParameters = new QGroupBox( tr("PARAMETERS"), this );
\r
486 QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters );
\r
487 GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 );
\r
489 TextLabelOrientation = new QLabel( tr("ORIENTATION"), GroupParameters);
\r
490 TextLabelOrientation->setObjectName( "TextLabelOrientation" );
\r
491 GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 );
\r
493 CBRelativeOrientation = new QComboBox(GroupParameters);
\r
494 CBRelativeOrientation->setObjectName( "RelativeOrientation" );
\r
495 CBRelativeOrientation->addItem( tr("ALONG_XY") );
\r
496 CBRelativeOrientation->addItem( tr("ALONG_YZ") );
\r
497 CBRelativeOrientation->addItem( tr("ALONG_ZX") );
\r
498 GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 );
\r
500 TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters );
\r
501 TextLabelDistance->setObjectName( "TextLabelDistance" );
\r
502 GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 );
\r
504 SpinSliderDistance = new QtxDoubleSpinSlider( 0., 1., 0.01, GroupParameters );
\r
505 SpinSliderDistance->setObjectName( "SpinSliderDistance" );
\r
506 SpinSliderDistance->setPrecision( precision );
\r
507 QFont fnt = SpinSliderDistance->font(); fnt.setBold( true ); SpinSliderDistance->setFont( fnt );
\r
508 GroupParametersLayout->addWidget( SpinSliderDistance, 1, 1 );
\r
510 QString aUnitRot = "\xB0";
\r
512 TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters );
\r
513 TextLabelRotation1->setObjectName( "TextLabelRotation1" );
\r
514 GroupParametersLayout->addWidget( TextLabelRotation1, 2, 0 );
\r
516 SpinSliderRotation1 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );
\r
517 SpinSliderRotation1->setObjectName( "SpinSliderRotation1" );
\r
518 SpinSliderRotation1->setUnit( aUnitRot );
\r
519 SpinSliderRotation1->setFont( fnt );
\r
520 GroupParametersLayout->addWidget( SpinSliderRotation1, 2, 1 );
\r
522 TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters);
\r
523 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
\r
524 TextLabelRotation2->setObjectName( "TextLabelRotation2" );
\r
525 GroupParametersLayout->addWidget( TextLabelRotation2, 3, 0 );
\r
527 SpinSliderRotation2 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters );
\r
528 SpinSliderRotation2->setObjectName( "SpinSliderRotation2" );
\r
529 SpinSliderRotation2->setUnit( aUnitRot );
\r
530 SpinSliderRotation2->setFont( fnt );
\r
531 GroupParametersLayout->addWidget( SpinSliderRotation2, 3, 1 );
\r
533 /***************************************************************/
\r
534 QGroupBox* CheckBoxWidget = new QGroupBox( this );
\r
535 QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget );
\r
537 PreviewCheckBox = new QCheckBox( tr("PREVIEW"), CheckBoxWidget );
\r
538 PreviewCheckBox->setObjectName( "PreviewCheckBox" );
\r
539 PreviewCheckBox->setChecked( true );
\r
540 CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter );
\r
542 AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget );
\r
543 AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" );
\r
544 CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter );
\r
546 /***************************************************************/
\r
547 QGroupBox* GroupButtons = new QGroupBox( this );
\r
548 QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons );
\r
549 GroupButtonsLayout->setAlignment( Qt::AlignTop );
\r
550 GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 );
\r
552 buttonOk = new QPushButton( GroupButtons );
\r
553 buttonOk->setObjectName( "buttonOk" );
\r
554 buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE" ) );
\r
555 buttonOk->setAutoDefault( TRUE );
\r
556 buttonOk->setDefault( TRUE );
\r
557 GroupButtonsLayout->addWidget( buttonOk );
\r
559 buttonApply = new QPushButton( GroupButtons );
\r
560 buttonApply->setObjectName( "buttonApply" );
\r
561 buttonApply->setText( tr( "BUT_APPLY" ) );
\r
562 buttonApply->setAutoDefault( TRUE );
\r
563 buttonApply->setDefault( TRUE );
\r
564 GroupButtonsLayout->addWidget( buttonApply );
\r
566 GroupButtonsLayout->addStretch();
\r
568 buttonClose = new QPushButton( GroupButtons );
\r
569 buttonClose->setObjectName( "buttonClose" );
\r
570 buttonClose->setText( tr( "BUT_CLOSE" ) );
\r
571 buttonClose->setAutoDefault( TRUE );
\r
572 GroupButtonsLayout->addWidget( buttonClose );
\r
574 QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons );
\r
575 buttonHelp->setAutoDefault( TRUE );
\r
576 GroupButtonsLayout->addWidget( buttonHelp );
\r
578 /***************************************************************/
\r
579 ModeStackedLayout->addWidget( ModeActiveWidget );
\r
580 ModeStackedLayout->addWidget( GroupParameters );
\r
582 topLayout->addWidget( GroupPlanes );
\r
583 topLayout->addLayout( ModeStackedLayout );
\r
584 topLayout->addWidget( CheckBoxWidget );
\r
585 topLayout->addWidget( GroupButtons );
\r
587 this->setLayout( topLayout );
\r
592 // Signals and slots connections
\r
593 connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) );
\r
594 connect( isActivePlane, SIGNAL ( toggled ( bool ) ), this, SLOT( onValueChanged() ) );
\r
595 connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) );
\r
596 connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) );
\r
597 connect( buttonDisableAll, SIGNAL( clicked() ), this, SLOT( ClickOnDisableAll() ) );
\r
599 connect( resetButton, SIGNAL (clicked() ), this, SLOT( onReset() ) );
\r
600 connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ;
\r
601 connect( SpinBox_X, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
\r
602 connect( SpinBox_Y, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
\r
603 connect( SpinBox_Z, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
\r
604 connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
\r
605 connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
\r
606 connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
\r
607 connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ;
\r
609 connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( int ) ) );
\r
610 connect( SpinSliderDistance, SIGNAL( valueChanged( double ) ), this, SLOT( onValueChanged() ) );
\r
611 connect( SpinSliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
\r
612 connect( SpinSliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) );
\r
614 connect( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ;
\r
615 connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) );
\r
617 connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ;
\r
618 connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
\r
619 connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
\r
620 connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) );
\r
623 myIsSelectPlane = false;
\r
624 myIsPlaneCreation = false;
\r
625 myIsUpdatingControls = false;
\r
628 myModel->getViewer3d()->InitActiveViews();
\r
630 OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) myModel->getViewManager();
\r
631 myInteractor = new OCCViewer_ClipPlaneInteractor( aViewMgr, this );
\r
632 connect( myInteractor, SIGNAL( planeClicked( const Handle_AIS_Plane& ) ), SLOT( onPlaneClicked( const Handle_AIS_Plane& ) ) );
\r
633 connect( myInteractor, SIGNAL( planeDragged( const Handle_AIS_Plane& ) ), SLOT( onPlaneDragged( const Handle_AIS_Plane& ) ) );
\r
635 myLocalPlanes = myModel->getClipPlanes();
\r
641 Destroys the object and frees any allocated resources
\r
643 OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg()
\r
645 myLocalPlanes.clear();
\r
649 Custom handling of close event: erases preview
\r
651 void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e )
\r
654 QDialog::closeEvent( e );
\r
655 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
\r
657 v->onClipping(false);
\r
661 Custom handling of show event: displays preview
\r
663 void OCCViewer_ClippingDlg::showEvent( QShowEvent* e )
\r
665 QDialog::showEvent( e );
\r
666 onPreview( PreviewCheckBox->isChecked() );
\r
670 Custom handling of hide event: erases preview
\r
672 void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e )
\r
675 QDialog::hideEvent( e );
\r
676 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
\r
678 v->onClipping(false);
\r
683 Initialization of initial values of widgets
\r
685 void OCCViewer_ClippingDlg::initParam()
\r
687 SpinBox_X->setValue( 0.0 );
\r
688 SpinBox_Y->setValue( 0.0 );
\r
689 SpinBox_Z->setValue( 0.0 );
\r
691 SpinBox_Dx->setValue( 1.0 );
\r
692 SpinBox_Dy->setValue( 1.0 );
\r
693 SpinBox_Dz->setValue( 1.0 );
\r
695 CBAbsoluteOrientation->setCurrentIndex(0);
\r
697 SpinSliderDistance->setValue( 0.5 );
\r
698 SpinSliderRotation1->setValue( 0 );
\r
699 SpinSliderRotation2->setValue( 0 );
\r
700 CBRelativeOrientation->setCurrentIndex( 0 );
\r
702 isActivePlane->setChecked( true );
\r
706 Set plane parameters from widgets.
\r
708 void OCCViewer_ClippingDlg::setPlaneParam( OCCViewer_ClipPlane& thePlane )
\r
710 OCCViewer_ClipPlane::PlaneMode aMode = currentPlaneMode();
\r
712 thePlane.Mode = aMode;
\r
714 if ( aMode == OCCViewer_ClipPlane::Absolute )
\r
716 if( qFuzzyIsNull( SpinBox_Dx->value() ) &&
\r
717 qFuzzyIsNull( SpinBox_Dy->value() ) &&
\r
718 qFuzzyIsNull( SpinBox_Dz->value() ) ) {
\r
723 thePlane.OrientationType = (aMode == OCCViewer_ClipPlane::Absolute)
\r
724 ? CBAbsoluteOrientation->currentIndex()
\r
725 : CBRelativeOrientation->currentIndex();
\r
728 if ( aMode == OCCViewer_ClipPlane::Absolute )
\r
730 if ( thePlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )
\r
732 thePlane.AbsoluteOrientation.Dx = SpinBox_Dx->value();
\r
733 thePlane.AbsoluteOrientation.Dy = SpinBox_Dy->value();
\r
734 thePlane.AbsoluteOrientation.Dz = SpinBox_Dz->value();
\r
738 thePlane.AbsoluteOrientation.IsInvert = SpinBox_Dx->value() < 0.0
\r
739 || SpinBox_Dy->value() < 0.0
\r
740 || SpinBox_Dz->value() < 0.0;
\r
743 thePlane.X = SpinBox_X->value();
\r
744 thePlane.Y = SpinBox_Y->value();
\r
745 thePlane.Z = SpinBox_Z->value();
\r
749 thePlane.RelativeOrientation.Rotation1 = SpinSliderRotation1->value();
\r
750 thePlane.RelativeOrientation.Rotation2 = SpinSliderRotation2->value();
\r
752 double aPlaneDx = 0.0;
\r
753 double aPlaneDy = 0.0;
\r
754 double aPlaneDz = 0.0;
\r
759 OCCViewer_ClipPlane::RelativeToDXYZ( thePlane.OrientationType,
\r
760 thePlane.RelativeOrientation.Rotation1,
\r
761 thePlane.RelativeOrientation.Rotation2,
\r
762 aPlaneDx, aPlaneDy, aPlaneDz );
\r
764 DistanceToXYZ( myModel->getAISContext(),
\r
765 myModel->trihedronSize(),
\r
766 SpinSliderDistance->value(),
\r
767 aPlaneDx, aPlaneDy, aPlaneDz,
\r
775 thePlane.IsOn = isActivePlane->isChecked();
\r
779 Synchronize dialog's widgets with data
\r
781 void OCCViewer_ClippingDlg::synchronize()
\r
783 ComboBoxPlanes->clear();
\r
784 int aNbPlanesAbsolute = myLocalPlanes.size();
\r
787 for(int i = 1; i<=aNbPlanesAbsolute; i++ ) {
\r
788 aName = QString("Plane %1").arg(i);
\r
789 ComboBoxPlanes->addItem( aName );
\r
792 int aPos = ComboBoxPlanes->count() - 1;
\r
793 ComboBoxPlanes->setCurrentIndex( aPos );
\r
795 bool anIsControlsEnable = ( aPos >= 0 );
\r
796 if ( anIsControlsEnable ) {
\r
797 onSelectPlane( aPos );
\r
800 ComboBoxPlanes->addItem( tr( "NO_PLANES" ) );
\r
803 if ( currentPlaneMode() == OCCViewer_ClipPlane::Absolute )
\r
805 SpinBox_X->setEnabled( anIsControlsEnable );
\r
806 SpinBox_Y->setEnabled( anIsControlsEnable );
\r
807 SpinBox_Z->setEnabled( anIsControlsEnable );
\r
808 SpinBox_Dx->setEnabled( anIsControlsEnable );
\r
809 SpinBox_Dy->setEnabled( anIsControlsEnable );
\r
810 SpinBox_Dz->setEnabled( anIsControlsEnable );
\r
811 CBAbsoluteOrientation->setEnabled( anIsControlsEnable );
\r
812 invertButton->setEnabled( anIsControlsEnable );
\r
813 resetButton->setEnabled( anIsControlsEnable );
\r
815 else if ( currentPlaneMode() == OCCViewer_ClipPlane::Relative )
\r
817 CBRelativeOrientation->setEnabled( anIsControlsEnable );
\r
818 SpinSliderDistance->setEnabled( anIsControlsEnable );
\r
819 SpinSliderRotation1->setEnabled( anIsControlsEnable );
\r
820 SpinSliderRotation2->setEnabled( anIsControlsEnable );
\r
821 isActivePlane->setEnabled( anIsControlsEnable );
\r
823 isActivePlane->setEnabled( anIsControlsEnable );
\r
827 Displays preview of clipping plane
\r
829 void OCCViewer_ClippingDlg::displayPreview()
\r
831 if ( myBusy || !isValid() || !myModel)
\r
834 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
\r
836 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
\r
838 for ( int i=0; i < clipPlanesCount(); i++ ) {
\r
839 OCCViewer_ClipPlane& aClipPlane = getClipPlane(i);
\r
840 if ( aClipPlane.IsOn ) {
\r
841 Handle(AIS_Plane) myPreviewPlane;
\r
845 clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
\r
846 myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
\r
847 myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
\r
848 myPreviewPlane->SetSize( aSize, aSize );
\r
849 ic->SetWidth( myPreviewPlane, 10, false );
\r
850 ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
\r
851 ic->SetTransparency( myPreviewPlane, 0.5, false );
\r
852 Quantity_Color c = (aCurPlaneIndex == i) ? Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ) : Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB );
\r
853 ic->SetColor( myPreviewPlane, c , false );
\r
854 ic->Display( myPreviewPlane, 1, 0, false );
\r
855 myPreviewPlaneVector.push_back( myPreviewPlane );
\r
860 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
\r
861 getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
\r
862 gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
\r
863 (aYmax + aYmin) * 0.5,
\r
864 (aZmax + aZmin) * 0.5 );
\r
866 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
\r
868 myInteractor->setPlanes( myPreviewPlaneVector );
\r
869 myInteractor->setRotationCenter( aRotationCenter );
\r
870 myInteractor->setMinMax( aMinMax );
\r
871 myInteractor->setEnabled( true );
\r
874 void OCCViewer_ClippingDlg::updatePreview() {
\r
875 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
\r
876 int count = clipPlanesCount();
\r
879 myIsPlaneCreation ||
\r
882 (aCurPlaneIndex +1 > count) ||
\r
883 !PreviewCheckBox->isChecked())
\r
886 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
\r
888 OCCViewer_ClipPlane& aClipPlane = getClipPlane(aCurPlaneIndex);
\r
889 Handle(AIS_Plane) myPreviewPlane;
\r
891 if (aClipPlane.IsOn) {
\r
895 clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize());
\r
896 if(myPreviewPlaneVector.size() < clipPlanesCount()) {
\r
897 myPreviewPlaneVector.resize(clipPlanesCount());
\r
899 myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
\r
900 if(myPreviewPlane.IsNull()) {
\r
901 //Plane was not created
\r
902 myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt );
\r
903 myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR );
\r
904 myPreviewPlane->SetSize( aSize, aSize );
\r
905 ic->Display( myPreviewPlane, 1, 0, false );
\r
906 ic->SetWidth( myPreviewPlane, 10, false );
\r
907 ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false );
\r
908 ic->SetTransparency( myPreviewPlane, 0.5, false );
\r
909 myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane;
\r
911 myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) );
\r
912 myPreviewPlane->SetCenter( aBasePnt );
\r
913 myPreviewPlane->SetSize( aSize, aSize );
\r
916 ic->SetColor( myPreviewPlane, Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ), false );
\r
917 ic->Update( myPreviewPlane, Standard_False );
\r
919 if(myPreviewPlaneVector.size() > aCurPlaneIndex ) {
\r
920 myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex];
\r
921 if(ic->IsDisplayed(myPreviewPlane)) {
\r
922 ic->Erase( myPreviewPlane, false );
\r
923 ic->Remove( myPreviewPlane, false );
\r
925 myPreviewPlaneVector[aCurPlaneIndex].Nullify();
\r
928 for(int i = 0; i < myPreviewPlaneVector.size(); i++) {
\r
929 if( i == aCurPlaneIndex ) continue;
\r
930 if(!myPreviewPlaneVector[i].IsNull())
\r
931 ic->SetColor( myPreviewPlaneVector[i], Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false );
\r
935 double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
\r
936 getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
\r
937 gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5,
\r
938 (aYmax + aYmin) * 0.5,
\r
939 (aZmax + aZmin) * 0.5 );
\r
941 aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
\r
943 myInteractor->setPlanes( myPreviewPlaneVector );
\r
944 myInteractor->setRotationCenter( aRotationCenter );
\r
945 myInteractor->setMinMax( aMinMax );
\r
949 Erases preview of clipping plane
\r
951 void OCCViewer_ClippingDlg::erasePreview()
\r
956 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
\r
958 for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) {
\r
959 Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i];
\r
960 if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
\r
961 ic->Erase( myPreviewPlane, false );
\r
962 ic->Remove( myPreviewPlane, false );
\r
963 myPreviewPlane.Nullify();
\r
966 myPreviewPlaneVector.clear();
\r
968 myInteractor->setEnabled( false );
\r
972 Return true if plane parameters are valid
\r
974 bool OCCViewer_ClippingDlg::isValid()
\r
976 return ( SpinBox_Dx->value() !=0 || SpinBox_Dy->value() !=0 || SpinBox_Dz->value() !=0 );
\r
980 Update view after changes
\r
982 void OCCViewer_ClippingDlg::updateClipping()
\r
984 if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked())
\r
986 if (AutoApplyCheckBox->isChecked()) {
\r
990 if (!PreviewCheckBox->isChecked())
\r
998 Updates state of user controls.
\r
1000 void OCCViewer_ClippingDlg::updateControls()
\r
1002 if ( clipPlanesCount() == 0 )
\r
1008 int aPlaneIdx = ComboBoxPlanes->currentIndex();
\r
1010 OCCViewer_ClipPlane& aPlane = getClipPlane( aPlaneIdx );
\r
1012 double aPlaneDx = 0.0;
\r
1013 double aPlaneDy = 0.0;
\r
1014 double aPlaneDz = 0.0;
\r
1015 double aDistance = 0.0;
\r
1016 aPlane.OrientationToXYZ( aPlaneDx, aPlaneDy, aPlaneDz );
\r
1018 if ( aPlane.Mode == OCCViewer_ClipPlane::Absolute )
\r
1020 ModeStackedLayout->setCurrentIndex( 0 );
\r
1022 // Set plane parameters in the dialog
\r
1023 SpinBox_X->setValue( aPlane.X );
\r
1024 SpinBox_Y->setValue( aPlane.Y );
\r
1025 SpinBox_Z->setValue( aPlane.Z );
\r
1026 SpinBox_Dx->setValue( aPlaneDx );
\r
1027 SpinBox_Dy->setValue( aPlaneDy );
\r
1028 SpinBox_Dz->setValue( aPlaneDz );
\r
1029 CBAbsoluteOrientation->setCurrentIndex( aPlane.OrientationType );
\r
1030 onOrientationAbsoluteChanged( aPlane.OrientationType );
\r
1032 else if( aPlane.Mode == OCCViewer_ClipPlane::Relative )
\r
1034 ModeStackedLayout->setCurrentIndex( 1 );
\r
1036 // Set plane parameters in the dialog
\r
1037 SpinSliderRotation1->setValue( int( aPlane.RelativeOrientation.Rotation1 ) );
\r
1038 SpinSliderRotation2->setValue( int( aPlane.RelativeOrientation.Rotation2 ) );
\r
1040 XYZToDistance( myModel->getAISContext(),
\r
1041 myModel->trihedronSize(),
\r
1042 aPlane.X, aPlane.Y, aPlane.Z,
\r
1043 aPlaneDx, aPlaneDy, aPlaneDz,
\r
1046 SpinSliderDistance->setValue( aDistance );
\r
1048 CBRelativeOrientation->setCurrentIndex( aPlane.OrientationType );
\r
1049 onOrientationRelativeChanged( aPlane.OrientationType );
\r
1052 isActivePlane->setChecked( aPlane.IsOn );
\r
1056 SLOT on new button click: create a new clipping plane
\r
1058 void OCCViewer_ClippingDlg::ClickOnNew()
\r
1060 OCCViewer_ClipPlane aClipPlane;
\r
1062 // init controls state
\r
1063 myIsUpdatingControls = true;
\r
1065 myIsUpdatingControls = false;
\r
1067 // init plane according to the state of controls
\r
1068 setPlaneParam( aClipPlane );
\r
1071 myLocalPlanes.push_back( aClipPlane );
\r
1076 SLOT on delete button click: Delete selected clipping plane
\r
1078 void OCCViewer_ClippingDlg::ClickOnDelete()
\r
1080 int aPlaneIndex = ComboBoxPlanes->currentIndex();
\r
1081 if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount()))
\r
1084 myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex);
\r
1086 Handle(AIS_InteractiveContext) ic = myModel->getAISContext();
\r
1088 if(aPlaneIndex+1 <= myPreviewPlaneVector.size()) {
\r
1089 Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[aPlaneIndex];
\r
1090 if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) {
\r
1091 ic->Erase( myPreviewPlane, false );
\r
1092 ic->Remove( myPreviewPlane, false );
\r
1094 myPreviewPlaneVector.erase(myPreviewPlaneVector.begin() + aPlaneIndex);
\r
1097 if (AutoApplyCheckBox->isChecked()) {
\r
1100 myModel->update();
\r
1104 SLOT on disable all button click: Restore initial state of viewer,
\r
1105 erase all clipping planes
\r
1107 void OCCViewer_ClippingDlg::ClickOnDisableAll()
\r
1109 AutoApplyCheckBox->setChecked (false);
\r
1110 int aClipPlanesCount = clipPlanesCount();
\r
1111 for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++)
\r
1113 OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex);
\r
1114 aPlane.IsOn = false;
\r
1117 isActivePlane->setChecked(false);
\r
1118 myModel->setClipPlanes(myLocalPlanes);
\r
1119 myModel->update();
\r
1123 SLOT on ok button click: sets cutting plane and closes dialog
\r
1125 void OCCViewer_ClippingDlg::ClickOnOk()
\r
1132 SLOT on Apply button click: sets cutting plane and update viewer
\r
1134 void OCCViewer_ClippingDlg::ClickOnApply()
\r
1137 myModel->update();
\r
1141 SLOT on close button click: erases preview and rejects dialog
\r
1143 void OCCViewer_ClippingDlg::ClickOnClose()
\r
1146 OCCViewer_ViewWindow* v = qobject_cast<OCCViewer_ViewWindow*>(parent());
\r
1148 v->onClipping(false);
\r
1152 SLOT on help button click: opens a help page
\r
1154 void OCCViewer_ClippingDlg::ClickOnHelp()
\r
1156 SUIT_Application* app = SUIT_Session::session()->activeApplication();
\r
1158 app->onHelpContextModule( "GUI", "occ_3d_viewer_page.html", "clipping_planes" );
\r
1162 Set absolute mode of clipping plane
\r
1164 void OCCViewer_ClippingDlg::onModeAbsolute()
\r
1166 myIsPlaneCreation = true;
\r
1167 ModeStackedLayout->setCurrentIndex(0);
\r
1169 myIsPlaneCreation = false;
\r
1174 Set relative mode of clipping plane
\r
1176 void OCCViewer_ClippingDlg::onModeRelative()
\r
1178 myIsPlaneCreation = true;
\r
1179 ModeStackedLayout->setCurrentIndex(1);
\r
1181 myIsPlaneCreation = false;
\r
1182 SetCurrentPlaneParam();
\r
1187 SLOT: called on value of clipping plane changed
\r
1189 void OCCViewer_ClippingDlg::onValueChanged()
\r
1191 if ( myIsUpdatingControls )
\r
1196 SetCurrentPlaneParam();
\r
1198 if ( myIsSelectPlane )
\r
1207 Set current parameters of selected plane
\r
1209 void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex )
\r
1211 if ( clipPlanesCount() == 0 )
\r
1216 OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex );
\r
1218 myIsSelectPlane = true;
\r
1220 ComboBoxPlanes->setCurrentIndex( theIndex );
\r
1221 myIsSelectPlane = false;
\r
1225 Restore parameters of selected plane
\r
1227 void OCCViewer_ClippingDlg::SetCurrentPlaneParam()
\r
1229 if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy )
\r
1234 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
\r
1236 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
\r
1238 setPlaneParam( aPlane );
\r
1242 SLOT on reset button click: sets default values
\r
1244 void OCCViewer_ClippingDlg::onReset()
\r
1247 SpinBox_X->setValue(0);
\r
1248 SpinBox_Y->setValue(0);
\r
1249 SpinBox_Z->setValue(0);
\r
1256 SLOT on invert button click: inverts normal of cutting plane
\r
1258 void OCCViewer_ClippingDlg::onInvert()
\r
1260 double Dx = SpinBox_Dx->value();
\r
1261 double Dy = SpinBox_Dy->value();
\r
1262 double Dz = SpinBox_Dz->value();
\r
1265 SpinBox_Dx->setValue( -Dx );
\r
1266 SpinBox_Dy->setValue( -Dy );
\r
1267 SpinBox_Dz->setValue( -Dz );
\r
1270 if ( clipPlanesCount() != 0 )
\r
1272 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
\r
1273 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
\r
1274 aPlane.AbsoluteOrientation.IsInvert = !aPlane.AbsoluteOrientation.IsInvert;
\r
1280 SLOT: called on orientation of clipping plane in absolute mode changed
\r
1282 void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode )
\r
1284 bool isUserMode = (mode==0);
\r
1286 TextLabelX->setEnabled( isUserMode );
\r
1287 TextLabelY->setEnabled( isUserMode );
\r
1288 TextLabelZ->setEnabled( isUserMode );
\r
1290 SpinBox_X->setEnabled( isUserMode );
\r
1291 SpinBox_Y->setEnabled( isUserMode );
\r
1292 SpinBox_Z->setEnabled( isUserMode );
\r
1294 TextLabelDx->setEnabled( isUserMode );
\r
1295 TextLabelDy->setEnabled( isUserMode );
\r
1296 TextLabelDz->setEnabled( isUserMode );
\r
1298 SpinBox_Dx->setEnabled( isUserMode );
\r
1299 SpinBox_Dy->setEnabled( isUserMode );
\r
1300 SpinBox_Dz->setEnabled( isUserMode );
\r
1302 if ( !isUserMode ) {
\r
1304 double aDx = 0, aDy = 0, aDz = 0;
\r
1309 TextLabelZ->setEnabled( true );
\r
1310 SpinBox_Z->setEnabled( true );
\r
1311 SpinBox_Z->setFocus();
\r
1313 else if ( mode == 2 )
\r
1316 TextLabelX->setEnabled( true );
\r
1317 SpinBox_X->setEnabled( true );
\r
1318 SpinBox_X->setFocus();
\r
1320 else if ( mode == 3 )
\r
1323 TextLabelY->setEnabled( true );
\r
1324 SpinBox_Y->setEnabled( true );
\r
1325 SpinBox_Y->setFocus();
\r
1328 int aCurPlaneIndex = ComboBoxPlanes->currentIndex();
\r
1329 OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex );
\r
1330 if ( aPlane.AbsoluteOrientation.IsInvert == true )
\r
1338 SpinBox_Dx->setValue( aDx );
\r
1339 SpinBox_Dy->setValue( aDy );
\r
1340 SpinBox_Dz->setValue( aDz );
\r
1344 if ( !myIsUpdatingControls )
\r
1346 SetCurrentPlaneParam();
\r
1352 SLOT: called on orientation of clipping plane in relative mode changed
\r
1354 void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem)
\r
1356 if ( clipPlanesCount() == 0 )
\r
1359 if ( theItem == 0 ) {
\r
1360 TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) );
\r
1361 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) );
\r
1363 else if ( theItem == 1 ) {
\r
1364 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) );
\r
1365 TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) );
\r
1367 else if ( theItem == 2 ) {
\r
1368 TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) );
\r
1369 TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) );
\r
1372 if ( !myIsUpdatingControls )
\r
1374 if( (QComboBox*)sender() == CBRelativeOrientation )
\r
1376 SetCurrentPlaneParam();
\r
1384 SLOT: called on preview check box toggled
\r
1386 void OCCViewer_ClippingDlg::onPreview( bool on )
\r
1394 SLOT: called on Auto Apply check box toggled
\r
1396 void OCCViewer_ClippingDlg::onAutoApply( bool toggled )
\r
1400 myModel->update();
\r
1405 SLOT on Apply button click: sets cutting plane
\r
1407 void OCCViewer_ClippingDlg::onApply()
\r
1411 myIsSelectPlane = true;
\r
1413 qApp->processEvents();
\r
1414 QApplication::setOverrideCursor( Qt::WaitCursor );
\r
1415 qApp->processEvents();
\r
1417 myModel->setClipPlanes(myLocalPlanes);
\r
1419 QApplication::restoreOverrideCursor();
\r
1420 myIsSelectPlane = false;
\r
1424 SLOT: Called when clip plane is clicked in viewer.
\r
1426 void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane )
\r
1428 for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
\r
1430 Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
\r
1431 if ( aPlane != thePlane )
\r
1436 ComboBoxPlanes->setCurrentIndex( aPlaneIt );
\r
1443 SLOT: Called when clip plane is changed by dragging in viewer.
\r
1445 void OCCViewer_ClippingDlg::onPlaneDragged( const Handle(AIS_Plane)& thePlane )
\r
1447 for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ )
\r
1449 Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt );
\r
1450 if ( aPlane != thePlane )
\r
1455 OCCViewer_ClipPlane& aClipPlane = getClipPlane( aPlaneIt );
\r
1457 gp_Pln aPln = thePlane->Component()->Pln();
\r
1458 const gp_Pnt& aPlaneP = aPln.Location();
\r
1459 const gp_Dir& aPlaneN = aPln.Axis().Direction();
\r
1461 aClipPlane.X = aPlaneP.X();
\r
1462 aClipPlane.Y = aPlaneP.Y();
\r
1463 aClipPlane.Z = aPlaneP.Z();
\r
1465 if ( aClipPlane.Mode == OCCViewer_ClipPlane::Absolute )
\r
1467 if ( aClipPlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom )
\r
1469 aClipPlane.AbsoluteOrientation.Dx = aPlaneN.X();
\r
1470 aClipPlane.AbsoluteOrientation.Dy = aPlaneN.Y();
\r
1471 aClipPlane.AbsoluteOrientation.Dz = aPlaneN.Z();
\r
1476 OCCViewer_ClipPlane::DXYZToRelative( aPlaneN.X(), aPlaneN.Y(), aPlaneN.Z(),
\r
1477 aClipPlane.OrientationType,
\r
1478 aClipPlane.RelativeOrientation.Rotation1,
\r
1479 aClipPlane.RelativeOrientation.Rotation2 );
\r
1482 myIsUpdatingControls = true;
\r
1484 myIsUpdatingControls = false;
\r
1486 if ( AutoApplyCheckBox->isChecked() )
\r
1495 OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx )
\r
1497 return myLocalPlanes[theIdx];
\r
1500 int OCCViewer_ClippingDlg::clipPlanesCount()
\r
1502 return myLocalPlanes.size();
\r
1505 OCCViewer_ClipPlane::PlaneMode OCCViewer_ClippingDlg::currentPlaneMode() const
1507 return ModeStackedLayout->currentIndex() == 0
1508 ? OCCViewer_ClipPlane::Absolute
1509 : OCCViewer_ClipPlane::Relative;