]> SALOME platform Git repositories - modules/visu.git/blob - src/PIPELINE/VISU_LookupTable.cxx
Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/visu.git] / src / PIPELINE / VISU_LookupTable.cxx
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  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 //  File   : VISU_LookupTable.cxx
24 //  Author : Vitaliy Smetannikov
25 //  Module : VISU
26
27 #include "VISU_LookupTable.hxx"
28
29 #include <vtkObjectFactory.h>
30 #include <vtkBitArray.h>
31 #include <math.h>
32
33 using namespace std;
34
35 vtkStandardNewMacro(VISU_LookupTable);
36
37 VISU_LookupTable
38 ::VISU_LookupTable(int sze, int ext):
39   vtkLookupTable(sze, ext), 
40   myScale(1.0), 
41   myBicolor(false) 
42 {}
43
44 void 
45 VISU_LookupTable
46 ::SetMapScale(vtkFloatingPointType theScale)
47 {
48   if( myScale != theScale )
49   {
50     myScale = theScale;
51     Modified();
52   }
53 }
54
55 void VISU_LookupTable::SetBicolor( bool theBicolor )
56 {
57   if( myBicolor != theBicolor )
58   {
59     myBicolor = theBicolor;
60     Modified();
61   }
62 }
63
64
65 int 
66 VISU_LookupTable
67 ::ComputeLogRange(vtkFloatingPointType inRange[2], 
68                   vtkFloatingPointType outRange[2])
69 {
70   if(inRange[0] >= inRange[1])
71     return -1;
72   if(0.0 <= inRange[0] && 0.0 < inRange[1]){
73     if(inRange[0] != 0.0)
74       outRange[0] = log10((double)inRange[0]);
75     else
76       outRange[0] = log10((double)inRange[1]*1.0E-6);
77     outRange[1] = log10((double)inRange[1]);
78     return 0;
79   }else if(inRange[0] < 0.0 && inRange[1] <= 0.0){
80     outRange[0] = log10((double)-inRange[0]);
81     outRange[1] = log10((double)-inRange[1]);
82     return 1;
83   }else
84     return -1;
85 }
86
87 unsigned char* 
88 VISU_LookupTable
89 ::MapValue(vtkFloatingPointType v) 
90 {
91   if(GetScale() == VTK_SCALE_LOG10) {
92     vtkFloatingPointType aLowBound = log10(this->TableRange[0]);
93     v = pow(vtkFloatingPointType(10.0), aLowBound + (v - aLowBound)*myScale);
94     return vtkLookupTable::MapValue(v);
95   } else if (!myBicolor) {
96     v = this->TableRange[0] + (v - this->TableRange[0])*myScale;
97     return vtkLookupTable::MapValue(v);
98   } else {
99     unsigned char* table = this->Table->GetPointer(0);
100     int index = v > 0 ? 4*static_cast<int>(this->GetNumberOfColors()-1) : 0;
101     return &table[index];
102   }
103 }
104
105 // Apply log to value, with appropriate constraints.
106 inline 
107 vtkFloatingPointType 
108 VISU_ApplyLogScale(vtkFloatingPointType v, 
109                    vtkFloatingPointType range[2], 
110                    vtkFloatingPointType logRange[2])
111 {
112   // is the range set for negative numbers?
113   if (range[0] < 0)
114     {
115     if (v < 0)
116       {
117       v = log10(-static_cast<double>(v));
118       }
119     else if (range[0] > range[1])
120       {
121       v = logRange[0];
122       }
123     else
124       {
125       v = logRange[1];
126       }
127     }
128   else
129     {
130     if (v > 0)
131       {
132       v = log10(static_cast<double>(v));
133       }
134     else if (range[0] < range[1])
135       {
136       v = logRange[0];
137       }
138     else
139       {
140       v = logRange[1];
141       }
142     }
143   return v;
144 }                 
145
146 // Apply shift/scale to the scalar value v and do table lookup.
147 inline 
148 unsigned char *
149 VISU_LinearLookup(vtkFloatingPointType v,   
150                   unsigned char *table,
151                   vtkFloatingPointType maxIndex,
152                   vtkFloatingPointType shift, 
153                   vtkFloatingPointType scale,
154                   bool bicolor)
155 {
156   if( !bicolor )
157   {
158     vtkFloatingPointType findx = (v + shift)*scale;
159     if (findx < 0)
160       findx = 0;
161     if (findx > maxIndex)
162       findx = maxIndex;
163
164     return &table[4*static_cast<int>(findx)];
165     // round
166     //return &table[4*(int)(findx + 0.5f)];
167   }
168   else
169   {
170     int index = v > 0 ? 4*static_cast<int>(maxIndex) : 0;
171     return &table[index];
172   }
173 }
174
175 // accelerate the mapping by copying the data in 32-bit chunks instead
176 // of 8-bit chunks
177 template<class T>
178 void
179 VISU_LookupTableMapData(vtkLookupTable *self, 
180                         T *input, 
181                         unsigned char *output, 
182                         int length, 
183                         int inIncr, 
184                         int outFormat,
185                         vtkFloatingPointType theMapScale, 
186                         bool bicolor)
187 {
188   int i = length;
189   vtkFloatingPointType *range = self->GetTableRange();
190   vtkFloatingPointType maxIndex = self->GetNumberOfColors() - 1;
191   vtkFloatingPointType shift, scale;
192   unsigned char *table = self->GetPointer(0);
193   unsigned char *cptr;
194   vtkFloatingPointType alpha;
195
196   if ( (alpha=self->GetAlpha()) >= 1.0 ) //no blending required 
197     {
198     if (self->GetScale() == VTK_SCALE_LOG10)
199       {
200       vtkFloatingPointType val;
201       vtkFloatingPointType logRange[2];
202       VISU_LookupTable::ComputeLogRange(range, logRange);
203       shift = -logRange[0];
204       if (logRange[1] <= logRange[0])
205         {
206         scale = VTK_LARGE_FLOAT;
207         }
208       else
209         {
210         scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
211         }
212       /* correct scale
213       scale = maxIndex/(logRange[1] - logRange[0]);
214       */
215       if (outFormat == VTK_RGBA)
216         {
217         while (--i >= 0) 
218           {
219           val = VISU_ApplyLogScale(*input, range, logRange);
220           cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor); 
221           *output++ = *cptr++;
222           *output++ = *cptr++;
223           *output++ = *cptr++;
224           *output++ = *cptr++;     
225           input += inIncr;
226           }
227         }
228       else if (outFormat == VTK_RGB)
229         {
230         while (--i >= 0) 
231           {
232           val = VISU_ApplyLogScale(*input, range, logRange);
233           cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor); 
234           *output++ = *cptr++;
235           *output++ = *cptr++;
236           *output++ = *cptr++;
237           input += inIncr;
238           }
239         }
240       else if (outFormat == VTK_LUMINANCE_ALPHA)
241         {
242         while (--i >= 0) 
243           {
244           val = VISU_ApplyLogScale(*input, range, logRange);
245           cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor); 
246           *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 + 
247                                                  cptr[2]*0.11 + 0.5);
248           *output++ = cptr[3];
249           input += inIncr;
250           }
251         }
252       else // outFormat == VTK_LUMINANCE
253         {
254         while (--i >= 0) 
255           {
256           val = VISU_ApplyLogScale(*input, range, logRange);
257           cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor); 
258           *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 + 
259                                                  cptr[2]*0.11 + 0.5);
260           input += inIncr;
261           }
262         }
263       }//if log scale
264
265     else //not log scale
266       {
267       shift = -range[0];
268       if (range[1] <= range[0])
269         {
270         scale = VTK_LARGE_FLOAT;
271         }
272       else
273         {
274         scale = (maxIndex + 1)/(range[1] - range[0]);
275         }
276       /* correct scale
277       scale = maxIndex/(range[1] - range[0]);
278       */
279
280       if (outFormat == VTK_RGBA)
281         {
282         while (--i >= 0) 
283           {
284           cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor); 
285           *output++ = *cptr++;
286           *output++ = *cptr++;
287           *output++ = *cptr++;
288           *output++ = *cptr++;     
289           input += inIncr;
290           }
291         }
292       else if (outFormat == VTK_RGB)
293         {
294         while (--i >= 0) 
295           {
296           cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor); 
297           *output++ = *cptr++;
298           *output++ = *cptr++;
299           *output++ = *cptr++;
300           input += inIncr;
301           }
302         }
303       else if (outFormat == VTK_LUMINANCE_ALPHA)
304         {
305         while (--i >= 0) 
306           {
307           cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor); 
308           *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 + 
309                                                  cptr[2]*0.11 + 0.5);
310           *output++ = cptr[3];
311           input += inIncr;
312           }
313         }
314       else // outFormat == VTK_LUMINANCE
315         {
316         while (--i >= 0) 
317           {
318           cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor); 
319           *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 + 
320                                                  cptr[2]*0.11 + 0.5);
321           input += inIncr;
322           }
323         }
324       }//if not log lookup
325     }//if blending not needed
326
327   else //blend with the specified alpha
328     {
329     if (self->GetScale() == VTK_SCALE_LOG10)
330       {
331       vtkFloatingPointType val;
332       vtkFloatingPointType logRange[2];
333       VISU_LookupTable::ComputeLogRange(range, logRange);
334       shift = -logRange[0];
335       if (logRange[1] <= logRange[0])
336         {
337         scale = VTK_LARGE_FLOAT;
338         }
339       else
340         {
341         scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
342         }
343       /* correct scale
344       scale = maxIndex/(logRange[1] - logRange[0]);
345       */
346       if (outFormat == VTK_RGBA)
347         {
348         while (--i >= 0) 
349           {
350           val = VISU_ApplyLogScale(*input, range, logRange);
351           cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor); 
352           *output++ = *cptr++;
353           *output++ = *cptr++;
354           *output++ = *cptr++;
355           *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
356           input += inIncr;
357           }
358         }
359       else if (outFormat == VTK_RGB)
360         {
361         while (--i >= 0) 
362           {
363           val = VISU_ApplyLogScale(*input, range, logRange);
364           cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor); 
365           *output++ = *cptr++;
366           *output++ = *cptr++;
367           *output++ = *cptr++;
368           input += inIncr;
369           }
370         }
371       else if (outFormat == VTK_LUMINANCE_ALPHA)
372         {
373         while (--i >= 0) 
374           {
375           val = VISU_ApplyLogScale(*input, range, logRange);
376           cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor); 
377           *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 + 
378                                                  cptr[2]*0.11 + 0.5);
379           *output++ = static_cast<unsigned char>(alpha*cptr[3]);
380           input += inIncr;
381           }
382         }
383       else // outFormat == VTK_LUMINANCE
384         {
385         while (--i >= 0) 
386           {
387           val = VISU_ApplyLogScale(*input, range, logRange);
388           cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor); 
389           *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 + 
390                                                  cptr[2]*0.11 + 0.5);
391           input += inIncr;
392           }
393         }
394       }//log scale with blending
395
396     else //no log scale with blending
397       {
398       shift = -range[0];
399       if (range[1] <= range[0])
400         {
401         scale = VTK_LARGE_FLOAT;
402         }
403       else
404         {
405         scale = (maxIndex + 1)/(range[1] - range[0]);
406         }
407       /* correct scale
408       scale = maxIndex/(range[1] - range[0]);
409       */
410
411       if (outFormat == VTK_RGBA)
412         {
413         while (--i >= 0) 
414           {
415           cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor); 
416           *output++ = *cptr++;
417           *output++ = *cptr++;
418           *output++ = *cptr++;
419           *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
420           input += inIncr;
421           }
422         }
423       else if (outFormat == VTK_RGB)
424         {
425         while (--i >= 0) 
426           {
427           cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor); 
428           *output++ = *cptr++;
429           *output++ = *cptr++;
430           *output++ = *cptr++;
431           input += inIncr;
432           }
433         }
434       else if (outFormat == VTK_LUMINANCE_ALPHA)
435         {
436         while (--i >= 0) 
437           {
438           cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor); 
439           *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 + 
440                                                  cptr[2]*0.11 + 0.5);
441           *output++ = static_cast<unsigned char>(cptr[3]*alpha);
442           input += inIncr;
443           }
444         }
445       else // outFormat == VTK_LUMINANCE
446         {
447         while (--i >= 0) 
448           {
449           cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor); 
450           *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 + 
451                                                  cptr[2]*0.11 + 0.5);
452           input += inIncr;
453           }
454         }
455       }//no log scale
456     }//alpha blending
457 }
458
459 // Although this is a relatively expensive calculation,
460 // it is only done on the first render. Colors are cached
461 // for subsequent renders.
462 template<class T>
463 void
464 VISU_LookupTableMapMag(vtkLookupTable *self, 
465                        T *input, 
466                        unsigned char *output, 
467                        int length, 
468                        int inIncr, 
469                        int outFormat,
470                        vtkFloatingPointType theMapScale, 
471                        bool bicolor)
472 {
473   double tmp, sum;
474   double *mag;
475   int i, j;
476
477   mag = new double[length];
478   for (i = 0; i < length; ++i)
479     {
480     sum = 0;
481     for (j = 0; j < inIncr; ++j)
482       {
483       tmp = (double)(*input);  
484       sum += (tmp * tmp);
485       ++input;
486       }
487     mag[i] = sqrt(sum);
488     }
489
490   VISU_LookupTableMapData(self, mag, output, length, 1, outFormat, theMapScale, bicolor);
491
492   delete [] mag;
493 }
494
495
496 void VISU_LookupTable::MapScalarsThroughTable2(void *input, 
497                                                unsigned char *output,
498                                                int inputDataType, 
499                                                int numberOfValues,
500                                                int inputIncrement,
501                                                int outputFormat)
502 {
503   if (this->UseMagnitude && inputIncrement > 1)
504     {
505     switch (inputDataType)
506       {
507       case VTK_BIT:
508         vtkErrorMacro("Cannot comput magnitude of bit array.");
509         break;
510       case VTK_CHAR:
511         VISU_LookupTableMapMag(this,static_cast<char *>(input),output,
512                                numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
513         return; 
514       case VTK_UNSIGNED_CHAR:
515         VISU_LookupTableMapMag(this,static_cast<unsigned char *>(input),output,
516                              numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
517         return;
518       case VTK_SHORT:
519         VISU_LookupTableMapMag(this,static_cast<short *>(input),output,
520                              numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
521         return;
522       case VTK_UNSIGNED_SHORT:
523         VISU_LookupTableMapMag(this,static_cast<unsigned short *>(input),output,
524                              numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
525         return;
526       case VTK_INT:
527         VISU_LookupTableMapMag(this,static_cast<int *>(input),output,
528                              numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
529         return;
530       case VTK_UNSIGNED_INT:
531         VISU_LookupTableMapMag(this,static_cast<unsigned int *>(input),output,
532                              numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
533         return;
534       case VTK_LONG:
535         VISU_LookupTableMapMag(this,static_cast<long *>(input),output,
536                              numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
537         return;
538       case VTK_UNSIGNED_LONG:
539         VISU_LookupTableMapMag(this,static_cast<unsigned long *>(input),output,
540                              numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
541         return;
542       case VTK_FLOAT:
543         VISU_LookupTableMapMag(this,static_cast<float *>(input),output,
544                              numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
545         return;
546       case VTK_DOUBLE:
547         VISU_LookupTableMapMag(this,static_cast<double *>(input),output,
548                              numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
549         return;
550       default:
551         vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");
552         return;
553       }
554     }
555
556   switch (inputDataType)
557     {
558     case VTK_BIT:
559       {
560       vtkIdType i, id;
561       vtkBitArray *bitArray = vtkBitArray::New();
562       bitArray->SetVoidArray(input,numberOfValues,1);
563       vtkUnsignedCharArray *newInput = vtkUnsignedCharArray::New();
564       newInput->SetNumberOfValues(numberOfValues);
565       for (id=i=0; i<numberOfValues; i++, id+=inputIncrement)
566         {
567         newInput->SetValue(i, bitArray->GetValue(id));
568         }
569       VISU_LookupTableMapData(this,
570                               static_cast<unsigned char*>(newInput->GetPointer(0)),
571                               output,numberOfValues,
572                               inputIncrement,outputFormat,myScale,myBicolor);
573       newInput->Delete();
574       bitArray->Delete();
575       }
576       break;
577       
578     case VTK_CHAR:
579       VISU_LookupTableMapData(this,static_cast<char *>(input),output,
580                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
581       break;
582       
583     case VTK_UNSIGNED_CHAR:
584       VISU_LookupTableMapData(this,static_cast<unsigned char *>(input),output,
585                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
586       break;
587       
588     case VTK_SHORT:
589       VISU_LookupTableMapData(this,static_cast<short *>(input),output,
590                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
591       break;
592       
593     case VTK_UNSIGNED_SHORT:
594       VISU_LookupTableMapData(this,static_cast<unsigned short *>(input),output,
595                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
596       break;
597       
598     case VTK_INT:
599       VISU_LookupTableMapData(this,static_cast<int *>(input),output,
600                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
601       break;
602       
603     case VTK_UNSIGNED_INT:
604       VISU_LookupTableMapData(this,static_cast<unsigned int *>(input),output,
605                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
606       break;
607       
608     case VTK_LONG:
609       VISU_LookupTableMapData(this,static_cast<long *>(input),output,
610                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
611       break;
612       
613     case VTK_UNSIGNED_LONG:
614       VISU_LookupTableMapData(this,static_cast<unsigned long *>(input),output,
615                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
616       break;
617       
618     case VTK_FLOAT:
619       VISU_LookupTableMapData(this,static_cast<float *>(input),output,
620                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
621       break;
622       
623     case VTK_DOUBLE:
624       VISU_LookupTableMapData(this,static_cast<double *>(input),output,
625                               numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
626       break;
627       
628     default:
629       vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");
630       return;
631     }
632 }  
633