1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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
22 // VISU OBJECT : interactive object for VISU entities implementation
23 // File : VISU_LookupTable.cxx
24 // Author : Vitaliy Smetannikov
27 #include "VISU_LookupTable.hxx"
29 #include <vtkObjectFactory.h>
30 #include <vtkBitArray.h>
36 //----------------------------------------------------------------------------
37 vtkStandardNewMacro(VISU_LookupTable);
40 //----------------------------------------------------------------------------
42 ::VISU_LookupTable(int sze, int ext):
43 vtkLookupTable(sze, ext),
48 //----------------------------------------------------------------------------
53 CopyColor( unsigned char* theTaget, const unsigned char* theSource )
55 theTaget[0] = theSource[0];
56 theTaget[1] = theSource[1];
57 theTaget[2] = theSource[2];
62 //----------------------------------------------------------------------------
65 ::MarkValueByColor( vtkFloatingPointType theValue,
66 unsigned char* theColor )
68 vtkIdType anIndex = this->GetIndex( theValue );
69 unsigned char *aTablePtr = this->GetPointer( anIndex );
70 CopyColor( aTablePtr, theColor );
74 //----------------------------------------------------------------------------
77 ::FillByColor( unsigned char* theColor )
79 vtkIdType aNbColors = this->GetNumberOfColors();
80 for(int i = 0; i < aNbColors; i++){
81 unsigned char *aTablePtr = this->GetPointer(i);
82 CopyColor( aTablePtr, theColor );
87 //----------------------------------------------------------------------------
92 unsigned char aRedPtr[3] = {255, 0, 0};
93 unsigned char aBluePtr[3] = {0, 0, 255};
95 vtkFloatingPointType aRange[2];
96 this->GetTableRange(aRange);
97 vtkIdType aNbColors = this->GetNumberOfColors();
99 vtkFloatingPointType aDelta = (aRange[1]-aRange[0])/aNbColors;
100 vtkFloatingPointType aValue = aRange[0]+0.5*aDelta;
101 for(int i = 0; i < aNbColors; i++){
102 vtkIdType anIndex = this->GetIndex(aValue);
103 unsigned char* aTablePtr = this->GetPointer(anIndex);
105 CopyColor(aTablePtr,aRedPtr);
107 CopyColor(aTablePtr,aBluePtr);
114 //----------------------------------------------------------------------------
117 ::SetMapScale(vtkFloatingPointType theScale)
119 if( myScale != theScale )
126 void VISU_LookupTable::SetBicolor( bool theBicolor )
128 if( myBicolor != theBicolor )
130 myBicolor = theBicolor;
138 ::ComputeLogRange(vtkFloatingPointType inRange[2],
139 vtkFloatingPointType outRange[2])
141 if(inRange[0] >= inRange[1])
143 if(0.0 <= inRange[0] && 0.0 < inRange[1]){
144 if(inRange[0] != 0.0)
145 outRange[0] = log10((double)inRange[0]);
147 outRange[0] = log10((double)inRange[1]*1.0E-6);
148 outRange[1] = log10((double)inRange[1]);
150 }else if(inRange[0] < 0.0 && inRange[1] <= 0.0){
151 outRange[0] = log10((double)-inRange[0]);
152 outRange[1] = log10((double)-inRange[1]);
160 ::MapValue(vtkFloatingPointType v)
162 if(GetScale() == VTK_SCALE_LOG10) {
163 vtkFloatingPointType aLowBound = log10(this->TableRange[0]);
164 v = pow(vtkFloatingPointType(10.0), aLowBound + (v - aLowBound)*myScale);
165 return vtkLookupTable::MapValue(v);
166 } else if (!myBicolor) {
167 v = this->TableRange[0] + (v - this->TableRange[0])*myScale;
168 return vtkLookupTable::MapValue(v);
170 unsigned char* table = this->Table->GetPointer(0);
171 int index = v > 0 ? 4*static_cast<int>(this->GetNumberOfColors()-1) : 0;
172 return &table[index];
176 // Apply log to value, with appropriate constraints.
179 VISU_ApplyLogScale(vtkFloatingPointType v,
180 vtkFloatingPointType range[2],
181 vtkFloatingPointType logRange[2])
183 // is the range set for negative numbers?
188 v = log10(-static_cast<double>(v));
190 else if (range[0] > range[1])
203 v = log10(static_cast<double>(v));
205 else if (range[0] < range[1])
217 // Apply shift/scale to the scalar value v and do table lookup.
220 VISU_LinearLookup(vtkFloatingPointType v,
221 unsigned char *table,
222 vtkFloatingPointType maxIndex,
223 vtkFloatingPointType shift,
224 vtkFloatingPointType scale,
229 vtkFloatingPointType findx = (v + shift)*scale;
232 if (findx > maxIndex)
235 return &table[4*static_cast<int>(findx)];
237 //return &table[4*(int)(findx + 0.5f)];
241 int index = v > 0 ? 4*static_cast<int>(maxIndex) : 0;
242 return &table[index];
246 // accelerate the mapping by copying the data in 32-bit chunks instead
250 VISU_LookupTableMapData(vtkLookupTable *self,
252 unsigned char *output,
256 vtkFloatingPointType theMapScale,
260 vtkFloatingPointType *range = self->GetTableRange();
261 vtkFloatingPointType maxIndex = self->GetNumberOfColors() - 1;
262 vtkFloatingPointType shift, scale;
263 unsigned char *table = self->GetPointer(0);
265 vtkFloatingPointType alpha;
267 if ( (alpha=self->GetAlpha()) >= 1.0 ) //no blending required
269 if (self->GetScale() == VTK_SCALE_LOG10)
271 vtkFloatingPointType val;
272 vtkFloatingPointType logRange[2];
273 VISU_LookupTable::ComputeLogRange(range, logRange);
274 shift = -logRange[0];
275 if (logRange[1] <= logRange[0])
277 scale = VTK_LARGE_FLOAT;
281 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
284 scale = maxIndex/(logRange[1] - logRange[0]);
286 if (outFormat == VTK_RGBA)
290 val = VISU_ApplyLogScale(*input, range, logRange);
291 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
299 else if (outFormat == VTK_RGB)
303 val = VISU_ApplyLogScale(*input, range, logRange);
304 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
311 else if (outFormat == VTK_LUMINANCE_ALPHA)
315 val = VISU_ApplyLogScale(*input, range, logRange);
316 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
317 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
323 else // outFormat == VTK_LUMINANCE
327 val = VISU_ApplyLogScale(*input, range, logRange);
328 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
329 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
339 if (range[1] <= range[0])
341 scale = VTK_LARGE_FLOAT;
345 scale = (maxIndex + 1)/(range[1] - range[0]);
348 scale = maxIndex/(range[1] - range[0]);
351 if (outFormat == VTK_RGBA)
355 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
363 else if (outFormat == VTK_RGB)
367 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
374 else if (outFormat == VTK_LUMINANCE_ALPHA)
378 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
379 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
385 else // outFormat == VTK_LUMINANCE
389 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
390 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
396 }//if blending not needed
398 else //blend with the specified alpha
400 if (self->GetScale() == VTK_SCALE_LOG10)
402 vtkFloatingPointType val;
403 vtkFloatingPointType logRange[2];
404 VISU_LookupTable::ComputeLogRange(range, logRange);
405 shift = -logRange[0];
406 if (logRange[1] <= logRange[0])
408 scale = VTK_LARGE_FLOAT;
412 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
415 scale = maxIndex/(logRange[1] - logRange[0]);
417 if (outFormat == VTK_RGBA)
421 val = VISU_ApplyLogScale(*input, range, logRange);
422 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
426 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
430 else if (outFormat == VTK_RGB)
434 val = VISU_ApplyLogScale(*input, range, logRange);
435 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
442 else if (outFormat == VTK_LUMINANCE_ALPHA)
446 val = VISU_ApplyLogScale(*input, range, logRange);
447 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
448 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
450 *output++ = static_cast<unsigned char>(alpha*cptr[3]);
454 else // outFormat == VTK_LUMINANCE
458 val = VISU_ApplyLogScale(*input, range, logRange);
459 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
460 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
465 }//log scale with blending
467 else //no log scale with blending
470 if (range[1] <= range[0])
472 scale = VTK_LARGE_FLOAT;
476 scale = (maxIndex + 1)/(range[1] - range[0]);
479 scale = maxIndex/(range[1] - range[0]);
482 if (outFormat == VTK_RGBA)
486 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
490 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
494 else if (outFormat == VTK_RGB)
498 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
505 else if (outFormat == VTK_LUMINANCE_ALPHA)
509 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
510 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
512 *output++ = static_cast<unsigned char>(cptr[3]*alpha);
516 else // outFormat == VTK_LUMINANCE
520 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
521 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
530 // Although this is a relatively expensive calculation,
531 // it is only done on the first render. Colors are cached
532 // for subsequent renders.
535 VISU_LookupTableMapMag(vtkLookupTable *self,
537 unsigned char *output,
541 vtkFloatingPointType theMapScale,
548 mag = new double[length];
549 for (i = 0; i < length; ++i)
552 for (j = 0; j < inIncr; ++j)
554 tmp = (double)(*input);
561 VISU_LookupTableMapData(self, mag, output, length, 1, outFormat, theMapScale, bicolor);
567 void VISU_LookupTable::MapScalarsThroughTable2(void *input,
568 unsigned char *output,
574 if (this->UseMagnitude && inputIncrement > 1)
576 switch (inputDataType)
579 vtkErrorMacro("Cannot comput magnitude of bit array.");
582 VISU_LookupTableMapMag(this,static_cast<char *>(input),output,
583 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
585 case VTK_UNSIGNED_CHAR:
586 VISU_LookupTableMapMag(this,static_cast<unsigned char *>(input),output,
587 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
590 VISU_LookupTableMapMag(this,static_cast<short *>(input),output,
591 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
593 case VTK_UNSIGNED_SHORT:
594 VISU_LookupTableMapMag(this,static_cast<unsigned short *>(input),output,
595 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
598 VISU_LookupTableMapMag(this,static_cast<int *>(input),output,
599 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
601 case VTK_UNSIGNED_INT:
602 VISU_LookupTableMapMag(this,static_cast<unsigned int *>(input),output,
603 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
606 VISU_LookupTableMapMag(this,static_cast<long *>(input),output,
607 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
609 case VTK_UNSIGNED_LONG:
610 VISU_LookupTableMapMag(this,static_cast<unsigned long *>(input),output,
611 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
614 VISU_LookupTableMapMag(this,static_cast<float *>(input),output,
615 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
618 VISU_LookupTableMapMag(this,static_cast<double *>(input),output,
619 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
622 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");
627 switch (inputDataType)
632 vtkBitArray *bitArray = vtkBitArray::New();
633 bitArray->SetVoidArray(input,numberOfValues,1);
634 vtkUnsignedCharArray *newInput = vtkUnsignedCharArray::New();
635 newInput->SetNumberOfValues(numberOfValues);
636 for (id=i=0; i<numberOfValues; i++, id+=inputIncrement)
638 newInput->SetValue(i, bitArray->GetValue(id));
640 VISU_LookupTableMapData(this,
641 static_cast<unsigned char*>(newInput->GetPointer(0)),
642 output,numberOfValues,
643 inputIncrement,outputFormat,myScale,myBicolor);
650 VISU_LookupTableMapData(this,static_cast<char *>(input),output,
651 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
654 case VTK_UNSIGNED_CHAR:
655 VISU_LookupTableMapData(this,static_cast<unsigned char *>(input),output,
656 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
660 VISU_LookupTableMapData(this,static_cast<short *>(input),output,
661 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
664 case VTK_UNSIGNED_SHORT:
665 VISU_LookupTableMapData(this,static_cast<unsigned short *>(input),output,
666 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
670 VISU_LookupTableMapData(this,static_cast<int *>(input),output,
671 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
674 case VTK_UNSIGNED_INT:
675 VISU_LookupTableMapData(this,static_cast<unsigned int *>(input),output,
676 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
680 VISU_LookupTableMapData(this,static_cast<long *>(input),output,
681 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
684 case VTK_UNSIGNED_LONG:
685 VISU_LookupTableMapData(this,static_cast<unsigned long *>(input),output,
686 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
690 VISU_LookupTableMapData(this,static_cast<float *>(input),output,
691 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
695 VISU_LookupTableMapData(this,static_cast<double *>(input),output,
696 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
700 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");