1 // Copyright (C) 2007-2013 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
23 // VISU OBJECT : interactive object for VISU entities implementation
24 // File : VISU_LookupTable.cxx
25 // Author : Vitaliy Smetannikov
28 #include "VISU_LookupTable.hxx"
30 #include <vtkObjectFactory.h>
31 #include <vtkBitArray.h>
37 //----------------------------------------------------------------------------
38 vtkStandardNewMacro(VISU_LookupTable);
41 //----------------------------------------------------------------------------
43 ::VISU_LookupTable(int sze, int ext):
44 vtkLookupTable(sze, ext),
47 myHasMarkedValues(false)
50 //----------------------------------------------------------------------------
55 CopyColor( unsigned char* theTaget, const unsigned char* theSource )
57 theTaget[0] = theSource[0];
58 theTaget[1] = theSource[1];
59 theTaget[2] = theSource[2];
64 //----------------------------------------------------------------------------
67 ::MarkValueByColor( double theValue,
68 unsigned char* theColor )
70 vtkIdType anIndex = this->GetIndex( theValue );
71 unsigned char *aTablePtr = this->GetPointer( anIndex );
72 CopyColor( aTablePtr, theColor );
73 myHasMarkedValues = true;
77 //----------------------------------------------------------------------------
80 ::FillByColor( unsigned char* theColor )
82 vtkIdType aNbColors = this->GetNumberOfColors();
83 for(int i = 0; i < aNbColors; i++){
84 unsigned char *aTablePtr = this->GetPointer(i);
85 CopyColor( aTablePtr, theColor );
90 //----------------------------------------------------------------------------
95 unsigned char aRedPtr[3] = {255, 0, 0};
96 unsigned char aBluePtr[3] = {0, 0, 255};
99 this->GetTableRange(aRange);
100 vtkIdType aNbColors = this->GetNumberOfColors();
102 double aDelta = (aRange[1]-aRange[0])/aNbColors;
103 double aValue = aRange[0]+0.5*aDelta;
104 for(int i = 0; i < aNbColors; i++){
105 vtkIdType anIndex = this->GetIndex(aValue);
106 unsigned char* aTablePtr = this->GetPointer(anIndex);
108 CopyColor(aTablePtr,aRedPtr);
110 CopyColor(aTablePtr,aBluePtr);
117 //----------------------------------------------------------------------------
120 ::SetMapScale(double theScale)
122 if( myScale != theScale )
129 void VISU_LookupTable::SetBicolor( bool theBicolor )
131 if( myBicolor != theBicolor )
133 myBicolor = theBicolor;
141 ::ComputeLogRange(double inRange[2],
144 if(inRange[0] >= inRange[1])
146 if(0.0 <= inRange[0] && 0.0 < inRange[1]){
147 if(inRange[0] != 0.0)
148 outRange[0] = log10((double)inRange[0]);
150 outRange[0] = log10((double)inRange[1]*1.0E-6);
151 outRange[1] = log10((double)inRange[1]);
153 }else if(inRange[0] < 0.0 && inRange[1] <= 0.0){
154 outRange[0] = log10((double)-inRange[0]);
155 outRange[1] = log10((double)-inRange[1]);
165 if(GetScale() == VTK_SCALE_LOG10) {
166 double aLowBound = log10(this->TableRange[0]);
167 v = pow(double(10.0), aLowBound + (v - aLowBound)*myScale);
168 return vtkLookupTable::MapValue(v);
169 } else if (!myBicolor) {
170 v = this->TableRange[0] + (v - this->TableRange[0])*myScale;
171 return vtkLookupTable::MapValue(v);
173 unsigned char* table = this->Table->GetPointer(0);
174 int index = v > 0 ? 4*static_cast<int>(this->GetNumberOfColors()-1) : 0;
175 return &table[index];
183 Superclass::ForceBuild();
184 myHasMarkedValues = false;
187 // Apply log to value, with appropriate constraints.
190 VISU_ApplyLogScale(double v,
194 // is the range set for negative numbers?
197 v = log10(-static_cast<double>(v));
199 else if (range[0] > range[1]) {
208 v = log10(static_cast<double>(v));
210 else if (range[0] < range[1]) {
220 // Apply shift/scale to the scalar value v and do table lookup.
223 VISU_LinearLookup(double v,
224 unsigned char *table,
232 double findx = (v + shift)*scale;
235 if (findx > maxIndex)
238 return &table[4*static_cast<int>(findx)];
240 //return &table[4*(int)(findx + 0.5f)];
244 int index = v > 0 ? 4*static_cast<int>(maxIndex) : 0;
245 return &table[index];
249 // accelerate the mapping by copying the data in 32-bit chunks instead
253 VISU_LookupTableMapData(vtkLookupTable *self,
255 unsigned char *output,
263 double *range = self->GetTableRange();
264 double maxIndex = self->GetNumberOfColors() - 1;
266 unsigned char *table = self->GetPointer(0);
270 if ( (alpha=self->GetAlpha()) >= 1.0 ) //no blending required
272 if (self->GetScale() == VTK_SCALE_LOG10)
276 VISU_LookupTable::ComputeLogRange(range, logRange);
277 shift = -logRange[0];
278 if (logRange[1] <= logRange[0])
280 scale = VTK_LARGE_FLOAT;
284 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
287 scale = maxIndex/(logRange[1] - logRange[0]);
289 if (outFormat == VTK_RGBA)
293 val = VISU_ApplyLogScale(*input, range, logRange);
294 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
302 else if (outFormat == VTK_RGB)
306 val = VISU_ApplyLogScale(*input, range, logRange);
307 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
314 else if (outFormat == VTK_LUMINANCE_ALPHA)
318 val = VISU_ApplyLogScale(*input, range, logRange);
319 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
320 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
326 else // outFormat == VTK_LUMINANCE
330 val = VISU_ApplyLogScale(*input, range, logRange);
331 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
332 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
342 if (range[1] <= range[0])
344 scale = VTK_LARGE_FLOAT;
348 scale = (maxIndex + 1)/(range[1] - range[0]);
351 scale = maxIndex/(range[1] - range[0]);
354 if (outFormat == VTK_RGBA)
358 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
366 else if (outFormat == VTK_RGB)
370 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
377 else if (outFormat == VTK_LUMINANCE_ALPHA)
381 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
382 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
388 else // outFormat == VTK_LUMINANCE
392 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
393 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
399 }//if blending not needed
401 else //blend with the specified alpha
403 if (self->GetScale() == VTK_SCALE_LOG10)
407 VISU_LookupTable::ComputeLogRange(range, logRange);
408 shift = -logRange[0];
409 if (logRange[1] <= logRange[0])
411 scale = VTK_LARGE_FLOAT;
415 scale = (maxIndex + 1)/(logRange[1] - logRange[0]);
418 scale = maxIndex/(logRange[1] - logRange[0]);
420 if (outFormat == VTK_RGBA)
424 val = VISU_ApplyLogScale(*input, range, logRange);
425 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
429 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
433 else if (outFormat == VTK_RGB)
437 val = VISU_ApplyLogScale(*input, range, logRange);
438 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
445 else if (outFormat == VTK_LUMINANCE_ALPHA)
449 val = VISU_ApplyLogScale(*input, range, logRange);
450 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
451 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
453 *output++ = static_cast<unsigned char>(alpha*cptr[3]);
457 else // outFormat == VTK_LUMINANCE
461 val = VISU_ApplyLogScale(*input, range, logRange);
462 cptr = VISU_LinearLookup(val, table, maxIndex, shift, scale*theMapScale, bicolor);
463 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
468 }//log scale with blending
470 else //no log scale with blending
473 if (range[1] <= range[0])
475 scale = VTK_LARGE_FLOAT;
479 scale = (maxIndex + 1)/(range[1] - range[0]);
482 scale = maxIndex/(range[1] - range[0]);
485 if (outFormat == VTK_RGBA)
489 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
493 *output++ = static_cast<unsigned char>((*cptr)*alpha); cptr++;
497 else if (outFormat == VTK_RGB)
501 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
508 else if (outFormat == VTK_LUMINANCE_ALPHA)
512 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
513 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
515 *output++ = static_cast<unsigned char>(cptr[3]*alpha);
519 else // outFormat == VTK_LUMINANCE
523 cptr = VISU_LinearLookup(*input, table, maxIndex, shift, scale*theMapScale, bicolor);
524 *output++ = static_cast<unsigned char>(cptr[0]*0.30 + cptr[1]*0.59 +
533 // Although this is a relatively expensive calculation,
534 // it is only done on the first render. Colors are cached
535 // for subsequent renders.
538 VISU_LookupTableMapMag(vtkLookupTable *self,
540 unsigned char *output,
551 mag = new double[length];
552 for (i = 0; i < length; ++i)
555 for (j = 0; j < inIncr; ++j)
557 tmp = (double)(*input);
564 VISU_LookupTableMapData(self, mag, output, length, 1, outFormat, theMapScale, bicolor);
570 void VISU_LookupTable::MapScalarsThroughTable2(void *input,
571 unsigned char *output,
577 if (this->UseMagnitude && inputIncrement > 1)
579 switch (inputDataType)
582 vtkErrorMacro("Cannot comput magnitude of bit array.");
585 VISU_LookupTableMapMag(this,static_cast<char *>(input),output,
586 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
588 case VTK_UNSIGNED_CHAR:
589 VISU_LookupTableMapMag(this,static_cast<unsigned char *>(input),output,
590 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
593 VISU_LookupTableMapMag(this,static_cast<short *>(input),output,
594 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
596 case VTK_UNSIGNED_SHORT:
597 VISU_LookupTableMapMag(this,static_cast<unsigned short *>(input),output,
598 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
601 VISU_LookupTableMapMag(this,static_cast<int *>(input),output,
602 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
604 case VTK_UNSIGNED_INT:
605 VISU_LookupTableMapMag(this,static_cast<unsigned int *>(input),output,
606 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
609 VISU_LookupTableMapMag(this,static_cast<long *>(input),output,
610 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
612 case VTK_UNSIGNED_LONG:
613 VISU_LookupTableMapMag(this,static_cast<unsigned long *>(input),output,
614 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
617 VISU_LookupTableMapMag(this,static_cast<float *>(input),output,
618 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
621 VISU_LookupTableMapMag(this,static_cast<double *>(input),output,
622 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
625 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");
630 switch (inputDataType)
635 vtkBitArray *bitArray = vtkBitArray::New();
636 bitArray->SetVoidArray(input,numberOfValues,1);
637 vtkUnsignedCharArray *newInput = vtkUnsignedCharArray::New();
638 newInput->SetNumberOfValues(numberOfValues);
639 for (id=i=0; i<numberOfValues; i++, id+=inputIncrement)
641 newInput->SetValue(i, bitArray->GetValue(id));
643 VISU_LookupTableMapData(this,
644 static_cast<unsigned char*>(newInput->GetPointer(0)),
645 output,numberOfValues,
646 inputIncrement,outputFormat,myScale,myBicolor);
653 VISU_LookupTableMapData(this,static_cast<char *>(input),output,
654 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
657 case VTK_UNSIGNED_CHAR:
658 VISU_LookupTableMapData(this,static_cast<unsigned char *>(input),output,
659 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
663 VISU_LookupTableMapData(this,static_cast<short *>(input),output,
664 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
667 case VTK_UNSIGNED_SHORT:
668 VISU_LookupTableMapData(this,static_cast<unsigned short *>(input),output,
669 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
673 VISU_LookupTableMapData(this,static_cast<int *>(input),output,
674 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
677 case VTK_UNSIGNED_INT:
678 VISU_LookupTableMapData(this,static_cast<unsigned int *>(input),output,
679 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
683 VISU_LookupTableMapData(this,static_cast<long *>(input),output,
684 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
687 case VTK_UNSIGNED_LONG:
688 VISU_LookupTableMapData(this,static_cast<unsigned long *>(input),output,
689 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
693 VISU_LookupTableMapData(this,static_cast<float *>(input),output,
694 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
698 VISU_LookupTableMapData(this,static_cast<double *>(input),output,
699 numberOfValues,inputIncrement,outputFormat,myScale,myBicolor);
703 vtkErrorMacro(<< "MapImageThroughTable: Unknown input ScalarType");