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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
23 // File : VISU_LookupTable.cxx
24 // Author : Vitaliy Smetannikov
27 #include "VISU_LookupTable.hxx"
29 #include <vtkObjectFactory.h>
30 #include <vtkBitArray.h>
35 VISU_LookupTable *VISU_LookupTable::New() {
36 vtkObject* ret = vtkObjectFactory::CreateInstance("VISU_LookupTable");
38 return (VISU_LookupTable*)ret;
39 return new VISU_LookupTable;
42 VISU_LookupTable::VISU_LookupTable(int sze, int ext)
43 : vtkLookupTable(sze, ext), myScale(1.0), myBicolor(false) {}
45 void VISU_LookupTable::SetMapScale(float theScale)
47 if( myScale != theScale )
54 void VISU_LookupTable::SetBicolor( bool theBicolor )
56 if( myBicolor != theBicolor )
58 myBicolor = theBicolor;
64 int VISU_LookupTable::ComputeLogRange(float inRange[2], float outRange[2]){
65 if(inRange[0] >= inRange[1])
67 if(0.0 <= inRange[0] && 0.0 < inRange[1]){
69 outRange[0] = log10((double)inRange[0]);
71 outRange[0] = log10((double)inRange[1]*1.0E-6);
72 outRange[1] = log10((double)inRange[1]);
74 }else if(inRange[0] < 0.0 && inRange[1] <= 0.0){
75 outRange[0] = log10((double)-inRange[0]);
76 outRange[1] = log10((double)-inRange[1]);
82 unsigned char* VISU_LookupTable::MapValue(float v) {
83 if(GetScale() == VTK_SCALE_LOG10) {
84 float aLowBound = log10(this->TableRange[0]);
85 v = pow(10.0f,aLowBound + (v - aLowBound)*myScale);
86 return vtkLookupTable::MapValue(v);
87 } else if (!myBicolor) {
88 v = this->TableRange[0] + (v - this->TableRange[0])*myScale;
89 return vtkLookupTable::MapValue(v);
91 unsigned char* table = this->Table->GetPointer(0);
92 int index = v > 0 ? 4*static_cast<int>(this->GetNumberOfColors()-1) : 0;
97 // Apply log to value, with appropriate constraints.
98 inline float VISU_ApplyLogScale(float v, float range[2],
101 // is the range set for negative numbers?
106 v = log10(-static_cast<double>(v));
108 else if (range[0] > range[1])
121 v = log10(static_cast<double>(v));
123 else if (range[0] < range[1])
135 // Apply shift/scale to the scalar value v and do table lookup.
136 inline unsigned char *VISU_LinearLookup(float v,
137 unsigned char *table,
139 float shift, float scale,
144 float findx = (v + shift)*scale;
147 if (findx > maxIndex)
150 return &table[4*static_cast<int>(findx)];
152 //return &table[4*(int)(findx + 0.5f)];
156 int index = v > 0 ? 4*static_cast<int>(maxIndex) : 0;
157 return &table[index];
161 // accelerate the mapping by copying the data in 32-bit chunks instead
164 void VISU_LookupTableMapData(vtkLookupTable *self, T *input,
165 unsigned char *output, int length,
166 int inIncr, int outFormat,
167 float theMapScale, bool bicolor)
170 float *range = self->GetTableRange();
171 float maxIndex = self->GetNumberOfColors() - 1;
173 unsigned char *table = self->GetPointer(0);
177 if ( (alpha=self->GetAlpha()) >= 1.0 ) //no blending required
179 if (self->GetScale() == VTK_SCALE_LOG10)
183 VISU_LookupTable::ComputeLogRange(range, logRange);
184 shift = -logRange[0];
185 if (logRange[1] <= logRange[0])
187 scale = VTK_LARGE_FLOAT;
191 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
194 scale = maxIndex/(logRange[1] - logRange[0]);
196 if (outFormat == VTK_RGBA)
200 val = VISU_ApplyLogScale(*input, range, logRange);
201 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
209 else if (outFormat == VTK_RGB)
213 val = VISU_ApplyLogScale(*input, range, logRange);
214 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
221 else if (outFormat == VTK_LUMINANCE_ALPHA)
225 val = VISU_ApplyLogScale(*input, range, logRange);
226 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
227 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
233 else // outFormat == VTK_LUMINANCE
237 val = VISU_ApplyLogScale(*input, range, logRange);
238 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
239 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
249 if (range[1] <= range[0])
251 scale = VTK_LARGE_FLOAT;
255 scale = (maxIndex + 1)/(range[1] - range[0]);
258 scale = maxIndex/(range[1] - range[0]);
261 if (outFormat == VTK_RGBA)
265 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
273 else if (outFormat == VTK_RGB)
277 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
284 else if (outFormat == VTK_LUMINANCE_ALPHA)
288 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
289 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
295 else // outFormat == VTK_LUMINANCE
299 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
300 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
306 }//if blending not needed
308 else //blend with the specified alpha
310 if (self->GetScale() == VTK_SCALE_LOG10)
314 VISU_LookupTable::ComputeLogRange(range, logRange);
315 shift = -logRange[0];
316 if (logRange[1] <= logRange[0])
318 scale = VTK_LARGE_FLOAT;
322 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
325 scale = maxIndex/(logRange[1] - logRange[0]);
327 if (outFormat == VTK_RGBA)
331 val = VISU_ApplyLogScale(*input, range, logRange);
332 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
336 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
340 else if (outFormat == VTK_RGB)
344 val = VISU_ApplyLogScale(*input, range, logRange);
345 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
352 else if (outFormat == VTK_LUMINANCE_ALPHA)
356 val = VISU_ApplyLogScale(*input, range, logRange);
357 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
358 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
360 *output++ = static_cast<unsigned char>(alpha*cptr[3]);
364 else // outFormat == VTK_LUMINANCE
368 val = VISU_ApplyLogScale(*input, range, logRange);
369 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
370 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
375 }//log scale with blending
377 else //no log scale with blending
380 if (range[1] <= range[0])
382 scale = VTK_LARGE_FLOAT;
386 scale = (maxIndex + 1)/(range[1] - range[0]);
389 scale = maxIndex/(range[1] - range[0]);
392 if (outFormat == VTK_RGBA)
396 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale, bicolor);
400 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
404 else if (outFormat == VTK_RGB)
408 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale, bicolor);
415 else if (outFormat == VTK_LUMINANCE_ALPHA)
419 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale, bicolor);
420 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
422 *output++ = static_cast<unsigned char>(cptr[3]*alpha);
426 else // outFormat == VTK_LUMINANCE
430 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale, bicolor);
431 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
440 // Although this is a relatively expensive calculation,
441 // it is only done on the first render. Colors are cached
442 // for subsequent renders.
444 void VISU_LookupTableMapMag(vtkLookupTable *self, T *input,
445 unsigned char *output, int length,
446 int inIncr, int outFormat,
447 float theMapScale, bool bicolor)
453 mag = new double[length];
454 for (i = 0; i < length; ++i)
457 for (j = 0; j < inIncr; ++j)
459 tmp = (double)(*input);
466 VISU_LookupTableMapData(self, mag, output, length, 1, outFormat, theMapScale, bicolor);
472 void VISU_LookupTable::MapScalarsThroughTable2(void *input,
473 unsigned char *output,
479 if (this->UseMagnitude && inputIncrement > 1)
481 switch (inputDataType)
484 vtkErrorMacro("Cannot comput magnitude of bit array.");
487 VISU_LookupTableMapMag(this,static_cast<char *>(input),output,
488 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
490 case VTK_UNSIGNED_CHAR:
491 VISU_LookupTableMapMag(this,static_cast<unsigned char *>(input),output,
492 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
495 VISU_LookupTableMapMag(this,static_cast<short *>(input),output,
496 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
498 case VTK_UNSIGNED_SHORT:
499 VISU_LookupTableMapMag(this,static_cast<unsigned short *>(input),output,
500 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
503 VISU_LookupTableMapMag(this,static_cast<int *>(input),output,
504 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
506 case VTK_UNSIGNED_INT:
507 VISU_LookupTableMapMag(this,static_cast<unsigned int *>(input),output,
508 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
511 VISU_LookupTableMapMag(this,static_cast<long *>(input),output,
512 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
514 case VTK_UNSIGNED_LONG:
515 VISU_LookupTableMapMag(this,static_cast<unsigned long *>(input),output,
516 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
519 VISU_LookupTableMapMag(this,static_cast<float *>(input),output,
520 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
523 VISU_LookupTableMapMag(this,static_cast<double *>(input),output,
524 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
527 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");
532 switch (inputDataType)
537 vtkBitArray *bitArray = vtkBitArray::New();
538 bitArray->SetVoidArray(input,numberOfValues,1);
539 vtkUnsignedCharArray *newInput = vtkUnsignedCharArray::New();
540 newInput->SetNumberOfValues(numberOfValues);
541 for (id=i=0; i<numberOfValues; i++, id+=inputIncrement)
543 newInput->SetValue(i, bitArray->GetValue(id));
545 VISU_LookupTableMapData(this,
546 static_cast<unsigned char*>(newInput->GetPointer(0)),
547 output,numberOfValues,
548 inputIncrement,outputFormat,myScale,myBicolor);
555 VISU_LookupTableMapData(this,static_cast<char *>(input),output,
556 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
559 case VTK_UNSIGNED_CHAR:
560 VISU_LookupTableMapData(this,static_cast<unsigned char *>(input),output,
561 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
565 VISU_LookupTableMapData(this,static_cast<short *>(input),output,
566 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
569 case VTK_UNSIGNED_SHORT:
570 VISU_LookupTableMapData(this,static_cast<unsigned short *>(input),output,
571 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
575 VISU_LookupTableMapData(this,static_cast<int *>(input),output,
576 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
579 case VTK_UNSIGNED_INT:
580 VISU_LookupTableMapData(this,static_cast<unsigned int *>(input),output,
581 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
585 VISU_LookupTableMapData(this,static_cast<long *>(input),output,
586 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
589 case VTK_UNSIGNED_LONG:
590 VISU_LookupTableMapData(this,static_cast<unsigned long *>(input),output,
591 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
595 VISU_LookupTableMapData(this,static_cast<float *>(input),output,
596 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
600 VISU_LookupTableMapData(this,static_cast<double *>(input),output,
601 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
605 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");