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 void VISU_PipeLine::AddClippingPlane(vtkPlane* thePlane)
170 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
171 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
172 aFunction->AddItem(thePlane);
177 vtkPlane* VISU_PipeLine::GetClippingPlane(vtkIdType theID) const
179 vtkPlane* aPlane = NULL;
180 if(theID >= 0 && theID < GetNumberOfClippingPlanes()){
181 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
182 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
183 vtkImplicitFunction* aFun = NULL;
184 aFunction->InitTraversal();
185 for(vtkIdType anID = 0; anID <= theID; anID++)
186 aFun = aFunction->GetNextItem();
187 aPlane = dynamic_cast<vtkPlane*>(aFun);
193 void VISU_PipeLine::RemoveAllClippingPlanes()
195 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
196 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
197 aFunction->RemoveAllItems();
198 aBoolean->Modified(); // VTK bug
202 vtkIdType VISU_PipeLine::GetNumberOfClippingPlanes() const
204 if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
205 vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
206 return aFunction->GetNumberOfItems();
211 static void ComputeBoundsParam (vtkDataSet* theDataSet,
212 float theDirection[3], float theMinPnt[3],
213 float& theMaxBoundPrj, float& theMinBoundPrj)
216 theDataSet->GetBounds(aBounds);
218 //Enlarge bounds in order to avoid conflicts of precision
219 for(int i = 0; i < 6; i += 2){
220 static double EPS = 1.0E-3;
221 float aDelta = (aBounds[i+1] - aBounds[i])*EPS;
222 aBounds[i] -= aDelta;
223 aBounds[i+1] += aDelta;
226 float aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]},
227 {aBounds[1],aBounds[2],aBounds[4]},
228 {aBounds[0],aBounds[3],aBounds[4]},
229 {aBounds[1],aBounds[3],aBounds[4]},
230 {aBounds[0],aBounds[2],aBounds[5]},
231 {aBounds[1],aBounds[2],aBounds[5]},
232 {aBounds[0],aBounds[3],aBounds[5]},
233 {aBounds[1],aBounds[3],aBounds[5]}};
235 int aMaxId = 0, aMinId = aMaxId;
236 theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]);
237 theMinBoundPrj = theMaxBoundPrj;
238 for(int i = 1; i < 8; i++){
239 float aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]);
240 if(theMaxBoundPrj < aTmp){
241 theMaxBoundPrj = aTmp;
244 if(theMinBoundPrj > aTmp){
245 theMinBoundPrj = aTmp;
249 float *aMinPnt = aBoundPoints[aMaxId];
250 theMinPnt[0] = aMinPnt[0];
251 theMinPnt[1] = aMinPnt[1];
252 theMinPnt[2] = aMinPnt[2];
255 static void DistanceToPosition (vtkDataSet* theDataSet,
256 float theDirection[3], float theDist, float thePos[3])
258 float aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
259 ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
260 float aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist;
261 thePos[0] = aMinPnt[0]-theDirection[0]*aLength;
262 thePos[1] = aMinPnt[1]-theDirection[1]*aLength;
263 thePos[2] = aMinPnt[2]-theDirection[2]*aLength;
266 static void PositionToDistance (vtkDataSet* theDataSet,
267 float theDirection[3], float thePos[3], float& theDist)
269 float aMaxBoundPrj, aMinBoundPrj, aMinPnt[3];
270 ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj);
271 float aPrj = vtkMath::Dot(theDirection,thePos);
272 theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj);
275 void VISU_PipeLine::SetPlaneParam (float theDir[3], float theDist, vtkPlane* thePlane)
277 thePlane->SetNormal(theDir);
279 ::DistanceToPosition(GetInput(),theDir,theDist,anOrigin);
280 thePlane->SetOrigin(anOrigin);
283 void VISU_PipeLine::GetPlaneParam (float theDir[3], float& theDist, vtkPlane* thePlane)
285 thePlane->GetNormal(theDir);
288 thePlane->GetOrigin(anOrigin);
289 ::PositionToDistance(GetInput(),theDir,anOrigin,theDist);
292 //=======================================================================
293 //function : IsPlanarInput
295 //=======================================================================
296 bool VISU_PipeLine::IsPlanarInput() const
299 GetInput()->GetBounds( aBounds ); // xmin,xmax, ymin,ymax, zmin,zmax
300 if (fabs( aBounds[0] - aBounds[1] ) <= FLT_MIN ||
301 fabs( aBounds[2] - aBounds[3] ) <= FLT_MIN ||
302 fabs( aBounds[4] - aBounds[5] ) <= FLT_MIN )