00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "vtkMitkThickSlicesFilter.h"
00019
00020 #include "vtkDataArray.h"
00021 #include "vtkImageData.h"
00022 #include "vtkInformation.h"
00023 #include "vtkInformationVector.h"
00024 #include "vtkObjectFactory.h"
00025 #include "vtkPointData.h"
00026 #include "vtkStreamingDemandDrivenPipeline.h"
00027
00028 #include <math.h>
00029 #include <vtksys/ios/sstream>
00030
00031 vtkCxxRevisionMacro(vtkMitkThickSlicesFilter, "$Revision: 1.00 $");
00032 vtkStandardNewMacro(vtkMitkThickSlicesFilter);
00033
00034
00035
00036 vtkMitkThickSlicesFilter::vtkMitkThickSlicesFilter()
00037 {
00038 this->HandleBoundaries = 1;
00039 this->Dimensionality = 2;
00040
00041 this->m_CurrentMode = MIP;
00042
00043
00044 this->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
00045 vtkDataSetAttributes::SCALARS);
00046 }
00047
00048
00049 void vtkMitkThickSlicesFilter::PrintSelf(ostream& os, vtkIndent indent)
00050 {
00051 this->Superclass::PrintSelf(os, indent);
00052 os << indent << "HandleBoundaries: " << this->HandleBoundaries << "\n";
00053 os << indent << "Dimensionality: " << this->Dimensionality << "\n";
00054 }
00055
00056
00057 int vtkMitkThickSlicesFilter::RequestInformation(vtkInformation*,
00058 vtkInformationVector** inputVector,
00059 vtkInformationVector* outputVector)
00060 {
00061
00062 vtkInformation* outInfo = outputVector->GetInformationObject(0);
00063 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
00064
00065
00066 int extent[6];
00067 inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent);
00068
00069
00070 extent[4] = extent[5] = 0;
00071
00072
00073 outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent, 6);
00074
00075
00076
00077
00078
00079
00080
00081 return 1;
00082 }
00083
00084
00085
00086 int vtkMitkThickSlicesFilter::RequestUpdateExtent(vtkInformation*,
00087 vtkInformationVector** inputVector,
00088 vtkInformationVector* outputVector)
00089 {
00090
00091 vtkInformation* outInfo = outputVector->GetInformationObject(0);
00092 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
00093
00094
00095 int wholeExtent[6];
00096 inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), wholeExtent);
00097
00098
00099 int inUExt[6];
00100 outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inUExt);
00101
00102
00103
00104
00105 inUExt[4] = wholeExtent[4];
00106 inUExt[5] = wholeExtent[5];
00107
00108
00109 inInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), inUExt, 6);
00110
00111 return 1;
00112 }
00113
00114
00115
00116
00117
00118 template <class T>
00119 void vtkMitkThickSlicesFilterExecute(vtkMitkThickSlicesFilter *self,
00120 vtkImageData *inData, T *inPtr,
00121 vtkImageData *outData, T *outPtr,
00122 int outExt[6], int )
00123 {
00124 int idxX, idxY;
00125 int maxX, maxY;
00126 vtkIdType inIncX, inIncY, inIncZ;
00127 vtkIdType outIncX, outIncY, outIncZ;
00128 int axesNum;
00129 int *inExt = inData->GetExtent();
00130 int *wholeExtent;
00131 vtkIdType *inIncs;
00132 int useYMin, useYMax, useXMin, useXMax;
00133
00134
00135 maxX = outExt[1] - outExt[0];
00136 maxY = outExt[3] - outExt[2];
00137
00138
00139
00140
00141 axesNum = self->GetDimensionality();
00142
00143
00144 inData->GetContinuousIncrements(outExt, inIncX, inIncY, inIncZ);
00145 outData->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 inIncs = inData->GetIncrements();
00157 wholeExtent = inData->GetExtent();
00158
00159
00160 inPtr += (outExt[0]-inExt[0])*inIncs[0] +
00161 (outExt[2]-inExt[2])*inIncs[1] +
00162 (outExt[4]-inExt[4])*inIncs[2];
00163
00164
00165
00166 int _minZ = wholeExtent[4];
00167 int _maxZ = wholeExtent[5];
00168
00169 if(_maxZ<_minZ)
00170 return;
00171
00172 double invNum = 1.0 / (_maxZ-_minZ+1) ;
00173
00174
00175 switch(self->GetThickSliceMode())
00176 {
00177 default:
00178 case vtkMitkThickSlicesFilter::MIP:
00179 {
00180
00181 for (idxY = 0; idxY <= maxY; idxY++)
00182 {
00183 useYMin = ((idxY + outExt[2]) <= wholeExtent[2]) ? 0 : -inIncs[1];
00184 useYMax = ((idxY + outExt[2]) >= wholeExtent[3]) ? 0 : inIncs[1];
00185 for (idxX = 0; idxX <= maxX; idxX++)
00186 {
00187 useXMin = ((idxX + outExt[0]) <= wholeExtent[0]) ? 0 : -inIncs[0];
00188 useXMax = ((idxX + outExt[0]) >= wholeExtent[1]) ? 0 : inIncs[0];
00189
00190 T mip = inPtr[_minZ*inIncs[2]];
00191
00192 for(int z = _minZ+1; z<= _maxZ;z++)
00193 {
00194 T value = inPtr[z*inIncs[2]];
00195 if(value > mip)
00196 mip=value;
00197 }
00198
00199
00200 *outPtr = mip;
00201 outPtr++;
00202 inPtr++;
00203 }
00204 outPtr += outIncY;
00205 inPtr += inIncY;
00206 }
00207 }
00208 break;
00209
00210 case vtkMitkThickSlicesFilter::SUM:
00211 {
00212
00213 for (idxY = 0; idxY <= maxY; idxY++)
00214 {
00215 useYMin = ((idxY + outExt[2]) <= wholeExtent[2]) ? 0 : -inIncs[1];
00216 useYMax = ((idxY + outExt[2]) >= wholeExtent[3]) ? 0 : inIncs[1];
00217 for (idxX = 0; idxX <= maxX; idxX++)
00218 {
00219 useXMin = ((idxX + outExt[0]) <= wholeExtent[0]) ? 0 : -inIncs[0];
00220 useXMax = ((idxX + outExt[0]) >= wholeExtent[1]) ? 0 : inIncs[0];
00221
00222 double sum = 0;
00223
00224 for(int z = _minZ; z<= _maxZ;z++)
00225 {
00226 T value = inPtr[z*inIncs[2]];
00227 sum += value;
00228 }
00229
00230
00231 *outPtr = invNum*sum;
00232 outPtr++;
00233 inPtr++;
00234 }
00235 outPtr += outIncY;
00236 inPtr += inIncY;
00237 }
00238 }
00239 break;
00240 }
00241
00242 }
00243
00244 int vtkMitkThickSlicesFilter::RequestData(
00245 vtkInformation* request,
00246 vtkInformationVector** inputVector,
00247 vtkInformationVector* outputVector)
00248 {
00249 if (!this->Superclass::RequestData(request, inputVector, outputVector))
00250 {
00251 return 0;
00252 }
00253 vtkImageData* output = vtkImageData::GetData(outputVector);
00254 vtkDataArray* outArray = output->GetPointData()->GetScalars();
00255 vtksys_ios::ostringstream newname;
00256 newname << (outArray->GetName()?outArray->GetName():"")
00257 << "Gradient";
00258 outArray->SetName(newname.str().c_str());
00259
00260 if (this->GetInputArrayToProcess(0, inputVector))
00261 {
00262 output->GetPointData()->AddArray(
00263 this->GetInputArrayToProcess(0, inputVector));
00264 }
00265 return 1;
00266 }
00267
00268
00269
00270
00271
00272 void vtkMitkThickSlicesFilter::ThreadedRequestData(vtkInformation*,
00273 vtkInformationVector** inputVector,
00274 vtkInformationVector*,
00275 vtkImageData*** inData,
00276 vtkImageData** outData,
00277 int outExt[6],
00278 int threadId)
00279 {
00280
00281 vtkImageData* input = inData[0][0];
00282 vtkImageData* output = outData[0];
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 vtkDataArray* inputArray = this->GetInputArrayToProcess(0, inputVector);
00294 if (!inputArray)
00295 {
00296 vtkErrorMacro("No input array was found. Cannot execute");
00297 return;
00298 }
00299
00300
00301
00302 if(inputArray->GetNumberOfComponents() != 1)
00303 {
00304 vtkErrorMacro(
00305 "Execute: input has more than one component. "
00306 "The input to gradient should be a single component image. "
00307 "Think about it. If you insist on using a color image then "
00308 "run it though RGBToHSV then ExtractComponents to get the V "
00309 "components. That's probably what you want anyhow.");
00310 return;
00311 }
00312
00313 void* inPtr = inputArray->GetVoidPointer(0);
00314 void* outPtr = output->GetScalarPointerForExtent(outExt);
00315
00316 switch(inputArray->GetDataType())
00317 {
00318 vtkTemplateMacro(
00319 vtkMitkThickSlicesFilterExecute(this, input, static_cast<VTK_TT*>(inPtr), output, static_cast<VTK_TT*>(outPtr), outExt, threadId)
00320 );
00321 default:
00322 vtkErrorMacro("Execute: Unknown ScalarType " << input->GetScalarType());
00323 return;
00324 }
00325 }