/*========================================================================= medInria Copyright (c) INRIA 2013 - 2018. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include "vtkImageFromBoundsSource.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkStreamingDemandDrivenPipeline.h" #include "vtkImageData.h" vtkStandardNewMacro(vtkImageFromBoundsSource); //---------------------------------------------------------------------------- vtkImageFromBoundsSource::vtkImageFromBoundsSource() { this->OutputImageSize[0] = 128; this->OutputImageSize[1] = 128; this->OutputImageSize[2] = 128; this->OutputImageOrigin[0] = 0.0; this->OutputImageOrigin[1] = 0.0; this->OutputImageOrigin[2] = 0.0; this->OutputImageSpacing[0] = 1.0; this->OutputImageSpacing[1] = 1.0; this->OutputImageSpacing[2] = 1.0; this->OutputImageBounds[0] = 0.0; this->OutputImageBounds[1] = -1.0; this->OutputImageBounds[2] = 0.0; this->OutputImageBounds[3] = -1.0; this->OutputImageBounds[4] = 0.0; this->OutputImageBounds[5] = -1.0; this->SpacingSet = 0; this->OriginSet = 0; this->ImageBoundsSet = 0; this->OutValue = 0.0; this->OutValueSet =0; this->OutputScalarType = VTK_UNSIGNED_CHAR; this->SetNumberOfInputPorts(0); } //---------------------------------------------------------------------------- vtkImageFromBoundsSource::~vtkImageFromBoundsSource() { } //---------------------------------------------------------------------------- void vtkImageFromBoundsSource::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); os << indent << "Image Bounds: (" << this->OutputImageBounds[1] << ", " << this->OutputImageBounds[2] << this->OutputImageBounds[1] << ", " << this->OutputImageBounds[2] << this->OutputImageBounds[1] << ", " << this->OutputImageBounds[2] << ")\n"; os << indent << "OutValue: " << this->OutValue << "\n"; os << indent << "OutputScalarType: " << this->OutputScalarType << "\n"; os << indent << "Output Origin: (" << this->OutputImageOrigin[0] << ", " << this->OutputImageOrigin[1] << ", " << this->OutputImageOrigin[2] << ")\n"; } //---------------------------------------------------------------------------- void vtkImageFromBoundsSource::SetOutputImageBounds(const double bounds[6]) { int idx; for (idx = 0; idx < 6; ++idx) { if (this->OutputImageBounds[idx] != bounds[idx]) { this->OutputImageBounds[idx] = bounds[idx]; this->Modified(); } } this->ImageBoundsSet = 1; } //---------------------------------------------------------------------------- void vtkImageFromBoundsSource::SetOutputImageBounds(double minX, double maxX, double minY, double maxY, double minZ, double maxZ) { double bounds[6]; bounds[0] = minX; bounds[1] = maxX; bounds[2] = minY; bounds[3] = maxY; bounds[4] = minZ; bounds[5] = maxZ; this->SetOutputImageBounds(bounds); } //---------------------------------------------------------------------------- void vtkImageFromBoundsSource::GetOutputImageBounds(double bounds[6]) { int idx; for (idx = 0; idx < 6; ++idx) { bounds[idx] = this->OutputImageBounds[idx]; } } //---------------------------------------------------------------------------- int vtkImageFromBoundsSource::RequestInformation ( vtkInformation * vtkNotUsed(request), vtkInformationVector** vtkNotUsed( inputVector ), vtkInformationVector *outputVector) { if(ImageBoundsSet) { // Use the bounds to set the image origin if (!this->OriginSet) { if ( this->OutputImageBounds[0] <= this->OutputImageBounds[1] && this->OutputImageBounds[2] <= this->OutputImageBounds[3] && this->OutputImageBounds[4] <= this->OutputImageBounds[5] ) { this->OutputImageOrigin[0] = this->OutputImageBounds[0]; this->OutputImageOrigin[1] = this->OutputImageBounds[2]; this->OutputImageOrigin[2] = this->OutputImageBounds[4]; } } // If spacing has not been set by the user, estimate it. if (!this->SpacingSet) { for (unsigned int i=0; i<3; i++) this->OutputImageSpacing[i] = (this->OutputImageBounds[2*i+1] - this->OutputImageBounds[2*i])/(double)this->OutputImageSize[i]; } // get the info objects vtkInformation* outInfo = outputVector->GetInformationObject(0); outInfo->Set(vtkDataObject::ORIGIN(), this->OutputImageOrigin, 3); outInfo->Set(vtkDataObject::SPACING(),this->OutputImageSpacing,3); outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), 0, this->OutputImageSize[0] - 1, 0, this->OutputImageSize[1] - 1, 0, this->OutputImageSize[2] - 1); vtkDataObject::SetPointDataActiveScalarInfo(outInfo, this->OutputScalarType, -1); return 1; } return 0; } template void vtkImageFromBoundsSourceExecute(vtkImageFromBoundsSource *self, vtkImageData *data, int ext[6], T *ptr) { int min0, max0; int idx0, idx1, idx2; vtkIdType inc0, inc1, inc2; T outVal; unsigned long count = 0; unsigned long target; outVal = static_cast(self->GetOutValue()); min0 = ext[0]; max0 = ext[1]; data->GetContinuousIncrements(ext, inc0, inc1, inc2); target = static_cast((ext[5]-ext[4]+1)*(ext[3]-ext[2]+1)/50.0); target++; for (idx2 = ext[4]; idx2 <= ext[5]; ++idx2) { for (idx1 = ext[2]; !self->AbortExecute && idx1 <= ext[3]; ++idx1) { if (!(count%target)) { self->UpdateProgress(count/(50.0*target)); } count++; for (idx0 = min0; idx0 <= max0; ++idx0) { *ptr = outVal; ++ptr; // inc0 is 0 } ptr += inc1; } ptr += inc2; } } //---------------------------------------------------------------------------- int vtkImageFromBoundsSource::RequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector ** vtkNotUsed( inputVector ), vtkInformationVector *outputVector) { vtkInformation *outInfo = outputVector->GetInformationObject(0); vtkImageData *data = vtkImageData::SafeDownCast( outInfo->Get(vtkDataObject::DATA_OBJECT())); if(this->OutValueSet) { int extent[6]; outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),extent); data->SetExtent(extent); data->AllocateScalars(outInfo); void *ptr; ptr = data->GetScalarPointerForExtent(extent); switch (data->GetScalarType()) { vtkTemplateMacro( vtkImageFromBoundsSourceExecute(this, data, extent, static_cast(ptr))); default: vtkErrorMacro("Execute: Unknown output ScalarType"); } } else { // just allocate data ! data->SetExtent( outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT())); data->AllocateScalars(outInfo); } return 1; }