From eec18479f601db0a573f0cbec64fed686960181f Mon Sep 17 00:00:00 2001 From: apl Date: Thu, 6 Mar 2014 20:05:02 +0400 Subject: [PATCH] Fix for OCCViewer_ClippingDlg: Relative Distance is now recalculated depending on the bounding box. --- src/OCCViewer/OCCViewer_ClipPlane.cxx | 335 +- src/OCCViewer/OCCViewer_ClipPlane.h | 113 +- src/OCCViewer/OCCViewer_ClippingDlg.cxx | 3052 ++++++------ src/OCCViewer/OCCViewer_ClippingDlg.h | 6 +- src/OCCViewer/OCCViewer_ViewModel.cxx | 25 +- src/OCCViewer/OCCViewer_ViewWindow.cxx | 5853 ++++++++++++----------- 6 files changed, 4848 insertions(+), 4536 deletions(-) diff --git a/src/OCCViewer/OCCViewer_ClipPlane.cxx b/src/OCCViewer/OCCViewer_ClipPlane.cxx index 68a458b40..8584ddcb0 100644 --- a/src/OCCViewer/OCCViewer_ClipPlane.cxx +++ b/src/OCCViewer/OCCViewer_ClipPlane.cxx @@ -21,62 +21,315 @@ // #include "OCCViewer_ClipPlane.h" +#include +#include +#include -#include +namespace +{ + /*! + 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]; + } +}; -/*! - Constructor of class OrientedPlane - */ -OrientedPlane::OrientedPlane(): - Orientation (0), - Distance (0.5), - Rotation1 (0), - Rotation2 (0) +OCCViewer_ClipPlane::OCCViewer_ClipPlane() +: X( 0.0 ), + Y( 0.0 ), + Z( 0.0 ), + Mode( Absolute ), + IsOn( true ) { + OrientationType = AbsoluteCustom; + AbsoluteOrientation.Dx = 0.0; + AbsoluteOrientation.Dy = 0.0; + AbsoluteOrientation.Dz = 1.0; + AbsoluteOrientation.IsInvert = false; } /*! - Operator of another OrientedPlane assignment. - @param other the OrientedPlane to assign. - @return the assigned OrientedPlane. + Operator of another OCCViewer_ClipPlane assignment. + @param theOther the OCCViewer_ClipPlane to assign. + @return the assigned OCCViewer_ClipPlane. */ -OrientedPlane& OrientedPlane::operator = ( const OrientedPlane& other ) +OCCViewer_ClipPlane& OCCViewer_ClipPlane::operator = ( const OCCViewer_ClipPlane& theOther ) { - Orientation = other.Orientation; - Distance = other.Distance; - Rotation1 = other.Rotation1; - Rotation2 = other.Rotation2; + X = theOther.X; + Y = theOther.Y; + Z = theOther.Z; + IsOn = theOther.IsOn; + Mode = theOther.Mode; + + OrientationType = theOther.OrientationType; + + switch ( Mode ) + { + case Absolute : + AbsoluteOrientation.IsInvert = theOther.AbsoluteOrientation.IsInvert; + AbsoluteOrientation.Dx = theOther.AbsoluteOrientation.Dx; + AbsoluteOrientation.Dy = theOther.AbsoluteOrientation.Dy; + AbsoluteOrientation.Dz = theOther.AbsoluteOrientation.Dz; + break; + + case Relative : + RelativeOrientation.Rotation1 = theOther.RelativeOrientation.Rotation1; + RelativeOrientation.Rotation2 = theOther.RelativeOrientation.Rotation2; + break; + } + return *this; } -OCCViewer_ClipPlane::OCCViewer_ClipPlane() : - RelativeMode(), - X (0.0), Y (0.0), Z (0.0), - Dx(1.0), Dy(1.0), Dz(1.0), - Orientation (0), - IsInvert (false), - PlaneMode (Absolute), - IsOn(true) +/*! + Converts defined orientation to direction. + @param theDx [out] the direction x component. + @param theDy [out] the direction y component. + @param theDz [out] the direction y component. +*/ +void OCCViewer_ClipPlane::OrientationToXYZ( double &theDx, double &theDy, double &theDz ) const { + // Absolute definition of the clipping plane + if ( Mode == Absolute ) + { + switch ( OrientationType ) + { + case AbsoluteXY : + theDx = 0.0; + theDy = 0.0; + theDz = AbsoluteOrientation.IsInvert ? 1.0 : -1.0; + break; + + case AbsoluteYZ : + theDx = AbsoluteOrientation.IsInvert ? 1.0 : -1.0; + theDy = 0.0; + theDz = 0.0; + break; + + case AbsoluteZX : + theDx = 0.0; + theDy = AbsoluteOrientation.IsInvert ? 1.0 : -1.0; + theDz = 0.0; + break; + + case AbsoluteCustom : + theDx = AbsoluteOrientation.Dx; + theDy = AbsoluteOrientation.Dy; + theDz = AbsoluteOrientation.Dz; + break; + } + + return; + } + + // Relative definition of the clipping plane + RelativeToDXYZ( OrientationType, + RelativeOrientation.Rotation1, + RelativeOrientation.Rotation2, + theDx, theDy, theDz ); } /*! - Operator of another OCCViewer_ClipPlane assignment. - @param other the OCCViewer_ClipPlane to assign. - @return the assigned OCCViewer_ClipPlane. + Converts normal direction to relative definition. + @param theDx [in] the direction x component. + @param theDy [in] the direction y component. + @param theDz [in] the direction y component. + @param theRelativeType [in] the relative orientation type. + @param theRotation1 [out] the angle of rotation around first axis. + @param theRotation2 [out] the angle of rotation around second axis. */ -OCCViewer_ClipPlane& OCCViewer_ClipPlane::operator = ( const OCCViewer_ClipPlane& other ) +void OCCViewer_ClipPlane::DXYZToRelative( const double theDx, + const double theDy, + const double theDz, + const int theOrientationType, + double& theRotation1, + double& theRotation2 ) { - RelativeMode = other.RelativeMode; - X = other.X; - Y = other.Y; - Z = other.Z; - Dx = other.Dx; - Dy = other.Dy; - Dz = other.Dz; - Orientation = other.Orientation; - IsInvert = other.IsInvert; - PlaneMode = other.PlaneMode; - IsOn = other.IsOn; - return *this; + gp_Dir aPlaneN( theDx, theDy, theDz ); + + const gp_Dir& aDX = gp::DX(); + const gp_Dir& aDY = gp::DY(); + const gp_Dir& aDZ = gp::DZ(); + double anAng1 = 0.0; + double anAng2 = 0.0; + switch ( theOrientationType ) + { + case RelativeXY : + { + if ( aDY.IsParallel( aPlaneN, Precision::Angular() ) ) + { + anAng1 = 0.0; + anAng2 = 0.0; + break; + } + + if ( aDX.IsParallel( aPlaneN, Precision::Angular() ) ) + { + anAng1 = 0.0; + anAng2 = 0.0; + break; + } + + gp_Dir aDir1 = aPlaneN ^ aDX; + gp_Dir aDir2 = aDY ^ aPlaneN; + gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDY ^ aPlaneN ); + + if ( aDir1 * aRightHand.YDirection() < 0.0 ) + { + aDir1.Reverse(); + } + if ( aDir2 * aRightHand.XDirection() < 0.0 ) + { + aDir2.Reverse(); + } + + anAng1 = aDY.AngleWithRef( aDir1, aDX ); + anAng2 = aDX.AngleWithRef( aDir2, -aDY ); + } + break; + + case RelativeYZ : + { + if ( aDZ.IsParallel( aPlaneN, Precision::Angular() ) ) + { + anAng1 = 0.0; + anAng2 = 0.0; + break; + } + + if ( aDY.IsParallel( aPlaneN, Precision::Angular() ) ) + { + anAng1 = 0.0; + anAng2 = 0.0; + break; + } + + gp_Dir aDir1 = aPlaneN ^ aDY; + gp_Dir aDir2 = aDZ ^ aPlaneN; + gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDZ ^ aPlaneN ); + + if ( aDir1 * aRightHand.YDirection() < 0.0 ) + { + aDir1.Reverse(); + } + if ( aDir2 * aRightHand.XDirection() < 0.0 ) + { + aDir2.Reverse(); + } + + anAng1 = aDZ.AngleWithRef( aDir1, aDY ); + anAng2 = aDY.AngleWithRef( aDir2, -aDZ ); + } + break; + + case RelativeZX : + { + if ( aDX.IsParallel( aPlaneN, Precision::Angular() ) ) + { + anAng1 = 0.0; + anAng2 = 0.0; + break; + } + + if ( aDZ.IsParallel( aPlaneN, Precision::Angular() ) ) + { + anAng1 = 0.0; + anAng2 = 0.0; + break; + } + + gp_Dir aDir1 = aPlaneN ^ aDZ; + gp_Dir aDir2 = aDX ^ aPlaneN; + gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDX ^ aPlaneN ); + + if ( aDir1 * aRightHand.YDirection() < 0.0 ) + { + aDir1.Reverse(); + } + if ( aDir2 * aRightHand.XDirection() < 0.0 ) + { + aDir2.Reverse(); + } + + anAng1 = aDX.AngleWithRef( aDir1, aDZ ); + anAng2 = aDZ.AngleWithRef( aDir2, -aDX ); + } + break; + } + + theRotation1 = anAng1 * ( 180.0 / M_PI ); + theRotation2 = anAng2 * ( 180.0 / M_PI ); +} + +/*! + Converts normal direction to relative definition. + @param theDx [in] the direction x component. + @param theDy [in] the direction y component. + @param theDz [in] the direction y component. + @param theRelativeType [in] the relative orientation type. + @param theRotation1 [out] the angle of rotation around first axis. + @param theRotation2 [out] the angle of rotation around second axis. +*/ +void OCCViewer_ClipPlane::RelativeToDXYZ( const int theOrientationType, + const double theRotation1, + const double theRotation2, + double& theDx, + double& theDy, + double& theDz ) +{ + double aNormal[3]; + double aDir[2][3] = { { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 } }; + + static double aCoeff = M_PI / 180.0; + + double anU[2] = { cos( aCoeff * theRotation1 ), cos( aCoeff * theRotation2 ) }; + double aV[2] = { sqrt( 1.0 - anU[0] * anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) }; + + aV[0] = theRotation1 > 0.0 ? aV[0] : -aV[0]; + aV[1] = theRotation2 > 0.0 ? aV[1] : -aV[1]; + + switch ( theOrientationType ) + { + case RelativeXY : + aDir[0][1] = anU[0]; + aDir[0][2] = aV[0]; + aDir[1][0] = anU[1]; + aDir[1][2] = aV[1]; + break; + + case RelativeYZ : + aDir[0][2] = anU[0]; + aDir[0][0] = aV[0]; + aDir[1][1] = anU[1]; + aDir[1][0] = aV[1]; + break; + + case RelativeZX : + 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 aDen; + aDen = sqrt( aNormal[0] * aNormal[0] + aNormal[1] * aNormal[1] + aNormal[2] * aNormal[2] ); + if ( aDen != 0.0 ) + { + for (int i = 0; i < 3; i++) + { + aNormal[i] /= aDen; + } + } + + theDx = aNormal[0]; + theDy = aNormal[1]; + theDz = aNormal[2]; } diff --git a/src/OCCViewer/OCCViewer_ClipPlane.h b/src/OCCViewer/OCCViewer_ClipPlane.h index 329e8e7e2..35f9c0842 100644 --- a/src/OCCViewer/OCCViewer_ClipPlane.h +++ b/src/OCCViewer/OCCViewer_ClipPlane.h @@ -28,45 +28,96 @@ #include #include -enum ClipPlaneMode { Absolute, Relative }; - /*! - \class OrientedPlane - \brief Parameters of clipping plane in relative mode + \class OCCViewer_ClipPlane + Definition of OCC viewer clipping plane. */ -class OCCVIEWER_EXPORT OrientedPlane { +class OCCVIEWER_EXPORT OCCViewer_ClipPlane +{ +public: - public: - OrientedPlane(); - OrientedPlane& operator =(const OrientedPlane& other); + enum PlaneMode + { + Absolute, + Relative + }; - public: - Standard_Integer Orientation; - Standard_Real Distance; - Standard_Real Rotation1; - Standard_Real Rotation2; -}; + enum AbsoluteOrientationType + { + AbsoluteCustom, + AbsoluteXY, + AbsoluteYZ, + AbsoluteZX + }; + + enum RelativeOrientationType + { + RelativeXY, + RelativeYZ, + RelativeZX + }; + +public: -class OCCVIEWER_EXPORT OCCViewer_ClipPlane -{ - - public: OCCViewer_ClipPlane(); - OCCViewer_ClipPlane& operator =(const OCCViewer_ClipPlane& other); - - public: - OrientedPlane RelativeMode; - Standard_Real X; - Standard_Real Y; - Standard_Real Z; - Standard_Real Dx; - Standard_Real Dy; - Standard_Real Dz; - Standard_Integer Orientation; - bool IsInvert; + OCCViewer_ClipPlane& operator =( const OCCViewer_ClipPlane& theOther ); + +// Parameters +public: + + // Plane definition mode + PlaneMode Mode; + + // Is active bool IsOn; - ClipPlaneMode PlaneMode; + // Plane position + double X; + double Y; + double Z; + + // Orientation type + int OrientationType; + + // Plane orientation (depends on mode) + union + { + struct + { + bool IsInvert; + double Dx; + double Dy; + double Dz; + } AbsoluteOrientation; + + struct + { + double Rotation1; + double Rotation2; + } RelativeOrientation; + }; + +// Tools +public: + + // Converts defined orientation to direction. + void OrientationToXYZ( double& theDx, double& theDy, double& theDz ) const; + + // Converts absoulte orientation to relative equivalent. + static void DXYZToRelative( const double theDx, + const double theDy, + const double theDz, + const int theRelativeType, + double& theRotation1, + double& theRotation2 ); + + // Converts relative orientation to absolute equivalent. + static void RelativeToDXYZ( const int theRelativeType, + const double theRotation1, + const double theRotation2, + double& theDx, + double& theDy, + double& theDz ); }; typedef std::vector ClipPlanesList; diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.cxx b/src/OCCViewer/OCCViewer_ClippingDlg.cxx index 593792d32..23b53653a 100644 --- a/src/OCCViewer/OCCViewer_ClippingDlg.cxx +++ b/src/OCCViewer/OCCViewer_ClippingDlg.cxx @@ -1,1546 +1,1510 @@ -// 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 -// -// 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// QT Includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/********************************************************************************** - ************************ 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], - 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 theOrigin[3], - Handle(AIS_InteractiveContext) ic, - double theDefaultSize) -{ - double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - getMinMaxFromContext(ic,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]. - */ -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 (OCCViewer_ClipPlane& thePlane, Handle(AIS_InteractiveContext) ic, double theDefaultSize ) -{ - 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; - } - } - } - - double anOrigin[3]; - - anOrigin[0] = anOrigin[1] = anOrigin[2] = 0; - bool anIsOk = true; - - anIsOk = ComputeClippingPlaneParameters( aNormal, - thePlane.RelativeMode.Distance, - anOrigin, - ic, - theDefaultSize ); - if( !anIsOk ) - return; - thePlane.X = anOrigin[0]; - thePlane.Y = anOrigin[1]; - thePlane.Z = anOrigin[2]; - thePlane.Dx = aNormal[0]; - thePlane.Dy = aNormal[1]; - thePlane.Dz = aNormal[2]; -} - -/*! - \brief Converts absolute plane definition to relative system. - \param thePlane [in/out] the plane to convert. - \param theIC [in] the interactive context. - \param theDefaultSize [in] the default trihedron size. - */ -void absolutePlaneToRelative( OCCViewer_ClipPlane& thePlane, Handle(AIS_InteractiveContext) theIC, double theDefaultSize ) -{ - gp_Pnt aPlaneP( thePlane.X, thePlane.Y, thePlane.Z ); - gp_Dir aPlaneN( thePlane.Dx, thePlane.Dy, thePlane.Dz ); - - double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; - - getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); - - Bnd_Box aMinMax; - aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); - - gp_Trsf aRelativeTransform; - aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) ); - Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform ); - - 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 ); - thePlane.RelativeMode.Distance = aRelativeDistance; - - const gp_Dir& aDX = gp::DX(); - const gp_Dir& aDY = gp::DY(); - const gp_Dir& aDZ = gp::DZ(); - double anAng1 = 0.0; - double anAng2 = 0.0; - switch ( thePlane.RelativeMode.Orientation ) - { - case 0: - { - if ( aDY.IsParallel( aPlaneN, Precision::Angular() ) ) - { - anAng1 = 0.0; - anAng2 = 0.0; - break; - } - - if ( aDX.IsParallel( aPlaneN, Precision::Angular() ) ) - { - anAng1 = 0.0; - anAng2 = 0.0; - break; - } - - gp_Dir aDir1 = aPlaneN ^ aDX; - gp_Dir aDir2 = aDY ^ aPlaneN; - gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDY ^ aPlaneN ); - - if ( aDir1 * aRightHand.YDirection() < 0.0 ) - { - aDir1.Reverse(); - } - if ( aDir2 * aRightHand.XDirection() < 0.0 ) - { - aDir2.Reverse(); - } - - anAng1 = aDY.AngleWithRef( aDir1, aDX ); - anAng2 = aDX.AngleWithRef( aDir2, -aDY ); - break; - } - case 1: - { - if ( aDZ.IsParallel( aPlaneN, Precision::Angular() ) ) - { - anAng1 = 0.0; - anAng2 = 0.0; - break; - } - - if ( aDY.IsParallel( aPlaneN, Precision::Angular() ) ) - { - anAng1 = 0.0; - anAng2 = 0.0; - break; - } - - gp_Dir aDir1 = aPlaneN ^ aDY; - gp_Dir aDir2 = aDZ ^ aPlaneN; - gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDZ ^ aPlaneN ); - - if ( aDir1 * aRightHand.YDirection() < 0.0 ) - { - aDir1.Reverse(); - } - if ( aDir2 * aRightHand.XDirection() < 0.0 ) - { - aDir2.Reverse(); - } - - anAng1 = aDZ.AngleWithRef( aDir1, aDY ); - anAng2 = aDY.AngleWithRef( aDir2, -aDZ ); - break; - } - case 2: - { - if ( aDX.IsParallel( aPlaneN, Precision::Angular() ) ) - { - anAng1 = 0.0; - anAng2 = 0.0; - break; - } - - if ( aDZ.IsParallel( aPlaneN, Precision::Angular() ) ) - { - anAng1 = 0.0; - anAng2 = 0.0; - break; - } - - gp_Dir aDir1 = aPlaneN ^ aDZ; - gp_Dir aDir2 = aDX ^ aPlaneN; - gp_Ax3 aRightHand( gp::Origin(), aPlaneN, aDX ^ aPlaneN ); - - if ( aDir1 * aRightHand.YDirection() < 0.0 ) - { - aDir1.Reverse(); - } - if ( aDir2 * aRightHand.XDirection() < 0.0 ) - { - aDir2.Reverse(); - } - - anAng1 = aDX.AngleWithRef( aDir1, aDZ ); - anAng2 = aDZ.AngleWithRef( aDir2, -aDX ); - break; - } - } - - thePlane.RelativeMode.Rotation1 = anAng1 * ( 180.0 / M_PI ); - thePlane.RelativeMode.Rotation2 = anAng2 * ( 180.0 / M_PI ); -} - -/*! - 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; - - - gp_Pnt aBasePnt(theClipPlane.X , theClipPlane.Y , theClipPlane.Z); - gp_Dir aNormal(theClipPlane.Dx, theClipPlane.Dy, theClipPlane.Dz ); - - // 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 ********************* - *********************************************************************************/ -/*! - Constructor - \param view - view window - \param parent - parent widget -*/ -OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model) - : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ), - myCurrentClipPlaneMode (Absolute) -{ - setObjectName( "OCCViewer_ClippingDlg" ); - setModal( false ); - - setWindowTitle( tr( "Clipping" ) ); - - setAttribute (Qt::WA_DeleteOnClose, true); - - QVBoxLayout* topLayout = new QVBoxLayout( this ); - topLayout->setMargin( 11 ); topLayout->setSpacing( 6 ); - - /***************************************************************/ - // 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 ); - - 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; - - // 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, GroupAbsolutePoint ); - SpinBox_X->setObjectName("SpinBox_X" ); - SpinBox_X->setPrecision( precision ); - GroupPointLayout->addWidget( SpinBox_X, 0, 1 ); - - TextLabelY = new QLabel( GroupAbsolutePoint ); - TextLabelY->setObjectName( "TextLabelY" ); - TextLabelY->setText( tr("Y:") ); - GroupPointLayout->addWidget( TextLabelY, 0, 2 ); - - 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( GroupAbsolutePoint ); - TextLabelZ->setObjectName( "TextLabelZ" ); - TextLabelZ->setText( tr("Z:") ); - GroupPointLayout->addWidget( TextLabelZ, 0, 4 ); - - 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( GroupAbsolutePoint ); - resetButton->setObjectName( "resetButton" ); - resetButton->setText( tr( "RESET" ) ); - GroupPointLayout->addWidget( resetButton, 0, 6 ); - - // 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 ); - - TextLabelDx = new QLabel( GroupAbsoluteDirection ); - TextLabelDx->setObjectName( "TextLabelDx" ); - TextLabelDx->setText( tr("Dx:") ); - GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 ); - - 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( GroupAbsoluteDirection ); - TextLabelDy->setObjectName( "TextLabelDy" ); - TextLabelDy->setText( tr("Dy:") ); - GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 ); - - 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( GroupAbsoluteDirection ); - TextLabelDz->setObjectName( "TextLabelDz" ); - TextLabelDz->setText( tr("Dz:") ); - GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 ); - - 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( GroupAbsoluteDirection ); - invertButton->setObjectName( "invertButton" ); - invertButton->setText( tr( "INVERT" ) ); - GroupDirectionLayout->addWidget( invertButton, 0, 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 ); - - TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters ); - TextLabelDistance->setObjectName( "TextLabelDistance" ); - 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, 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, 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 ); - QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget ); - - 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 ); - 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->setDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonApply ); - - GroupButtonsLayout->addStretch(); - - buttonClose = new QPushButton( GroupButtons ); - buttonClose->setObjectName( "buttonClose" ); - buttonClose->setText( tr( "BUT_CLOSE" ) ); - buttonClose->setAutoDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonClose ); - - QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons ); - buttonHelp->setAutoDefault( TRUE ); - GroupButtonsLayout->addWidget( buttonHelp ); - - /***************************************************************/ - ModeStackedLayout->addWidget( ModeActiveWidget ); - ModeStackedLayout->addWidget( GroupParameters ); - - topLayout->addWidget( GroupPlanes ); - topLayout->addLayout( ModeStackedLayout ); - topLayout->addWidget( CheckBoxWidget ); - topLayout->addWidget( GroupButtons ); - - this->setLayout( topLayout ); - - // Initializations - initParam(); - - // 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() ) ); - - 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( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ; - - connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( 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 ) ) ); - - 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() ) ); - - myBusy = false; - myIsSelectPlane = false; - 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(); -} - -/*! - Destructor - Destroys the object and frees any allocated resources -*/ -OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg() -{ - myLocalPlanes.clear(); -} - -/*! - Custom handling of close event: erases preview -*/ -void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e ) -{ - erasePreview(); - QDialog::closeEvent( e ); - OCCViewer_ViewWindow* v = qobject_cast(parent()); - if(v) - v->onClipping(false); -} - -/*! - Custom handling of show event: displays preview -*/ -void OCCViewer_ClippingDlg::showEvent( QShowEvent* e ) -{ - QDialog::showEvent( e ); - onPreview( PreviewCheckBox->isChecked() ); -} - -/*! - Custom handling of hide event: erases preview -*/ -void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e ) -{ - erasePreview(); - QDialog::hideEvent( e ); - OCCViewer_ViewWindow* v = qobject_cast(parent()); - if(v) - v->onClipping(false); - -} - -/*! - 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); - - SpinSliderDistance->setValue( 0.5 ); - SpinSliderRotation1->setValue( 0 ); - SpinSliderRotation2->setValue( 0 ); - CBRelativeOrientation->setCurrentIndex( 0 ); -} - -/*! - Synchronize dialog's widgets with data -*/ -void OCCViewer_ClippingDlg::synchronize() -{ - ComboBoxPlanes->clear(); - int aNbPlanesAbsolute = myLocalPlanes.size(); - - 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(); - } - if ( myCurrentClipPlaneMode == 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( myCurrentClipPlaneMode == Relative ) { - CBRelativeOrientation->setEnabled( anIsControlsEnable ); - SpinSliderDistance->setEnabled( anIsControlsEnable ); - SpinSliderRotation1->setEnabled( anIsControlsEnable ); - SpinSliderRotation2->setEnabled( anIsControlsEnable ); - isActivePlane->setEnabled( anIsControlsEnable ); - } - isActivePlane->setEnabled( anIsControlsEnable ); -} - -/*! - Displays preview of clipping plane -*/ -void OCCViewer_ClippingDlg::displayPreview() -{ - if ( myBusy || !isValid() || !myModel) - return; - - Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - - int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - - 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 ); -} - -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()); - } - 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, 0, false ); - ic->SetWidth( myPreviewPlane, 10, false ); - ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false ); - ic->SetTransparency( myPreviewPlane, 0.5, false ); - myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane; - } else { - myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) ); - myPreviewPlane->SetCenter( aBasePnt ); - myPreviewPlane->SetSize( aSize, aSize ); - } - - 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(); - } - } - 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 ); -} - -/*! - Erases preview of clipping plane -*/ -void OCCViewer_ClippingDlg::erasePreview() -{ - if ( !myModel ) - return; - - 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 ) ) { - ic->Erase( myPreviewPlane, false ); - ic->Remove( myPreviewPlane, false ); - myPreviewPlane.Nullify(); - } - } - myPreviewPlaneVector.clear(); - myModel->update(); - myInteractor->setEnabled( false ); -} - -/*! - 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::updateClipping() -{ - if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked()) - { - if (AutoApplyCheckBox->isChecked()) { - onApply(); - } - - 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 ); - - if ( aPlane.PlaneMode == Absolute ) - { - ModeStackedLayout->setCurrentIndex( 0 ); - myCurrentClipPlaneMode = Absolute; - int anOrientation = aPlane.Orientation; - // Set plane parameters in the dialog - SpinBox_X->setValue( aPlane.X ); - SpinBox_Y->setValue( aPlane.Y ); - SpinBox_Z->setValue( aPlane.Z ); - SpinBox_Dx->setValue( aPlane.Dx ); - SpinBox_Dy->setValue( aPlane.Dy ); - SpinBox_Dz->setValue( aPlane.Dz ); - CBAbsoluteOrientation->setCurrentIndex( anOrientation ); - onOrientationAbsoluteChanged( anOrientation ); - } - else if( aPlane.PlaneMode == Relative ) - { - ModeStackedLayout->setCurrentIndex( 1 ); - myCurrentClipPlaneMode = Relative; - int anOrientation = aPlane.RelativeMode.Orientation; - - // Set plane parameters in the dialog - double aFmtDistance = double(aPlane.RelativeMode.Distance); - int aFmtRotation1 = int(aPlane.RelativeMode.Rotation1); - int aFmtRotation2 = int(aPlane.RelativeMode.Rotation2); - - SpinSliderDistance->setValue( aFmtDistance ); - SpinSliderRotation1->setValue( aFmtRotation1 ); - SpinSliderRotation2->setValue( aFmtRotation2 ); - CBRelativeOrientation->setCurrentIndex( anOrientation ); - onOrientationRelativeChanged( anOrientation ); - } - - isActivePlane->setChecked( aPlane.IsOn ); -} - -/*! - SLOT on new button click: create a new clipping plane -*/ -void OCCViewer_ClippingDlg::ClickOnNew() -{ - OCCViewer_ClipPlane aPlane; - aPlane.PlaneMode = (ClipPlaneMode )myCurrentClipPlaneMode; - myLocalPlanes.push_back(aPlane); - synchronize(); -} - -/*! - SLOT on delete button click: Delete selected clipping plane -*/ -void OCCViewer_ClippingDlg::ClickOnDelete() -{ - int aPlaneIndex = ComboBoxPlanes->currentIndex(); - if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount())) - return; - - myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex); - - Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - - 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(); -} - -/*! - SLOT on disable all button click: Restore initial state of viewer, - erase all clipping planes -*/ -void OCCViewer_ClippingDlg::ClickOnDisableAll() -{ - AutoApplyCheckBox->setChecked (false); - int aClipPlanesCount = clipPlanesCount(); - for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++) - { - OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex); - aPlane.IsOn = false; - } - erasePreview(); - isActivePlane->setChecked(false); - myModel->setClipPlanes(myLocalPlanes); - myModel->update(); -} - -/*! - SLOT on ok button click: sets cutting plane and closes dialog -*/ -void OCCViewer_ClippingDlg::ClickOnOk() -{ - onApply(); - ClickOnClose(); -} - -/*! - SLOT on Apply button click: sets cutting plane and update viewer -*/ -void OCCViewer_ClippingDlg::ClickOnApply() -{ - onApply(); - myModel->update(); -} - -/*! - SLOT on close button click: erases preview and rejects dialog -*/ -void OCCViewer_ClippingDlg::ClickOnClose() -{ - erasePreview(); - OCCViewer_ViewWindow* v = qobject_cast(parent()); - if(v) - v->onClipping(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() -{ - myIsPlaneCreation = true; - ModeStackedLayout->setCurrentIndex(0); - myCurrentClipPlaneMode = Absolute; - ClickOnNew(); - myIsPlaneCreation = false; - updateClipping(); -} - -/*! - Set relative mode of clipping plane -*/ -void OCCViewer_ClippingDlg::onModeRelative() -{ - myIsPlaneCreation = true; - ModeStackedLayout->setCurrentIndex(1); - myCurrentClipPlaneMode = Relative; - ClickOnNew(); - myIsPlaneCreation = false; - SetCurrentPlaneParam(); - updateClipping(); -} - -/*! - SLOT: called on value of clipping plane changed -*/ -void OCCViewer_ClippingDlg::onValueChanged() -{ - if ( myIsUpdatingControls ) - { - return; - } - - SetCurrentPlaneParam(); - - if ( myIsSelectPlane ) - { - return; - } - - updateClipping(); -} - -/*! - Set current parameters of selected plane -*/ -void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex ) -{ - if ( clipPlanesCount() == 0 ) - { - return; - } - - OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex ); - - myIsSelectPlane = true; - updateControls(); - ComboBoxPlanes->setCurrentIndex( theIndex ); - myIsSelectPlane = false; -} - -/*! - Restore parameters of selected plane -*/ -void OCCViewer_ClippingDlg::SetCurrentPlaneParam() -{ - if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy) - return; - - int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - - OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex ); - - if ( aPlane.PlaneMode == Absolute ) - { - if( qFuzzyIsNull( SpinBox_Dx->value() ) && - qFuzzyIsNull( SpinBox_Dy->value() ) && - qFuzzyIsNull( SpinBox_Dz->value() ) ) { - return; - } - aPlane.Orientation = CBAbsoluteOrientation->currentIndex(); - aPlane.X = SpinBox_X->value(); - aPlane.Y = SpinBox_Y->value(); - aPlane.Z = SpinBox_Z->value(); - aPlane.Dx = SpinBox_Dx->value(); - aPlane.Dy = SpinBox_Dy->value(); - aPlane.Dz = SpinBox_Dz->value(); - absolutePlaneToRelative( aPlane, myModel->getAISContext(),myModel->trihedronSize() ); - } - else if( aPlane.PlaneMode == Relative ) - { - aPlane.RelativeMode.Orientation = CBRelativeOrientation->currentIndex(); - aPlane.RelativeMode.Distance = SpinSliderDistance->value(); - aPlane.RelativeMode.Rotation1 = SpinSliderRotation1->value(); - aPlane.RelativeMode.Rotation2 = SpinSliderRotation2->value(); - relativePlaneToAbsolute( aPlane, myModel->getAISContext(),myModel->trihedronSize() ); - } - aPlane.IsOn = isActivePlane->isChecked(); -} - -/*! - SLOT on reset button click: sets default values -*/ -void OCCViewer_ClippingDlg::onReset() -{ - myBusy = true; - SpinBox_X->setValue(0); - SpinBox_Y->setValue(0); - SpinBox_Z->setValue(0); - myBusy = false; - - updateClipping(); -} - -/*! - SLOT on invert button click: inverts normal of cutting plane -*/ -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 ( clipPlanesCount() != 0 ) { - int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex ); - aPlane.IsInvert = !aPlane.IsInvert; - } - updateClipping(); -} - -/*! - SLOT: called on orientation of clipping plane in absolute mode changed -*/ -void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode ) -{ - bool isUserMode = (mode==0); - - TextLabelX->setEnabled( isUserMode ); - TextLabelY->setEnabled( isUserMode ); - TextLabelZ->setEnabled( isUserMode ); - - SpinBox_X->setEnabled( isUserMode ); - SpinBox_Y->setEnabled( isUserMode ); - SpinBox_Z->setEnabled( isUserMode ); - - TextLabelDx->setEnabled( isUserMode ); - TextLabelDy->setEnabled( isUserMode ); - TextLabelDz->setEnabled( isUserMode ); - - SpinBox_Dx->setEnabled( isUserMode ); - SpinBox_Dy->setEnabled( isUserMode ); - SpinBox_Dz->setEnabled( isUserMode ); - - if ( !isUserMode ) { - - 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(); - } - - int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex ); - if ( aPlane.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 ( !myIsUpdatingControls ) - { - SetCurrentPlaneParam(); - updateClipping(); - } -} - -/*! - SLOT: called on orientation of clipping plane in relative mode changed -*/ -void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem) -{ - if ( clipPlanesCount() == 0 ) - return; - - 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" ) ); - } - - if ( !myIsUpdatingControls ) - { - if( (QComboBox*)sender() == CBRelativeOrientation ) - { - SetCurrentPlaneParam(); - } - - updateClipping(); - } -} - -/*! - SLOT: called on preview check box toggled -*/ -void OCCViewer_ClippingDlg::onPreview( bool on ) -{ - erasePreview(); - if ( on ) - displayPreview(); -} - -/*! - SLOT: called on Auto Apply check box toggled -*/ -void OCCViewer_ClippingDlg::onAutoApply( bool toggled ) -{ - if ( toggled ) { - onApply(); - myModel->update(); - } -} - -/*! - SLOT on Apply button click: sets cutting plane -*/ -void OCCViewer_ClippingDlg::onApply() -{ - if ( myBusy ) - return; - myIsSelectPlane = true; - - qApp->processEvents(); - QApplication::setOverrideCursor( Qt::WaitCursor ); - qApp->processEvents(); - - myModel->setClipPlanes(myLocalPlanes); - - QApplication::restoreOverrideCursor(); - myIsSelectPlane = false; -} - -/*! - SLOT: Called when clip plane is clicked in viewer. -*/ -void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane ) -{ - for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ ) - { - Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt ); - if ( aPlane != thePlane ) - { - continue; - } - - ComboBoxPlanes->setCurrentIndex( aPlaneIt ); - - break; - } -} - -/*! - SLOT: Called when clip plane is changed by dragging in viewer. -*/ -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(); - aClipPlane.Dx = aPlaneN.X(); - aClipPlane.Dy = aPlaneN.Y(); - aClipPlane.Dz = aPlaneN.Z(); - absolutePlaneToRelative( aClipPlane, myModel->getAISContext(), myModel->trihedronSize() ); - - myIsUpdatingControls = true; - updateControls(); - myIsUpdatingControls = false; - - if ( AutoApplyCheckBox->isChecked() ) - { - onApply(); - } - - break; - } -} - -OCCViewer_ClipPlane& OCCViewer_ClippingDlg::getClipPlane( int theIdx ) -{ - return myLocalPlanes[theIdx]; -} - -int OCCViewer_ClippingDlg::clipPlanesCount() +// 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 +// +// 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// QT Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/********************************************************************************** + ************************ 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( const double theBounds[6], + const double theDirection[3], + double theMinPnt[3], + double& theMaxBoundPrj, + double& theMinBoundPrj ) +{ + 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; + aEnlargeBounds[i ] = theBounds[i ] - aDelta; + aEnlargeBounds[i+1] = theBounds[i+1] + aDelta; + } + + 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] + + 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( 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; +} + +/*! + Compute the parameters of clipping plane + */ +bool ComputeClippingPlaneParameters( const Handle(AIS_InteractiveContext)& theIC, + const double theDefaultSize, + const double theNormal[3], + const double theDist, + double theOrigin[3] ) +{ + double aBounds[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + + getMinMaxFromContext( theIC, theDefaultSize, aBounds[0], aBounds[2], aBounds[4], aBounds[1], aBounds[3], aBounds[5] ); + + DistanceToPosition( aBounds, theNormal, theDist, theOrigin ); + return true; +} + +/*! + \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. + */ +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 ) +{ + 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; +} + +/*! + \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 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 ) +{ + gp_Pnt aPlaneP( theX, theY, theZ ); + gp_Dir aPlaneN( theDX, theDY, theDZ ); + + double aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; + + getMinMaxFromContext( theIC, theDefaultSize, aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); + + Bnd_Box aMinMax; + aMinMax.Update( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); + + gp_Trsf aRelativeTransform; + aRelativeTransform.SetTransformation( gp_Ax3(), gp_Ax3( aPlaneP, aPlaneN ) ); + Bnd_Box aRelativeBounds = aMinMax.Transformed( aRelativeTransform ); + + 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 ********************* + *********************************************************************************/ +/*! + Constructor + \param view - view window + \param parent - parent widget +*/ +OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCViewer_Viewer* model) + : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ) +{ + setObjectName( "OCCViewer_ClippingDlg" ); + setModal( false ); + + setWindowTitle( tr( "Clipping" ) ); + + setAttribute (Qt::WA_DeleteOnClose, true); + + QVBoxLayout* topLayout = new QVBoxLayout( this ); + topLayout->setMargin( 11 ); topLayout->setSpacing( 6 ); + + /***************************************************************/ + // 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 ); + + 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; + + // 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, GroupAbsolutePoint ); + SpinBox_X->setObjectName("SpinBox_X" ); + SpinBox_X->setPrecision( precision ); + GroupPointLayout->addWidget( SpinBox_X, 0, 1 ); + + TextLabelY = new QLabel( GroupAbsolutePoint ); + TextLabelY->setObjectName( "TextLabelY" ); + TextLabelY->setText( tr("Y:") ); + GroupPointLayout->addWidget( TextLabelY, 0, 2 ); + + 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( GroupAbsolutePoint ); + TextLabelZ->setObjectName( "TextLabelZ" ); + TextLabelZ->setText( tr("Z:") ); + GroupPointLayout->addWidget( TextLabelZ, 0, 4 ); + + 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( GroupAbsolutePoint ); + resetButton->setObjectName( "resetButton" ); + resetButton->setText( tr( "RESET" ) ); + GroupPointLayout->addWidget( resetButton, 0, 6 ); + + // 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 ); + + TextLabelDx = new QLabel( GroupAbsoluteDirection ); + TextLabelDx->setObjectName( "TextLabelDx" ); + TextLabelDx->setText( tr("Dx:") ); + GroupDirectionLayout->addWidget( TextLabelDx, 0, 0 ); + + 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( GroupAbsoluteDirection ); + TextLabelDy->setObjectName( "TextLabelDy" ); + TextLabelDy->setText( tr("Dy:") ); + GroupDirectionLayout->addWidget( TextLabelDy, 0, 2 ); + + 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( GroupAbsoluteDirection ); + TextLabelDz->setObjectName( "TextLabelDz" ); + TextLabelDz->setText( tr("Dz:") ); + GroupDirectionLayout->addWidget( TextLabelDz, 0, 4 ); + + 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( GroupAbsoluteDirection ); + invertButton->setObjectName( "invertButton" ); + invertButton->setText( tr( "INVERT" ) ); + GroupDirectionLayout->addWidget( invertButton, 0, 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 ); + + TextLabelDistance = new QLabel( tr("DISTANCE"), GroupParameters ); + TextLabelDistance->setObjectName( "TextLabelDistance" ); + 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, 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, 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 ); + QHBoxLayout* CheckBoxLayout = new QHBoxLayout( CheckBoxWidget ); + + 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 ); + 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->setDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonApply ); + + GroupButtonsLayout->addStretch(); + + buttonClose = new QPushButton( GroupButtons ); + buttonClose->setObjectName( "buttonClose" ); + buttonClose->setText( tr( "BUT_CLOSE" ) ); + buttonClose->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonClose ); + + QPushButton* buttonHelp = new QPushButton( tr( "SMESH_BUT_HELP" ), GroupButtons ); + buttonHelp->setAutoDefault( TRUE ); + GroupButtonsLayout->addWidget( buttonHelp ); + + /***************************************************************/ + ModeStackedLayout->addWidget( ModeActiveWidget ); + ModeStackedLayout->addWidget( GroupParameters ); + + topLayout->addWidget( GroupPlanes ); + topLayout->addLayout( ModeStackedLayout ); + topLayout->addWidget( CheckBoxWidget ); + topLayout->addWidget( GroupButtons ); + + this->setLayout( topLayout ); + + // Initializations + initParam(); + + // 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() ) ); + + 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( CBAbsoluteOrientation, SIGNAL ( activated ( int ) ), this, SLOT( onOrientationAbsoluteChanged( int ) ) ) ; + + connect( CBRelativeOrientation, SIGNAL( activated( int ) ), this, SLOT( onOrientationRelativeChanged( 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 ) ) ); + + 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() ) ); + + myBusy = false; + myIsSelectPlane = false; + 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(); +} + +/*! + Destructor + Destroys the object and frees any allocated resources +*/ +OCCViewer_ClippingDlg::~OCCViewer_ClippingDlg() +{ + myLocalPlanes.clear(); +} + +/*! + Custom handling of close event: erases preview +*/ +void OCCViewer_ClippingDlg::closeEvent( QCloseEvent* e ) +{ + erasePreview(); + QDialog::closeEvent( e ); + OCCViewer_ViewWindow* v = qobject_cast(parent()); + if(v) + v->onClipping(false); +} + +/*! + Custom handling of show event: displays preview +*/ +void OCCViewer_ClippingDlg::showEvent( QShowEvent* e ) +{ + QDialog::showEvent( e ); + onPreview( PreviewCheckBox->isChecked() ); +} + +/*! + Custom handling of hide event: erases preview +*/ +void OCCViewer_ClippingDlg::hideEvent( QHideEvent* e ) +{ + erasePreview(); + QDialog::hideEvent( e ); + OCCViewer_ViewWindow* v = qobject_cast(parent()); + if(v) + v->onClipping(false); + +} + +/*! + 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); + + SpinSliderDistance->setValue( 0.5 ); + SpinSliderRotation1->setValue( 0 ); + SpinSliderRotation2->setValue( 0 ); + CBRelativeOrientation->setCurrentIndex( 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(); +} + +/*! + Synchronize dialog's widgets with data +*/ +void OCCViewer_ClippingDlg::synchronize() +{ + ComboBoxPlanes->clear(); + int aNbPlanesAbsolute = myLocalPlanes.size(); + + 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(); + } + if ( currentPlaneMode() == OCCViewer_ClipPlane::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 ( currentPlaneMode() == OCCViewer_ClipPlane::Relative ) + { + CBRelativeOrientation->setEnabled( anIsControlsEnable ); + SpinSliderDistance->setEnabled( anIsControlsEnable ); + SpinSliderRotation1->setEnabled( anIsControlsEnable ); + SpinSliderRotation2->setEnabled( anIsControlsEnable ); + isActivePlane->setEnabled( anIsControlsEnable ); + } + isActivePlane->setEnabled( anIsControlsEnable ); +} + +/*! + Displays preview of clipping plane +*/ +void OCCViewer_ClippingDlg::displayPreview() +{ + if ( myBusy || !isValid() || !myModel) + return; + + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + + 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 ); +} + +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()); + } + 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, 0, false ); + ic->SetWidth( myPreviewPlane, 10, false ); + ic->SetMaterial( myPreviewPlane, Graphic3d_NOM_PLASTIC, false ); + ic->SetTransparency( myPreviewPlane, 0.5, false ); + myPreviewPlaneVector[aCurPlaneIndex] = myPreviewPlane; + } else { + myPreviewPlane->SetComponent( new Geom_Plane( aBasePnt, aNormal ) ); + myPreviewPlane->SetCenter( aBasePnt ); + myPreviewPlane->SetSize( aSize, aSize ); + } + + 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(); + } + } + 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 ); +} + +/*! + Erases preview of clipping plane +*/ +void OCCViewer_ClippingDlg::erasePreview() +{ + if ( !myModel ) + return; + + 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 ) ) { + ic->Erase( myPreviewPlane, false ); + ic->Remove( myPreviewPlane, false ); + myPreviewPlane.Nullify(); + } + } + myPreviewPlaneVector.clear(); + myModel->update(); + myInteractor->setEnabled( false ); +} + +/*! + 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::updateClipping() +{ + if (PreviewCheckBox->isChecked() || AutoApplyCheckBox->isChecked()) + { + if (AutoApplyCheckBox->isChecked()) { + onApply(); + } + + 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() +{ + 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(); +} + +/*! + SLOT on delete button click: Delete selected clipping plane +*/ +void OCCViewer_ClippingDlg::ClickOnDelete() +{ + int aPlaneIndex = ComboBoxPlanes->currentIndex(); + if ( (clipPlanesCount() == 0) || (aPlaneIndex+1 > clipPlanesCount())) + return; + + myLocalPlanes.erase(myLocalPlanes.begin() + aPlaneIndex); + + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + + 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(); +} + +/*! + SLOT on disable all button click: Restore initial state of viewer, + erase all clipping planes +*/ +void OCCViewer_ClippingDlg::ClickOnDisableAll() +{ + AutoApplyCheckBox->setChecked (false); + int aClipPlanesCount = clipPlanesCount(); + for ( int anIndex = 0; anIndex < aClipPlanesCount; anIndex++) + { + OCCViewer_ClipPlane& aPlane = getClipPlane(anIndex); + aPlane.IsOn = false; + } + erasePreview(); + isActivePlane->setChecked(false); + myModel->setClipPlanes(myLocalPlanes); + myModel->update(); +} + +/*! + SLOT on ok button click: sets cutting plane and closes dialog +*/ +void OCCViewer_ClippingDlg::ClickOnOk() +{ + onApply(); + ClickOnClose(); +} + +/*! + SLOT on Apply button click: sets cutting plane and update viewer +*/ +void OCCViewer_ClippingDlg::ClickOnApply() +{ + onApply(); + myModel->update(); +} + +/*! + SLOT on close button click: erases preview and rejects dialog +*/ +void OCCViewer_ClippingDlg::ClickOnClose() +{ + erasePreview(); + OCCViewer_ViewWindow* v = qobject_cast(parent()); + if(v) + v->onClipping(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() +{ + myIsPlaneCreation = true; + ModeStackedLayout->setCurrentIndex(0); + ClickOnNew(); + myIsPlaneCreation = false; + updateClipping(); +} + +/*! + Set relative mode of clipping plane +*/ +void OCCViewer_ClippingDlg::onModeRelative() +{ + myIsPlaneCreation = true; + ModeStackedLayout->setCurrentIndex(1); + ClickOnNew(); + myIsPlaneCreation = false; + SetCurrentPlaneParam(); + updateClipping(); +} + +/*! + SLOT: called on value of clipping plane changed +*/ +void OCCViewer_ClippingDlg::onValueChanged() +{ + if ( myIsUpdatingControls ) + { + return; + } + + SetCurrentPlaneParam(); + + if ( myIsSelectPlane ) + { + return; + } + + updateClipping(); +} + +/*! + Set current parameters of selected plane +*/ +void OCCViewer_ClippingDlg::onSelectPlane ( int theIndex ) +{ + if ( clipPlanesCount() == 0 ) + { + return; + } + + OCCViewer_ClipPlane& aClipPlane = getClipPlane( theIndex ); + + myIsSelectPlane = true; + updateControls(); + ComboBoxPlanes->setCurrentIndex( theIndex ); + myIsSelectPlane = false; +} + +/*! + Restore parameters of selected plane +*/ +void OCCViewer_ClippingDlg::SetCurrentPlaneParam() +{ + if ( clipPlanesCount() == 0 || myIsSelectPlane || myBusy ) + { + return; + } + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + + OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex ); + + setPlaneParam( aPlane ); +} + +/*! + SLOT on reset button click: sets default values +*/ +void OCCViewer_ClippingDlg::onReset() +{ + myBusy = true; + SpinBox_X->setValue(0); + SpinBox_Y->setValue(0); + SpinBox_Z->setValue(0); + myBusy = false; + + updateClipping(); +} + +/*! + SLOT on invert button click: inverts normal of cutting plane +*/ +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 ( clipPlanesCount() != 0 ) + { + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + OCCViewer_ClipPlane& aPlane = getClipPlane( aCurPlaneIndex ); + aPlane.AbsoluteOrientation.IsInvert = !aPlane.AbsoluteOrientation.IsInvert; + } + updateClipping(); +} + +/*! + SLOT: called on orientation of clipping plane in absolute mode changed +*/ +void OCCViewer_ClippingDlg::onOrientationAbsoluteChanged( int mode ) +{ + bool isUserMode = (mode==0); + + TextLabelX->setEnabled( isUserMode ); + TextLabelY->setEnabled( isUserMode ); + TextLabelZ->setEnabled( isUserMode ); + + SpinBox_X->setEnabled( isUserMode ); + SpinBox_Y->setEnabled( isUserMode ); + SpinBox_Z->setEnabled( isUserMode ); + + TextLabelDx->setEnabled( isUserMode ); + TextLabelDy->setEnabled( isUserMode ); + TextLabelDz->setEnabled( isUserMode ); + + SpinBox_Dx->setEnabled( isUserMode ); + SpinBox_Dy->setEnabled( isUserMode ); + SpinBox_Dz->setEnabled( isUserMode ); + + if ( !isUserMode ) { + + 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(); + } + + 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; + } + + if ( !myIsUpdatingControls ) + { + SetCurrentPlaneParam(); + updateClipping(); + } +} + +/*! + SLOT: called on orientation of clipping plane in relative mode changed +*/ +void OCCViewer_ClippingDlg::onOrientationRelativeChanged (int theItem) +{ + if ( clipPlanesCount() == 0 ) + return; + + 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" ) ); + } + + if ( !myIsUpdatingControls ) + { + if( (QComboBox*)sender() == CBRelativeOrientation ) + { + SetCurrentPlaneParam(); + } + + updateClipping(); + } +} + +/*! + SLOT: called on preview check box toggled +*/ +void OCCViewer_ClippingDlg::onPreview( bool on ) +{ + erasePreview(); + if ( on ) + displayPreview(); +} + +/*! + SLOT: called on Auto Apply check box toggled +*/ +void OCCViewer_ClippingDlg::onAutoApply( bool toggled ) +{ + if ( toggled ) { + onApply(); + myModel->update(); + } +} + +/*! + SLOT on Apply button click: sets cutting plane +*/ +void OCCViewer_ClippingDlg::onApply() +{ + if ( myBusy ) + return; + myIsSelectPlane = true; + + qApp->processEvents(); + QApplication::setOverrideCursor( Qt::WaitCursor ); + qApp->processEvents(); + + myModel->setClipPlanes(myLocalPlanes); + + QApplication::restoreOverrideCursor(); + myIsSelectPlane = false; +} + +/*! + SLOT: Called when clip plane is clicked in viewer. +*/ +void OCCViewer_ClippingDlg::onPlaneClicked( const Handle(AIS_Plane)& thePlane ) +{ + for ( int aPlaneIt = 0; aPlaneIt < myPreviewPlaneVector.size(); aPlaneIt++ ) + { + Handle(AIS_Plane)& aPlane = myPreviewPlaneVector.at( aPlaneIt ); + if ( aPlane != thePlane ) + { + continue; + } + + ComboBoxPlanes->setCurrentIndex( aPlaneIt ); + + break; + } +} + +/*! + SLOT: Called when clip plane is changed by dragging in viewer. +*/ +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 ) +{ + return myLocalPlanes[theIdx]; +} + +int OCCViewer_ClippingDlg::clipPlanesCount() +{ + return myLocalPlanes.size(); +} + +OCCViewer_ClipPlane::PlaneMode OCCViewer_ClippingDlg::currentPlaneMode() const { - return myLocalPlanes.size(); + return ModeStackedLayout->currentIndex() == 0 + ? OCCViewer_ClipPlane::Absolute + : OCCViewer_ClipPlane::Relative; } diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.h b/src/OCCViewer/OCCViewer_ClippingDlg.h index 23ee3d24c..13a293f52 100644 --- a/src/OCCViewer/OCCViewer_ClippingDlg.h +++ b/src/OCCViewer/OCCViewer_ClippingDlg.h @@ -68,6 +68,7 @@ private : virtual void showEvent ( QShowEvent * ); virtual void hideEvent ( QHideEvent * ); void initParam(); + void setPlaneParam( OCCViewer_ClipPlane& thePlane ); void displayPreview(); void erasePreview(); void updatePreview(); @@ -78,6 +79,10 @@ private : OCCViewer_ClipPlane& getClipPlane( int ); int clipPlanesCount(); + OCCViewer_ClipPlane::PlaneMode currentPlaneMode() const; + +private: + QComboBox* ComboBoxPlanes; QCheckBox* isActivePlane; QPushButton* buttonNew; @@ -126,7 +131,6 @@ private : OCCViewer_Viewer* myModel; Handle(V3d_View) myView3d; - Standard_Integer myCurrentClipPlaneMode; std::vector myPreviewPlaneVector; bool myIsSelectPlane; diff --git a/src/OCCViewer/OCCViewer_ViewModel.cxx b/src/OCCViewer/OCCViewer_ViewModel.cxx index 242756b9f..1eb2ec85e 100755 --- a/src/OCCViewer/OCCViewer_ViewModel.cxx +++ b/src/OCCViewer/OCCViewer_ViewModel.cxx @@ -1041,16 +1041,21 @@ void OCCViewer_Viewer::setClipPlanes(ClipPlanesList theList) // 2. Create new clipping planes ClipPlanesList::iterator inIt = theList.begin(); - for (;inIt != theList.end(); inIt++ ) { - OCCViewer_ClipPlane plane; - plane = (*inIt); - myClipPlanes.push_back(plane); - gp_Pln aPln (gp_Pnt (plane.X, plane.Y, plane.Z), - gp_Dir (plane.Dx, plane.Dy, plane.Dz)); - Handle(Graphic3d_ClipPlane) aGraphic3dPlane = new Graphic3d_ClipPlane(); - aGraphic3dPlane->SetEquation (aPln); - aGraphic3dPlane->SetOn(plane.IsOn); - myInternalClipPlanes.Append(aGraphic3dPlane); + for (;inIt != theList.end(); inIt++ ) + { + OCCViewer_ClipPlane aPlane = *inIt; + + double aDx = 0.0, aDy = 0.0, aDz = 0.0; + aPlane.OrientationToXYZ( aDx, aDy, aDz ); + + gp_Pnt anOrigin( aPlane.X, aPlane.Y, aPlane.Z ); + gp_Dir aDirection( aDx, aDy, aDz ); + + Handle(Graphic3d_ClipPlane) aGraphic3dPlane = new Graphic3d_ClipPlane( gp_Pln( anOrigin, aDirection ) ); + aGraphic3dPlane->SetOn( aPlane.IsOn ); + + myInternalClipPlanes.Append( aGraphic3dPlane ); + myClipPlanes.push_back( aPlane ); } // 3. Apply clipping planes diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index 4ca97504b..11ed72b85 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -1,2909 +1,2944 @@ -// 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 -// -// 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : OCCViewer_ViewWindow.cxx -// Author : - -#include "OCCViewer_ViewWindow.h" -#include "OCCViewer_ViewModel.h" -#include "OCCViewer_ViewPort3d.h" -#include "OCCViewer_ViewManager.h" -#include "OCCViewer_ViewSketcher.h" -#include "OCCViewer_CreateRestoreViewDlg.h" -#include "OCCViewer_ClipPlane.h" -#include "OCCViewer_SetRotationPointDlg.h" -#include "OCCViewer_AxialScaleDlg.h" -#include "OCCViewer_CubeAxesDlg.h" -#include "OCCViewer_ClippingDlg.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#if OCC_VERSION_LARGE > 0x06060000 -#include -#include - -#endif - -#include - -#include "utilities.h" - -// // OpenCV includes -// #include -// #include - -static QEvent* l_mbPressEvent = 0; - -#ifdef WIN32 -# include -#endif - -#include - -const char* imageZoomCursor[] = { -"32 32 3 1", -". c None", -"a c #000000", -"# c #ffffff", -"................................", -"................................", -".#######........................", -"..aaaaaaa.......................", -"................................", -".............#####..............", -"...........##.aaaa##............", -"..........#.aa.....a#...........", -".........#.a.........#..........", -".........#a..........#a.........", -"........#.a...........#.........", -"........#a............#a........", -"........#a............#a........", -"........#a............#a........", -"........#a............#a........", -".........#...........#.a........", -".........#a..........#a.........", -".........##.........#.a.........", -"........#####.....##.a..........", -".......###aaa#####.aa...........", -"......###aa...aaaaa.......#.....", -".....###aa................#a....", -"....###aa.................#a....", -"...###aa...............#######..", -"....#aa.................aa#aaaa.", -".....a....................#a....", -"..........................#a....", -"...........................a....", -"................................", -"................................", -"................................", -"................................"}; - -const char* imageRotateCursor[] = { -"32 32 3 1", -". c None", -"a c #000000", -"# c #ffffff", -"................................", -"................................", -"................................", -"................................", -"........#.......................", -".......#.a......................", -"......#######...................", -".......#aaaaa#####..............", -"........#..##.a#aa##........##..", -".........a#.aa..#..a#.....##.aa.", -".........#.a.....#...#..##.aa...", -".........#a.......#..###.aa.....", -"........#.a.......#a..#aa.......", -"........#a.........#..#a........", -"........#a.........#a.#a........", -"........#a.........#a.#a........", -"........#a.........#a.#a........", -".........#.........#a#.a........", -"........##a........#a#a.........", -"......##.a#.......#.#.a.........", -"....##.aa..##.....##.a..........", -"..##.aa.....a#####.aa...........", -"...aa.........aaa#a.............", -"................#.a.............", -"...............#.a..............", -"..............#.a...............", -"...............a................", -"................................", -"................................", -"................................", -"................................", -"................................"}; - -const char* imageCrossCursor[] = { - "32 32 3 1", - ". c None", - "a c #000000", - "# c #ffffff", - "................................", - "................................", - "................................", - "................................", - "................................", - "................................", - "................................", - "...............#................", - "...............#a...............", - "...............#a...............", - "...............#a...............", - "...............#a...............", - "...............#a...............", - "...............#a...............", - "...............#a...............", - ".......#################........", - "........aaaaaaa#aaaaaaaaa.......", - "...............#a...............", - "...............#a...............", - "...............#a...............", - "...............#a...............", - "...............#a...............", - "...............#a...............", - "...............#a...............", - "................a...............", - "................................", - "................................", - "................................", - "................................", - "................................", - "................................", - "................................"}; - - -/*! - \brief Constructor - \param theDesktop main window of application - \param theModel OCC 3D viewer -*/ -OCCViewer_ViewWindow::OCCViewer_ViewWindow( SUIT_Desktop* theDesktop, - OCCViewer_Viewer* theModel ) -: SUIT_ViewWindow( theDesktop ) -{ - myModel = theModel; - myRestoreFlag = 0; - myEnableDrawMode = false; - myDrawRect=false; - updateEnabledDrawMode(); - myScalingDlg = 0; - mySetRotationPointDlg = 0; - myRectBand = 0; - - IsSketcherStyle = false; - myIsKeyFree = false; - - mypSketcher = 0; - myCurSketch = -1; - my2dMode = No2dMode; - - myInteractionStyle = SUIT_ViewModel::STANDARD; - myPreselectionEnabled = true; - mySelectionEnabled = true; - - - clearViewAspects(); - -} - -/*! - \brief Destructor. -*/ -OCCViewer_ViewWindow::~OCCViewer_ViewWindow() -{ - endDrawRect(); - qDeleteAll( mySketchers ); -} - -/*! - \brief Internal initialization. -*/ -void OCCViewer_ViewWindow::initLayout() -{ - myViewPort = new OCCViewer_ViewPort3d( this, myModel->getViewer3d(), V3d_ORTHOGRAPHIC ); - myViewPort->installEventFilter(this); - setCentralWidget(myViewPort); - myOperation = NOTHING; - - myCurrPointType = GRAVITY; - myPrevPointType = GRAVITY; - mySelectedPoint = gp_Pnt(0.,0.,0.); - myRotationPointSelection = false; - - setTransformRequested ( NOTHING ); - setTransformInProcess ( false ); - - createActions(); - createToolBar(); - - switch (my2dMode) { - case XYPlane: - onTopView(); - break; - case XZPlane: - onLeftView(); - break; - case YZPlane: - onFrontView(); - break; - } - - // Graduated axes dialog - QtxAction* anAction = dynamic_cast( toolMgr()->action( GraduatedAxesId ) ); - myCubeAxesDlg = new OCCViewer_CubeAxesDlg( anAction, this, "OCCViewer_CubeAxesDlg" ); - myCubeAxesDlg->initialize(); - - connect( myViewPort, SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), this, SLOT( emitViewModified() ) ); -} - -OCCViewer_ViewWindow* OCCViewer_ViewWindow::getView( const int mode ) const -{ - return mode == get2dMode() ? const_cast( this ) : 0; -} - -/*! - \brief Detect viewer operation according the the mouse button pressed - and key modifiers used. - \param theEvent mouse event - \return type of the operation -*/ -OCCViewer_ViewWindow::OperationType -OCCViewer_ViewWindow::getButtonState( QMouseEvent* theEvent, int theInteractionStyle ) -{ - OperationType aOp = NOTHING; - SUIT_ViewModel::InteractionStyle aStyle = (SUIT_ViewModel::InteractionStyle)theInteractionStyle; - if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::ZOOM]) && - (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::ZOOM]) ) - aOp = ZOOMVIEW; - else if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::PAN]) && - (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::PAN]) ) - aOp = PANVIEW; - else if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::ROTATE]) && - (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::ROTATE]) && - (my2dMode == No2dMode)) - aOp = ROTATE; - - return aOp; -} - -/*! - \brief Customize event handling - \param watched event receiver object - \param e event - \return \c true if the event processing should be stopped -*/ -bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e ) -{ - if ( watched == myViewPort ) { - int aType = e->type(); - switch(aType) { - case QEvent::MouseButtonPress: - vpMousePressEvent((QMouseEvent*) e); - return true; - - case QEvent::MouseButtonRelease: - vpMouseReleaseEvent((QMouseEvent*) e); - return true; - - case QEvent::MouseMove: - vpMouseMoveEvent((QMouseEvent*) e); - return true; - - case QEvent::MouseButtonDblClick: - emit mouseDoubleClicked(this, (QMouseEvent*)e); - return true; - - case QEvent::Wheel: - { - QWheelEvent* aEvent = (QWheelEvent*) e; - myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() ); - double delta = (double)( aEvent->delta() ) / ( 15 * 8 ); - int x = aEvent->x(); - int y = aEvent->y(); - int x1 = (int)( aEvent->x() + width()*delta/100 ); - int y1 = (int)( aEvent->y() + height()*delta/100 ); - myViewPort->zoom( x, y, x1, y1 ); - } - return true; - - case QEvent::ContextMenu: - { - QContextMenuEvent * aEvent = (QContextMenuEvent*)e; - if ( aEvent->reason() != QContextMenuEvent::Mouse ) - emit contextMenuRequested( aEvent ); - } - return true; - - case QEvent::KeyPress: - emit keyPressed(this, (QKeyEvent*) e); - return true; - - default: - break; - } - } - return SUIT_ViewWindow::eventFilter(watched, e); -} - -/*! - \brief Update state of enable draw mode state. -*/ -void OCCViewer_ViewWindow::updateEnabledDrawMode() -{ - if ( myModel ) - myEnableDrawMode = myModel->isSelectionEnabled() && myModel->isMultiSelectionEnabled(); -} - -/*! - \brief Handle mouse press event - \param theEvent mouse event -*/ -void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent ) -{ - myStartX = theEvent->x(); - myStartY = theEvent->y(); - int anInteractionStyle = interactionStyle(); - - // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed), - // which are assigned for pan and rotate - these operations are activated immediately after pressing - // of the first button, so it is necessary to switch to zoom when the second button is pressed - bool aSwitchToZoom = false; - if ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && - ( myOperation == PANVIEW || myOperation == ROTATE ) ) { - aSwitchToZoom = getButtonState( theEvent, anInteractionStyle ) == ZOOMVIEW; - } - - switch ( myOperation ) { - case WINDOWFIT: - if ( theEvent->button() == Qt::LeftButton ) - emit vpTransformationStarted ( WINDOWFIT ); - break; - - case PANGLOBAL: - if ( theEvent->button() == Qt::LeftButton ) - emit vpTransformationStarted ( PANGLOBAL ); - break; - - case ZOOMVIEW: - if ( theEvent->button() == Qt::LeftButton ) { - myViewPort->startZoomAtPoint( myStartX, myStartY ); - emit vpTransformationStarted ( ZOOMVIEW ); - } - break; - - case PANVIEW: - if ( aSwitchToZoom ) { - myViewPort->startZoomAtPoint( myStartX, myStartY ); - activateZoom(); - } - else if ( theEvent->button() == Qt::LeftButton ) - emit vpTransformationStarted ( PANVIEW ); - break; - - case ROTATE: - if ( aSwitchToZoom ) { - myViewPort->startZoomAtPoint( myStartX, myStartY ); - activateZoom(); - } - else if ( theEvent->button() == Qt::LeftButton ) { - myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); - emit vpTransformationStarted ( ROTATE ); - } - break; - - default: - /* Try to activate a transformation */ - OperationType aState; - if ( interactionStyle() == SUIT_ViewModel::STANDARD ) - aState = getButtonState(theEvent, anInteractionStyle); - else { - aState = OCCViewer_ViewWindow::NOTHING; - myIsKeyFree = true; - } - switch ( aState ) { - case ZOOMVIEW: - myViewPort->startZoomAtPoint( myStartX, myStartY ); - activateZoom(); - break; - case PANVIEW: - activatePanning(); - break; - case ROTATE: - activateRotation(); - myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); - break; - default: - if ( myRotationPointSelection ) - { - if ( theEvent->button() == Qt::LeftButton ) - { - Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - ic->Select(); - for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() ) - { - TopoDS_Shape aShape = ic->SelectedShape(); - if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX ) - { - gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) ); - if ( mySetRotationPointDlg ) - { - myRotationPointSelection = false; - mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z()); - } - } - else - { - myCurrPointType = myPrevPointType; - break; - } - } - if ( ic->NbSelected() == 0 ) myCurrPointType = myPrevPointType; - if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange(); - ic->CloseAllContexts(); - myOperation = NOTHING; - myViewPort->setCursor( myCursor ); - myCursorIsHand = false; - myRotationPointSelection = false; - } - } - else - emit mousePressed(this, theEvent); - break; - } - /* notify that we start a transformation */ - if ( transformRequested() ) - emit vpTransformationStarted ( myOperation ); - } - if ( transformRequested() ) - setTransformInProcess( true ); - - /* we may need it for sketching... */ - if ( l_mbPressEvent ) - delete l_mbPressEvent; - l_mbPressEvent = new QMouseEvent( *theEvent ); -} - - -/*! - \brief Start zooming operation. - - Sets the corresponding cursor for the widget. -*/ -void OCCViewer_ViewWindow::activateZoom() -{ - if ( !transformRequested() && !myCursorIsHand ) - myCursor = cursor(); /* save old cursor */ - - if ( myOperation != ZOOMVIEW ) { - QPixmap zoomPixmap (imageZoomCursor); - QCursor zoomCursor (zoomPixmap); - if( setTransformRequested ( ZOOMVIEW ) ) - myViewPort->setCursor( zoomCursor ); - } -} - - -/*! - \brief Start panning operation. - - Sets the corresponding cursor for the widget. -*/ -void OCCViewer_ViewWindow::activatePanning() -{ - if ( !transformRequested() && !myCursorIsHand ) - myCursor = cursor(); // save old cursor - - if ( myOperation != PANVIEW ) { - QCursor panCursor (Qt::SizeAllCursor); - if( setTransformRequested ( PANVIEW ) ) - myViewPort->setCursor( panCursor ); - } -} - -/*! - \brief Start rotation operation - - Sets the corresponding cursor for the widget. -*/ -void OCCViewer_ViewWindow::activateRotation() -{ - if ( !transformRequested() && !myCursorIsHand ) - myCursor = cursor(); // save old cursor - - if ( myOperation != ROTATE ) { - QPixmap rotatePixmap (imageRotateCursor); - QCursor rotCursor (rotatePixmap); - if( setTransformRequested ( ROTATE ) ) - myViewPort->setCursor( rotCursor ); - } -} - -/*! - \brief Compute the gravity center. - \param theX used to return X coordinate of the gravity center - \param theY used to return Y coordinate of the gravity center - \param theZ used to return Z coordinate of the gravity center - \return \c true if the gravity center is computed -*/ -bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, double& theZ ) -{ - Handle(Visual3d_View) aView = myViewPort->getView()->View(); - - Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W ; - Standard_Real Umin,Vmin,Umax,Vmax ; - Standard_Integer Nstruct,Npoint ; - Graphic3d_MapOfStructure MySetOfStructures; - - aView->DisplayedStructures (MySetOfStructures); - Nstruct = MySetOfStructures.Extent() ; - - Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ; -#if OCC_VERSION_LARGE > 0x06070000 - aView->Camera()->WindowLimit(Umin,Vmin,Umax,Vmax); -#else - aView->ViewMapping().WindowLimit(Umin,Vmin,Umax,Vmax); -#endif - Npoint = 0 ; theX = theY = theZ = 0. ; - for( ; MyIterator.More(); MyIterator.Next()) { - if (!(MyIterator.Key())->IsEmpty()) { - (MyIterator.Key())->MinMaxValues(Xmin,Ymin,Zmin, - Xmax,Ymax,Zmax) ; - - Standard_Real LIM = ShortRealLast() -1.; - if (! (fabs(Xmin) > LIM || fabs(Ymin) > LIM || fabs(Zmin) > LIM - || fabs(Xmax) > LIM || fabs(Ymax) > LIM || fabs(Zmax) > LIM )) { - - aView->Projects(Xmin,Ymin,Zmin,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmin ; - } - aView->Projects(Xmax,Ymin,Zmin,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmin ; - } - aView->Projects(Xmin,Ymax,Zmin,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmin ; - } - aView->Projects(Xmax,Ymax,Zmin,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmin ; - } - aView->Projects(Xmin,Ymin,Zmax,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmax ; - } - aView->Projects(Xmax,Ymin,Zmax,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmax ; - } - aView->Projects(Xmin,Ymax,Zmax,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmax ; - } - aView->Projects(Xmax,Ymax,Zmax,U,V,W) ; - if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { - Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmax ; - } - } - } - } - if( Npoint > 0 ) { - theX /= Npoint ; theY /= Npoint ; theZ /= Npoint ; - } - return true; -} - -/*! - \brief Set the gravity center as a rotation point. -*/ -void OCCViewer_ViewWindow::activateSetRotationGravity() -{ - if ( myRotationPointSelection ) - { - Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - ic->CloseAllContexts(); - myOperation = NOTHING; - myViewPort->setCursor( myCursor ); - myCursorIsHand = false; - myRotationPointSelection = false; - } - - myPrevPointType = myCurrPointType; - myCurrPointType = GRAVITY; - - Standard_Real Xcenter, Ycenter, Zcenter; - if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) ) - mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter ); -} - -/*! - \brief Update gravity center in the "Set Rotation Point" dialog box. - \sa OCCViewer_SetRotationPointDlg class -*/ -void OCCViewer_ViewWindow::updateGravityCoords() -{ - if ( mySetRotationPointDlg && mySetRotationPointDlg->isVisible() && myCurrPointType == GRAVITY ) - { - Standard_Real Xcenter, Ycenter, Zcenter; - if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) ) - mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter ); - } -} - -/*! - \brief Set the point selected by the user as a rotation point. - \param theX X coordinate of the rotation point - \param theY Y coordinate of the rotation point - \param theZ Z coordinate of the rotation point -*/ -void OCCViewer_ViewWindow::activateSetRotationSelected( double theX, double theY, double theZ ) -{ - if ( myRotationPointSelection ) - { - Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - ic->CloseAllContexts(); - myOperation = NOTHING; - myViewPort->setCursor( myCursor ); - myCursorIsHand = false; - myRotationPointSelection = false; - } - - myPrevPointType = myCurrPointType; - myCurrPointType = SELECTED; - mySelectedPoint.SetCoord(theX,theY,theZ); -} - -/*! - \brief Start the point selection process. -*/ -void OCCViewer_ViewWindow::activateStartPointSelection() -{ - myPrevPointType = myCurrPointType; - myCurrPointType = SELECTED; - - // activate selection ------> - Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - - ic->OpenLocalContext(); - - 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_Shape) ) ) - { - ic->Load(anObj,-1); - ic->Activate(anObj,AIS_Shape::SelectionMode(TopAbs_VERTEX)); - } - } - // activate selection <------ - - if ( !myCursorIsHand ) - { - QCursor handCursor (Qt::PointingHandCursor); - myCursorIsHand = true; - myCursor = cursor(); - myViewPort->setCursor( handCursor ); - } - myRotationPointSelection = true; -} - -/*! - \brief Start global panning operation - - Sets the corresponding cursor for the widget. -*/ -void OCCViewer_ViewWindow::activateGlobalPanning() -{ - Handle(V3d_View) aView3d = myViewPort->getView(); - if ( !aView3d.IsNull() ) { - QPixmap globalPanPixmap (imageCrossCursor); - QCursor glPanCursor (globalPanPixmap); - myCurScale = aView3d->Scale(); - aView3d->FitAll(0.01, false); - myCursor = cursor(); // save old cursor - myViewPort->fitAll(); // fits view before selecting a new scene center - if( setTransformRequested( PANGLOBAL ) ) - myViewPort->setCursor( glPanCursor ); - } -} - -/*! - \brief Starts fit operation. - - Sets the corresponding cursor for the widget. -*/ -void OCCViewer_ViewWindow::activateWindowFit() -{ - if ( !transformRequested() && !myCursorIsHand ) - myCursor = cursor(); /* save old cursor */ - - if ( myOperation != WINDOWFIT ) { - QCursor handCursor (Qt::PointingHandCursor); - if( setTransformRequested ( WINDOWFIT ) ) - { - myViewPort->setCursor ( handCursor ); - myCursorIsHand = true; - } - } -} - -/*! - \brief Start delayed viewer operation. -*/ -bool OCCViewer_ViewWindow::setTransformRequested( OperationType op ) -{ - bool ok = transformEnabled( op ); - myOperation = ok ? op : NOTHING; - myViewPort->setMouseTracking( myOperation == NOTHING ); - return ok; -} - -/*! - \brief Handle mouse move event. - \param theEvent mouse event -*/ -void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent ) -{ - if ( myIsKeyFree && interactionStyle() == SUIT_ViewModel::KEY_FREE ) { - myIsKeyFree = false; - switch ( getButtonState( theEvent, interactionStyle() ) ) { - case ZOOMVIEW: - myViewPort->startZoomAtPoint( myStartX, myStartY ); - activateZoom(); - break; - case PANVIEW: - activatePanning(); - break; - case ROTATE: - activateRotation(); - myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); - break; - default: - break; - } - } - - myCurrX = theEvent->x(); - myCurrY = theEvent->y(); - switch (myOperation) { - case ROTATE: - myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint); - break; - - case ZOOMVIEW: - myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY); - myStartX = myCurrX; - myStartY = myCurrY; - break; - - case PANVIEW: - myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY); - myStartX = myCurrX; - myStartY = myCurrY; - break; - -/* case WINDOWFIT: - myDrawRect = true; - repaint(); - break; -*/ - case PANGLOBAL: - break; - - default: - if ( myRotationPointSelection || isSketcherStyle() ) - { - emit mouseMoving( this, theEvent ); - } - else - { - int aState = theEvent->modifiers(); - int aButton = theEvent->buttons(); - int anInteractionStyle = interactionStyle(); - if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD && - aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) || - ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && - aButton == Qt::LeftButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) { - myDrawRect = myEnableDrawMode; - if ( myDrawRect ) { - drawRect(); - if ( !myCursorIsHand ) { // we are going to sketch a rectangle - QCursor handCursor (Qt::PointingHandCursor); - myCursorIsHand = true; - myCursor = cursor(); - myViewPort->setCursor( handCursor ); - } - } - emit mouseMoving( this, theEvent ); - } - else if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD && - aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) || - ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && - aButton == Qt::RightButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) { - OCCViewer_ViewSketcher* sketcher = 0; - QList::Iterator it; - for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) - { - OCCViewer_ViewSketcher* sk = (*it); - if( sk->isDefault() && sk->sketchButton() == aButton ) - sketcher = sk; - } - if ( sketcher && myCurSketch == -1 ) - { - activateSketching( sketcher->type() ); - if ( mypSketcher ) - { - myCurSketch = mypSketcher->sketchButton(); - - if ( l_mbPressEvent ) - { - QApplication::sendEvent( getViewPort(), l_mbPressEvent ); - delete l_mbPressEvent; - l_mbPressEvent = 0; - } - QApplication::sendEvent( getViewPort(), theEvent ); - } - } - } - else - emit mouseMoving( this, theEvent ); - } - } -} - -/*! - \brief Handle mouse release event. - \param theEvent mouse event -*/ -void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent) -{ - switch ( myOperation ) { - case NOTHING: - { - int prevState = myCurSketch; - if(theEvent->button() == Qt::RightButton) - { - QList::Iterator it; - for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it ) - { - OCCViewer_ViewSketcher* sk = (*it); - if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch ) - myCurSketch = -1; - } - } - - emit mouseReleased(this, theEvent); - if(theEvent->button() == Qt::RightButton && prevState == -1) - { - QContextMenuEvent aEvent( QContextMenuEvent::Mouse, - theEvent->pos(), theEvent->globalPos() ); - emit contextMenuRequested( &aEvent ); - } - } - break; - case ROTATE: - myViewPort->endRotation(); - resetState(); - break; - - case PANVIEW: - case ZOOMVIEW: - resetState(); - break; - - case PANGLOBAL: - if ( theEvent->button() == Qt::LeftButton ) { - myViewPort->setCenter( theEvent->x(), theEvent->y() ); - myViewPort->getView()->SetScale(myCurScale); - resetState(); - } - break; - - case WINDOWFIT: - if ( theEvent->button() == Qt::LeftButton ) { - myCurrX = theEvent->x(); - myCurrY = theEvent->y(); - drawRect(); - QRect rect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY); - if ( !rect.isEmpty() ) myViewPort->fitRect(rect); - endDrawRect(); - resetState(); - } - break; - } - - // NOTE: viewer 3D detects a rectangle of selection using this event - // so we must emit it BEFORE resetting the selection rectangle - - if ( theEvent->button() == Qt::LeftButton && myDrawRect ) { - drawRect(); - endDrawRect(); - resetState(); - myViewPort->update(); - } - - if ( l_mbPressEvent ) - { - delete l_mbPressEvent; - l_mbPressEvent = 0; - } -} - -/*! - \brief Reset the viewport to its initial state - ( no transformations in process etc. ) -*/ -void OCCViewer_ViewWindow::resetState() -{ - myDrawRect = false; - - if ( myRotationPointSelection ) - { - QCursor handCursor (Qt::PointingHandCursor); - myViewPort->setCursor( handCursor ); - } - else - { - if ( transformRequested() || myCursorIsHand ) - myViewPort->setCursor( myCursor ); - myCursorIsHand = false; - } - - if ( transformRequested() ) - emit vpTransformationFinished (myOperation); - - setTransformInProcess( false ); - setTransformRequested( NOTHING ); -} - - -/*! - \brief Draw rubber band rectangle. -*/ -void OCCViewer_ViewWindow::drawRect() -{ - if ( !myRectBand ) { - myRectBand = new QtxRectRubberBand( myViewPort ); - //QPalette palette; - //palette.setColor(myRectBand->foregroundRole(), Qt::white); - //myRectBand->setPalette(palette); - } - //myRectBand->hide(); - - myRectBand->setUpdatesEnabled ( false ); - QRect aRect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY); - myRectBand->initGeometry( aRect ); - - if ( !myRectBand->isVisible() ) - myRectBand->show(); - - myRectBand->setUpdatesEnabled ( true ); - //myRectBand->repaint(); - - //myRectBand->setVisible( aRect.isValid() ); - //if ( myRectBand->isVisible() ) - // myRectBand->repaint(); - //else - // myRectBand->show(); - //myRectBand->repaint(); -} - -/*! - \brief Clear rubber band rectangle on the end on the dragging operation. -*/ -void OCCViewer_ViewWindow::endDrawRect() -{ - //delete myRectBand; - //myRectBand = 0; - if ( myRectBand ) - { - myRectBand->clearGeometry(); - myRectBand->hide(); - } -} - -/*! - \brief Create actions. -*/ -void OCCViewer_ViewWindow::createActions() -{ - if( !toolMgr()->isEmpty() ) - return; - - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - - QtxAction* aAction; - - // Dump view - aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_DUMP" ) ), - tr( "MNU_DUMP_VIEW" ), 0, this); - aAction->setStatusTip(tr("DSC_DUMP_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onDumpView())); - toolMgr()->registerAction( aAction, DumpId ); - - // FitAll - aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITALL" ) ), - tr( "MNU_FITALL" ), 0, this); - aAction->setStatusTip(tr("DSC_FITALL")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onFitAll())); - toolMgr()->registerAction( aAction, FitAllId ); - - // FitRect - aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITAREA" ) ), - tr( "MNU_FITRECT" ), 0, this); - aAction->setStatusTip(tr("DSC_FITRECT")); - connect(aAction, SIGNAL(triggered()), this, SLOT(activateWindowFit())); - toolMgr()->registerAction( aAction, FitRectId ); - - // Zoom - aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ZOOM" ) ), - tr( "MNU_ZOOM_VIEW" ), 0, this); - aAction->setStatusTip(tr("DSC_ZOOM_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(activateZoom())); - toolMgr()->registerAction( aAction, ZoomId ); - - // Panning - aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_PAN" ) ), - tr( "MNU_PAN_VIEW" ), 0, this); - aAction->setStatusTip(tr("DSC_PAN_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(activatePanning())); - toolMgr()->registerAction( aAction, PanId ); - - // Global Panning - aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_GLOBALPAN" ) ), - tr( "MNU_GLOBALPAN_VIEW" ), 0, this); - aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(activateGlobalPanning())); - toolMgr()->registerAction( aAction, GlobalPanId ); - - // Rotation Point - mySetRotationPointAction = new QtxAction(tr("MNU_CHANGINGROTATIONPOINT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATION_POINT" ) ), - tr( "MNU_CHANGINGROTATIONPOINT_VIEW" ), 0, this); - mySetRotationPointAction->setStatusTip(tr("DSC_CHANGINGROTATIONPOINT_VIEW")); - mySetRotationPointAction->setCheckable( true ); - connect(mySetRotationPointAction, SIGNAL(toggled( bool )), this, SLOT(onSetRotationPoint( bool ))); - toolMgr()->registerAction( mySetRotationPointAction, ChangeRotationPointId ); - - // Rotation - aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATE" ) ), - tr( "MNU_ROTATE_VIEW" ), 0, this); - aAction->setStatusTip(tr("DSC_ROTATE_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(activateRotation())); - toolMgr()->registerAction( aAction, RotationId ); - - // Projections - aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FRONT" ) ), - tr( "MNU_FRONT_VIEW" ), 0, this, false, "Viewers:Front view"); - aAction->setStatusTip(tr("DSC_FRONT_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onFrontView())); - this->addAction(aAction); - toolMgr()->registerAction( aAction, FrontId ); - - aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BACK" ) ), - tr( "MNU_BACK_VIEW" ), 0, this, false, "Viewers:Back view"); - aAction->setStatusTip(tr("DSC_BACK_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onBackView())); - this->addAction(aAction); - toolMgr()->registerAction( aAction, BackId ); - - aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TOP" ) ), - tr( "MNU_TOP_VIEW" ), 0, this, false, "Viewers:Top view"); - aAction->setStatusTip(tr("DSC_TOP_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onTopView())); - this->addAction(aAction); - toolMgr()->registerAction( aAction, TopId ); - - aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BOTTOM" ) ), - tr( "MNU_BOTTOM_VIEW" ), 0, this, false, "Viewers:Bottom view"); - aAction->setStatusTip(tr("DSC_BOTTOM_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onBottomView())); - this->addAction(aAction); - toolMgr()->registerAction( aAction, BottomId ); - - aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_LEFT" ) ), - tr( "MNU_LEFT_VIEW" ), 0, this, false, "Viewers:Left view"); - aAction->setStatusTip(tr("DSC_LEFT_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onLeftView())); - this->addAction(aAction); - toolMgr()->registerAction( aAction, LeftId ); - - aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RIGHT" ) ), - tr( "MNU_RIGHT_VIEW" ), 0, this, false, "Viewers:Right view"); - aAction->setStatusTip(tr("DSC_RIGHT_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onRightView())); - this->addAction(aAction); - toolMgr()->registerAction( aAction, RightId ); - - // rotate anticlockwise - aAction = new QtxAction(tr("MNU_ANTICLOCKWISE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ANTICLOCKWISE" ) ), - tr( "MNU_ANTICLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate anticlockwise"); - aAction->setStatusTip(tr("DSC_ANTICLOCKWISE_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onAntiClockWiseView())); - this->addAction(aAction); - toolMgr()->registerAction( aAction, AntiClockWiseId ); - - // rotate clockwise - aAction = new QtxAction(tr("MNU_CLOCKWISE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_CLOCKWISE" ) ), - tr( "MNU_CLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate clockwise"); - aAction->setStatusTip(tr("DSC_CLOCKWISE_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onClockWiseView())); - this->addAction(aAction); - toolMgr()->registerAction( aAction, ClockWiseId ); - - // Reset - aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RESET" ) ), - tr( "MNU_RESET_VIEW" ), 0, this, false, "Viewers:Reset view"); - aAction->setStatusTip(tr("DSC_RESET_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onResetView())); - this->addAction(aAction); - toolMgr()->registerAction( aAction, ResetId ); - - // Clone - aAction = new QtxAction(tr("MNU_CLONE_VIEW"), - aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_CLONE_VIEW")), - tr("MNU_CLONE_VIEW"), 0, this); - aAction->setStatusTip(tr("DSC_CLONE_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onCloneView())); - toolMgr()->registerAction( aAction, CloneId ); - - aAction = new QtxAction (tr ("MNU_CLIPPING"), aResMgr->loadPixmap ("OCCViewer", tr ("ICON_OCCVIEWER_CLIPPING")), - tr ("MNU_CLIPPING"), 0, this); - aAction->setStatusTip (tr ("DSC_CLIPPING")); - aAction->setCheckable (true); - connect (aAction, SIGNAL (toggled (bool)), this, SLOT (onClipping (bool))); - toolMgr()->registerAction (aAction, ClippingId); - - aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ), - tr( "MNU_SHOOT_VIEW" ), 0, this); - aAction->setStatusTip(tr("DSC_SHOOT_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onMemorizeView())); - toolMgr()->registerAction( aAction, MemId ); - - aAction = new QtxAction(tr("MNU_PRESETS_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESETS_VIEW" ) ), - tr( "MNU_PRESETS_VIEW" ), 0, this); - aAction->setStatusTip(tr("DSC_PRESETS_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onRestoreView())); - toolMgr()->registerAction( aAction, RestoreId ); - - if (myModel->trihedronActivated()) { - aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TRIHEDRON" ) ), - tr( "MNU_SHOW_TRIHEDRE" ), 0, this); - aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRE")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onTrihedronShow())); - toolMgr()->registerAction( aAction, TrihedronShowId ); - } - - // Scale - aAction = new QtxAction(tr("MNU_SCALING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SCALING" ) ), - tr( "MNU_SCALING" ), 0, this); - aAction->setStatusTip(tr("DSC_SCALING")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onAxialScale())); - toolMgr()->registerAction( aAction, AxialScaleId ); - - // Enable/disable preselection - aAction = new QtxAction(tr("MNU_ENABLE_PRESELECTION"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESELECTION" ) ), - tr( "MNU_ENABLE_PRESELECTION" ), 0, this); - aAction->setStatusTip(tr("DSC_ENABLE_PRESELECTION")); - aAction->setCheckable(true); - connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchPreselection(bool))); - toolMgr()->registerAction( aAction, SwitchPreselectionId ); - - // Enable/disable selection - aAction = new QtxAction(tr("MNU_ENABLE_SELECTION"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SELECTION" ) ), - tr( "MNU_ENABLE_SELECTION" ), 0, this); - aAction->setStatusTip(tr("DSC_ENABLE_SELECTION")); - aAction->setCheckable(true); - connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchSelection(bool))); - toolMgr()->registerAction( aAction, SwitchSelectionId ); - - // Graduated axes - aAction = new QtxAction(tr("MNU_GRADUATED_AXES"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_GRADUATED_AXES" ) ), - tr( "MNU_GRADUATED_AXES" ), 0, this); - aAction->setStatusTip(tr("DSC_GRADUATED_AXES")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onGraduatedAxes())); - toolMgr()->registerAction( aAction, GraduatedAxesId ); - - // Active only ambient light or not - aAction = new QtxAction(tr("MNU_AMBIENT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_AMBIENT" ) ), - tr( "MNU_AMBIENT" ), 0, this); - aAction->setStatusTip(tr("DSC_AMBIENT")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onAmbientToogle())); - toolMgr()->registerAction( aAction, AmbientId ); - - // Switch between interaction styles - aAction = new QtxAction(tr("MNU_STYLE_SWITCH"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_STYLE_SWITCH" ) ), - tr( "MNU_STYLE_SWITCH" ), 0, this); - aAction->setStatusTip(tr("DSC_STYLE_SWITCH")); - aAction->setCheckable(true); - connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchInteractionStyle(bool))); - toolMgr()->registerAction( aAction, SwitchInteractionStyleId ); - - // Switch between zooming styles - aAction = new QtxAction(tr("MNU_ZOOMING_STYLE_SWITCH"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_ZOOMING_STYLE_SWITCH" ) ), - tr( "MNU_ZOOMING_STYLE_SWITCH" ), 0, this); - aAction->setStatusTip(tr("DSC_ZOOMING_STYLE_SWITCH")); - aAction->setCheckable(true); - connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchZoomingStyle(bool))); - toolMgr()->registerAction( aAction, SwitchZoomingStyleId ); - - // Maximized view - aAction = new QtxAction(tr("MNU_MINIMIZE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ), - tr( "MNU_MINIMIZE_VIEW" ), 0, this ); - aAction->setStatusTip(tr("DSC_MINIMIZE_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(onMaximizedView())); - toolMgr()->registerAction( aAction, MaximizedId ); - - // Return to 3d view - if (my2dMode!=No2dMode){ - aAction = new QtxAction(tr("MNU_RETURN_3D_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_RETURN_3D_VIEW" ) ), - tr( "MNU_RETURN_3D_VIEW" ), 0, this ); - aAction->setStatusTip(tr("DSC_RETURN_3D_VIEW")); - connect(aAction, SIGNAL(triggered()), this, SLOT(returnTo3dView())); - toolMgr()->registerAction( aAction, ReturnTo3dViewId ); - } - - // Synchronize View - toolMgr()->registerAction( synchronizeAction(), SynchronizeId ); -} - -/*! - \brief Create toolbar. -*/ -void OCCViewer_ViewWindow::createToolBar() -{ - QString aToolbarName; - switch (my2dMode) { - case XYPlane: - aToolbarName = tr( "LBL_XYTOOLBAR_LABEL" ); - break; - case XZPlane: - aToolbarName = tr( "LBL_XZTOOLBAR_LABEL" ); - break; - case YZPlane: - aToolbarName = tr( "LBL_YZTOOLBAR_LABEL" ); - break; - default: - aToolbarName = tr( "LBL_3DTOOLBAR_LABEL" ); - } - - int tid = toolMgr()->createToolBar( aToolbarName, false ); - if ( my2dMode != No2dMode ){ - toolMgr()->append( ReturnTo3dViewId, tid ); - toolMgr()->append( toolMgr()->separator(), tid ); - } - toolMgr()->append( DumpId, tid ); - toolMgr()->append( SwitchInteractionStyleId, tid ); -#if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version - toolMgr()->append( SwitchZoomingStyleId, tid ); -#endif - toolMgr()->append( SwitchPreselectionId, tid ); - toolMgr()->append( SwitchSelectionId, tid ); - if( myModel->trihedronActivated() ) - toolMgr()->append( TrihedronShowId, tid ); - - QtxMultiAction* aScaleAction = new QtxMultiAction( this ); - aScaleAction->insertAction( toolMgr()->action( FitAllId ) ); - aScaleAction->insertAction( toolMgr()->action( FitRectId ) ); - aScaleAction->insertAction( toolMgr()->action( ZoomId ) ); - toolMgr()->append( aScaleAction, tid ); - - QtxMultiAction* aPanningAction = new QtxMultiAction( this ); - aPanningAction->insertAction( toolMgr()->action( PanId ) ); - aPanningAction->insertAction( toolMgr()->action( GlobalPanId ) ); - toolMgr()->append( aPanningAction, tid ); - - if (my2dMode == No2dMode) { - toolMgr()->append( ChangeRotationPointId, tid ); - toolMgr()->append( RotationId, tid ); - - QtxMultiAction* aViewsAction = new QtxMultiAction( this ); - aViewsAction->insertAction( toolMgr()->action( FrontId ) ); - aViewsAction->insertAction( toolMgr()->action( BackId ) ); - aViewsAction->insertAction( toolMgr()->action( TopId ) ); - aViewsAction->insertAction( toolMgr()->action( BottomId ) ); - aViewsAction->insertAction( toolMgr()->action( LeftId ) ); - aViewsAction->insertAction( toolMgr()->action( RightId ) ); - toolMgr()->append( aViewsAction, tid ); - - toolMgr()->append( AntiClockWiseId, tid ); - toolMgr()->append( ClockWiseId, tid ); - - toolMgr()->append( ResetId, tid ); - } - - QtxMultiAction* aMemAction = new QtxMultiAction( this ); - aMemAction->insertAction( toolMgr()->action( MemId ) ); - aMemAction->insertAction( toolMgr()->action( RestoreId ) ); - toolMgr()->append( aMemAction, tid ); - - toolMgr()->append( toolMgr()->separator(), tid ); - toolMgr()->append( CloneId, tid ); - - toolMgr()->append( toolMgr()->separator(), tid ); - toolMgr()->append( ClippingId, tid ); - toolMgr()->append( AxialScaleId, tid ); -#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version - toolMgr()->append( GraduatedAxesId, tid ); -#endif - toolMgr()->append( AmbientId, tid ); - - toolMgr()->append( MaximizedId, tid ); - toolMgr()->append( SynchronizeId, tid ); -} - -/*! - \brief Perform 'fit all' operation. -*/ -void OCCViewer_ViewWindow::onViewFitAll() -{ - myViewPort->fitAll(); -} - -/*! - \brief Perform "front view" transformation. -*/ -void OCCViewer_ViewWindow::onFrontView() -{ - emit vpTransformationStarted ( FRONTVIEW ); - Handle(V3d_View) aView3d = myViewPort->getView(); - if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xpos); - onViewFitAll(); - emit vpTransformationFinished ( FRONTVIEW ); -} - -/*! - \brief Perform "back view" transformation. -*/ -void OCCViewer_ViewWindow::onBackView() -{ - emit vpTransformationStarted ( BACKVIEW ); - Handle(V3d_View) aView3d = myViewPort->getView(); - if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xneg); - onViewFitAll(); - emit vpTransformationFinished ( BACKVIEW ); -} - -/*! - \brief Perform "top view" transformation. -*/ -void OCCViewer_ViewWindow::onTopView() -{ - emit vpTransformationStarted ( TOPVIEW ); - Handle(V3d_View) aView3d = myViewPort->getView(); - if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zpos); - onViewFitAll(); - emit vpTransformationFinished ( TOPVIEW ); -} - -/*! - \brief Perform "bottom view" transformation. -*/ -void OCCViewer_ViewWindow::onBottomView() -{ - emit vpTransformationStarted ( BOTTOMVIEW ); - Handle(V3d_View) aView3d = myViewPort->getView(); - if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zneg); - onViewFitAll(); - emit vpTransformationFinished ( BOTTOMVIEW ); -} - -/*! - \brief Perform "left view" transformation. -*/ -void OCCViewer_ViewWindow::onLeftView() -{ - emit vpTransformationStarted ( LEFTVIEW ); - Handle(V3d_View) aView3d = myViewPort->getView(); - if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Yneg); - onViewFitAll(); - emit vpTransformationFinished ( LEFTVIEW ); -} - -/*! - \brief Perform "right view" transformation. -*/ -void OCCViewer_ViewWindow::onRightView() -{ - emit vpTransformationStarted ( RIGHTVIEW ); - Handle(V3d_View) aView3d = myViewPort->getView(); - if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Ypos); - onViewFitAll(); - emit vpTransformationFinished ( RIGHTVIEW ); -} - -/*! - \brief Rotate view 90 degrees clockwise -*/ -void OCCViewer_ViewWindow::onClockWiseView() -{ - emit vpTransformationStarted ( CLOCKWISEVIEW ); - myViewPort->rotateXY( 90. ); - emit vpTransformationFinished ( CLOCKWISEVIEW ); -} - -/*! - \brief Rotate view 90 degrees conterclockwise -*/ -void OCCViewer_ViewWindow::onAntiClockWiseView() -{ - emit vpTransformationStarted ( ANTICLOCKWISEVIEW ); - myViewPort->rotateXY( -90. ); - emit vpTransformationFinished ( ANTICLOCKWISEVIEW ); -} - -/*! - \brief Perform "reset view" transformation. - - Sets default orientation of the viewport camera. -*/ -void OCCViewer_ViewWindow::onResetView() -{ - emit vpTransformationStarted( RESETVIEW ); - bool upd = myViewPort->getView()->SetImmediateUpdate( false ); - myViewPort->getView()->Reset( false ); - myViewPort->fitAll( false, true, false ); - myViewPort->getView()->SetImmediateUpdate( upd ); - myViewPort->getView()->Update(); - emit vpTransformationFinished( RESETVIEW ); -} - -/*! - \brief Perform "fit all" transformation. -*/ -void OCCViewer_ViewWindow::onFitAll() -{ - emit vpTransformationStarted( FITALLVIEW ); - myViewPort->fitAll(); - emit vpTransformationFinished( FITALLVIEW ); -} - -/*! - \brief Called if 'change rotation point' operation is activated. - \param on action state -*/ -void OCCViewer_ViewWindow::onSetRotationPoint( bool on ) -{ - if (on) - { - if (!mySetRotationPointDlg) - { - mySetRotationPointDlg = new OCCViewer_SetRotationPointDlg (this); - mySetRotationPointDlg->SetAction(mySetRotationPointAction); - } - - if (!mySetRotationPointDlg->isVisible()) - { - //if (mySetRotationPointDlg->IsFirstShown()) - if (myCurrPointType == GRAVITY) - { - Standard_Real Xcenter, Ycenter, Zcenter; - if (computeGravityCenter(Xcenter, Ycenter, Zcenter)) - mySetRotationPointDlg->setCoords(Xcenter, Ycenter, Zcenter); - } - mySetRotationPointDlg->show(); - } - } - else - { - if (mySetRotationPointDlg->isVisible()) - mySetRotationPointDlg->hide(); - } -} - -/*! - \brief Create one more window with same content. -*/ -void OCCViewer_ViewWindow::onCloneView() -{ - SUIT_ViewWindow* vw = myManager->createViewWindow(); - //vw->show(); - emit viewCloned( vw ); -} - -/*! - Creates one more window with same content -*/ -void OCCViewer_ViewWindow::onAxialScale() -{ - if ( !myScalingDlg ) - myScalingDlg = new OCCViewer_AxialScaleDlg( this ); - - if ( !myScalingDlg->isVisible() ) - { - myScalingDlg->Update(); - myScalingDlg->show(); - } -} - -/*! - Shows Graduated Axes dialog -*/ -void OCCViewer_ViewWindow::onGraduatedAxes() -{ - myCubeAxesDlg->Update(); - myCubeAxesDlg->show(); -} - -void OCCViewer_ViewWindow::onAmbientToogle() -{ - Handle(V3d_Viewer) viewer = myViewPort->getViewer(); - viewer->InitDefinedLights(); - while(viewer->MoreDefinedLights()) - { - Handle(V3d_Light) light = viewer->DefinedLight(); - if(light->Type() != V3d_AMBIENT) - { - Handle(V3d_View) aView3d = myViewPort->getView(); - if( aView3d->IsActiveLight(light) ) viewer->SetLightOff(light); - else viewer->SetLightOn(light); - } - viewer->NextDefinedLights(); - } - viewer->Update(); -} - -/*! - \brief Store view parameters. -*/ -void OCCViewer_ViewWindow::onMemorizeView() -{ - appendViewAspect( getViewParams() ); -} - -/*! - \brief Restore view parameters. -*/ -void OCCViewer_ViewWindow::onRestoreView() -{ - OCCViewer_CreateRestoreViewDlg* aDlg = new OCCViewer_CreateRestoreViewDlg( centralWidget(), this ); - connect( aDlg, SIGNAL( dlgOk() ), this, SLOT( setRestoreFlag() ) ); - aDlg->exec(); - updateViewAspects( aDlg->parameters() ); - if( myRestoreFlag && aDlg->parameters().count() ) - performRestoring( aDlg->currentItem() ); -} - -/*! - \brief Restore view parameters. - \param anItem view parameters -*/ -void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool baseParamsOnly ) -{ - Handle(V3d_View) aView3d = myViewPort->getView(); - - Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False ); - aView3d->SetScale( anItem.scale ); - aView3d->SetCenter( anItem.centerX, anItem.centerY ); - aView3d->SetTwist( anItem.twist ); - aView3d->SetAt( anItem.atX, anItem.atY, anItem.atZ ); - aView3d->SetImmediateUpdate( prev ); - 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 ( !baseParamsOnly ) { - - myModel->setTrihedronShown( anItem.isVisible ); - myModel->setTrihedronSize( anItem.size ); - -#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version - // graduated trihedron - bool anIsVisible = anItem.gtIsVisible; - OCCViewer_AxisWidget::AxisData anAxisData[3]; - anAxisData[0].DrawName = anItem.gtDrawNameX; - anAxisData[1].DrawName = anItem.gtDrawNameZ; - anAxisData[2].DrawName = anItem.gtDrawNameZ; - anAxisData[0].Name = anItem.gtNameX; - anAxisData[1].Name = anItem.gtNameZ; - anAxisData[2].Name = anItem.gtNameZ; - anAxisData[0].NameColor = QColor( anItem.gtNameColorRX, - anItem.gtNameColorGX, - anItem.gtNameColorBX ); - anAxisData[1].NameColor = QColor( anItem.gtNameColorRY, - anItem.gtNameColorGY, - anItem.gtNameColorBY ); - anAxisData[2].NameColor = QColor( anItem.gtNameColorRZ, - anItem.gtNameColorGZ, - anItem.gtNameColorBZ ); - anAxisData[0].DrawValues = anItem.gtDrawValuesX; - anAxisData[1].DrawValues = anItem.gtDrawValuesY; - anAxisData[2].DrawValues = anItem.gtDrawValuesZ; - anAxisData[0].NbValues = anItem.gtNbValuesX; - anAxisData[1].NbValues = anItem.gtNbValuesY; - anAxisData[2].NbValues = anItem.gtNbValuesZ; - anAxisData[0].Offset = anItem.gtOffsetX; - anAxisData[1].Offset = anItem.gtOffsetY; - anAxisData[2].Offset = anItem.gtOffsetZ; - anAxisData[0].Color = QColor( anItem.gtColorRX, - anItem.gtColorGX, - anItem.gtColorBX ); - anAxisData[1].Color = QColor( anItem.gtColorRY, - anItem.gtColorGY, - anItem.gtColorBY ); - anAxisData[2].Color = QColor( anItem.gtColorRZ, - anItem.gtColorGZ, - anItem.gtColorBZ ); - anAxisData[0].DrawTickmarks = anItem.gtDrawTickmarksX; - anAxisData[1].DrawTickmarks = anItem.gtDrawTickmarksY; - anAxisData[2].DrawTickmarks = anItem.gtDrawTickmarksZ; - anAxisData[0].TickmarkLength = anItem.gtTickmarkLengthX; - anAxisData[1].TickmarkLength = anItem.gtTickmarkLengthY; - anAxisData[2].TickmarkLength = anItem.gtTickmarkLengthZ; - - myCubeAxesDlg->SetData( anIsVisible, anAxisData ); - myCubeAxesDlg->ApplyData( aView3d ); -#endif - - } // if ( !baseParamsOnly ) - - myRestoreFlag = 0; -} - -/*! - \brief Set restore flag. -*/ -void OCCViewer_ViewWindow::setRestoreFlag() -{ - myRestoreFlag = 1; -} - -/*! - \brief Called when action "show/hide trihedron" is activated. -*/ -void OCCViewer_ViewWindow::onTrihedronShow() -{ - myModel->toggleTrihedron(); -} - -/*! - \brief Toggles preselection (highlighting) on/off -*/ -void OCCViewer_ViewWindow::onSwitchPreselection( bool on ) -{ - myPreselectionEnabled = on; - myModel->setSelectionOptions( isPreselectionEnabled(), myModel->isSelectionEnabled() ); - - // unhighlight all highlighted objects - /*if ( !on ) { - myModel->unHighlightAll( true, false ); - }*/ - - // update action state if method is called outside - QtxAction* a = dynamic_cast( toolMgr()->action( SwitchPreselectionId ) ); - if ( a && a->isChecked() != on ) { - a->setChecked( on ); - } -} - -/*! - \brief Toggles selection on/off -*/ -void OCCViewer_ViewWindow::onSwitchSelection( bool on ) -{ - mySelectionEnabled = on; - myModel->setSelectionOptions( myModel->isPreselectionEnabled(), isSelectionEnabled() ); - - // update action state if method is called outside - - // preselection - QtxAction* a = dynamic_cast( toolMgr()->action( SwitchPreselectionId ) ); - if ( a ) { - a->setEnabled( on ); - } - - // selection - a = dynamic_cast( toolMgr()->action( SwitchSelectionId ) ); - if ( a && a->isChecked() != on ) { - a->setChecked( on ); - } -} - -/*! - \brief Switches "keyboard free" interaction style on/off -*/ -void OCCViewer_ViewWindow::onSwitchInteractionStyle( bool on ) -{ - myInteractionStyle = on ? (int)SUIT_ViewModel::KEY_FREE : (int)SUIT_ViewModel::STANDARD; - - // update action state if method is called outside - QtxAction* a = dynamic_cast( toolMgr()->action( SwitchInteractionStyleId ) ); - if ( a->isChecked() != on ) - a->setChecked( on ); -} - -/*! - \brief Toogles advanced zooming style (relatively to the cursor position) on/off -*/ -void OCCViewer_ViewWindow::onSwitchZoomingStyle( bool on ) -{ - myViewPort->setAdvancedZoomingEnabled( on ); - - // update action state if method is called outside - QtxAction* a = dynamic_cast( toolMgr()->action( SwitchZoomingStyleId ) ); - if ( a->isChecked() != on ) - a->setChecked( on ); -} - -/*! - \brief Get current interaction style - \return interaction style -*/ -int OCCViewer_ViewWindow::interactionStyle() const -{ - return myInteractionStyle; -} - -/*! - \brief Set current interaction style - \param theStyle interaction style -*/ -void OCCViewer_ViewWindow::setInteractionStyle( const int theStyle ) -{ - onSwitchInteractionStyle( theStyle == (int)SUIT_ViewModel::KEY_FREE ); -} - -/*! - \brief Get current zooming style - \return zooming style -*/ -int OCCViewer_ViewWindow::zoomingStyle() const -{ - return myViewPort->isAdvancedZoomingEnabled() ? 1 : 0; -} - -/*! - \brief Set current zooming style - \param theStyle zooming style -*/ -void OCCViewer_ViewWindow::setZoomingStyle( const int theStyle ) -{ - onSwitchZoomingStyle( theStyle == 1 ); -} - -/*! - \brief Dump view window contents to the pixmap. - \return pixmap containing all scene rendered in the window -*/ -QImage OCCViewer_ViewWindow::dumpView() -{ - Handle(V3d_View) view = myViewPort->getView(); - if ( view.IsNull() ) - return QImage(); - - int aWidth = myViewPort->width(); - int aHeight = myViewPort->height(); - QApplication::syncX(); - view->Redraw(); // In order to reactivate GL context - //view->Update(); - - OpenGLUtils_FrameBuffer aFrameBuffer; - if( aFrameBuffer.init( aWidth, aHeight ) ) - { - QImage anImage( aWidth, aHeight, QImage::Format_RGB32 ); - - glPushAttrib( GL_VIEWPORT_BIT ); - glViewport( 0, 0, aWidth, aHeight ); - aFrameBuffer.bind(); - - // draw scene - view->Redraw(); - - aFrameBuffer.unbind(); - glPopAttrib(); - - aFrameBuffer.bind(); - glReadPixels( 0, 0, aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() ); - aFrameBuffer.unbind(); - - anImage = anImage.rgbSwapped(); - anImage = anImage.mirrored(); - return anImage; - } - // if frame buffers are unsupported, use old functionality - //view->Redraw(); - - unsigned char* data = new unsigned char[ aWidth*aHeight*4 ]; - - QPoint p = myViewPort->mapFromParent(myViewPort->geometry().topLeft()); - - glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, - data); - - QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 ); - anImage = anImage.mirrored(); - anImage = anImage.rgbSwapped(); - return anImage; -} - -bool OCCViewer_ViewWindow::dumpViewToFormat( const QImage& img, - const QString& fileName, - const QString& format ) -{ - if ( format != "PS" && format != "EPS") - return SUIT_ViewWindow::dumpViewToFormat( img, fileName, format ); - - Handle(Visual3d_View) a3dView = myViewPort->getView()->View(); - - if (format == "PS") - a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_PostScript); - else if (format == "EPS") - a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_EnhPostScript); - - return true; -} - - -QString OCCViewer_ViewWindow::filter() const -{ - return tr( "OCC_IMAGE_FILES" ); -} - - -/*! - \brief Set parameters of the cutting plane - \param on if \c true, cutting plane is enabled - \param x X position of plane point - \param y Y position of plane point - \param z Z position of plane point - \param dx X coordinate of plane normal - \param dy Y coordinate of plane normal - \param dz Z coordinate of plane normal -*/ -void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x, const double y, const double z, - const double dx, const double dy, const double dz ) -{ - Handle(V3d_View) view = myViewPort->getView(); - if ( view.IsNull() ) - return; - - if ( on ) { - Handle(V3d_Viewer) viewer = myViewPort->getViewer(); - - // try to use already existing plane or create a new one - Handle(V3d_Plane) clipPlane; - - // calculate new a,b,c,d values for the plane - gp_Pln pln (gp_Pnt(x, y, z), gp_Dir(dx, dy, dz)); - double a, b, c, d; - pln.Coefficients(a, b, c, d); - - Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); - Handle(Graphic3d_ClipPlane) aClipPlane; - if(aPlanes.Size() > 0 ) { - Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); - aClipPlane = anIter.Value(); - aClipPlane->SetEquation(pln); - aClipPlane->SetOn(Standard_True); - } else { - aClipPlane = new Graphic3d_ClipPlane(pln); - view->AddClipPlane(aClipPlane); - aClipPlane->SetOn(Standard_True); - } - } - else { - Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); - Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); - for( ;anIter.More();anIter.Next() ){ - Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); - aClipPlane->SetOn(Standard_False); - } - } - - view->Update(); - view->Redraw(); -} - -void OCCViewer_ViewWindow::setCuttingPlane( bool on, const gp_Pln pln ) -{ - gp_Dir aDir = pln.Axis().Direction(); - gp_Pnt aPnt = pln.Location(); - setCuttingPlane(on, aPnt.X(), aPnt.Y(), aPnt.Z(), aDir.X(), aDir.Y(), aDir.Z()); -} - - -/*! - \brief Check if any cutting plane is enabled - \return \c true if at least one cutting plane is enabled -*/ -bool OCCViewer_ViewWindow::isCuttingPlane() -{ - Handle(V3d_View) view = myViewPort->getView(); - bool res = false; - Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); - Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); - for( ;anIter.More();anIter.Next() ) { - Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); - if(aClipPlane->IsOn()) { - res = true; - break; - } - } - return res; -} - -/*! - \brief Get the visual parameters of the view window. - \return visual parameters of view window -*/ -viewAspect OCCViewer_ViewWindow::getViewParams() const -{ - double centerX, centerY, projX, projY, projZ, twist; - double atX, atY, atZ, eyeX, eyeY, eyeZ; - double aScaleX, aScaleY, aScaleZ; - - Handle(V3d_View) aView3d = myViewPort->getView(); - - aView3d->Center( centerX, centerY ); - aView3d->Proj( projX, projY, projZ ); - aView3d->At( atX, atY, atZ ); - aView3d->Eye( eyeX, eyeY, eyeZ ); - twist = aView3d->Twist(); - - aView3d->AxialScale(aScaleX,aScaleY,aScaleZ); - - bool isShown = myModel->isTrihedronVisible(); - double size = myModel->trihedronSize(); - - QString aName = QTime::currentTime().toString() + QString::fromLatin1( " h:m:s" ); - - viewAspect params; - params.scale = aView3d->Scale(); - params.centerX = centerX; - params.centerY = centerY; - params.projX = projX; - params.projY = projY; - params.projZ = projZ; - params.twist = twist; - params.atX = atX; - params.atY = atY; - params.atZ = atZ; - params.eyeX = eyeX; - params.eyeY = eyeY; - params.eyeZ = eyeZ; - params.scaleX = aScaleX; - params.scaleY = aScaleY; - params.scaleZ = aScaleZ; - params.name = aName; - params.isVisible= isShown; - params.size = size; - -#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version - // graduated trihedron - bool anIsVisible = false; - OCCViewer_AxisWidget::AxisData anAxisData[3]; - myCubeAxesDlg->GetData( anIsVisible, anAxisData ); - - params.gtIsVisible = anIsVisible; - params.gtDrawNameX = anAxisData[0].DrawName; - params.gtDrawNameY = anAxisData[1].DrawName; - params.gtDrawNameZ = anAxisData[2].DrawName; - params.gtNameX = anAxisData[0].Name; - params.gtNameY = anAxisData[1].Name; - params.gtNameZ = anAxisData[2].Name; - params.gtNameColorRX = anAxisData[0].NameColor.red(); - params.gtNameColorGX = anAxisData[0].NameColor.green(); - params.gtNameColorBX = anAxisData[0].NameColor.blue(); - params.gtNameColorRY = anAxisData[1].NameColor.red(); - params.gtNameColorGY = anAxisData[1].NameColor.green(); - params.gtNameColorBY = anAxisData[1].NameColor.blue(); - params.gtNameColorRZ = anAxisData[2].NameColor.red(); - params.gtNameColorGZ = anAxisData[2].NameColor.green(); - params.gtNameColorBZ = anAxisData[2].NameColor.blue(); - params.gtDrawValuesX = anAxisData[0].DrawValues; - params.gtDrawValuesY = anAxisData[1].DrawValues; - params.gtDrawValuesZ = anAxisData[2].DrawValues; - params.gtNbValuesX = anAxisData[0].NbValues; - params.gtNbValuesY = anAxisData[1].NbValues; - params.gtNbValuesZ = anAxisData[2].NbValues; - params.gtOffsetX = anAxisData[0].Offset; - params.gtOffsetY = anAxisData[1].Offset; - params.gtOffsetZ = anAxisData[2].Offset; - params.gtColorRX = anAxisData[0].Color.red(); - params.gtColorGX = anAxisData[0].Color.green(); - params.gtColorBX = anAxisData[0].Color.blue(); - params.gtColorRY = anAxisData[1].Color.red(); - params.gtColorGY = anAxisData[1].Color.green(); - params.gtColorBY = anAxisData[1].Color.blue(); - params.gtColorRZ = anAxisData[2].Color.red(); - params.gtColorGZ = anAxisData[2].Color.green(); - params.gtColorBZ = anAxisData[2].Color.blue(); - params.gtDrawTickmarksX = anAxisData[0].DrawTickmarks; - params.gtDrawTickmarksY = anAxisData[1].DrawTickmarks; - params.gtDrawTickmarksZ = anAxisData[2].DrawTickmarks; - params.gtTickmarkLengthX = anAxisData[0].TickmarkLength; - params.gtTickmarkLengthY = anAxisData[1].TickmarkLength; - params.gtTickmarkLengthZ = anAxisData[2].TickmarkLength; -#endif - - return params; -} - -/*! - \brief Get visual parameters of this view window. - \return visual parameters of view window -*/ -QString OCCViewer_ViewWindow::getVisualParameters() -{ - viewAspect params = getViewParams(); - - QStringList data; - - data << QString( "scale=%1" ) .arg( params.scale, 0, 'e', 12 ); - data << QString( "centerX=%1" ) .arg( params.centerX, 0, 'e', 12 ); - data << QString( "centerY=%1" ) .arg( params.centerY, 0, 'e', 12 ); - data << QString( "projX=%1" ) .arg( params.projX, 0, 'e', 12 ); - data << QString( "projY=%1" ) .arg( params.projY, 0, 'e', 12 ); - data << QString( "projZ=%1" ) .arg( params.projZ, 0, 'e', 12 ); - data << QString( "twist=%1" ) .arg( params.twist, 0, 'e', 12 ); - data << QString( "atX=%1" ) .arg( params.atX, 0, 'e', 12 ); - data << QString( "atY=%1" ) .arg( params.atY, 0, 'e', 12 ); - data << QString( "atZ=%1" ) .arg( params.atZ, 0, 'e', 12 ); - data << QString( "eyeX=%1" ) .arg( params.eyeX, 0, 'e', 12 ); - data << QString( "eyeY=%1" ) .arg( params.eyeY, 0, 'e', 12 ); - data << QString( "eyeZ=%1" ) .arg( params.eyeZ, 0, 'e', 12 ); - data << QString( "scaleX=%1" ) .arg( params.scaleX, 0, 'e', 12 ); - data << QString( "scaleY=%1" ) .arg( params.scaleY, 0, 'e', 12 ); - data << QString( "scaleZ=%1" ) .arg( params.scaleZ, 0, 'e', 12 ); - data << QString( "isVisible=%1" ).arg( params.isVisible ); - data << QString( "size=%1" ) .arg( params.size, 0, 'f', 2 ); - - ClipPlanesList aPlanes = myModel->getClipPlanes(); - for ( int i=0; i < aPlanes.size(); i++ ) { - OCCViewer_ClipPlane& aPlane = aPlanes[i]; - QString ClippingPlane = QString( "ClippingPlane%1=").arg( i+1 ); - ClippingPlane += QString( "Mode~%1;").arg( (int)aPlane.PlaneMode ); - ClippingPlane += QString( "IsActive~%1;").arg( aPlane.IsOn ); - 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 ); - 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 ); - data << QString( "gtDrawNameX=%1" ) .arg( params.gtDrawNameX ); - data << QString( "gtDrawNameY=%1" ) .arg( params.gtDrawNameY ); - data << QString( "gtDrawNameZ=%1" ) .arg( params.gtDrawNameZ ); - data << QString( "gtNameX=%1" ) .arg( params.gtNameX ); - data << QString( "gtNameY=%1" ) .arg( params.gtNameY ); - data << QString( "gtNameZ=%1" ) .arg( params.gtNameZ ); - data << QString( "gtNameColorRX=%1" ) .arg( params.gtNameColorRX ); - data << QString( "gtNameColorGX=%1" ) .arg( params.gtNameColorGX ); - data << QString( "gtNameColorBX=%1" ) .arg( params.gtNameColorBX ); - data << QString( "gtNameColorRY=%1" ) .arg( params.gtNameColorRY ); - data << QString( "gtNameColorGY=%1" ) .arg( params.gtNameColorGY ); - data << QString( "gtNameColorBY=%1" ) .arg( params.gtNameColorBY ); - data << QString( "gtNameColorRZ=%1" ) .arg( params.gtNameColorRZ ); - data << QString( "gtNameColorGZ=%1" ) .arg( params.gtNameColorGZ ); - data << QString( "gtNameColorBZ=%1" ) .arg( params.gtNameColorBZ ); - data << QString( "gtDrawValuesX=%1" ) .arg( params.gtDrawValuesX ); - data << QString( "gtDrawValuesY=%1" ) .arg( params.gtDrawValuesY ); - data << QString( "gtDrawValuesZ=%1" ) .arg( params.gtDrawValuesZ ); - data << QString( "gtNbValuesX=%1" ) .arg( params.gtNbValuesX ); - data << QString( "gtNbValuesY=%1" ) .arg( params.gtNbValuesY ); - data << QString( "gtNbValuesZ=%1" ) .arg( params.gtNbValuesZ ); - data << QString( "gtOffsetX=%1" ) .arg( params.gtOffsetX ); - data << QString( "gtOffsetY=%1" ) .arg( params.gtOffsetY ); - data << QString( "gtOffsetZ=%1" ) .arg( params.gtOffsetZ ); - data << QString( "gtColorRX=%1" ) .arg( params.gtColorRX ); - data << QString( "gtColorGX=%1" ) .arg( params.gtColorGX ); - data << QString( "gtColorBX=%1" ) .arg( params.gtColorBX ); - data << QString( "gtColorRY=%1" ) .arg( params.gtColorRY ); - data << QString( "gtColorGY=%1" ) .arg( params.gtColorGY ); - data << QString( "gtColorBY=%1" ) .arg( params.gtColorBY ); - data << QString( "gtColorRZ=%1" ) .arg( params.gtColorRZ ); - data << QString( "gtColorGZ=%1" ) .arg( params.gtColorGZ ); - data << QString( "gtColorBZ=%1" ) .arg( params.gtColorBZ ); - data << QString( "gtDrawTickmarksX=%1" ) .arg( params.gtDrawTickmarksX ); - data << QString( "gtDrawTickmarksY=%1" ) .arg( params.gtDrawTickmarksY ); - data << QString( "gtDrawTickmarksZ=%1" ) .arg( params.gtDrawTickmarksZ ); - data << QString( "gtTickmarkLengthX=%1" ).arg( params.gtTickmarkLengthX ); - data << QString( "gtTickmarkLengthY=%1" ).arg( params.gtTickmarkLengthY ); - data << QString( "gtTickmarkLengthZ=%1" ).arg( params.gtTickmarkLengthZ ); -#endif - QString bg = Qtx::backgroundToString( background() ).replace( "=", "$" ); - data << QString( "background=%1" ).arg( bg ); - - return data.join("*"); -} - -/*! - \brief Restore visual parameters of the view window. - \param parameters visual parameters of view window -*/ -void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters ) -{ - viewAspect params; - ClipPlanesList aClipPlanes; - QStringList data = parameters.split( '*' ); - Qtx::BackgroundData bgData; - if ( parameters.contains( '=' ) ) // new format - "scale=1.000e+00*centerX=0.000e+00..." - { - foreach( QString param, data ) { - QString paramName = param.section( '=', 0, 0 ).trimmed(); - QString paramValue = param.section( '=', 1, 1 ).trimmed(); - if ( paramName == "scale" ) params.scale = paramValue.toDouble(); - else if ( paramName == "centerX" ) params.centerX = paramValue.toDouble(); - else if ( paramName == "centerY" ) params.centerY = paramValue.toDouble(); - else if ( paramName == "projX" ) params.projX = paramValue.toDouble(); - else if ( paramName == "projY" ) params.projY = paramValue.toDouble(); - else if ( paramName == "projZ" ) params.projZ = paramValue.toDouble(); - else if ( paramName == "twist" ) params.twist = paramValue.toDouble(); - else if ( paramName == "atX" ) params.atX = paramValue.toDouble(); - else if ( paramName == "atY" ) params.atY = paramValue.toDouble(); - else if ( paramName == "atZ" ) params.atZ = paramValue.toDouble(); - else if ( paramName == "eyeX" ) params.eyeX = paramValue.toDouble(); - else if ( paramName == "eyeY" ) params.eyeY = paramValue.toDouble(); - else if ( paramName == "eyeZ" ) params.eyeZ = paramValue.toDouble(); - else if ( paramName == "scaleX" ) params.scaleX = paramValue.toDouble(); - else if ( paramName == "scaleY" ) params.scaleY = paramValue.toDouble(); - 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" ) ) { - QStringList ClipPlaneData = paramValue.split( ';' ); - OCCViewer_ClipPlane aPlane; - 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 = ( ClipPlaneMode )ClipPlane_paramValue.toInt(); - else if ( ClipPlane_paramName == "IsActive" ) aPlane.IsOn = 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(); - } - aClipPlanes.push_back(aPlane); - } - // graduated trihedron - else if ( paramName == "gtIsVisible" ) params.gtIsVisible = paramValue.toInt(); - else if ( paramName == "gtDrawNameX" ) params.gtDrawNameX = paramValue.toInt(); - else if ( paramName == "gtDrawNameY" ) params.gtDrawNameY = paramValue.toInt(); - else if ( paramName == "gtDrawNameZ" ) params.gtDrawNameZ = paramValue.toInt(); - else if ( paramName == "gtNameX" ) params.gtNameX = paramValue; - else if ( paramName == "gtNameY" ) params.gtNameY = paramValue; - else if ( paramName == "gtNameZ" ) params.gtNameZ = paramValue; - else if ( paramName == "gtNameColorRX" ) params.gtNameColorRX = paramValue.toInt(); - else if ( paramName == "gtNameColorGX" ) params.gtNameColorGX = paramValue.toInt(); - else if ( paramName == "gtNameColorBX" ) params.gtNameColorBX = paramValue.toInt(); - else if ( paramName == "gtNameColorRY" ) params.gtNameColorRY = paramValue.toInt(); - else if ( paramName == "gtNameColorGY" ) params.gtNameColorGY = paramValue.toInt(); - else if ( paramName == "gtNameColorBY" ) params.gtNameColorBY = paramValue.toInt(); - else if ( paramName == "gtNameColorRZ" ) params.gtNameColorRZ = paramValue.toInt(); - else if ( paramName == "gtNameColorGZ" ) params.gtNameColorGZ = paramValue.toInt(); - else if ( paramName == "gtNameColorBZ" ) params.gtNameColorBZ = paramValue.toInt(); - else if ( paramName == "gtDrawValuesX" ) params.gtDrawValuesX = paramValue.toInt(); - else if ( paramName == "gtDrawValuesY" ) params.gtDrawValuesY = paramValue.toInt(); - else if ( paramName == "gtDrawValuesZ" ) params.gtDrawValuesZ = paramValue.toInt(); - else if ( paramName == "gtNbValuesX" ) params.gtNbValuesX = paramValue.toInt(); - else if ( paramName == "gtNbValuesY" ) params.gtNbValuesY = paramValue.toInt(); - else if ( paramName == "gtNbValuesZ" ) params.gtNbValuesZ = paramValue.toInt(); - else if ( paramName == "gtOffsetX" ) params.gtOffsetX = paramValue.toInt(); - else if ( paramName == "gtOffsetY" ) params.gtOffsetY = paramValue.toInt(); - else if ( paramName == "gtOffsetZ" ) params.gtOffsetZ = paramValue.toInt(); - else if ( paramName == "gtColorRX" ) params.gtColorRX = paramValue.toInt(); - else if ( paramName == "gtColorGX" ) params.gtColorGX = paramValue.toInt(); - else if ( paramName == "gtColorBX" ) params.gtColorBX = paramValue.toInt(); - else if ( paramName == "gtColorRY" ) params.gtColorRY = paramValue.toInt(); - else if ( paramName == "gtColorGY" ) params.gtColorGY = paramValue.toInt(); - else if ( paramName == "gtColorBY" ) params.gtColorBY = paramValue.toInt(); - else if ( paramName == "gtColorRZ" ) params.gtColorRZ = paramValue.toInt(); - else if ( paramName == "gtColorGZ" ) params.gtColorGZ = paramValue.toInt(); - else if ( paramName == "gtColorBZ" ) params.gtColorBZ = paramValue.toInt(); - else if ( paramName == "gtDrawTickmarksX" ) params.gtDrawTickmarksX = paramValue.toInt(); - else if ( paramName == "gtDrawTickmarksY" ) params.gtDrawTickmarksY = paramValue.toInt(); - else if ( paramName == "gtDrawTickmarksZ" ) params.gtDrawTickmarksZ = paramValue.toInt(); - else if ( paramName == "gtTickmarkLengthX" ) params.gtTickmarkLengthX = paramValue.toInt(); - else if ( paramName == "gtTickmarkLengthY" ) params.gtTickmarkLengthY = paramValue.toInt(); - else if ( paramName == "gtTickmarkLengthZ" ) params.gtTickmarkLengthZ = paramValue.toInt(); - else if ( paramName == "background" ) { - QString bg = paramValue.replace( "$", "=" ); - bgData = Qtx::stringToBackground( bg ); - } - } - } - else // old format - "1.000e+00*0.000e+00..." - { - int idx = 0; - params.scale = data.count() > idx ? data[idx++].toDouble() : 1.0; - params.centerX = data.count() > idx ? data[idx++].toDouble() : 0.0; - params.centerY = data.count() > idx ? data[idx++].toDouble() : 0.0; - params.projX = data.count() > idx ? data[idx++].toDouble() : sqrt(1./3); - params.projY = data.count() > idx ? data[idx++].toDouble() : -sqrt(1./3); - params.projZ = data.count() > idx ? data[idx++].toDouble() : sqrt(1./3); - params.twist = data.count() > idx ? data[idx++].toDouble() : 0.0; - params.atX = data.count() > idx ? data[idx++].toDouble() : 0.0; - params.atY = data.count() > idx ? data[idx++].toDouble() : 0.0; - params.atZ = data.count() > idx ? data[idx++].toDouble() : 0.0; - params.eyeX = data.count() > idx ? data[idx++].toDouble() : sqrt(250000./3); - params.eyeY = data.count() > idx ? data[idx++].toDouble() : -sqrt(250000./3); - params.eyeZ = data.count() > idx ? data[idx++].toDouble() : sqrt(250000./3); - params.scaleX = data.count() > idx ? data[idx++].toDouble() : 1.0; - params.scaleY = data.count() > idx ? data[idx++].toDouble() : 1.0; - params.scaleZ = data.count() > idx ? data[idx++].toDouble() : 1.0; - params.isVisible = data.count() > idx ? data[idx++].toInt() : 1; - params.size = data.count() > idx ? data[idx++].toDouble() : 100.0; - } - performRestoring( params ); - setBackground( bgData ); - myModel->setClipPlanes(aClipPlanes); -} - -/*! - \brief Handle show event. - - Emits Show() signal. - - \param theEvent show event -*/ -void OCCViewer_ViewWindow::showEvent( QShowEvent* theEvent ) -{ - emit Show( theEvent ); -} - -/*! - \brief Handle hide event. - - Emits Hide() signal. - - \param theEvent hide event -*/ -void OCCViewer_ViewWindow::hideEvent( QHideEvent* theEvent ) -{ - emit Hide( theEvent ); -} - - -/*! - Creates default sketcher. [ virtual protected ] -*/ -OCCViewer_ViewSketcher* OCCViewer_ViewWindow::createSketcher( int type ) -{ - if ( type == Rect ) - return new OCCViewer_RectSketcher( this, type ); - if ( type == Polygon ) - return new OCCViewer_PolygonSketcher( this, type ); - return 0; -} - -void OCCViewer_ViewWindow::initSketchers() -{ - if ( mySketchers.isEmpty() ) - { - mySketchers.append( createSketcher( Rect ) ); - mySketchers.append( createSketcher( Polygon ) ); - } -} - -OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ ) -{ - OCCViewer_ViewSketcher* sketcher = 0; - QList::Iterator it; - for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) - { - OCCViewer_ViewSketcher* sk = (*it); - if ( sk->type() == typ ) - sketcher = sk; - } - return sketcher; -} - -/*! - Handles requests for sketching in the active view. [ virtual public ] -*/ -void OCCViewer_ViewWindow::activateSketching( int type ) -{ - OCCViewer_ViewPort3d* vp = getViewPort(); - if ( !vp ) - return; - - if ( !vp->isSketchingEnabled() ) - return; - - /* Finish current sketching */ - if ( type == NoSketching ) - { - if ( mypSketcher ) - { - onSketchingFinished(); - mypSketcher->deactivate(); - mypSketcher = 0; - } - } - /* Activate new sketching */ - else - { - activateSketching( NoSketching ); /* concurrency not suported */ - mypSketcher = getSketcher( type ); - if ( mypSketcher ) - { - mypSketcher->activate(); - onSketchingStarted(); - } - } -} - -/*! - Unhilights detected entities. [ virtual protected ] -*/ -void OCCViewer_ViewWindow::onSketchingStarted() -{ -} - -/*! - Selection by rectangle or polygon. [ virtual protected ] -*/ -void OCCViewer_ViewWindow::onSketchingFinished() -{ - MESSAGE("OCCViewer_ViewWindow::onSketchingFinished()") - if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept ) - { - Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - bool append = bool( mypSketcher->buttonState() && mypSketcher->isHasShift() ); - switch( mypSketcher->type() ) - { - case Rect: - { - QRect* aRect = (QRect*)mypSketcher->data(); - if( aRect ) - { - int aLeft = aRect->left(); - int aRight = aRect->right(); - int aTop = aRect->top(); - int aBottom = aRect->bottom(); -// myRect = aRect; - - if( append ) - ic->ShiftSelect( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False ); - else - ic->Select( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False ); - } - } - break; - case Polygon: - { - QPolygon* aPolygon = (QPolygon*)mypSketcher->data(); - if( aPolygon ) - { - int size = aPolygon->size(); - TColgp_Array1OfPnt2d anArray( 1, size ); - - QPolygon::Iterator it = aPolygon->begin(); - QPolygon::Iterator itEnd = aPolygon->end(); - for( int index = 1; it != itEnd; ++it, index++ ) - { - QPoint aPoint = *it; - anArray.SetValue( index, gp_Pnt2d( aPoint.x(), aPoint.y() ) ); - } - - if( append ) - ic->ShiftSelect( anArray, getViewPort()->getView(), Standard_False ); - else - ic->Select( anArray, getViewPort()->getView(), Standard_False ); - } - } - break; - default: - break; - } - - OCCViewer_ViewManager* aViewMgr = ( OCCViewer_ViewManager* )getViewManager(); - aViewMgr->getOCCViewer()->performSelectionChanged(); - } -} - -OCCViewer_ViewPort3d* OCCViewer_ViewWindow::getViewPort() -{ - return myViewPort; -} - -bool OCCViewer_ViewWindow::transformRequested() const -{ - return ( myOperation != NOTHING ); -} - -bool OCCViewer_ViewWindow::transformInProcess() const -{ - return myEventStarted; -} - -void OCCViewer_ViewWindow::setTransformInProcess( bool bOn ) -{ - myEventStarted = bOn; -} - -/*! - Set enabled state of transformation (rotate, zoom, etc) -*/ -void OCCViewer_ViewWindow::setTransformEnabled( const OperationType id, const bool on ) -{ - if ( id != NOTHING ) myStatus.insert( id, on ); -} - -/*! - \return enabled state of transformation (rotate, zoom, etc) -*/ -bool OCCViewer_ViewWindow::transformEnabled( const OperationType id ) const -{ - return myStatus.contains( id ) ? myStatus[ id ] : true; -} - -void OCCViewer_ViewWindow::onMaximizedView() -{ - setMaximized(!isMaximized()); -} - -void OCCViewer_ViewWindow::returnTo3dView() -{ - setReturnedTo3dView( true ); -} - -void OCCViewer_ViewWindow::setReturnedTo3dView(bool isVisible3dView) -{ - if ( !toolMgr()->action( ReturnTo3dViewId ) || - toolMgr()->isShown(ReturnTo3dViewId) != isVisible3dView ) return; - if ( !isVisible3dView ) - toolMgr()->show( ReturnTo3dViewId ); - else - toolMgr()->hide( ReturnTo3dViewId ); - if ( isVisible3dView ) emit returnedTo3d( ); -} - - -void OCCViewer_ViewWindow::setMaximized(bool toMaximize, bool toSendSignal) -{ - QAction* anAction = toolMgr()->action( MaximizedId ); - QAction* anAction2 = toolMgr()->action( ReturnTo3dViewId ); - SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); - if ( toMaximize ) { - anAction->setText( tr( "MNU_MINIMIZE_VIEW" ) ); - anAction->setToolTip( tr( "MNU_MINIMIZE_VIEW" ) ); - anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ) ); - anAction->setStatusTip( tr( "DSC_MINIMIZE_VIEW" ) ); - if ( anAction2 && my2dMode != No2dMode ) toolMgr()->show( ReturnTo3dViewId ); - if (toSendSignal) { - emit maximized( this, true ); - } - } - else { - anAction->setText( tr( "MNU_MAXIMIZE_VIEW" ) ); - anAction->setToolTip( tr( "MNU_MAXIMIZE_VIEW" ) ); - anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MAXIMIZE" ) ) ); - anAction->setStatusTip( tr( "DSC_MAXIMIZE_VIEW" ) ); - if ( anAction2 && my2dMode != No2dMode ) toolMgr()->hide( ReturnTo3dViewId ); - if (toSendSignal) { - emit maximized( this, false ); - } - } -} - -bool OCCViewer_ViewWindow::isMaximized() const -{ - return !(toolMgr()->action( MaximizedId )->text() == tr( "MNU_MAXIMIZE_VIEW" )); -} - -void OCCViewer_ViewWindow::setSketcherStyle( bool enable ) -{ - IsSketcherStyle = enable; -} - -bool OCCViewer_ViewWindow::isSketcherStyle() const -{ - return IsSketcherStyle; -} - - -void OCCViewer_ViewWindow::set2dMode(Mode2dType theType) -{ - my2dMode = theType; -} - -// obsolete -QColor OCCViewer_ViewWindow::backgroundColor() const -{ - return myViewPort ? myViewPort->backgroundColor() : Qt::black; -} - -// obsolete -void OCCViewer_ViewWindow::setBackgroundColor( const QColor& theColor ) -{ - if ( myViewPort ) myViewPort->setBackgroundColor( theColor ); -} - -Qtx::BackgroundData OCCViewer_ViewWindow::background() const -{ - return myViewPort ? myViewPort->background() : Qtx::BackgroundData(); -} - -void OCCViewer_ViewWindow::setBackground( const Qtx::BackgroundData& theBackground ) -{ - if ( myViewPort ) myViewPort->setBackground( theBackground ); -} - -/*! - Clears view aspects -*/ -void OCCViewer_ViewWindow::clearViewAspects() -{ - myViewAspects.clear(); -} - -/*! - \return const reference to list of view aspects -*/ -const viewAspectList& OCCViewer_ViewWindow::getViewAspects() -{ - return myViewAspects; -} - -/*! - Appends new view aspect - \param aParams - new view aspects -*/ -void OCCViewer_ViewWindow::appendViewAspect( const viewAspect& aParams ) -{ - myViewAspects.append( aParams ); -} - -/*! - Replaces old view aspects by new ones - \param aViewList - list of new view aspects -*/ -void OCCViewer_ViewWindow::updateViewAspects( const viewAspectList& aViewList ) -{ - myViewAspects = aViewList; -} - -/*! - Get camera properties for the OCC view window. - \return shared pointer on camera properties. -*/ -SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties() -{ - SUIT_CameraProperties aProps; - - Handle(V3d_View) aSourceView = getViewPort()->getView(); - if ( aSourceView.IsNull() ) - return aProps; - - if ( get2dMode() == No2dMode ) { - aProps.setDimension( SUIT_CameraProperties::Dim3D ); - } - else { - aProps.setDimension( SUIT_CameraProperties::Dim2D ); - aProps.setViewSide( (SUIT_CameraProperties::ViewSide)(int)get2dMode() ); - } - - // read common properites of the view - Standard_Real anUpDir[3]; - Standard_Real aPrjDir[3]; - Standard_Real aMapScale[2]; - Standard_Real aTranslation[3]; - Standard_Real anAxialScale[3]; - - aSourceView->Up(anUpDir[0], anUpDir[1], anUpDir[2]); - aSourceView->Proj(aPrjDir[0], aPrjDir[1], aPrjDir[2]); - aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]); - aSourceView->Size(aMapScale[0], aMapScale[1]); - - getViewPort()->getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); - - // we use similar depth to the one used in perspective projection - // to proivde a convinience synchronization with other camera views that - // can switch between orthogonal & perspective projection. otherwise, - // the camera will get to close when switching from orthogonal to perspective. - Standard_Real aCameraDepth = aSourceView->Depth() + aSourceView->ZSize() * 0.5; - - // store common props - aProps.setViewUp(anUpDir[0], anUpDir[1], anUpDir[2]); - aProps.setMappingScale(aMapScale[1] / 2.0); - aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); - - // generate view orientation matrix for transforming OCC projection reference point - // into a camera (eye) position. - gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed( - gp_Dir(aPrjDir[0], aPrjDir[1], aPrjDir[2])); - - gp_Trsf aTrsf; - aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aPrjDir[0], aTranslation[0], - aLeftDir.Y(), anUpDir[1], aPrjDir[1], aTranslation[1], - aLeftDir.Z(), anUpDir[2], aPrjDir[2], aTranslation[2], - Precision::Confusion(), - Precision::Confusion() ); - -// get projection reference point in view coordinates -#if OCC_VERSION_LARGE > 0x06070000 - gp_Pnt aProjRef = aSourceView->Camera()->ProjectionShift(); - aProjRef.SetX( -aProjRef.X() ); - aProjRef.SetY( -aProjRef.Y() ); -#else - Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint(); -#endif - - // transform to world-space coordinate system - gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aCameraDepth).Transformed(aTrsf); - - // compute focal point - double aFocalPoint[3]; - - aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aCameraDepth; - aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aCameraDepth; - aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aCameraDepth; - - aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]); - aProps.setPosition(aPosition.X(), aPosition.Y(), aPosition.Z()); - - return aProps; -} - -/*! - Synchronize views. - This implementation synchronizes OCC view's camera propreties. -*/ -void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView ) -{ - bool blocked = blockSignals( true ); - - SUIT_CameraProperties aProps = theView->cameraProperties(); - if ( !cameraProperties().isCompatible( aProps ) ) { - // other view, this one is being currently synchronized to, seems has become incompatible - // we have to break synchronization - updateSyncViews(); - return; - } - - Handle(V3d_View) aDestView = getViewPort()->getView(); - - aDestView->SetImmediateUpdate( Standard_False ); - - double anUpDir[3]; - double aPosition[3]; - double aFocalPoint[3]; - double aMapScaling; - double anAxialScale[3]; - - // get common properties - aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]); - aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]); - aProps.getViewUp(anUpDir[0], anUpDir[1], anUpDir[2]); - aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); - aMapScaling = aProps.getMappingScale() * 2.0; - - gp_Dir aProjDir(aPosition[0] - aFocalPoint[0], - aPosition[1] - aFocalPoint[1], - aPosition[2] - aFocalPoint[2]); - - // get custom view translation - Standard_Real aTranslation[3]; - aDestView->At(aTranslation[0], aTranslation[1], aTranslation[2]); - - gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed( - gp_Dir(aProjDir.X(), aProjDir.Y(), aProjDir.Z())); - - // convert camera position into a view reference point - gp_Trsf aTrsf; - aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aProjDir.X(), aTranslation[0], - aLeftDir.Y(), anUpDir[1], aProjDir.Y(), aTranslation[1], - aLeftDir.Z(), anUpDir[2], aProjDir.Z(), aTranslation[2], - Precision::Confusion(), - Precision::Confusion() ); - aTrsf.Invert(); - - // transform to view-space coordinate system - gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]); - aProjRef.Transform(aTrsf); - -#if OCC_VERSION_LARGE > 0x06070000 - aDestView->Camera()->SetDirection( -aProjDir ); - aDestView->Camera()->SetUp( gp_Dir( anUpDir[0], anUpDir[1], anUpDir[2] ) ); - aDestView->Camera()->SetProjectionShift( gp_Pnt( -aProjRef.X(), -aProjRef.Y(), 0.0 ) ); -#else - // set view camera properties using low-level approach. this is done - // in order to avoid interference with static variables in v3d view used - // when rotation is in process in another view. - Visual3d_ViewMapping aMapping = aDestView->View()->ViewMapping(); - Visual3d_ViewOrientation anOrientation = aDestView->View()->ViewOrientation(); - - Graphic3d_Vector aMappingProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z()); - Graphic3d_Vector aMappingUp(anUpDir[0], anUpDir[1], anUpDir[2]); - - aMappingProj.Normalize(); - aMappingUp.Normalize(); - - anOrientation.SetViewReferencePlane(aMappingProj); - anOrientation.SetViewReferenceUp(aMappingUp); - - aDestView->SetViewMapping(aMapping); - aDestView->SetViewOrientation(anOrientation); - - // set panning - aDestView->SetCenter(aProjRef.X(), aProjRef.Y()); -#endif - - // set mapping scale - Standard_Real aWidth, aHeight; - aDestView->Size(aWidth, aHeight); - - if ( aWidth > aHeight ) - aDestView->SetSize (aMapScaling * (aWidth / aHeight)); - else - aDestView->SetSize (aMapScaling); - - getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); - - aDestView->ZFitAll(); - aDestView->SetImmediateUpdate( Standard_True ); - aDestView->Redraw(); - - blockSignals( blocked ); -} - -/*! - \brief Indicates whether preselection is enabled - \return true if preselection is enabled -*/ -bool OCCViewer_ViewWindow::isPreselectionEnabled() const -{ - return myPreselectionEnabled; -} - -/*! - \brief Enables/disables preselection - \param theIsToEnable if true - preselection will be enabled -*/ -void OCCViewer_ViewWindow::enablePreselection( bool theIsToEnable ) -{ - onSwitchPreselection( theIsToEnable ); -} - -/*! - \brief Indicates whether selection is enabled - \return true if selection is enabled -*/ -bool OCCViewer_ViewWindow::isSelectionEnabled() const -{ - return mySelectionEnabled; -} - -/*! - \brief Enables/disables selection - \param theIsToEnable if true - selection will be enabled -*/ -void OCCViewer_ViewWindow::enableSelection( bool theIsToEnable ) -{ - onSwitchSelection( theIsToEnable ); -} - - -/*! - \brief called if clipping operation is activated / deactivated. - - Enables/disables clipping plane displaying. - - \parma on action state -*/ -void OCCViewer_ViewWindow::onClipping (bool theIsOn) -{ - if(!myModel) return; - OCCViewer_ClippingDlg* aClippingDlg = myModel->getClippingDlg(); - - if (theIsOn) { - if (!aClippingDlg) { - aClippingDlg = new OCCViewer_ClippingDlg (this, myModel); - myModel->setClippingDlg(aClippingDlg); - } - if (!aClippingDlg->isVisible()) - aClippingDlg->show(); - } else { - if ( aClippingDlg ) { - aClippingDlg->close(); - myModel->setClippingDlg(0); - } - } - - SUIT_ViewManager* mgr = getViewManager(); - if( mgr ) { - QVector aViews = mgr->getViews(); - for(int i = 0, iEnd = aViews.size(); i < iEnd; i++) { - if(SUIT_ViewWindow* aViewWindow = aViews.at(i)) { - QtxActionToolMgr* mgr = aViewWindow->toolMgr(); - if(!mgr) continue; - QAction* a = toolMgr()->action( ClippingId ); - if(!a) continue; - if(theIsOn != a->isChecked()){ - disconnect (a, SIGNAL (toggled (bool)), aViewWindow, SLOT (onClipping (bool))); - a->setChecked(theIsOn); - connect (a, SIGNAL (toggled (bool)), aViewWindow, SLOT (onClipping (bool))); - } - } - } - } -} +// 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 +// +// 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : OCCViewer_ViewWindow.cxx +// Author : + +#include "OCCViewer_ViewWindow.h" +#include "OCCViewer_ViewModel.h" +#include "OCCViewer_ViewPort3d.h" +#include "OCCViewer_ViewManager.h" +#include "OCCViewer_ViewSketcher.h" +#include "OCCViewer_CreateRestoreViewDlg.h" +#include "OCCViewer_ClipPlane.h" +#include "OCCViewer_SetRotationPointDlg.h" +#include "OCCViewer_AxialScaleDlg.h" +#include "OCCViewer_CubeAxesDlg.h" +#include "OCCViewer_ClippingDlg.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#if OCC_VERSION_LARGE > 0x06060000 +#include +#include + +#endif + +#include + +#include "utilities.h" + +// // OpenCV includes +// #include +// #include + +static QEvent* l_mbPressEvent = 0; + +#ifdef WIN32 +# include +#endif + +#include + +const char* imageZoomCursor[] = { +"32 32 3 1", +". c None", +"a c #000000", +"# c #ffffff", +"................................", +"................................", +".#######........................", +"..aaaaaaa.......................", +"................................", +".............#####..............", +"...........##.aaaa##............", +"..........#.aa.....a#...........", +".........#.a.........#..........", +".........#a..........#a.........", +"........#.a...........#.........", +"........#a............#a........", +"........#a............#a........", +"........#a............#a........", +"........#a............#a........", +".........#...........#.a........", +".........#a..........#a.........", +".........##.........#.a.........", +"........#####.....##.a..........", +".......###aaa#####.aa...........", +"......###aa...aaaaa.......#.....", +".....###aa................#a....", +"....###aa.................#a....", +"...###aa...............#######..", +"....#aa.................aa#aaaa.", +".....a....................#a....", +"..........................#a....", +"...........................a....", +"................................", +"................................", +"................................", +"................................"}; + +const char* imageRotateCursor[] = { +"32 32 3 1", +". c None", +"a c #000000", +"# c #ffffff", +"................................", +"................................", +"................................", +"................................", +"........#.......................", +".......#.a......................", +"......#######...................", +".......#aaaaa#####..............", +"........#..##.a#aa##........##..", +".........a#.aa..#..a#.....##.aa.", +".........#.a.....#...#..##.aa...", +".........#a.......#..###.aa.....", +"........#.a.......#a..#aa.......", +"........#a.........#..#a........", +"........#a.........#a.#a........", +"........#a.........#a.#a........", +"........#a.........#a.#a........", +".........#.........#a#.a........", +"........##a........#a#a.........", +"......##.a#.......#.#.a.........", +"....##.aa..##.....##.a..........", +"..##.aa.....a#####.aa...........", +"...aa.........aaa#a.............", +"................#.a.............", +"...............#.a..............", +"..............#.a...............", +"...............a................", +"................................", +"................................", +"................................", +"................................", +"................................"}; + +const char* imageCrossCursor[] = { + "32 32 3 1", + ". c None", + "a c #000000", + "# c #ffffff", + "................................", + "................................", + "................................", + "................................", + "................................", + "................................", + "................................", + "...............#................", + "...............#a...............", + "...............#a...............", + "...............#a...............", + "...............#a...............", + "...............#a...............", + "...............#a...............", + "...............#a...............", + ".......#################........", + "........aaaaaaa#aaaaaaaaa.......", + "...............#a...............", + "...............#a...............", + "...............#a...............", + "...............#a...............", + "...............#a...............", + "...............#a...............", + "...............#a...............", + "................a...............", + "................................", + "................................", + "................................", + "................................", + "................................", + "................................", + "................................"}; + + +/*! + \brief Constructor + \param theDesktop main window of application + \param theModel OCC 3D viewer +*/ +OCCViewer_ViewWindow::OCCViewer_ViewWindow( SUIT_Desktop* theDesktop, + OCCViewer_Viewer* theModel ) +: SUIT_ViewWindow( theDesktop ) +{ + myModel = theModel; + myRestoreFlag = 0; + myEnableDrawMode = false; + myDrawRect=false; + updateEnabledDrawMode(); + myScalingDlg = 0; + mySetRotationPointDlg = 0; + myRectBand = 0; + + IsSketcherStyle = false; + myIsKeyFree = false; + + mypSketcher = 0; + myCurSketch = -1; + my2dMode = No2dMode; + + myInteractionStyle = SUIT_ViewModel::STANDARD; + myPreselectionEnabled = true; + mySelectionEnabled = true; + + + clearViewAspects(); + +} + +/*! + \brief Destructor. +*/ +OCCViewer_ViewWindow::~OCCViewer_ViewWindow() +{ + endDrawRect(); + qDeleteAll( mySketchers ); +} + +/*! + \brief Internal initialization. +*/ +void OCCViewer_ViewWindow::initLayout() +{ + myViewPort = new OCCViewer_ViewPort3d( this, myModel->getViewer3d(), V3d_ORTHOGRAPHIC ); + myViewPort->installEventFilter(this); + setCentralWidget(myViewPort); + myOperation = NOTHING; + + myCurrPointType = GRAVITY; + myPrevPointType = GRAVITY; + mySelectedPoint = gp_Pnt(0.,0.,0.); + myRotationPointSelection = false; + + setTransformRequested ( NOTHING ); + setTransformInProcess ( false ); + + createActions(); + createToolBar(); + + switch (my2dMode) { + case XYPlane: + onTopView(); + break; + case XZPlane: + onLeftView(); + break; + case YZPlane: + onFrontView(); + break; + } + + // Graduated axes dialog + QtxAction* anAction = dynamic_cast( toolMgr()->action( GraduatedAxesId ) ); + myCubeAxesDlg = new OCCViewer_CubeAxesDlg( anAction, this, "OCCViewer_CubeAxesDlg" ); + myCubeAxesDlg->initialize(); + + connect( myViewPort, SIGNAL( vpTransformed( OCCViewer_ViewPort* ) ), this, SLOT( emitViewModified() ) ); +} + +OCCViewer_ViewWindow* OCCViewer_ViewWindow::getView( const int mode ) const +{ + return mode == get2dMode() ? const_cast( this ) : 0; +} + +/*! + \brief Detect viewer operation according the the mouse button pressed + and key modifiers used. + \param theEvent mouse event + \return type of the operation +*/ +OCCViewer_ViewWindow::OperationType +OCCViewer_ViewWindow::getButtonState( QMouseEvent* theEvent, int theInteractionStyle ) +{ + OperationType aOp = NOTHING; + SUIT_ViewModel::InteractionStyle aStyle = (SUIT_ViewModel::InteractionStyle)theInteractionStyle; + if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::ZOOM]) && + (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::ZOOM]) ) + aOp = ZOOMVIEW; + else if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::PAN]) && + (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::PAN]) ) + aOp = PANVIEW; + else if( (theEvent->modifiers() == SUIT_ViewModel::myStateMap[aStyle][SUIT_ViewModel::ROTATE]) && + (theEvent->buttons() == SUIT_ViewModel::myButtonMap[aStyle][SUIT_ViewModel::ROTATE]) && + (my2dMode == No2dMode)) + aOp = ROTATE; + + return aOp; +} + +/*! + \brief Customize event handling + \param watched event receiver object + \param e event + \return \c true if the event processing should be stopped +*/ +bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e ) +{ + if ( watched == myViewPort ) { + int aType = e->type(); + switch(aType) { + case QEvent::MouseButtonPress: + vpMousePressEvent((QMouseEvent*) e); + return true; + + case QEvent::MouseButtonRelease: + vpMouseReleaseEvent((QMouseEvent*) e); + return true; + + case QEvent::MouseMove: + vpMouseMoveEvent((QMouseEvent*) e); + return true; + + case QEvent::MouseButtonDblClick: + emit mouseDoubleClicked(this, (QMouseEvent*)e); + return true; + + case QEvent::Wheel: + { + QWheelEvent* aEvent = (QWheelEvent*) e; + myViewPort->startZoomAtPoint( aEvent->x(), aEvent->y() ); + double delta = (double)( aEvent->delta() ) / ( 15 * 8 ); + int x = aEvent->x(); + int y = aEvent->y(); + int x1 = (int)( aEvent->x() + width()*delta/100 ); + int y1 = (int)( aEvent->y() + height()*delta/100 ); + myViewPort->zoom( x, y, x1, y1 ); + } + return true; + + case QEvent::ContextMenu: + { + QContextMenuEvent * aEvent = (QContextMenuEvent*)e; + if ( aEvent->reason() != QContextMenuEvent::Mouse ) + emit contextMenuRequested( aEvent ); + } + return true; + + case QEvent::KeyPress: + emit keyPressed(this, (QKeyEvent*) e); + return true; + + default: + break; + } + } + return SUIT_ViewWindow::eventFilter(watched, e); +} + +/*! + \brief Update state of enable draw mode state. +*/ +void OCCViewer_ViewWindow::updateEnabledDrawMode() +{ + if ( myModel ) + myEnableDrawMode = myModel->isSelectionEnabled() && myModel->isMultiSelectionEnabled(); +} + +/*! + \brief Handle mouse press event + \param theEvent mouse event +*/ +void OCCViewer_ViewWindow::vpMousePressEvent( QMouseEvent* theEvent ) +{ + myStartX = theEvent->x(); + myStartY = theEvent->y(); + int anInteractionStyle = interactionStyle(); + + // in "key free" interaction style zoom operation is activated by two buttons (simultaneously pressed), + // which are assigned for pan and rotate - these operations are activated immediately after pressing + // of the first button, so it is necessary to switch to zoom when the second button is pressed + bool aSwitchToZoom = false; + if ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && + ( myOperation == PANVIEW || myOperation == ROTATE ) ) { + aSwitchToZoom = getButtonState( theEvent, anInteractionStyle ) == ZOOMVIEW; + } + + switch ( myOperation ) { + case WINDOWFIT: + if ( theEvent->button() == Qt::LeftButton ) + emit vpTransformationStarted ( WINDOWFIT ); + break; + + case PANGLOBAL: + if ( theEvent->button() == Qt::LeftButton ) + emit vpTransformationStarted ( PANGLOBAL ); + break; + + case ZOOMVIEW: + if ( theEvent->button() == Qt::LeftButton ) { + myViewPort->startZoomAtPoint( myStartX, myStartY ); + emit vpTransformationStarted ( ZOOMVIEW ); + } + break; + + case PANVIEW: + if ( aSwitchToZoom ) { + myViewPort->startZoomAtPoint( myStartX, myStartY ); + activateZoom(); + } + else if ( theEvent->button() == Qt::LeftButton ) + emit vpTransformationStarted ( PANVIEW ); + break; + + case ROTATE: + if ( aSwitchToZoom ) { + myViewPort->startZoomAtPoint( myStartX, myStartY ); + activateZoom(); + } + else if ( theEvent->button() == Qt::LeftButton ) { + myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); + emit vpTransformationStarted ( ROTATE ); + } + break; + + default: + /* Try to activate a transformation */ + OperationType aState; + if ( interactionStyle() == SUIT_ViewModel::STANDARD ) + aState = getButtonState(theEvent, anInteractionStyle); + else { + aState = OCCViewer_ViewWindow::NOTHING; + myIsKeyFree = true; + } + switch ( aState ) { + case ZOOMVIEW: + myViewPort->startZoomAtPoint( myStartX, myStartY ); + activateZoom(); + break; + case PANVIEW: + activatePanning(); + break; + case ROTATE: + activateRotation(); + myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); + break; + default: + if ( myRotationPointSelection ) + { + if ( theEvent->button() == Qt::LeftButton ) + { + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + ic->Select(); + for ( ic->InitSelected(); ic->MoreSelected(); ic->NextSelected() ) + { + TopoDS_Shape aShape = ic->SelectedShape(); + if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX ) + { + gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( ic->SelectedShape() ) ); + if ( mySetRotationPointDlg ) + { + myRotationPointSelection = false; + mySetRotationPointDlg->setCoords(aPnt.X(), aPnt.Y(), aPnt.Z()); + } + } + else + { + myCurrPointType = myPrevPointType; + break; + } + } + if ( ic->NbSelected() == 0 ) myCurrPointType = myPrevPointType; + if ( mySetRotationPointDlg ) mySetRotationPointDlg->toggleChange(); + ic->CloseAllContexts(); + myOperation = NOTHING; + myViewPort->setCursor( myCursor ); + myCursorIsHand = false; + myRotationPointSelection = false; + } + } + else + emit mousePressed(this, theEvent); + break; + } + /* notify that we start a transformation */ + if ( transformRequested() ) + emit vpTransformationStarted ( myOperation ); + } + if ( transformRequested() ) + setTransformInProcess( true ); + + /* we may need it for sketching... */ + if ( l_mbPressEvent ) + delete l_mbPressEvent; + l_mbPressEvent = new QMouseEvent( *theEvent ); +} + + +/*! + \brief Start zooming operation. + + Sets the corresponding cursor for the widget. +*/ +void OCCViewer_ViewWindow::activateZoom() +{ + if ( !transformRequested() && !myCursorIsHand ) + myCursor = cursor(); /* save old cursor */ + + if ( myOperation != ZOOMVIEW ) { + QPixmap zoomPixmap (imageZoomCursor); + QCursor zoomCursor (zoomPixmap); + if( setTransformRequested ( ZOOMVIEW ) ) + myViewPort->setCursor( zoomCursor ); + } +} + + +/*! + \brief Start panning operation. + + Sets the corresponding cursor for the widget. +*/ +void OCCViewer_ViewWindow::activatePanning() +{ + if ( !transformRequested() && !myCursorIsHand ) + myCursor = cursor(); // save old cursor + + if ( myOperation != PANVIEW ) { + QCursor panCursor (Qt::SizeAllCursor); + if( setTransformRequested ( PANVIEW ) ) + myViewPort->setCursor( panCursor ); + } +} + +/*! + \brief Start rotation operation + + Sets the corresponding cursor for the widget. +*/ +void OCCViewer_ViewWindow::activateRotation() +{ + if ( !transformRequested() && !myCursorIsHand ) + myCursor = cursor(); // save old cursor + + if ( myOperation != ROTATE ) { + QPixmap rotatePixmap (imageRotateCursor); + QCursor rotCursor (rotatePixmap); + if( setTransformRequested ( ROTATE ) ) + myViewPort->setCursor( rotCursor ); + } +} + +/*! + \brief Compute the gravity center. + \param theX used to return X coordinate of the gravity center + \param theY used to return Y coordinate of the gravity center + \param theZ used to return Z coordinate of the gravity center + \return \c true if the gravity center is computed +*/ +bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, double& theZ ) +{ + Handle(Visual3d_View) aView = myViewPort->getView()->View(); + + Standard_Real Xmin,Ymin,Zmin,Xmax,Ymax,Zmax,U,V,W ; + Standard_Real Umin,Vmin,Umax,Vmax ; + Standard_Integer Nstruct,Npoint ; + Graphic3d_MapOfStructure MySetOfStructures; + + aView->DisplayedStructures (MySetOfStructures); + Nstruct = MySetOfStructures.Extent() ; + + Graphic3d_MapIteratorOfMapOfStructure MyIterator(MySetOfStructures) ; +#if OCC_VERSION_LARGE > 0x06070000 + aView->Camera()->WindowLimit(Umin,Vmin,Umax,Vmax); +#else + aView->ViewMapping().WindowLimit(Umin,Vmin,Umax,Vmax); +#endif + Npoint = 0 ; theX = theY = theZ = 0. ; + for( ; MyIterator.More(); MyIterator.Next()) { + if (!(MyIterator.Key())->IsEmpty()) { + (MyIterator.Key())->MinMaxValues(Xmin,Ymin,Zmin, + Xmax,Ymax,Zmax) ; + + Standard_Real LIM = ShortRealLast() -1.; + if (! (fabs(Xmin) > LIM || fabs(Ymin) > LIM || fabs(Zmin) > LIM + || fabs(Xmax) > LIM || fabs(Ymax) > LIM || fabs(Zmax) > LIM )) { + + aView->Projects(Xmin,Ymin,Zmin,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmin ; + } + aView->Projects(Xmax,Ymin,Zmin,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmin ; + } + aView->Projects(Xmin,Ymax,Zmin,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmin ; + } + aView->Projects(Xmax,Ymax,Zmin,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmin ; + } + aView->Projects(Xmin,Ymin,Zmax,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmin ; theY += Ymin ; theZ += Zmax ; + } + aView->Projects(Xmax,Ymin,Zmax,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmax ; theY += Ymin ; theZ += Zmax ; + } + aView->Projects(Xmin,Ymax,Zmax,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmin ; theY += Ymax ; theZ += Zmax ; + } + aView->Projects(Xmax,Ymax,Zmax,U,V,W) ; + if( U >= Umin && U <= Umax && V >= Vmin && V <= Vmax ) { + Npoint++ ; theX += Xmax ; theY += Ymax ; theZ += Zmax ; + } + } + } + } + if( Npoint > 0 ) { + theX /= Npoint ; theY /= Npoint ; theZ /= Npoint ; + } + return true; +} + +/*! + \brief Set the gravity center as a rotation point. +*/ +void OCCViewer_ViewWindow::activateSetRotationGravity() +{ + if ( myRotationPointSelection ) + { + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + ic->CloseAllContexts(); + myOperation = NOTHING; + myViewPort->setCursor( myCursor ); + myCursorIsHand = false; + myRotationPointSelection = false; + } + + myPrevPointType = myCurrPointType; + myCurrPointType = GRAVITY; + + Standard_Real Xcenter, Ycenter, Zcenter; + if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) ) + mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter ); +} + +/*! + \brief Update gravity center in the "Set Rotation Point" dialog box. + \sa OCCViewer_SetRotationPointDlg class +*/ +void OCCViewer_ViewWindow::updateGravityCoords() +{ + if ( mySetRotationPointDlg && mySetRotationPointDlg->isVisible() && myCurrPointType == GRAVITY ) + { + Standard_Real Xcenter, Ycenter, Zcenter; + if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) ) + mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter ); + } +} + +/*! + \brief Set the point selected by the user as a rotation point. + \param theX X coordinate of the rotation point + \param theY Y coordinate of the rotation point + \param theZ Z coordinate of the rotation point +*/ +void OCCViewer_ViewWindow::activateSetRotationSelected( double theX, double theY, double theZ ) +{ + if ( myRotationPointSelection ) + { + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + ic->CloseAllContexts(); + myOperation = NOTHING; + myViewPort->setCursor( myCursor ); + myCursorIsHand = false; + myRotationPointSelection = false; + } + + myPrevPointType = myCurrPointType; + myCurrPointType = SELECTED; + mySelectedPoint.SetCoord(theX,theY,theZ); +} + +/*! + \brief Start the point selection process. +*/ +void OCCViewer_ViewWindow::activateStartPointSelection() +{ + myPrevPointType = myCurrPointType; + myCurrPointType = SELECTED; + + // activate selection ------> + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + + ic->OpenLocalContext(); + + 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_Shape) ) ) + { + ic->Load(anObj,-1); + ic->Activate(anObj,AIS_Shape::SelectionMode(TopAbs_VERTEX)); + } + } + // activate selection <------ + + if ( !myCursorIsHand ) + { + QCursor handCursor (Qt::PointingHandCursor); + myCursorIsHand = true; + myCursor = cursor(); + myViewPort->setCursor( handCursor ); + } + myRotationPointSelection = true; +} + +/*! + \brief Start global panning operation + + Sets the corresponding cursor for the widget. +*/ +void OCCViewer_ViewWindow::activateGlobalPanning() +{ + Handle(V3d_View) aView3d = myViewPort->getView(); + if ( !aView3d.IsNull() ) { + QPixmap globalPanPixmap (imageCrossCursor); + QCursor glPanCursor (globalPanPixmap); + myCurScale = aView3d->Scale(); + aView3d->FitAll(0.01, false); + myCursor = cursor(); // save old cursor + myViewPort->fitAll(); // fits view before selecting a new scene center + if( setTransformRequested( PANGLOBAL ) ) + myViewPort->setCursor( glPanCursor ); + } +} + +/*! + \brief Starts fit operation. + + Sets the corresponding cursor for the widget. +*/ +void OCCViewer_ViewWindow::activateWindowFit() +{ + if ( !transformRequested() && !myCursorIsHand ) + myCursor = cursor(); /* save old cursor */ + + if ( myOperation != WINDOWFIT ) { + QCursor handCursor (Qt::PointingHandCursor); + if( setTransformRequested ( WINDOWFIT ) ) + { + myViewPort->setCursor ( handCursor ); + myCursorIsHand = true; + } + } +} + +/*! + \brief Start delayed viewer operation. +*/ +bool OCCViewer_ViewWindow::setTransformRequested( OperationType op ) +{ + bool ok = transformEnabled( op ); + myOperation = ok ? op : NOTHING; + myViewPort->setMouseTracking( myOperation == NOTHING ); + return ok; +} + +/*! + \brief Handle mouse move event. + \param theEvent mouse event +*/ +void OCCViewer_ViewWindow::vpMouseMoveEvent( QMouseEvent* theEvent ) +{ + if ( myIsKeyFree && interactionStyle() == SUIT_ViewModel::KEY_FREE ) { + myIsKeyFree = false; + switch ( getButtonState( theEvent, interactionStyle() ) ) { + case ZOOMVIEW: + myViewPort->startZoomAtPoint( myStartX, myStartY ); + activateZoom(); + break; + case PANVIEW: + activatePanning(); + break; + case ROTATE: + activateRotation(); + myViewPort->startRotation(myStartX, myStartY, myCurrPointType, mySelectedPoint); + break; + default: + break; + } + } + + myCurrX = theEvent->x(); + myCurrY = theEvent->y(); + switch (myOperation) { + case ROTATE: + myViewPort->rotate(myCurrX, myCurrY, myCurrPointType, mySelectedPoint); + break; + + case ZOOMVIEW: + myViewPort->zoom(myStartX, myStartY, myCurrX, myCurrY); + myStartX = myCurrX; + myStartY = myCurrY; + break; + + case PANVIEW: + myViewPort->pan(myCurrX - myStartX, myStartY - myCurrY); + myStartX = myCurrX; + myStartY = myCurrY; + break; + +/* case WINDOWFIT: + myDrawRect = true; + repaint(); + break; +*/ + case PANGLOBAL: + break; + + default: + if ( myRotationPointSelection || isSketcherStyle() ) + { + emit mouseMoving( this, theEvent ); + } + else + { + int aState = theEvent->modifiers(); + int aButton = theEvent->buttons(); + int anInteractionStyle = interactionStyle(); + if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD && + aButton == Qt::LeftButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) || + ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && + aButton == Qt::LeftButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) { + myDrawRect = myEnableDrawMode; + if ( myDrawRect ) { + drawRect(); + if ( !myCursorIsHand ) { // we are going to sketch a rectangle + QCursor handCursor (Qt::PointingHandCursor); + myCursorIsHand = true; + myCursor = cursor(); + myViewPort->setCursor( handCursor ); + } + } + emit mouseMoving( this, theEvent ); + } + else if ( ( anInteractionStyle == SUIT_ViewModel::STANDARD && + aButton == Qt::RightButton && ( aState == Qt::NoModifier || Qt::ShiftModifier ) ) || + ( anInteractionStyle == SUIT_ViewModel::KEY_FREE && + aButton == Qt::RightButton && ( aState == Qt::ControlModifier || aState == ( Qt::ControlModifier|Qt::ShiftModifier ) ) ) ) { + OCCViewer_ViewSketcher* sketcher = 0; + QList::Iterator it; + for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) + { + OCCViewer_ViewSketcher* sk = (*it); + if( sk->isDefault() && sk->sketchButton() == aButton ) + sketcher = sk; + } + if ( sketcher && myCurSketch == -1 ) + { + activateSketching( sketcher->type() ); + if ( mypSketcher ) + { + myCurSketch = mypSketcher->sketchButton(); + + if ( l_mbPressEvent ) + { + QApplication::sendEvent( getViewPort(), l_mbPressEvent ); + delete l_mbPressEvent; + l_mbPressEvent = 0; + } + QApplication::sendEvent( getViewPort(), theEvent ); + } + } + } + else + emit mouseMoving( this, theEvent ); + } + } +} + +/*! + \brief Handle mouse release event. + \param theEvent mouse event +*/ +void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent) +{ + switch ( myOperation ) { + case NOTHING: + { + int prevState = myCurSketch; + if(theEvent->button() == Qt::RightButton) + { + QList::Iterator it; + for ( it = mySketchers.begin(); it != mySketchers.end() && myCurSketch != -1; ++it ) + { + OCCViewer_ViewSketcher* sk = (*it); + if( ( sk->sketchButton() & theEvent->button() ) && sk->sketchButton() == myCurSketch ) + myCurSketch = -1; + } + } + + emit mouseReleased(this, theEvent); + if(theEvent->button() == Qt::RightButton && prevState == -1) + { + QContextMenuEvent aEvent( QContextMenuEvent::Mouse, + theEvent->pos(), theEvent->globalPos() ); + emit contextMenuRequested( &aEvent ); + } + } + break; + case ROTATE: + myViewPort->endRotation(); + resetState(); + break; + + case PANVIEW: + case ZOOMVIEW: + resetState(); + break; + + case PANGLOBAL: + if ( theEvent->button() == Qt::LeftButton ) { + myViewPort->setCenter( theEvent->x(), theEvent->y() ); + myViewPort->getView()->SetScale(myCurScale); + resetState(); + } + break; + + case WINDOWFIT: + if ( theEvent->button() == Qt::LeftButton ) { + myCurrX = theEvent->x(); + myCurrY = theEvent->y(); + drawRect(); + QRect rect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY); + if ( !rect.isEmpty() ) myViewPort->fitRect(rect); + endDrawRect(); + resetState(); + } + break; + } + + // NOTE: viewer 3D detects a rectangle of selection using this event + // so we must emit it BEFORE resetting the selection rectangle + + if ( theEvent->button() == Qt::LeftButton && myDrawRect ) { + drawRect(); + endDrawRect(); + resetState(); + myViewPort->update(); + } + + if ( l_mbPressEvent ) + { + delete l_mbPressEvent; + l_mbPressEvent = 0; + } +} + +/*! + \brief Reset the viewport to its initial state + ( no transformations in process etc. ) +*/ +void OCCViewer_ViewWindow::resetState() +{ + myDrawRect = false; + + if ( myRotationPointSelection ) + { + QCursor handCursor (Qt::PointingHandCursor); + myViewPort->setCursor( handCursor ); + } + else + { + if ( transformRequested() || myCursorIsHand ) + myViewPort->setCursor( myCursor ); + myCursorIsHand = false; + } + + if ( transformRequested() ) + emit vpTransformationFinished (myOperation); + + setTransformInProcess( false ); + setTransformRequested( NOTHING ); +} + + +/*! + \brief Draw rubber band rectangle. +*/ +void OCCViewer_ViewWindow::drawRect() +{ + if ( !myRectBand ) { + myRectBand = new QtxRectRubberBand( myViewPort ); + //QPalette palette; + //palette.setColor(myRectBand->foregroundRole(), Qt::white); + //myRectBand->setPalette(palette); + } + //myRectBand->hide(); + + myRectBand->setUpdatesEnabled ( false ); + QRect aRect = SUIT_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY); + myRectBand->initGeometry( aRect ); + + if ( !myRectBand->isVisible() ) + myRectBand->show(); + + myRectBand->setUpdatesEnabled ( true ); + //myRectBand->repaint(); + + //myRectBand->setVisible( aRect.isValid() ); + //if ( myRectBand->isVisible() ) + // myRectBand->repaint(); + //else + // myRectBand->show(); + //myRectBand->repaint(); +} + +/*! + \brief Clear rubber band rectangle on the end on the dragging operation. +*/ +void OCCViewer_ViewWindow::endDrawRect() +{ + //delete myRectBand; + //myRectBand = 0; + if ( myRectBand ) + { + myRectBand->clearGeometry(); + myRectBand->hide(); + } +} + +/*! + \brief Create actions. +*/ +void OCCViewer_ViewWindow::createActions() +{ + if( !toolMgr()->isEmpty() ) + return; + + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + + QtxAction* aAction; + + // Dump view + aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_DUMP" ) ), + tr( "MNU_DUMP_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_DUMP_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onDumpView())); + toolMgr()->registerAction( aAction, DumpId ); + + // FitAll + aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITALL" ) ), + tr( "MNU_FITALL" ), 0, this); + aAction->setStatusTip(tr("DSC_FITALL")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onFitAll())); + toolMgr()->registerAction( aAction, FitAllId ); + + // FitRect + aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FITAREA" ) ), + tr( "MNU_FITRECT" ), 0, this); + aAction->setStatusTip(tr("DSC_FITRECT")); + connect(aAction, SIGNAL(triggered()), this, SLOT(activateWindowFit())); + toolMgr()->registerAction( aAction, FitRectId ); + + // Zoom + aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ZOOM" ) ), + tr( "MNU_ZOOM_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_ZOOM_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(activateZoom())); + toolMgr()->registerAction( aAction, ZoomId ); + + // Panning + aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_PAN" ) ), + tr( "MNU_PAN_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_PAN_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(activatePanning())); + toolMgr()->registerAction( aAction, PanId ); + + // Global Panning + aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_GLOBALPAN" ) ), + tr( "MNU_GLOBALPAN_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(activateGlobalPanning())); + toolMgr()->registerAction( aAction, GlobalPanId ); + + // Rotation Point + mySetRotationPointAction = new QtxAction(tr("MNU_CHANGINGROTATIONPOINT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATION_POINT" ) ), + tr( "MNU_CHANGINGROTATIONPOINT_VIEW" ), 0, this); + mySetRotationPointAction->setStatusTip(tr("DSC_CHANGINGROTATIONPOINT_VIEW")); + mySetRotationPointAction->setCheckable( true ); + connect(mySetRotationPointAction, SIGNAL(toggled( bool )), this, SLOT(onSetRotationPoint( bool ))); + toolMgr()->registerAction( mySetRotationPointAction, ChangeRotationPointId ); + + // Rotation + aAction = new QtxAction(tr("MNU_ROTATE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ROTATE" ) ), + tr( "MNU_ROTATE_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_ROTATE_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(activateRotation())); + toolMgr()->registerAction( aAction, RotationId ); + + // Projections + aAction = new QtxAction(tr("MNU_FRONT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_FRONT" ) ), + tr( "MNU_FRONT_VIEW" ), 0, this, false, "Viewers:Front view"); + aAction->setStatusTip(tr("DSC_FRONT_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onFrontView())); + this->addAction(aAction); + toolMgr()->registerAction( aAction, FrontId ); + + aAction = new QtxAction(tr("MNU_BACK_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BACK" ) ), + tr( "MNU_BACK_VIEW" ), 0, this, false, "Viewers:Back view"); + aAction->setStatusTip(tr("DSC_BACK_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onBackView())); + this->addAction(aAction); + toolMgr()->registerAction( aAction, BackId ); + + aAction = new QtxAction(tr("MNU_TOP_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TOP" ) ), + tr( "MNU_TOP_VIEW" ), 0, this, false, "Viewers:Top view"); + aAction->setStatusTip(tr("DSC_TOP_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onTopView())); + this->addAction(aAction); + toolMgr()->registerAction( aAction, TopId ); + + aAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_BOTTOM" ) ), + tr( "MNU_BOTTOM_VIEW" ), 0, this, false, "Viewers:Bottom view"); + aAction->setStatusTip(tr("DSC_BOTTOM_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onBottomView())); + this->addAction(aAction); + toolMgr()->registerAction( aAction, BottomId ); + + aAction = new QtxAction(tr("MNU_LEFT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_LEFT" ) ), + tr( "MNU_LEFT_VIEW" ), 0, this, false, "Viewers:Left view"); + aAction->setStatusTip(tr("DSC_LEFT_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onLeftView())); + this->addAction(aAction); + toolMgr()->registerAction( aAction, LeftId ); + + aAction = new QtxAction(tr("MNU_RIGHT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RIGHT" ) ), + tr( "MNU_RIGHT_VIEW" ), 0, this, false, "Viewers:Right view"); + aAction->setStatusTip(tr("DSC_RIGHT_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onRightView())); + this->addAction(aAction); + toolMgr()->registerAction( aAction, RightId ); + + // rotate anticlockwise + aAction = new QtxAction(tr("MNU_ANTICLOCKWISE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_ANTICLOCKWISE" ) ), + tr( "MNU_ANTICLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate anticlockwise"); + aAction->setStatusTip(tr("DSC_ANTICLOCKWISE_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onAntiClockWiseView())); + this->addAction(aAction); + toolMgr()->registerAction( aAction, AntiClockWiseId ); + + // rotate clockwise + aAction = new QtxAction(tr("MNU_CLOCKWISE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_CLOCKWISE" ) ), + tr( "MNU_CLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate clockwise"); + aAction->setStatusTip(tr("DSC_CLOCKWISE_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onClockWiseView())); + this->addAction(aAction); + toolMgr()->registerAction( aAction, ClockWiseId ); + + // Reset + aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_RESET" ) ), + tr( "MNU_RESET_VIEW" ), 0, this, false, "Viewers:Reset view"); + aAction->setStatusTip(tr("DSC_RESET_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onResetView())); + this->addAction(aAction); + toolMgr()->registerAction( aAction, ResetId ); + + // Clone + aAction = new QtxAction(tr("MNU_CLONE_VIEW"), + aResMgr->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_CLONE_VIEW")), + tr("MNU_CLONE_VIEW"), 0, this); + aAction->setStatusTip(tr("DSC_CLONE_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onCloneView())); + toolMgr()->registerAction( aAction, CloneId ); + + aAction = new QtxAction (tr ("MNU_CLIPPING"), aResMgr->loadPixmap ("OCCViewer", tr ("ICON_OCCVIEWER_CLIPPING")), + tr ("MNU_CLIPPING"), 0, this); + aAction->setStatusTip (tr ("DSC_CLIPPING")); + aAction->setCheckable (true); + connect (aAction, SIGNAL (toggled (bool)), this, SLOT (onClipping (bool))); + toolMgr()->registerAction (aAction, ClippingId); + + aAction = new QtxAction(tr("MNU_SHOOT_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SHOOT_VIEW" ) ), + tr( "MNU_SHOOT_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_SHOOT_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onMemorizeView())); + toolMgr()->registerAction( aAction, MemId ); + + aAction = new QtxAction(tr("MNU_PRESETS_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESETS_VIEW" ) ), + tr( "MNU_PRESETS_VIEW" ), 0, this); + aAction->setStatusTip(tr("DSC_PRESETS_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onRestoreView())); + toolMgr()->registerAction( aAction, RestoreId ); + + if (myModel->trihedronActivated()) { + aAction = new QtxAction(tr("MNU_SHOW_TRIHEDRE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_VIEW_TRIHEDRON" ) ), + tr( "MNU_SHOW_TRIHEDRE" ), 0, this); + aAction->setStatusTip(tr("DSC_SHOW_TRIHEDRE")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onTrihedronShow())); + toolMgr()->registerAction( aAction, TrihedronShowId ); + } + + // Scale + aAction = new QtxAction(tr("MNU_SCALING"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SCALING" ) ), + tr( "MNU_SCALING" ), 0, this); + aAction->setStatusTip(tr("DSC_SCALING")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onAxialScale())); + toolMgr()->registerAction( aAction, AxialScaleId ); + + // Enable/disable preselection + aAction = new QtxAction(tr("MNU_ENABLE_PRESELECTION"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_PRESELECTION" ) ), + tr( "MNU_ENABLE_PRESELECTION" ), 0, this); + aAction->setStatusTip(tr("DSC_ENABLE_PRESELECTION")); + aAction->setCheckable(true); + connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchPreselection(bool))); + toolMgr()->registerAction( aAction, SwitchPreselectionId ); + + // Enable/disable selection + aAction = new QtxAction(tr("MNU_ENABLE_SELECTION"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_SELECTION" ) ), + tr( "MNU_ENABLE_SELECTION" ), 0, this); + aAction->setStatusTip(tr("DSC_ENABLE_SELECTION")); + aAction->setCheckable(true); + connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchSelection(bool))); + toolMgr()->registerAction( aAction, SwitchSelectionId ); + + // Graduated axes + aAction = new QtxAction(tr("MNU_GRADUATED_AXES"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_GRADUATED_AXES" ) ), + tr( "MNU_GRADUATED_AXES" ), 0, this); + aAction->setStatusTip(tr("DSC_GRADUATED_AXES")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onGraduatedAxes())); + toolMgr()->registerAction( aAction, GraduatedAxesId ); + + // Active only ambient light or not + aAction = new QtxAction(tr("MNU_AMBIENT"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_AMBIENT" ) ), + tr( "MNU_AMBIENT" ), 0, this); + aAction->setStatusTip(tr("DSC_AMBIENT")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onAmbientToogle())); + toolMgr()->registerAction( aAction, AmbientId ); + + // Switch between interaction styles + aAction = new QtxAction(tr("MNU_STYLE_SWITCH"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_STYLE_SWITCH" ) ), + tr( "MNU_STYLE_SWITCH" ), 0, this); + aAction->setStatusTip(tr("DSC_STYLE_SWITCH")); + aAction->setCheckable(true); + connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchInteractionStyle(bool))); + toolMgr()->registerAction( aAction, SwitchInteractionStyleId ); + + // Switch between zooming styles + aAction = new QtxAction(tr("MNU_ZOOMING_STYLE_SWITCH"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_ZOOMING_STYLE_SWITCH" ) ), + tr( "MNU_ZOOMING_STYLE_SWITCH" ), 0, this); + aAction->setStatusTip(tr("DSC_ZOOMING_STYLE_SWITCH")); + aAction->setCheckable(true); + connect(aAction, SIGNAL(toggled(bool)), this, SLOT(onSwitchZoomingStyle(bool))); + toolMgr()->registerAction( aAction, SwitchZoomingStyleId ); + + // Maximized view + aAction = new QtxAction(tr("MNU_MINIMIZE_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ), + tr( "MNU_MINIMIZE_VIEW" ), 0, this ); + aAction->setStatusTip(tr("DSC_MINIMIZE_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(onMaximizedView())); + toolMgr()->registerAction( aAction, MaximizedId ); + + // Return to 3d view + if (my2dMode!=No2dMode){ + aAction = new QtxAction(tr("MNU_RETURN_3D_VIEW"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_RETURN_3D_VIEW" ) ), + tr( "MNU_RETURN_3D_VIEW" ), 0, this ); + aAction->setStatusTip(tr("DSC_RETURN_3D_VIEW")); + connect(aAction, SIGNAL(triggered()), this, SLOT(returnTo3dView())); + toolMgr()->registerAction( aAction, ReturnTo3dViewId ); + } + + // Synchronize View + toolMgr()->registerAction( synchronizeAction(), SynchronizeId ); +} + +/*! + \brief Create toolbar. +*/ +void OCCViewer_ViewWindow::createToolBar() +{ + QString aToolbarName; + switch (my2dMode) { + case XYPlane: + aToolbarName = tr( "LBL_XYTOOLBAR_LABEL" ); + break; + case XZPlane: + aToolbarName = tr( "LBL_XZTOOLBAR_LABEL" ); + break; + case YZPlane: + aToolbarName = tr( "LBL_YZTOOLBAR_LABEL" ); + break; + default: + aToolbarName = tr( "LBL_3DTOOLBAR_LABEL" ); + } + + int tid = toolMgr()->createToolBar( aToolbarName, false ); + if ( my2dMode != No2dMode ){ + toolMgr()->append( ReturnTo3dViewId, tid ); + toolMgr()->append( toolMgr()->separator(), tid ); + } + toolMgr()->append( DumpId, tid ); + toolMgr()->append( SwitchInteractionStyleId, tid ); +#if OCC_VERSION_LARGE > 0x0603000A // available only with OCC-6.3-sp11 and higher version + toolMgr()->append( SwitchZoomingStyleId, tid ); +#endif + toolMgr()->append( SwitchPreselectionId, tid ); + toolMgr()->append( SwitchSelectionId, tid ); + if( myModel->trihedronActivated() ) + toolMgr()->append( TrihedronShowId, tid ); + + QtxMultiAction* aScaleAction = new QtxMultiAction( this ); + aScaleAction->insertAction( toolMgr()->action( FitAllId ) ); + aScaleAction->insertAction( toolMgr()->action( FitRectId ) ); + aScaleAction->insertAction( toolMgr()->action( ZoomId ) ); + toolMgr()->append( aScaleAction, tid ); + + QtxMultiAction* aPanningAction = new QtxMultiAction( this ); + aPanningAction->insertAction( toolMgr()->action( PanId ) ); + aPanningAction->insertAction( toolMgr()->action( GlobalPanId ) ); + toolMgr()->append( aPanningAction, tid ); + + if (my2dMode == No2dMode) { + toolMgr()->append( ChangeRotationPointId, tid ); + toolMgr()->append( RotationId, tid ); + + QtxMultiAction* aViewsAction = new QtxMultiAction( this ); + aViewsAction->insertAction( toolMgr()->action( FrontId ) ); + aViewsAction->insertAction( toolMgr()->action( BackId ) ); + aViewsAction->insertAction( toolMgr()->action( TopId ) ); + aViewsAction->insertAction( toolMgr()->action( BottomId ) ); + aViewsAction->insertAction( toolMgr()->action( LeftId ) ); + aViewsAction->insertAction( toolMgr()->action( RightId ) ); + toolMgr()->append( aViewsAction, tid ); + + toolMgr()->append( AntiClockWiseId, tid ); + toolMgr()->append( ClockWiseId, tid ); + + toolMgr()->append( ResetId, tid ); + } + + QtxMultiAction* aMemAction = new QtxMultiAction( this ); + aMemAction->insertAction( toolMgr()->action( MemId ) ); + aMemAction->insertAction( toolMgr()->action( RestoreId ) ); + toolMgr()->append( aMemAction, tid ); + + toolMgr()->append( toolMgr()->separator(), tid ); + toolMgr()->append( CloneId, tid ); + + toolMgr()->append( toolMgr()->separator(), tid ); + toolMgr()->append( ClippingId, tid ); + toolMgr()->append( AxialScaleId, tid ); +#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version + toolMgr()->append( GraduatedAxesId, tid ); +#endif + toolMgr()->append( AmbientId, tid ); + + toolMgr()->append( MaximizedId, tid ); + toolMgr()->append( SynchronizeId, tid ); +} + +/*! + \brief Perform 'fit all' operation. +*/ +void OCCViewer_ViewWindow::onViewFitAll() +{ + myViewPort->fitAll(); +} + +/*! + \brief Perform "front view" transformation. +*/ +void OCCViewer_ViewWindow::onFrontView() +{ + emit vpTransformationStarted ( FRONTVIEW ); + Handle(V3d_View) aView3d = myViewPort->getView(); + if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xpos); + onViewFitAll(); + emit vpTransformationFinished ( FRONTVIEW ); +} + +/*! + \brief Perform "back view" transformation. +*/ +void OCCViewer_ViewWindow::onBackView() +{ + emit vpTransformationStarted ( BACKVIEW ); + Handle(V3d_View) aView3d = myViewPort->getView(); + if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Xneg); + onViewFitAll(); + emit vpTransformationFinished ( BACKVIEW ); +} + +/*! + \brief Perform "top view" transformation. +*/ +void OCCViewer_ViewWindow::onTopView() +{ + emit vpTransformationStarted ( TOPVIEW ); + Handle(V3d_View) aView3d = myViewPort->getView(); + if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zpos); + onViewFitAll(); + emit vpTransformationFinished ( TOPVIEW ); +} + +/*! + \brief Perform "bottom view" transformation. +*/ +void OCCViewer_ViewWindow::onBottomView() +{ + emit vpTransformationStarted ( BOTTOMVIEW ); + Handle(V3d_View) aView3d = myViewPort->getView(); + if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Zneg); + onViewFitAll(); + emit vpTransformationFinished ( BOTTOMVIEW ); +} + +/*! + \brief Perform "left view" transformation. +*/ +void OCCViewer_ViewWindow::onLeftView() +{ + emit vpTransformationStarted ( LEFTVIEW ); + Handle(V3d_View) aView3d = myViewPort->getView(); + if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Yneg); + onViewFitAll(); + emit vpTransformationFinished ( LEFTVIEW ); +} + +/*! + \brief Perform "right view" transformation. +*/ +void OCCViewer_ViewWindow::onRightView() +{ + emit vpTransformationStarted ( RIGHTVIEW ); + Handle(V3d_View) aView3d = myViewPort->getView(); + if ( !aView3d.IsNull() ) aView3d->SetProj (V3d_Ypos); + onViewFitAll(); + emit vpTransformationFinished ( RIGHTVIEW ); +} + +/*! + \brief Rotate view 90 degrees clockwise +*/ +void OCCViewer_ViewWindow::onClockWiseView() +{ + emit vpTransformationStarted ( CLOCKWISEVIEW ); + myViewPort->rotateXY( 90. ); + emit vpTransformationFinished ( CLOCKWISEVIEW ); +} + +/*! + \brief Rotate view 90 degrees conterclockwise +*/ +void OCCViewer_ViewWindow::onAntiClockWiseView() +{ + emit vpTransformationStarted ( ANTICLOCKWISEVIEW ); + myViewPort->rotateXY( -90. ); + emit vpTransformationFinished ( ANTICLOCKWISEVIEW ); +} + +/*! + \brief Perform "reset view" transformation. + + Sets default orientation of the viewport camera. +*/ +void OCCViewer_ViewWindow::onResetView() +{ + emit vpTransformationStarted( RESETVIEW ); + bool upd = myViewPort->getView()->SetImmediateUpdate( false ); + myViewPort->getView()->Reset( false ); + myViewPort->fitAll( false, true, false ); + myViewPort->getView()->SetImmediateUpdate( upd ); + myViewPort->getView()->Update(); + emit vpTransformationFinished( RESETVIEW ); +} + +/*! + \brief Perform "fit all" transformation. +*/ +void OCCViewer_ViewWindow::onFitAll() +{ + emit vpTransformationStarted( FITALLVIEW ); + myViewPort->fitAll(); + emit vpTransformationFinished( FITALLVIEW ); +} + +/*! + \brief Called if 'change rotation point' operation is activated. + \param on action state +*/ +void OCCViewer_ViewWindow::onSetRotationPoint( bool on ) +{ + if (on) + { + if (!mySetRotationPointDlg) + { + mySetRotationPointDlg = new OCCViewer_SetRotationPointDlg (this); + mySetRotationPointDlg->SetAction(mySetRotationPointAction); + } + + if (!mySetRotationPointDlg->isVisible()) + { + //if (mySetRotationPointDlg->IsFirstShown()) + if (myCurrPointType == GRAVITY) + { + Standard_Real Xcenter, Ycenter, Zcenter; + if (computeGravityCenter(Xcenter, Ycenter, Zcenter)) + mySetRotationPointDlg->setCoords(Xcenter, Ycenter, Zcenter); + } + mySetRotationPointDlg->show(); + } + } + else + { + if (mySetRotationPointDlg->isVisible()) + mySetRotationPointDlg->hide(); + } +} + +/*! + \brief Create one more window with same content. +*/ +void OCCViewer_ViewWindow::onCloneView() +{ + SUIT_ViewWindow* vw = myManager->createViewWindow(); + //vw->show(); + emit viewCloned( vw ); +} + +/*! + Creates one more window with same content +*/ +void OCCViewer_ViewWindow::onAxialScale() +{ + if ( !myScalingDlg ) + myScalingDlg = new OCCViewer_AxialScaleDlg( this ); + + if ( !myScalingDlg->isVisible() ) + { + myScalingDlg->Update(); + myScalingDlg->show(); + } +} + +/*! + Shows Graduated Axes dialog +*/ +void OCCViewer_ViewWindow::onGraduatedAxes() +{ + myCubeAxesDlg->Update(); + myCubeAxesDlg->show(); +} + +void OCCViewer_ViewWindow::onAmbientToogle() +{ + Handle(V3d_Viewer) viewer = myViewPort->getViewer(); + viewer->InitDefinedLights(); + while(viewer->MoreDefinedLights()) + { + Handle(V3d_Light) light = viewer->DefinedLight(); + if(light->Type() != V3d_AMBIENT) + { + Handle(V3d_View) aView3d = myViewPort->getView(); + if( aView3d->IsActiveLight(light) ) viewer->SetLightOff(light); + else viewer->SetLightOn(light); + } + viewer->NextDefinedLights(); + } + viewer->Update(); +} + +/*! + \brief Store view parameters. +*/ +void OCCViewer_ViewWindow::onMemorizeView() +{ + appendViewAspect( getViewParams() ); +} + +/*! + \brief Restore view parameters. +*/ +void OCCViewer_ViewWindow::onRestoreView() +{ + OCCViewer_CreateRestoreViewDlg* aDlg = new OCCViewer_CreateRestoreViewDlg( centralWidget(), this ); + connect( aDlg, SIGNAL( dlgOk() ), this, SLOT( setRestoreFlag() ) ); + aDlg->exec(); + updateViewAspects( aDlg->parameters() ); + if( myRestoreFlag && aDlg->parameters().count() ) + performRestoring( aDlg->currentItem() ); +} + +/*! + \brief Restore view parameters. + \param anItem view parameters +*/ +void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool baseParamsOnly ) +{ + Handle(V3d_View) aView3d = myViewPort->getView(); + + Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False ); + aView3d->SetScale( anItem.scale ); + aView3d->SetCenter( anItem.centerX, anItem.centerY ); + aView3d->SetTwist( anItem.twist ); + aView3d->SetAt( anItem.atX, anItem.atY, anItem.atZ ); + aView3d->SetImmediateUpdate( prev ); + 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 ( !baseParamsOnly ) { + + myModel->setTrihedronShown( anItem.isVisible ); + myModel->setTrihedronSize( anItem.size ); + +#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version + // graduated trihedron + bool anIsVisible = anItem.gtIsVisible; + OCCViewer_AxisWidget::AxisData anAxisData[3]; + anAxisData[0].DrawName = anItem.gtDrawNameX; + anAxisData[1].DrawName = anItem.gtDrawNameZ; + anAxisData[2].DrawName = anItem.gtDrawNameZ; + anAxisData[0].Name = anItem.gtNameX; + anAxisData[1].Name = anItem.gtNameZ; + anAxisData[2].Name = anItem.gtNameZ; + anAxisData[0].NameColor = QColor( anItem.gtNameColorRX, + anItem.gtNameColorGX, + anItem.gtNameColorBX ); + anAxisData[1].NameColor = QColor( anItem.gtNameColorRY, + anItem.gtNameColorGY, + anItem.gtNameColorBY ); + anAxisData[2].NameColor = QColor( anItem.gtNameColorRZ, + anItem.gtNameColorGZ, + anItem.gtNameColorBZ ); + anAxisData[0].DrawValues = anItem.gtDrawValuesX; + anAxisData[1].DrawValues = anItem.gtDrawValuesY; + anAxisData[2].DrawValues = anItem.gtDrawValuesZ; + anAxisData[0].NbValues = anItem.gtNbValuesX; + anAxisData[1].NbValues = anItem.gtNbValuesY; + anAxisData[2].NbValues = anItem.gtNbValuesZ; + anAxisData[0].Offset = anItem.gtOffsetX; + anAxisData[1].Offset = anItem.gtOffsetY; + anAxisData[2].Offset = anItem.gtOffsetZ; + anAxisData[0].Color = QColor( anItem.gtColorRX, + anItem.gtColorGX, + anItem.gtColorBX ); + anAxisData[1].Color = QColor( anItem.gtColorRY, + anItem.gtColorGY, + anItem.gtColorBY ); + anAxisData[2].Color = QColor( anItem.gtColorRZ, + anItem.gtColorGZ, + anItem.gtColorBZ ); + anAxisData[0].DrawTickmarks = anItem.gtDrawTickmarksX; + anAxisData[1].DrawTickmarks = anItem.gtDrawTickmarksY; + anAxisData[2].DrawTickmarks = anItem.gtDrawTickmarksZ; + anAxisData[0].TickmarkLength = anItem.gtTickmarkLengthX; + anAxisData[1].TickmarkLength = anItem.gtTickmarkLengthY; + anAxisData[2].TickmarkLength = anItem.gtTickmarkLengthZ; + + myCubeAxesDlg->SetData( anIsVisible, anAxisData ); + myCubeAxesDlg->ApplyData( aView3d ); +#endif + + } // if ( !baseParamsOnly ) + + myRestoreFlag = 0; +} + +/*! + \brief Set restore flag. +*/ +void OCCViewer_ViewWindow::setRestoreFlag() +{ + myRestoreFlag = 1; +} + +/*! + \brief Called when action "show/hide trihedron" is activated. +*/ +void OCCViewer_ViewWindow::onTrihedronShow() +{ + myModel->toggleTrihedron(); +} + +/*! + \brief Toggles preselection (highlighting) on/off +*/ +void OCCViewer_ViewWindow::onSwitchPreselection( bool on ) +{ + myPreselectionEnabled = on; + myModel->setSelectionOptions( isPreselectionEnabled(), myModel->isSelectionEnabled() ); + + // unhighlight all highlighted objects + /*if ( !on ) { + myModel->unHighlightAll( true, false ); + }*/ + + // update action state if method is called outside + QtxAction* a = dynamic_cast( toolMgr()->action( SwitchPreselectionId ) ); + if ( a && a->isChecked() != on ) { + a->setChecked( on ); + } +} + +/*! + \brief Toggles selection on/off +*/ +void OCCViewer_ViewWindow::onSwitchSelection( bool on ) +{ + mySelectionEnabled = on; + myModel->setSelectionOptions( myModel->isPreselectionEnabled(), isSelectionEnabled() ); + + // update action state if method is called outside + + // preselection + QtxAction* a = dynamic_cast( toolMgr()->action( SwitchPreselectionId ) ); + if ( a ) { + a->setEnabled( on ); + } + + // selection + a = dynamic_cast( toolMgr()->action( SwitchSelectionId ) ); + if ( a && a->isChecked() != on ) { + a->setChecked( on ); + } +} + +/*! + \brief Switches "keyboard free" interaction style on/off +*/ +void OCCViewer_ViewWindow::onSwitchInteractionStyle( bool on ) +{ + myInteractionStyle = on ? (int)SUIT_ViewModel::KEY_FREE : (int)SUIT_ViewModel::STANDARD; + + // update action state if method is called outside + QtxAction* a = dynamic_cast( toolMgr()->action( SwitchInteractionStyleId ) ); + if ( a->isChecked() != on ) + a->setChecked( on ); +} + +/*! + \brief Toogles advanced zooming style (relatively to the cursor position) on/off +*/ +void OCCViewer_ViewWindow::onSwitchZoomingStyle( bool on ) +{ + myViewPort->setAdvancedZoomingEnabled( on ); + + // update action state if method is called outside + QtxAction* a = dynamic_cast( toolMgr()->action( SwitchZoomingStyleId ) ); + if ( a->isChecked() != on ) + a->setChecked( on ); +} + +/*! + \brief Get current interaction style + \return interaction style +*/ +int OCCViewer_ViewWindow::interactionStyle() const +{ + return myInteractionStyle; +} + +/*! + \brief Set current interaction style + \param theStyle interaction style +*/ +void OCCViewer_ViewWindow::setInteractionStyle( const int theStyle ) +{ + onSwitchInteractionStyle( theStyle == (int)SUIT_ViewModel::KEY_FREE ); +} + +/*! + \brief Get current zooming style + \return zooming style +*/ +int OCCViewer_ViewWindow::zoomingStyle() const +{ + return myViewPort->isAdvancedZoomingEnabled() ? 1 : 0; +} + +/*! + \brief Set current zooming style + \param theStyle zooming style +*/ +void OCCViewer_ViewWindow::setZoomingStyle( const int theStyle ) +{ + onSwitchZoomingStyle( theStyle == 1 ); +} + +/*! + \brief Dump view window contents to the pixmap. + \return pixmap containing all scene rendered in the window +*/ +QImage OCCViewer_ViewWindow::dumpView() +{ + Handle(V3d_View) view = myViewPort->getView(); + if ( view.IsNull() ) + return QImage(); + + int aWidth = myViewPort->width(); + int aHeight = myViewPort->height(); + QApplication::syncX(); + view->Redraw(); // In order to reactivate GL context + //view->Update(); + + OpenGLUtils_FrameBuffer aFrameBuffer; + if( aFrameBuffer.init( aWidth, aHeight ) ) + { + QImage anImage( aWidth, aHeight, QImage::Format_RGB32 ); + + glPushAttrib( GL_VIEWPORT_BIT ); + glViewport( 0, 0, aWidth, aHeight ); + aFrameBuffer.bind(); + + // draw scene + view->Redraw(); + + aFrameBuffer.unbind(); + glPopAttrib(); + + aFrameBuffer.bind(); + glReadPixels( 0, 0, aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() ); + aFrameBuffer.unbind(); + + anImage = anImage.rgbSwapped(); + anImage = anImage.mirrored(); + return anImage; + } + // if frame buffers are unsupported, use old functionality + //view->Redraw(); + + unsigned char* data = new unsigned char[ aWidth*aHeight*4 ]; + + QPoint p = myViewPort->mapFromParent(myViewPort->geometry().topLeft()); + + glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, + data); + + QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 ); + anImage = anImage.mirrored(); + anImage = anImage.rgbSwapped(); + return anImage; +} + +bool OCCViewer_ViewWindow::dumpViewToFormat( const QImage& img, + const QString& fileName, + const QString& format ) +{ + if ( format != "PS" && format != "EPS") + return SUIT_ViewWindow::dumpViewToFormat( img, fileName, format ); + + Handle(Visual3d_View) a3dView = myViewPort->getView()->View(); + + if (format == "PS") + a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_PostScript); + else if (format == "EPS") + a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_EnhPostScript); + + return true; +} + + +QString OCCViewer_ViewWindow::filter() const +{ + return tr( "OCC_IMAGE_FILES" ); +} + + +/*! + \brief Set parameters of the cutting plane + \param on if \c true, cutting plane is enabled + \param x X position of plane point + \param y Y position of plane point + \param z Z position of plane point + \param dx X coordinate of plane normal + \param dy Y coordinate of plane normal + \param dz Z coordinate of plane normal +*/ +void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x, const double y, const double z, + const double dx, const double dy, const double dz ) +{ + Handle(V3d_View) view = myViewPort->getView(); + if ( view.IsNull() ) + return; + + if ( on ) { + Handle(V3d_Viewer) viewer = myViewPort->getViewer(); + + // try to use already existing plane or create a new one + Handle(V3d_Plane) clipPlane; + + // calculate new a,b,c,d values for the plane + gp_Pln pln (gp_Pnt(x, y, z), gp_Dir(dx, dy, dz)); + double a, b, c, d; + pln.Coefficients(a, b, c, d); + + Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); + Handle(Graphic3d_ClipPlane) aClipPlane; + if(aPlanes.Size() > 0 ) { + Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); + aClipPlane = anIter.Value(); + aClipPlane->SetEquation(pln); + aClipPlane->SetOn(Standard_True); + } else { + aClipPlane = new Graphic3d_ClipPlane(pln); + view->AddClipPlane(aClipPlane); + aClipPlane->SetOn(Standard_True); + } + } + else { + Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); + Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); + for( ;anIter.More();anIter.Next() ){ + Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); + aClipPlane->SetOn(Standard_False); + } + } + + view->Update(); + view->Redraw(); +} + +void OCCViewer_ViewWindow::setCuttingPlane( bool on, const gp_Pln pln ) +{ + gp_Dir aDir = pln.Axis().Direction(); + gp_Pnt aPnt = pln.Location(); + setCuttingPlane(on, aPnt.X(), aPnt.Y(), aPnt.Z(), aDir.X(), aDir.Y(), aDir.Z()); +} + + +/*! + \brief Check if any cutting plane is enabled + \return \c true if at least one cutting plane is enabled +*/ +bool OCCViewer_ViewWindow::isCuttingPlane() +{ + Handle(V3d_View) view = myViewPort->getView(); + bool res = false; + Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); + Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); + for( ;anIter.More();anIter.Next() ) { + Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); + if(aClipPlane->IsOn()) { + res = true; + break; + } + } + return res; +} + +/*! + \brief Get the visual parameters of the view window. + \return visual parameters of view window +*/ +viewAspect OCCViewer_ViewWindow::getViewParams() const +{ + double centerX, centerY, projX, projY, projZ, twist; + double atX, atY, atZ, eyeX, eyeY, eyeZ; + double aScaleX, aScaleY, aScaleZ; + + Handle(V3d_View) aView3d = myViewPort->getView(); + + aView3d->Center( centerX, centerY ); + aView3d->Proj( projX, projY, projZ ); + aView3d->At( atX, atY, atZ ); + aView3d->Eye( eyeX, eyeY, eyeZ ); + twist = aView3d->Twist(); + + aView3d->AxialScale(aScaleX,aScaleY,aScaleZ); + + bool isShown = myModel->isTrihedronVisible(); + double size = myModel->trihedronSize(); + + QString aName = QTime::currentTime().toString() + QString::fromLatin1( " h:m:s" ); + + viewAspect params; + params.scale = aView3d->Scale(); + params.centerX = centerX; + params.centerY = centerY; + params.projX = projX; + params.projY = projY; + params.projZ = projZ; + params.twist = twist; + params.atX = atX; + params.atY = atY; + params.atZ = atZ; + params.eyeX = eyeX; + params.eyeY = eyeY; + params.eyeZ = eyeZ; + params.scaleX = aScaleX; + params.scaleY = aScaleY; + params.scaleZ = aScaleZ; + params.name = aName; + params.isVisible= isShown; + params.size = size; + +#if OCC_VERSION_LARGE > 0x06030009 // available only with OCC-6.3-sp10 and higher version + // graduated trihedron + bool anIsVisible = false; + OCCViewer_AxisWidget::AxisData anAxisData[3]; + myCubeAxesDlg->GetData( anIsVisible, anAxisData ); + + params.gtIsVisible = anIsVisible; + params.gtDrawNameX = anAxisData[0].DrawName; + params.gtDrawNameY = anAxisData[1].DrawName; + params.gtDrawNameZ = anAxisData[2].DrawName; + params.gtNameX = anAxisData[0].Name; + params.gtNameY = anAxisData[1].Name; + params.gtNameZ = anAxisData[2].Name; + params.gtNameColorRX = anAxisData[0].NameColor.red(); + params.gtNameColorGX = anAxisData[0].NameColor.green(); + params.gtNameColorBX = anAxisData[0].NameColor.blue(); + params.gtNameColorRY = anAxisData[1].NameColor.red(); + params.gtNameColorGY = anAxisData[1].NameColor.green(); + params.gtNameColorBY = anAxisData[1].NameColor.blue(); + params.gtNameColorRZ = anAxisData[2].NameColor.red(); + params.gtNameColorGZ = anAxisData[2].NameColor.green(); + params.gtNameColorBZ = anAxisData[2].NameColor.blue(); + params.gtDrawValuesX = anAxisData[0].DrawValues; + params.gtDrawValuesY = anAxisData[1].DrawValues; + params.gtDrawValuesZ = anAxisData[2].DrawValues; + params.gtNbValuesX = anAxisData[0].NbValues; + params.gtNbValuesY = anAxisData[1].NbValues; + params.gtNbValuesZ = anAxisData[2].NbValues; + params.gtOffsetX = anAxisData[0].Offset; + params.gtOffsetY = anAxisData[1].Offset; + params.gtOffsetZ = anAxisData[2].Offset; + params.gtColorRX = anAxisData[0].Color.red(); + params.gtColorGX = anAxisData[0].Color.green(); + params.gtColorBX = anAxisData[0].Color.blue(); + params.gtColorRY = anAxisData[1].Color.red(); + params.gtColorGY = anAxisData[1].Color.green(); + params.gtColorBY = anAxisData[1].Color.blue(); + params.gtColorRZ = anAxisData[2].Color.red(); + params.gtColorGZ = anAxisData[2].Color.green(); + params.gtColorBZ = anAxisData[2].Color.blue(); + params.gtDrawTickmarksX = anAxisData[0].DrawTickmarks; + params.gtDrawTickmarksY = anAxisData[1].DrawTickmarks; + params.gtDrawTickmarksZ = anAxisData[2].DrawTickmarks; + params.gtTickmarkLengthX = anAxisData[0].TickmarkLength; + params.gtTickmarkLengthY = anAxisData[1].TickmarkLength; + params.gtTickmarkLengthZ = anAxisData[2].TickmarkLength; +#endif + + return params; +} + +/*! + \brief Get visual parameters of this view window. + \return visual parameters of view window +*/ +QString OCCViewer_ViewWindow::getVisualParameters() +{ + viewAspect params = getViewParams(); + + QStringList data; + + data << QString( "scale=%1" ) .arg( params.scale, 0, 'e', 12 ); + data << QString( "centerX=%1" ) .arg( params.centerX, 0, 'e', 12 ); + data << QString( "centerY=%1" ) .arg( params.centerY, 0, 'e', 12 ); + data << QString( "projX=%1" ) .arg( params.projX, 0, 'e', 12 ); + data << QString( "projY=%1" ) .arg( params.projY, 0, 'e', 12 ); + data << QString( "projZ=%1" ) .arg( params.projZ, 0, 'e', 12 ); + data << QString( "twist=%1" ) .arg( params.twist, 0, 'e', 12 ); + data << QString( "atX=%1" ) .arg( params.atX, 0, 'e', 12 ); + data << QString( "atY=%1" ) .arg( params.atY, 0, 'e', 12 ); + data << QString( "atZ=%1" ) .arg( params.atZ, 0, 'e', 12 ); + data << QString( "eyeX=%1" ) .arg( params.eyeX, 0, 'e', 12 ); + data << QString( "eyeY=%1" ) .arg( params.eyeY, 0, 'e', 12 ); + data << QString( "eyeZ=%1" ) .arg( params.eyeZ, 0, 'e', 12 ); + data << QString( "scaleX=%1" ) .arg( params.scaleX, 0, 'e', 12 ); + data << QString( "scaleY=%1" ) .arg( params.scaleY, 0, 'e', 12 ); + data << QString( "scaleZ=%1" ) .arg( params.scaleZ, 0, 'e', 12 ); + data << QString( "isVisible=%1" ).arg( params.isVisible ); + data << QString( "size=%1" ) .arg( params.size, 0, 'f', 2 ); + + ClipPlanesList aPlanes = myModel->getClipPlanes(); + for ( int i=0; i < aPlanes.size(); i++ ) + { + OCCViewer_ClipPlane& aPlane = aPlanes[i]; + QString ClippingPlane = QString( "ClippingPlane%1=").arg( i+1 ); + ClippingPlane += QString( "Mode~%1;").arg( (int)aPlane.Mode ); + ClippingPlane += QString( "IsActive~%1;").arg( aPlane.IsOn ); + switch ( aPlane.Mode ) + { + case OCCViewer_ClipPlane::Absolute : + { + ClippingPlane += QString( "AbsoluteOrientation~%1;" ).arg( aPlane.OrientationType ); + + if ( aPlane.OrientationType == OCCViewer_ClipPlane::AbsoluteCustom ) + { + ClippingPlane += QString( "Dx~%1;" ).arg( aPlane.AbsoluteOrientation.Dx ); + ClippingPlane += QString( "Dy~%1;" ).arg( aPlane.AbsoluteOrientation.Dy ); + ClippingPlane += QString( "Dz~%1;" ).arg( aPlane.AbsoluteOrientation.Dz ); + } + else + { + ClippingPlane += QString( "IsInvert~%1;" ).arg( aPlane.AbsoluteOrientation.IsInvert ); + } + } + break; + + case OCCViewer_ClipPlane::Relative : + { + ClippingPlane += QString( "RelativeOrientation~%1;" ).arg( aPlane.OrientationType ); + ClippingPlane += QString( "Rotation1~%1;" ).arg( aPlane.RelativeOrientation.Rotation1 ); + ClippingPlane += QString( "Rotation2~%1" ).arg( aPlane.RelativeOrientation.Rotation2 ); + } + break; + } + + ClippingPlane += QString( "X~%1;" ).arg( aPlane.X ); + ClippingPlane += QString( "Y~%1;" ).arg( aPlane.Y ); + ClippingPlane += QString( "Z~%1;" ).arg( aPlane.Z ); + 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 ); + data << QString( "gtDrawNameX=%1" ) .arg( params.gtDrawNameX ); + data << QString( "gtDrawNameY=%1" ) .arg( params.gtDrawNameY ); + data << QString( "gtDrawNameZ=%1" ) .arg( params.gtDrawNameZ ); + data << QString( "gtNameX=%1" ) .arg( params.gtNameX ); + data << QString( "gtNameY=%1" ) .arg( params.gtNameY ); + data << QString( "gtNameZ=%1" ) .arg( params.gtNameZ ); + data << QString( "gtNameColorRX=%1" ) .arg( params.gtNameColorRX ); + data << QString( "gtNameColorGX=%1" ) .arg( params.gtNameColorGX ); + data << QString( "gtNameColorBX=%1" ) .arg( params.gtNameColorBX ); + data << QString( "gtNameColorRY=%1" ) .arg( params.gtNameColorRY ); + data << QString( "gtNameColorGY=%1" ) .arg( params.gtNameColorGY ); + data << QString( "gtNameColorBY=%1" ) .arg( params.gtNameColorBY ); + data << QString( "gtNameColorRZ=%1" ) .arg( params.gtNameColorRZ ); + data << QString( "gtNameColorGZ=%1" ) .arg( params.gtNameColorGZ ); + data << QString( "gtNameColorBZ=%1" ) .arg( params.gtNameColorBZ ); + data << QString( "gtDrawValuesX=%1" ) .arg( params.gtDrawValuesX ); + data << QString( "gtDrawValuesY=%1" ) .arg( params.gtDrawValuesY ); + data << QString( "gtDrawValuesZ=%1" ) .arg( params.gtDrawValuesZ ); + data << QString( "gtNbValuesX=%1" ) .arg( params.gtNbValuesX ); + data << QString( "gtNbValuesY=%1" ) .arg( params.gtNbValuesY ); + data << QString( "gtNbValuesZ=%1" ) .arg( params.gtNbValuesZ ); + data << QString( "gtOffsetX=%1" ) .arg( params.gtOffsetX ); + data << QString( "gtOffsetY=%1" ) .arg( params.gtOffsetY ); + data << QString( "gtOffsetZ=%1" ) .arg( params.gtOffsetZ ); + data << QString( "gtColorRX=%1" ) .arg( params.gtColorRX ); + data << QString( "gtColorGX=%1" ) .arg( params.gtColorGX ); + data << QString( "gtColorBX=%1" ) .arg( params.gtColorBX ); + data << QString( "gtColorRY=%1" ) .arg( params.gtColorRY ); + data << QString( "gtColorGY=%1" ) .arg( params.gtColorGY ); + data << QString( "gtColorBY=%1" ) .arg( params.gtColorBY ); + data << QString( "gtColorRZ=%1" ) .arg( params.gtColorRZ ); + data << QString( "gtColorGZ=%1" ) .arg( params.gtColorGZ ); + data << QString( "gtColorBZ=%1" ) .arg( params.gtColorBZ ); + data << QString( "gtDrawTickmarksX=%1" ) .arg( params.gtDrawTickmarksX ); + data << QString( "gtDrawTickmarksY=%1" ) .arg( params.gtDrawTickmarksY ); + data << QString( "gtDrawTickmarksZ=%1" ) .arg( params.gtDrawTickmarksZ ); + data << QString( "gtTickmarkLengthX=%1" ).arg( params.gtTickmarkLengthX ); + data << QString( "gtTickmarkLengthY=%1" ).arg( params.gtTickmarkLengthY ); + data << QString( "gtTickmarkLengthZ=%1" ).arg( params.gtTickmarkLengthZ ); +#endif + QString bg = Qtx::backgroundToString( background() ).replace( "=", "$" ); + data << QString( "background=%1" ).arg( bg ); + + return data.join("*"); +} + +/*! + \brief Restore visual parameters of the view window. + \param parameters visual parameters of view window +*/ +void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters ) +{ + viewAspect params; + ClipPlanesList aClipPlanes; + QStringList data = parameters.split( '*' ); + Qtx::BackgroundData bgData; + if ( parameters.contains( '=' ) ) // new format - "scale=1.000e+00*centerX=0.000e+00..." + { + foreach( QString param, data ) { + QString paramName = param.section( '=', 0, 0 ).trimmed(); + QString paramValue = param.section( '=', 1, 1 ).trimmed(); + if ( paramName == "scale" ) params.scale = paramValue.toDouble(); + else if ( paramName == "centerX" ) params.centerX = paramValue.toDouble(); + else if ( paramName == "centerY" ) params.centerY = paramValue.toDouble(); + else if ( paramName == "projX" ) params.projX = paramValue.toDouble(); + else if ( paramName == "projY" ) params.projY = paramValue.toDouble(); + else if ( paramName == "projZ" ) params.projZ = paramValue.toDouble(); + else if ( paramName == "twist" ) params.twist = paramValue.toDouble(); + else if ( paramName == "atX" ) params.atX = paramValue.toDouble(); + else if ( paramName == "atY" ) params.atY = paramValue.toDouble(); + else if ( paramName == "atZ" ) params.atZ = paramValue.toDouble(); + else if ( paramName == "eyeX" ) params.eyeX = paramValue.toDouble(); + else if ( paramName == "eyeY" ) params.eyeY = paramValue.toDouble(); + else if ( paramName == "eyeZ" ) params.eyeZ = paramValue.toDouble(); + else if ( paramName == "scaleX" ) params.scaleX = paramValue.toDouble(); + else if ( paramName == "scaleY" ) params.scaleY = paramValue.toDouble(); + 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" ) ) + { + QStringList ClipPlaneData = paramValue.split( ';' ); + OCCViewer_ClipPlane aPlane; + 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.Mode = ( OCCViewer_ClipPlane::PlaneMode ) ClipPlane_paramValue.toInt(); + } + else if ( ClipPlane_paramName == "IsActive" ) aPlane.IsOn = 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 + { + switch ( aPlane.Mode ) + { + case OCCViewer_ClipPlane::Absolute : + if ( ClipPlane_paramName == "Dx" ) aPlane.AbsoluteOrientation.Dx = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Dy" ) aPlane.AbsoluteOrientation.Dy = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Dz" ) aPlane.AbsoluteOrientation.Dz = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "IsInvert" ) aPlane.AbsoluteOrientation.IsInvert = ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "AbsoluteOrientation" ) aPlane.OrientationType = ClipPlane_paramValue.toInt(); + break; + + case OCCViewer_ClipPlane::Relative : + if ( ClipPlane_paramName == "RelativeOrientation" ) aPlane.OrientationType = ClipPlane_paramValue.toInt(); + else if ( ClipPlane_paramName == "Rotation1" ) aPlane.RelativeOrientation.Rotation1 = ClipPlane_paramValue.toDouble(); + else if ( ClipPlane_paramName == "Rotation2" ) aPlane.RelativeOrientation.Rotation2 = ClipPlane_paramValue.toDouble(); + break; + } + } + } + aClipPlanes.push_back(aPlane); + } + // graduated trihedron + else if ( paramName == "gtIsVisible" ) params.gtIsVisible = paramValue.toInt(); + else if ( paramName == "gtDrawNameX" ) params.gtDrawNameX = paramValue.toInt(); + else if ( paramName == "gtDrawNameY" ) params.gtDrawNameY = paramValue.toInt(); + else if ( paramName == "gtDrawNameZ" ) params.gtDrawNameZ = paramValue.toInt(); + else if ( paramName == "gtNameX" ) params.gtNameX = paramValue; + else if ( paramName == "gtNameY" ) params.gtNameY = paramValue; + else if ( paramName == "gtNameZ" ) params.gtNameZ = paramValue; + else if ( paramName == "gtNameColorRX" ) params.gtNameColorRX = paramValue.toInt(); + else if ( paramName == "gtNameColorGX" ) params.gtNameColorGX = paramValue.toInt(); + else if ( paramName == "gtNameColorBX" ) params.gtNameColorBX = paramValue.toInt(); + else if ( paramName == "gtNameColorRY" ) params.gtNameColorRY = paramValue.toInt(); + else if ( paramName == "gtNameColorGY" ) params.gtNameColorGY = paramValue.toInt(); + else if ( paramName == "gtNameColorBY" ) params.gtNameColorBY = paramValue.toInt(); + else if ( paramName == "gtNameColorRZ" ) params.gtNameColorRZ = paramValue.toInt(); + else if ( paramName == "gtNameColorGZ" ) params.gtNameColorGZ = paramValue.toInt(); + else if ( paramName == "gtNameColorBZ" ) params.gtNameColorBZ = paramValue.toInt(); + else if ( paramName == "gtDrawValuesX" ) params.gtDrawValuesX = paramValue.toInt(); + else if ( paramName == "gtDrawValuesY" ) params.gtDrawValuesY = paramValue.toInt(); + else if ( paramName == "gtDrawValuesZ" ) params.gtDrawValuesZ = paramValue.toInt(); + else if ( paramName == "gtNbValuesX" ) params.gtNbValuesX = paramValue.toInt(); + else if ( paramName == "gtNbValuesY" ) params.gtNbValuesY = paramValue.toInt(); + else if ( paramName == "gtNbValuesZ" ) params.gtNbValuesZ = paramValue.toInt(); + else if ( paramName == "gtOffsetX" ) params.gtOffsetX = paramValue.toInt(); + else if ( paramName == "gtOffsetY" ) params.gtOffsetY = paramValue.toInt(); + else if ( paramName == "gtOffsetZ" ) params.gtOffsetZ = paramValue.toInt(); + else if ( paramName == "gtColorRX" ) params.gtColorRX = paramValue.toInt(); + else if ( paramName == "gtColorGX" ) params.gtColorGX = paramValue.toInt(); + else if ( paramName == "gtColorBX" ) params.gtColorBX = paramValue.toInt(); + else if ( paramName == "gtColorRY" ) params.gtColorRY = paramValue.toInt(); + else if ( paramName == "gtColorGY" ) params.gtColorGY = paramValue.toInt(); + else if ( paramName == "gtColorBY" ) params.gtColorBY = paramValue.toInt(); + else if ( paramName == "gtColorRZ" ) params.gtColorRZ = paramValue.toInt(); + else if ( paramName == "gtColorGZ" ) params.gtColorGZ = paramValue.toInt(); + else if ( paramName == "gtColorBZ" ) params.gtColorBZ = paramValue.toInt(); + else if ( paramName == "gtDrawTickmarksX" ) params.gtDrawTickmarksX = paramValue.toInt(); + else if ( paramName == "gtDrawTickmarksY" ) params.gtDrawTickmarksY = paramValue.toInt(); + else if ( paramName == "gtDrawTickmarksZ" ) params.gtDrawTickmarksZ = paramValue.toInt(); + else if ( paramName == "gtTickmarkLengthX" ) params.gtTickmarkLengthX = paramValue.toInt(); + else if ( paramName == "gtTickmarkLengthY" ) params.gtTickmarkLengthY = paramValue.toInt(); + else if ( paramName == "gtTickmarkLengthZ" ) params.gtTickmarkLengthZ = paramValue.toInt(); + else if ( paramName == "background" ) { + QString bg = paramValue.replace( "$", "=" ); + bgData = Qtx::stringToBackground( bg ); + } + } + } + else // old format - "1.000e+00*0.000e+00..." + { + int idx = 0; + params.scale = data.count() > idx ? data[idx++].toDouble() : 1.0; + params.centerX = data.count() > idx ? data[idx++].toDouble() : 0.0; + params.centerY = data.count() > idx ? data[idx++].toDouble() : 0.0; + params.projX = data.count() > idx ? data[idx++].toDouble() : sqrt(1./3); + params.projY = data.count() > idx ? data[idx++].toDouble() : -sqrt(1./3); + params.projZ = data.count() > idx ? data[idx++].toDouble() : sqrt(1./3); + params.twist = data.count() > idx ? data[idx++].toDouble() : 0.0; + params.atX = data.count() > idx ? data[idx++].toDouble() : 0.0; + params.atY = data.count() > idx ? data[idx++].toDouble() : 0.0; + params.atZ = data.count() > idx ? data[idx++].toDouble() : 0.0; + params.eyeX = data.count() > idx ? data[idx++].toDouble() : sqrt(250000./3); + params.eyeY = data.count() > idx ? data[idx++].toDouble() : -sqrt(250000./3); + params.eyeZ = data.count() > idx ? data[idx++].toDouble() : sqrt(250000./3); + params.scaleX = data.count() > idx ? data[idx++].toDouble() : 1.0; + params.scaleY = data.count() > idx ? data[idx++].toDouble() : 1.0; + params.scaleZ = data.count() > idx ? data[idx++].toDouble() : 1.0; + params.isVisible = data.count() > idx ? data[idx++].toInt() : 1; + params.size = data.count() > idx ? data[idx++].toDouble() : 100.0; + } + performRestoring( params ); + setBackground( bgData ); + myModel->setClipPlanes(aClipPlanes); +} + +/*! + \brief Handle show event. + + Emits Show() signal. + + \param theEvent show event +*/ +void OCCViewer_ViewWindow::showEvent( QShowEvent* theEvent ) +{ + emit Show( theEvent ); +} + +/*! + \brief Handle hide event. + + Emits Hide() signal. + + \param theEvent hide event +*/ +void OCCViewer_ViewWindow::hideEvent( QHideEvent* theEvent ) +{ + emit Hide( theEvent ); +} + + +/*! + Creates default sketcher. [ virtual protected ] +*/ +OCCViewer_ViewSketcher* OCCViewer_ViewWindow::createSketcher( int type ) +{ + if ( type == Rect ) + return new OCCViewer_RectSketcher( this, type ); + if ( type == Polygon ) + return new OCCViewer_PolygonSketcher( this, type ); + return 0; +} + +void OCCViewer_ViewWindow::initSketchers() +{ + if ( mySketchers.isEmpty() ) + { + mySketchers.append( createSketcher( Rect ) ); + mySketchers.append( createSketcher( Polygon ) ); + } +} + +OCCViewer_ViewSketcher* OCCViewer_ViewWindow::getSketcher( const int typ ) +{ + OCCViewer_ViewSketcher* sketcher = 0; + QList::Iterator it; + for ( it = mySketchers.begin(); it != mySketchers.end() && !sketcher; ++it ) + { + OCCViewer_ViewSketcher* sk = (*it); + if ( sk->type() == typ ) + sketcher = sk; + } + return sketcher; +} + +/*! + Handles requests for sketching in the active view. [ virtual public ] +*/ +void OCCViewer_ViewWindow::activateSketching( int type ) +{ + OCCViewer_ViewPort3d* vp = getViewPort(); + if ( !vp ) + return; + + if ( !vp->isSketchingEnabled() ) + return; + + /* Finish current sketching */ + if ( type == NoSketching ) + { + if ( mypSketcher ) + { + onSketchingFinished(); + mypSketcher->deactivate(); + mypSketcher = 0; + } + } + /* Activate new sketching */ + else + { + activateSketching( NoSketching ); /* concurrency not suported */ + mypSketcher = getSketcher( type ); + if ( mypSketcher ) + { + mypSketcher->activate(); + onSketchingStarted(); + } + } +} + +/*! + Unhilights detected entities. [ virtual protected ] +*/ +void OCCViewer_ViewWindow::onSketchingStarted() +{ +} + +/*! + Selection by rectangle or polygon. [ virtual protected ] +*/ +void OCCViewer_ViewWindow::onSketchingFinished() +{ + MESSAGE("OCCViewer_ViewWindow::onSketchingFinished()") + if ( mypSketcher && mypSketcher->result() == OCCViewer_ViewSketcher::Accept ) + { + Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); + bool append = bool( mypSketcher->buttonState() && mypSketcher->isHasShift() ); + switch( mypSketcher->type() ) + { + case Rect: + { + QRect* aRect = (QRect*)mypSketcher->data(); + if( aRect ) + { + int aLeft = aRect->left(); + int aRight = aRect->right(); + int aTop = aRect->top(); + int aBottom = aRect->bottom(); +// myRect = aRect; + + if( append ) + ic->ShiftSelect( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False ); + else + ic->Select( aLeft, aBottom, aRight, aTop, getViewPort()->getView(), Standard_False ); + } + } + break; + case Polygon: + { + QPolygon* aPolygon = (QPolygon*)mypSketcher->data(); + if( aPolygon ) + { + int size = aPolygon->size(); + TColgp_Array1OfPnt2d anArray( 1, size ); + + QPolygon::Iterator it = aPolygon->begin(); + QPolygon::Iterator itEnd = aPolygon->end(); + for( int index = 1; it != itEnd; ++it, index++ ) + { + QPoint aPoint = *it; + anArray.SetValue( index, gp_Pnt2d( aPoint.x(), aPoint.y() ) ); + } + + if( append ) + ic->ShiftSelect( anArray, getViewPort()->getView(), Standard_False ); + else + ic->Select( anArray, getViewPort()->getView(), Standard_False ); + } + } + break; + default: + break; + } + + OCCViewer_ViewManager* aViewMgr = ( OCCViewer_ViewManager* )getViewManager(); + aViewMgr->getOCCViewer()->performSelectionChanged(); + } +} + +OCCViewer_ViewPort3d* OCCViewer_ViewWindow::getViewPort() +{ + return myViewPort; +} + +bool OCCViewer_ViewWindow::transformRequested() const +{ + return ( myOperation != NOTHING ); +} + +bool OCCViewer_ViewWindow::transformInProcess() const +{ + return myEventStarted; +} + +void OCCViewer_ViewWindow::setTransformInProcess( bool bOn ) +{ + myEventStarted = bOn; +} + +/*! + Set enabled state of transformation (rotate, zoom, etc) +*/ +void OCCViewer_ViewWindow::setTransformEnabled( const OperationType id, const bool on ) +{ + if ( id != NOTHING ) myStatus.insert( id, on ); +} + +/*! + \return enabled state of transformation (rotate, zoom, etc) +*/ +bool OCCViewer_ViewWindow::transformEnabled( const OperationType id ) const +{ + return myStatus.contains( id ) ? myStatus[ id ] : true; +} + +void OCCViewer_ViewWindow::onMaximizedView() +{ + setMaximized(!isMaximized()); +} + +void OCCViewer_ViewWindow::returnTo3dView() +{ + setReturnedTo3dView( true ); +} + +void OCCViewer_ViewWindow::setReturnedTo3dView(bool isVisible3dView) +{ + if ( !toolMgr()->action( ReturnTo3dViewId ) || + toolMgr()->isShown(ReturnTo3dViewId) != isVisible3dView ) return; + if ( !isVisible3dView ) + toolMgr()->show( ReturnTo3dViewId ); + else + toolMgr()->hide( ReturnTo3dViewId ); + if ( isVisible3dView ) emit returnedTo3d( ); +} + + +void OCCViewer_ViewWindow::setMaximized(bool toMaximize, bool toSendSignal) +{ + QAction* anAction = toolMgr()->action( MaximizedId ); + QAction* anAction2 = toolMgr()->action( ReturnTo3dViewId ); + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); + if ( toMaximize ) { + anAction->setText( tr( "MNU_MINIMIZE_VIEW" ) ); + anAction->setToolTip( tr( "MNU_MINIMIZE_VIEW" ) ); + anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MINIMIZE" ) ) ); + anAction->setStatusTip( tr( "DSC_MINIMIZE_VIEW" ) ); + if ( anAction2 && my2dMode != No2dMode ) toolMgr()->show( ReturnTo3dViewId ); + if (toSendSignal) { + emit maximized( this, true ); + } + } + else { + anAction->setText( tr( "MNU_MAXIMIZE_VIEW" ) ); + anAction->setToolTip( tr( "MNU_MAXIMIZE_VIEW" ) ); + anAction->setIcon( aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_MAXIMIZE" ) ) ); + anAction->setStatusTip( tr( "DSC_MAXIMIZE_VIEW" ) ); + if ( anAction2 && my2dMode != No2dMode ) toolMgr()->hide( ReturnTo3dViewId ); + if (toSendSignal) { + emit maximized( this, false ); + } + } +} + +bool OCCViewer_ViewWindow::isMaximized() const +{ + return !(toolMgr()->action( MaximizedId )->text() == tr( "MNU_MAXIMIZE_VIEW" )); +} + +void OCCViewer_ViewWindow::setSketcherStyle( bool enable ) +{ + IsSketcherStyle = enable; +} + +bool OCCViewer_ViewWindow::isSketcherStyle() const +{ + return IsSketcherStyle; +} + + +void OCCViewer_ViewWindow::set2dMode(Mode2dType theType) +{ + my2dMode = theType; +} + +// obsolete +QColor OCCViewer_ViewWindow::backgroundColor() const +{ + return myViewPort ? myViewPort->backgroundColor() : Qt::black; +} + +// obsolete +void OCCViewer_ViewWindow::setBackgroundColor( const QColor& theColor ) +{ + if ( myViewPort ) myViewPort->setBackgroundColor( theColor ); +} + +Qtx::BackgroundData OCCViewer_ViewWindow::background() const +{ + return myViewPort ? myViewPort->background() : Qtx::BackgroundData(); +} + +void OCCViewer_ViewWindow::setBackground( const Qtx::BackgroundData& theBackground ) +{ + if ( myViewPort ) myViewPort->setBackground( theBackground ); +} + +/*! + Clears view aspects +*/ +void OCCViewer_ViewWindow::clearViewAspects() +{ + myViewAspects.clear(); +} + +/*! + \return const reference to list of view aspects +*/ +const viewAspectList& OCCViewer_ViewWindow::getViewAspects() +{ + return myViewAspects; +} + +/*! + Appends new view aspect + \param aParams - new view aspects +*/ +void OCCViewer_ViewWindow::appendViewAspect( const viewAspect& aParams ) +{ + myViewAspects.append( aParams ); +} + +/*! + Replaces old view aspects by new ones + \param aViewList - list of new view aspects +*/ +void OCCViewer_ViewWindow::updateViewAspects( const viewAspectList& aViewList ) +{ + myViewAspects = aViewList; +} + +/*! + Get camera properties for the OCC view window. + \return shared pointer on camera properties. +*/ +SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties() +{ + SUIT_CameraProperties aProps; + + Handle(V3d_View) aSourceView = getViewPort()->getView(); + if ( aSourceView.IsNull() ) + return aProps; + + if ( get2dMode() == No2dMode ) { + aProps.setDimension( SUIT_CameraProperties::Dim3D ); + } + else { + aProps.setDimension( SUIT_CameraProperties::Dim2D ); + aProps.setViewSide( (SUIT_CameraProperties::ViewSide)(int)get2dMode() ); + } + + // read common properites of the view + Standard_Real anUpDir[3]; + Standard_Real aPrjDir[3]; + Standard_Real aMapScale[2]; + Standard_Real aTranslation[3]; + Standard_Real anAxialScale[3]; + + aSourceView->Up(anUpDir[0], anUpDir[1], anUpDir[2]); + aSourceView->Proj(aPrjDir[0], aPrjDir[1], aPrjDir[2]); + aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]); + aSourceView->Size(aMapScale[0], aMapScale[1]); + + getViewPort()->getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); + + // we use similar depth to the one used in perspective projection + // to proivde a convinience synchronization with other camera views that + // can switch between orthogonal & perspective projection. otherwise, + // the camera will get to close when switching from orthogonal to perspective. + Standard_Real aCameraDepth = aSourceView->Depth() + aSourceView->ZSize() * 0.5; + + // store common props + aProps.setViewUp(anUpDir[0], anUpDir[1], anUpDir[2]); + aProps.setMappingScale(aMapScale[1] / 2.0); + aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); + + // generate view orientation matrix for transforming OCC projection reference point + // into a camera (eye) position. + gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed( + gp_Dir(aPrjDir[0], aPrjDir[1], aPrjDir[2])); + + gp_Trsf aTrsf; + aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aPrjDir[0], aTranslation[0], + aLeftDir.Y(), anUpDir[1], aPrjDir[1], aTranslation[1], + aLeftDir.Z(), anUpDir[2], aPrjDir[2], aTranslation[2], + Precision::Confusion(), + Precision::Confusion() ); + +// get projection reference point in view coordinates +#if OCC_VERSION_LARGE > 0x06070000 + gp_Pnt aProjRef = aSourceView->Camera()->ProjectionShift(); + aProjRef.SetX( -aProjRef.X() ); + aProjRef.SetY( -aProjRef.Y() ); +#else + Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint(); +#endif + + // transform to world-space coordinate system + gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aCameraDepth).Transformed(aTrsf); + + // compute focal point + double aFocalPoint[3]; + + aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aCameraDepth; + aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aCameraDepth; + aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aCameraDepth; + + aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]); + aProps.setPosition(aPosition.X(), aPosition.Y(), aPosition.Z()); + + return aProps; +} + +/*! + Synchronize views. + This implementation synchronizes OCC view's camera propreties. +*/ +void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView ) +{ + bool blocked = blockSignals( true ); + + SUIT_CameraProperties aProps = theView->cameraProperties(); + if ( !cameraProperties().isCompatible( aProps ) ) { + // other view, this one is being currently synchronized to, seems has become incompatible + // we have to break synchronization + updateSyncViews(); + return; + } + + Handle(V3d_View) aDestView = getViewPort()->getView(); + + aDestView->SetImmediateUpdate( Standard_False ); + + double anUpDir[3]; + double aPosition[3]; + double aFocalPoint[3]; + double aMapScaling; + double anAxialScale[3]; + + // get common properties + aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]); + aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]); + aProps.getViewUp(anUpDir[0], anUpDir[1], anUpDir[2]); + aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); + aMapScaling = aProps.getMappingScale() * 2.0; + + gp_Dir aProjDir(aPosition[0] - aFocalPoint[0], + aPosition[1] - aFocalPoint[1], + aPosition[2] - aFocalPoint[2]); + + // get custom view translation + Standard_Real aTranslation[3]; + aDestView->At(aTranslation[0], aTranslation[1], aTranslation[2]); + + gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed( + gp_Dir(aProjDir.X(), aProjDir.Y(), aProjDir.Z())); + + // convert camera position into a view reference point + gp_Trsf aTrsf; + aTrsf.SetValues( aLeftDir.X(), anUpDir[0], aProjDir.X(), aTranslation[0], + aLeftDir.Y(), anUpDir[1], aProjDir.Y(), aTranslation[1], + aLeftDir.Z(), anUpDir[2], aProjDir.Z(), aTranslation[2], + Precision::Confusion(), + Precision::Confusion() ); + aTrsf.Invert(); + + // transform to view-space coordinate system + gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]); + aProjRef.Transform(aTrsf); + +#if OCC_VERSION_LARGE > 0x06070000 + aDestView->Camera()->SetDirection( -aProjDir ); + aDestView->Camera()->SetUp( gp_Dir( anUpDir[0], anUpDir[1], anUpDir[2] ) ); + aDestView->Camera()->SetProjectionShift( gp_Pnt( -aProjRef.X(), -aProjRef.Y(), 0.0 ) ); +#else + // set view camera properties using low-level approach. this is done + // in order to avoid interference with static variables in v3d view used + // when rotation is in process in another view. + Visual3d_ViewMapping aMapping = aDestView->View()->ViewMapping(); + Visual3d_ViewOrientation anOrientation = aDestView->View()->ViewOrientation(); + + Graphic3d_Vector aMappingProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z()); + Graphic3d_Vector aMappingUp(anUpDir[0], anUpDir[1], anUpDir[2]); + + aMappingProj.Normalize(); + aMappingUp.Normalize(); + + anOrientation.SetViewReferencePlane(aMappingProj); + anOrientation.SetViewReferenceUp(aMappingUp); + + aDestView->SetViewMapping(aMapping); + aDestView->SetViewOrientation(anOrientation); + + // set panning + aDestView->SetCenter(aProjRef.X(), aProjRef.Y()); +#endif + + // set mapping scale + Standard_Real aWidth, aHeight; + aDestView->Size(aWidth, aHeight); + + if ( aWidth > aHeight ) + aDestView->SetSize (aMapScaling * (aWidth / aHeight)); + else + aDestView->SetSize (aMapScaling); + + getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); + + aDestView->ZFitAll(); + aDestView->SetImmediateUpdate( Standard_True ); + aDestView->Redraw(); + + blockSignals( blocked ); +} + +/*! + \brief Indicates whether preselection is enabled + \return true if preselection is enabled +*/ +bool OCCViewer_ViewWindow::isPreselectionEnabled() const +{ + return myPreselectionEnabled; +} + +/*! + \brief Enables/disables preselection + \param theIsToEnable if true - preselection will be enabled +*/ +void OCCViewer_ViewWindow::enablePreselection( bool theIsToEnable ) +{ + onSwitchPreselection( theIsToEnable ); +} + +/*! + \brief Indicates whether selection is enabled + \return true if selection is enabled +*/ +bool OCCViewer_ViewWindow::isSelectionEnabled() const +{ + return mySelectionEnabled; +} + +/*! + \brief Enables/disables selection + \param theIsToEnable if true - selection will be enabled +*/ +void OCCViewer_ViewWindow::enableSelection( bool theIsToEnable ) +{ + onSwitchSelection( theIsToEnable ); +} + + +/*! + \brief called if clipping operation is activated / deactivated. + + Enables/disables clipping plane displaying. + + \parma on action state +*/ +void OCCViewer_ViewWindow::onClipping (bool theIsOn) +{ + if(!myModel) return; + OCCViewer_ClippingDlg* aClippingDlg = myModel->getClippingDlg(); + + if (theIsOn) { + if (!aClippingDlg) { + aClippingDlg = new OCCViewer_ClippingDlg (this, myModel); + myModel->setClippingDlg(aClippingDlg); + } + if (!aClippingDlg->isVisible()) + aClippingDlg->show(); + } else { + if ( aClippingDlg ) { + aClippingDlg->close(); + myModel->setClippingDlg(0); + } + } + + SUIT_ViewManager* mgr = getViewManager(); + if( mgr ) { + QVector aViews = mgr->getViews(); + for(int i = 0, iEnd = aViews.size(); i < iEnd; i++) { + if(SUIT_ViewWindow* aViewWindow = aViews.at(i)) { + QtxActionToolMgr* mgr = aViewWindow->toolMgr(); + if(!mgr) continue; + QAction* a = toolMgr()->action( ClippingId ); + if(!a) continue; + if(theIsOn != a->isChecked()){ + disconnect (a, SIGNAL (toggled (bool)), aViewWindow, SLOT (onClipping (bool))); + a->setChecked(theIsOn); + connect (a, SIGNAL (toggled (bool)), aViewWindow, SLOT (onClipping (bool))); + } + } + } + } +} -- 2.39.2