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