X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FOCCViewer%2FOCCViewer_ClippingDlg.cxx;h=40ee9ad4611b7746b5fe6d0a71b195eb4b0dac62;hb=c47605c13ccf37a7b3fcb9cb6c8baf38d3643f77;hp=065ef91f2ff21b1b165ca059d9929fc37893079f;hpb=a0054494bc71aff902b2bac8449acbcb118192e4;p=modules%2Fgui.git diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.cxx b/src/OCCViewer/OCCViewer_ClippingDlg.cxx old mode 100644 new mode 100755 index 065ef91f2..40ee9ad46 --- a/src/OCCViewer/OCCViewer_ClippingDlg.cxx +++ b/src/OCCViewer/OCCViewer_ClippingDlg.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,14 +23,19 @@ #include "OCCViewer_ClippingDlg.h" #include +#include +#include #include #include "SUIT_Session.h" #include "SUIT_ViewWindow.h" #include "SUIT_ViewManager.h" +#include "OCCViewer_ClipPlane.h" #include "OCCViewer_ViewWindow.h" #include "OCCViewer_ViewPort3d.h" #include "OCCViewer_ViewModel.h" +#include "OCCViewer_ViewManager.h" +#include "OCCViewer_ClipPlaneInteractor.h" #include #include @@ -59,60 +64,80 @@ #include #include -/*! - Constructor of class ClipPlane - */ -ClipPlane::ClipPlane(): - RelativeMode(), - X(0.0), Y(0.0), Z(0.0), - Dx(1.0), Dy(1.0), Dz(1.0), - Orientation(0), - IsActive( true ), - IsInvert( false ), - PlaneMode( Absolute ) -{ -} - -/*! - Constructor of class OrientedPlane - */ -OrientedPlane::OrientedPlane(): - Orientation(0), - Distance(0.5), - Rotation1(0), - Rotation2(0) -{ -} - /********************************************************************************** ************************ Internal functions ************************ *********************************************************************************/ +void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic, + double theDefaultSize, + double& theXMin, + double& theYMin, + double& theZMin, + double& theXMax, + double& theYMax, + double& theZMax) { + + double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax; + aXMin = aYMin = aZMin = DBL_MAX; + aXMax = aYMax = aZMax = -DBL_MAX; + + bool isFound = false; + AIS_ListOfInteractive aList; + ic->DisplayedObjects( aList ); + for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) { + Handle(AIS_InteractiveObject) anObj = it.Value(); + if ( !anObj.IsNull() && anObj->HasPresentation() && + !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) { + Handle(Prs3d_Presentation) aPrs = anObj->Presentation(); + if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) { + isFound = true; + double xmin, ymin, zmin, xmax, ymax, zmax; + aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax ); + aXMin = qMin( aXMin, xmin ); aXMax = qMax( aXMax, xmax ); + aYMin = qMin( aYMin, ymin ); aYMax = qMax( aYMax, ymax ); + aZMin = qMin( aZMin, zmin ); aZMax = qMax( aZMax, zmax ); + } + } + } + + if(!isFound) { + if(theDefaultSize == 0.0) + theDefaultSize = 100.; + aXMin = aYMin = aZMin = -theDefaultSize; + aXMax = aYMax = aZMax = theDefaultSize; + } + theXMin = aXMin;theYMin = aYMin;theZMin = aZMin; + theXMax = aXMax;theYMax = aYMax;theZMax = aZMax; +} + /*! Compute the point of bounding box and current clipping plane */ -void ComputeBoundsParam( double theBounds[6], - double theDirection[3], +void ComputeBoundsParam( const double theBounds[6], + const double theDirection[3], double theMinPnt[3], double& theMaxBoundPrj, double& theMinBoundPrj ) { - //Enlarge bounds in order to avoid conflicts of precision - for(int i = 0; i < 6; i += 2) { + double aEnlargeBounds[6]; + + // Enlarge bounds in order to avoid conflicts of precision + for(int i = 0; i < 6; i += 2) + { static double EPS = 1.0E-3; double aDelta = (theBounds[i+1] - theBounds[i])*EPS; - theBounds[i] -= aDelta; - theBounds[i+1] += aDelta; + aEnlargeBounds[i ] = theBounds[i ] - aDelta; + aEnlargeBounds[i+1] = theBounds[i+1] + aDelta; } - double aBoundPoints[8][3] = { { theBounds[0], theBounds[2], theBounds[4] }, - { theBounds[1], theBounds[2], theBounds[4] }, - { theBounds[0], theBounds[3], theBounds[4] }, - { theBounds[1], theBounds[3], theBounds[4] }, - { theBounds[0], theBounds[2], theBounds[5] }, - { theBounds[1], theBounds[2], theBounds[5] }, - { theBounds[0], theBounds[3], theBounds[5] }, - { theBounds[1], theBounds[3], theBounds[5] } }; + double aBoundPoints[8][3] = { { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[4] }, + { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[4] }, + { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[4] }, + { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[4] }, + { aEnlargeBounds[0], aEnlargeBounds[2], aEnlargeBounds[5] }, + { aEnlargeBounds[1], aEnlargeBounds[2], aEnlargeBounds[5] }, + { aEnlargeBounds[0], aEnlargeBounds[3], aEnlargeBounds[5] }, + { aEnlargeBounds[1], aEnlargeBounds[3], aEnlargeBounds[5] } }; int aMaxId = 0; theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1] @@ -138,131 +163,161 @@ void ComputeBoundsParam( double theBounds[6], /*! Compute the position of current plane by distance */ -void DistanceToPosition( double theBounds[6], - double theDirection[3], - double theDist, +void DistanceToPosition( const double theBounds[6], + const double theDirection[3], + const double theDist, double thePos[3] ) { double aMaxBoundPrj, aMinBoundPrj, aMinPnt[3]; - ComputeBoundsParam( theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj ); - double aLength = (aMaxBoundPrj - aMinBoundPrj)*theDist; - thePos[0] = aMinPnt[0] - theDirection[0]*aLength; - thePos[1] = aMinPnt[1] - theDirection[1]*aLength; - thePos[2] = aMinPnt[2] - theDirection[2]*aLength; + ComputeBoundsParam( theBounds, theDirection, aMinPnt, aMaxBoundPrj, aMinBoundPrj ); + double aLength = (aMaxBoundPrj - aMinBoundPrj) * theDist; + thePos[0] = aMinPnt[0] - theDirection[0] * aLength; + thePos[1] = aMinPnt[1] - theDirection[1] * aLength; + thePos[2] = aMinPnt[2] - theDirection[2] * aLength; } /*! Compute the parameters of clipping plane */ -bool ComputeClippingPlaneParameters( double theNormal[3], - double theDist, - double theBounds[6], - double theOrigin[3], - Handle(V3d_View) theView3d ) +bool ComputeClippingPlaneParameters( const Handle(AIS_InteractiveContext)& theIC, + const double theDefaultSize, + const double theNormal[3], + const double theDist, + double theOrigin[3] ) { - bool anIsOk = false; - theBounds[0] = theBounds[2] = theBounds[4] = 999.99; - theBounds[1] = theBounds[3] = theBounds[5] = -999.99; double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - theView3d->View()->MinMaxValues( aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5]); - if ( !theView3d->View()->ContainsFacet() ) { - aBounds[0] = aBounds[2] = aBounds[4] = 0.0; - aBounds[1] = aBounds[3] = aBounds[5] = 100.0; - } - anIsOk = true; - - if( !anIsOk ) - return false; + getMinMaxFromContext( theIC, theDefaultSize, aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5] ); DistanceToPosition( aBounds, theNormal, theDist, theOrigin ); return true; } /*! - Cross product of two 3-vectors. Result vector in result[3]. + \brief Converts relative plane parameters to absolute. + \param theIC [in] the interactive context. + \param theDefaultSize [in] the default trihedron size. + \param theDistance [in] the plane distance relative to minimum corner of model boundaries. + \param theDX [in] x component of plane direction. + \param theDY [in] y component of plane direction. + \param theDZ [in] z component of plane direction. + \param theX [out] x coordinate of plane origin. + \param theY [out] y coordinate of plane origin. + \param theZ [out] z coordinate of plane origin. */ -void Cross(const double first[3], const double second[3], double result[3]) +bool DistanceToXYZ ( const Handle(AIS_InteractiveContext)& theIC, + const double theDefaultSize, + const double theDistance, + const double theDX, + const double theDY, + const double theDZ, + double& theX, + double& theY, + double& theZ ) { - result[0] = first[1]*second[2] - first[2]*second[1]; - result[1] = first[2]*second[0] - first[0]*second[2]; - result[2] = first[0]*second[1] - first[1]*second[0]; + double aNormal[3] = { theDX, theDY, theDZ }; + double anOrigin[3] = { 0.0, 0.0, 0.0 }; + + bool anIsOk = ComputeClippingPlaneParameters( theIC, theDefaultSize, aNormal, theDistance, anOrigin ); + + if( !anIsOk ) + { + return false; + } + + theX = anOrigin[0]; + theY = anOrigin[1]; + theZ = anOrigin[2]; + + return true; } /*! - Compute relative clipping plane in absolute coordinates + \brief Converts absolute position and direction to bounding box distance. + \param theIC [in] the interactive context. + \param theDefaultSize [in] the default trihedron size. + \param theX [in] x coordinate of plane origin. + \param theY [in] y coordinate of plane origin. + \param theZ [in] z coordinate of plane origin. + \param theDX [in] x component of plane direction. + \param theDY [in] y component of plane direction. + \param theDZ [in] z component of plane direction. + \param theDistance [out] the plane distance relative to minimum corner of model boundaries. */ -void RelativePlaneToAbsolute ( ClipPlane* thePlane, Handle(V3d_View) theView3d ) +void XYZToDistance ( const Handle(AIS_InteractiveContext)& theIC, + const double theDefaultSize, + const double theX, + const double theY, + const double theZ, + const double theDX, + const double theDY, + const double theDZ, + double& theDistance ) { - double aNormal[3]; - double aDir[2][3] = { { 0, 0, 0 }, { 0, 0, 0 } }; - { - static double aCoeff = M_PI/180.0; - - double anU[2] = { cos( aCoeff * thePlane->RelativeMode.Rotation1 ), cos( aCoeff * thePlane->RelativeMode.Rotation2 ) }; - double aV[2] = { sqrt( 1.0 - anU[0]*anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) }; - aV[0] = thePlane->RelativeMode.Rotation1 > 0? aV[0]: -aV[0]; - aV[1] = thePlane->RelativeMode.Rotation2 > 0? aV[1]: -aV[1]; - - switch ( thePlane->RelativeMode.Orientation ) { - case 0: - aDir[0][1] = anU[0]; - aDir[0][2] = aV[0]; - aDir[1][0] = anU[1]; - aDir[1][2] = aV[1]; - break; - case 1: - aDir[0][2] = anU[0]; - aDir[0][0] = aV[0]; - aDir[1][1] = anU[1]; - aDir[1][0] = aV[1]; - break; - case 2: - aDir[0][0] = anU[0]; - aDir[0][1] = aV[0]; - aDir[1][2] = anU[1]; - aDir[1][1] = aV[1]; - break; - } + gp_Pnt aPlaneP( theX, theY, theZ ); + gp_Dir aPlaneN( theDX, theDY, theDZ ); - Cross( aDir[1], aDir[0], aNormal ); - // Normalize - double den; - den = sqrt( aNormal[0] * aNormal[0] + aNormal[1] * aNormal[1] + aNormal[2] * aNormal[2] ); - if ( den != 0.0 ) { - for (int i=0; i < 3; i++) { - aNormal[i] /= den; - } - } - Cross( aNormal, aDir[1], aDir[0] ); - } + double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; - double aBounds[6]; - double anOrigin[3]; + getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); - bool anIsOk = false; + Bnd_Box aMinMax; + aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); - anOrigin[0] = anOrigin[1] = anOrigin[2] = 0; - aBounds[0] = aBounds[2] = aBounds[4] = 0; - aBounds[1] = aBounds[3] = aBounds[5] = 0; - anIsOk = true; + gp_Trsf aRelativeTransform; + aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) ); + Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform ); - anIsOk = ComputeClippingPlaneParameters( aNormal, - thePlane->RelativeMode.Distance, - aBounds, - anOrigin, - theView3d ); - if( !anIsOk ) - return; - - thePlane->Dx = aNormal[0]; - thePlane->Dy = aNormal[1]; - thePlane->Dz = aNormal[2]; - thePlane->X = anOrigin[0]; - thePlane->Y = anOrigin[1]; - thePlane->Z = anOrigin[2]; + aRelativeBounds.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); + + double aLength = aZmax - aZmin; + double aDistance = aZmax; + + double aRelativeDistance = aLength > 0.01 ? aDistance / aLength : 0.0; + aRelativeDistance = qMin( aRelativeDistance, aLength ); + aRelativeDistance = qMax( aRelativeDistance, 0.0 ); + theDistance = aRelativeDistance; +} + +/*! + Compute clipping plane size base point and normal + */ + +void clipPlaneParams(OCCViewer_ClipPlane& theClipPlane, Handle(AIS_InteractiveContext) theContext, + double& theSize, gp_Pnt& theBasePnt, gp_Dir& theNormal, double defaultSize) { + double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax; + aXMin = aYMin = aZMin = DBL_MAX; + aXMax = aYMax = aZMax = -DBL_MAX; + + getMinMaxFromContext(theContext,defaultSize,aXMin, aYMin, aZMin, aXMax, aYMax, aZMax); + double aSize = 50; + + double aNormalX = 0.0; + double aNormalY = 0.0; + double aNormalZ = 0.0; + theClipPlane.OrientationToXYZ( aNormalX, aNormalY, aNormalZ ); + gp_Pnt aBasePnt( theClipPlane.X, theClipPlane.Y, theClipPlane.Z ); + gp_Dir aNormal( aNormalX, aNormalY, aNormalZ ); + + // compute clipping plane size + gp_Pnt aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 ); + double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2; + aSize = aDiag * 1.1; + + // compute clipping plane center ( redefine the base point ) + IntAna_IntConicQuad intersector = IntAna_IntConicQuad(); + + intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() ); + + if ( intersector.IsDone() && intersector.NbPoints() == 1 ) + aBasePnt = intersector.Point( 1 ); + + theSize = aSize; + theBasePnt = aBasePnt; + theNormal = aNormal; } + /********************************************************************************* ********************* class OCCViewer_ClippingDlg ********************* *********************************************************************************/ @@ -270,18 +325,16 @@ void RelativePlaneToAbsolute ( ClipPlane* thePlane, Handle(V3d_View) theView3d ) Constructor \param view - view window \param parent - parent widget - \param name - dialog name - \param modal - is this dialog modal - \param fl - flags */ -OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const char* name, bool modal, Qt::WindowFlags fl ) -: QDialog( view, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ), - myView( view ) +OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model) + : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ) { setObjectName( "OCCViewer_ClippingDlg" ); - setModal( modal ); + setModal( false ); setWindowTitle( tr( "Clipping" ) ); + + setAttribute (Qt::WA_DeleteOnClose, true); QVBoxLayout* topLayout = new QVBoxLayout( this ); topLayout->setMargin( 11 ); topLayout->setSpacing( 6 ); @@ -299,7 +352,6 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const MenuMode->addAction( tr( "ABSOLUTE" ), this, SLOT( onModeAbsolute() ) ); MenuMode->addAction( tr( "RELATIVE" ), this, SLOT( onModeRelative() ) ); buttonNew->setMenu( MenuMode ); - CurrentMode = Absolute; GroupPlanesLayout->addWidget( ComboBoxPlanes ); GroupPlanesLayout->addWidget( isActivePlane ); @@ -445,72 +497,38 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const CBRelativeOrientation->addItem( tr("ALONG_ZX") ); GroupParametersLayout->addWidget( CBRelativeOrientation, 0, 1 ); - TLValueDistance = new QLabel( GroupParameters ); - TLValueDistance->setObjectName( "TLValueDistance" ); - TLValueDistance->setAlignment( Qt::AlignCenter ); - TLValueDistance->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - QFont fnt = TLValueDistance->font(); fnt.setBold( true ); TLValueDistance->setFont( fnt ); - GroupParametersLayout->addWidget( TLValueDistance, 1, 1 ); - TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters ); TextLabelDistance->setObjectName( "TextLabelDistance" ); - GroupParametersLayout->addWidget( TextLabelDistance, 2, 0 ); - - SliderDistance = new QSlider( Qt::Horizontal, GroupParameters ); - SliderDistance->setObjectName( "SliderDistance" ); - SliderDistance->setFocusPolicy( Qt::NoFocus ); - SliderDistance->setMinimumSize( 300, 0 ); - SliderDistance->setMinimum( 0 ); - SliderDistance->setMaximum( 100 ); - SliderDistance->setSingleStep( 1 ); - SliderDistance->setPageStep( 10 ); - SliderDistance->setTracking( false ); - GroupParametersLayout->addWidget( SliderDistance, 2, 1 ); - - TLValueRotation1 = new QLabel( GroupParameters ); - TLValueRotation1->setObjectName( "TLValueRotation1" ); - TLValueRotation1->setAlignment( Qt::AlignCenter ); - TLValueRotation1->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - TLValueRotation1->setFont( fnt ); - GroupParametersLayout->addWidget( TLValueRotation1, 3, 1 ); + GroupParametersLayout->addWidget( TextLabelDistance, 1, 0 ); + + SpinSliderDistance = new QtxDoubleSpinSlider( 0., 1., 0.01, GroupParameters ); + SpinSliderDistance->setObjectName( "SpinSliderDistance" ); + SpinSliderDistance->setPrecision( precision ); + QFont fnt = SpinSliderDistance->font(); fnt.setBold( true ); SpinSliderDistance->setFont( fnt ); + GroupParametersLayout->addWidget( SpinSliderDistance, 1, 1 ); + + QString aUnitRot = "\xB0"; TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters ); TextLabelRotation1->setObjectName( "TextLabelRotation1" ); - GroupParametersLayout->addWidget( TextLabelRotation1, 4, 0 ); - - SliderRotation1 = new QSlider( Qt::Horizontal, GroupParameters ); - SliderRotation1->setObjectName( "SliderRotation1" ); - SliderRotation1->setFocusPolicy( Qt::NoFocus ); - SliderRotation1->setMinimumSize( 300, 0 ); - SliderRotation1->setMinimum( -180 ); - SliderRotation1->setMaximum( 180 ); - SliderRotation1->setSingleStep( 1 ); - SliderRotation1->setPageStep( 10 ); - SliderRotation1->setTracking(false); - GroupParametersLayout->addWidget( SliderRotation1, 4, 1 ); - - TLValueRotation2 = new QLabel( GroupParameters ); - TLValueRotation2->setObjectName( "TLValueRotation2" ); - TLValueRotation2->setAlignment( Qt::AlignCenter ); - TLValueRotation2->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); - TLValueRotation2->setFont( fnt ); - GroupParametersLayout->addWidget( TLValueRotation2, 5, 1 ); + GroupParametersLayout->addWidget( TextLabelRotation1, 2, 0 ); + + SpinSliderRotation1 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters ); + SpinSliderRotation1->setObjectName( "SpinSliderRotation1" ); + SpinSliderRotation1->setUnit( aUnitRot ); + SpinSliderRotation1->setFont( fnt ); + GroupParametersLayout->addWidget( SpinSliderRotation1, 2, 1 ); TextLabelRotation2 = new QLabel(tr("ROTATION_AROUND_Y_X2Z"), GroupParameters); TextLabelRotation2->setObjectName( "TextLabelRotation2" ); TextLabelRotation2->setObjectName( "TextLabelRotation2" ); - GroupParametersLayout->addWidget( TextLabelRotation2, 6, 0 ); - - SliderRotation2 = new QSlider( Qt::Horizontal, GroupParameters ); - SliderRotation2->setObjectName( "SliderRotation2" ); - SliderRotation2->setFocusPolicy( Qt::NoFocus ); - SliderRotation2->setMinimumSize( 300, 0 ); - SliderRotation2->setMinimum( -180 ); - SliderRotation2->setMaximum( 180 ); - SliderRotation2->setSingleStep( 1 ); - SliderRotation2->setPageStep( 10 ); - SliderRotation2->setTracking(false); - GroupParametersLayout->addWidget( SliderRotation2, 6, 1 ); + GroupParametersLayout->addWidget( TextLabelRotation2, 3, 0 ); + + SpinSliderRotation2 = new QtxIntSpinSlider( -180, 180, 1, GroupParameters ); + SpinSliderRotation2->setObjectName( "SpinSliderRotation2" ); + SpinSliderRotation2->setUnit( aUnitRot ); + SpinSliderRotation2->setFont( fnt ); + GroupParametersLayout->addWidget( SpinSliderRotation2, 3, 1 ); /***************************************************************/ QGroupBox* CheckBoxWidget = new QGroupBox( this ); @@ -589,12 +607,9 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const connect( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ; connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( int ) ) ); - connect( SliderDistance, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderDistanceHasMoved( int ) ) ); - connect( SliderDistance, SIGNAL( valueChanged( int ) ), this, SLOT( SliderDistanceHasMoved( int ) ) ); - connect( SliderRotation1, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderRotation1HasMoved( int ) ) ); - connect( SliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( SliderRotation1HasMoved( int ) ) ); - connect( SliderRotation2, SIGNAL( sliderMoved( int ) ), this, SLOT( SliderRotation2HasMoved( int ) ) ); - connect( SliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( SliderRotation2HasMoved( int ) ) ); + connect( SpinSliderDistance, SIGNAL( valueChanged( double ) ), this, SLOT( onValueChanged() ) ); + connect( SpinSliderRotation1, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) ); + connect( SpinSliderRotation2, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged() ) ); connect( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ; connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) ); @@ -603,14 +618,21 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const connect( buttonOk, SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); connect( buttonApply, SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ); connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( ClickOnHelp() ) ); - - connect(view, SIGNAL(Show( QShowEvent* ) ), this, SLOT( onViewShow() ) ); - connect(view, SIGNAL(Hide( QHideEvent* ) ), this, SLOT( onViewHide() ) ); myBusy = false; myIsSelectPlane = false; - myView3d = myView->getViewPort()->getView(); + myIsPlaneCreation = false; + myIsUpdatingControls = false; + myModel = model; + + myModel->getViewer3d()->InitActiveViews(); + + OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) myModel->getViewManager(); + myInteractor = new OCCViewer_ClipPlaneInteractor( aViewMgr, this ); + connect( myInteractor, SIGNAL( planeClicked( const Handle_AIS_Plane& ) ), SLOT( onPlaneClicked( const Handle_AIS_Plane& ) ) ); + connect( myInteractor, SIGNAL( planeDragged( const Handle_AIS_Plane& ) ), SLOT( onPlaneDragged( const Handle_AIS_Plane& ) ) ); + myLocalPlanes = myModel->getClipPlanes(); synchronize(); } @@ -618,11 +640,9 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const Destructor Destroys the object and frees any allocated resources */ -OCCViewer_ClippingDlg::~ OCCViewer_ClippingDlg() +OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg() { - // no need to delete child widgets, Qt does it all for us - foreach( ClipPlane* aPlane, myClippingPlanes ) - delete aPlane; + myLocalPlanes.clear(); } /*! @@ -631,8 +651,10 @@ OCCViewer_ClippingDlg::~ OCCViewer_ClippingDlg() void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e ) { erasePreview(); - myAction->setChecked( false ); QDialog::closeEvent( e ); + OCCViewer_ViewWindow* v = qobject_cast(parent()); + if(v) + v->onClipping(false); } /*! @@ -651,6 +673,10 @@ void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e ) { erasePreview(); QDialog::hideEvent( e ); + OCCViewer_ViewWindow* v = qobject_cast(parent()); + if(v) + v->onClipping(false); + } /*! @@ -668,13 +694,85 @@ void OCCViewer_ClippingDlg::initParam() CBAbsoluteOrientation->setCurrentIndex(0); - TLValueDistance->setText( "0" ); - TLValueRotation1->setText( "0\xB0" ); - TLValueRotation2->setText( "0\xB0" ); + SpinSliderDistance->setValue( 0.5 ); + SpinSliderRotation1->setValue( 0 ); + SpinSliderRotation2->setValue( 0 ); CBRelativeOrientation->setCurrentIndex( 0 ); - SliderDistance->setValue( 50 ); - SliderRotation1->setValue( 0 ); - SliderRotation2->setValue( 0 ); + + isActivePlane->setChecked( true ); +} + +/*! + Set plane parameters from widgets. +*/ +void OCCViewer_ClippingDlg::setPlaneParam( OCCViewer_ClipPlane& thePlane ) +{ + OCCViewer_ClipPlane::PlaneMode aMode = currentPlaneMode(); + + thePlane.Mode = aMode; + + if ( aMode == OCCViewer_ClipPlane::Absolute ) + { + if( qFuzzyIsNull( SpinBox_Dx->value() ) && + qFuzzyIsNull( SpinBox_Dy->value() ) && + qFuzzyIsNull( SpinBox_Dz->value() ) ) { + return; + } + } + + thePlane.OrientationType = (aMode == OCCViewer_ClipPlane::Absolute) + ? CBAbsoluteOrientation->currentIndex() + : CBRelativeOrientation->currentIndex(); + + // Get XYZ, DXYZ + if ( aMode == OCCViewer_ClipPlane::Absolute ) + { + if ( thePlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom ) + { + thePlane.AbsoluteOrientation.Dx = SpinBox_Dx->value(); + thePlane.AbsoluteOrientation.Dy = SpinBox_Dy->value(); + thePlane.AbsoluteOrientation.Dz = SpinBox_Dz->value(); + } + else + { + thePlane.AbsoluteOrientation.IsInvert = SpinBox_Dx->value() < 0.0 + || SpinBox_Dy->value() < 0.0 + || SpinBox_Dz->value() < 0.0; + } + + thePlane.X = SpinBox_X->value(); + thePlane.Y = SpinBox_Y->value(); + thePlane.Z = SpinBox_Z->value(); + } + else + { + thePlane.RelativeOrientation.Rotation1 = SpinSliderRotation1->value(); + thePlane.RelativeOrientation.Rotation2 = SpinSliderRotation2->value(); + + double aPlaneDx = 0.0; + double aPlaneDy = 0.0; + double aPlaneDz = 0.0; + double aX = 0.0; + double aY = 0.0; + double aZ = 0.0; + + OCCViewer_ClipPlane::RelativeToDXYZ( thePlane.OrientationType, + thePlane.RelativeOrientation.Rotation1, + thePlane.RelativeOrientation.Rotation2, + aPlaneDx, aPlaneDy, aPlaneDz ); + + DistanceToXYZ( myModel->getAISContext(), + myModel->trihedronSize(), + SpinSliderDistance->value(), + aPlaneDx, aPlaneDy, aPlaneDz, + aX, aY, aZ ); + + thePlane.X = aX; + thePlane.Y = aY; + thePlane.Z = aZ; + } + + thePlane.IsOn = isActivePlane->isChecked(); } /*! @@ -683,7 +781,7 @@ void OCCViewer_ClippingDlg::initParam() void OCCViewer_ClippingDlg::synchronize() { ComboBoxPlanes->clear(); - int aNbPlanesAbsolute = myClippingPlanes.size(); + int aNbPlanesAbsolute = myLocalPlanes.size(); QString aName; for(int i = 1; i<=aNbPlanesAbsolute; i++ ) { @@ -701,9 +799,9 @@ void OCCViewer_ClippingDlg::synchronize() else { ComboBoxPlanes->addItem( tr( "NO_PLANES" ) ); initParam(); - ClickOnDisableAll(); } - if ( CurrentMode == Absolute ) { + if ( currentPlaneMode() == OCCViewer_ClipPlane::Absolute ) + { SpinBox_X->setEnabled( anIsControlsEnable ); SpinBox_Y->setEnabled( anIsControlsEnable ); SpinBox_Z->setEnabled( anIsControlsEnable ); @@ -714,11 +812,12 @@ void OCCViewer_ClippingDlg::synchronize() invertButton->setEnabled( anIsControlsEnable ); resetButton->setEnabled( anIsControlsEnable ); } - else if( CurrentMode == Relative ) { + else if ( currentPlaneMode() == OCCViewer_ClipPlane::Relative ) + { CBRelativeOrientation->setEnabled( anIsControlsEnable ); - SliderDistance->setEnabled( anIsControlsEnable ); - SliderRotation1->setEnabled( anIsControlsEnable ); - SliderRotation2->setEnabled( anIsControlsEnable ); + SpinSliderDistance->setEnabled( anIsControlsEnable ); + SpinSliderRotation1->setEnabled( anIsControlsEnable ); + SpinSliderRotation2->setEnabled( anIsControlsEnable ); isActivePlane->setEnabled( anIsControlsEnable ); } isActivePlane->setEnabled( anIsControlsEnable ); @@ -729,85 +828,121 @@ void OCCViewer_ClippingDlg::synchronize() */ void OCCViewer_ClippingDlg::displayPreview() { - if ( myBusy || !isValid() ) - return; - - OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel(); - if ( !anOCCViewer ) + if ( myBusy || !isValid() || !myModel) return; - Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext(); - - double aXMin, aYMin, aZMin, aXMax, aYMax, aZMax; - aXMin = aYMin = aZMin = DBL_MAX; - aXMax = aYMax = aZMax = -DBL_MAX; + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - bool isFound = false; - AIS_ListOfInteractive aList; - ic->DisplayedObjects( aList ); - for ( AIS_ListIteratorOfListOfInteractive it( aList ); it.More(); it.Next() ) - { - Handle(AIS_InteractiveObject) anObj = it.Value(); - if ( !anObj.IsNull() && anObj->HasPresentation() && - !anObj->IsKind( STANDARD_TYPE(AIS_Plane) ) ) { - Handle(Prs3d_Presentation) aPrs = anObj->Presentation(); - if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) { - isFound = true; - double xmin, ymin, zmin, xmax, ymax, zmax; - aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax ); - aXMin = qMin( aXMin, xmin ); aXMax = qMax( aXMax, xmax ); - aYMin = qMin( aYMin, ymin ); aYMax = qMax( aYMax, ymax ); - aZMin = qMin( aZMin, zmin ); aZMax = qMax( aZMax, zmax ); - } + for ( int i=0; i < clipPlanesCount(); i++ ) { + OCCViewer_ClipPlane& aClipPlane = getClipPlane(i); + if ( aClipPlane.IsOn ) { + Handle(AIS_Plane) myPreviewPlane; + double aSize; + gp_Pnt aBasePnt; + gp_Dir aNormal; + clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize()); + myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt ); + myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR ); + myPreviewPlane->SetSize( aSize, aSize ); + ic->SetWidth( myPreviewPlane, 10, false ); + ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false ); + ic->SetTransparency( myPreviewPlane, 0.5, false ); + 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 ); + ic->SetColor( myPreviewPlane, c , false ); + ic->Display( myPreviewPlane, 1, 0, false ); + myPreviewPlaneVector.push_back( myPreviewPlane ); } } + myModel->update(); + + double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5, + (aYmax + aYmin) * 0.5, + (aZmax + aZmin) * 0.5 ); + Bnd_Box aMinMax; + aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); + + myInteractor->setPlanes( myPreviewPlaneVector ); + myInteractor->setRotationCenter( aRotationCenter ); + myInteractor->setMinMax( aMinMax ); + myInteractor->setEnabled( true ); +} - double aSize = 50; - - ClipPlane* aClipPlane; - for ( int i=0; i < myClippingPlanes.size(); i++ ) { - Pnt_ClipPlane aPlane = myClippingPlanes[i]; - aClipPlane = aPlane; - - double Epsilon = 0.0001; - double Epsilon_Dx = ( aClipPlane->Dx > 0 ) ? Epsilon: -Epsilon; - double Epsilon_Dy = ( aClipPlane->Dy > 0 ) ? Epsilon: -Epsilon; - double Epsilon_Dz = ( aClipPlane->Dz > 0 ) ? Epsilon: -Epsilon; - - gp_Pnt aBasePnt( aClipPlane->X + Epsilon_Dx, aClipPlane->Y + Epsilon_Dy, aClipPlane->Z + Epsilon_Dz ); - gp_Dir aNormal( aClipPlane->Dx, aClipPlane->Dy, aClipPlane->Dz ); - gp_Pnt aCenter = aBasePnt; - - if ( isFound ) - { - // compute clipping plane size - aCenter = gp_Pnt( ( aXMin + aXMax ) / 2, ( aYMin + aYMax ) / 2, ( aZMin + aZMax ) / 2 ); - double aDiag = aCenter.Distance( gp_Pnt( aXMax, aYMax, aZMax ) )*2; - aSize = aDiag * 1.1; - - // compute clipping plane center ( redefine the base point ) - IntAna_IntConicQuad intersector = IntAna_IntConicQuad(); - - intersector.Perform( gp_Lin( aCenter, aNormal), gp_Pln( aBasePnt, aNormal), Precision::Confusion() ); - if ( intersector.IsDone() && intersector.NbPoints() == 1 ) - aBasePnt = intersector.Point( 1 ); +void OCCViewer_ClippingDlg::updatePreview() { + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + int count = clipPlanesCount(); + if ( myBusy || + !isValid() || + myIsPlaneCreation || + !myModel || + count == 0 || + (aCurPlaneIndex +1 > count) || + !PreviewCheckBox->isChecked()) + return; + + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + + OCCViewer_ClipPlane& aClipPlane = getClipPlane(aCurPlaneIndex); + Handle(AIS_Plane) myPreviewPlane; + + if (aClipPlane.IsOn) { + double aSize; + gp_Pnt aBasePnt; + gp_Dir aNormal; + clipPlaneParams(aClipPlane, ic, aSize, aBasePnt, aNormal, myModel->trihedronSize()); + if(myPreviewPlaneVector.size() < clipPlanesCount()) { + myPreviewPlaneVector.resize(clipPlanesCount()); } - - if ( aClipPlane->IsActive == true ) { - Handle(AIS_Plane) myPreviewPlane; - myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ) ); + myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex]; + if(myPreviewPlane.IsNull()) { + //Plane was not created + myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ), aBasePnt ); + myPreviewPlane->SetTypeOfSensitivity( Select3D_TOS_INTERIOR ); myPreviewPlane->SetSize( aSize, aSize ); - - ic->Display( myPreviewPlane, 1, -1, false ); + ic->Display( myPreviewPlane, 1, 0, false ); ic->SetWidth( myPreviewPlane, 10, false ); ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false ); ic->SetTransparency( myPreviewPlane, 0.5, false ); - ic->SetColor( myPreviewPlane, Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false ); + myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane; + } else { + myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) ); + myPreviewPlane->SetCenter( aBasePnt ); + myPreviewPlane->SetSize( aSize, aSize ); + } - myPreviewPlaneVector.push_back( myPreviewPlane ); + ic->SetColor( myPreviewPlane, Quantity_Color( 255. / 255., 70. / 255., 0. / 255., Quantity_TOC_RGB ), false ); + ic->Update( myPreviewPlane, Standard_False ); + } else { + if(myPreviewPlaneVector.size() > aCurPlaneIndex ) { + myPreviewPlane = myPreviewPlaneVector[aCurPlaneIndex]; + if(ic->IsDisplayed(myPreviewPlane)) { + ic->Erase( myPreviewPlane, false ); + ic->Remove( myPreviewPlane, false ); + } + myPreviewPlaneVector[aCurPlaneIndex].Nullify(); } } - anOCCViewer->update(); + for(int i = 0; i < myPreviewPlaneVector.size(); i++) { + if( i == aCurPlaneIndex ) continue; + if(!myPreviewPlaneVector[i].IsNull()) + ic->SetColor( myPreviewPlaneVector[i], Quantity_Color( 85 / 255., 85 / 255., 255 / 255., Quantity_TOC_RGB ), false ); + } + myModel->update(); + + double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + getMinMaxFromContext( ic, myModel->trihedronSize(), aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); + gp_Pnt aRotationCenter( (aXmax + aXmin) * 0.5, + (aYmax + aYmin) * 0.5, + (aZmax + aZmin) * 0.5 ); + Bnd_Box aMinMax; + aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); + + myInteractor->setPlanes( myPreviewPlaneVector ); + myInteractor->setRotationCenter( aRotationCenter ); + myInteractor->setMinMax( aMinMax ); } /*! @@ -815,12 +950,11 @@ void OCCViewer_ClippingDlg::displayPreview() */ void OCCViewer_ClippingDlg::erasePreview() { - OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel(); - if ( !anOCCViewer ) + if ( !myModel ) return; - - Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext(); - + + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) { Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i]; if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) { @@ -829,7 +963,9 @@ void OCCViewer_ClippingDlg::erasePreview() myPreviewPlane.Nullify(); } } - anOCCViewer->update(); + myPreviewPlaneVector.clear(); + myModel->update(); + myInteractor->setEnabled( false ); } /*! @@ -843,25 +979,96 @@ bool OCCViewer_ClippingDlg::isValid() /*! Update view after changes */ -void OCCViewer_ClippingDlg::updateView() +void OCCViewer_ClippingDlg::updateClipping() { - if ( PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked() ) { - erasePreview(); - if ( AutoApplyCheckBox->isChecked() ) + if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked()) + { + if (AutoApplyCheckBox->isChecked()) { onApply(); - if ( PreviewCheckBox->isChecked() && !isRestore ) - displayPreview(); + } + + if (!PreviewCheckBox->isChecked()) + myModel->update(); + else + updatePreview(); } } +/*! + Updates state of user controls. +*/ +void OCCViewer_ClippingDlg::updateControls() +{ + if ( clipPlanesCount() == 0 ) + { + initParam(); + return; + } + + int aPlaneIdx = ComboBoxPlanes->currentIndex(); + + OCCViewer_ClipPlane& aPlane = getClipPlane( aPlaneIdx ); + + double aPlaneDx = 0.0; + double aPlaneDy = 0.0; + double aPlaneDz = 0.0; + double aDistance = 0.0; + aPlane.OrientationToXYZ( aPlaneDx, aPlaneDy, aPlaneDz ); + + if ( aPlane.Mode == OCCViewer_ClipPlane::Absolute ) + { + ModeStackedLayout->setCurrentIndex( 0 ); + + // Set plane parameters in the dialog + SpinBox_X->setValue( aPlane.X ); + SpinBox_Y->setValue( aPlane.Y ); + SpinBox_Z->setValue( aPlane.Z ); + SpinBox_Dx->setValue( aPlaneDx ); + SpinBox_Dy->setValue( aPlaneDy ); + SpinBox_Dz->setValue( aPlaneDz ); + CBAbsoluteOrientation->setCurrentIndex( aPlane.OrientationType ); + onOrientationAbsoluteChanged( aPlane.OrientationType ); + } + else if( aPlane.Mode == OCCViewer_ClipPlane::Relative ) + { + ModeStackedLayout->setCurrentIndex( 1 ); + + // Set plane parameters in the dialog + SpinSliderRotation1->setValue( int( aPlane.RelativeOrientation.Rotation1 ) ); + SpinSliderRotation2->setValue( int( aPlane.RelativeOrientation.Rotation2 ) ); + + XYZToDistance( myModel->getAISContext(), + myModel->trihedronSize(), + aPlane.X, aPlane.Y, aPlane.Z, + aPlaneDx, aPlaneDy, aPlaneDz, + aDistance ); + + SpinSliderDistance->setValue( aDistance ); + + CBRelativeOrientation->setCurrentIndex( aPlane.OrientationType ); + onOrientationRelativeChanged( aPlane.OrientationType ); + } + + isActivePlane->setChecked( aPlane.IsOn ); +} + /*! SLOT on new button click: create a new clipping plane */ void OCCViewer_ClippingDlg::ClickOnNew() { - ClipPlane* aPlane = new ClipPlane(); - aPlane->PlaneMode = CurrentMode; - myClippingPlanes.push_back( aPlane ); + OCCViewer_ClipPlane aClipPlane; + + // init controls state + myIsUpdatingControls = true; + initParam(); + myIsUpdatingControls = false; + + // init plane according to the state of controls + setPlaneParam( aClipPlane ); + + // add plane + myLocalPlanes.push_back( aClipPlane ); synchronize(); } @@ -870,15 +1077,27 @@ void OCCViewer_ClippingDlg::ClickOnNew() */ void OCCViewer_ClippingDlg::ClickOnDelete() { - if ( myClippingPlanes.empty() ) + int aPlaneIndex = ComboBoxPlanes->currentIndex(); + if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount())) return; - int aPlaneIndex = ComboBoxPlanes->currentIndex(); + myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex); + + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - ClipPlaneVector::iterator anIter = myClippingPlanes.begin() + aPlaneIndex; - myClippingPlanes.erase( anIter ); - updateView(); + if(aPlaneIndex+1 <= myPreviewPlaneVector.size()) { + Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[aPlaneIndex]; + if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) { + ic->Erase( myPreviewPlane, false ); + ic->Remove( myPreviewPlane, false ); + } + myPreviewPlaneVector.erase(myPreviewPlaneVector.begin() + aPlaneIndex); + } synchronize(); + if (AutoApplyCheckBox->isChecked()) { + onApply(); + } + myModel->update(); } /*! @@ -887,15 +1106,17 @@ void OCCViewer_ClippingDlg::ClickOnDelete() */ void OCCViewer_ClippingDlg::ClickOnDisableAll() { - AutoApplyCheckBox->setChecked( false ); - Graphic3d_SetOfHClipPlane aPlanes = myView3d->GetClipPlanes(); - Graphic3d_SetOfHClipPlane::Iterator anIter (aPlanes); - for( ;anIter.More();anIter.Next() ){ - Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); - aClipPlane->SetOn(Standard_False); + AutoApplyCheckBox->setChecked (false); + int aClipPlanesCount = clipPlanesCount(); + for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++) + { + OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex); + aPlane.IsOn = false; } - myView3d->Update(); - myView3d->Redraw(); + erasePreview(); + isActivePlane->setChecked(false); + myModel->setClipPlanes(myLocalPlanes); + myModel->update(); } /*! @@ -904,8 +1125,7 @@ void OCCViewer_ClippingDlg::ClickOnDisableAll() void OCCViewer_ClippingDlg::ClickOnOk() { onApply(); - erasePreview(); - myAction->setChecked( false ); + ClickOnClose(); } /*! @@ -914,8 +1134,7 @@ void OCCViewer_ClippingDlg::ClickOnOk() void OCCViewer_ClippingDlg::ClickOnApply() { onApply(); - myView3d->Update(); - myView3d->Redraw(); + myModel->update(); } /*! @@ -924,7 +1143,9 @@ void OCCViewer_ClippingDlg::ClickOnApply() void OCCViewer_ClippingDlg::ClickOnClose() { erasePreview(); - myAction->setChecked( false ); + OCCViewer_ViewWindow* v = qobject_cast(parent()); + if(v) + v->onClipping(false); } /*! @@ -942,10 +1163,11 @@ void OCCViewer_ClippingDlg::ClickOnHelp() */ void OCCViewer_ClippingDlg::onModeAbsolute() { + myIsPlaneCreation = true; ModeStackedLayout->setCurrentIndex(0); - CurrentMode = Absolute; ClickOnNew(); - onValueChanged(); + myIsPlaneCreation = false; + updateClipping(); } /*! @@ -953,10 +1175,12 @@ void OCCViewer_ClippingDlg::onModeAbsolute() */ void OCCViewer_ClippingDlg::onModeRelative() { + myIsPlaneCreation = true; ModeStackedLayout->setCurrentIndex(1); - CurrentMode = Relative; ClickOnNew(); - onValueChanged(); + myIsPlaneCreation = false; + SetCurrentPlaneParam(); + updateClipping(); } /*! @@ -964,10 +1188,19 @@ void OCCViewer_ClippingDlg::onModeRelative() */ void OCCViewer_ClippingDlg::onValueChanged() { + if ( myIsUpdatingControls ) + { + return; + } + SetCurrentPlaneParam(); + if ( myIsSelectPlane ) + { return; - updateView(); + } + + updateClipping(); } /*! @@ -975,44 +1208,16 @@ void OCCViewer_ClippingDlg::onValueChanged() */ void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex ) { - if ( myClippingPlanes.empty() ) + if ( clipPlanesCount() == 0 ) + { return; + } - Pnt_ClipPlane aPlane = myClippingPlanes[theIndex]; - ClipPlane* aClipPlane = aPlane; + OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex ); myIsSelectPlane = true; - if ( aClipPlane->PlaneMode == Absolute ) { - ModeStackedLayout->setCurrentIndex( 0 ); - CurrentMode = Absolute; - int anOrientation = aClipPlane->Orientation; - // Set plane parameters in the dialog - SpinBox_X->setValue( aClipPlane->X ); - SpinBox_Y->setValue( aClipPlane->Y ); - SpinBox_Z->setValue( aClipPlane->Z ); - SpinBox_Dx->setValue( aClipPlane->Dx ); - SpinBox_Dy->setValue( aClipPlane->Dy ); - SpinBox_Dz->setValue( aClipPlane->Dz ); - CBAbsoluteOrientation->setCurrentIndex( anOrientation ); - onOrientationAbsoluteChanged( anOrientation ); - } - else if( aClipPlane->PlaneMode == Relative ) { - ModeStackedLayout->setCurrentIndex( 1 ); - CurrentMode = Relative; - int anOrientation = aClipPlane->RelativeMode.Orientation; - // Set plane parameters in the dialog - SliderDistance->setValue( aClipPlane->RelativeMode.Distance*100 ); - TLValueDistance->setText( QString::number(aClipPlane->RelativeMode.Distance ) ); - SliderRotation1->setValue( aClipPlane->RelativeMode.Rotation1 ); - TLValueRotation1->setText( QString( "%1\xB0" ).arg( aClipPlane->RelativeMode.Rotation1 ) ); - SliderRotation2->setValue( aClipPlane->RelativeMode.Rotation2 ); - TLValueRotation2->setText( QString( "%1\xB0" ).arg( aClipPlane->RelativeMode.Rotation2 ) ); - CBRelativeOrientation->setCurrentIndex( anOrientation ); - onOrientationRelativeChanged( anOrientation ); - } - isActivePlane->setChecked( aClipPlane->IsActive ); + updateControls(); ComboBoxPlanes->setCurrentIndex( theIndex ); - myIsSelectPlane = false; } @@ -1021,32 +1226,16 @@ void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex ) */ void OCCViewer_ClippingDlg::SetCurrentPlaneParam() { - if ( myClippingPlanes.empty() || myIsSelectPlane ) + if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy ) + { return; + } int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex]; - ClipPlane* aPlaneData = aPlane; - - if ( aPlaneData->PlaneMode == Absolute ) { - aPlaneData->Orientation = CBAbsoluteOrientation->currentIndex(); - aPlaneData->X = SpinBox_X->value(); - aPlaneData->Y = SpinBox_Y->value(); - aPlaneData->Z = SpinBox_Z->value(); - aPlaneData->Dx = SpinBox_Dx->value(); - aPlaneData->Dy = SpinBox_Dy->value(); - aPlaneData->Dz = SpinBox_Dz->value(); - } - else if( aPlaneData->PlaneMode == Relative ) { - aPlaneData->RelativeMode.Orientation = CBRelativeOrientation->currentIndex(); - aPlaneData->RelativeMode.Distance = TLValueDistance->text().toDouble(); - aPlaneData->RelativeMode.Rotation1 = TLValueRotation1->text().remove("\xB0").toInt(); - aPlaneData->RelativeMode.Rotation2 = TLValueRotation2->text().remove("\xB0").toInt(); - erasePreview(); - RelativePlaneToAbsolute( aPlane, myView3d ); - } - aPlaneData->IsActive = isActivePlane->isChecked(); + OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex ); + + setPlaneParam( aPlane ); } /*! @@ -1060,7 +1249,7 @@ void OCCViewer_ClippingDlg::onReset() SpinBox_Z->setValue(0); myBusy = false; - updateView(); + updateClipping(); } /*! @@ -1078,13 +1267,13 @@ void OCCViewer_ClippingDlg::onInvert() SpinBox_Dz->setValue( -Dz ); myBusy = false; - if ( !myClippingPlanes.empty() ) { + if ( clipPlanesCount() != 0 ) + { int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex]; - ClipPlane* aPlaneData = aPlane; - aPlaneData->IsInvert = !aPlaneData->IsInvert; + OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex ); + aPlane.AbsoluteOrientation.IsInvert = !aPlane.AbsoluteOrientation.IsInvert; } - updateView(); + updateClipping(); } /*! @@ -1110,48 +1299,53 @@ void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode ) SpinBox_Dy->setEnabled( isUserMode ); SpinBox_Dz->setEnabled( isUserMode ); - if ( isUserMode ) - return; + if ( !isUserMode ) { - double aDx = 0, aDy = 0, aDz = 0; + double aDx = 0, aDy = 0, aDz = 0; - if ( mode == 1 ) - { - aDz = 1; - TextLabelZ->setEnabled( true ); - SpinBox_Z->setEnabled( true ); - SpinBox_Z->setFocus(); - } - else if ( mode == 2 ) - { - aDx = 1; - TextLabelX->setEnabled( true ); - SpinBox_X->setEnabled( true ); - SpinBox_X->setFocus(); - } - else if ( mode == 3 ) - { - aDy = 1; - TextLabelY->setEnabled( true ); - SpinBox_Y->setEnabled( true ); - SpinBox_Y->setFocus(); + if ( mode == 1 ) + { + aDz = 1; + TextLabelZ->setEnabled( true ); + SpinBox_Z->setEnabled( true ); + SpinBox_Z->setFocus(); + } + else if ( mode == 2 ) + { + aDx = 1; + TextLabelX->setEnabled( true ); + SpinBox_X->setEnabled( true ); + SpinBox_X->setFocus(); + } + else if ( mode == 3 ) + { + aDy = 1; + TextLabelY->setEnabled( true ); + SpinBox_Y->setEnabled( true ); + SpinBox_Y->setFocus(); + } + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex ); + if ( aPlane.AbsoluteOrientation.IsInvert == true ) + { + aDx = -aDx; + aDy = -aDy; + aDz = -aDz; + } + + myBusy = true; + SpinBox_Dx->setValue( aDx ); + SpinBox_Dy->setValue( aDy ); + SpinBox_Dz->setValue( aDz ); + myBusy = false; } - int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex]; - ClipPlane* aPlaneData = aPlane; - if ( aPlaneData->IsInvert == true ) { - aDx = -aDx; aDy = -aDy; aDz = -aDz; + if ( !myIsUpdatingControls ) + { + SetCurrentPlaneParam(); + updateClipping(); } - - myBusy = true; - SpinBox_Dx->setValue( aDx ); - SpinBox_Dy->setValue( aDy ); - SpinBox_Dz->setValue( aDz ); - myBusy = false; - - SetCurrentPlaneParam(); - updateView(); } /*! @@ -1159,9 +1353,9 @@ void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode ) */ void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem) { - if ( myClippingPlanes.empty() ) + if ( clipPlanesCount() == 0 ) return; - + if ( theItem == 0 ) { TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) ); TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) ); @@ -1175,9 +1369,15 @@ void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem) TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) ); } - if( (QComboBox*)sender() == CBRelativeOrientation ) - SetCurrentPlaneParam(); - updateView(); + if ( !myIsUpdatingControls ) + { + if( (QComboBox*)sender() == CBRelativeOrientation ) + { + SetCurrentPlaneParam(); + } + + updateClipping(); + } } /*! @@ -1195,9 +1395,10 @@ void OCCViewer_ClippingDlg::onPreview( bool on ) */ void OCCViewer_ClippingDlg::onAutoApply( bool toggled ) { - if ( toggled ) onApply(); - myView3d->Update(); - myView3d->Redraw(); + if ( toggled ) { + onApply(); + myModel->update(); + } } /*! @@ -1208,66 +1409,102 @@ void OCCViewer_ClippingDlg::onApply() if ( myBusy ) return; myIsSelectPlane = true; - Graphic3d_SetOfHClipPlane aPlanes = myView3d->GetClipPlanes(); - Graphic3d_SetOfHClipPlane::Iterator anIter (aPlanes); - for( ;anIter.More();anIter.Next() ){ - Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); - aClipPlane->SetOn(Standard_False); - } qApp->processEvents(); QApplication::setOverrideCursor( Qt::WaitCursor ); qApp->processEvents(); - for ( int i=0;iIsActive == true ) - myView->setCuttingPlane( true, aClipPlane->X , aClipPlane->Y , aClipPlane->Z, - aClipPlane->Dx, aClipPlane->Dy, aClipPlane->Dz ); - } + myModel->setClipPlanes(myLocalPlanes); QApplication::restoreOverrideCursor(); myIsSelectPlane = false; } -void OCCViewer_ClippingDlg::onViewShow() +/*! + SLOT: Called when clip plane is clicked in viewer. +*/ +void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane ) { - if(myAction->isChecked()) - show(); - else - hide(); -} + for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ ) + { + Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt ); + if ( aPlane != thePlane ) + { + continue; + } -void OCCViewer_ClippingDlg::onViewHide() -{ - hide(); + ComboBoxPlanes->setCurrentIndex( aPlaneIt ); + + break; + } } /*! - SLOT: Called when value of slider distance change + SLOT: Called when clip plane is changed by dragging in viewer. */ -void OCCViewer_ClippingDlg::SliderDistanceHasMoved( int value ) +void OCCViewer_ClippingDlg::onPlaneDragged( const Handle(AIS_Plane)& thePlane ) +{ + for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ ) + { + Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt ); + if ( aPlane != thePlane ) + { + continue; + } + + OCCViewer_ClipPlane& aClipPlane = getClipPlane( aPlaneIt ); + + gp_Pln aPln = thePlane->Component()->Pln(); + const gp_Pnt& aPlaneP = aPln.Location(); + const gp_Dir& aPlaneN = aPln.Axis().Direction(); + + aClipPlane.X = aPlaneP.X(); + aClipPlane.Y = aPlaneP.Y(); + aClipPlane.Z = aPlaneP.Z(); + + if ( aClipPlane.Mode == OCCViewer_ClipPlane::Absolute ) + { + if ( aClipPlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom ) + { + aClipPlane.AbsoluteOrientation.Dx = aPlaneN.X(); + aClipPlane.AbsoluteOrientation.Dy = aPlaneN.Y(); + aClipPlane.AbsoluteOrientation.Dz = aPlaneN.Z(); + } + } + else + { + OCCViewer_ClipPlane::DXYZToRelative( aPlaneN.X(), aPlaneN.Y(), aPlaneN.Z(), + aClipPlane.OrientationType, + aClipPlane.RelativeOrientation.Rotation1, + aClipPlane.RelativeOrientation.Rotation2 ); + } + + myIsUpdatingControls = true; + updateControls(); + myIsUpdatingControls = false; + + if ( AutoApplyCheckBox->isChecked() ) + { + onApply(); + } + + break; + } +} + +OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx ) { - double new_value = value/100.; - TLValueDistance->setText( QString("%1").arg( new_value ) ); - onValueChanged(); + return myLocalPlanes[theIdx]; } -/*! - SLOT: Called when value of slider rotation1 change -*/ -void OCCViewer_ClippingDlg::SliderRotation1HasMoved( int value ) +int OCCViewer_ClippingDlg::clipPlanesCount() { - TLValueRotation1->setText( QString("%1\xB0").arg( value ) ); - onValueChanged(); + return myLocalPlanes.size(); } -/*! - SLOT: Called when value of slider rotation2 change -*/ -void OCCViewer_ClippingDlg::SliderRotation2HasMoved( int value ) +OCCViewer_ClipPlane::PlaneMode OCCViewer_ClippingDlg::currentPlaneMode() const { - TLValueRotation2->setText( QString("%1\xB0").arg( value ) ); - onValueChanged(); + return ModeStackedLayout->currentIndex() == 0 + ? OCCViewer_ClipPlane::Absolute + : OCCViewer_ClipPlane::Relative; }