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 ( theRange[0] > theRange[1] )
176 if (VISU::CheckIsSameRange( GetScalarRange(), theRange) )
179 myFieldTransform->SetScalarRange( theRange );
180 myBarTable->SetRange( theRange );
184 //----------------------------------------------------------------------------
187 ::SetScalarFilterRange( vtkFloatingPointType theRange[2] )
189 vtkFloatingPointType aRange[ 2 ];
190 this->GetScalarFilterRange( aRange );
192 if ( VISU::CheckIsSameRange( aRange, theRange) )
195 myThreshold->ThresholdBetween( theRange[0], theRange[1] );
199 //----------------------------------------------------------------------------
202 ::GetScalarFilterRange( vtkFloatingPointType theRange[2] )
204 theRange[ 0 ] = myThreshold->GetLowerThreshold();
205 theRange[ 1 ] = myThreshold->GetUpperThreshold();
209 //----------------------------------------------------------------------------
210 vtkFloatingPointType*
212 ::GetScalarFilterRange()
214 static vtkFloatingPointType aRange[ 2 ];
216 this->GetScalarFilterRange( aRange );
222 //----------------------------------------------------------------------------
225 ::UseScalarFiltering( bool theUseScalarFilter )
227 if ( theUseScalarFilter ) {
228 // Include threshold filter between the transform and the pass filters.
229 myPassFilter->SetInput( myThreshold->GetOutput() );
231 // Exclude threshold filter before the pass filter.
232 myPassFilter->SetInput( myFieldTransform->GetOutput() );
237 //----------------------------------------------------------------------------
240 ::IsScalarFilterUsed()
242 return myThreshold->GetOutput() == myPassFilter->GetInput();
246 //----------------------------------------------------------------------------
251 unsigned long int aTime = this->GetMTime();
252 // If modified then update the distribution array
253 if (aTime > myDistribution->GetMTime()) {
254 // Set number of colors for the distribution
255 int nbColors = this->GetNbColors();
256 this->myDistribution->SetNumberOfValues(nbColors);
257 // Initialize numbers of colored cells with zero
258 this->myDistribution->FillComponent(0, 0);
259 // Create a lookup table to compute a color of a cell
260 VISU_LookupTable* lut = GetMapperTable();
261 vtkFloatingPointType aMapScale = lut->GetMapScale();
262 // Get scalar values from the input data to calculate their distribution within cells
263 vtkDataArray* dataArr;
264 // Dtermine where we have to take scalars from: cells data or points data.
265 if(VISU::IsDataOnCells(this->GetOutput())) {
266 dataArr = this->GetOutput()->GetCellData()->GetScalars();
268 dataArr = this->GetOutput()->GetPointData()->GetScalars();
270 // If scalars data array is not defined then create an empty one to avoid exceptions
271 if (dataArr == NULL) {
272 dataArr = vtkDoubleArray::New();
275 // Get range of scalars values
276 // vtkFloatingPointType aRange[2];
277 // dataArr->GetRange(aRange);
279 // Build the lookup table with the found range
280 // Get number of scalar values
281 int aNbVals = dataArr->GetNumberOfTuples();
283 // Count the number of scalar values for each color in the input data
286 // For each scalar value
287 for(vtkIdType aValId = 0; aValId < aNbVals; aValId++){
288 // Find the color index for this scalar value
289 idx = lut->GetIndex(*(dataArr->GetTuple(aValId)) * aMapScale);
290 // Increment the distribution value for this color index
291 cnt = this->myDistribution->GetValue(idx);
292 this->myDistribution->SetValue(idx, cnt + 1);
294 // Compute relative values when 1 is according to the total number of scalar values
295 for(vtkIdType aValId = 0; aValId < nbColors; aValId++){
296 cnt = this->myDistribution->GetValue(aValId);
297 this->myDistribution->SetValue(aValId, cnt / aNbVals);
300 this->myDistribution->Modified();
304 return myDistribution;
306 //----------------------------------------------------------------------------
309 //----------------------------------------------------------------------------
310 vtkFloatingPointType*
314 return myFieldTransform->GetScalarRange();
317 //----------------------------------------------------------------------------
320 ::SetScaling(int theScaling)
322 if(GetScaling() == theScaling)
325 myBarTable->SetScale(theScaling);
327 if(theScaling == VTK_SCALE_LOG10)
328 myFieldTransform->SetScalarTransform(&(VISU_FieldTransform::Log10));
330 myFieldTransform->SetScalarTransform(&(VISU_FieldTransform::Ident));
333 //----------------------------------------------------------------------------
338 return myBarTable->GetScale();
341 //----------------------------------------------------------------------------
344 ::SetNbColors(int theNbColors)
346 myMapperTable->SetNumberOfColors(theNbColors);
347 myBarTable->SetNumberOfColors(theNbColors);
354 return myMapperTable->GetNumberOfColors();
358 //----------------------------------------------------------------------------
365 vtkFloatingPointType aRange[2];
366 GetSourceRange( aRange );
368 SetScalarRange( aRange );
369 SetScalarFilterRange( aRange );
372 //----------------------------------------------------------------------------
377 if(myPassFilter->GetInput())
378 myPassFilter->Update();
379 return myPassFilter->GetUnstructuredGridOutput();
383 //----------------------------------------------------------------------------
388 myExtractor->SetInput( Superclass::GetClippedInput() );
389 myFieldTransform->SetInput(myExtractor->GetOutput());
391 myThreshold->SetInput( myFieldTransform->GetOutput() );
392 // The pass filter is used here for possibility to include/exclude
393 // threshold filter before it.
394 myPassFilter->SetInput( myFieldTransform->GetOutput() );
396 GetMapperHolder()->SetLookupTable(GetMapperTable());
397 //GetMapper()->InterpolateScalarsBeforeMappingOn();
398 GetMapper()->SetUseLookupTableScalarRange( true );
399 GetMapper()->SetColorModeToMapScalars();
400 GetMapper()->ScalarVisibilityOn();
404 //----------------------------------------------------------------------------
409 vtkFloatingPointType *aRange = GetScalarRange();
410 vtkFloatingPointType aScalarRange[2] = {aRange[0], aRange[1]};
411 if(myBarTable->GetScale() == VTK_SCALE_LOG10)
412 VISU_LookupTable::ComputeLogRange(aRange, aScalarRange);
414 if(!VISU::CheckIsSameRange(myMapperTable->GetRange(), aScalarRange))
415 myMapperTable->SetRange(aScalarRange);
417 myMapperTable->Build();
420 Superclass::Update();
424 //----------------------------------------------------------------------------
429 unsigned long int aSize = Superclass::GetMemorySize();
431 if(vtkDataObject* aDataObject = myExtractor->GetInput())
432 aSize = aDataObject->GetActualMemorySize() * 1024;
434 if(vtkDataObject* aDataObject = myFieldTransform->GetInput())
435 aSize += aDataObject->GetActualMemorySize() * 1024;
441 //----------------------------------------------------------------------------
446 return myMapperTable.GetPointer();
450 //----------------------------------------------------------------------------
455 return myBarTable.GetPointer();
459 //----------------------------------------------------------------------------
462 ::GetExtractorFilter()
464 return myExtractor.GetPointer();
468 //----------------------------------------------------------------------------
471 ::GetFieldTransformFilter()
473 return myFieldTransform.GetPointer();
477 //----------------------------------------------------------------------------
480 ::SetMapScale(vtkFloatingPointType theMapScale)
482 if(!VISU::CheckIsSameValue(myMapperTable->GetMapScale(), theMapScale)){
483 myMapperTable->SetMapScale(theMapScale);
484 myMapperTable->Build();
492 return myMapperTable->GetMapScale();
496 //----------------------------------------------------------------------------
499 ::GetSourceRange(vtkFloatingPointType theRange[2])
501 myExtractor->Update();
502 myExtractor->GetOutput()->GetScalarRange( theRange );
504 if (isnan(theRange[0]) || isnan(theRange[1]))
505 throw std::runtime_error("Arithmetic exception detected");
512 vtkFloatingPointType aRange[2];
513 GetSourceRange( aRange );
514 SetScalarRange( aRange );