From e35a68657aec31d5eebadca3f39dd0a05556bed4 Mon Sep 17 00:00:00 2001 From: mpa Date: Fri, 2 Sep 2016 12:55:40 +0300 Subject: [PATCH] INT PAL 53136: OCC and VTK viewers have different default rotation point of the same objects. --- src/OCCViewer/OCCViewer_Utilities.cxx | 82 ++++++++++++++++++++++++++ src/OCCViewer/OCCViewer_Utilities.h | 17 ++++++ src/OCCViewer/OCCViewer_ViewPort3d.cxx | 4 +- src/OCCViewer/OCCViewer_ViewWindow.cxx | 16 ++--- src/OCCViewer/OCCViewer_ViewWindow.h | 2 +- 5 files changed, 110 insertions(+), 11 deletions(-) diff --git a/src/OCCViewer/OCCViewer_Utilities.cxx b/src/OCCViewer/OCCViewer_Utilities.cxx index 8782bb7ab..5a6594281 100755 --- a/src/OCCViewer/OCCViewer_Utilities.cxx +++ b/src/OCCViewer/OCCViewer_Utilities.cxx @@ -32,6 +32,7 @@ // OCC includes #include +#include // QT includes #include @@ -147,3 +148,84 @@ bool OCCViewer_Utilities::isDialogOpened( OCCViewer_ViewWindow* theView, const Q isFound = true; return isFound; } + +bool OCCViewer_Utilities::computeVisibleBounds( const Handle(V3d_View) theView, + double theBounds[6] ) +{ + bool isAny = false; + + theBounds[0] = theBounds[2] = theBounds[4] = DBL_MAX; + theBounds[1] = theBounds[3] = theBounds[5] = -DBL_MAX; + + Graphic3d_MapOfStructure aSetOfStructures; + theView->View()->DisplayedStructures( aSetOfStructures ); + Graphic3d_MapIteratorOfMapOfStructure aStructureIt( aSetOfStructures ); + + for( ; aStructureIt.More(); aStructureIt.Next() ) { + const Handle(Graphic3d_Structure)& aStructure = aStructureIt.Key(); + if ( aStructure->IsEmpty() || !aStructure->IsVisible() || + aStructure->IsInfinite() || aStructure->CStructure()->IsForHighlight ) + continue; + double aBounds[6]; +#if OCC_VERSION_LARGE > 0x06070100 + Bnd_Box aBox = aStructure->MinMaxValues(); + aBounds[0] = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X(); + aBounds[2] = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y(); + aBounds[4] = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Z(); + aBounds[1] = aBox.IsVoid() ? RealLast() : aBox.CornerMax().X(); + aBounds[3] = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Y(); + aBounds[5] = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Z(); +#else + aStructure->MinMaxValues( aBounds[0], aBounds[2], aBounds[4], + aBounds[1], aBounds[3], aBounds[5] ); +#endif + + if ( aBounds[0] > -DBL_MAX && aBounds[1] < DBL_MAX && + aBounds[2] > -DBL_MAX && aBounds[3] < DBL_MAX && + aBounds[4] > -DBL_MAX && aBounds[5] < DBL_MAX ) + { + isAny = true; + for ( int i = 0; i < 5; i = i + 2 ) { + theBounds[i] = std::min( theBounds[i], aBounds[i] ); + theBounds[i+1] = std::max( theBounds[i+1], aBounds[i+1] ); + } + } + } + return isAny; +} + +bool OCCViewer_Utilities::computeVisibleBBCenter( const Handle(V3d_View) theView, + double& theX, double& theY, double& theZ ) +{ + double aBounds[6]; + if ( !computeVisibleBounds( theView, aBounds ) ) + { + // null bounding box => the center is (0,0,0) + theX = 0.0; + theY = 0.0; + theZ = 0.0; + return true; + } + + static double aMinDistance = 1.0 / DBL_MAX; + + double aLength = aBounds[1]-aBounds[0]; + aLength = std::max( ( aBounds[3]-aBounds[2]), aLength ); + aLength = std::max( ( aBounds[5]-aBounds[4]), aLength ); + + if ( aLength < aMinDistance ) + return false; + + double aWidth = sqrt( ( aBounds[1] - aBounds[0] ) * ( aBounds[1] - aBounds[0] ) + + ( aBounds[3] - aBounds[2] ) * ( aBounds[3] - aBounds[2] ) + + ( aBounds[5] - aBounds[4] ) * ( aBounds[5] - aBounds[4] ) ); + + if(aWidth < aMinDistance) + return false; + + theX = (aBounds[0] + aBounds[1])/2.0; + theY = (aBounds[2] + aBounds[3])/2.0; + theZ = (aBounds[4] + aBounds[5])/2.0; + + return true; +} diff --git a/src/OCCViewer/OCCViewer_Utilities.h b/src/OCCViewer/OCCViewer_Utilities.h index 73b32e11b..68f845a8f 100755 --- a/src/OCCViewer/OCCViewer_Utilities.h +++ b/src/OCCViewer/OCCViewer_Utilities.h @@ -63,6 +63,23 @@ public: */ static bool isDialogOpened( OCCViewer_ViewWindow* theView, const QString& theName ); + /*! + * Get bounding box of visible objects. + * \param theView defined occ view + * \param theBounds used to return bounds of the bounding box + * \return \c true if the bounding box is computed + */ + static bool computeVisibleBounds( const Handle(V3d_View) theView, double theBounds[6] ); + + /*! + * Compute the bounding box center of visible objects. + * \param theView defined occ view + * \param theX used to return X coordinate of the bounding box center + * \param theY used to return Y coordinate of the bounding box center + * \param theZ used to return Z coordinate of the bounding box center + * \return \c true if the bounding box center is computed + */ + static bool computeVisibleBBCenter( const Handle(V3d_View) theView, double& theX, double& theY, double& theZ ); }; #endif // OCCVIEWER_UTILITIES_H diff --git a/src/OCCViewer/OCCViewer_ViewPort3d.cxx b/src/OCCViewer/OCCViewer_ViewPort3d.cxx index 4a2cb3a22..ee51e0b4e 100755 --- a/src/OCCViewer/OCCViewer_ViewPort3d.cxx +++ b/src/OCCViewer/OCCViewer_ViewPort3d.cxx @@ -498,7 +498,7 @@ void OCCViewer_ViewPort3d::startRotation( int x, int y, //activeView()->Gravity(gx,gy,gz); switch ( theRotationPointType ) { - case OCCViewer_ViewWindow::GRAVITY: + case OCCViewer_ViewWindow::BBCENTER: activeView()->StartRotation( x, y, 0.45 ); break; case OCCViewer_ViewWindow::SELECTED: @@ -540,7 +540,7 @@ void OCCViewer_ViewPort3d::rotate( int x, int y, { if ( !activeView().IsNull() ) { switch ( theRotationPointType ) { - case OCCViewer_ViewWindow::GRAVITY: + case OCCViewer_ViewWindow::BBCENTER: activeView()->Rotation( x, y ); break; case OCCViewer_ViewWindow::SELECTED: diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index 70eaeeee0..52d5c8376 100644 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -294,8 +294,8 @@ void OCCViewer_ViewWindow::initLayout() setCentralWidget(myViewPort); myOperation = NOTHING; - myCurrPointType = GRAVITY; - myPrevPointType = GRAVITY; + myCurrPointType = BBCENTER; + myPrevPointType = BBCENTER; mySelectedPoint = gp_Pnt(0.,0.,0.); myRotationPointSelection = false; @@ -777,10 +777,10 @@ void OCCViewer_ViewWindow::activateSetRotationGravity() } myPrevPointType = myCurrPointType; - myCurrPointType = GRAVITY; + myCurrPointType = BBCENTER; Standard_Real Xcenter, Ycenter, Zcenter; - if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) ) + if ( OCCViewer_Utilities::computeVisibleBBCenter( myViewPort->getView(), Xcenter, Ycenter, Zcenter ) ) mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter ); } @@ -790,10 +790,10 @@ void OCCViewer_ViewWindow::activateSetRotationGravity() */ void OCCViewer_ViewWindow::updateGravityCoords() { - if ( mySetRotationPointDlg && mySetRotationPointDlg->isVisible() && myCurrPointType == GRAVITY ) + if ( mySetRotationPointDlg && mySetRotationPointDlg->isVisible() && myCurrPointType == BBCENTER ) { Standard_Real Xcenter, Ycenter, Zcenter; - if ( computeGravityCenter( Xcenter, Ycenter, Zcenter ) ) + if ( OCCViewer_Utilities::computeVisibleBBCenter( myViewPort->getView(), Xcenter, Ycenter, Zcenter ) ) mySetRotationPointDlg->setCoords( Xcenter, Ycenter, Zcenter ); } } @@ -1893,10 +1893,10 @@ void OCCViewer_ViewWindow::onSetRotationPoint( bool on ) if (!mySetRotationPointDlg->isVisible()) { //if (mySetRotationPointDlg->IsFirstShown()) - if (myCurrPointType == GRAVITY) + if (myCurrPointType == BBCENTER) { Standard_Real Xcenter, Ycenter, Zcenter; - if (computeGravityCenter(Xcenter, Ycenter, Zcenter)) + if (OCCViewer_Utilities::computeVisibleBBCenter(myViewPort->getView(), Xcenter, Ycenter, Zcenter)) mySetRotationPointDlg->setCoords(Xcenter, Ycenter, Zcenter); } mySetRotationPointDlg->show(); diff --git a/src/OCCViewer/OCCViewer_ViewWindow.h b/src/OCCViewer/OCCViewer_ViewWindow.h index a180ab298..e83fe217e 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.h +++ b/src/OCCViewer/OCCViewer_ViewWindow.h @@ -159,7 +159,7 @@ public: FRONTVIEW, BACKVIEW, TOPVIEW, BOTTOMVIEW, LEFTVIEW, RIGHTVIEW, CLOCKWISEVIEW, ANTICLOCKWISEVIEW, PROJECTION }; - enum RotationPointType{ GRAVITY, SELECTED }; + enum RotationPointType{ BBCENTER, SELECTED }; enum SketchingType { NoSketching, Rect, Polygon }; -- 2.39.2