Salome HOME
Copyright update 2022
[modules/gui.git] / src / VTKViewer / VTKViewer_MarkerUtils.cxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "VTKViewer_MarkerUtils.h"
21
22 // VTK Includes
23 #include <vtkImageData.h>
24
25 // QT Includes
26 #include <QFile>
27 #include <QImage>
28 #include <QString>
29 #include <QTextStream>
30
31 namespace VTK
32 {
33   bool LoadTextureData( const QString& theFileName,
34                         VTK::MarkerScale theMarkerScale,
35                         VTK::MarkerTexture& theMarkerTexture )
36   {
37     theMarkerTexture.clear();
38
39     QFile aFile( theFileName );
40     if( !aFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
41       return false;
42
43     bool ok;
44     int aWidth = 0, aHeight = 0;
45
46     int aTextureIndex = theMarkerScale == VTK::MS_NONE ? 0 : (int)theMarkerScale-1;
47     int aCurrentTexture = 0;
48
49     QTextStream aTextStream( &aFile );
50     while( !aTextStream.atEnd() )
51     {
52       QString aLine = aTextStream.readLine();
53       if( aLine.isEmpty() )
54       {
55         aCurrentTexture++;
56         continue;
57       }
58
59       if( aCurrentTexture != aTextureIndex )
60         continue;
61
62       int aLineSize = aLine.size();
63       for( int i = 0; i < aLineSize; i++ )
64       {
65         ok = false;
66         unsigned int aPixel = QString( aLine.at( i ) ).toUInt( &ok );
67         if( ok )
68           theMarkerTexture.push_back( aPixel );
69       }
70       if( aWidth == 0 )
71         aWidth = aLineSize;
72       aHeight++;
73     }
74
75     if( (int)theMarkerTexture.size() != aWidth * aHeight )
76       return false;
77
78     theMarkerTexture.push_front( aWidth );
79     theMarkerTexture.push_front( aHeight );
80     return true;
81   }
82
83   vtkSmartPointer<vtkImageData> MakeVTKImage( const VTK::MarkerTexture& theMarkerTexture,
84                                               bool theWhiteForeground )
85   {
86     VTK::MarkerTexture::const_iterator anIter = theMarkerTexture.begin();
87
88     int aWidth = *anIter++;
89     int aHeight = *anIter++;
90
91     vtkSmartPointer<vtkImageData> anImageData = vtkImageData::New();
92     anImageData->Delete();
93
94     anImageData->SetExtent( 0, aWidth-1, 0, aHeight-1, 0, 0 );
95     anImageData->AllocateScalars( VTK_UNSIGNED_CHAR, 4 );
96
97     unsigned char* aDataPtr = (unsigned char*)anImageData->GetScalarPointer();
98
99     int anId = 0;
100     int aSize = aWidth * aHeight * 4;
101     int aCoef = theWhiteForeground ? 1 : 0;
102     while( anId < aSize )
103     {
104       int aValue = (*anIter++) * 255;
105       aDataPtr[ anId++ ] = aValue * aCoef;
106       aDataPtr[ anId++ ] = aValue * aCoef;
107       aDataPtr[ anId++ ] = aValue * aCoef;
108       aDataPtr[ anId++ ] = aValue;
109     }
110
111     return anImageData;
112   }
113
114   QImage ConvertToQImage( vtkImageData* theImageData )
115   {
116     if( theImageData->GetScalarType() != VTK_UNSIGNED_CHAR )
117       return QImage();
118
119     int extent[6];
120     theImageData->GetExtent( extent );
121     int width = extent[1] - extent[0] + 1;
122     int height = extent[3] - extent[2] + 1;
123
124     const int wmin = 20;
125     const int hmin = 20;
126
127     int xshift = width  < wmin ? (wmin-width)/2  : 0;
128     int yshift = height < hmin ? (hmin-height)/2 : 0;
129   
130     QImage anImage(width < wmin ? wmin : width, height < hmin ? hmin : height, QImage::Format_ARGB32);
131     anImage.fill(qRgba(255,255,255,0));
132     for( int i = 0; i < height; i++ )
133     {
134       QRgb* bits = reinterpret_cast<QRgb*>( anImage.scanLine(i+yshift) );
135       unsigned char* row = static_cast<unsigned char*>(
136         theImageData->GetScalarPointer( extent[0], extent[2] + height - i - 1, extent[4] ) );
137       for( int j = 0; j < width; j++ )
138       {
139         unsigned char* data = &row[ j*4 ];
140         bits[j+xshift] = qRgba( data[0], data[1], data[2], data[3] );
141       }
142     }
143     return anImage;
144   }
145
146   int GetUniqueId( const VTK::MarkerMap& theMarkerMap )
147   {
148     int anId = 0;
149     while( anId++ < 100 ) {
150       bool anOk = true;
151       VTK::MarkerMap::const_iterator anIter = theMarkerMap.begin();
152       for( ; anIter != theMarkerMap.end(); anIter++ ) {
153         if( anId == anIter->first ) {
154           anOk = false;
155           continue;
156         }
157       }
158       if( anOk )
159         return anId;
160     }
161     return theMarkerMap.size() + 1;
162   }
163 }