]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Visualization/ImageBlender.cxx
MPR-OpenGL integration: not yet finished, just one step to go. IT DOES NOT COMPILE.
[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   return(
88     this->Superclass::RequestData( request, inputVector, outputVector )
89     );
90 }
91
92 // -------------------------------------------------------------------------
93 // Description:
94 // This templated function executes the filter for any type of data.
95 template< class T >
96 void cpExtensions_Visualization_ImageBlender_Execute(
97   cpExtensions::Visualization::ImageBlender* self,
98   vtkImageData** inDatas, int numInputs,
99   const std::vector< double >& ranges, vtkImageData* outData,
100   int outExt[ 6 ], int id, T* really_not_used
101   )
102 {
103   vtkImageIterator< T > inItsFast[ 256 ];
104   T* inSIFast[ 256 ];
105   vtkImageProgressIterator< T > outIt( outData, outExt, self, id );
106   vtkImageIterator< T >* inIts;
107   T** inSI;
108   if( numInputs < 256 )
109   {
110     inIts = inItsFast;
111     inSI = inSIFast;
112   }
113   else
114   {
115     inIts = new vtkImageIterator< T >[ numInputs ];
116     inSI = new T*[ numInputs ];
117
118   } // fi
119
120   // Loop through all input ImageData to initialize iterators
121   for( int i = 0; i < numInputs; ++i )
122     inIts[ i ].Initialize( inDatas[ i ], outExt );
123
124   // Loop through output pixels
125   while( !outIt.IsAtEnd( ) )
126   {
127     for( int j = 0; j < numInputs; ++j )
128       inSI[ j ] = inIts[ j ].BeginSpan( );
129
130     T* outSI = outIt.BeginSpan( );
131     T* outSIEnd = outIt.EndSpan( );
132
133     // Pixel operation
134     while( outSI != outSIEnd )
135     {
136       // Input 0 is ignored: it is just used to guarantee sizes all over
137       // the result
138       double vmax = double( 0 );
139       for( int k = 1; k < numInputs; ++k )
140       {
141         double v =
142           ( ( double( k ) * double( *inSI[ k ] ) ) - ranges[ k << 1 ] ) /
143           ( ranges[ ( k << 1 ) + 1 ] - ranges[ k << 1 ] );
144         vmax = ( vmax < v )? v: vmax;
145
146       } // rof
147       *outSI = static_cast< T >( vmax );
148       outSI++;
149       for( int l = 0; l < numInputs; ++l )
150         inSI[ l ]++;
151
152     } // elihw
153     for( int j = 0; j < numInputs; ++j )
154       inIts[ j ].NextSpan( );
155     outIt.NextSpan( );
156
157   } // elihw
158
159   if( numInputs >= 256)
160   {
161     delete [] inIts;
162     delete [] inSI;
163
164   } // fi
165 }
166
167 // -------------------------------------------------------------------------
168 void cpExtensions::Visualization::ImageBlender::
169 ThreadedRequestData(
170   vtkInformation* request,
171   vtkInformationVector** inputVector,
172   vtkInformationVector* outputVector,
173   vtkImageData*** inData, vtkImageData** outData,
174   int outExt[ 6 ], int id
175   )
176 {
177   if( inData[ 0 ][ 0 ] == NULL )
178   {
179     vtkErrorMacro( << "Input " << 0 << " must be specified." );
180     return;
181
182   } // fi
183
184   int numInputs = this->GetNumberOfInputConnections( 0 );
185   int scalarType = inData[ 0 ][ 0 ]->GetScalarType( );
186   int numComp = inData[ 0 ][ 0 ]->GetNumberOfScalarComponents( );
187   for( int i = 1; i < numInputs; ++i )
188   {
189     int otherType = inData[ 0 ][ i ]->GetScalarType( );
190     int otherComp = inData[ 0 ][ i ]->GetNumberOfScalarComponents( );
191     if( otherType != scalarType || otherComp != numComp )
192     {
193       if( id == 0 )
194         vtkErrorMacro(
195           "ThreadedRequestData: Input " << i
196           << " has " << otherComp << " components of type "
197           << otherType << ", but input 0 has " << numComp
198           << " components of type " << scalarType
199           );
200       return;
201
202     } // fi
203
204   } // rof
205
206   switch( scalarType )
207   {
208     vtkTemplateMacro(
209       cpExtensions_Visualization_ImageBlender_Execute(
210         this, inData[ 0 ], numInputs, this->m_Ranges,
211         outData[ 0 ], outExt, id, static_cast< VTK_TT* >( 0 )
212         )
213       );
214   default:
215     if( id == 0 )
216       vtkErrorMacro( << "Execute: Unknown ScalarType" );
217     return;
218   } // hctiws
219 }
220
221 // -------------------------------------------------------------------------
222 int cpExtensions::Visualization::ImageBlender::
223 FillInputPortInformation( int i, vtkInformation* info )
224 {
225   info->Set( vtkAlgorithm::INPUT_IS_REPEATABLE( ), 1 );
226   return( this->Superclass::FillInputPortInformation( i,info ) );
227 }
228
229 // eof - $RCSfile$