]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Visualization/ImageBlender.cxx
...
[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 unsigned int cpExtensions::Visualization::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::Visualization::ImageBlender::
31 ImageBlender( )
32   : Superclass( )
33 {
34   this->SetNumberOfInputPorts( 1 );
35 }
36
37 // -------------------------------------------------------------------------
38 cpExtensions::Visualization::ImageBlender::
39 ~ImageBlender( )
40 {
41 }
42
43 // -------------------------------------------------------------------------
44 int cpExtensions::Visualization::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::Visualization::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_Visualization_ImageBlender_Execute(
107   cpExtensions::Visualization::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       double vmax = double( 0 );
149       for( int k = 1; k < numInputs; ++k )
150       {
151         double v =
152           ( ( double( k ) * double( *inSI[ k ] ) ) - ranges[ k << 1 ] ) /
153           ( ranges[ ( k << 1 ) + 1 ] - ranges[ k << 1 ] );
154         vmax = ( vmax < v )? v: vmax;
155
156       } // rof
157       *outSI = static_cast< T >( vmax );
158       outSI++;
159       for( int l = 0; l < numInputs; ++l )
160         inSI[ l ]++;
161
162     } // elihw
163     for( int j = 0; j < numInputs; ++j )
164       inIts[ j ].NextSpan( );
165     outIt.NextSpan( );
166
167   } // elihw
168
169   if( numInputs >= 256)
170   {
171     delete [] inIts;
172     delete [] inSI;
173
174   } // fi
175 }
176
177 // -------------------------------------------------------------------------
178 void cpExtensions::Visualization::ImageBlender::
179 ThreadedRequestData(
180   vtkInformation* request,
181   vtkInformationVector** inputVector,
182   vtkInformationVector* outputVector,
183   vtkImageData*** inData, vtkImageData** outData,
184   int outExt[ 6 ], int id
185   )
186 {
187   if( inData[ 0 ][ 0 ] == NULL )
188   {
189     vtkErrorMacro( << "Input " << 0 << " must be specified." );
190     return;
191
192   } // fi
193
194   int numInputs = this->GetNumberOfInputConnections( 0 );
195   int scalarType = inData[ 0 ][ 0 ]->GetScalarType( );
196   int numComp = inData[ 0 ][ 0 ]->GetNumberOfScalarComponents( );
197   for( int i = 1; i < numInputs; ++i )
198   {
199     int otherType = inData[ 0 ][ i ]->GetScalarType( );
200     int otherComp = inData[ 0 ][ i ]->GetNumberOfScalarComponents( );
201     if( otherType != scalarType || otherComp != numComp )
202     {
203       if( id == 0 )
204         vtkErrorMacro(
205           "ThreadedRequestData: Input " << i
206           << " has " << otherComp << " components of type "
207           << otherType << ", but input 0 has " << numComp
208           << " components of type " << scalarType
209           );
210       return;
211
212     } // fi
213
214   } // rof
215
216   switch( scalarType )
217   {
218     vtkTemplateMacro(
219       cpExtensions_Visualization_ImageBlender_Execute(
220         this, inData[ 0 ], numInputs, this->m_Ranges,
221         outData[ 0 ], outExt, id, static_cast< VTK_TT* >( 0 )
222         )
223       );
224   default:
225     if( id == 0 )
226       vtkErrorMacro( << "Execute: Unknown ScalarType" );
227     return;
228   } // hctiws
229 }
230
231 // -------------------------------------------------------------------------
232 int cpExtensions::Visualization::ImageBlender::
233 FillInputPortInformation( int i, vtkInformation* info )
234 {
235   info->Set( vtkAlgorithm::INPUT_IS_REPEATABLE( ), 1 );
236   return( this->Superclass::FillInputPortInformation( i,info ) );
237 }
238
239 // eof - $RCSfile$