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) {}
45 int VISU_LookupTable::ComputeLogRange(float inRange[2], float outRange[2]){
46 if(inRange[0] >= inRange[1])
48 if(0.0 <= inRange[0] && 0.0 < inRange[1]){
50 outRange[0] = log10((double)inRange[0]);
52 outRange[0] = log10((double)inRange[1]*1.0E-6);
53 outRange[1] = log10((double)inRange[1]);
55 }else if(inRange[0] < 0.0 && inRange[1] <= 0.0){
56 outRange[0] = log10((double)-inRange[0]);
57 outRange[1] = log10((double)-inRange[1]);
63 unsigned char* VISU_LookupTable::MapValue(float v) {
64 if(GetScale() == VTK_SCALE_LOG10) {
65 float aLowBound = log10(this->TableRange[0]);
66 v = pow(10.0f,aLowBound + (v - aLowBound)*myScale);
67 return vtkLookupTable::MapValue(v);
69 v = this->TableRange[0] + (v - this->TableRange[0])*myScale;
70 return vtkLookupTable::MapValue(v);
74 // Apply log to value, with appropriate constraints.
75 inline float VISU_ApplyLogScale(float v, float range[2],
78 // is the range set for negative numbers?
83 v = log10(-static_cast<double>(v));
85 else if (range[0] > range[1])
98 v = log10(static_cast<double>(v));
100 else if (range[0] < range[1])
112 // Apply shift/scale to the scalar value v and do table lookup.
113 inline unsigned char *VISU_LinearLookup(float v,
114 unsigned char *table,
116 float shift, float scale)
118 float findx = (v + shift)*scale;
123 if (findx > maxIndex)
127 return &table[4*static_cast<int>(findx)];
129 return &table[4*(int)(findx + 0.5f)];
133 // accelerate the mapping by copying the data in 32-bit chunks instead
136 void VISU_LookupTableMapData(vtkLookupTable *self, T *input,
137 unsigned char *output, int length,
138 int inIncr, int outFormat, float theMapScale)
141 float *range = self->GetTableRange();
142 float maxIndex = self->GetNumberOfColors() - 1;
144 unsigned char *table = self->GetPointer(0);
148 if ( (alpha=self->GetAlpha()) >= 1.0 ) //no blending required
150 if (self->GetScale() == VTK_SCALE_LOG10)
154 VISU_LookupTable::ComputeLogRange(range, logRange);
155 shift = -logRange[0];
156 if (logRange[1] <= logRange[0])
158 scale = VTK_LARGE_FLOAT;
162 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
165 scale = maxIndex/(logRange[1] - logRange[0]);
167 if (outFormat == VTK_RGBA)
171 val = VISU_ApplyLogScale(*input, range, logRange);
172 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale);
180 else if (outFormat == VTK_RGB)
184 val = VISU_ApplyLogScale(*input, range, logRange);
185 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale);
192 else if (outFormat == VTK_LUMINANCE_ALPHA)
196 val = VISU_ApplyLogScale(*input, range, logRange);
197 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale);
198 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
204 else // outFormat == VTK_LUMINANCE
208 val = VISU_ApplyLogScale(*input, range, logRange);
209 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale);
210 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
220 if (range[1] <= range[0])
222 scale = VTK_LARGE_FLOAT;
226 scale = (maxIndex + 1)/(range[1] - range[0]);
229 scale = maxIndex/(range[1] - range[0]);
232 if (outFormat == VTK_RGBA)
236 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale);
244 else if (outFormat == VTK_RGB)
248 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale);
255 else if (outFormat == VTK_LUMINANCE_ALPHA)
259 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale);
260 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
266 else // outFormat == VTK_LUMINANCE
270 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale);
271 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
277 }//if blending not needed
279 else //blend with the specified alpha
281 if (self->GetScale() == VTK_SCALE_LOG10)
285 VISU_LookupTable::ComputeLogRange(range, logRange);
286 shift = -logRange[0];
287 if (logRange[1] <= logRange[0])
289 scale = VTK_LARGE_FLOAT;
293 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
296 scale = maxIndex/(logRange[1] - logRange[0]);
298 if (outFormat == VTK_RGBA)
302 val = VISU_ApplyLogScale(*input, range, logRange);
303 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale);
307 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
311 else if (outFormat == VTK_RGB)
315 val = VISU_ApplyLogScale(*input, range, logRange);
316 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale);
323 else if (outFormat == VTK_LUMINANCE_ALPHA)
327 val = VISU_ApplyLogScale(*input, range, logRange);
328 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale);
329 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
331 *output++ = static_cast<unsigned char>(alpha*cptr[3]);
335 else // outFormat == VTK_LUMINANCE
339 val = VISU_ApplyLogScale(*input, range, logRange);
340 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale);
341 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
346 }//log scale with blending
348 else //no log scale with blending
351 if (range[1] <= range[0])
353 scale = VTK_LARGE_FLOAT;
357 scale = (maxIndex + 1)/(range[1] - range[0]);
360 scale = maxIndex/(range[1] - range[0]);
363 if (outFormat == VTK_RGBA)
367 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale);
371 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
375 else if (outFormat == VTK_RGB)
379 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale);
386 else if (outFormat == VTK_LUMINANCE_ALPHA)
390 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale);
391 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
393 *output++ = static_cast<unsigned char>(cptr[3]*alpha);
397 else // outFormat == VTK_LUMINANCE
401 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale);
402 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
411 // Although this is a relatively expensive calculation,
412 // it is only done on the first render. Colors are cached
413 // for subsequent renders.
415 void VISU_LookupTableMapMag(vtkLookupTable *self, T *input,
416 unsigned char *output, int length,
417 int inIncr, int outFormat, float theMapScale)
423 mag = new double[length];
424 for (i = 0; i < length; ++i)
427 for (j = 0; j < inIncr; ++j)
429 tmp = (double)(*input);
436 VISU_LookupTableMapData(self, mag, output, length, 1, outFormat, theMapScale);
442 void VISU_LookupTable::MapScalarsThroughTable2(void *input,
443 unsigned char *output,
449 if (this->UseMagnitude && inputIncrement > 1)
451 switch (inputDataType)
454 vtkErrorMacro("Cannot comput magnitude of bit array.");
457 VISU_LookupTableMapMag(this,static_cast<char *>(input),output,
458 numberOfValues,inputIncrement,outputFormat,myScale);
460 case VTK_UNSIGNED_CHAR:
461 VISU_LookupTableMapMag(this,static_cast<unsigned char *>(input),output,
462 numberOfValues,inputIncrement,outputFormat,myScale);
465 VISU_LookupTableMapMag(this,static_cast<short *>(input),output,
466 numberOfValues,inputIncrement,outputFormat,myScale);
468 case VTK_UNSIGNED_SHORT:
469 VISU_LookupTableMapMag(this,static_cast<unsigned short *>(input),output,
470 numberOfValues,inputIncrement,outputFormat,myScale);
473 VISU_LookupTableMapMag(this,static_cast<int *>(input),output,
474 numberOfValues,inputIncrement,outputFormat,myScale);
476 case VTK_UNSIGNED_INT:
477 VISU_LookupTableMapMag(this,static_cast<unsigned int *>(input),output,
478 numberOfValues,inputIncrement,outputFormat,myScale);
481 VISU_LookupTableMapMag(this,static_cast<long *>(input),output,
482 numberOfValues,inputIncrement,outputFormat,myScale);
484 case VTK_UNSIGNED_LONG:
485 VISU_LookupTableMapMag(this,static_cast<unsigned long *>(input),output,
486 numberOfValues,inputIncrement,outputFormat,myScale);
489 VISU_LookupTableMapMag(this,static_cast<float *>(input),output,
490 numberOfValues,inputIncrement,outputFormat,myScale);
493 VISU_LookupTableMapMag(this,static_cast<double *>(input),output,
494 numberOfValues,inputIncrement,outputFormat,myScale);
497 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");
502 switch (inputDataType)
507 vtkBitArray *bitArray = vtkBitArray::New();
508 bitArray->SetVoidArray(input,numberOfValues,1);
509 vtkUnsignedCharArray *newInput = vtkUnsignedCharArray::New();
510 newInput->SetNumberOfValues(numberOfValues);
511 for (id=i=0; i<numberOfValues; i++, id+=inputIncrement)
513 newInput->SetValue(i, bitArray->GetValue(id));
515 VISU_LookupTableMapData(this,
516 static_cast<unsigned char*>(newInput->GetPointer(0)),
517 output,numberOfValues,
518 inputIncrement,outputFormat,myScale);
525 VISU_LookupTableMapData(this,static_cast<char *>(input),output,
526 numberOfValues,inputIncrement,outputFormat,myScale);
529 case VTK_UNSIGNED_CHAR:
530 VISU_LookupTableMapData(this,static_cast<unsigned char *>(input),output,
531 numberOfValues,inputIncrement,outputFormat,myScale);
535 VISU_LookupTableMapData(this,static_cast<short *>(input),output,
536 numberOfValues,inputIncrement,outputFormat,myScale);
539 case VTK_UNSIGNED_SHORT:
540 VISU_LookupTableMapData(this,static_cast<unsigned short *>(input),output,
541 numberOfValues,inputIncrement,outputFormat,myScale);
545 VISU_LookupTableMapData(this,static_cast<int *>(input),output,
546 numberOfValues,inputIncrement,outputFormat,myScale);
549 case VTK_UNSIGNED_INT:
550 VISU_LookupTableMapData(this,static_cast<unsigned int *>(input),output,
551 numberOfValues,inputIncrement,outputFormat,myScale);
555 VISU_LookupTableMapData(this,static_cast<long *>(input),output,
556 numberOfValues,inputIncrement,outputFormat,myScale);
559 case VTK_UNSIGNED_LONG:
560 VISU_LookupTableMapData(this,static_cast<unsigned long *>(input),output,
561 numberOfValues,inputIncrement,outputFormat,myScale);
565 VISU_LookupTableMapData(this,static_cast<float *>(input),output,
566 numberOfValues,inputIncrement,outputFormat,myScale);
570 VISU_LookupTableMapData(this,static_cast<double *>(input),output,
571 numberOfValues,inputIncrement,outputFormat,myScale);
575 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");