1 // Copyright (C) 2007-2008 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
22 // VISU OBJECT : interactive object for VISU entities implementation
23 // File: VISU_StreamLinesPL.cxx
24 // Author: Alexey PETROV
27 #include "VISU_StreamLinesPL.hxx"
29 #include "VISU_Extractor.hxx"
30 //#include "VISU_FieldTransform.hxx"
31 //#include "VISU_UsedPointsFilter.hxx"
32 #include "VISU_MaskPointsFilter.hxx"
33 #include "VISU_PipeLineUtils.hxx"
35 #include "VTKViewer_GeometryFilter.h"
40 #include <vtkDataSet.h>
41 #include <vtkStreamLine.h>
44 static int MYDEBUG = 0;
46 static int MYDEBUG = 0;
49 static vtkFloatingPointType EPS = 1.0e-7;
50 static vtkFloatingPointType aMinNbOfSteps = 1.0E+2;
51 //static vtkFloatingPointType aMaxNbOfSteps = 1.0E+3;
52 static vtkFloatingPointType aCoeffOfIntStep = 1.0E+1;
55 //----------------------------------------------------------------------------
56 vtkStandardNewMacro(VISU_StreamLinesPL);
59 //----------------------------------------------------------------------------
61 ::VISU_StreamLinesPL()
63 SetIsShrinkable(false);
64 SetIsFeatureEdgesAllowed(false);
66 myStream = vtkStreamLine::New();
67 myCenters = vtkCellCenters::New();
68 myGeomFilter = VTKViewer_GeometryFilter::New();
69 myPointsFilter = VISU_MaskPointsFilter::New();
75 //----------------------------------------------------------------------------
77 ::~VISU_StreamLinesPL()
79 myPointsFilter->Delete();
80 myPointsFilter = NULL;
85 myGeomFilter->Delete();
93 //----------------------------------------------------------------------------
98 unsigned long int aTime = Superclass::GetMTime();
100 aTime = std::max(aTime, myStream->GetMTime());
101 aTime = std::max(aTime, myCenters->GetMTime());
102 aTime = std::max(aTime, myGeomFilter->GetMTime());
103 aTime = std::max(aTime, myPointsFilter->GetMTime());
106 aTime = std::max(aTime, mySource->GetMTime());
112 //----------------------------------------------------------------------------
115 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
118 Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
120 if(VISU_StreamLinesPL *aPipeLine = dynamic_cast<VISU_StreamLinesPL*>(thePipeLine)){
121 SetParams(aPipeLine->GetIntegrationStep(),
122 aPipeLine->GetPropagationTime(),
123 aPipeLine->GetStepLength(),
124 aPipeLine->GetSource(),
125 aPipeLine->GetUsedPoints(),
126 aPipeLine->GetDirection());
131 //----------------------------------------------------------------------------
134 ::GetNecasseryMemorySize(vtkIdType theNbOfPoints,
135 vtkFloatingPointType theStepLength,
136 vtkFloatingPointType thePropogationTime,
137 vtkFloatingPointType thePercents)
139 static vtkFloatingPointType aStreamPointSize = sizeof(vtkFloatingPointType)*15 + sizeof(vtkIdType)*2;
140 static vtkFloatingPointType aStreamArraySize = aStreamPointSize*1024; // == 69632
142 vtkFloatingPointType aNbCells = thePercents*theNbOfPoints*2.0;
143 vtkFloatingPointType aNbPointsPerCell = thePropogationTime/theStepLength;
144 vtkFloatingPointType aCellsSize = aNbCells*(1+aNbPointsPerCell);
145 vtkFloatingPointType aPointsSize = aCellsSize*3.0*sizeof(vtkFloatingPointType);
147 vtkFloatingPointType aConnectivitySize = aCellsSize*sizeof(vtkIdType);
148 vtkFloatingPointType aTypesSize = aNbCells*sizeof(char);
149 vtkFloatingPointType aLocationsSize = aNbCells*sizeof(int);
150 //vtkFloatingPointType aNbCellsPerPoint = aCellsSize / aNbCells - 1;
151 vtkFloatingPointType aMeshSize = aPointsSize + aConnectivitySize + aTypesSize + aLocationsSize;
153 vtkFloatingPointType anAssignedDataSize = aCellsSize*4.0*sizeof(vtkFloatingPointType);
154 vtkFloatingPointType anOutputDataSetSize = aMeshSize + anAssignedDataSize;
156 size_t aResult = size_t(aStreamArraySize*aNbCells + anOutputDataSetSize);
161 //----------------------------------------------------------------------------
164 ::FindPossibleParams(vtkDataSet* theDataSet,
165 vtkFloatingPointType& theStepLength,
166 vtkFloatingPointType& thePropogationTime,
167 vtkFloatingPointType& thePercents)
169 static vtkFloatingPointType aPercentsDecrease = 3.0, aStepLengthIncrease = 9.0;
170 vtkIdType aNbOfPoints = theDataSet->GetNumberOfPoints();
171 size_t aSize = GetNecasseryMemorySize(aNbOfPoints,theStepLength,thePropogationTime,thePercents);
172 size_t anIsPossible = CheckAvailableMemory(aSize);
174 vtkFloatingPointType aMaxStepLength = std::max(GetMaxStepLength(theDataSet),thePropogationTime);
175 vtkFloatingPointType aMinStepLength = GetMinStepLength(theDataSet);
176 vtkFloatingPointType aDeltaStepLength = (aMaxStepLength - aMinStepLength)/aStepLengthIncrease;
177 for(int i = 2, aStepChanged = 1, aPerecentsChanged = 1; aStepChanged || aPerecentsChanged; i++){
178 vtkFloatingPointType aStepLength = theStepLength + aDeltaStepLength;
179 if(aStepLength < aMaxStepLength) theStepLength = aStepLength;
180 else if(aStepChanged){
181 aStepLength = aMaxStepLength;
184 vtkFloatingPointType aPercents = thePercents /= aPercentsDecrease;
185 if(aPercents*aNbOfPoints > 1) thePercents = aPercents;
186 else if(aPerecentsChanged) {
187 thePercents = 1.1 / aNbOfPoints;
188 aPerecentsChanged = 0;
190 aSize = GetNecasseryMemorySize(aNbOfPoints,theStepLength,thePropogationTime,thePercents);
191 if(CheckAvailableMemory(aSize)){
197 if(MYDEBUG) MESSAGE("FindPossibleParams - aSize = "<<aSize<<"; anIsPossible = "<<anIsPossible);
202 //----------------------------------------------------------------------------
205 ::SetParams(vtkFloatingPointType theIntStep,
206 vtkFloatingPointType thePropogationTime,
207 vtkFloatingPointType theStepLength,
208 vtkPointSet* theSource,
209 vtkFloatingPointType thePercents,
212 vtkPointSet* aDataSet = theSource? theSource: GetMergedInput();
215 vtkIdType aNbOfPoints = aDataSet->GetNumberOfPoints();
216 vtkDataSet* aPointSet = GetExtractorFilter()->GetOutput();
217 if (thePercents * aNbOfPoints < 1)
218 thePercents = 2.0 / aNbOfPoints;
220 theIntStep = CorrectIntegrationStep(theIntStep,
224 thePropogationTime = CorrectPropagationTime(thePropogationTime,
227 theStepLength = CorrectStepLength(theStepLength,
230 size_t anIsAccepted = FindPossibleParams(aPointSet,
236 mySource = theSource;
237 myPercents = thePercents;
238 if(VISU::IsDataOnCells(GetMergedInput())){
239 myCenters->SetInput(aDataSet);
240 myCenters->VertexCellsOn();
241 aDataSet = myCenters->GetOutput();
243 myPointsFilter->SetInput(aDataSet);
244 myPointsFilter->SetPercentsOfUsedPoints(thePercents);
245 aDataSet = myPointsFilter->GetOutput();
246 myStream->SetSource(aDataSet);
247 myStream->SetIntegrationStepLength(theIntStep);
248 myStream->SetMaximumPropagationTime(thePropogationTime);
249 myStream->SetStepLength(theStepLength);
250 myStream->SetSavePointInterval(theIntStep*aMinNbOfSteps);
251 myStream->SetIntegrationDirection(theDirection);
252 myStream->Modified();
259 //----------------------------------------------------------------------------
268 //----------------------------------------------------------------------------
277 //----------------------------------------------------------------------------
280 ::GetStreamerSource()
282 return myStream->GetSource();
286 //----------------------------------------------------------------------------
291 return GetVelocityCoeff(GetExtractorFilter()->GetOutput());
295 //----------------------------------------------------------------------------
298 ::GetVelocityCoeff(vtkDataSet* theDataSet)
300 vtkFloatingPointType* aScalarRange = theDataSet->GetScalarRange();
301 vtkFloatingPointType aVelocity = (fabs(aScalarRange[1]) + fabs(aScalarRange[0]))/2.0;
309 //----------------------------------------------------------------------------
312 ::IsPossible(vtkPointSet* theDataSet,
313 vtkFloatingPointType thePercents)
315 vtkFloatingPointType aStepLength = GetBaseStepLength(theDataSet);
316 vtkFloatingPointType aBasePropTime = GetBasePropagationTime(theDataSet);
317 VISU_MaskPointsFilter *aPointsFilter = VISU_MaskPointsFilter::New();
318 aPointsFilter->SetInput(theDataSet);
319 vtkDataSet* aDataSet = aPointsFilter->GetOutput();
321 size_t aRes = FindPossibleParams(aDataSet,
325 aPointsFilter->Delete();
330 //----------------------------------------------------------------------------
333 ::GetIntegrationStep()
335 return myStream->GetIntegrationStepLength();
339 //----------------------------------------------------------------------------
344 return myStream->GetStepLength();
348 //----------------------------------------------------------------------------
351 ::GetPropagationTime()
353 return myStream->GetMaximumPropagationTime();
357 //----------------------------------------------------------------------------
362 return myStream->GetIntegrationDirection();
366 //----------------------------------------------------------------------------
369 ::GetMinIntegrationStep(vtkDataSet* theDataSet,
370 vtkFloatingPointType thePercents)
375 theDataSet->Update();
378 vtkFloatingPointType aVolume = 1.0;
379 vtkFloatingPointType* aBounds = theDataSet->GetBounds();
380 for(int i = 0, j = 0; i < 3; ++i, j = 2*i){
381 vtkFloatingPointType tmp = aBounds[j+1] - aBounds[j];
389 return 0.0; // absolutely empty object
391 vtkFloatingPointType anStepLength = GetMaxIntegrationStep(theDataSet)/aCoeffOfIntStep;
392 vtkFloatingPointType aBasePropTime = GetBasePropagationTime(theDataSet)/GetVelocityCoeff(theDataSet);
394 vtkIdType aNbOfPoints = theDataSet->GetNumberOfPoints();
395 size_t aSize = GetNecasseryMemorySize(aNbOfPoints,anStepLength,aBasePropTime,thePercents);
396 size_t aRealSize = GetAvailableMemory(aSize);
397 vtkFloatingPointType anAverageVolume = aVolume / aRealSize;
398 vtkFloatingPointType aStep = pow(double(anAverageVolume), double(1.0/double(degree)));
403 //----------------------------------------------------------------------------
406 ::GetMinIntegrationStep()
408 return GetMinIntegrationStep(GetExtractorFilter()->GetOutput(), GetUsedPoints());
412 //----------------------------------------------------------------------------
415 ::GetMaxIntegrationStep(vtkDataSet* theDataSet)
420 theDataSet->Update();
422 vtkFloatingPointType aLength = theDataSet->GetLength();
423 vtkFloatingPointType* aBounds = theDataSet->GetBounds();
424 vtkFloatingPointType aMaxSizeY = (aBounds[3]-aBounds[2])/aLength;
425 vtkFloatingPointType aMaxSizeZ = (aBounds[5]-aBounds[4])/aLength;
426 vtkFloatingPointType aMinMax = (aBounds[1] - aBounds[0])/aLength;
427 if (aMinMax < EPS || (aMaxSizeY < aMinMax && aMaxSizeY > EPS))
429 if (aMinMax < EPS || (aMaxSizeZ < aMinMax && aMaxSizeZ > EPS))
431 return aMinMax*aLength/2.0;
435 //----------------------------------------------------------------------------
438 ::GetMaxIntegrationStep()
440 return GetMaxIntegrationStep(GetExtractorFilter()->GetOutput());
444 //----------------------------------------------------------------------------
447 ::GetBaseIntegrationStep(vtkDataSet* theDataSet,
448 vtkFloatingPointType thePercents)
450 theDataSet->Update();
452 vtkFloatingPointType aMaxIntegrationStep = GetMaxIntegrationStep(theDataSet);
453 vtkFloatingPointType anIntegrationStep = aMaxIntegrationStep / aCoeffOfIntStep;
454 vtkFloatingPointType aMinMax = theDataSet->GetLength() / theDataSet->GetNumberOfPoints();
455 if(aMinMax > anIntegrationStep)
456 anIntegrationStep = (anIntegrationStep*aCoeffOfIntStep*0.9+aMinMax)/aCoeffOfIntStep;
458 vtkFloatingPointType aMinIntegrationStep = GetMinIntegrationStep(theDataSet, thePercents);
459 if(aMinIntegrationStep > anIntegrationStep)
460 anIntegrationStep = aMinIntegrationStep;
462 return anIntegrationStep;
466 //----------------------------------------------------------------------------
469 ::CorrectIntegrationStep(vtkFloatingPointType theStep,
470 vtkDataSet* theDataSet,
471 vtkFloatingPointType thePercents)
473 theDataSet->Update();
475 vtkFloatingPointType aMinIntegrationStep = GetMinIntegrationStep(theDataSet, thePercents);
476 if(aMinIntegrationStep > theStep)
477 theStep = aMinIntegrationStep;
479 vtkFloatingPointType aMaxIntegrationStep = GetMaxIntegrationStep(theDataSet);
480 if(aMaxIntegrationStep < theStep)
481 theStep = aMaxIntegrationStep;
487 //----------------------------------------------------------------------------
490 ::GetMinPropagationTime(vtkDataSet* theDataSet)
495 return GetMinStepLength(theDataSet);
499 //----------------------------------------------------------------------------
502 ::GetMinPropagationTime()
504 return GetMinPropagationTime(GetExtractorFilter()->GetOutput());
508 //----------------------------------------------------------------------------
511 ::GetMaxPropagationTime(vtkDataSet* theDataSet)
516 return GetBasePropagationTime(theDataSet)*aMinNbOfSteps;
520 //----------------------------------------------------------------------------
523 ::GetMaxPropagationTime()
525 return GetMaxPropagationTime(GetExtractorFilter()->GetOutput());
529 //----------------------------------------------------------------------------
532 ::CorrectPropagationTime(vtkFloatingPointType thePropagationTime,
533 vtkDataSet* theDataSet)
535 vtkFloatingPointType aMinPropagationTime = GetMinPropagationTime(theDataSet);
536 if(aMinPropagationTime > thePropagationTime)
537 thePropagationTime = aMinPropagationTime;
539 vtkFloatingPointType aMaxPropagationTime = GetMaxPropagationTime(theDataSet);
540 if(aMaxPropagationTime < thePropagationTime)
541 thePropagationTime = aMaxPropagationTime;
543 return thePropagationTime;
547 //----------------------------------------------------------------------------
550 ::GetBasePropagationTime(vtkDataSet* theDataSet)
555 theDataSet->Update();
556 vtkFloatingPointType aPropagationTime = theDataSet->GetLength() / GetVelocityCoeff(theDataSet);
558 return aPropagationTime;
562 //----------------------------------------------------------------------------
565 ::GetBasePropagationTime()
567 return GetBasePropagationTime(GetExtractorFilter()->GetOutput());
571 //----------------------------------------------------------------------------
574 ::GetMinStepLength(vtkDataSet* theDataSet)
576 static vtkFloatingPointType aNbOfStepsOfIntStep = 1.0E+1;
577 vtkFloatingPointType anIntStep = GetMinIntegrationStep(theDataSet);
578 vtkFloatingPointType aStepLength = anIntStep * aNbOfStepsOfIntStep / GetVelocityCoeff(theDataSet);
583 //----------------------------------------------------------------------------
588 return GetMinStepLength(GetExtractorFilter()->GetOutput());
592 //----------------------------------------------------------------------------
595 ::GetMaxStepLength(vtkDataSet* theDataSet)
597 vtkFloatingPointType aStepLength = GetBasePropagationTime(theDataSet);
602 //----------------------------------------------------------------------------
607 return GetMaxStepLength(GetExtractorFilter()->GetOutput());
611 //----------------------------------------------------------------------------
614 ::CorrectStepLength(vtkFloatingPointType theStep,
615 vtkDataSet* theDataSet)
617 vtkFloatingPointType aMinStep = GetMinStepLength(theDataSet);
618 if(theStep < aMinStep)
621 vtkFloatingPointType aMaxStep = GetMaxStepLength(theDataSet);
622 if(theStep > aMaxStep)
629 //----------------------------------------------------------------------------
632 ::GetBaseStepLength(vtkDataSet* theDataSet)
634 static vtkFloatingPointType anAvgNbOfSteps = 1.0E+2;
635 vtkFloatingPointType aPropagationTime = GetBasePropagationTime(theDataSet);
636 vtkFloatingPointType aStepLength = aPropagationTime/anAvgNbOfSteps;
637 aStepLength = CorrectStepLength(aStepLength,theDataSet);
643 //----------------------------------------------------------------------------
650 vtkDataSet* aDataSet = GetExtractorFilter()->GetOutput();
651 vtkFloatingPointType anIntStep = GetBaseIntegrationStep(aDataSet);
652 vtkFloatingPointType aPropagationTime = GetBasePropagationTime(aDataSet);
653 vtkFloatingPointType aStepLength = GetBaseStepLength(aDataSet);
660 //----------------------------------------------------------------------------
667 VISU::CellDataToPoint(myStream,
668 myCellDataToPointData,
671 myGeomFilter->SetInput(myStream->GetOutput());
672 myGeomFilter->ExtentClippingOn();
676 //----------------------------------------------------------------------------
681 return myGeomFilter->GetOutput();
685 //----------------------------------------------------------------------------
691 Superclass::Update();
693 vtkFloatingPointType aBounds[6];
694 GetMergedInput()->GetBounds(aBounds);
695 myGeomFilter->SetExtent(aBounds);
697 // std::string aFileName = std::string(getenv("HOME"))+"/"+getenv("USER")+"-myStream.vtk";
698 // VISU::WriteToFile(myStream->GetOutput(), aFileName);
700 }catch(std::exception& exc){
701 MSG(true, "Follow exception was occured :\n"<<exc.what());
703 MSG(MYDEBUG,"Unknown exception was occured\n");
708 //----------------------------------------------------------------------------
713 unsigned long int aSize = Superclass::GetMemorySize();
715 if(vtkDataSet* aDataSet = myStream->GetOutput())
716 aSize += aDataSet->GetActualMemorySize() * 1024;
718 if(vtkDataSet* aDataSet = myGeomFilter->GetOutput())
719 aSize += aDataSet->GetActualMemorySize() * 1024;
721 if(myCellDataToPointData->GetInput())
722 if(vtkDataSet* aDataSet = myCellDataToPointData->GetOutput())
723 aSize += aDataSet->GetActualMemorySize() * 1024;
729 //----------------------------------------------------------------------------
732 ::SetMapScale(vtkFloatingPointType theMapScale)
734 Superclass::SetMapScale(theMapScale);
738 //----------------------------------------------------------------------------