]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Visualization/ImageBlender.cxx
sphere widget done, finally
[cpPlugins.git] / lib / cpExtensions / Visualization / ImageBlender.cxx
1 #include <cpExtensions/Visualization/ImageBlender.h>
2
3 #include <vtkDataObject.h>
4 #include <vtkImageData.h>
5 #include <vtkImageIterator.h>
6 #include <vtkImageProgressIterator.h>
7 #include <vtkInformation.h>
8 #include <vtkInformationVector.h>
9
10 // -------------------------------------------------------------------------
11 cpExtensions::Visualization::ImageBlender::
12 Self* cpExtensions::Visualization::ImageBlender::
13 New( )
14 {
15   return( new Self( ) );
16 }
17
18
19 // -------------------------------------------------------------------------
20 cpExtensions::Visualization::ImageBlender::
21 ImageBlender( )
22   : Superclass( )
23 {
24   this->SetNumberOfInputPorts( 1 );
25 }
26
27 // -------------------------------------------------------------------------
28 cpExtensions::Visualization::ImageBlender::
29 ~ImageBlender( )
30 {
31 }
32
33 // -------------------------------------------------------------------------
34 int cpExtensions::Visualization::ImageBlender::
35 RequestInformation(
36   vtkInformation* request,
37   vtkInformationVector** inputVector,
38   vtkInformationVector* outputVector
39   )
40 {
41   if( this->GetNumberOfInputConnections( 0 ) == 0 )
42     return( 0 );
43
44   vtkDataObject::SetPointDataActiveScalarInfo(
45     outputVector->GetInformationObject( 0 ),
46     VTK_UNSIGNED_CHAR,
47     1
48     );
49   return( 1 );
50 }
51
52 // -------------------------------------------------------------------------
53 int cpExtensions::Visualization::ImageBlender::
54 RequestData(
55   vtkInformation* request,
56   vtkInformationVector** inputVector,
57   vtkInformationVector* outputVector
58   )
59 {
60   this->m_Ranges.clear( );
61   for( int i = 0; i < this->GetNumberOfInputPorts( ); ++i )
62   {
63     vtkInformationVector* portInfo = inputVector[ i ];
64     for( int j = 0; j < portInfo->GetNumberOfInformationObjects( ); ++j )
65     {
66       vtkInformation* info = portInfo->GetInformationObject( j );
67       vtkImageData* image = vtkImageData::SafeDownCast(
68         info->Get( vtkDataObject::DATA_OBJECT( ) )
69         );
70       if( image != NULL )
71       {
72         double r[ 2 ];
73         image->GetScalarRange( r );
74         this->m_Ranges.push_back( r[ 0 ] );
75         this->m_Ranges.push_back( r[ 1 ] );
76       }
77       else
78       {
79         this->m_Ranges.push_back( double( 0 ) );
80         this->m_Ranges.push_back( double( 0 ) );
81
82       } // fi
83
84     } // rof
85
86   } // rof
87   this->Superclass::RequestData( request, inputVector, outputVector );
88 }
89
90 // -------------------------------------------------------------------------
91 // Description:
92 // This templated function executes the filter for any type of data.
93 template< class T >
94 void cpExtensions_Visualization_ImageBlender_Execute(
95   cpExtensions::Visualization::ImageBlender* self,
96   vtkImageData** inDatas, int numInputs,
97   const std::vector< double >& ranges, vtkImageData* outData,
98   int outExt[ 6 ], int id, T* really_not_used
99   )
100 {
101   vtkImageIterator< T > inItsFast[ 256 ];
102   T* inSIFast[ 256 ];
103   vtkImageProgressIterator< T > outIt( outData, outExt, self, id );
104   vtkImageIterator< T >* inIts;
105   T** inSI;
106   if( numInputs < 256 )
107   {
108     inIts = inItsFast;
109     inSI = inSIFast;
110   }
111   else
112   {
113     inIts = new vtkImageIterator< T >[ numInputs ];
114     inSI = new T*[ numInputs ];
115
116   } // fi
117
118   // Loop through all input ImageData to initialize iterators
119   for( int i = 0; i < numInputs; ++i )
120     inIts[ i ].Initialize( inDatas[ i ], outExt );
121
122   // Loop through output pixels
123   while( !outIt.IsAtEnd( ) )
124   {
125     for( int j = 0; j < numInputs; ++j )
126       inSI[ j ] = inIts[ j ].BeginSpan( );
127
128     T* outSI = outIt.BeginSpan( );
129     T* outSIEnd = outIt.EndSpan( );
130
131     // Pixel operation
132     while( outSI != outSIEnd )
133     {
134       // Input 0 is ignored: it is just used to guarantee sizes all over
135       // the result
136       double vmax = double( 0 );
137       for( int k = 1; k < numInputs; ++k )
138       {
139         double v =
140           ( ( double( k ) * double( *inSI[ k ] ) ) - ranges[ k << 1 ] ) /
141           ( ranges[ ( k << 1 ) + 1 ] - ranges[ k << 1 ] );
142         vmax = ( vmax < v )? v: vmax;
143
144       } // rof
145       *outSI = static_cast< T >( vmax );
146       outSI++;
147       for( int l = 0; l < numInputs; ++l )
148         inSI[ l ]++;
149
150     } // elihw
151     for( int j = 0; j < numInputs; ++j )
152       inIts[ j ].NextSpan( );
153     outIt.NextSpan( );
154
155   } // elihw
156
157   if( numInputs >= 256)
158   {
159     delete [] inIts;
160     delete [] inSI;
161
162   } // fi
163 }
164
165 // -------------------------------------------------------------------------
166 void cpExtensions::Visualization::ImageBlender::
167 ThreadedRequestData(
168   vtkInformation* request,
169   vtkInformationVector** inputVector,
170   vtkInformationVector* outputVector,
171   vtkImageData*** inData, vtkImageData** outData,
172   int outExt[ 6 ], int id
173   )
174 {
175   if( inData[ 0 ][ 0 ] == NULL )
176   {
177     vtkErrorMacro( << "Input " << 0 << " must be specified." );
178     return;
179
180   } // fi
181
182   int numInputs = this->GetNumberOfInputConnections( 0 );
183   int scalarType = inData[ 0 ][ 0 ]->GetScalarType( );
184   int numComp = inData[ 0 ][ 0 ]->GetNumberOfScalarComponents( );
185   for( int i = 1; i < numInputs; ++i )
186   {
187     int otherType = inData[ 0 ][ i ]->GetScalarType( );
188     int otherComp = inData[ 0 ][ i ]->GetNumberOfScalarComponents( );
189     if( otherType != scalarType || otherComp != numComp )
190     {
191       if( id == 0 )
192         vtkErrorMacro(
193           "ThreadedRequestData: Input " << i
194           << " has " << otherComp << " components of type "
195           << otherType << ", but input 0 has " << numComp
196           << " components of type " << scalarType
197           );
198       return;
199
200     } // fi
201
202   } // rof
203
204   switch( scalarType )
205   {
206     vtkTemplateMacro(
207       cpExtensions_Visualization_ImageBlender_Execute(
208         this, inData[ 0 ], numInputs, this->m_Ranges,
209         outData[ 0 ], outExt, id, static_cast< VTK_TT* >( 0 )
210         )
211       );
212   default:
213     if( id == 0 )
214       vtkErrorMacro( << "Execute: Unknown ScalarType" );
215     return;
216   } // hctiws
217 }
218
219 // -------------------------------------------------------------------------
220 int cpExtensions::Visualization::ImageBlender::
221 FillInputPortInformation( int i, vtkInformation* info )
222 {
223   info->Set( vtkAlgorithm::INPUT_IS_REPEATABLE( ), 1 );
224   return( this->Superclass::FillInputPortInformation( i,info ) );
225 }
226
227 // eof - $RCSfile$