1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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
23 // VISU OBJECT : interactive object for VISU entities implementation
24 // File: VISU_StreamLinesPL.cxx
25 // Author: Alexey PETROV
28 #include "VISU_StreamLinesPL.hxx"
30 #include "VISU_Extractor.hxx"
31 //#include "VISU_FieldTransform.hxx"
32 //#include "VISU_UsedPointsFilter.hxx"
33 #include "VISU_MaskPointsFilter.hxx"
34 #include "VISU_PipeLineUtils.hxx"
36 #include "VTKViewer_CellCenters.h"
37 #include "VTKViewer_GeometryFilter.h"
39 #include <SUIT_Session.h>
40 #include <SUIT_ResourceMgr.h>
45 #include <vtkDataSet.h>
46 #include <vtkStreamLine.h>
49 static int MYDEBUG = 0;
51 static int MYDEBUG = 0;
54 static double EPS = 1.0e-7;
55 static double aMinNbOfSteps = 1.0E+2;
56 //static double aMaxNbOfSteps = 1.0E+3;
57 static double aCoeffOfIntStep = 1.0E+1;
60 //----------------------------------------------------------------------------
61 vtkStandardNewMacro(VISU_StreamLinesPL);
64 //----------------------------------------------------------------------------
66 ::VISU_StreamLinesPL()
68 SetIsShrinkable(false);
69 SetIsFeatureEdgesAllowed(false);
71 myStream = vtkStreamLine::New();
72 myCenters = VTKViewer_CellCenters::New();
73 myGeomFilter = VTKViewer_GeometryFilter::New();
74 myPointsFilter = VISU_MaskPointsFilter::New();
77 myPercents = GetUsedPointsDefault();
81 //----------------------------------------------------------------------------
83 ::~VISU_StreamLinesPL()
85 myPointsFilter->Delete();
86 myPointsFilter = NULL;
91 myGeomFilter->Delete();
99 //----------------------------------------------------------------------------
104 unsigned long int aTime = Superclass::GetMTime();
106 aTime = std::max(aTime, myStream->GetMTime());
107 aTime = std::max(aTime, myCenters->GetMTime());
108 aTime = std::max(aTime, myGeomFilter->GetMTime());
109 aTime = std::max(aTime, myPointsFilter->GetMTime());
112 aTime = std::max(aTime, mySource->GetMTime());
118 //----------------------------------------------------------------------------
121 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
124 Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
126 if(VISU_StreamLinesPL *aPipeLine = dynamic_cast<VISU_StreamLinesPL*>(thePipeLine)){
127 SetParams(aPipeLine->GetIntegrationStep(),
128 aPipeLine->GetPropagationTime(),
129 aPipeLine->GetStepLength(),
130 aPipeLine->GetSource(),
131 aPipeLine->GetUsedPoints(),
132 aPipeLine->GetDirection());
137 //----------------------------------------------------------------------------
140 ::GetNecasseryMemorySize(vtkIdType theNbOfPoints,
141 double theStepLength,
142 double thePropogationTime,
145 static double aStreamPointSize = sizeof(double)*15 + sizeof(vtkIdType)*2;
146 static double aStreamArraySize = aStreamPointSize*1024; // == 69632
148 double aNbCells = thePercents*theNbOfPoints*2.0;
149 double aNbPointsPerCell = thePropogationTime/theStepLength;
150 double aCellsSize = aNbCells*(1+aNbPointsPerCell);
151 double aPointsSize = aCellsSize*3.0*sizeof(double);
153 double aConnectivitySize = aCellsSize*sizeof(vtkIdType);
154 double aTypesSize = aNbCells*sizeof(char);
155 double aLocationsSize = aNbCells*sizeof(int);
156 //double aNbCellsPerPoint = aCellsSize / aNbCells - 1;
157 double aMeshSize = aPointsSize + aConnectivitySize + aTypesSize + aLocationsSize;
159 double anAssignedDataSize = aCellsSize*4.0*sizeof(double);
160 double anOutputDataSetSize = aMeshSize + anAssignedDataSize;
162 double aResult = aStreamArraySize*aNbCells + anOutputDataSetSize;
167 //----------------------------------------------------------------------------
170 ::FindPossibleParams(vtkDataSet* theDataSet,
171 double& theStepLength,
172 double& thePropogationTime,
175 static double aPercentsDecrease = 3.0, aStepLengthIncrease = 9.0;
176 vtkIdType aNbOfPoints = theDataSet->GetNumberOfPoints();
177 double aSize = GetNecasseryMemorySize(aNbOfPoints,theStepLength,thePropogationTime,thePercents);
178 size_t anIsPossible = CheckAvailableMemory(aSize);
180 double aMaxStepLength = std::max(GetMaxStepLength(theDataSet),thePropogationTime);
181 double aMinStepLength = GetMinStepLength(theDataSet,thePercents);
182 double aDeltaStepLength = (aMaxStepLength - aMinStepLength)/aStepLengthIncrease;
183 for(int i = 2, aStepChanged = 1, aPerecentsChanged = 1; aStepChanged || aPerecentsChanged; i++){
184 double aStepLength = theStepLength + aDeltaStepLength;
185 if(aStepLength < aMaxStepLength) theStepLength = aStepLength;
186 else if(aStepChanged){
187 aStepLength = aMaxStepLength;
190 double aPercents = thePercents /= aPercentsDecrease;
191 if(aPercents*aNbOfPoints > 1) thePercents = aPercents;
192 else if(aPerecentsChanged) {
193 thePercents = 1.1 / aNbOfPoints;
194 aPerecentsChanged = 0;
196 aSize = GetNecasseryMemorySize(aNbOfPoints,theStepLength,thePropogationTime,thePercents);
197 if(CheckAvailableMemory(aSize)){
203 if(MYDEBUG) MESSAGE("FindPossibleParams - aSize = "<<aSize<<"; anIsPossible = "<<anIsPossible);
208 //----------------------------------------------------------------------------
211 ::SetParams(double theIntStep,
212 double thePropogationTime,
213 double theStepLength,
214 vtkPointSet* theSource,
218 vtkPointSet* aDataSet = theSource? theSource: GetMergedInput();
220 vtkIdType aNbOfPoints = aDataSet->GetNumberOfPoints();
221 vtkDataSet* aPointSet = GetExtractorFilter()->GetOutput();
222 if (thePercents * aNbOfPoints < 1)
223 thePercents = 2.0 / aNbOfPoints;
225 theIntStep = CorrectIntegrationStep(theIntStep,
229 thePropogationTime = CorrectPropagationTime(thePropogationTime,
233 theStepLength = CorrectStepLength(theStepLength,
237 size_t anIsAccepted = FindPossibleParams(aPointSet,
243 mySource = theSource;
244 myPercents = thePercents;
245 if(VISU::IsDataOnCells(GetMergedInput())){
246 myCenters->SetInputData(aDataSet);
247 myCenters->VertexCellsOn();
248 aDataSet = myCenters->GetOutput();
251 myPointsFilter->SetInputData(aDataSet);
252 myPointsFilter->SetPercentsOfUsedPoints(thePercents);
253 aDataSet = myPointsFilter->GetOutput();
254 myPointsFilter->Update();
255 myStream->SetSourceData(aDataSet);
256 myStream->SetIntegrationStepLength(theIntStep);
257 myStream->SetMaximumPropagationTime(thePropogationTime);
258 myStream->SetStepLength(theStepLength);
259 myStream->SetSavePointInterval(theIntStep*aMinNbOfSteps);
260 myStream->SetIntegrationDirection(theDirection);
261 myStream->Modified();
268 //----------------------------------------------------------------------------
277 //----------------------------------------------------------------------------
286 //----------------------------------------------------------------------------
289 ::GetStreamerSource()
291 return myStream->GetSource();
295 //----------------------------------------------------------------------------
300 return GetVelocityCoeff(GetExtractorFilter()->GetOutput());
304 //----------------------------------------------------------------------------
307 ::GetVelocityCoeff(vtkDataSet* theDataSet)
309 double* aScalarRange = theDataSet->GetScalarRange();
310 double aVelocity = (fabs(aScalarRange[1]) + fabs(aScalarRange[0]))/2.0;
318 //----------------------------------------------------------------------------
321 ::IsPossible(vtkPointSet* theDataSet)
323 double aPercents = GetUsedPointsDefault();
324 double aStepLength = GetBaseStepLength(theDataSet,
326 double aBasePropTime = GetBasePropagationTime(theDataSet);
327 VISU_MaskPointsFilter *aPointsFilter = VISU_MaskPointsFilter::New();
328 aPointsFilter->SetInputData(theDataSet);
329 vtkDataSet* aDataSet = aPointsFilter->GetOutput();
330 aPointsFilter->Update();
331 size_t aRes = FindPossibleParams(aDataSet,
335 aPointsFilter->Delete();
340 //----------------------------------------------------------------------------
343 ::GetIntegrationStep()
345 return myStream->GetIntegrationStepLength();
349 //----------------------------------------------------------------------------
354 return myStream->GetStepLength();
358 //----------------------------------------------------------------------------
361 ::GetPropagationTime()
363 return myStream->GetMaximumPropagationTime();
367 //----------------------------------------------------------------------------
372 return myStream->GetIntegrationDirection();
376 //----------------------------------------------------------------------------
379 ::GetMinIntegrationStep(vtkDataSet* theDataSet,
386 double aVolume = 1.0;
387 double* aBounds = theDataSet->GetBounds();
388 for(int i = 0, j = 0; i < 3; ++i, j = 2*i){
389 double tmp = aBounds[j+1] - aBounds[j];
397 return 0.0; // absolutely empty object
399 double anStepLength = GetMaxIntegrationStep(theDataSet)/aCoeffOfIntStep;
400 // 0020724: last division has been commented, seems to be a logical mistake (to discuss with APO)
401 double aBasePropTime = GetBasePropagationTime(theDataSet); // /GetVelocityCoeff(theDataSet)
403 vtkIdType aNbOfPoints = theDataSet->GetNumberOfPoints();
404 double aSize = GetNecasseryMemorySize(aNbOfPoints,anStepLength,aBasePropTime,thePercents);
405 size_t aRealSize = GetAvailableMemory(aSize);
406 double anAverageVolume = aVolume / aRealSize;
407 double aStep = pow(double(anAverageVolume), double(1.0/double(degree)));
412 //----------------------------------------------------------------------------
415 ::GetMinIntegrationStep()
417 return GetMinIntegrationStep(GetExtractorFilter()->GetOutput(), GetUsedPoints());
421 //----------------------------------------------------------------------------
424 ::GetMaxIntegrationStep(vtkDataSet* theDataSet)
429 double aLength = theDataSet->GetLength();
430 double* aBounds = theDataSet->GetBounds();
431 double aMaxSizeY = (aBounds[3]-aBounds[2])/aLength;
432 double aMaxSizeZ = (aBounds[5]-aBounds[4])/aLength;
433 double aMinMax = (aBounds[1] - aBounds[0])/aLength;
434 if (aMinMax < EPS || (aMaxSizeY < aMinMax && aMaxSizeY > EPS))
436 if (aMinMax < EPS || (aMaxSizeZ < aMinMax && aMaxSizeZ > EPS))
438 return aMinMax*aLength/2.0;
442 //----------------------------------------------------------------------------
445 ::GetMaxIntegrationStep()
447 return GetMaxIntegrationStep(GetExtractorFilter()->GetOutput());
451 //----------------------------------------------------------------------------
454 ::GetBaseIntegrationStep(vtkDataSet* theDataSet,
457 double aMaxIntegrationStep = GetMaxIntegrationStep(theDataSet);
458 double anIntegrationStep = aMaxIntegrationStep / aCoeffOfIntStep;
459 double aMinMax = theDataSet->GetLength() / theDataSet->GetNumberOfPoints();
460 if(aMinMax > anIntegrationStep)
461 anIntegrationStep = (anIntegrationStep*aCoeffOfIntStep*0.9+aMinMax)/aCoeffOfIntStep;
463 double aMinIntegrationStep = GetMinIntegrationStep(theDataSet, thePercents);
464 if(aMinIntegrationStep > anIntegrationStep)
465 anIntegrationStep = aMinIntegrationStep;
467 return anIntegrationStep;
471 //----------------------------------------------------------------------------
474 ::CorrectIntegrationStep(double theStep,
475 vtkDataSet* theDataSet,
478 double aMinIntegrationStep = GetMinIntegrationStep(theDataSet, thePercents);
479 if(aMinIntegrationStep > theStep)
480 theStep = aMinIntegrationStep;
482 double aMaxIntegrationStep = GetMaxIntegrationStep(theDataSet);
483 if(aMaxIntegrationStep < theStep)
484 theStep = aMaxIntegrationStep;
490 //----------------------------------------------------------------------------
493 ::GetMinPropagationTime(vtkDataSet* theDataSet,
499 return GetMinStepLength(theDataSet, thePercents);
503 //----------------------------------------------------------------------------
506 ::GetMinPropagationTime()
508 return GetMinPropagationTime(GetExtractorFilter()->GetOutput(), GetUsedPoints());
512 //----------------------------------------------------------------------------
515 ::GetMaxPropagationTime(vtkDataSet* theDataSet)
520 return GetBasePropagationTime(theDataSet)*aMinNbOfSteps;
524 //----------------------------------------------------------------------------
527 ::GetMaxPropagationTime()
529 return GetMaxPropagationTime(GetExtractorFilter()->GetOutput());
533 //----------------------------------------------------------------------------
536 ::CorrectPropagationTime(double thePropagationTime,
537 vtkDataSet* theDataSet,
540 double aMinPropagationTime = GetMinPropagationTime(theDataSet, thePercents);
541 if(aMinPropagationTime > thePropagationTime)
542 thePropagationTime = aMinPropagationTime;
544 double aMaxPropagationTime = GetMaxPropagationTime(theDataSet);
545 if(aMaxPropagationTime < thePropagationTime)
546 thePropagationTime = aMaxPropagationTime;
548 return thePropagationTime;
552 //----------------------------------------------------------------------------
555 ::GetBasePropagationTime(vtkDataSet* theDataSet)
560 double aPropagationTime = theDataSet->GetLength() / GetVelocityCoeff(theDataSet);
562 return aPropagationTime;
566 //----------------------------------------------------------------------------
569 ::GetBasePropagationTime()
571 return GetBasePropagationTime(GetExtractorFilter()->GetOutput());
575 //----------------------------------------------------------------------------
578 ::GetMinStepLength(vtkDataSet* theDataSet,
581 static double aNbOfStepsOfIntStep = 1.0E+1;
582 double anIntStep = GetMinIntegrationStep(theDataSet, thePercents);
583 double aStepLength = anIntStep * aNbOfStepsOfIntStep / GetVelocityCoeff(theDataSet);
588 //----------------------------------------------------------------------------
593 return GetMinStepLength(GetExtractorFilter()->GetOutput(), GetUsedPoints());
597 //----------------------------------------------------------------------------
600 ::GetMaxStepLength(vtkDataSet* theDataSet)
602 double aStepLength = GetBasePropagationTime(theDataSet);
607 //----------------------------------------------------------------------------
612 return GetMaxStepLength(GetExtractorFilter()->GetOutput());
616 //----------------------------------------------------------------------------
619 ::CorrectStepLength(double theStep,
620 vtkDataSet* theDataSet,
623 double aMinStep = GetMinStepLength(theDataSet, thePercents);
624 if(theStep < aMinStep)
627 double aMaxStep = GetMaxStepLength(theDataSet);
628 if(theStep > aMaxStep)
635 //----------------------------------------------------------------------------
638 ::GetBaseStepLength(vtkDataSet* theDataSet,
641 static double anAvgNbOfSteps = 1.0E+2;
642 double aPropagationTime = GetBasePropagationTime(theDataSet);
643 double aStepLength = aPropagationTime/anAvgNbOfSteps;
644 aStepLength = CorrectStepLength(aStepLength,theDataSet,thePercents);
650 //----------------------------------------------------------------------------
653 ::GetUsedPointsDefault()
655 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
656 return aResourceMgr->doubleValue("VISU", "stream_lines_used_points", 0.01);
660 //----------------------------------------------------------------------------
667 vtkDataSet* aDataSet = GetExtractorFilter()->GetOutput();
668 double anIntStep = GetBaseIntegrationStep(aDataSet, GetUsedPoints());
669 double aPropagationTime = GetBasePropagationTime(aDataSet);
670 double aStepLength = GetBaseStepLength(aDataSet, GetUsedPoints());
679 //----------------------------------------------------------------------------
686 VISU::CellDataToPoint(myStream,
687 myCellDataToPointData,
689 GetMergedInputPort());
691 myGeomFilter->SetInputConnection(myStream->GetOutputPort());
692 myGeomFilter->ExtentClippingOn();
696 //----------------------------------------------------------------------------
701 return myGeomFilter->GetOutputPort();
705 //----------------------------------------------------------------------------
711 Superclass::Update();
714 GetMergedInput()->GetBounds(aBounds);
715 myGeomFilter->SetExtent(aBounds);
717 // std::string aFileName = std::string(getenv("HOME"))+"/"+getenv("USER")+"-myStream.vtk";
718 // VISU::WriteToFile(myStream->GetOutput(), aFileName);
720 }catch(std::exception& exc){
721 MSG(true, "Follow exception was occured :\n"<<exc.what());
723 MSG(MYDEBUG,"Unknown exception was occured\n");
728 //----------------------------------------------------------------------------
733 unsigned long int aSize = Superclass::GetMemorySize();
735 if(vtkDataSet* aDataSet = myStream->GetOutput())
736 aSize += aDataSet->GetActualMemorySize() * 1024;
738 if(vtkDataSet* aDataSet = myGeomFilter->GetOutput())
739 aSize += aDataSet->GetActualMemorySize() * 1024;
741 if(myCellDataToPointData->GetInput())
742 if(vtkDataSet* aDataSet = myCellDataToPointData->GetOutput())
743 aSize += aDataSet->GetActualMemorySize() * 1024;
749 //----------------------------------------------------------------------------
752 ::SetMapScale(double theMapScale)
754 Superclass::SetMapScale(theMapScale);
758 //----------------------------------------------------------------------------