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),
46 myHasMarkedValues(false)
49 //----------------------------------------------------------------------------
54 CopyColor( unsigned char* theTaget, const unsigned char* theSource )
56 theTaget[0] = theSource[0];
57 theTaget[1] = theSource[1];
58 theTaget[2] = theSource[2];
63 //----------------------------------------------------------------------------
66 ::MarkValueByColor( vtkFloatingPointType theValue,
67 unsigned char* theColor )
69 vtkIdType anIndex = this->GetIndex( theValue );
70 unsigned char *aTablePtr = this->GetPointer( anIndex );
71 CopyColor( aTablePtr, theColor );
72 myHasMarkedValues = true;
76 //----------------------------------------------------------------------------
79 ::FillByColor( unsigned char* theColor )
81 vtkIdType aNbColors = this->GetNumberOfColors();
82 for(int i = 0; i < aNbColors; i++){
83 unsigned char *aTablePtr = this->GetPointer(i);
84 CopyColor( aTablePtr, theColor );
89 //----------------------------------------------------------------------------
94 unsigned char aRedPtr[3] = {255, 0, 0};
95 unsigned char aBluePtr[3] = {0, 0, 255};
97 vtkFloatingPointType aRange[2];
98 this->GetTableRange(aRange);
99 vtkIdType aNbColors = this->GetNumberOfColors();
101 vtkFloatingPointType aDelta = (aRange[1]-aRange[0])/aNbColors;
102 vtkFloatingPointType aValue = aRange[0]+0.5*aDelta;
103 for(int i = 0; i < aNbColors; i++){
104 vtkIdType anIndex = this->GetIndex(aValue);
105 unsigned char* aTablePtr = this->GetPointer(anIndex);
107 CopyColor(aTablePtr,aRedPtr);
109 CopyColor(aTablePtr,aBluePtr);
116 //----------------------------------------------------------------------------
119 ::SetMapScale(vtkFloatingPointType theScale)
121 if( myScale != theScale )
128 void VISU_LookupTable::SetBicolor( bool theBicolor )
130 if( myBicolor != theBicolor )
132 myBicolor = theBicolor;
140 ::ComputeLogRange(vtkFloatingPointType inRange[2],
141 vtkFloatingPointType outRange[2])
143 if(inRange[0] >= inRange[1])
145 if(0.0 <= inRange[0] && 0.0 < inRange[1]){
146 if(inRange[0] != 0.0)
147 outRange[0] = log10((double)inRange[0]);
149 outRange[0] = log10((double)inRange[1]*1.0E-6);
150 outRange[1] = log10((double)inRange[1]);
152 }else if(inRange[0] < 0.0 && inRange[1] <= 0.0){
153 outRange[0] = log10((double)-inRange[0]);
154 outRange[1] = log10((double)-inRange[1]);
162 ::MapValue(vtkFloatingPointType v)
164 if(GetScale() == VTK_SCALE_LOG10) {
165 vtkFloatingPointType aLowBound = log10(this->TableRange[0]);
166 v = pow(vtkFloatingPointType(10.0), aLowBound + (v - aLowBound)*myScale);
167 return vtkLookupTable::MapValue(v);
168 } else if (!myBicolor) {
169 v = this->TableRange[0] + (v - this->TableRange[0])*myScale;
170 return vtkLookupTable::MapValue(v);
172 unsigned char* table = this->Table->GetPointer(0);
173 int index = v > 0 ? 4*static_cast<int>(this->GetNumberOfColors()-1) : 0;
174 return &table[index];
182 Superclass::ForceBuild();
183 myHasMarkedValues = false;
186 // Apply log to value, with appropriate constraints.
189 VISU_ApplyLogScale(vtkFloatingPointType v,
190 vtkFloatingPointType range[2],
191 vtkFloatingPointType logRange[2])
193 // is the range set for negative numbers?
196 v = log10(-static_cast<double>(v));
198 else if (range[0] > range[1]) {
207 v = log10(static_cast<double>(v));
209 else if (range[0] < range[1]) {
219 // Apply shift/scale to the scalar value v and do table lookup.
222 VISU_LinearLookup(vtkFloatingPointType v,
223 unsigned char *table,
224 vtkFloatingPointType maxIndex,
225 vtkFloatingPointType shift,
226 vtkFloatingPointType scale,
231 vtkFloatingPointType findx = (v + shift)*scale;
234 if (findx > maxIndex)
237 return &table[4*static_cast<int>(findx)];
239 //return &table[4*(int)(findx + 0.5f)];
243 int index = v > 0 ? 4*static_cast<int>(maxIndex) : 0;
244 return &table[index];
248 // accelerate the mapping by copying the data in 32-bit chunks instead
252 VISU_LookupTableMapData(vtkLookupTable *self,
254 unsigned char *output,
258 vtkFloatingPointType theMapScale,
262 vtkFloatingPointType *range = self->GetTableRange();
263 vtkFloatingPointType maxIndex = self->GetNumberOfColors() - 1;
264 vtkFloatingPointType shift, scale;
265 unsigned char *table = self->GetPointer(0);
267 vtkFloatingPointType alpha;
269 if ( (alpha=self->GetAlpha()) >= 1.0 ) //no blending required
271 if (self->GetScale() == VTK_SCALE_LOG10)
273 vtkFloatingPointType val;
274 vtkFloatingPointType logRange[2];
275 VISU_LookupTable::ComputeLogRange(range, logRange);
276 shift = -logRange[0];
277 if (logRange[1] <= logRange[0])
279 scale = VTK_LARGE_FLOAT;
283 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
286 scale = maxIndex/(logRange[1] - logRange[0]);
288 if (outFormat == VTK_RGBA)
292 val = VISU_ApplyLogScale(*input, range, logRange);
293 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
301 else if (outFormat == VTK_RGB)
305 val = VISU_ApplyLogScale(*input, range, logRange);
306 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
313 else if (outFormat == VTK_LUMINANCE_ALPHA)
317 val = VISU_ApplyLogScale(*input, range, logRange);
318 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
319 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
325 else // outFormat == VTK_LUMINANCE
329 val = VISU_ApplyLogScale(*input, range, logRange);
330 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
331 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
341 if (range[1] <= range[0])
343 scale = VTK_LARGE_FLOAT;
347 scale = (maxIndex + 1)/(range[1] - range[0]);
350 scale = maxIndex/(range[1] - range[0]);
353 if (outFormat == VTK_RGBA)
357 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
365 else if (outFormat == VTK_RGB)
369 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
376 else if (outFormat == VTK_LUMINANCE_ALPHA)
380 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
381 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
387 else // outFormat == VTK_LUMINANCE
391 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
392 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
398 }//if blending not needed
400 else //blend with the specified alpha
402 if (self->GetScale() == VTK_SCALE_LOG10)
404 vtkFloatingPointType val;
405 vtkFloatingPointType logRange[2];
406 VISU_LookupTable::ComputeLogRange(range, logRange);
407 shift = -logRange[0];
408 if (logRange[1] <= logRange[0])
410 scale = VTK_LARGE_FLOAT;
414 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
417 scale = maxIndex/(logRange[1] - logRange[0]);
419 if (outFormat == VTK_RGBA)
423 val = VISU_ApplyLogScale(*input, range, logRange);
424 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
428 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
432 else if (outFormat == VTK_RGB)
436 val = VISU_ApplyLogScale(*input, range, logRange);
437 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
444 else if (outFormat == VTK_LUMINANCE_ALPHA)
448 val = VISU_ApplyLogScale(*input, range, logRange);
449 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
450 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
452 *output++ = static_cast<unsigned char>(alpha*cptr[3]);
456 else // outFormat == VTK_LUMINANCE
460 val = VISU_ApplyLogScale(*input, range, logRange);
461 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
462 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
467 }//log scale with blending
469 else //no log scale with blending
472 if (range[1] <= range[0])
474 scale = VTK_LARGE_FLOAT;
478 scale = (maxIndex + 1)/(range[1] - range[0]);
481 scale = maxIndex/(range[1] - range[0]);
484 if (outFormat == VTK_RGBA)
488 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
492 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
496 else if (outFormat == VTK_RGB)
500 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
507 else if (outFormat == VTK_LUMINANCE_ALPHA)
511 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
512 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
514 *output++ = static_cast<unsigned char>(cptr[3]*alpha);
518 else // outFormat == VTK_LUMINANCE
522 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
523 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
532 // Although this is a relatively expensive calculation,
533 // it is only done on the first render. Colors are cached
534 // for subsequent renders.
537 VISU_LookupTableMapMag(vtkLookupTable *self,
539 unsigned char *output,
543 vtkFloatingPointType theMapScale,
550 mag = new double[length];
551 for (i = 0; i < length; ++i)
554 for (j = 0; j < inIncr; ++j)
556 tmp = (double)(*input);
563 VISU_LookupTableMapData(self, mag, output, length, 1, outFormat, theMapScale, bicolor);
569 void VISU_LookupTable::MapScalarsThroughTable2(void *input,
570 unsigned char *output,
576 if (this->UseMagnitude && inputIncrement > 1)
578 switch (inputDataType)
581 vtkErrorMacro("Cannot comput magnitude of bit array.");
584 VISU_LookupTableMapMag(this,static_cast<char *>(input),output,
585 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
587 case VTK_UNSIGNED_CHAR:
588 VISU_LookupTableMapMag(this,static_cast<unsigned char *>(input),output,
589 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
592 VISU_LookupTableMapMag(this,static_cast<short *>(input),output,
593 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
595 case VTK_UNSIGNED_SHORT:
596 VISU_LookupTableMapMag(this,static_cast<unsigned short *>(input),output,
597 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
600 VISU_LookupTableMapMag(this,static_cast<int *>(input),output,
601 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
603 case VTK_UNSIGNED_INT:
604 VISU_LookupTableMapMag(this,static_cast<unsigned int *>(input),output,
605 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
608 VISU_LookupTableMapMag(this,static_cast<long *>(input),output,
609 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
611 case VTK_UNSIGNED_LONG:
612 VISU_LookupTableMapMag(this,static_cast<unsigned long *>(input),output,
613 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
616 VISU_LookupTableMapMag(this,static_cast<float *>(input),output,
617 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
620 VISU_LookupTableMapMag(this,static_cast<double *>(input),output,
621 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
624 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");
629 switch (inputDataType)
634 vtkBitArray *bitArray = vtkBitArray::New();
635 bitArray->SetVoidArray(input,numberOfValues,1);
636 vtkUnsignedCharArray *newInput = vtkUnsignedCharArray::New();
637 newInput->SetNumberOfValues(numberOfValues);
638 for (id=i=0; i<numberOfValues; i++, id+=inputIncrement)
640 newInput->SetValue(i, bitArray->GetValue(id));
642 VISU_LookupTableMapData(this,
643 static_cast<unsigned char*>(newInput->GetPointer(0)),
644 output,numberOfValues,
645 inputIncrement,outputFormat,myScale,myBicolor);
652 VISU_LookupTableMapData(this,static_cast<char *>(input),output,
653 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
656 case VTK_UNSIGNED_CHAR:
657 VISU_LookupTableMapData(this,static_cast<unsigned char *>(input),output,
658 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
662 VISU_LookupTableMapData(this,static_cast<short *>(input),output,
663 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
666 case VTK_UNSIGNED_SHORT:
667 VISU_LookupTableMapData(this,static_cast<unsigned short *>(input),output,
668 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
672 VISU_LookupTableMapData(this,static_cast<int *>(input),output,
673 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
676 case VTK_UNSIGNED_INT:
677 VISU_LookupTableMapData(this,static_cast<unsigned int *>(input),output,
678 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
682 VISU_LookupTableMapData(this,static_cast<long *>(input),output,
683 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
686 case VTK_UNSIGNED_LONG:
687 VISU_LookupTableMapData(this,static_cast<unsigned long *>(input),output,
688 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
692 VISU_LookupTableMapData(this,static_cast<float *>(input),output,
693 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
697 VISU_LookupTableMapData(this,static_cast<double *>(input),output,
698 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
702 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");