]> SALOME platform Git repositories - modules/visu.git/blob - src/PIPELINE/VISU_PipeLine.cxx
Salome HOME
Merge with branch V2_2_0_VISU_improvement
[modules/visu.git] / src / PIPELINE / VISU_PipeLine.cxx
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 // File:    VISU_PipeLine.cxx
25 // Author:  Alexey PETROV
26 // Module : VISU
27
28
29 #include "VISU_PipeLine.hxx"
30 #include "VISU_PipeLineUtils.hxx"
31
32 #include "SALOME_ExtractGeometry.h"
33
34 #include <float.h>
35
36 #include <vtkObjectFactory.h>
37 #include <vtkDataSetMapper.h>
38 #include <vtkUnstructuredGrid.h>
39
40 #include <vtkPlane.h>
41 #include <vtkExtractGeometry.h>
42 #include <vtkImplicitBoolean.h>
43 #include <vtkImplicitFunctionCollection.h>
44 #include <vtkMath.h>
45
46 static int MYVTKDEBUG = 0;
47
48 #ifdef _DEBUG_
49 static int MYDEBUG = 0;
50 #else
51 static int MYDEBUG = 0;
52 #endif
53
54 VISU_PipeLine::VISU_PipeLine()
55 {
56   if(MYDEBUG) MESSAGE("VISU_PipeLine - "<<this);
57   // Clipping planes
58   myExtractGeometry = SALOME_ExtractGeometry::New();
59   //myExtractGeometry->SetReleaseDataFlag(true);
60   myExtractGeometry->Delete();
61   //myExtractGeometry->DebugOn();
62
63   vtkImplicitBoolean* anImplicitBoolean = vtkImplicitBoolean::New();
64   myExtractGeometry->SetImplicitBoolean(anImplicitBoolean);
65   anImplicitBoolean->SetOperationTypeToIntersection();
66   anImplicitBoolean->Delete();
67
68   // Mapper
69   myMapper = TMapper::New();
70   myInput = NULL;
71
72   myIsShrinkable = false;
73
74   SetDebug(MYVTKDEBUG);
75 }
76
77 VISU_PipeLine::~VISU_PipeLine()
78 {
79   if(MYDEBUG) MESSAGE("~VISU_PipeLine - "<<this);
80   myMapper->Delete();
81 }
82
83 void VISU_PipeLine::ShallowCopy(VISU_PipeLine *thePipeLine){
84   SetInput(thePipeLine->GetInput());
85   myMapper->ShallowCopy(thePipeLine->GetMapper());
86   myExtractGeometry->SetImplicitBoolean(thePipeLine->myExtractGeometry->GetImplicitBoolean());
87   Build();
88 }
89
90 void VISU_PipeLine::SameAs(VISU_PipeLine *thePipeLine){
91   ShallowCopy(thePipeLine);
92   myExtractGeometry->SetImplicitBoolean(vtkImplicitBoolean::New());
93   myExtractGeometry->GetImplicitBoolean()->Delete();
94 }
95
96 TInput* VISU_PipeLine::GetInput() const
97 {
98   return myInput;
99 }
100
101 TInput* VISU_PipeLine::GetInput2() const
102 {
103   vtkUnstructuredGrid* aDataSet = myExtractGeometry->GetOutput();
104   aDataSet->Update();
105   return aDataSet;
106 }
107
108 void VISU_PipeLine::SetInput(TInput* theInput)
109 {
110   myExtractGeometry->SetInput(theInput);
111   if((myInput = theInput))
112     myInput->Update();
113
114   Modified();
115 }
116
117 VISU_PipeLine::TMapper* VISU_PipeLine::GetMapper()
118 {
119   if(GetInput()){
120     if(!myMapper->GetInput()){
121       GetInput2()->Update();
122       Build();
123     }
124     myMapper->Update();
125   }
126   return myMapper;
127 }
128
129 void VISU_PipeLine::Update()
130 {
131   myMapper->Update();
132 }
133
134 int VISU_PipeLine::CheckAvailableMemory(const float& theSize)
135 {
136   try{
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){
146     if(MYDEBUG)
147       MESSAGE("CheckAvailableMemory("<<theSize<<") " << exc.what());
148   } catch(...) {
149     if(MYDEBUG)
150       MESSAGE("CheckAvailableMemory("<<theSize<<") - unexpected exception was caught!!!");
151   }
152   return 0;
153 }
154
155 float VISU_PipeLine::GetAvailableMemory(float theSize, float theMinSize)
156 {
157   while(!CheckAvailableMemory(theSize))
158     if(theSize > theMinSize)
159       theSize /= 2;
160     else
161       return 0;
162   return theSize;
163 }
164
165 //------------------------ Clipping planes -----------------------------------
166
167 void VISU_PipeLine::AddClippingPlane(vtkPlane* thePlane)
168 {
169   if(thePlane){
170     if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
171       vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
172       aFunction->AddItem(thePlane);
173     }
174   }
175 }
176
177 vtkPlane* VISU_PipeLine::GetClippingPlane(vtkIdType theID) const
178 {
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);
188     }
189   }
190   return aPlane;
191 }
192
193 void VISU_PipeLine::RemoveAllClippingPlanes()
194 {
195   if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
196     vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
197     aFunction->RemoveAllItems();
198     aBoolean->Modified(); // VTK bug
199   }
200 }
201
202 vtkIdType VISU_PipeLine::GetNumberOfClippingPlanes() const
203 {
204   if(vtkImplicitBoolean* aBoolean = myExtractGeometry->GetImplicitBoolean()){
205     vtkImplicitFunctionCollection* aFunction = aBoolean->GetFunction();
206     return aFunction->GetNumberOfItems();
207   }
208   return 0;
209 }
210
211 static void ComputeBoundsParam (vtkDataSet* theDataSet,
212                                 float theDirection[3], float theMinPnt[3],
213                                 float& theMaxBoundPrj, float& theMinBoundPrj)
214 {
215   float aBounds[6];
216   theDataSet->GetBounds(aBounds);
217
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;
224   }
225
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]}};
234
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;
242       aMaxId = i;
243     }
244     if(theMinBoundPrj > aTmp){
245       theMinBoundPrj = aTmp;
246       aMinId = i;
247     }
248   }
249   float *aMinPnt = aBoundPoints[aMaxId];
250   theMinPnt[0] = aMinPnt[0];
251   theMinPnt[1] = aMinPnt[1];
252   theMinPnt[2] = aMinPnt[2];
253 }
254
255 static void DistanceToPosition (vtkDataSet* theDataSet,
256                                 float theDirection[3], float theDist, float thePos[3])
257 {
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;
264 }
265
266 static void PositionToDistance (vtkDataSet* theDataSet,
267                                 float theDirection[3], float thePos[3], float& theDist)
268 {
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);
273 }
274
275 void VISU_PipeLine::SetPlaneParam (float theDir[3], float theDist, vtkPlane* thePlane)
276 {
277   thePlane->SetNormal(theDir);
278   float anOrigin[3];
279   ::DistanceToPosition(GetInput(),theDir,theDist,anOrigin);
280   thePlane->SetOrigin(anOrigin);
281 }
282
283 void VISU_PipeLine::GetPlaneParam (float theDir[3], float& theDist, vtkPlane* thePlane)
284 {
285   thePlane->GetNormal(theDir);
286
287   float anOrigin[3];
288   thePlane->GetOrigin(anOrigin);
289   ::PositionToDistance(GetInput(),theDir,anOrigin,theDist);
290 }
291
292 //=======================================================================
293 //function : IsPlanarInput
294 //purpose  :
295 //=======================================================================
296 bool VISU_PipeLine::IsPlanarInput() const
297 {
298   float aBounds[6];
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 )
303     return true;
304
305   return false;
306 }