From: rnv Date: Wed, 16 Oct 2013 12:45:53 +0000 (+0000) Subject: First stage of the "0021793: [CEA 625] Clipping : from coordinates or from bounding... X-Git-Tag: BR_hydro_v_0_3_1~40 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a0054494bc71aff902b2bac8449acbcb118192e4;p=modules%2Fgui.git First stage of the "0021793: [CEA 625] Clipping : from coordinates or from bounding box" issue. --- diff --git a/doc/salome/gui/images/Clipping_Absolute.png b/doc/salome/gui/images/Clipping_Absolute.png new file mode 100644 index 000000000..943fe56c9 Binary files /dev/null and b/doc/salome/gui/images/Clipping_Absolute.png differ diff --git a/doc/salome/gui/images/Clipping_Relative.png b/doc/salome/gui/images/Clipping_Relative.png new file mode 100644 index 000000000..82fc137d9 Binary files /dev/null and b/doc/salome/gui/images/Clipping_Relative.png differ diff --git a/doc/salome/gui/input/occ_3d_viewer.doc b/doc/salome/gui/input/occ_3d_viewer.doc index 783adee96..647318992 100644 --- a/doc/salome/gui/input/occ_3d_viewer.doc +++ b/doc/salome/gui/input/occ_3d_viewer.doc @@ -20,9 +20,13 @@ jpeg image format. \image html occ_view_style_switch.png -Interaction style switch - allows to switch between "Salome -standard controls" and "Keyboard free" \ref viewer_navigation_modes "interaction styles". - +Interaction style switch - allows to switch between standard +and "keyboard free" interaction styles. "Keyboard free" style allows +to process all view transformations without using keyboard (only by +mouse) and perform selection in view by pressing "S" key. By default, +rotation in this mode is performed by left mouse button, panning - by +middle mouse button, zooming - by left and middle mouse buttons +pressed simultaneously.
\image html occ_view_zooming_style_switch.png @@ -151,12 +155,20 @@ scene. Clone view - opens a new duplicate scene.
+\anchor clipping_planes \image html occ_view_clipping.png Clipping - allows to create cross-section views (clipping planes) of geometrical objects. -\image html clipping.png +To start, click on the \em New button. + +Now you must specify what mode of creating plane you want to choose: +absolute or relative. + +Absolute mode + +\image html Clipping_Absolute.png - Base point - allows to define the coordinates of the base point for the clipping plane. @@ -168,9 +180,23 @@ planes) of geometrical objects. - Invert - allows to select which part of the object will be removed and which will remain after clipping. + +Relative mode + +\image html Clipping_Relative.png -- Preview - allows to see the results of clipping in the - viewer. +- \b Orientation ( ||X-Y, ||X-Z or ||Y-Z). +- \b Distance between the opposite extremities of the boundary box of +selected objects, if it is set to 0.5 the boundary box is split in two halves. +- \b Rotation (in angle degrees) around X (Y to Z) and around +Y (X to Z) (depending on the chosen Orientation) + + +If the Show preview button is on, you can see the clipping plane +in the viewer. + +If the Auto Apply button is on, you can preview the +cross-section in the viewer.
@@ -218,28 +244,8 @@ on/off. \image html occ_view_minimized.png \image html occ_view_maximized.png -Create sub-views/Maximize - these buttons allow switching the current +Minimize/Maximize - these buttons allow switching the current view area to the minimized / maximized state. - -Create sub-views - user can select the layout and types of child sub-views: - -\image html create_sub-views_dlg.png - -- Sub-views Layout - - - Three radio-buttons to specify numbers of the views to arrange (2, 3 or 4). - - - Buttons (depending on the chosen number of views) with images to specify - view layout. - - - Buttons "Previous" and "Next" for possibility to change split schemas. - -- Sub-views Properties - - - Type of each sub-view: XZ, YZ, XY or XYZ. - -Maximize - the current view area will be converted to maximized state. -
\image html occ_view_sync.png @@ -256,5 +262,68 @@ In addition, when this button is in the "checked" state, the dynamic synchronization of the views is performed, i.e. any zoom, pan, rotate or other view operation done in one view is automatically applied to the other view. +
+ +\anchor occ_background +

Background

+ +OCC Viewer background can be customized using the "Change background" +popup menu command that opens the following dialog box: + +\image html change_background_dlg.png + +The following types of the background are supported: + +- Single color: the background is colored with the solid color + specified by the user in the dialog box. + +- Gradient background: the background is gradiently colored according + to two colors and the gradient type specified in the dialog box. The + following types of background are supported: + + - Horizontal + + - Vertical + + - First diagonal + + - Second diagonal + + - First corner + + - Second corner + + - Third corner + + - Fourth corner + +- Image: allows to set image as viewer background and define filling type: + + - Center: the image is located at the center of the viewer backgound + + - Tile: the image fills the entire viewer backgound one by one + + - Stretch: the image is stretched to the entire viewer backgound. + +Default background for the viewer is specified via the +\ref occ_preferences "application preferences". + +

Polyline selection

+ +OCC Viewer features a special Polyline Selection mechanism, +which allows selecting an arbitraty part of the graphic area using a +polygon frame (rubber band), instead of the usual selection with a +rectangular frame. + +To produce a Polyline Selection, lock the right mouse button and draw +the first side of the polygon, then change the direction by clicking +the left mouse button add draw another side, etc. The whole selection +frame is drawn with the locked right mouse button. + +\image html polyselection1.png + +As a result, only the nodes within the frame are selected. + +\image html polyselection2.png */ diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.cxx b/src/OCCViewer/OCCViewer_ClippingDlg.cxx index f49c43c8e..065ef91f2 100644 --- a/src/OCCViewer/OCCViewer_ClippingDlg.cxx +++ b/src/OCCViewer/OCCViewer_ClippingDlg.cxx @@ -33,6 +33,7 @@ #include "OCCViewer_ViewModel.h" #include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include // QT Includes #include @@ -53,7 +55,217 @@ #include #include #include +#include +#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 ************************ + *********************************************************************************/ + +/*! + Compute the point of bounding box and current clipping plane + */ +void ComputeBoundsParam( double theBounds[6], + 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) { + static double EPS = 1.0E-3; + double aDelta = (theBounds[i+1] - theBounds[i])*EPS; + theBounds[i] -= aDelta; + 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] } }; + + int aMaxId = 0; + theMaxBoundPrj = theDirection[0] * aBoundPoints[aMaxId][0] + theDirection[1] * aBoundPoints[aMaxId][1] + + theDirection[2] * aBoundPoints[aMaxId][2]; + theMinBoundPrj = theMaxBoundPrj; + for(int i = 1; i < 8; i++) { + double aTmp = theDirection[0] * aBoundPoints[i][0] + theDirection[1] * aBoundPoints[i][1] + + theDirection[2] * aBoundPoints[i][2]; + if(theMaxBoundPrj < aTmp) { + theMaxBoundPrj = aTmp; + aMaxId = i; + } + if(theMinBoundPrj > aTmp) { + theMinBoundPrj = aTmp; + } + } + double *aMinPnt = aBoundPoints[aMaxId]; + theMinPnt[0] = aMinPnt[0]; + theMinPnt[1] = aMinPnt[1]; + theMinPnt[2] = aMinPnt[2]; +} + +/*! + Compute the position of current plane by distance + */ +void DistanceToPosition( double theBounds[6], + double theDirection[3], + 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; +} + +/*! + Compute the parameters of clipping plane + */ +bool ComputeClippingPlaneParameters( double theNormal[3], + double theDist, + double theBounds[6], + double theOrigin[3], + Handle(V3d_View) theView3d ) +{ + 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; + + DistanceToPosition( aBounds, theNormal, theDist, theOrigin ); + return true; +} + +/*! + Cross product of two 3-vectors. Result vector in result[3]. + */ +void Cross(const double first[3], const double second[3], double result[3]) +{ + 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]; +} + +/*! + Compute relative clipping plane in absolute coordinates + */ +void RelativePlaneToAbsolute ( ClipPlane* thePlane, Handle(V3d_View) theView3d ) +{ + 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; + } + + 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 aBounds[6]; + double anOrigin[3]; + + bool anIsOk = false; + + anOrigin[0] = anOrigin[1] = anOrigin[2] = 0; + aBounds[0] = aBounds[2] = aBounds[4] = 0; + aBounds[1] = aBounds[3] = aBounds[5] = 0; + anIsOk = true; + + 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]; +} + +/********************************************************************************* + ********************* class OCCViewer_ClippingDlg ********************* + *********************************************************************************/ /*! Constructor \param view - view window @@ -73,130 +285,266 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const QVBoxLayout* topLayout = new QVBoxLayout( this ); topLayout->setMargin( 11 ); topLayout->setSpacing( 6 ); - + /***************************************************************/ - GroupPoint = new QGroupBox( this ); - GroupPoint->setObjectName( "GroupPoint" ); - GroupPoint->setTitle( tr("Base point") ); - QGridLayout* GroupPointLayout = new QGridLayout( GroupPoint ); - GroupPointLayout->setAlignment( Qt::AlignTop ); - GroupPointLayout->setSpacing( 6 ); - GroupPointLayout->setMargin( 11 ); - - // Controls + // Controls for selecting, creating, deleting planes + QGroupBox* GroupPlanes = new QGroupBox( tr("CLIPPING_PLANES"), this ); + QHBoxLayout* GroupPlanesLayout = new QHBoxLayout( GroupPlanes ); + ComboBoxPlanes = new QComboBox( GroupPlanes ); + isActivePlane = new QCheckBox( tr("IS_ACTIVE_PLANE"), this ); + buttonNew = new QPushButton( tr("BTN_NEW"), GroupPlanes ); + buttonDelete = new QPushButton( tr("BTN_DELETE"), GroupPlanes ); + buttonDisableAll = new QPushButton( tr("BTN_DISABLE_ALL"), GroupPlanes ); + MenuMode = new QMenu( "MenuMode", buttonNew ); + 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 ); + GroupPlanesLayout->addWidget( buttonNew ); + GroupPlanesLayout->addWidget( buttonDelete ); + GroupPlanesLayout->addWidget( buttonDisableAll ); + + ModeStackedLayout = new QStackedLayout(); + + /********************** Mode Absolute **********************/ + /* Controls for absolute mode of clipping plane: + X, Y, Z - coordinates of the intersection of cutting plane and the three axes + Dx, Dy, Dz - components of normal to the cutting plane + Orientation - direction of cutting plane + */ const double min = -1e+7; const double max = 1e+7; const double step = 5; const int precision = -7; - TextLabelX = new QLabel( GroupPoint ); + // Croup Point + QGroupBox* GroupAbsolutePoint = new QGroupBox( this ); + GroupAbsolutePoint->setObjectName( "GroupPoint" ); + GroupAbsolutePoint->setTitle( tr("BASE_POINT") ); + QGridLayout* GroupPointLayout = new QGridLayout( GroupAbsolutePoint ); + GroupPointLayout->setAlignment( Qt::AlignTop ); + GroupPointLayout->setSpacing( 6 ); GroupPointLayout->setMargin( 11 ); + + TextLabelX = new QLabel( GroupAbsolutePoint ); TextLabelX->setObjectName( "TextLabelX" ); TextLabelX->setText( tr("X:") ); GroupPointLayout->addWidget( TextLabelX, 0, 0 ); - SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupPoint ); + SpinBox_X = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint ); SpinBox_X->setObjectName("SpinBox_X" ); SpinBox_X->setPrecision( precision ); GroupPointLayout->addWidget( SpinBox_X, 0, 1 ); - TextLabelY = new QLabel( GroupPoint ); + TextLabelY = new QLabel( GroupAbsolutePoint ); TextLabelY->setObjectName( "TextLabelY" ); TextLabelY->setText( tr("Y:") ); GroupPointLayout->addWidget( TextLabelY, 0, 2 ); - SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupPoint ); + SpinBox_Y = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint ); SpinBox_Y->setObjectName("SpinBox_Y" ); SpinBox_Y->setPrecision( precision ); GroupPointLayout->addWidget( SpinBox_Y, 0, 3 ); - TextLabelZ = new QLabel( GroupPoint ); + TextLabelZ = new QLabel( GroupAbsolutePoint ); TextLabelZ->setObjectName( "TextLabelZ" ); TextLabelZ->setText( tr("Z:") ); GroupPointLayout->addWidget( TextLabelZ, 0, 4 ); - SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupPoint ); + SpinBox_Z = new QtxDoubleSpinBox( min, max, step, GroupAbsolutePoint ); SpinBox_Z->setObjectName("SpinBox_Z" ); SpinBox_Z->setPrecision( precision ); GroupPointLayout->addWidget( SpinBox_Z, 0, 5 ); - resetButton = new QPushButton( GroupPoint ); + resetButton = new QPushButton( GroupAbsolutePoint ); resetButton->setObjectName( "resetButton" ); - resetButton->setText( tr( "Reset" ) ); + resetButton->setText( tr( "RESET" ) ); GroupPointLayout->addWidget( resetButton, 0, 6 ); - /***************************************************************/ - GroupDirection = new QGroupBox( this ); - GroupDirection->setObjectName( "GroupDirection" ); - GroupDirection->setTitle( tr("Direction") ); - QGridLayout* GroupDirectionLayout = new QGridLayout( GroupDirection ); + // Group Direction + GroupAbsoluteDirection = new QGroupBox( this ); + GroupAbsoluteDirection->setObjectName( "GroupDirection" ); + GroupAbsoluteDirection->setTitle( tr("DIRECTION") ); + QGridLayout* GroupDirectionLayout = new QGridLayout( GroupAbsoluteDirection ); GroupDirectionLayout->setAlignment( Qt::AlignTop ); GroupDirectionLayout->setSpacing( 6 ); GroupDirectionLayout->setMargin( 11 ); - // Controls - TextLabelDx = new QLabel( GroupDirection ); + TextLabelDx = new QLabel( GroupAbsoluteDirection ); TextLabelDx->setObjectName( "TextLabelDx" ); TextLabelDx->setText( tr("Dx:") ); GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 ); - SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupDirection ); + SpinBox_Dx = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection ); SpinBox_Dx->setObjectName("SpinBox_Dx" ); SpinBox_Dx->setPrecision( precision ); GroupDirectionLayout->addWidget( SpinBox_Dx, 0, 1 ); - TextLabelDy = new QLabel( GroupDirection ); + TextLabelDy = new QLabel( GroupAbsoluteDirection ); TextLabelDy->setObjectName( "TextLabelDy" ); TextLabelDy->setText( tr("Dy:") ); GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 ); - SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupDirection ); + SpinBox_Dy = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection ); SpinBox_Dy->setObjectName("SpinBox_Dy" ); SpinBox_Dy->setPrecision( precision ); GroupDirectionLayout->addWidget( SpinBox_Dy, 0, 3 ); - TextLabelDz = new QLabel( GroupDirection ); + TextLabelDz = new QLabel( GroupAbsoluteDirection ); TextLabelDz->setObjectName( "TextLabelDz" ); TextLabelDz->setText( tr("Dz:") ); GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 ); - SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupDirection ); + SpinBox_Dz = new QtxDoubleSpinBox( min, max, step, GroupAbsoluteDirection ); SpinBox_Dz->setObjectName("SpinBox_Dz" ); SpinBox_Dz->setPrecision( precision ); GroupDirectionLayout->addWidget( SpinBox_Dz, 0, 5 ); - invertButton = new QPushButton( GroupDirection ); + invertButton = new QPushButton( GroupAbsoluteDirection ); invertButton->setObjectName( "invertButton" ); - invertButton->setText( tr( "Invert" ) ); + invertButton->setText( tr( "INVERT" ) ); GroupDirectionLayout->addWidget( invertButton, 0, 6 ); - DirectionCB = new QComboBox( GroupDirection ); - DirectionCB->setObjectName( "DirectionCB" ); - DirectionCB->insertItem(DirectionCB->count(),tr("CUSTOM")); - DirectionCB->insertItem(DirectionCB->count(),tr("||X-Y")); - DirectionCB->insertItem(DirectionCB->count(),tr("||Y-Z")); - DirectionCB->insertItem(DirectionCB->count(),tr("||Z-X")); - GroupDirectionLayout->addWidget( DirectionCB, 1, 0, 1, 6 ); - + CBAbsoluteOrientation = new QComboBox( GroupAbsoluteDirection ); + CBAbsoluteOrientation->setObjectName( "AbsoluteOrientation" ); + CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "CUSTOM" ) ); + CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||X-Y" ) ); + CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Y-Z" ) ); + CBAbsoluteOrientation->insertItem( CBAbsoluteOrientation->count(), tr( "||Z-X" ) ); + GroupDirectionLayout->addWidget( CBAbsoluteOrientation, 1, 0, 1, 6 ); + + QVBoxLayout* ModeActiveLayout = new QVBoxLayout(); + ModeActiveLayout->setMargin( 11 ); ModeActiveLayout->setSpacing( 6 ); + ModeActiveLayout->addWidget( GroupAbsolutePoint ); + ModeActiveLayout->addWidget( GroupAbsoluteDirection ); + + QWidget* ModeActiveWidget = new QWidget( this ); + ModeActiveWidget->setLayout( ModeActiveLayout ); + + /********************** Mode Relative **********************/ + /* Controls for relative mode of clipping plane: + Distance - Value from 0 to 1. + Specifies the distance from the minimum value in a given direction of bounding box to the current position + Rotation1, Rotation2 - turn angles of cutting plane in given directions + Orientation - direction of cutting plane + */ + QGroupBox* GroupParameters = new QGroupBox( tr("PARAMETERS"), this ); + QGridLayout* GroupParametersLayout = new QGridLayout( GroupParameters ); + GroupParametersLayout->setMargin( 11 ); GroupParametersLayout->setSpacing( 6 ); + + TextLabelOrientation = new QLabel( tr("ORIENTATION"), GroupParameters); + TextLabelOrientation->setObjectName( "TextLabelOrientation" ); + GroupParametersLayout->addWidget( TextLabelOrientation, 0, 0 ); + + CBRelativeOrientation = new QComboBox(GroupParameters); + CBRelativeOrientation->setObjectName( "RelativeOrientation" ); + CBRelativeOrientation->addItem( tr("ALONG_XY") ); + CBRelativeOrientation->addItem( tr("ALONG_YZ") ); + 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 ); + + 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 ); + + 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 ); + /***************************************************************/ + QGroupBox* CheckBoxWidget = new QGroupBox( this ); + QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget ); - PreviewChB = new QCheckBox( tr("Preview") ,this ); - PreviewChB->setObjectName( "PreviewChB" ); - PreviewChB->setChecked( true ); + PreviewCheckBox = new QCheckBox( tr("PREVIEW"), CheckBoxWidget ); + PreviewCheckBox->setObjectName( "PreviewCheckBox" ); + PreviewCheckBox->setChecked( true ); + CheckBoxLayout->addWidget( PreviewCheckBox, 0, Qt::AlignCenter ); + AutoApplyCheckBox = new QCheckBox( tr("AUTO_APPLY"), CheckBoxWidget ); + AutoApplyCheckBox->setObjectName( "AutoApplyCheckBox" ); + CheckBoxLayout->addWidget( AutoApplyCheckBox, 0, Qt::AlignCenter ); + /***************************************************************/ QGroupBox* GroupButtons = new QGroupBox( this ); - GroupButtons->setObjectName( "GroupButtons" ); QHBoxLayout* GroupButtonsLayout = new QHBoxLayout( GroupButtons ); GroupButtonsLayout->setAlignment( Qt::AlignTop ); GroupButtonsLayout->setMargin( 11 ); GroupButtonsLayout->setSpacing( 6 ); + buttonOk = new QPushButton( GroupButtons ); + buttonOk->setObjectName( "buttonOk" ); + buttonOk->setText( tr( "BUT_APPLY_AND_CLOSE" ) ); + buttonOk->setAutoDefault( TRUE ); + buttonOk->setDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonOk ); + buttonApply = new QPushButton( GroupButtons ); buttonApply->setObjectName( "buttonApply" ); buttonApply->setText( tr( "BUT_APPLY" ) ); - buttonApply->setAutoDefault( TRUE ); + buttonApply->setAutoDefault( TRUE ); buttonApply->setDefault( TRUE ); GroupButtonsLayout->addWidget( buttonApply ); - + GroupButtonsLayout->addStretch(); buttonClose = new QPushButton( GroupButtons ); @@ -205,47 +553,65 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const buttonClose->setAutoDefault( TRUE ); GroupButtonsLayout->addWidget( buttonClose ); + QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons ); + buttonHelp->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonHelp ); + /***************************************************************/ - - topLayout->addWidget( GroupPoint ); - topLayout->addWidget( GroupDirection ); - - topLayout->addWidget( PreviewChB ); + ModeStackedLayout->addWidget( ModeActiveWidget ); + ModeStackedLayout->addWidget( GroupParameters ); + topLayout->addWidget( GroupPlanes ); + topLayout->addLayout( ModeStackedLayout ); + topLayout->addWidget( CheckBoxWidget ); topLayout->addWidget( GroupButtons ); - /* initializations */ + this->setLayout( topLayout ); - SpinBox_X->setValue( 0.0 ); - SpinBox_Y->setValue( 0.0 ); - SpinBox_Z->setValue( 0.0 ); + // Initializations + initParam(); - SpinBox_Dx->setValue( 1.0 ); - SpinBox_Dy->setValue( 1.0 ); - SpinBox_Dz->setValue( 1.0 ); + // Signals and slots connections + connect( ComboBoxPlanes, SIGNAL( activated( int ) ), this, SLOT( onSelectPlane( int ) ) ); + connect( isActivePlane, SIGNAL ( toggled ( bool ) ), this, SLOT( onValueChanged() ) ); + connect( buttonNew, SIGNAL( clicked() ), buttonNew, SLOT( showMenu() ) ); + connect( buttonDelete, SIGNAL( clicked() ), this, SLOT( ClickOnDelete() ) ); + connect( buttonDisableAll, SIGNAL( clicked() ), this, SLOT( ClickOnDisableAll() ) ); - /* signals and slots connections */ connect( resetButton, SIGNAL (clicked() ), this, SLOT( onReset() ) ); connect( invertButton, SIGNAL (clicked() ), this, SLOT( onInvert() ) ) ; - connect( SpinBox_X, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) ); connect( SpinBox_Y, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) ); connect( SpinBox_Z, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) ); connect( SpinBox_Dx, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) ); connect( SpinBox_Dy, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) ); connect( SpinBox_Dz, SIGNAL ( valueChanged( double ) ), this, SLOT( onValueChanged() ) ); - - connect( DirectionCB, SIGNAL ( activated ( int ) ), this, SLOT( onModeChanged( int ) ) ) ; - - connect( PreviewChB, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ; + 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( PreviewCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT( onPreview( bool ) ) ) ; + connect( AutoApplyCheckBox, SIGNAL ( toggled( bool ) ), this, SLOT( onAutoApply( bool ) ) ); connect( buttonClose, SIGNAL( clicked() ), this, SLOT( ClickOnClose() ) ) ; + 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(); - connect(view, SIGNAL(Show( QShowEvent * )), this, SLOT(onViewShow())); - connect(view, SIGNAL(Hide( QHideEvent * )), this, SLOT(onViewHide())); + synchronize(); } /*! @@ -255,39 +621,29 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg( OCCViewer_ViewWindow* view, const OCCViewer_ClippingDlg::~ OCCViewer_ClippingDlg() { // no need to delete child widgets, Qt does it all for us + foreach( ClipPlane* aPlane, myClippingPlanes ) + delete aPlane; } - /*! Custom handling of close event: erases preview */ void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e ) { erasePreview(); - - // Set the clipping plane back - /*Handle(V3d_View) aView3d = myView->getViewPort()->getView(); - if ( !aView3d.IsNull() && !myClippingPlane.IsNull() ) - aView3d->SetPlaneOn( myClippingPlane );*/ - myAction->setChecked( false ); - QDialog::closeEvent( e ); } - /*! Custom handling of show event: displays preview */ void OCCViewer_ClippingDlg::showEvent( QShowEvent* e ) { - //ReserveClippingPlane(); - QDialog::showEvent( e ); - onPreview( PreviewChB->isChecked() ); + onPreview( PreviewCheckBox->isChecked() ); } - /*! Custom handling of hide event: erases preview */ @@ -297,42 +653,400 @@ void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e ) QDialog::hideEvent( e ); } +/*! + Initialization of initial values of widgets +*/ +void OCCViewer_ClippingDlg::initParam() +{ + SpinBox_X->setValue( 0.0 ); + SpinBox_Y->setValue( 0.0 ); + SpinBox_Z->setValue( 0.0 ); + + SpinBox_Dx->setValue( 1.0 ); + SpinBox_Dy->setValue( 1.0 ); + SpinBox_Dz->setValue( 1.0 ); + + CBAbsoluteOrientation->setCurrentIndex(0); + + TLValueDistance->setText( "0" ); + TLValueRotation1->setText( "0\xB0" ); + TLValueRotation2->setText( "0\xB0" ); + CBRelativeOrientation->setCurrentIndex( 0 ); + SliderDistance->setValue( 50 ); + SliderRotation1->setValue( 0 ); + SliderRotation2->setValue( 0 ); +} /*! - SLOT on close button click: erases preview and rejects dialog + Synchronize dialog's widgets with data */ -void OCCViewer_ClippingDlg::ClickOnClose() +void OCCViewer_ClippingDlg::synchronize() { - erasePreview(); + ComboBoxPlanes->clear(); + int aNbPlanesAbsolute = myClippingPlanes.size(); - // Set the clipping plane back - /*Handle(V3d_View) aView3d = myView->getViewPort()->getView(); - if ( !aView3d.IsNull() && !myClippingPlane.IsNull() ) - aView3d->SetPlaneOn( myClippingPlane ); - */ - myAction->setChecked( false ); - - reject(); + QString aName; + for(int i = 1; i<=aNbPlanesAbsolute; i++ ) { + aName = QString("Plane %1").arg(i); + ComboBoxPlanes->addItem( aName ); + } + + int aPos = ComboBoxPlanes->count() - 1; + ComboBoxPlanes->setCurrentIndex( aPos ); + + bool anIsControlsEnable = ( aPos >= 0 ); + if ( anIsControlsEnable ) { + onSelectPlane( aPos ); + } + else { + ComboBoxPlanes->addItem( tr( "NO_PLANES" ) ); + initParam(); + ClickOnDisableAll(); + } + if ( CurrentMode == Absolute ) { + SpinBox_X->setEnabled( anIsControlsEnable ); + SpinBox_Y->setEnabled( anIsControlsEnable ); + SpinBox_Z->setEnabled( anIsControlsEnable ); + SpinBox_Dx->setEnabled( anIsControlsEnable ); + SpinBox_Dy->setEnabled( anIsControlsEnable ); + SpinBox_Dz->setEnabled( anIsControlsEnable ); + CBAbsoluteOrientation->setEnabled( anIsControlsEnable ); + invertButton->setEnabled( anIsControlsEnable ); + resetButton->setEnabled( anIsControlsEnable ); + } + else if( CurrentMode == Relative ) { + CBRelativeOrientation->setEnabled( anIsControlsEnable ); + SliderDistance->setEnabled( anIsControlsEnable ); + SliderRotation1->setEnabled( anIsControlsEnable ); + SliderRotation2->setEnabled( anIsControlsEnable ); + isActivePlane->setEnabled( anIsControlsEnable ); + } + isActivePlane->setEnabled( anIsControlsEnable ); } +/*! + Displays preview of clipping plane +*/ +void OCCViewer_ClippingDlg::displayPreview() +{ + if ( myBusy || !isValid() ) + return; + + OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel(); + if ( !anOCCViewer ) + return; + + Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext(); + + 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 ); + } + } + } + + 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 ); + } + + if ( aClipPlane->IsActive == true ) { + Handle(AIS_Plane) myPreviewPlane; + myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ) ); + myPreviewPlane->SetSize( aSize, aSize ); + + ic->Display( myPreviewPlane, 1, -1, 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.push_back( myPreviewPlane ); + } + } + anOCCViewer->update(); +} /*! - SLOT on apply button click: sets cutting plane + Erases preview of clipping plane */ -void OCCViewer_ClippingDlg::ClickOnApply() +void OCCViewer_ClippingDlg::erasePreview() { - qApp->processEvents(); - QApplication::setOverrideCursor( Qt::WaitCursor ); - qApp->processEvents(); - - myView->setCuttingPlane( true, SpinBox_X->value() , SpinBox_Y->value() , SpinBox_Z->value(), - SpinBox_Dx->value(), SpinBox_Dy->value(), SpinBox_Dz->value() ); + OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel(); + if ( !anOCCViewer ) + return; - QApplication::restoreOverrideCursor(); + Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext(); + for ( int i=0; i < myPreviewPlaneVector.size(); i++ ) { + Handle(AIS_Plane) myPreviewPlane = myPreviewPlaneVector[i]; + if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) { + ic->Erase( myPreviewPlane, false ); + ic->Remove( myPreviewPlane, false ); + myPreviewPlane.Nullify(); + } + } + anOCCViewer->update(); +} + +/*! + Return true if plane parameters are valid +*/ +bool OCCViewer_ClippingDlg::isValid() +{ + return ( SpinBox_Dx->value() !=0 || SpinBox_Dy->value() !=0 || SpinBox_Dz->value() !=0 ); +} + +/*! + Update view after changes +*/ +void OCCViewer_ClippingDlg::updateView() +{ + if ( PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked() ) { + erasePreview(); + if ( AutoApplyCheckBox->isChecked() ) + onApply(); + if ( PreviewCheckBox->isChecked() && !isRestore ) + displayPreview(); + } +} + +/*! + 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 ); + synchronize(); +} + +/*! + SLOT on delete button click: Delete selected clipping plane +*/ +void OCCViewer_ClippingDlg::ClickOnDelete() +{ + if ( myClippingPlanes.empty() ) + return; + + int aPlaneIndex = ComboBoxPlanes->currentIndex(); + + ClipPlaneVector::iterator anIter = myClippingPlanes.begin() + aPlaneIndex; + myClippingPlanes.erase( anIter ); + updateView(); + synchronize(); +} + +/*! + SLOT on disable all button click: Restore initial state of viewer, + erase all clipping planes +*/ +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); + } + myView3d->Update(); + myView3d->Redraw(); +} + +/*! + SLOT on ok button click: sets cutting plane and closes dialog +*/ +void OCCViewer_ClippingDlg::ClickOnOk() +{ + onApply(); erasePreview(); - - //ReserveClippingPlane(); + myAction->setChecked( false ); +} + +/*! + SLOT on Apply button click: sets cutting plane and update viewer +*/ +void OCCViewer_ClippingDlg::ClickOnApply() +{ + onApply(); + myView3d->Update(); + myView3d->Redraw(); +} + +/*! + SLOT on close button click: erases preview and rejects dialog +*/ +void OCCViewer_ClippingDlg::ClickOnClose() +{ + erasePreview(); + myAction->setChecked( false ); +} + +/*! + SLOT on help button click: opens a help page +*/ +void OCCViewer_ClippingDlg::ClickOnHelp() +{ + SUIT_Application* app = SUIT_Session::session()->activeApplication(); + if ( app ) + app->onHelpContextModule( "GUI", "occ_3d_viewer_page.html", "clipping_planes" ); +} + +/*! + Set absolute mode of clipping plane +*/ +void OCCViewer_ClippingDlg::onModeAbsolute() +{ + ModeStackedLayout->setCurrentIndex(0); + CurrentMode = Absolute; + ClickOnNew(); + onValueChanged(); +} + +/*! + Set relative mode of clipping plane +*/ +void OCCViewer_ClippingDlg::onModeRelative() +{ + ModeStackedLayout->setCurrentIndex(1); + CurrentMode = Relative; + ClickOnNew(); + onValueChanged(); +} + +/*! + SLOT: called on value of clipping plane changed +*/ +void OCCViewer_ClippingDlg::onValueChanged() +{ + SetCurrentPlaneParam(); + if ( myIsSelectPlane ) + return; + updateView(); +} + +/*! + Set current parameters of selected plane +*/ +void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex ) +{ + if ( myClippingPlanes.empty() ) + return; + + Pnt_ClipPlane aPlane = myClippingPlanes[theIndex]; + ClipPlane* aClipPlane = aPlane; + + 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 ); + ComboBoxPlanes->setCurrentIndex( theIndex ); + + myIsSelectPlane = false; +} + +/*! + Restore parameters of selected plane +*/ +void OCCViewer_ClippingDlg::SetCurrentPlaneParam() +{ + if ( myClippingPlanes.empty() || myIsSelectPlane ) + 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(); } /*! @@ -346,11 +1060,7 @@ void OCCViewer_ClippingDlg::onReset() SpinBox_Z->setValue(0); myBusy = false; - if ( PreviewChB->isChecked() ) - { - erasePreview(); - displayPreview(); - } + updateView(); } /*! @@ -361,27 +1071,29 @@ void OCCViewer_ClippingDlg::onInvert() double Dx = SpinBox_Dx->value(); double Dy = SpinBox_Dy->value(); double Dz = SpinBox_Dz->value(); - + myBusy = true; SpinBox_Dx->setValue( -Dx ); SpinBox_Dy->setValue( -Dy ); SpinBox_Dz->setValue( -Dz ); myBusy = false; - if ( PreviewChB->isChecked() ) - { - erasePreview(); - displayPreview(); - } + if ( !myClippingPlanes.empty() ) { + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex]; + ClipPlane* aPlaneData = aPlane; + aPlaneData->IsInvert = !aPlaneData->IsInvert; + } + updateView(); } /*! - SLOT: called on mode changed + SLOT: called on orientation of clipping plane in absolute mode changed */ -void OCCViewer_ClippingDlg::onModeChanged( int mode ) +void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode ) { bool isUserMode = (mode==0); - + TextLabelX->setEnabled( isUserMode ); TextLabelY->setEnabled( isUserMode ); TextLabelZ->setEnabled( isUserMode ); @@ -397,196 +1109,126 @@ void OCCViewer_ClippingDlg::onModeChanged( int mode ) SpinBox_Dx->setEnabled( isUserMode ); SpinBox_Dy->setEnabled( isUserMode ); SpinBox_Dz->setEnabled( isUserMode ); - + if ( isUserMode ) return; double aDx = 0, aDy = 0, aDz = 0; if ( mode == 1 ) - { - aDz = 1; - TextLabelZ->setEnabled( true ); - SpinBox_Z->setEnabled( true ); - SpinBox_Z->setFocus(); - } + { + 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(); - } + { + 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(); - } - + { + aDy = 1; + TextLabelY->setEnabled( true ); + SpinBox_Y->setEnabled( true ); + SpinBox_Y->setFocus(); + } + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + Pnt_ClipPlane aPlane = myClippingPlanes[aCurPlaneIndex]; + ClipPlane* aPlaneData = aPlane; + if ( aPlaneData->IsInvert == true ) { + aDx = -aDx; aDy = -aDy; aDz = -aDz; + } + myBusy = true; SpinBox_Dx->setValue( aDx ); SpinBox_Dy->setValue( aDy ); SpinBox_Dz->setValue( aDz ); myBusy = false; - if ( PreviewChB->isChecked() ) - { - erasePreview(); - displayPreview(); - } + SetCurrentPlaneParam(); + updateView(); } - /*! - Displays preview of clipping plane + SLOT: called on orientation of clipping plane in relative mode changed */ -void OCCViewer_ClippingDlg::displayPreview() +void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem) { - if ( myBusy || !isValid() ) + if ( myClippingPlanes.empty() ) return; - OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel(); - if (!anOCCViewer) - return; - - Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext(); - - 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 ( theItem == 0 ) { + TextLabelRotation1->setText( tr( "ROTATION_AROUND_X_Y2Z" ) ); + TextLabelRotation2->setText( tr( "ROTATION_AROUND_Y_X2Z" ) ); + } + else if ( theItem == 1 ) { + TextLabelRotation1->setText( tr( "ROTATION_AROUND_Y_Z2X" ) ); + TextLabelRotation2->setText( tr( "ROTATION_AROUND_Z_Y2X" ) ); + } + else if ( theItem == 2 ) { + TextLabelRotation1->setText( tr( "ROTATION_AROUND_Z_X2Y" ) ); + TextLabelRotation2->setText( tr( "ROTATION_AROUND_X_Z2Y" ) ); } - double aSize = 50; - - gp_Pnt aBasePnt( SpinBox_X->value(), SpinBox_Y->value(), SpinBox_Z->value() ); - gp_Dir aNormal( SpinBox_Dx->value(), SpinBox_Dy->value(), SpinBox_Dz->value() ); - 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 ); - } - - myPreviewPlane = new AIS_Plane( new Geom_Plane( aBasePnt, aNormal ) ); - myPreviewPlane->SetSize( aSize, aSize ); - - // Deactivate clipping planes - //myView->getViewPort()->getView()->SetPlaneOff(); - //myView->setPlaneOff(); - - ic->Display( myPreviewPlane, 1, -1, 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 ); - - anOCCViewer->update(); -} - - -/*! - Erases preview of clipping plane -*/ -void OCCViewer_ClippingDlg::erasePreview () -{ - OCCViewer_Viewer* anOCCViewer = (OCCViewer_Viewer*)myView->getViewManager()->getViewModel(); - if (!anOCCViewer) - return; - - Handle(AIS_InteractiveContext) ic = anOCCViewer->getAISContext(); - - if ( !myPreviewPlane.IsNull() && ic->IsDisplayed( myPreviewPlane ) ) - { -#if OCC_VERSION_LARGE <= 0x06060000 - ic->Erase( myPreviewPlane, false, false ); -#else - ic->Erase( myPreviewPlane, false ); -#endif - ic->Remove( myPreviewPlane, false ); - myPreviewPlane.Nullify(); - } - - anOCCViewer->update(); -} - - -/*! - SLOT: called on value changes (co-ordinates of point or normal) -*/ -void OCCViewer_ClippingDlg::onValueChanged() -{ - if ( PreviewChB->isChecked() ) - { - erasePreview(); - displayPreview(); - } + if( (QComboBox*)sender() == CBRelativeOrientation ) + SetCurrentPlaneParam(); + updateView(); } - /*! SLOT: called on preview check box toggled */ void OCCViewer_ClippingDlg::onPreview( bool on ) { erasePreview(); - if ( on ) displayPreview(); } /*! - \return true if plane parameters are valid + SLOT: called on Auto Apply check box toggled */ -bool OCCViewer_ClippingDlg::isValid() +void OCCViewer_ClippingDlg::onAutoApply( bool toggled ) { - return ( SpinBox_Dx->value()!=0 || SpinBox_Dy->value()!=0 || SpinBox_Dz->value()!=0 ); + if ( toggled ) onApply(); + myView3d->Update(); + myView3d->Redraw(); } /*! - Remember the current clipping plane + SLOT on Apply button click: sets cutting plane */ -void OCCViewer_ClippingDlg::ReserveClippingPlane() +void OCCViewer_ClippingDlg::onApply() { - /*Handle(V3d_View) aView3d = myView->getViewPort()->getView(); - if ( !aView3d.IsNull() ) - { - aView3d->InitActivePlanes(); - if ( aView3d->MoreActivePlanes() ) - myClippingPlane = aView3d->ActivePlane(); - }*/ + 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 ); + } + + QApplication::restoreOverrideCursor(); + myIsSelectPlane = false; } void OCCViewer_ClippingDlg::onViewShow() @@ -602,3 +1244,30 @@ void OCCViewer_ClippingDlg::onViewHide() hide(); } +/*! + SLOT: Called when value of slider distance change +*/ +void OCCViewer_ClippingDlg::SliderDistanceHasMoved( int value ) +{ + double new_value = value/100.; + TLValueDistance->setText( QString("%1").arg( new_value ) ); + onValueChanged(); +} + +/*! + SLOT: Called when value of slider rotation1 change +*/ +void OCCViewer_ClippingDlg::SliderRotation1HasMoved( int value ) +{ + TLValueRotation1->setText( QString("%1\xB0").arg( value ) ); + onValueChanged(); +} + +/*! + SLOT: Called when value of slider rotation2 change +*/ +void OCCViewer_ClippingDlg::SliderRotation2HasMoved( int value ) +{ + TLValueRotation2->setText( QString("%1\xB0").arg( value ) ); + onValueChanged(); +} diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.h b/src/OCCViewer/OCCViewer_ClippingDlg.h index 92c785ab3..63ee8d84f 100644 --- a/src/OCCViewer/OCCViewer_ClippingDlg.h +++ b/src/OCCViewer/OCCViewer_ClippingDlg.h @@ -37,9 +37,43 @@ class QComboBox; class QCheckBox; class QtxDoubleSpinBox; class QtxAction; +class QStackedLayout; +class QSlider; +class QMenu; class OCCViewer_ViewWindow; +enum Mode { Absolute, Relative }; + +/*! + \class OrientedPlane + \brief Parameters of clipping plane in relative mode +*/ +class OrientedPlane { +public: + int Orientation; + double Distance; + double Rotation1; + double Rotation2; + OrientedPlane(); +}; + +/*! + \class ClipPlane + \brief Parameters of clipping plane +*/ +class ClipPlane { +public: + OrientedPlane RelativeMode; + double X,Y,Z,Dx,Dy,Dz; + int Orientation; + bool IsActive; + bool IsInvert; + Mode PlaneMode; + ClipPlane(); +}; +typedef ClipPlane* Pnt_ClipPlane; +typedef std::vector ClipPlaneVector; /*! \class OCCViewer_ClippingDlg @@ -49,69 +83,121 @@ class OCCViewer_ClippingDlg : public QDialog { Q_OBJECT - public: - OCCViewer_ClippingDlg(OCCViewer_ViewWindow* , const char* name = 0, bool modal = FALSE, Qt::WindowFlags fl = 0); - ~OCCViewer_ClippingDlg(); + public: + OCCViewer_ClippingDlg(OCCViewer_ViewWindow* , const char* name = 0, bool modal = FALSE, Qt::WindowFlags fl = 0); + ~OCCViewer_ClippingDlg(); - void SetAction( QtxAction* theAction ) { myAction = theAction; } + void SetAction( QtxAction* theAction ) { myAction = theAction; } + void synchronize(); + void SetCurrentPlaneParam(); + ClipPlaneVector myClippingPlanes; + bool isRestore; + private : - virtual void closeEvent( QCloseEvent* e ); - virtual void showEvent ( QShowEvent * ); - virtual void hideEvent ( QHideEvent * ); - void displayPreview(); - void erasePreview(); - void ReserveClippingPlane(); - - bool isValid(); - - QGroupBox* GroupPoint; - QLabel* TextLabelX; - QLabel* TextLabelY; - QLabel* TextLabelZ; - QtxDoubleSpinBox* SpinBox_X; - QtxDoubleSpinBox* SpinBox_Y; - QtxDoubleSpinBox* SpinBox_Z; - QPushButton* resetButton; + virtual void closeEvent( QCloseEvent* e ); + virtual void showEvent ( QShowEvent * ); + virtual void hideEvent ( QHideEvent * ); + void initParam(); + void displayPreview(); + void erasePreview(); + bool isValid(); + void updateView(); + + QComboBox* ComboBoxPlanes; + QCheckBox* isActivePlane; + QPushButton* buttonNew; + QMenu* MenuMode; + QPushButton* buttonDelete; + QPushButton* buttonDisableAll; + + QStackedLayout *ModeStackedLayout; + + QGroupBox* GroupAbsolutePoint; + QLabel* TextLabelX; + QLabel* TextLabelY; + QLabel* TextLabelZ; + QtxDoubleSpinBox* SpinBox_X; + QtxDoubleSpinBox* SpinBox_Y; + QtxDoubleSpinBox* SpinBox_Z; + QPushButton* resetButton; + + QGroupBox* GroupAbsoluteDirection; + QLabel* TextLabelDx; + QLabel* TextLabelDy; + QLabel* TextLabelDz; + QtxDoubleSpinBox* SpinBox_Dx; + QtxDoubleSpinBox* SpinBox_Dy; + QtxDoubleSpinBox* SpinBox_Dz; + QPushButton* invertButton; + QComboBox* CBAbsoluteOrientation; - QGroupBox* GroupDirection; - QLabel* TextLabelDx; - QLabel* TextLabelDy; - QLabel* TextLabelDz; - QtxDoubleSpinBox* SpinBox_Dx; - QtxDoubleSpinBox* SpinBox_Dy; - QtxDoubleSpinBox* SpinBox_Dz; - QPushButton* invertButton; + QGroupBox* GroupRelative; + QLabel* TextLabelOrientation; + QLabel* TextLabelDistance; + QLabel* TextLabelRotation1; + QLabel* TextLabelRotation2; + QLabel* TLValueDistance; + QLabel* TLValueRotation1; + QLabel* TLValueRotation2; + QSlider* SliderDistance; + QSlider* SliderRotation1; + QSlider* SliderRotation2; + QComboBox* CBRelativeOrientation; + + QCheckBox* PreviewCheckBox; + QCheckBox* AutoApplyCheckBox; + + QPushButton* buttonOk; + QPushButton* buttonApply; + QPushButton* buttonClose; - QComboBox* DirectionCB; + OCCViewer_ViewWindow* myView; + Handle(V3d_View) myView3d; - QCheckBox* PreviewChB; + std::vector myPreviewPlaneVector; - QPushButton* buttonApply; - QPushButton* buttonClose; - - OCCViewer_ViewWindow* myView; + bool myIsSelectPlane; + bool myBusy; - Handle(AIS_Plane) myPreviewPlane; - //Handle(V3d_Plane) myClippingPlane; - - bool myBusy; + Mode CurrentMode; + + QtxAction* myAction; - QtxAction* myAction; +public slots: + void onApply(); private slots: + + void ClickOnNew(); + void ClickOnDelete(); + void ClickOnDisableAll(); + void ClickOnOk(); void ClickOnApply(); void ClickOnClose(); + void ClickOnHelp(); + + void onModeAbsolute(); + void onModeRelative(); + + void onValueChanged(); + void onSelectPlane( int ); void onReset(); void onInvert(); - void onModeChanged( int mode ); - void onValueChanged(); + void onOrientationAbsoluteChanged( int ); + void onOrientationRelativeChanged (int); + void onPreview( bool on ); + void onAutoApply(bool); void onViewShow(); void onViewHide(); + + void SliderDistanceHasMoved(int); + void SliderRotation1HasMoved(int); + void SliderRotation2HasMoved(int); }; #endif // OCCVIEWER_CLIPPINGDLG_H diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index c783846ce..4697e6acb 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -1216,7 +1216,8 @@ void OCCViewer_ViewWindow::createActions() myClippingAction->setStatusTip(tr("DSC_CLIPPING")); myClippingAction->setCheckable( true ); connect(myClippingAction, SIGNAL(toggled( bool )), this, SLOT(onClipping( bool ))); - toolMgr()->registerAction( myClippingAction, ClippingId ); + // RNV: Temporary commented, this functionality will be moved into Geometry module + //toolMgr()->registerAction( myClippingAction, ClippingId ); aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ), tr( "MNU_SHOOT_VIEW" ), 0, this); @@ -1587,7 +1588,6 @@ void OCCViewer_ViewWindow::onClipping( bool on ) { if ( myClippingDlg->isVisible() ) myClippingDlg->hide(); - aParent->setCuttingPlane(false); } } @@ -1671,6 +1671,10 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base aView3d->SetEye( anItem.eyeX, anItem.eyeY, anItem.eyeZ ); aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ ); aView3d->SetAxialScale( anItem.scaleX, anItem.scaleY, anItem.scaleZ ); + if ( myClippingDlg ) { + myClippingDlg->onApply(); + myClippingDlg->isRestore = false; + } if ( !baseParamsOnly ) { @@ -1957,15 +1961,15 @@ void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x, const doub gp_Pln pln (gp_Pnt(x, y, z), gp_Dir(dx, dy, dz)); double a, b, c, d; pln.Coefficients(a, b, c, d); - + #if OCC_VERSION_LARGE > 0x06060000 // Porting to OCCT higher 6.6.0 version Graphic3d_SetOfHClipPlane aPlanes = view->GetClipPlanes(); Handle(Graphic3d_ClipPlane) aClipPlane; if(aPlanes.Size() > 0 ) { Graphic3d_SetOfHClipPlane::Iterator anIter (aPlanes); - anIter.Next(); aClipPlane = anIter.Value(); aClipPlane->SetEquation(pln); + aClipPlane->SetOn(Standard_True); } else { aClipPlane = new Graphic3d_ClipPlane(pln); view->AddClipPlane(aClipPlane); @@ -1981,13 +1985,8 @@ void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x, const doub view->SetPlaneOn(clipPlane); } #else - if (view->MoreActivePlanes()) - clipPlane = view->ActivePlane(); - else - clipPlane = new V3d_Plane (viewer); - + clipPlane = new V3d_Plane (viewer); clipPlane->SetPlane(a, b, c, d); - view->SetPlaneOn(clipPlane); #endif } else { @@ -2023,7 +2022,17 @@ bool OCCViewer_ViewWindow::isCuttingPlane() { Handle(V3d_View) view = myViewPort->getView(); #if OCC_VERSION_LARGE > 0x06060000 // Porting to OCCT higher 6.6.0 version - return (view->GetClipPlanes().Size()); + bool res = false; + Graphic3d_SetOfHClipPlane aPlanes = view->GetClipPlanes(); + Graphic3d_SetOfHClipPlane::Iterator anIter (aPlanes); + for( ;anIter.More();anIter.Next() ) { + Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); + if(aClipPlane->IsOn()) { + res = true; + break; + } + } + return res; #else view->InitActivePlanes(); return (view->MoreActivePlanes()); @@ -2127,7 +2136,6 @@ viewAspect OCCViewer_ViewWindow::getViewParams() const return params; } - /*! \brief Get visual parameters of this view window. \return visual parameters of view window @@ -2157,6 +2165,34 @@ QString OCCViewer_ViewWindow::getVisualParameters() data << QString( "isVisible=%1" ).arg( params.isVisible ); data << QString( "size=%1" ) .arg( params.size, 0, 'f', 2 ); + if ( myClippingDlg ) { + if ( !myClippingDlg->myClippingPlanes.empty() ) { + for ( int i=0; i < myClippingDlg->myClippingPlanes.size(); i++ ) { + QString ClippingPlane = QString( "ClippingPlane%1=").arg( i+1 ); + Pnt_ClipPlane aPlane = myClippingDlg->myClippingPlanes[i]; + ClippingPlane += QString( "Mode~%1;").arg( (int)aPlane->PlaneMode ); + ClippingPlane += QString( "IsActive~%1;").arg( aPlane->IsActive ); + if ( aPlane->PlaneMode == Absolute ) { + ClippingPlane += QString( "AbsoluteOrientation~%1;" ).arg( aPlane->Orientation ); + ClippingPlane += QString( "IsInvert~%1;" ).arg( aPlane->IsInvert ); + ClippingPlane += QString( "X~%1;" ).arg( aPlane->X ); + ClippingPlane += QString( "Y~%1;" ).arg( aPlane->Y ); + ClippingPlane += QString( "Z~%1;" ).arg( aPlane->Z ); + ClippingPlane += QString( "Dx~%1;" ).arg( aPlane->Dx ); + ClippingPlane += QString( "Dy~%1;" ).arg( aPlane->Dy );; + ClippingPlane += QString( "Dz~%1" ).arg( aPlane->Dz ); + } + else if ( aPlane->PlaneMode == Relative ) { + ClippingPlane += QString( "RelativeOrientation~%1;" ).arg( aPlane->RelativeMode.Orientation ); + ClippingPlane += QString( "Distance~%1;" ).arg( aPlane->RelativeMode.Distance ); + ClippingPlane += QString( "Rotation1~%1;" ).arg( aPlane->RelativeMode.Rotation1 ); + ClippingPlane += QString( "Rotation2~%1" ).arg( aPlane->RelativeMode.Rotation2 ); + } + data << ClippingPlane; + } + } + } + #if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 or newer version // graduated trihedron data << QString( "gtIsVisible=%1" ) .arg( params.gtIsVisible ); @@ -2239,6 +2275,41 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters ) else if ( paramName == "scaleZ" ) params.scaleZ = paramValue.toDouble(); else if ( paramName == "isVisible" ) params.isVisible = paramValue.toInt(); else if ( paramName == "size" ) params.size = paramValue.toDouble(); + else if ( paramName.contains( "ClippingPlane" ) ) { + OCCViewer_ViewWindow* aParent = dynamic_cast(parent()->parent()); + if (!aParent) + aParent = this; + if ( !myClippingDlg ) + { + myClippingDlg = new OCCViewer_ClippingDlg( aParent ); + myClippingDlg->SetAction( myClippingAction ); + myClippingDlg->hide(); + } + QStringList ClipPlaneData = paramValue.split( ';' ); + ClipPlane* aPlane = new ClipPlane(); + foreach( QString ClipPlaneParam, ClipPlaneData ) { + QString ClipPlane_paramName = ClipPlaneParam.section( '~', 0, 0 ).trimmed(); + QString ClipPlane_paramValue = ClipPlaneParam.section( '~', 1, 1 ).trimmed(); + if ( ClipPlane_paramName == "Mode" ) aPlane->PlaneMode = ( Mode )ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "IsActive" ) aPlane->IsActive = ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "AbsoluteOrientation" ) aPlane->Orientation = ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "IsInvert" ) aPlane->IsInvert = ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "X" ) aPlane->X = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Y" ) aPlane->Y = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Z" ) aPlane->Z = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Dx" ) aPlane->Dx = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Dy" ) aPlane->Dy = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Dz" ) aPlane->Dz = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "RelativeOrientation" ) aPlane->RelativeMode.Orientation = ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "Distance" ) aPlane->RelativeMode.Distance = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Rotation1" ) aPlane->RelativeMode.Rotation1 = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Rotation2" ) aPlane->RelativeMode.Rotation2 = ClipPlane_paramValue.toDouble(); + } + myClippingDlg->myClippingPlanes.push_back( aPlane ); + myClippingDlg->isRestore = true; + myClippingDlg->synchronize(); + myClippingDlg->SetCurrentPlaneParam(); + } // graduated trihedron else if ( paramName == "gtIsVisible" ) params.gtIsVisible = paramValue.toInt(); else if ( paramName == "gtDrawNameX" ) params.gtDrawNameX = paramValue.toInt(); diff --git a/src/OCCViewer/resources/OCCViewer_msg_en.ts b/src/OCCViewer/resources/OCCViewer_msg_en.ts index d9d1f0d99..705f737b3 100644 --- a/src/OCCViewer/resources/OCCViewer_msg_en.ts +++ b/src/OCCViewer/resources/OCCViewer_msg_en.ts @@ -305,7 +305,7 @@ MNU_MINIMIZE_VIEW - Create sub-views + Minimize @@ -443,4 +443,115 @@ Z: + + OCCViewer_ClippingDlg + + CLIPPING_PLANES + Clipping planes + + + NO_PLANES + No planes + + + IS_ACTIVE_PLANE + Active + + + BTN_NEW + New + + + BTN_DELETE + Delete + + + AUTO_APPLY + Auto Apply + + + MODE + Mode + + + ORIENTATION + Orientation + + + DISTANCE + Distance + + + ROTATION_AROUND_X_Y2Z + Rotation around X (Y to Z): + + + ROTATION_AROUND_Y_X2Z + Rotation around Y (X to Z): + + + ROTATION_AROUND_Z_Y2X + Rotation around Z (Y to X): + + + ROTATION_AROUND_X_Z2Y + Rotation around X (Z to Y): + + + ROTATION_AROUND_Y_Z2X + Rotation around Y (Z to X): + + + ROTATION_AROUND_Z_X2Y + Rotation around Z (X to Y): + + + ALONG_XY + || X-Y + + + ALONG_YZ + || Y-Z + + + ALONG_ZX + || Z-X + + + ABSOLUTE + Absolute + + + RELATIVE + Relative + + + BTN_DISABLE_ALL + Disable all + + + PREVIEW + Preview + + + RESET + Reset + + + INVERT + Invert + + + BASE_POINT + Base point + + + DIRECTION + Direction + + + PARAMETERS + Parameters + + diff --git a/src/OCCViewer/resources/OCCViewer_msg_fr.ts b/src/OCCViewer/resources/OCCViewer_msg_fr.ts index 0f09189f0..250fda174 100755 --- a/src/OCCViewer/resources/OCCViewer_msg_fr.ts +++ b/src/OCCViewer/resources/OCCViewer_msg_fr.ts @@ -305,7 +305,7 @@ MNU_MINIMIZE_VIEW - Créer les sous-vues + Minimiser @@ -443,4 +443,115 @@ Z: + + OCCViewer_ClippingDlg + + CLIPPING_PLANES + Les plans de coupe + + + NO_PLANES + Aucuns plans + + + IS_ACTIVE_PLANE + Active + + + BTN_NEW + Nouveau + + + BTN_DELETE + Supprimer + + + AUTO_APPLY + Appliquer automatiquement + + + MODE + Mode + + + ORIENTATION + Orientation + + + DISTANCE + Distance + + + ROTATION_AROUND_X_Y2Z + Rotation autour de X (Y à Z): + + + ROTATION_AROUND_Y_X2Z + Rotation autour de Y (X à Z): + + + ROTATION_AROUND_Z_Y2X + Rotation autour de Z (Y à X): + + + ROTATION_AROUND_X_Z2Y + Rotation autour de X (Z à Y): + + + ROTATION_AROUND_Y_Z2X + Rotation autour de Y (Z à X): + + + ROTATION_AROUND_Z_X2Y + Rotation autour de Z (X à Y): + + + ALONG_XY + || X-Y + + + ALONG_YZ + || Y-Z + + + ALONG_ZX + || Z-X + + + ABSOLUTE + Absolute + + + RELATIVE + Relative + + + BTN_DISABLE_ALL + Désactiver tous + + + PREVIEW + Prévisualiser + + + RESET + Réinitialiser + + + INVERT + Inverser + + + BASE_POINT + Le point fondamental + + + DIRECTION + Direction + + + PARAMETERS + Paramètres + + diff --git a/src/STD/resources/STD_msg_en.ts b/src/STD/resources/STD_msg_en.ts index 84899db0f..dd91f9b92 100644 --- a/src/STD/resources/STD_msg_en.ts +++ b/src/STD/resources/STD_msg_en.ts @@ -215,6 +215,10 @@ Do you want to reload it ? BUT_CLOSE &Close + + BUT_APPLY_AND_CLOSE + A&pply and Close + INF_DESK_EXIT Exit diff --git a/src/STD/resources/STD_msg_fr.ts b/src/STD/resources/STD_msg_fr.ts index e8f4b4e79..87c71765e 100755 --- a/src/STD/resources/STD_msg_fr.ts +++ b/src/STD/resources/STD_msg_fr.ts @@ -215,6 +215,10 @@ Voulez-vous le réouvrir? BUT_CLOSE &Fermer + + BUT_APPLY_AND_CLOSE + A&ppliquer et Fermer + INF_DESK_EXIT &Quitter diff --git a/src/SVTK/SVTK_RenderWindowInteractor.cxx b/src/SVTK/SVTK_RenderWindowInteractor.cxx index 560cef7c3..6301ece1d 100644 --- a/src/SVTK/SVTK_RenderWindowInteractor.cxx +++ b/src/SVTK/SVTK_RenderWindowInteractor.cxx @@ -292,8 +292,20 @@ QVTK_RenderWindowInteractor GetDevice()->LeftButtonReleaseEvent(); else if( event->button() & Qt::MidButton ) GetDevice()->MiddleButtonReleaseEvent(); - else if( event->button() & Qt::RightButton ) + else if( event->button() & Qt::RightButton ) { + #ifndef Fix_Of_vtkImplicitPlaneWidget_bug + GetDevice()->SetEventInformationFlipY( -99999, -99999, + event->modifiers() & Qt::ControlModifier, + event->modifiers() & Qt::ShiftModifier); + GetDevice()->LeftButtonPressEvent(); + GetDevice()->LeftButtonReleaseEvent(); + GetDevice()->SetEventInformationFlipY(event->x(), + event->y(), + event->modifiers() & Qt::ControlModifier, + event->modifiers() & Qt::ShiftModifier); + #endif GetDevice()->RightButtonReleaseEvent(); + } }