1 // Copyright (C) 2007-2011 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_ColoredPL.cxx
25 // Author: Alexey PETROV
28 #include "VISU_ColoredPL.hxx"
29 #include "VISU_Extractor.hxx"
30 #include "VISU_FieldTransform.hxx"
31 #include "VISU_LookupTable.hxx"
32 #include "VISU_MapperHolder.hxx"
34 #include "VISU_PipeLineUtils.hxx"
36 #include <vtkThreshold.h>
37 #include <vtkPassThroughFilter.h>
38 #include <vtkDoubleArray.h>
45 //----------------------------------------------------------------------------
48 myMapperTable( VISU_LookupTable::New() ),
49 myBarTable( VISU_LookupTable::New() ),
50 myExtractor( VISU_Extractor::New() ),
51 myFieldTransform( VISU_FieldTransform::New() ),
52 myThreshold ( vtkThreshold::New() ),
53 myPassFilter( vtkPassThroughFilter::New() ),
54 myDistribution( vtkDoubleArray::New() )
56 myMapperTable->Delete();
57 myMapperTable->SetScale(VTK_SCALE_LINEAR);
58 myMapperTable->SetHueRange(0.667, 0.0);
61 myBarTable->SetScale(VTK_SCALE_LINEAR);
62 myBarTable->SetHueRange(0.667, 0.0);
64 myExtractor->Delete();
66 myFieldTransform->Delete();
68 myThreshold->AllScalarsOff();
69 myThreshold->Delete();
70 myPassFilter->Delete();
71 myDistribution->Delete();
75 //----------------------------------------------------------------------------
81 //----------------------------------------------------------------------------
86 unsigned long int aTime = Superclass::GetMTime();
88 aTime = std::max(aTime, myMapperTable->GetMTime());
89 aTime = std::max(aTime, myBarTable->GetMTime());
90 aTime = std::max(aTime, myExtractor->GetMTime());
91 aTime = std::max(aTime, myFieldTransform->GetMTime());
92 aTime = std::max(aTime, myThreshold->GetMTime());
93 aTime = std::max(aTime, myPassFilter->GetMTime());
94 aTime = std::max(aTime, myDistribution->GetMTime());
100 //----------------------------------------------------------------------------
103 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
106 Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
108 if(VISU_ColoredPL *aPipeLine = dynamic_cast<VISU_ColoredPL*>(thePipeLine)){
109 if ( theIsCopyInput ) {
110 SetScalarRange( aPipeLine->GetScalarRange() );
111 if ( this->IsScalarFilterUsed() )
112 SetScalarFilterRange( aPipeLine->GetScalarFilterRange() );
115 SetScalarMode(aPipeLine->GetScalarMode());
116 SetNbColors(aPipeLine->GetNbColors());
117 SetScaling(aPipeLine->GetScaling());
118 SetMapScale(aPipeLine->GetMapScale());
123 //----------------------------------------------------------------------------
128 return myExtractor->GetScalarMode();
132 //----------------------------------------------------------------------------
135 ::SetScalarMode(int theScalarMode,
136 vtkDataSet *theInput,
137 VISU_Extractor* theExtractor)
140 if(VISU::IsDataOnPoints(theInput)){
141 vtkPointData *aPointData = theInput->GetPointData();
142 if(!aPointData->GetAttribute(vtkDataSetAttributes::VECTORS)) {
143 if(theScalarMode == 0){
148 vtkCellData *aCellData = theInput->GetCellData();
149 if(!aCellData->GetAttribute(vtkDataSetAttributes::VECTORS)){
150 if(theScalarMode == 0){
157 theExtractor->SetScalarMode(theScalarMode);
160 //----------------------------------------------------------------------------
163 ::SetScalarMode(int theScalarMode)
165 SetScalarMode(theScalarMode, GetInput(), myExtractor);
169 //----------------------------------------------------------------------------
172 ::SetScalarRange( vtkFloatingPointType theRange[2] )
174 if (isnan(theRange[0]) || isnan(theRange[1]))
175 throw std::runtime_error("NAN values in the presentation");
177 if ( theRange[0] > theRange[1] )
180 if (VISU::CheckIsSameRange( GetScalarRange(), theRange) )
183 myFieldTransform->SetScalarRange( theRange );
184 myBarTable->SetRange( theRange );
188 //----------------------------------------------------------------------------
191 ::SetScalarFilterRange( vtkFloatingPointType theRange[2] )
193 vtkFloatingPointType aRange[ 2 ];
194 this->GetScalarFilterRange( aRange );
196 if ( VISU::CheckIsSameRange( aRange, theRange) )
199 myThreshold->ThresholdBetween( theRange[0], theRange[1] );
203 //----------------------------------------------------------------------------
206 ::GetScalarFilterRange( vtkFloatingPointType theRange[2] )
208 theRange[ 0 ] = myThreshold->GetLowerThreshold();
209 theRange[ 1 ] = myThreshold->GetUpperThreshold();
213 //----------------------------------------------------------------------------
214 vtkFloatingPointType*
216 ::GetScalarFilterRange()
218 static vtkFloatingPointType aRange[ 2 ];
220 this->GetScalarFilterRange( aRange );
226 //----------------------------------------------------------------------------
229 ::UseScalarFiltering( bool theUseScalarFilter )
231 if ( theUseScalarFilter ) {
232 // Include threshold filter between the transform and the pass filters.
233 myPassFilter->SetInput( myThreshold->GetOutput() );
235 // Exclude threshold filter before the pass filter.
236 myPassFilter->SetInput( myFieldTransform->GetOutput() );
241 //----------------------------------------------------------------------------
244 ::IsScalarFilterUsed()
246 return myThreshold->GetOutput() == myPassFilter->GetInput();
250 //----------------------------------------------------------------------------
255 unsigned long int aTime = this->GetMTime();
256 // If modified then update the distribution array
257 if (aTime > myDistribution->GetMTime()) {
258 // Set number of colors for the distribution
259 int nbColors = this->GetNbColors();
260 this->myDistribution->SetNumberOfValues(nbColors);
261 // Initialize numbers of colored cells with zero
262 this->myDistribution->FillComponent(0, 0);
263 // Create a lookup table to compute a color of a cell
264 VISU_LookupTable* lut = GetMapperTable();
265 vtkFloatingPointType aMapScale = lut->GetMapScale();
266 // Get scalar values from the input data to calculate their distribution within cells
267 vtkDataArray* dataArr;
268 // Dtermine where we have to take scalars from: cells data or points data.
269 if(VISU::IsDataOnCells(this->GetOutput())) {
270 dataArr = this->GetOutput()->GetCellData()->GetScalars();
272 dataArr = this->GetOutput()->GetPointData()->GetScalars();
274 // If scalars data array is not defined then create an empty one to avoid exceptions
275 if (dataArr == NULL) {
276 dataArr = vtkDoubleArray::New();
279 // Get range of scalars values
280 // vtkFloatingPointType aRange[2];
281 // dataArr->GetRange(aRange);
283 // Build the lookup table with the found range
284 // Get number of scalar values
285 int aNbVals = dataArr->GetNumberOfTuples();
287 // Count the number of scalar values for each color in the input data
290 // For each scalar value
291 for(vtkIdType aValId = 0; aValId < aNbVals; aValId++){
292 // Find the color index for this scalar value
293 idx = lut->GetIndex(*(dataArr->GetTuple(aValId)) * aMapScale);
294 // Increment the distribution value for this color index
295 cnt = this->myDistribution->GetValue(idx);
296 this->myDistribution->SetValue(idx, cnt + 1);
298 // Compute relative values when 1 is according to the total number of scalar values
299 for(vtkIdType aValId = 0; aValId < nbColors; aValId++){
300 cnt = this->myDistribution->GetValue(aValId);
301 this->myDistribution->SetValue(aValId, cnt / aNbVals);
304 this->myDistribution->Modified();
308 return myDistribution;
310 //----------------------------------------------------------------------------
313 //----------------------------------------------------------------------------
314 vtkFloatingPointType*
318 return myFieldTransform->GetScalarRange();
321 //----------------------------------------------------------------------------
324 ::SetScaling(int theScaling)
326 if(GetScaling() == theScaling)
329 myBarTable->SetScale(theScaling);
331 if(theScaling == VTK_SCALE_LOG10)
332 myFieldTransform->SetScalarTransform(&(VISU_FieldTransform::Log10));
334 myFieldTransform->SetScalarTransform(&(VISU_FieldTransform::Ident));
337 //----------------------------------------------------------------------------
342 return myBarTable->GetScale();
345 //----------------------------------------------------------------------------
348 ::SetNbColors(int theNbColors)
350 myMapperTable->SetNumberOfColors(theNbColors);
351 myBarTable->SetNumberOfColors(theNbColors);
358 return myMapperTable->GetNumberOfColors();
362 //----------------------------------------------------------------------------
369 vtkFloatingPointType aRange[2];
370 GetSourceRange( aRange );
372 SetScalarRange( aRange );
373 SetScalarFilterRange( aRange );
376 //----------------------------------------------------------------------------
381 if(myPassFilter->GetInput())
382 myPassFilter->Update();
383 return myPassFilter->GetUnstructuredGridOutput();
387 //----------------------------------------------------------------------------
392 myExtractor->SetInput( Superclass::GetClippedInput() );
393 myFieldTransform->SetInput(myExtractor->GetOutput());
395 myThreshold->SetInput( myFieldTransform->GetOutput() );
396 // The pass filter is used here for possibility to include/exclude
397 // threshold filter before it.
398 myPassFilter->SetInput( myFieldTransform->GetOutput() );
400 GetMapperHolder()->SetLookupTable(GetMapperTable());
401 //GetMapper()->InterpolateScalarsBeforeMappingOn();
402 GetMapper()->SetUseLookupTableScalarRange( true );
403 GetMapper()->SetColorModeToMapScalars();
404 GetMapper()->ScalarVisibilityOn();
408 //----------------------------------------------------------------------------
413 vtkFloatingPointType *aRange = GetScalarRange();
414 vtkFloatingPointType aScalarRange[2] = {aRange[0], aRange[1]};
415 if(myBarTable->GetScale() == VTK_SCALE_LOG10)
416 VISU_LookupTable::ComputeLogRange(aRange, aScalarRange);
418 if(!VISU::CheckIsSameRange(myMapperTable->GetRange(), aScalarRange))
419 myMapperTable->SetRange(aScalarRange);
421 myMapperTable->Build();
424 Superclass::Update();
428 //----------------------------------------------------------------------------
433 unsigned long int aSize = Superclass::GetMemorySize();
435 if(vtkDataObject* aDataObject = myExtractor->GetInput())
436 aSize = aDataObject->GetActualMemorySize() * 1024;
438 if(vtkDataObject* aDataObject = myFieldTransform->GetInput())
439 aSize += aDataObject->GetActualMemorySize() * 1024;
445 //----------------------------------------------------------------------------
450 return myMapperTable.GetPointer();
454 //----------------------------------------------------------------------------
459 return myBarTable.GetPointer();
463 //----------------------------------------------------------------------------
466 ::GetExtractorFilter()
468 return myExtractor.GetPointer();
472 //----------------------------------------------------------------------------
475 ::GetFieldTransformFilter()
477 return myFieldTransform.GetPointer();
481 //----------------------------------------------------------------------------
484 ::SetMapScale(vtkFloatingPointType theMapScale)
486 if(!VISU::CheckIsSameValue(myMapperTable->GetMapScale(), theMapScale)){
487 myMapperTable->SetMapScale(theMapScale);
488 myMapperTable->Build();
496 return myMapperTable->GetMapScale();
500 //----------------------------------------------------------------------------
503 ::GetSourceRange(vtkFloatingPointType theRange[2])
505 myExtractor->Update();
506 myExtractor->GetOutput()->GetScalarRange( theRange );
508 if (isnan(theRange[0]) || isnan(theRange[1]))
509 throw std::runtime_error("NAN values in the presentation");
516 vtkFloatingPointType aRange[2];
517 GetSourceRange( aRange );
518 SetScalarRange( aRange );
521 //----------------------------------------------------------------------------
524 ::UpdateMapperLookupTable()
526 //rnv: This method update pointer to the myMapperTable in the MapperHolder
527 GetMapperHolder()->SetLookupTable(GetMapperTable());