1 #include <cpExtensions/Visualization/ImageBlender.h>
5 #include <vtkDataObject.h>
6 #include <vtkImageData.h>
7 #include <vtkImageIterator.h>
8 #include <vtkImageProgressIterator.h>
9 #include <vtkInformation.h>
10 #include <vtkInformationVector.h>
12 // -------------------------------------------------------------------------
13 cpExtensions::Visualization::ImageBlender::
14 Self* cpExtensions::Visualization::ImageBlender::
17 return( new Self( ) );
20 // -------------------------------------------------------------------------
21 void cpExtensions::Visualization::ImageBlender::
22 PrintSelf( std::ostream& os, vtkIndent indent )
24 this->Superclass::PrintSelf( os, indent );
27 os << indent << "Colors: " << std::endl;
28 auto i = this->Colors.begin( );
29 for( ; i != this->Colors.end( ); ++i )
31 << indent << indent << i->first << " : ["
32 << i->second.R << ", "
33 << i->second.G << ", "
38 // -------------------------------------------------------------------------
39 unsigned int cpExtensions::Visualization::ImageBlender::
40 GetNumberOfImages( ) const
43 ( const_cast< Self* >( this ) )->GetNumberOfInputConnections( 0 )
47 // -------------------------------------------------------------------------
48 void cpExtensions::Visualization::ImageBlender::
49 SetWindowLevel( const double& w, const double& l )
55 // -------------------------------------------------------------------------
56 void cpExtensions::Visualization::ImageBlender::
58 const unsigned int& i,
64 auto c = this->Colors.find( i );
65 if( c != this->Colors.end( ) )
81 // -------------------------------------------------------------------------
82 void cpExtensions::Visualization::ImageBlender::
84 const unsigned int& i,
90 this->Colors[ i ] = TColor( r, g, b );
94 // -------------------------------------------------------------------------
95 cpExtensions::Visualization::ImageBlender::
98 MaxWindow( double( 1 ) ),
99 MaxLevel( double( 1 ) ),
100 MinWindow( double( 0 ) ),
101 MinLevel( double( 0 ) ),
102 Window( double( 1 ) ),
103 Level( double( 0.5 ) )
105 this->SetNumberOfInputPorts( 1 );
108 // -------------------------------------------------------------------------
109 cpExtensions::Visualization::ImageBlender::
114 // -------------------------------------------------------------------------
115 int cpExtensions::Visualization::ImageBlender::
117 vtkInformation* request,
118 vtkInformationVector** inputVector,
119 vtkInformationVector* outputVector
122 // Check number of inputs
123 int numInputs = this->GetNumberOfInputConnections( 0 );
128 vtkInformation* inInfo = inputVector[ 0 ]->GetInformationObject( 0 );
131 vtkImageData* inData = vtkImageData::SafeDownCast(
132 inInfo->Get( vtkDataObject::DATA_OBJECT( ) )
137 // Configure buffer extent
138 inData->GetExtent( this->m_Extent );
139 this->m_Extent[ 1 ] -= this->m_Extent[ 0 ];
140 this->m_Extent[ 3 ] -= this->m_Extent[ 2 ];
141 this->m_Extent[ 5 ] -= this->m_Extent[ 4 ];
142 this->m_Extent[ 1 ] += 1;
143 this->m_Extent[ 3 ] += 1;
144 this->m_Extent[ 5 ] += 1;
146 // Configure window/level
147 this->m_WLSlope = double( 1 ) / this->Window;
148 this->m_WLOffset = double( 0.5 ) - ( this->Level / this->Window );
150 // Configure output type
151 vtkDataObject::SetPointDataActiveScalarInfo(
152 outputVector->GetInformationObject( 0 ),
158 // -------------------------------------------------------------------------
159 void cpExtensions::Visualization::ImageBlender::
161 vtkInformation* request,
162 vtkInformationVector** inputVector,
163 vtkInformationVector* outputVector,
164 vtkImageData*** inData,
165 vtkImageData** outData,
166 int outExt[ 6 ], int id
169 if( inData[ 0 ][ 0 ] == NULL )
171 vtkErrorMacro( << "Input " << 0 << " must be specified." );
176 int numInputs = this->GetNumberOfInputConnections( 0 );
177 int numComp = inData[ 0 ][ 0 ]->GetNumberOfScalarComponents( );
181 "ThreadedRequestData: Input has " << numComp
182 << " components, but just 1 is supported"
188 for( int i = 1; i < numInputs; ++i )
190 int otherComp = inData[ 0 ][ i ]->GetNumberOfScalarComponents( );
191 if( otherComp != numComp )
195 "ThreadedRequestData: Input " << i
196 << " has " << otherComp
197 << " components, but input 0 has " << numComp
207 this->_GenerateData( inData[ 0 ], numInputs, outData[ 0 ], outExt, id );
210 // -------------------------------------------------------------------------
211 int cpExtensions::Visualization::ImageBlender::
212 FillInputPortInformation( int i, vtkInformation* info )
214 info->Set( vtkAlgorithm::INPUT_IS_REPEATABLE( ), 1 );
215 return( this->Superclass::FillInputPortInformation( i, info ) );
219 // -------------------------------------------------------------------------
220 #define cpExtensions_ImageBlender_Type( O, V, T, B ) \
225 V = O( *( reinterpret_cast< char* >( B ) ) ); \
228 V = O( *( reinterpret_cast< short* >( B ) ) ); \
231 V = O( *( reinterpret_cast< int* >( B ) ) ); \
234 V = O( *( reinterpret_cast< long* >( B ) ) ); \
236 case VTK_UNSIGNED_CHAR: \
237 V = O( *( reinterpret_cast< unsigned char* >( B ) ) ); \
239 case VTK_UNSIGNED_SHORT: \
240 V = O( *( reinterpret_cast< unsigned short* >( B ) ) ); \
242 case VTK_UNSIGNED_INT: \
243 V = O( *( reinterpret_cast< unsigned int* >( B ) ) ); \
245 case VTK_UNSIGNED_LONG: \
246 V = O( *( reinterpret_cast< unsigned long* >( B ) ) ); \
249 V = O( *( reinterpret_cast< float* >( B ) ) ); \
252 V = O( *( reinterpret_cast< double* >( B ) ) ); \
256 // -------------------------------------------------------------------------
257 void cpExtensions::Visualization::ImageBlender::
259 vtkImageData** inDatas,
261 vtkImageData* outData,
266 static const double _0 = double( 0 );
267 static const double _1 = double( 1 );
268 static const double _255 = double( 255 );
270 unsigned char* mBuffer =
271 reinterpret_cast< unsigned char* >( inDatas[ 0 ]->GetScalarPointer( ) );
272 unsigned char* oBuffer =
273 reinterpret_cast< unsigned char* >( outData->GetScalarPointer( ) );
274 int mType = inDatas[ 0 ]->GetScalarType( );
275 int mSize = inDatas[ 0 ]->GetScalarSize( );
278 int e13 = this->m_Extent[ 1 ] * this->m_Extent[ 3 ];
279 for( int k = outExt[ 4 ]; k <= outExt[ 5 ]; ++k )
281 int dk = ( k - this->m_Extent[ 4 ] ) * e13;
282 for( int j = outExt[ 2 ]; j <= outExt[ 3 ]; ++j )
284 int dj = ( ( j - this->m_Extent[ 2 ] ) * this->m_Extent[ 3 ] ) + dk;
285 for( int i = outExt[ 0 ]; i <= outExt[ 1 ]; ++i )
287 int di = ( i - this->m_Extent[ 0 ] ) + dj;
290 cpExtensions_ImageBlender_Type(
291 double, v, mType, mBuffer + ( di * mSize )
293 v *= this->m_WLSlope;
294 v += this->m_WLOffset;
302 for( int i = 1; i < numInputs; ++i )
304 unsigned char* cBuffer =
305 reinterpret_cast< unsigned char* >(
306 inDatas[ i ]->GetScalarPointer( )
308 int cType = inDatas[ i ]->GetScalarType( );
309 int cSize = inDatas[ i ]->GetScalarSize( );
310 cpExtensions_ImageBlender_Type(
311 double, c, cType, cBuffer + ( di * cSize )
313 if( c > double( 0 ) )
315 TColor rgb = this->Colors[ i ];
326 oBuffer[ di3 + 0 ] = static_cast< unsigned char >( r * _255 );
327 oBuffer[ di3 + 1 ] = static_cast< unsigned char >( g * _255 );
328 oBuffer[ di3 + 2 ] = static_cast< unsigned char >( b * _255 );