]> SALOME platform Git repositories - modules/visu.git/blob - src/PIPELINE/VISU_StreamLinesPL.cxx
Salome HOME
Join modifications from branch BR_DEBUG_3_2_0b1
[modules/visu.git] / src / PIPELINE / VISU_StreamLinesPL.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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 // File:    VISU_PipeLine.cxx
24 // Author:  Alexey PETROV
25 // Module : VISU
26
27
28 #include "VISU_StreamLinesPL.hxx"
29 #include "VISU_PipeLineUtils.hxx"
30 #include "VISU_UsedPointsFilter.hxx"
31 #include "VTKViewer_GeometryFilter.h"
32
33 #include <algo.h>
34
35 #include <vtkCell.h>
36 #include <vtkPointSet.h>
37 #include <vtkStreamLine.h>
38
39 #ifdef _DEBUG_
40 static int MYDEBUG = 0;
41 #else
42 static int MYDEBUG = 0;
43 #endif
44
45 static vtkFloatingPointType EPS = 1.0e-7;
46 static vtkFloatingPointType aMinNbOfSteps = 1.0E+2;
47 //static vtkFloatingPointType aMaxNbOfSteps = 1.0E+3;
48 static vtkFloatingPointType aCoeffOfIntStep = 1.0E+1;
49
50
51 vtkStandardNewMacro(VISU_StreamLinesPL);
52
53 VISU_StreamLinesPL::VISU_StreamLinesPL(){
54   myStream = vtkStreamLine::New();
55   myCenters = vtkCellCenters::New();
56   myGeomFilter = VTKViewer_GeometryFilter::New();
57   myPointsFilter = VISU_UsedPointsFilter::New();
58   myPercents = 0.3;
59   mySource = NULL;
60 }
61
62 VISU_StreamLinesPL::~VISU_StreamLinesPL(){
63   myPointsFilter->UnRegisterAllOutputs();
64   myPointsFilter->Delete();
65
66   myCenters->UnRegisterAllOutputs();
67   myCenters->Delete();
68
69   myGeomFilter->UnRegisterAllOutputs();
70   myGeomFilter->Delete();
71
72   myStream->UnRegisterAllOutputs();
73   myStream->Delete();
74 }
75
76 void VISU_StreamLinesPL::ShallowCopy(VISU_PipeLine *thePipeLine){
77   if(VISU_StreamLinesPL *aPipeLine = dynamic_cast<VISU_StreamLinesPL*>(thePipeLine)){
78     SetParams(aPipeLine->GetIntegrationStep(),
79               aPipeLine->GetPropagationTime(),
80               aPipeLine->GetStepLength(),
81               aPipeLine->GetSource(),
82               aPipeLine->GetUsedPoints(),
83               aPipeLine->GetDirection());
84   }
85   VISU_DeformedShapePL::ShallowCopy(thePipeLine);
86 }
87
88
89 vtkFloatingPointType
90 VISU_StreamLinesPL
91 ::GetNecasseryMemorySize(vtkIdType theNbOfPoints, 
92                          vtkFloatingPointType theStepLength,
93                          vtkFloatingPointType thePropogationTime, 
94                          vtkFloatingPointType thePercents)
95 {
96   static vtkFloatingPointType aStreamPointSize = sizeof(vtkFloatingPointType)*15 + sizeof(vtkIdType)*2;
97   static vtkFloatingPointType aStreamArraySize = aStreamPointSize*1024; // == 69632
98
99   vtkFloatingPointType aNbCells = thePercents*theNbOfPoints*2.0;
100   vtkFloatingPointType aNbPointsPerCell = thePropogationTime/theStepLength;
101   vtkFloatingPointType aCellsSize = aNbCells*(1+aNbPointsPerCell);
102   vtkFloatingPointType aPointsSize = aCellsSize*3.0*sizeof(vtkFloatingPointType);
103
104   vtkFloatingPointType aConnectivitySize = aCellsSize*sizeof(vtkIdType);
105   vtkFloatingPointType aTypesSize = aNbCells*sizeof(char);
106   vtkFloatingPointType aLocationsSize = aNbCells*sizeof(int);
107   //vtkFloatingPointType aNbCellsPerPoint = aCellsSize / aNbCells - 1;
108   vtkFloatingPointType aMeshSize = aPointsSize + aConnectivitySize + aTypesSize + aLocationsSize;
109
110   vtkFloatingPointType anAssignedDataSize = aCellsSize*4.0*sizeof(vtkFloatingPointType);
111   vtkFloatingPointType anOutputDataSetSize = aMeshSize + anAssignedDataSize;
112
113   vtkFloatingPointType aResult = aStreamArraySize*aNbCells + anOutputDataSetSize;
114   return aResult;
115 }
116
117 int
118 VISU_StreamLinesPL
119 ::FindPossibleParams(vtkPointSet* theDataSet, 
120                      vtkFloatingPointType& theStepLength,
121                      vtkFloatingPointType& thePropogationTime, 
122                      vtkFloatingPointType& thePercents)
123 {
124   static vtkFloatingPointType aPercentsDecrease = 3.0, aStepLengthIncrease = 9.0;
125   vtkIdType aNbOfPoints = theDataSet->GetNumberOfPoints();
126   vtkFloatingPointType aSize = GetNecasseryMemorySize(aNbOfPoints,theStepLength,thePropogationTime,thePercents);
127   int isPoss = CheckAvailableMemory(aSize);
128   if(!isPoss){
129     vtkFloatingPointType aMaxStepLength = max(GetMaxStepLength(theDataSet),thePropogationTime);
130     vtkFloatingPointType aMinStepLength = GetMinStepLength(theDataSet);
131     vtkFloatingPointType aDeltaStepLength = (aMaxStepLength - aMinStepLength)/aStepLengthIncrease;
132     for(int i = 2, aStepChanged = 1, aPerecentsChanged = 1; aStepChanged || aPerecentsChanged; i++){
133       vtkFloatingPointType aStepLength = theStepLength + aDeltaStepLength;
134       if(aStepLength < aMaxStepLength) theStepLength = aStepLength;
135       else if(aStepChanged){
136         aStepLength = aMaxStepLength;
137         aStepChanged = 0;
138       }
139       vtkFloatingPointType aPercents = thePercents /= aPercentsDecrease;
140       if(aPercents*aNbOfPoints > 1) thePercents = aPercents;
141       else if(aPerecentsChanged) {
142         thePercents = 1.1 / aNbOfPoints;
143         aPerecentsChanged = 0;
144       }
145       aSize = GetNecasseryMemorySize(aNbOfPoints,theStepLength,thePropogationTime,thePercents);
146       if(CheckAvailableMemory(aSize)){
147         isPoss = i;
148         break;
149       }
150     }
151   }
152   if(MYDEBUG) MESSAGE("FindPossibleParams - aSize = "<<aSize<<"; isPoss = "<<isPoss);
153   return isPoss;
154 }
155
156
157 int
158 VISU_StreamLinesPL
159 ::SetParams(vtkFloatingPointType theIntStep,
160             vtkFloatingPointType thePropogationTime,
161             vtkFloatingPointType theStepLength,
162             vtkPointSet* theSource,
163             vtkFloatingPointType thePercents,
164             int theDirection,
165             int isOnlyTry)
166 {
167   vtkPointSet* aDataSet = theSource? theSource: myFieldTransform->GetUnstructuredGridOutput();
168   aDataSet->Update();
169   vtkIdType aNbOfPoints = aDataSet->GetNumberOfPoints();
170   vtkPointSet* aPointSet = myExtractor->GetOutput();
171   if(thePercents*aNbOfPoints < 1) thePercents = 2.0/aNbOfPoints;
172   theIntStep = CorrectIntegrationStep(theIntStep,aPointSet,thePercents);
173   thePropogationTime = CorrectPropagationTime(thePropogationTime,aPointSet);
174   theStepLength = CorrectStepLength(theStepLength,aPointSet);
175   int isAccepted = FindPossibleParams(aPointSet,theStepLength,thePropogationTime,thePercents);
176   if((!isOnlyTry && isAccepted) || (isOnlyTry && isAccepted == 1)){
177     mySource = theSource;
178     myPercents = thePercents;
179     if(GetInput2()->GetCellData()->GetNumberOfArrays()){
180       myCenters->SetInput(aDataSet);
181       myCenters->VertexCellsOn();
182       aDataSet = myCenters->GetOutput();
183     }
184     myPointsFilter->SetInput(aDataSet);
185     myPointsFilter->SetPercentsOfUsedPoints(thePercents);
186     aDataSet = myPointsFilter->GetOutput();
187     myStream->SetSource(aDataSet);
188     myStream->SetIntegrationStepLength(theIntStep);
189     myStream->SetMaximumPropagationTime(thePropogationTime);
190     myStream->SetStepLength(theStepLength);
191     myStream->SetSavePointInterval(theIntStep*aMinNbOfSteps);
192     myStream->SetIntegrationDirection(theDirection);
193     myStream->Modified();
194     Modified();
195   }
196   return isAccepted;
197 }
198
199
200 vtkPointSet* 
201 VISU_StreamLinesPL
202 ::GetSource() 
203 {
204   return mySource;
205 }
206
207 vtkFloatingPointType
208 VISU_StreamLinesPL
209 ::GetUsedPoints() 
210 {
211   return myPercents;
212 }
213
214 vtkDataSet* 
215 VISU_StreamLinesPL
216 ::GetStreamerSource()
217 {
218   return myStream->GetSource();
219 }
220
221 vtkFloatingPointType 
222 VISU_StreamLinesPL
223 ::GetVelocityCoeff()
224 {
225   return GetVelocityCoeff(myExtractor->GetOutput());
226 }
227
228 vtkFloatingPointType 
229 VISU_StreamLinesPL
230 ::GetVelocityCoeff(vtkPointSet* theDataSet)
231 {
232   vtkFloatingPointType* aScalarRange = theDataSet->GetScalarRange();
233   return (fabs(aScalarRange[1]) + fabs(aScalarRange[0]))/2.0;
234 }
235
236
237 int
238 VISU_StreamLinesPL
239 ::IsPossible(vtkPointSet* theDataSet, 
240              vtkFloatingPointType thePercents)
241 {
242   vtkFloatingPointType aStepLength = GetBaseStepLength(theDataSet);
243   vtkFloatingPointType aBasePropTime = GetBasePropagationTime(theDataSet);
244   VISU_UsedPointsFilter *aPointsFilter = VISU_UsedPointsFilter::New();
245   aPointsFilter->SetInput(theDataSet);
246   vtkPointSet* aDataSet = aPointsFilter->GetOutput();
247   aDataSet->Update();
248   int aRes = FindPossibleParams(aDataSet,aStepLength,aBasePropTime,thePercents);
249   aPointsFilter->UnRegisterAllOutputs();
250   aPointsFilter->Delete();
251   return aRes;
252 }
253
254
255 vtkFloatingPointType
256 VISU_StreamLinesPL
257 ::GetIntegrationStep()
258 {
259   return myStream->GetIntegrationStepLength();
260 }
261
262 vtkFloatingPointType
263 VISU_StreamLinesPL
264 ::GetStepLength() 
265 {
266   return myStream->GetStepLength();
267 }
268
269 vtkFloatingPointType
270 VISU_StreamLinesPL
271 ::GetPropagationTime() 
272 {
273   return myStream->GetMaximumPropagationTime();
274 }
275
276 int
277 VISU_StreamLinesPL
278 ::GetDirection()
279 {
280   return myStream->GetIntegrationDirection();
281 }
282
283
284 vtkFloatingPointType
285 VISU_StreamLinesPL
286 ::GetMinIntegrationStep(vtkPointSet* theDataSet, 
287                         vtkFloatingPointType thePercents) 
288 {
289   if(!theDataSet) return -1.0;
290   vtkFloatingPointType aVolume = 1.0;
291   int degree = 0;
292   theDataSet->Update();
293   vtkFloatingPointType* aBounds = theDataSet->GetBounds();
294   for(int i = 0, j = 0; i < 3; ++i, j = 2*i){
295     vtkFloatingPointType tmp = aBounds[j+1] - aBounds[j];
296     if (tmp > EPS ) {
297       aVolume *= tmp;
298       degree += 1;
299     }
300   }
301   if (degree < 1) return 0.0; // absolutely empty object
302   vtkFloatingPointType anStepLength = GetMaxIntegrationStep(theDataSet)/aCoeffOfIntStep;
303   vtkFloatingPointType aBasePropTime = GetBasePropagationTime(theDataSet)/GetVelocityCoeff(theDataSet);
304   thePercents = 1.0;
305   vtkIdType aNbOfPoints = theDataSet->GetNumberOfPoints();
306   vtkFloatingPointType aSize = GetNecasseryMemorySize(aNbOfPoints,anStepLength,aBasePropTime,thePercents);
307   vtkFloatingPointType aRealSize = GetAvailableMemory(aSize);
308   vtkFloatingPointType anAverageVolume = aVolume / aRealSize;
309   vtkFloatingPointType aStep = pow(double(anAverageVolume), double(1.0/double(degree)));
310   return aStep;
311 }
312
313 vtkFloatingPointType
314 VISU_StreamLinesPL
315 ::GetMinIntegrationStep()
316 {
317   return GetMinIntegrationStep(myExtractor->GetOutput(),GetUsedPoints());
318 }
319
320
321 vtkFloatingPointType
322 VISU_StreamLinesPL
323 ::GetMaxIntegrationStep(vtkPointSet* theDataSet) 
324 {
325   if(!theDataSet) return -1.0;
326   theDataSet->Update();
327   vtkFloatingPointType aLength = theDataSet->GetLength();
328   vtkFloatingPointType* aBounds = theDataSet->GetBounds();
329   vtkFloatingPointType aMaxSizeY = (aBounds[3]-aBounds[2])/aLength;
330   vtkFloatingPointType aMaxSizeZ = (aBounds[5]-aBounds[4])/aLength;
331   vtkFloatingPointType aMinMax = (aBounds[1] - aBounds[0])/aLength;
332   if (aMinMax < EPS || (aMaxSizeY < aMinMax && aMaxSizeY > EPS)) aMinMax = aMaxSizeY;
333   if (aMinMax < EPS || (aMaxSizeZ < aMinMax && aMaxSizeZ > EPS)) aMinMax = aMaxSizeZ;
334   return aMinMax*aLength/2.0;
335 }
336
337 vtkFloatingPointType
338 VISU_StreamLinesPL
339 ::GetMaxIntegrationStep()
340 {
341   return GetMaxIntegrationStep(myExtractor->GetOutput());
342 }
343
344 vtkFloatingPointType
345 VISU_StreamLinesPL
346 ::GetBaseIntegrationStep(vtkPointSet* theDataSet, 
347                          vtkFloatingPointType thePercents)
348 {
349   theDataSet->Update();
350   vtkFloatingPointType aMinIntegrationStep = GetMinIntegrationStep(theDataSet,thePercents);
351   vtkFloatingPointType aMaxIntegrationStep = GetMaxIntegrationStep(theDataSet);
352   vtkFloatingPointType anIntegrationStep = aMaxIntegrationStep / aCoeffOfIntStep;
353   vtkFloatingPointType aMinMax = theDataSet->GetLength()/theDataSet->GetNumberOfPoints();
354   if(aMinMax > anIntegrationStep)
355     anIntegrationStep = (anIntegrationStep*aCoeffOfIntStep*0.9+aMinMax)/aCoeffOfIntStep;
356   if(aMinIntegrationStep > anIntegrationStep)
357     anIntegrationStep = aMinIntegrationStep;
358   return anIntegrationStep;
359 }
360
361 vtkFloatingPointType
362 VISU_StreamLinesPL
363 ::CorrectIntegrationStep(vtkFloatingPointType theStep, 
364                          vtkPointSet* theDataSet, 
365                          vtkFloatingPointType thePercents)
366 {
367   theDataSet->Update();
368   vtkFloatingPointType aMinIntegrationStep = GetMinIntegrationStep(theDataSet,thePercents);
369   vtkFloatingPointType aMaxIntegrationStep = GetMaxIntegrationStep(theDataSet);
370   if(aMinIntegrationStep > theStep)
371     theStep = aMinIntegrationStep;
372   if(aMaxIntegrationStep < theStep)
373     theStep = aMaxIntegrationStep;
374   return theStep;
375 }
376
377
378 vtkFloatingPointType
379 VISU_StreamLinesPL
380 ::GetMinPropagationTime(vtkPointSet* theDataSet)
381 {
382   if(!theDataSet) return -1.0;
383   return GetMinStepLength(theDataSet);
384 }
385
386 vtkFloatingPointType
387 VISU_StreamLinesPL
388 ::GetMinPropagationTime()
389 {
390   return GetMinPropagationTime(myExtractor->GetOutput());
391 }
392
393 vtkFloatingPointType
394 VISU_StreamLinesPL
395 ::GetMaxPropagationTime(vtkPointSet* theDataSet)
396 {
397   if(!theDataSet) return -1.0;
398   return GetBasePropagationTime(theDataSet)*aMinNbOfSteps;
399 }
400
401 vtkFloatingPointType VISU_StreamLinesPL::GetMaxPropagationTime(){
402   return GetMaxPropagationTime(myExtractor->GetOutput());
403 }
404
405 vtkFloatingPointType
406 VISU_StreamLinesPL
407 ::CorrectPropagationTime(vtkFloatingPointType thePropagationTime, 
408                          vtkPointSet* theDataSet)
409 {
410   vtkFloatingPointType aMinPropagationTime = GetMinPropagationTime(theDataSet);
411   vtkFloatingPointType aMaxPropagationTime = GetMaxPropagationTime(theDataSet);
412   if(aMinPropagationTime > thePropagationTime)
413     thePropagationTime = aMinPropagationTime;
414   if(aMaxPropagationTime < thePropagationTime)
415     thePropagationTime = aMaxPropagationTime;
416   return thePropagationTime;
417 }
418
419 vtkFloatingPointType 
420 VISU_StreamLinesPL
421 ::GetBasePropagationTime(vtkPointSet* theDataSet)
422 {
423   if(!theDataSet) return -1.0;
424   theDataSet->Update();
425   vtkFloatingPointType aPropagationTime = theDataSet->GetLength()/GetVelocityCoeff(theDataSet);
426   return aPropagationTime;
427 }
428
429 vtkFloatingPointType 
430 VISU_StreamLinesPL
431 ::GetBasePropagationTime()
432 {
433   return GetBasePropagationTime(myExtractor->GetOutput());
434 }
435
436
437 vtkFloatingPointType 
438 VISU_StreamLinesPL
439 ::GetMinStepLength(vtkPointSet* theDataSet)
440 {
441   static vtkFloatingPointType aNbOfStepsOfIntStep = 1.0E+1;
442   vtkFloatingPointType anIntStep = GetMinIntegrationStep(theDataSet);
443   vtkFloatingPointType aStepLength = anIntStep*aNbOfStepsOfIntStep/GetVelocityCoeff(theDataSet);
444   return aStepLength;
445 }
446
447 vtkFloatingPointType
448 VISU_StreamLinesPL
449 ::GetMinStepLength()
450 {
451   return GetMinStepLength(myExtractor->GetOutput());
452 }
453
454 vtkFloatingPointType
455 VISU_StreamLinesPL
456 ::GetMaxStepLength(vtkPointSet* theDataSet)
457 {
458   vtkFloatingPointType aStepLength = GetBasePropagationTime(theDataSet);
459   return aStepLength;
460 }
461
462 vtkFloatingPointType
463 VISU_StreamLinesPL
464 ::GetMaxStepLength()
465 {
466   return GetMaxStepLength(myExtractor->GetOutput());
467 }
468
469 vtkFloatingPointType
470 VISU_StreamLinesPL
471 ::CorrectStepLength(vtkFloatingPointType theStep, 
472                     vtkPointSet* theDataSet)
473 {
474   vtkFloatingPointType aMinStep = GetMinStepLength(theDataSet);
475   if(theStep < aMinStep) theStep = aMinStep;
476   vtkFloatingPointType aMaxStep = GetMaxStepLength(theDataSet);
477   if(theStep > aMaxStep) theStep = aMaxStep;
478   return theStep;
479 }
480
481 vtkFloatingPointType
482 VISU_StreamLinesPL
483 ::GetBaseStepLength(vtkPointSet* theDataSet)
484 {
485   static vtkFloatingPointType anAvgNbOfSteps = 1.0E+2;
486   vtkFloatingPointType aPropagationTime = GetBasePropagationTime(theDataSet);
487   vtkFloatingPointType aStepLength = aPropagationTime/anAvgNbOfSteps;
488   aStepLength = CorrectStepLength(aStepLength,theDataSet);
489   return aStepLength;
490 }
491
492
493 void
494 VISU_StreamLinesPL
495 ::Init()
496 {
497   VISU_ScalarMapPL::Init();
498   vtkPointSet* aDataSet = myExtractor->GetOutput();
499   vtkFloatingPointType anIntStep = GetBaseIntegrationStep(aDataSet);
500   vtkFloatingPointType aPropagationTime = GetBasePropagationTime(aDataSet);
501   vtkFloatingPointType aStepLength = GetBaseStepLength(aDataSet);
502   SetParams(anIntStep,aPropagationTime,aStepLength);
503 }
504
505 VISU_ScalarMapPL::THook* 
506 VISU_StreamLinesPL
507 ::DoHook()
508 {
509   GetInput2()->Update();
510   VISU::CellDataToPoint(myStream,myCellDataToPointData,GetInput2(),myFieldTransform);
511   vtkFloatingPointType *aBounds = GetInput2()->GetBounds();
512   myGeomFilter->SetExtent(aBounds);
513   myGeomFilter->ExtentClippingOn();
514   myGeomFilter->SetInput(myStream->GetOutput());
515   return myGeomFilter->GetOutput();
516 }
517
518 void
519 VISU_StreamLinesPL
520 ::Update()
521 {
522   VISU_ScalarMapPL::Update();
523 }
524
525 void
526 VISU_StreamLinesPL
527 ::SetMapScale(vtkFloatingPointType theMapScale)
528 {
529   VISU_ScalarMapPL::SetMapScale(theMapScale);
530 }