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