X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FOCCViewer%2FOCCViewer_ClipPlane.cxx;h=3064e65b711e05364ec419862ede95a6082ba4d9;hb=e6caa123c65e3c4a3017364ec5bb4225fd898465;hp=68a458b409a56cfb304c1e83a5f9b7cd2a667fd7;hpb=034a705024b224972c148e1e3834c5ee38df184b;p=modules%2Fgui.git diff --git a/src/OCCViewer/OCCViewer_ClipPlane.cxx b/src/OCCViewer/OCCViewer_ClipPlane.cxx index 68a458b40..3064e65b7 100644 --- a/src/OCCViewer/OCCViewer_ClipPlane.cxx +++ b/src/OCCViewer/OCCViewer_ClipPlane.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2015 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 @@ -21,62 +21,316 @@ // #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 : + int anInvertCoeff = AbsoluteOrientation.IsInvert ? 1 : -1; + theDx = anInvertCoeff * AbsoluteOrientation.Dx; + theDy = anInvertCoeff * AbsoluteOrientation.Dy; + theDz = anInvertCoeff * 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]; }