// VISU OBJECT : interactive object for VISU entities implementation
//
// Copyright (C) 2003 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.
-//
-// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+// 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.
+//
+// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
//
//
//
#include "VISU_PipeLine.hxx"
+#include "VISU_PipeLineUtils.hxx"
+
+#include "SALOME_ExtractGeometry.h"
+
+#include <float.h>
#include <vtkObjectFactory.h>
#include <vtkDataSetMapper.h>
#include <vtkUnstructuredGrid.h>
+#include <vtkPlane.h>
+#include <vtkExtractGeometry.h>
+#include <vtkImplicitBoolean.h>
+#include <vtkImplicitFunctionCollection.h>
+#include <vtkMath.h>
+
+static int MYVTKDEBUG = 0;
+
#ifdef _DEBUG_
static int MYDEBUG = 0;
-static int MYDEBUGWITHFILES = 0;
#else
static int MYDEBUG = 0;
-static int MYDEBUGWITHFILES = 0;
#endif
-VISU_PipeLine::VISU_PipeLine(){
+VISU_PipeLine::VISU_PipeLine()
+{
+ if(MYDEBUG) MESSAGE("VISU_PipeLine - "<<this);
+ // Clipping planes
+ myExtractGeometry = SALOME_ExtractGeometry::New();
+ //myExtractGeometry->SetReleaseDataFlag(true);
+ myExtractGeometry->Delete();
+ //myExtractGeometry->DebugOn();
+
+ vtkImplicitBoolean* anImplicitBoolean = vtkImplicitBoolean::New();
+ myExtractGeometry->SetImplicitBoolean(anImplicitBoolean);
+ anImplicitBoolean->SetOperationTypeToIntersection();
+ anImplicitBoolean->Delete();
+
+ // Mapper
myMapper = TMapper::New();
myInput = NULL;
+
+ myIsShrinkable = false;
+
+ SetDebug(MYVTKDEBUG);
}
-VISU_PipeLine::~VISU_PipeLine(){
+VISU_PipeLine::~VISU_PipeLine()
+{
+ if(MYDEBUG) MESSAGE("~VISU_PipeLine - "<<this);
myMapper->Delete();
- SetInput(NULL);
}
void VISU_PipeLine::ShallowCopy(VISU_PipeLine *thePipeLine){
SetInput(thePipeLine->GetInput());
myMapper->ShallowCopy(thePipeLine->GetMapper());
+ myExtractGeometry->SetImplicitBoolean(thePipeLine->myExtractGeometry->GetImplicitBoolean());
Build();
}
-void VISU_PipeLine::SetInput(TInput* theInput){
- if (myInput != theInput){
- if (myInput != NULL) myInput->UnRegister(this);
- myInput = theInput;
- if (myInput != NULL) {
- myInput->Register(this);
- myInput->Update();
- }
- Modified();
- }
+void VISU_PipeLine::SameAs(VISU_PipeLine *thePipeLine){
+ ShallowCopy(thePipeLine);
+ myExtractGeometry->SetImplicitBoolean(vtkImplicitBoolean::New());
+ myExtractGeometry->GetImplicitBoolean()->Delete();
+}
+
+TInput* VISU_PipeLine::GetInput() const
+{
+ return myInput;
}
-VISU_PipeLine::TMapper* VISU_PipeLine::GetMapper() {
- if(myInput){
+TInput* VISU_PipeLine::GetInput2() const
+{
+ vtkUnstructuredGrid* aDataSet = myExtractGeometry->GetOutput();
+ aDataSet->Update();
+ return aDataSet;
+}
+
+void VISU_PipeLine::SetInput(TInput* theInput)
+{
+ myExtractGeometry->SetInput(theInput);
+ if((myInput = theInput))
+ myInput->Update();
+
+ Modified();
+}
+
+VISU_PipeLine::TMapper* VISU_PipeLine::GetMapper()
+{
+ if(GetInput()){
if(!myMapper->GetInput()){
- myInput->Update();
+ GetInput2()->Update();
Build();
}
myMapper->Update();
return myMapper;
}
-void VISU_PipeLine::Update(){
+void VISU_PipeLine::Update()
+{
myMapper->Update();
}
-
-size_t VISU_PipeLine::CheckAvailableMemory(const size_t& theSize){
+int VISU_PipeLine::CheckAvailableMemory(const float& theSize)
+{
try{
- char *aCheck = new char[theSize];
+ if(theSize > ULONG_MAX) return 0;
+ size_t aSize = size_t(theSize);
+ char *aCheck = new char[aSize];
if(aCheck) delete [] aCheck;
if(MYDEBUG && aCheck == NULL)
- cout<<"VISU_PipeLine::CheckAvailableMemory("<<theSize<<") - cannot alloacate such amount of memory!!!\n";
+ MESSAGE("CheckAvailableMemory("<<theSize<<") - cannot alloacate such amount of memory!!!");
return aCheck != NULL;
//return theSize < 1000*1024*1024;
- }catch(...){
+ }catch(std::bad_alloc& exc){
if(MYDEBUG)
- cout<<"VISU_PipeLine::CheckAvailableMemory("<<theSize<<") - unexpected exception was caught!!!\n";
+ MESSAGE("CheckAvailableMemory("<<theSize<<") " << exc.what());
+ } catch(...) {
+ if(MYDEBUG)
+ MESSAGE("CheckAvailableMemory("<<theSize<<") - unexpected exception was caught!!!");
}
return 0;
}
-
-size_t VISU_PipeLine::GetAvailableMemory(size_t theSize, size_t theMinSize){
+float VISU_PipeLine::GetAvailableMemory(float theSize, float theMinSize)
+{
while(!CheckAvailableMemory(theSize))
if(theSize > theMinSize)
theSize /= 2;
return 0;
return theSize;
}
+
+//------------------------ Clipping planes -----------------------------------
+
+bool VISU_PipeLine::AddClippingPlane(vtkPlane* thePlane)
+{
+ if (thePlane) {
+ if (vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()) {
+ vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
+ aFunction->AddItem(thePlane);
+
+ // Check, that at least one cell present after clipping.
+ // This check was introduced because of bug IPAL8849.
+ vtkUnstructuredGrid* aClippedGrid = GetInput2();
+ if (aClippedGrid->GetNumberOfCells() < 1) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+vtkPlane* VISU_PipeLine::GetClippingPlane(vtkIdType theID) const
+{
+ vtkPlane* aPlane = NULL;
+ if(theID >= 0 && theID < GetNumberOfClippingPlanes()){
+ if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
+ vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
+ vtkImplicitFunction* aFun = NULL;
+ aFunction->InitTraversal();
+ for(vtkIdType anID = 0; anID <= theID; anID++)
+ aFun = aFunction->GetNextItem();
+ aPlane = dynamic_cast<vtkPlane*>(aFun);
+ }
+ }
+ return aPlane;
+}
+
+void VISU_PipeLine::RemoveAllClippingPlanes()
+{
+ if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
+ vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
+ aFunction->RemoveAllItems();
+ aBoolean->Modified(); // VTK bug
+ }
+}
+
+vtkIdType VISU_PipeLine::GetNumberOfClippingPlanes() const
+{
+ if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
+ vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
+ return aFunction->GetNumberOfItems();
+ }
+ return 0;
+}
+
+static void ComputeBoundsParam (vtkDataSet* theDataSet,
+ float theDirection[3], float theMinPnt[3],
+ float& theMaxBoundPrj, float& theMinBoundPrj)
+{
+ float aBounds[6];
+ theDataSet->GetBounds(aBounds);
+
+ //Enlarge bounds in order to avoid conflicts of precision
+ for(int i = 0; i < 6; i += 2){
+ static double EPS = 1.0E-3;
+ float aDelta = (aBounds[i+1] - aBounds[i])*EPS;
+ aBounds[i] -= aDelta;
+ aBounds[i+1] += aDelta;
+ }
+
+ float aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
+ {aBounds[1],aBounds[2],aBounds[4]},
+ {aBounds[0],aBounds[3],aBounds[4]},
+ {aBounds[1],aBounds[3],aBounds[4]},
+ {aBounds[0],aBounds[2],aBounds[5]},
+ {aBounds[1],aBounds[2],aBounds[5]},
+ {aBounds[0],aBounds[3],aBounds[5]},
+ {aBounds[1],aBounds[3],aBounds[5]}};
+
+ int aMaxId = 0, aMinId = aMaxId;
+ theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
+ theMinBoundPrj = theMaxBoundPrj;
+ for(int i = 1; i < 8; i++){
+ float aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
+ if(theMaxBoundPrj < aTmp){
+ theMaxBoundPrj = aTmp;
+ aMaxId = i;
+ }
+ if(theMinBoundPrj > aTmp){
+ theMinBoundPrj = aTmp;
+ aMinId = i;
+ }
+ }
+ float *aMinPnt = aBoundPoints[aMaxId];
+ theMinPnt[0] = aMinPnt[0];
+ theMinPnt[1] = aMinPnt[1];
+ theMinPnt[2] = aMinPnt[2];
+}
+
+static void DistanceToPosition (vtkDataSet* theDataSet,
+ float theDirection[3], float theDist, float thePos[3])
+{
+ float aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+ ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
+ float 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;
+}
+
+static void PositionToDistance (vtkDataSet* theDataSet,
+ float theDirection[3], float thePos[3], float& theDist)
+{
+ float aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
+ ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
+ float aPrj = vtkMath::Dot(theDirection,thePos);
+ theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
+}
+
+void VISU_PipeLine::SetPlaneParam (float theDir[3], float theDist, vtkPlane* thePlane)
+{
+ thePlane->SetNormal(theDir);
+ float anOrigin[3];
+ ::DistanceToPosition(GetInput(),theDir,theDist,anOrigin);
+ thePlane->SetOrigin(anOrigin);
+}
+
+void VISU_PipeLine::GetPlaneParam (float theDir[3], float& theDist, vtkPlane* thePlane)
+{
+ thePlane->GetNormal(theDir);
+
+ float anOrigin[3];
+ thePlane->GetOrigin(anOrigin);
+ ::PositionToDistance(GetInput(),theDir,anOrigin,theDist);
+}
+
+//=======================================================================
+//function : IsPlanarInput
+//purpose :
+//=======================================================================
+bool VISU_PipeLine::IsPlanarInput() const
+{
+ float aBounds[6];
+ GetInput()->GetBounds( aBounds ); // xmin,xmax, ymin,ymax, zmin,zmax
+ if (fabs( aBounds[0] - aBounds[1] ) <= FLT_MIN ||
+ fabs( aBounds[2] - aBounds[3] ) <= FLT_MIN ||
+ fabs( aBounds[4] - aBounds[5] ) <= FLT_MIN )
+ return true;
+
+ return false;
+}