1 // VISU OBJECT : interactive object for VISU entities implementation
3 // Copyright (C) 2003 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
23 // File : VISU_LookupTable.cxx
24 // Author : Vitaliy Smetannikov
27 #include "VISU_LookupTable.hxx"
29 #include <vtkObjectFactory.h>
30 #include <vtkBitArray.h>
35 vtkStandardNewMacro(VISU_LookupTable);
38 ::VISU_LookupTable(int sze, int ext):
39 vtkLookupTable(sze, ext),
46 ::SetMapScale(vtkFloatingPointType theScale)
48 if( myScale != theScale )
55 void VISU_LookupTable::SetBicolor( bool theBicolor )
57 if( myBicolor != theBicolor )
59 myBicolor = theBicolor;
67 ::ComputeLogRange(vtkFloatingPointType inRange[2],
68 vtkFloatingPointType outRange[2])
70 if(inRange[0] >= inRange[1])
72 if(0.0 <= inRange[0] && 0.0 < inRange[1]){
74 outRange[0] = log10((double)inRange[0]);
76 outRange[0] = log10((double)inRange[1]*1.0E-6);
77 outRange[1] = log10((double)inRange[1]);
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]);
89 ::MapValue(vtkFloatingPointType v)
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);
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];
105 // Apply log to value, with appropriate constraints.
108 VISU_ApplyLogScale(vtkFloatingPointType v,
109 vtkFloatingPointType range[2],
110 vtkFloatingPointType logRange[2])
112 // is the range set for negative numbers?
117 v = log10(-static_cast<double>(v));
119 else if (range[0] > range[1])
132 v = log10(static_cast<double>(v));
134 else if (range[0] < range[1])
146 // Apply shift/scale to the scalar value v and do table lookup.
149 VISU_LinearLookup(vtkFloatingPointType v,
150 unsigned char *table,
151 vtkFloatingPointType maxIndex,
152 vtkFloatingPointType shift,
153 vtkFloatingPointType scale,
158 vtkFloatingPointType findx = (v + shift)*scale;
161 if (findx > maxIndex)
164 return &table[4*static_cast<int>(findx)];
166 //return &table[4*(int)(findx + 0.5f)];
170 int index = v > 0 ? 4*static_cast<int>(maxIndex) : 0;
171 return &table[index];
175 // accelerate the mapping by copying the data in 32-bit chunks instead
179 VISU_LookupTableMapData(vtkLookupTable *self,
181 unsigned char *output,
185 vtkFloatingPointType theMapScale,
189 vtkFloatingPointType *range = self->GetTableRange();
190 vtkFloatingPointType maxIndex = self->GetNumberOfColors() - 1;
191 vtkFloatingPointType shift, scale;
192 unsigned char *table = self->GetPointer(0);
194 vtkFloatingPointType alpha;
196 if ( (alpha=self->GetAlpha()) >= 1.0 ) //no blending required
198 if (self->GetScale() == VTK_SCALE_LOG10)
200 vtkFloatingPointType val;
201 vtkFloatingPointType logRange[2];
202 VISU_LookupTable::ComputeLogRange(range, logRange);
203 shift = -logRange[0];
204 if (logRange[1] <= logRange[0])
206 scale = VTK_LARGE_FLOAT;
210 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
213 scale = maxIndex/(logRange[1] - logRange[0]);
215 if (outFormat == VTK_RGBA)
219 val = VISU_ApplyLogScale(*input, range, logRange);
220 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
228 else if (outFormat == VTK_RGB)
232 val = VISU_ApplyLogScale(*input, range, logRange);
233 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
240 else if (outFormat == VTK_LUMINANCE_ALPHA)
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 +
252 else // outFormat == VTK_LUMINANCE
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 +
268 if (range[1] <= range[0])
270 scale = VTK_LARGE_FLOAT;
274 scale = (maxIndex + 1)/(range[1] - range[0]);
277 scale = maxIndex/(range[1] - range[0]);
280 if (outFormat == VTK_RGBA)
284 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
292 else if (outFormat == VTK_RGB)
296 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
303 else if (outFormat == VTK_LUMINANCE_ALPHA)
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 +
314 else // outFormat == VTK_LUMINANCE
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 +
325 }//if blending not needed
327 else //blend with the specified alpha
329 if (self->GetScale() == VTK_SCALE_LOG10)
331 vtkFloatingPointType val;
332 vtkFloatingPointType logRange[2];
333 VISU_LookupTable::ComputeLogRange(range, logRange);
334 shift = -logRange[0];
335 if (logRange[1] <= logRange[0])
337 scale = VTK_LARGE_FLOAT;
341 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
344 scale = maxIndex/(logRange[1] - logRange[0]);
346 if (outFormat == VTK_RGBA)
350 val = VISU_ApplyLogScale(*input, range, logRange);
351 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
355 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
359 else if (outFormat == VTK_RGB)
363 val = VISU_ApplyLogScale(*input, range, logRange);
364 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
371 else if (outFormat == VTK_LUMINANCE_ALPHA)
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 +
379 *output++ = static_cast<unsigned char>(alpha*cptr[3]);
383 else // outFormat == VTK_LUMINANCE
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 +
394 }//log scale with blending
396 else //no log scale with blending
399 if (range[1] <= range[0])
401 scale = VTK_LARGE_FLOAT;
405 scale = (maxIndex + 1)/(range[1] - range[0]);
408 scale = maxIndex/(range[1] - range[0]);
411 if (outFormat == VTK_RGBA)
415 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
419 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
423 else if (outFormat == VTK_RGB)
427 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
434 else if (outFormat == VTK_LUMINANCE_ALPHA)
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 +
441 *output++ = static_cast<unsigned char>(cptr[3]*alpha);
445 else // outFormat == VTK_LUMINANCE
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 +
459 // Although this is a relatively expensive calculation,
460 // it is only done on the first render. Colors are cached
461 // for subsequent renders.
464 VISU_LookupTableMapMag(vtkLookupTable *self,
466 unsigned char *output,
470 vtkFloatingPointType theMapScale,
477 mag = new double[length];
478 for (i = 0; i < length; ++i)
481 for (j = 0; j < inIncr; ++j)
483 tmp = (double)(*input);
490 VISU_LookupTableMapData(self, mag, output, length, 1, outFormat, theMapScale, bicolor);
496 void VISU_LookupTable::MapScalarsThroughTable2(void *input,
497 unsigned char *output,
503 if (this->UseMagnitude && inputIncrement > 1)
505 switch (inputDataType)
508 vtkErrorMacro("Cannot comput magnitude of bit array.");
511 VISU_LookupTableMapMag(this,static_cast<char *>(input),output,
512 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
514 case VTK_UNSIGNED_CHAR:
515 VISU_LookupTableMapMag(this,static_cast<unsigned char *>(input),output,
516 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
519 VISU_LookupTableMapMag(this,static_cast<short *>(input),output,
520 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
522 case VTK_UNSIGNED_SHORT:
523 VISU_LookupTableMapMag(this,static_cast<unsigned short *>(input),output,
524 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
527 VISU_LookupTableMapMag(this,static_cast<int *>(input),output,
528 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
530 case VTK_UNSIGNED_INT:
531 VISU_LookupTableMapMag(this,static_cast<unsigned int *>(input),output,
532 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
535 VISU_LookupTableMapMag(this,static_cast<long *>(input),output,
536 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
538 case VTK_UNSIGNED_LONG:
539 VISU_LookupTableMapMag(this,static_cast<unsigned long *>(input),output,
540 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
543 VISU_LookupTableMapMag(this,static_cast<float *>(input),output,
544 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
547 VISU_LookupTableMapMag(this,static_cast<double *>(input),output,
548 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
551 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");
556 switch (inputDataType)
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)
567 newInput->SetValue(i, bitArray->GetValue(id));
569 VISU_LookupTableMapData(this,
570 static_cast<unsigned char*>(newInput->GetPointer(0)),
571 output,numberOfValues,
572 inputIncrement,outputFormat,myScale,myBicolor);
579 VISU_LookupTableMapData(this,static_cast<char *>(input),output,
580 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
583 case VTK_UNSIGNED_CHAR:
584 VISU_LookupTableMapData(this,static_cast<unsigned char *>(input),output,
585 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
589 VISU_LookupTableMapData(this,static_cast<short *>(input),output,
590 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
593 case VTK_UNSIGNED_SHORT:
594 VISU_LookupTableMapData(this,static_cast<unsigned short *>(input),output,
595 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
599 VISU_LookupTableMapData(this,static_cast<int *>(input),output,
600 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
603 case VTK_UNSIGNED_INT:
604 VISU_LookupTableMapData(this,static_cast<unsigned int *>(input),output,
605 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
609 VISU_LookupTableMapData(this,static_cast<long *>(input),output,
610 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
613 case VTK_UNSIGNED_LONG:
614 VISU_LookupTableMapData(this,static_cast<unsigned long *>(input),output,
615 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
619 VISU_LookupTableMapData(this,static_cast<float *>(input),output,
620 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
624 VISU_LookupTableMapData(this,static_cast<double *>(input),output,
625 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
629 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");