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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
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 <vtkImplicitFunctionCollection.h>
46 static int MYVTKDEBUG = 0;
49 static int MYDEBUG = 0;
51 static int MYDEBUG = 0;
54 VISU_PipeLine::VISU_PipeLine()
56 if(MYDEBUG) MESSAGE("VISU_PipeLine - "<<this);
58 myExtractGeometry = SALOME_ExtractGeometry::New();
59 //myExtractGeometry->SetReleaseDataFlag(true);
60 myExtractGeometry->Delete();
61 //myExtractGeometry->DebugOn();
63 vtkImplicitBoolean* anImplicitBoolean = vtkImplicitBoolean::New();
64 myExtractGeometry->SetImplicitBoolean(anImplicitBoolean);
65 anImplicitBoolean->SetOperationTypeToIntersection();
66 anImplicitBoolean->Delete();
69 myMapper = TMapper::New();
72 myIsShrinkable = false;
77 VISU_PipeLine::~VISU_PipeLine()
79 if(MYDEBUG) MESSAGE("~VISU_PipeLine - "<<this);
83 void VISU_PipeLine::ShallowCopy(VISU_PipeLine *thePipeLine){
84 SetInput(thePipeLine->GetInput());
85 myMapper->ShallowCopy(thePipeLine->GetMapper());
86 myExtractGeometry->SetImplicitBoolean(thePipeLine->myExtractGeometry->GetImplicitBoolean());
90 void VISU_PipeLine::SameAs(VISU_PipeLine *thePipeLine){
91 ShallowCopy(thePipeLine);
92 myExtractGeometry->SetImplicitBoolean(vtkImplicitBoolean::New());
93 myExtractGeometry->GetImplicitBoolean()->Delete();
96 TInput* VISU_PipeLine::GetInput() const
101 TInput* VISU_PipeLine::GetInput2() const
103 vtkUnstructuredGrid* aDataSet = myExtractGeometry->GetOutput();
108 void VISU_PipeLine::SetInput(TInput* theInput)
110 myExtractGeometry->SetInput(theInput);
111 if((myInput = theInput))
117 VISU_PipeLine::TMapper* VISU_PipeLine::GetMapper()
120 if(!myMapper->GetInput()){
121 GetInput2()->Update();
129 void VISU_PipeLine::Update()
134 int VISU_PipeLine::CheckAvailableMemory(const float& theSize)
137 if(theSize > ULONG_MAX) return 0;
138 size_t aSize = size_t(theSize);
139 char *aCheck = new char[aSize];
140 if(aCheck) delete [] aCheck;
141 if(MYDEBUG && aCheck == NULL)
142 MESSAGE("CheckAvailableMemory("<<theSize<<") - cannot alloacate such amount of memory!!!");
143 return aCheck != NULL;
144 //return theSize < 1000*1024*1024;
145 }catch(std::bad_alloc& exc){
147 MESSAGE("CheckAvailableMemory("<<theSize<<") " << exc.what());
150 MESSAGE("CheckAvailableMemory("<<theSize<<") - unexpected exception was caught!!!");
155 float VISU_PipeLine::GetAvailableMemory(float theSize, float theMinSize)
157 while(!CheckAvailableMemory(theSize))
158 if(theSize > theMinSize)
165 //------------------------ Clipping planes -----------------------------------
167 bool VISU_PipeLine::AddClippingPlane(vtkPlane* thePlane)
170 if (vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()) {
171 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
172 aFunction->AddItem(thePlane);
174 // Check, that at least one cell present after clipping.
175 // This check was introduced because of bug IPAL8849.
176 vtkUnstructuredGrid* aClippedGrid = GetInput2();
177 if (aClippedGrid->GetNumberOfCells() < 1) {
185 vtkPlane* VISU_PipeLine::GetClippingPlane(vtkIdType theID) const
187 vtkPlane* aPlane = NULL;
188 if(theID >= 0 && theID < GetNumberOfClippingPlanes()){
189 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
190 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
191 vtkImplicitFunction* aFun = NULL;
192 aFunction->InitTraversal();
193 for(vtkIdType anID = 0; anID <= theID; anID++)
194 aFun = aFunction->GetNextItem();
195 aPlane = dynamic_cast<vtkPlane*>(aFun);
201 void VISU_PipeLine::RemoveAllClippingPlanes()
203 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
204 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
205 aFunction->RemoveAllItems();
206 aBoolean->Modified(); // VTK bug
210 vtkIdType VISU_PipeLine::GetNumberOfClippingPlanes() const
212 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
213 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
214 return aFunction->GetNumberOfItems();
219 static void ComputeBoundsParam (vtkDataSet* theDataSet,
220 float theDirection[3], float theMinPnt[3],
221 float& theMaxBoundPrj, float& theMinBoundPrj)
224 theDataSet->GetBounds(aBounds);
226 //Enlarge bounds in order to avoid conflicts of precision
227 for(int i = 0; i < 6; i += 2){
228 static double EPS = 1.0E-3;
229 float aDelta = (aBounds[i+1] - aBounds[i])*EPS;
230 aBounds[i] -= aDelta;
231 aBounds[i+1] += aDelta;
234 float aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
235 {aBounds[1],aBounds[2],aBounds[4]},
236 {aBounds[0],aBounds[3],aBounds[4]},
237 {aBounds[1],aBounds[3],aBounds[4]},
238 {aBounds[0],aBounds[2],aBounds[5]},
239 {aBounds[1],aBounds[2],aBounds[5]},
240 {aBounds[0],aBounds[3],aBounds[5]},
241 {aBounds[1],aBounds[3],aBounds[5]}};
243 int aMaxId = 0, aMinId = aMaxId;
244 theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
245 theMinBoundPrj = theMaxBoundPrj;
246 for(int i = 1; i < 8; i++){
247 float aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
248 if(theMaxBoundPrj < aTmp){
249 theMaxBoundPrj = aTmp;
252 if(theMinBoundPrj > aTmp){
253 theMinBoundPrj = aTmp;
257 float *aMinPnt = aBoundPoints[aMaxId];
258 theMinPnt[0] = aMinPnt[0];
259 theMinPnt[1] = aMinPnt[1];
260 theMinPnt[2] = aMinPnt[2];
263 static void DistanceToPosition (vtkDataSet* theDataSet,
264 float theDirection[3], float theDist, float thePos[3])
266 float aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
267 ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
268 float aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
269 thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
270 thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
271 thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
274 static void PositionToDistance (vtkDataSet* theDataSet,
275 float theDirection[3], float thePos[3], float& theDist)
277 float aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
278 ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
279 float aPrj = vtkMath::Dot(theDirection,thePos);
280 theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
283 void VISU_PipeLine::SetPlaneParam (float theDir[3], float theDist, vtkPlane* thePlane)
285 thePlane->SetNormal(theDir);
287 ::DistanceToPosition(GetInput(),theDir,theDist,anOrigin);
288 thePlane->SetOrigin(anOrigin);
291 void VISU_PipeLine::GetPlaneParam (float theDir[3], float& theDist, vtkPlane* thePlane)
293 thePlane->GetNormal(theDir);
296 thePlane->GetOrigin(anOrigin);
297 ::PositionToDistance(GetInput(),theDir,anOrigin,theDist);
300 //=======================================================================
301 //function : IsPlanarInput
303 //=======================================================================
304 bool VISU_PipeLine::IsPlanarInput() const
307 GetInput()->GetBounds( aBounds ); // xmin,xmax, ymin,ymax, zmin,zmax
308 if (fabs( aBounds[0] - aBounds[1] ) <= FLT_MIN ||
309 fabs( aBounds[2] - aBounds[3] ) <= FLT_MIN ||
310 fabs( aBounds[4] - aBounds[5] ) <= FLT_MIN )