Salome HOME
1407f02e9e16ffb679b3f8a6141b03db27d97051
[modules/visu.git] / src / PIPELINE / VISU_ColoredPL.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  VISU OBJECT : interactive object for VISU entities implementation
23 // File:    VISU_ColoredPL.cxx
24 // Author:  Alexey PETROV
25 // Module : VISU
26 //
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"
32
33 #include "VISU_PipeLineUtils.hxx"
34
35 #include <vtkThreshold.h>
36 #include <vtkPassThroughFilter.h>
37 #include <vtkDoubleArray.h>
38
39 #ifdef WNT
40 #include <float.h>
41 #define isnan _isnan
42 #endif
43
44 //----------------------------------------------------------------------------
45 VISU_ColoredPL
46 ::VISU_ColoredPL():
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() )
54 {
55   myMapperTable->Delete();
56   myMapperTable->SetScale(VTK_SCALE_LINEAR);
57   myMapperTable->SetHueRange(0.667, 0.0);
58
59   myBarTable->Delete();
60   myBarTable->SetScale(VTK_SCALE_LINEAR);
61   myBarTable->SetHueRange(0.667, 0.0);
62
63   myExtractor->Delete();
64
65   myFieldTransform->Delete();
66
67   myThreshold->AllScalarsOff(); 
68   myThreshold->Delete();
69   myPassFilter->Delete();
70   myDistribution->Delete();
71 }
72
73
74 //----------------------------------------------------------------------------
75 VISU_ColoredPL
76 ::~VISU_ColoredPL()
77 {}
78
79
80 //----------------------------------------------------------------------------
81 unsigned long int 
82 VISU_ColoredPL
83 ::GetMTime()
84 {
85   unsigned long int aTime = Superclass::GetMTime();
86
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());
94
95   return aTime;
96 }
97
98
99 //----------------------------------------------------------------------------
100 void
101 VISU_ColoredPL
102 ::DoShallowCopy(VISU_PipeLine *thePipeLine,
103                 bool theIsCopyInput)
104 {
105   Superclass::DoShallowCopy(thePipeLine, theIsCopyInput);
106
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() );
112     }
113
114     SetScalarMode(aPipeLine->GetScalarMode());
115     SetNbColors(aPipeLine->GetNbColors());
116     SetScaling(aPipeLine->GetScaling());
117     SetMapScale(aPipeLine->GetMapScale());
118   }
119 }
120
121
122 //----------------------------------------------------------------------------
123 int
124 VISU_ColoredPL
125 ::GetScalarMode()
126 {
127   return myExtractor->GetScalarMode();
128 }
129
130
131 //----------------------------------------------------------------------------
132 void
133 VISU_ColoredPL
134 ::SetScalarMode(int theScalarMode,
135                 vtkDataSet *theInput,
136                 VISU_Extractor* theExtractor)
137 {
138   if(theInput){
139     if(VISU::IsDataOnPoints(theInput)){
140       vtkPointData *aPointData = theInput->GetPointData();
141       if(!aPointData->GetAttribute(vtkDataSetAttributes::VECTORS)) {
142         if(theScalarMode == 0){
143           return;
144         }
145       }
146     } else {
147       vtkCellData *aCellData = theInput->GetCellData();
148       if(!aCellData->GetAttribute(vtkDataSetAttributes::VECTORS)){
149         if(theScalarMode == 0){
150           return;
151         }
152       }
153     }
154   }
155
156   theExtractor->SetScalarMode(theScalarMode);
157 }
158
159 //----------------------------------------------------------------------------
160 void
161 VISU_ColoredPL
162 ::SetScalarMode(int theScalarMode)
163 {
164   SetScalarMode(theScalarMode, GetInput(), myExtractor);
165 }
166
167
168 //----------------------------------------------------------------------------
169 void
170 VISU_ColoredPL
171 ::SetScalarRange( vtkFloatingPointType theRange[2] )
172 {
173   if (isnan(theRange[0]) || isnan(theRange[1]))
174     throw std::runtime_error("NAN values in the presentation");
175
176   if ( theRange[0] > theRange[1] ) 
177     return;
178   
179   if (VISU::CheckIsSameRange( GetScalarRange(), theRange) )
180     return;
181
182   myFieldTransform->SetScalarRange( theRange );
183   myBarTable->SetRange( theRange );
184 }
185
186
187 //----------------------------------------------------------------------------
188 void
189 VISU_ColoredPL
190 ::SetScalarFilterRange( vtkFloatingPointType theRange[2] )
191 {
192   vtkFloatingPointType aRange[ 2 ];
193   this->GetScalarFilterRange( aRange );
194
195   if ( VISU::CheckIsSameRange( aRange, theRange) )
196     return;
197
198   myThreshold->ThresholdBetween( theRange[0], theRange[1] );
199 }
200
201
202 //----------------------------------------------------------------------------
203 void
204 VISU_ColoredPL
205 ::GetScalarFilterRange( vtkFloatingPointType theRange[2] )
206 {
207   theRange[ 0 ] = myThreshold->GetLowerThreshold();
208   theRange[ 1 ] = myThreshold->GetUpperThreshold();
209 }
210
211
212 //----------------------------------------------------------------------------
213 vtkFloatingPointType*
214 VISU_ColoredPL
215 ::GetScalarFilterRange()
216 {
217   static vtkFloatingPointType aRange[ 2 ];
218
219   this->GetScalarFilterRange( aRange );
220
221   return aRange;
222 }
223
224
225 //----------------------------------------------------------------------------
226 void
227 VISU_ColoredPL
228 ::UseScalarFiltering( bool theUseScalarFilter )
229 {
230   if ( theUseScalarFilter ) {
231     // Include threshold filter between the transform and the pass filters. 
232     myPassFilter->SetInput( myThreshold->GetOutput() );
233   } else {
234     // Exclude threshold filter before the pass filter. 
235     myPassFilter->SetInput( myFieldTransform->GetOutput() );
236   }
237 }
238
239
240 //----------------------------------------------------------------------------
241 bool
242 VISU_ColoredPL
243 ::IsScalarFilterUsed()
244 {
245   return myThreshold->GetOutput() == myPassFilter->GetInput();
246 }
247
248
249 //----------------------------------------------------------------------------
250 vtkDoubleArray* 
251 VISU_ColoredPL
252 ::GetDistribution() 
253 {
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();
270     } else {
271         dataArr = this->GetOutput()->GetPointData()->GetScalars();
272     }
273     // If scalars data array is not defined then create an empty one to avoid exceptions
274     if (dataArr == NULL) {
275         dataArr = vtkDoubleArray::New();
276     }
277     
278     // Get range of scalars values
279 //    vtkFloatingPointType aRange[2];
280 //    dataArr->GetRange(aRange);
281
282     // Build the lookup table with the found range
283     // Get number of scalar values
284     int aNbVals = dataArr->GetNumberOfTuples();
285     if (aNbVals > 0) {
286       // Count the number of scalar values for each color in the input data
287       int idx = 0;
288       double cnt = 0;
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);
296       }
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);
301       }
302     }
303     this->myDistribution->Modified();
304         
305   }
306   
307   return myDistribution;
308 }
309 //----------------------------------------------------------------------------
310   // RKV : End
311
312 //----------------------------------------------------------------------------
313 vtkFloatingPointType* 
314 VISU_ColoredPL
315 ::GetScalarRange() 
316 {
317   return myFieldTransform->GetScalarRange();
318 }
319
320 //----------------------------------------------------------------------------
321 void
322 VISU_ColoredPL
323 ::SetScaling(int theScaling) 
324 {
325   if(GetScaling() == theScaling)
326     return;
327
328   myBarTable->SetScale(theScaling);
329
330   if(theScaling == VTK_SCALE_LOG10)
331     myFieldTransform->SetScalarTransform(&(VISU_FieldTransform::Log10));
332   else
333     myFieldTransform->SetScalarTransform(&(VISU_FieldTransform::Ident));
334 }
335
336 //----------------------------------------------------------------------------
337 int
338 VISU_ColoredPL
339 ::GetScaling() 
340 {
341   return myBarTable->GetScale();
342 }
343
344 //----------------------------------------------------------------------------
345 void
346 VISU_ColoredPL
347 ::SetNbColors(int theNbColors) 
348 {
349   myMapperTable->SetNumberOfColors(theNbColors);
350   myBarTable->SetNumberOfColors(theNbColors);
351 }
352
353 int
354 VISU_ColoredPL
355 ::GetNbColors() 
356 {
357   return myMapperTable->GetNumberOfColors();
358 }
359
360
361 //----------------------------------------------------------------------------
362 void
363 VISU_ColoredPL
364 ::Init()
365 {
366   SetScalarMode(0);
367
368   vtkFloatingPointType aRange[2];
369   GetSourceRange( aRange );
370
371   SetScalarRange( aRange );
372   SetScalarFilterRange( aRange );
373 }
374
375 //----------------------------------------------------------------------------
376 vtkPointSet* 
377 VISU_ColoredPL
378 ::GetClippedInput()
379 {
380   if(myPassFilter->GetInput())
381     myPassFilter->Update();
382   return myPassFilter->GetUnstructuredGridOutput();
383 }
384
385
386 //----------------------------------------------------------------------------
387 void
388 VISU_ColoredPL
389 ::Build() 
390 {
391   myExtractor->SetInput( Superclass::GetClippedInput() );
392   myFieldTransform->SetInput(myExtractor->GetOutput());
393
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() );
398
399   GetMapperHolder()->SetLookupTable(GetMapperTable());
400   //GetMapper()->InterpolateScalarsBeforeMappingOn();
401   GetMapper()->SetUseLookupTableScalarRange( true );
402   GetMapper()->SetColorModeToMapScalars();
403   GetMapper()->ScalarVisibilityOn();
404 }
405
406
407 //----------------------------------------------------------------------------
408 void
409 VISU_ColoredPL
410 ::Update() 
411
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);
416
417   if(!VISU::CheckIsSameRange(myMapperTable->GetRange(), aScalarRange))
418     myMapperTable->SetRange(aScalarRange);
419   
420   myMapperTable->Build();
421   myBarTable->Build();
422
423   Superclass::Update();
424 }
425
426
427 //----------------------------------------------------------------------------
428 unsigned long int
429 VISU_ColoredPL
430 ::GetMemorySize()
431 {
432   unsigned long int aSize = Superclass::GetMemorySize();
433
434   if(vtkDataObject* aDataObject = myExtractor->GetInput())
435     aSize = aDataObject->GetActualMemorySize() * 1024;
436   
437   if(vtkDataObject* aDataObject = myFieldTransform->GetInput())
438     aSize += aDataObject->GetActualMemorySize() * 1024;
439   
440   return aSize;
441 }
442
443
444 //----------------------------------------------------------------------------
445 VISU_LookupTable *
446 VISU_ColoredPL
447 ::GetMapperTable()
448
449   return myMapperTable.GetPointer();
450 }
451
452
453 //----------------------------------------------------------------------------
454 VISU_LookupTable*
455 VISU_ColoredPL
456 ::GetBarTable()
457 {
458   return myBarTable.GetPointer();
459 }
460
461
462 //----------------------------------------------------------------------------
463 VISU_Extractor*
464 VISU_ColoredPL
465 ::GetExtractorFilter()
466 {
467   return myExtractor.GetPointer();
468 }
469
470
471 //----------------------------------------------------------------------------
472 VISU_FieldTransform*
473 VISU_ColoredPL
474 ::GetFieldTransformFilter()
475 {
476   return myFieldTransform.GetPointer();
477 }
478
479
480 //----------------------------------------------------------------------------
481 void 
482 VISU_ColoredPL
483 ::SetMapScale(vtkFloatingPointType theMapScale)
484 {
485   if(!VISU::CheckIsSameValue(myMapperTable->GetMapScale(), theMapScale)){
486     myMapperTable->SetMapScale(theMapScale);
487     myMapperTable->Build();
488   }
489 }
490
491 vtkFloatingPointType
492 VISU_ColoredPL
493 ::GetMapScale()
494 {
495   return myMapperTable->GetMapScale();
496 }
497
498
499 //----------------------------------------------------------------------------
500 void
501 VISU_ColoredPL
502 ::GetSourceRange(vtkFloatingPointType theRange[2])
503 {
504   myExtractor->Update();
505   myExtractor->GetOutput()->GetScalarRange( theRange );
506   
507   if (isnan(theRange[0]) || isnan(theRange[1]))
508     throw std::runtime_error("NAN values in the presentation");
509 }
510
511 void
512 VISU_ColoredPL
513 ::SetSourceRange()
514 {
515   vtkFloatingPointType aRange[2];
516   GetSourceRange( aRange );
517   SetScalarRange( aRange );
518 }