X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FVTKViewer%2FVTKViewer_Utilities.cxx;h=89ca6be894d58085f1c08ea4cd8ce442cc0f2325;hb=4802c0e2d8691cfc11e91e3e4baffffb0a52d6b5;hp=a05b0a36f5654b691ee82f7d34a13466088d18c6;hpb=232b55569765049c7d1cceb5096a45f8584c9369;p=modules%2Fgui.git diff --git a/src/VTKViewer/VTKViewer_Utilities.cxx b/src/VTKViewer/VTKViewer_Utilities.cxx index a05b0a36f..89ca6be89 100755 --- a/src/VTKViewer/VTKViewer_Utilities.cxx +++ b/src/VTKViewer/VTKViewer_Utilities.cxx @@ -1,146 +1,173 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// Copyright (C) 2007-2013 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 +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// 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 +// +// 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 +// 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/ +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + +#include "VTKViewer_Utilities.h" #include "VTKViewer_Actor.h" +#include "VTKViewer_Algorithm.h" + +#include // VTK Includes #include #include #include #include -#include "VTKViewer_Utilities.h" - -/*!@see vtkRenderer::ResetCamera(float bounds[6]) method*/ -void ResetCamera(vtkRenderer* theRenderer, int theUsingZeroFocalPoint) +/*!@see vtkRenderer::ResetCamera(double bounds[6]) method*/ +void +ResetCamera(vtkRenderer* theRenderer, + int theUsingZeroFocalPoint) { - if(!theRenderer) return; - float bounds[6]; - int aCount = ComputeVisiblePropBounds(theRenderer,bounds); + if(!theRenderer) + return; + + vtkCamera* aCamera = theRenderer->GetActiveCamera(); + if(!aCamera) + return; + + double aBounds[6]; + int aCount = ComputeVisiblePropBounds(theRenderer,aBounds); + if(theUsingZeroFocalPoint || aCount){ - float aLength = bounds[1]-bounds[0]; - aLength = max((bounds[3]-bounds[2]),aLength); - aLength = max((bounds[5]-bounds[4]),aLength); + static double MIN_DISTANCE = 1.0 / VTK_LARGE_FLOAT; + + double aLength = aBounds[1]-aBounds[0]; + aLength = std::max((aBounds[3]-aBounds[2]),aLength); + aLength = std::max((aBounds[5]-aBounds[4]),aLength); - double vn[3]; - if ( theRenderer->GetActiveCamera() != NULL ) - theRenderer->GetActiveCamera()->GetViewPlaneNormal(vn); - else{ + if(aLength < MIN_DISTANCE) return; - } + + 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 < MIN_DISTANCE) + return; + + double aViewPlaneNormal[3]; + aCamera->GetViewPlaneNormal(aViewPlaneNormal); - float center[3] = {0.0, 0.0, 0.0}; + double aCenter[3] = {0.0, 0.0, 0.0}; if(!theUsingZeroFocalPoint){ - center[0] = (bounds[0] + bounds[1])/2.0; - center[1] = (bounds[2] + bounds[3])/2.0; - center[2] = (bounds[4] + bounds[5])/2.0; + aCenter[0] = (aBounds[0] + aBounds[1])/2.0; + aCenter[1] = (aBounds[2] + aBounds[3])/2.0; + aCenter[2] = (aBounds[4] + aBounds[5])/2.0; } - theRenderer->GetActiveCamera()->SetFocalPoint(center[0],center[1],center[2]); + aCamera->SetFocalPoint(aCenter[0],aCenter[1],aCenter[2]); - float width = sqrt((bounds[1]-bounds[0])*(bounds[1]-bounds[0]) + - (bounds[3]-bounds[2])*(bounds[3]-bounds[2]) + - (bounds[5]-bounds[4])*(bounds[5]-bounds[4])); - - double ang = theRenderer->GetActiveCamera()->GetViewAngle(); - float distance = 2.0*width/tan(ang*vtkMath::Pi()/360.0); + double aViewAngle = aCamera->GetViewAngle(); + double aDistance = 2.0*aWidth/tan(aViewAngle*vtkMath::Pi()/360.0); // check view-up vector against view plane normal - double *vup = theRenderer->GetActiveCamera()->GetViewUp(); - if ( fabs(vtkMath::Dot(vup,vn)) > 0.999 ){ - theRenderer->GetActiveCamera()->SetViewUp(-vup[2], vup[0], vup[1]); - } + double aViewUp[3]; + aCamera->GetViewUp(aViewUp); + if(fabs(vtkMath::Dot(aViewUp,aViewPlaneNormal)) > 0.999) + aCamera->SetViewUp(-aViewUp[2], aViewUp[0], aViewUp[1]); // update the camera - theRenderer->GetActiveCamera()->SetPosition(center[0]+distance*vn[0], - center[1]+distance*vn[1], - center[2]+distance*vn[2]); + aCamera->SetPosition(aCenter[0]+aDistance*aViewPlaneNormal[0], + aCenter[1]+aDistance*aViewPlaneNormal[1], + aCenter[2]+aDistance*aViewPlaneNormal[2]); + // find size of the window - int* winsize = theRenderer->GetSize(); - if(winsize[0] < winsize[1]) width *= float(winsize[1])/float(winsize[0]); + int* aWinSize = theRenderer->GetSize(); + if(aWinSize[0] < aWinSize[1]) + aWidth *= double(aWinSize[1])/double(aWinSize[0]); - if(theUsingZeroFocalPoint) width *= sqrt(2.0); + if(theUsingZeroFocalPoint) + aWidth *= sqrt(2.0); - theRenderer->GetActiveCamera()->SetParallelScale(width/2.0); + aCamera->SetParallelScale(aWidth/2.0); } - //workaround on VTK - //theRenderer->ResetCameraClippingRange(bounds); + ResetCameraClippingRange(theRenderer); } /*! Compute the bounds of the visible props*/ -int ComputeVisiblePropBounds(vtkRenderer* theRenderer, float theBounds[6]) +int +ComputeVisiblePropBounds(vtkRenderer* theRenderer, + double theBounds[6]) { - float *bounds; - int aCount=0; + int aCount = 0; theBounds[0] = theBounds[2] = theBounds[4] = VTK_LARGE_FLOAT; theBounds[1] = theBounds[3] = theBounds[5] = -VTK_LARGE_FLOAT; // loop through all props - vtkActorCollection* aCollection = theRenderer->GetActors(); + VTK::ActorCollectionCopy aCopy(theRenderer->GetActors()); + vtkActorCollection* aCollection = aCopy.GetActors(); aCollection->InitTraversal(); - while (vtkActor* prop = aCollection->GetNextActor()) { + while (vtkActor* aProp = aCollection->GetNextActor()) { // if it's invisible, or has no geometry, we can skip the rest - if ( prop->GetVisibility() ) - { - if(VTKViewer_Actor* anActor = VTKViewer_Actor::SafeDownCast(prop)) - if(anActor->IsInfinitive()) continue; - bounds = prop->GetBounds(); - // make sure we haven't got bogus bounds - if ( bounds != NULL && - bounds[0] > -VTK_LARGE_FLOAT && bounds[1] < VTK_LARGE_FLOAT && - bounds[2] > -VTK_LARGE_FLOAT && bounds[3] < VTK_LARGE_FLOAT && - bounds[4] > -VTK_LARGE_FLOAT && bounds[5] < VTK_LARGE_FLOAT ) - { - aCount++; - - if (bounds[0] < theBounds[0]) - { - theBounds[0] = bounds[0]; - } - if (bounds[1] > theBounds[1]) - { - theBounds[1] = bounds[1]; - } - if (bounds[2] < theBounds[2]) - { - theBounds[2] = bounds[2]; - } - if (bounds[3] > theBounds[3]) - { - theBounds[3] = bounds[3]; - } - if (bounds[4] < theBounds[4]) - { - theBounds[4] = bounds[4]; - } - if (bounds[5] > theBounds[5]) - { - theBounds[5] = bounds[5]; - } - }//not bogus + if(aProp->GetVisibility() && aProp->GetMapper() && vtkMath::AreBoundsInitialized(aProp->GetBounds())){ + if(VTKViewer_Actor* anActor = VTKViewer_Actor::SafeDownCast(aProp)) + if(anActor->IsInfinitive()) + continue; + double *aBounds = aProp->GetBounds(); + static double MIN_DISTANCE = 1./VTK_LARGE_FLOAT; + static double MAX_DISTANCE = 0.9*VTK_LARGE_FLOAT; + + if(abs(aBounds[1] - aBounds[0]) < MIN_DISTANCE) { + aBounds[0]-=0.001; + aBounds[1]+=0.001; + } + + if(abs(aBounds[3] - aBounds[2]) < MIN_DISTANCE) { + aBounds[2]-=0.001; + aBounds[3]+=0.001; + } + + if(abs(aBounds[5] - aBounds[4]) < MIN_DISTANCE) { + aBounds[4]-=0.001; + aBounds[5]+=0.001; + } + + // make sure we haven't got bogus bounds + if ( aBounds != NULL && + aBounds[0] > -MAX_DISTANCE && aBounds[1] < MAX_DISTANCE && + aBounds[2] > -MAX_DISTANCE && aBounds[3] < MAX_DISTANCE && + aBounds[4] > -MAX_DISTANCE && aBounds[5] < MAX_DISTANCE) + { + aCount++; + + theBounds[0] = std::min(aBounds[0],theBounds[0]); + theBounds[2] = std::min(aBounds[2],theBounds[2]); + theBounds[4] = std::min(aBounds[4],theBounds[4]); + + theBounds[1] = std::max(aBounds[1],theBounds[1]); + theBounds[3] = std::max(aBounds[3],theBounds[3]); + theBounds[5] = std::max(aBounds[5],theBounds[5]); + + }//not bogus } } return aCount; } -/*!@see vtkRenderer::ResetCameraClippingRange(float bounds[6]) method*/ -void ResetCameraClippingRange(vtkRenderer* theRenderer) +/*!@see vtkRenderer::ResetCameraClippingRange(double bounds[6]) method*/ +void +ResetCameraClippingRange(vtkRenderer* theRenderer) { if(!theRenderer || !theRenderer->VisibleActorCount()) return; @@ -155,8 +182,9 @@ void ResetCameraClippingRange(vtkRenderer* theRenderer) double position[3]; anActiveCamera->GetPosition(position); - float bounds[6]; - theRenderer->ComputeVisiblePropBounds(bounds); + double bounds[6]; + //theRenderer->ComputeVisiblePropBounds(bounds); + ComputeVisiblePropBounds(theRenderer, bounds); double center[3]; center[0] = (bounds[0] + bounds[1])/2.0; @@ -171,7 +199,7 @@ void ResetCameraClippingRange(vtkRenderer* theRenderer) (position[1]-center[1])*(position[1]-center[1]) + (position[2]-center[2])*(position[2]-center[2])); - float range[2] = {distance - width/2.0, distance + width/2.0}; + double range[2] = {distance - width/2.0, distance + width/2.0}; // Do not let the range behind the camera throw off the calculation. if (range[0] < 0.0) range[0] = 0.0; @@ -180,26 +208,166 @@ void ResetCameraClippingRange(vtkRenderer* theRenderer) } /*!Compute trihedron size.*/ -bool ComputeTrihedronSize( vtkRenderer* theRenderer,double& theNewSize, - const double theSize, const float theSizeInPercents ) +bool +ComputeTrihedronSize( vtkRenderer* theRenderer, + double& theNewSize, + const double theSize, + const double theSizeInPercents ) { // calculating diagonal of visible props of the renderer - float bnd[ 6 ]; + double bnd[ 6 ]; if ( ComputeVisiblePropBounds( theRenderer, bnd ) == 0 ) { bnd[ 1 ] = bnd[ 3 ] = bnd[ 5 ] = 100; bnd[ 0 ] = bnd[ 2 ] = bnd[ 4 ] = 0; } - float aLength = 0; + double aLength = 0; aLength = bnd[ 1 ]-bnd[ 0 ]; - aLength = max( ( bnd[ 3 ] - bnd[ 2 ] ),aLength ); - aLength = max( ( bnd[ 5 ] - bnd[ 4 ] ),aLength ); + aLength = std::max( ( bnd[ 3 ] - bnd[ 2 ] ),aLength ); + aLength = std::max( ( bnd[ 5 ] - bnd[ 4 ] ),aLength ); - static float EPS_SIZE = 5.0E-3; + static double EPS_SIZE = 5.0E-3; theNewSize = aLength * theSizeInPercents / 100.0; // if the new trihedron size have sufficient difference, then apply the value return fabs( theNewSize - theSize) > theSize * EPS_SIZE || fabs( theNewSize-theSize ) > theNewSize * EPS_SIZE; } + +bool IsBBEmpty(vtkRenderer* theRenderer) +{ + if(!theRenderer) + return false; + + double aNewBndBox[6]; + aNewBndBox[ 0 ] = aNewBndBox[ 2 ] = aNewBndBox[ 4 ] = VTK_LARGE_FLOAT; + aNewBndBox[ 1 ] = aNewBndBox[ 3 ] = aNewBndBox[ 5 ] = -VTK_LARGE_FLOAT; + + // iterate through displayed objects and set size if necessary + VTK::ActorCollectionCopy aCopy(theRenderer->GetActors()); + vtkActorCollection* anActors = aCopy.GetActors(); + anActors->InitTraversal(); + bool isAny = false; + while(vtkActor* anAct = anActors->GetNextActor()) + //if(SALOME_Actor* anActor = dynamic_cast(anAct)) + if(VTKViewer_Actor* anActor = VTKViewer_Actor::SafeDownCast(anAct)) + if(anActor->GetVisibility() && !anActor->IsInfinitive()) + { + double *aBounds = anActor->GetBounds(); + if(aBounds[0] > -VTK_LARGE_FLOAT && aBounds[1] < VTK_LARGE_FLOAT && + aBounds[2] > -VTK_LARGE_FLOAT && aBounds[3] < VTK_LARGE_FLOAT && + aBounds[4] > -VTK_LARGE_FLOAT && aBounds[5] < VTK_LARGE_FLOAT) + isAny = true; + } + + return !isAny; +} + +bool ComputeBBCenter(vtkRenderer* theRenderer, double theCenter[3]) +{ + theCenter[0] = theCenter[1] = theCenter[2] = 0.0; + + if(!theRenderer) + return false; + + double aNewBndBox[6]; + aNewBndBox[ 0 ] = aNewBndBox[ 2 ] = aNewBndBox[ 4 ] = VTK_LARGE_FLOAT; + aNewBndBox[ 1 ] = aNewBndBox[ 3 ] = aNewBndBox[ 5 ] = -VTK_LARGE_FLOAT; + + // iterate through displayed objects and set size if necessary + VTK::ActorCollectionCopy aCopy(theRenderer->GetActors()); + vtkActorCollection* anActors = aCopy.GetActors(); + anActors->InitTraversal(); + bool isAny = false; + while(vtkActor* anAct = anActors->GetNextActor()) + { + //if(SALOME_Actor* anActor = dynamic_cast(anAct)) + if(VTKViewer_Actor* anActor = VTKViewer_Actor::SafeDownCast(anAct)) + { + if(anActor->GetVisibility() && !anActor->IsInfinitive()) + { + double *aBounds = anActor->GetBounds(); + if(aBounds[0] > -VTK_LARGE_FLOAT && aBounds[1] < VTK_LARGE_FLOAT && + aBounds[2] > -VTK_LARGE_FLOAT && aBounds[3] < VTK_LARGE_FLOAT && + aBounds[4] > -VTK_LARGE_FLOAT && aBounds[5] < VTK_LARGE_FLOAT) + { + for(int i = 0; i < 5; i = i + 2){ + if(aBounds[i] < aNewBndBox[i]) + aNewBndBox[i] = aBounds[i]; + if(aBounds[i+1] > aNewBndBox[i+1]) + aNewBndBox[i+1] = aBounds[i+1]; + } + isAny = true; + } + } + } + } + + if ( !isAny ) + { + // null bounding box => the center is (0,0,0) + return true; + } + + if(aNewBndBox[0] > -VTK_LARGE_FLOAT && aNewBndBox[1] < VTK_LARGE_FLOAT && + aNewBndBox[2] > -VTK_LARGE_FLOAT && aNewBndBox[3] < VTK_LARGE_FLOAT && + aNewBndBox[4] > -VTK_LARGE_FLOAT && aNewBndBox[5] < VTK_LARGE_FLOAT) + { + static double MIN_DISTANCE = 1.0 / VTK_LARGE_FLOAT; + + double aLength = aNewBndBox[1]-aNewBndBox[0]; + aLength = std::max((aNewBndBox[3]-aNewBndBox[2]),aLength); + aLength = std::max((aNewBndBox[5]-aNewBndBox[4]),aLength); + + if(aLength < MIN_DISTANCE) + return false; + + double aWidth = + sqrt((aNewBndBox[1]-aNewBndBox[0])*(aNewBndBox[1]-aNewBndBox[0]) + + (aNewBndBox[3]-aNewBndBox[2])*(aNewBndBox[3]-aNewBndBox[2]) + + (aNewBndBox[5]-aNewBndBox[4])*(aNewBndBox[5]-aNewBndBox[4])); + + if(aWidth < MIN_DISTANCE) + return false; + + theCenter[0] = (aNewBndBox[0] + aNewBndBox[1])/2.0; + theCenter[1] = (aNewBndBox[2] + aNewBndBox[3])/2.0; + theCenter[2] = (aNewBndBox[4] + aNewBndBox[5])/2.0; + return true; + } + + return false; + + /* + double aBounds[6]; + int aCount = ComputeVisiblePropBounds(theRenderer,aBounds); + printf("aNewBndBox[0] = %f, aNewBndBox[1] = %f,\naNewBndBox[2] = %f, aNewBndBox[3] = %f,\naNewBndBox[4] = %f, aNewBndBox[5] = %f\n", + aBounds[0],aBounds[1],aBounds[2],aBounds[3],aBounds[4],aBounds[5]); + printf("aCount = %d\n",aCount); + + if(aCount){ + static double MIN_DISTANCE = 1.0 / VTK_LARGE_FLOAT; + + double aLength = aBounds[1]-aBounds[0]; + aLength = max((aBounds[3]-aBounds[2]),aLength); + aLength = max((aBounds[5]-aBounds[4]),aLength); + + if(aLength < MIN_DISTANCE) + 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 < MIN_DISTANCE) + return false; + + theCenter[0] = (aBounds[0] + aBounds[1])/2.0; + theCenter[1] = (aBounds[2] + aBounds[3])/2.0; + theCenter[2] = (aBounds[4] + aBounds[5])/2.0; + return true; + } + return false;*/ +}