1 // VISU OBJECT : interactive object for VISU entities implementation
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 // File: VISU_PipeLine.cxx
25 // Author: Alexey PETROV
29 #include "VISU_PipeLine.hxx"
30 #include "VISU_PipeLineUtils.hxx"
32 #include "SALOME_ExtractGeometry.h"
36 #include <vtkObjectFactory.h>
37 #include <vtkDataSetMapper.h>
38 #include <vtkUnstructuredGrid.h>
41 #include <vtkExtractGeometry.h>
42 #include <vtkImplicitBoolean.h>
43 #include <vtkImplicitFunction.h>
44 #include <vtkImplicitFunctionCollection.h>
47 static int MYVTKDEBUG = 0;
50 static int MYDEBUG = 0;
52 static int MYDEBUG = 0;
57 myMapper(vtkDataSetMapper::New()),
58 myExtractGeometry(SALOME_ExtractGeometry::New())
60 if(MYDEBUG) MESSAGE("VISU_PipeLine::VISU_PipeLine - "<<this);
66 myExtractGeometry->Delete();
67 myExtractGeometry->SetStoreMapping(true);
69 vtkImplicitBoolean* anImplicitBoolean = vtkImplicitBoolean::New();
70 myExtractGeometry->SetImplicitFunction(anImplicitBoolean);
71 anImplicitBoolean->SetOperationTypeToIntersection();
72 anImplicitBoolean->Delete();
74 myIsShrinkable = false;
81 if(MYDEBUG) MESSAGE("VISU_PipeLine::~VISU_PipeLine - "<<this);
84 // Turn debugging output on.
89 myExtractGeometry->DebugOn();
90 Superclass::DebugOn();
93 // Turn debugging output off.
98 myExtractGeometry->DebugOff();
99 Superclass::DebugOff();
104 ::ShallowCopy(VISU_PipeLine *thePipeLine)
106 SetImplicitFunction(thePipeLine->GetImplicitFunction());
108 // To restore mapper input from pipeline
109 vtkDataSet* aDatsSet = myMapper->GetInput();
110 GetMapper()->ShallowCopy(thePipeLine->GetMapper());
111 myMapper->SetInput(aDatsSet);
118 ::SameAs(VISU_PipeLine *thePipeLine)
120 ShallowCopy(thePipeLine);
121 SetImplicitFunction(vtkImplicitBoolean::New());
122 GetImplicitFunction()->Delete();
129 return myInput.GetPointer();
136 return GetMapper()->GetInput();
143 vtkUnstructuredGrid* aDataSet = myExtractGeometry->GetOutput();
150 ::SetInput(TInput* theInput)
155 myExtractGeometry->SetInput(theInput);
161 VISU_PipeLine::TMapper*
166 if(!myMapper->GetInput()){
167 GetInput2()->Update();
172 return myMapper.GetPointer();
184 ::CheckAvailableMemory(const vtkFloatingPointType& theSize)
187 if(theSize > ULONG_MAX) return 0;
188 size_t aSize = size_t(theSize);
189 char *aCheck = new char[aSize];
190 if(aCheck) delete [] aCheck;
191 if(MYDEBUG && aCheck == NULL)
192 MESSAGE("CheckAvailableMemory("<<theSize<<") - cannot alloacate such amount of memory!!!");
193 return aCheck != NULL;
194 //return theSize < 1000*1024*1024;
195 }catch(std::bad_alloc& exc){
197 MESSAGE("CheckAvailableMemory("<<theSize<<") " << exc.what());
200 MESSAGE("CheckAvailableMemory("<<theSize<<") - unexpected exception was caught!!!");
207 ::GetAvailableMemory(vtkFloatingPointType theSize,
208 vtkFloatingPointType theMinSize)
210 while(!CheckAvailableMemory(theSize))
211 if(theSize > theMinSize)
218 //------------------------ Clipping planes -----------------------------------
221 ::AddClippingPlane(vtkPlane* thePlane)
224 if (vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()) {
225 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
226 aFunction->AddItem(thePlane);
228 // Check, that at least one cell present after clipping.
229 // This check was introduced because of bug IPAL8849.
230 vtkUnstructuredGrid* aClippedGrid = GetInput2();
231 if (aClippedGrid->GetNumberOfCells() < 1) {
241 ::GetClippingPlane(vtkIdType theID) const
243 vtkPlane* aPlane = NULL;
244 if(theID >= 0 && theID < GetNumberOfClippingPlanes()){
245 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
246 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
247 vtkImplicitFunction* aFun = NULL;
248 aFunction->InitTraversal();
249 for(vtkIdType anID = 0; anID <= theID; anID++)
250 aFun = aFunction->GetNextItem();
251 aPlane = dynamic_cast<vtkPlane*>(aFun);
259 ::RemoveAllClippingPlanes()
261 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
262 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
263 aFunction->RemoveAllItems();
264 aBoolean->Modified(); // VTK bug
270 ::GetNumberOfClippingPlanes() const
272 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
273 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
274 return aFunction->GetNumberOfItems();
281 ComputeBoundsParam (vtkDataSet* theDataSet,
282 vtkFloatingPointType theDirection[3],
283 vtkFloatingPointType theMinPnt[3],
284 vtkFloatingPointType& theMaxBoundPrj,
285 vtkFloatingPointType& theMinBoundPrj)
287 vtkFloatingPointType aBounds[6];
288 theDataSet->GetBounds(aBounds);
290 //Enlarge bounds in order to avoid conflicts of precision
291 for(int i = 0; i < 6; i += 2){
292 static double EPS = 1.0E-3;
293 vtkFloatingPointType aDelta = (aBounds[i+1] - aBounds[i])*EPS;
294 aBounds[i] -= aDelta;
295 aBounds[i+1] += aDelta;
298 vtkFloatingPointType aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
299 {aBounds[1],aBounds[2],aBounds[4]},
300 {aBounds[0],aBounds[3],aBounds[4]},
301 {aBounds[1],aBounds[3],aBounds[4]},
302 {aBounds[0],aBounds[2],aBounds[5]},
303 {aBounds[1],aBounds[2],aBounds[5]},
304 {aBounds[0],aBounds[3],aBounds[5]},
305 {aBounds[1],aBounds[3],aBounds[5]}};
307 int aMaxId = 0, aMinId = aMaxId;
308 theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
309 theMinBoundPrj = theMaxBoundPrj;
310 for(int i = 1; i < 8; i++){
311 vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
312 if(theMaxBoundPrj < aTmp){
313 theMaxBoundPrj = aTmp;
316 if(theMinBoundPrj > aTmp){
317 theMinBoundPrj = aTmp;
321 vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId];
322 theMinPnt[0] = aMinPnt[0];
323 theMinPnt[1] = aMinPnt[1];
324 theMinPnt[2] = aMinPnt[2];
329 DistanceToPosition(vtkDataSet* theDataSet,
330 vtkFloatingPointType theDirection[3],
331 vtkFloatingPointType theDist,
332 vtkFloatingPointType thePos[3])
334 vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
335 ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
336 vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
337 thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
338 thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
339 thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
344 PositionToDistance (vtkDataSet* theDataSet,
345 vtkFloatingPointType theDirection[3],
346 vtkFloatingPointType thePos[3],
347 vtkFloatingPointType& theDist)
349 vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
350 ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
351 vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos);
352 theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
357 ::SetPlaneParam(vtkFloatingPointType theDir[3],
358 vtkFloatingPointType theDist,
361 thePlane->SetNormal(theDir);
362 vtkFloatingPointType anOrigin[3];
363 ::DistanceToPosition(GetInput(),theDir,theDist,anOrigin);
364 thePlane->SetOrigin(anOrigin);
369 ::GetPlaneParam(vtkFloatingPointType theDir[3],
370 vtkFloatingPointType& theDist,
373 thePlane->GetNormal(theDir);
375 vtkFloatingPointType anOrigin[3];
376 thePlane->GetOrigin(anOrigin);
377 ::PositionToDistance(GetInput(),theDir,anOrigin,theDist);
380 //=======================================================================
381 //function : IsPlanarInput
383 //=======================================================================
386 ::IsPlanarInput() const
388 vtkFloatingPointType aBounds[6];
389 GetInput()->GetBounds( aBounds ); // xmin,xmax, ymin,ymax, zmin,zmax
390 if (fabs( aBounds[0] - aBounds[1] ) <= FLT_MIN ||
391 fabs( aBounds[2] - aBounds[3] ) <= FLT_MIN ||
392 fabs( aBounds[4] - aBounds[5] ) <= FLT_MIN )
398 //=======================================================================
401 ::GetNodeObjID(vtkIdType theID)
403 vtkIdType anID = myExtractGeometry->GetNodeObjId(theID);
404 return myIDMapper->GetNodeObjID(anID);
409 ::GetNodeVTKID(vtkIdType theID)
411 vtkIdType anID = myIDMapper->GetNodeVTKID(theID);
412 return myExtractGeometry->GetNodeVTKId(anID);
415 vtkFloatingPointType*
417 ::GetNodeCoord(int theObjID)
419 return myIDMapper->GetNodeCoord(theObjID);
422 //=======================================================================
425 ::GetElemObjID(vtkIdType theID)
427 vtkIdType anID = myExtractGeometry->GetElemObjId(theID);
428 return myIDMapper->GetElemObjID(anID);
433 ::GetElemVTKID(vtkIdType theID)
435 vtkIdType anID = myIDMapper->GetElemVTKID(theID);
436 return myExtractGeometry->GetElemVTKId(anID);
441 ::GetElemCell(vtkIdType theObjID)
443 return myIDMapper->GetElemCell(theObjID);
446 //=======================================================================
449 ::SetIDMapper(const VISU::PIDMapper& theIDMapper)
451 myIDMapper = theIDMapper;
452 SetInput(myIDMapper->GetVTKOutput());
455 const VISU::PIDMapper&
457 ::GetIDMapper() const
462 //=======================================================================
465 ::SetImplicitFunction(vtkImplicitFunction *theFunction)
467 myExtractGeometry->SetImplicitFunction(theFunction);
470 vtkImplicitFunction *
472 ::GetImplicitFunction()
474 return myExtractGeometry->GetImplicitFunction();
477 SALOME_ExtractGeometry*
479 ::GetExtractGeometryFilter()
481 return myExtractGeometry.GetPointer();