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_ColoredPL.cxx
24 // Author: Alexey PETROV
27 #include "VISU_ColoredPL.hxx"
28 #include "VISU_Extractor.hxx"
29 #include "VISU_FieldTransform.hxx"
30 #include "VISU_LookupTable.hxx"
31 #include "VISU_MapperHolder.hxx"
33 #include "VISU_PipeLineUtils.hxx"
35 #include <vtkThreshold.h>
36 #include <vtkPassThroughFilter.h>
37 #include <vtkDoubleArray.h>
44 //----------------------------------------------------------------------------
47 myMapperTable( VISU_LookupTable::New() ),
48 myBarTable( VISU_LookupTable::New() ),
49 myExtractor( VISU_Extractor::New() ),
50 myFieldTransform( VISU_FieldTransform::New() ),
51 myThreshold ( vtkThreshold::New() ),
52 myPassFilter( vtkPassThroughFilter::New() ),
53 myDistribution( vtkDoubleArray::New() )
55 myMapperTable->Delete();
56 myMapperTable->SetScale(VTK_SCALE_LINEAR);
57 myMapperTable->SetHueRange(0.667, 0.0);
60 myBarTable->SetScale(VTK_SCALE_LINEAR);
61 myBarTable->SetHueRange(0.667, 0.0);
63 myExtractor->Delete();
65 myFieldTransform->Delete();
67 myThreshold->AllScalarsOn();
68 myThreshold->Delete();
69 myPassFilter->Delete();
70 myDistribution->Delete();
74 //----------------------------------------------------------------------------
80 //----------------------------------------------------------------------------
85 unsigned long int aTime = Superclass::GetMTime();
87 aTime = std::max(aTime, myMapperTable->GetMTime());
88 aTime = std::max(aTime, myBarTable->GetMTime());
89 aTime = std::max(aTime, myExtractor->GetMTime());
90 aTime = std::max(aTime, myFieldTransform->GetMTime());
91 aTime = std::max(aTime, myThreshold->GetMTime());
92 aTime = std::max(aTime, myPassFilter->GetMTime());
93 aTime = std::max(aTime, myDistribution->GetMTime());
99 //----------------------------------------------------------------------------
102 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
105 Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
107 if(VISU_ColoredPL *aPipeLine = dynamic_cast<VISU_ColoredPL*>(thePipeLine)){
108 if ( theIsCopyInput ) {
109 SetScalarRange( aPipeLine->GetScalarRange() );
110 if ( this->IsScalarFilterUsed() )
111 SetScalarFilterRange( aPipeLine->GetScalarFilterRange() );
114 SetScalarMode(aPipeLine->GetScalarMode());
115 SetNbColors(aPipeLine->GetNbColors());
116 SetScaling(aPipeLine->GetScaling());
117 SetMapScale(aPipeLine->GetMapScale());
122 //----------------------------------------------------------------------------
127 return myExtractor->GetScalarMode();
131 //----------------------------------------------------------------------------
134 ::SetScalarMode(int theScalarMode,
135 vtkDataSet *theInput,
136 VISU_Extractor* theExtractor)
139 if(VISU::IsDataOnPoints(theInput)){
140 vtkPointData *aPointData = theInput->GetPointData();
141 if(!aPointData->GetAttribute(vtkDataSetAttributes::VECTORS)) {
142 if(theScalarMode == 0){
147 vtkCellData *aCellData = theInput->GetCellData();
148 if(!aCellData->GetAttribute(vtkDataSetAttributes::VECTORS)){
149 if(theScalarMode == 0){
156 theExtractor->SetScalarMode(theScalarMode);
159 //----------------------------------------------------------------------------
162 ::SetScalarMode(int theScalarMode)
164 SetScalarMode(theScalarMode, GetInput(), myExtractor);
168 //----------------------------------------------------------------------------
171 ::SetScalarRange( vtkFloatingPointType theRange[2] )
173 if (isnan(theRange[0]) || isnan(theRange[1]))
174 throw std::runtime_error("NAN values in the presentation");
176 if ( theRange[0] > theRange[1] )
179 if (VISU::CheckIsSameRange( GetScalarRange(), theRange) )
182 myFieldTransform->SetScalarRange( theRange );
183 myBarTable->SetRange( theRange );
187 //----------------------------------------------------------------------------
190 ::SetScalarFilterRange( vtkFloatingPointType theRange[2] )
192 vtkFloatingPointType aRange[ 2 ];
193 this->GetScalarFilterRange( aRange );
195 if ( VISU::CheckIsSameRange( aRange, theRange) )
198 myThreshold->ThresholdBetween( theRange[0], theRange[1] );
202 //----------------------------------------------------------------------------
205 ::GetScalarFilterRange( vtkFloatingPointType theRange[2] )
207 theRange[ 0 ] = myThreshold->GetLowerThreshold();
208 theRange[ 1 ] = myThreshold->GetUpperThreshold();
212 //----------------------------------------------------------------------------
213 vtkFloatingPointType*
215 ::GetScalarFilterRange()
217 static vtkFloatingPointType aRange[ 2 ];
219 this->GetScalarFilterRange( aRange );
225 //----------------------------------------------------------------------------
228 ::UseScalarFiltering( bool theUseScalarFilter )
230 if ( theUseScalarFilter ) {
231 // Include threshold filter between the transform and the pass filters.
232 myPassFilter->SetInput( myThreshold->GetOutput() );
234 // Exclude threshold filter before the pass filter.
235 myPassFilter->SetInput( myFieldTransform->GetOutput() );
240 //----------------------------------------------------------------------------
243 ::IsScalarFilterUsed()
245 return myThreshold->GetOutput() == myPassFilter->GetInput();
249 //----------------------------------------------------------------------------
254 unsigned long int aTime = this->GetMTime();
255 // If modified then update the distribution array
256 if (aTime > myDistribution->GetMTime()) {
257 // Set number of colors for the distribution
258 int nbColors = this->GetNbColors();
259 this->myDistribution->SetNumberOfValues(nbColors);
260 // Initialize numbers of colored cells with zero
261 this->myDistribution->FillComponent(0, 0);
262 // Create a lookup table to compute a color of a cell
263 VISU_LookupTable* lut = GetMapperTable();
264 vtkFloatingPointType aMapScale = lut->GetMapScale();
265 // Get scalar values from the input data to calculate their distribution within cells
266 vtkDataArray* dataArr;
267 // Dtermine where we have to take scalars from: cells data or points data.
268 if(VISU::IsDataOnCells(this->GetOutput())) {
269 dataArr = this->GetOutput()->GetCellData()->GetScalars();
271 dataArr = this->GetOutput()->GetPointData()->GetScalars();
273 // If scalars data array is not defined then create an empty one to avoid exceptions
274 if (dataArr == NULL) {
275 dataArr = vtkDoubleArray::New();
278 // Get range of scalars values
279 // vtkFloatingPointType aRange[2];
280 // dataArr->GetRange(aRange);
282 // Build the lookup table with the found range
283 // Get number of scalar values
284 int aNbVals = dataArr->GetNumberOfTuples();
286 // Count the number of scalar values for each color in the input data
289 // For each scalar value
290 for(vtkIdType aValId = 0; aValId < aNbVals; aValId++){
291 // Find the color index for this scalar value
292 idx = lut->GetIndex(*(dataArr->GetTuple(aValId)) * aMapScale);
293 // Increment the distribution value for this color index
294 cnt = this->myDistribution->GetValue(idx);
295 this->myDistribution->SetValue(idx, cnt + 1);
297 // Compute relative values when 1 is according to the total number of scalar values
298 for(vtkIdType aValId = 0; aValId < nbColors; aValId++){
299 cnt = this->myDistribution->GetValue(aValId);
300 this->myDistribution->SetValue(aValId, cnt / aNbVals);
303 this->myDistribution->Modified();
307 return myDistribution;
309 //----------------------------------------------------------------------------
312 //----------------------------------------------------------------------------
313 vtkFloatingPointType*
317 return myFieldTransform->GetScalarRange();
320 //----------------------------------------------------------------------------
323 ::SetScaling(int theScaling)
325 if(GetScaling() == theScaling)
328 myBarTable->SetScale(theScaling);
330 if(theScaling == VTK_SCALE_LOG10)
331 myFieldTransform->SetScalarTransform(&(VISU_FieldTransform::Log10));
333 myFieldTransform->SetScalarTransform(&(VISU_FieldTransform::Ident));
336 //----------------------------------------------------------------------------
341 return myBarTable->GetScale();
344 //----------------------------------------------------------------------------
347 ::SetNbColors(int theNbColors)
349 myMapperTable->SetNumberOfColors(theNbColors);
350 myBarTable->SetNumberOfColors(theNbColors);
357 return myMapperTable->GetNumberOfColors();
361 //----------------------------------------------------------------------------
368 vtkFloatingPointType aRange[2];
369 GetSourceRange( aRange );
371 SetScalarRange( aRange );
372 SetScalarFilterRange( aRange );
375 //----------------------------------------------------------------------------
380 if(myPassFilter->GetInput())
381 myPassFilter->Update();
382 return myPassFilter->GetUnstructuredGridOutput();
386 //----------------------------------------------------------------------------
391 myExtractor->SetInput( Superclass::GetClippedInput() );
392 myFieldTransform->SetInput(myExtractor->GetOutput());
394 myThreshold->SetInput( myFieldTransform->GetOutput() );
395 // The pass filter is used here for possibility to include/exclude
396 // threshold filter before it.
397 myPassFilter->SetInput( myFieldTransform->GetOutput() );
399 GetMapperHolder()->SetLookupTable(GetMapperTable());
400 //GetMapper()->InterpolateScalarsBeforeMappingOn();
401 GetMapper()->SetUseLookupTableScalarRange( true );
402 GetMapper()->SetColorModeToMapScalars();
403 GetMapper()->ScalarVisibilityOn();
407 //----------------------------------------------------------------------------
412 vtkFloatingPointType *aRange = GetScalarRange();
413 vtkFloatingPointType aScalarRange[2] = {aRange[0], aRange[1]};
414 if(myBarTable->GetScale() == VTK_SCALE_LOG10)
415 VISU_LookupTable::ComputeLogRange(aRange, aScalarRange);
417 if(!VISU::CheckIsSameRange(myMapperTable->GetRange(), aScalarRange))
418 myMapperTable->SetRange(aScalarRange);
420 myMapperTable->Build();
423 Superclass::Update();
427 //----------------------------------------------------------------------------
432 unsigned long int aSize = Superclass::GetMemorySize();
434 if(vtkDataObject* aDataObject = myExtractor->GetInput())
435 aSize = aDataObject->GetActualMemorySize() * 1024;
437 if(vtkDataObject* aDataObject = myFieldTransform->GetInput())
438 aSize += aDataObject->GetActualMemorySize() * 1024;
444 //----------------------------------------------------------------------------
449 return myMapperTable.GetPointer();
453 //----------------------------------------------------------------------------
458 return myBarTable.GetPointer();
462 //----------------------------------------------------------------------------
465 ::GetExtractorFilter()
467 return myExtractor.GetPointer();
471 //----------------------------------------------------------------------------
474 ::GetFieldTransformFilter()
476 return myFieldTransform.GetPointer();
480 //----------------------------------------------------------------------------
483 ::SetMapScale(vtkFloatingPointType theMapScale)
485 if(!VISU::CheckIsSameValue(myMapperTable->GetMapScale(), theMapScale)){
486 myMapperTable->SetMapScale(theMapScale);
487 myMapperTable->Build();
495 return myMapperTable->GetMapScale();
499 //----------------------------------------------------------------------------
502 ::GetSourceRange(vtkFloatingPointType theRange[2])
504 myExtractor->Update();
505 myExtractor->GetOutput()->GetScalarRange( theRange );
507 if (isnan(theRange[0]) || isnan(theRange[1]))
508 throw std::runtime_error("NAN values in the presentation");
515 vtkFloatingPointType aRange[2];
516 GetSourceRange( aRange );
517 SetScalarRange( aRange );