1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkImplicitFunctionToImageStencil.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkImplicitFunctionToImageStencil.h"
#include "vtkImageStencilData.h"
#include "vtkImplicitFunction.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include <math.h>
vtkCxxRevisionMacro(vtkImplicitFunctionToImageStencil, "$Revision: 1.12 $");
vtkStandardNewMacro(vtkImplicitFunctionToImageStencil);
vtkCxxSetObjectMacro(vtkImplicitFunctionToImageStencil,Input, vtkImplicitFunction);
//----------------------------------------------------------------------------
vtkImplicitFunctionToImageStencil::vtkImplicitFunctionToImageStencil()
{
this->SetNumberOfInputPorts(0);
this->Threshold = 0;
this->Input = NULL;
}
//----------------------------------------------------------------------------
vtkImplicitFunctionToImageStencil::~vtkImplicitFunctionToImageStencil()
{
this->SetInput(NULL);
}
//----------------------------------------------------------------------------
void vtkImplicitFunctionToImageStencil::PrintSelf(ostream& os,
vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Input: " << this->Input << "\n";
os << indent << "Threshold: " << this->Threshold << "\n";
}
//----------------------------------------------------------------------------
// set up the clipping extents from an implicit function by brute force
// (i.e. by evaluating the function at each and every voxel)
int vtkImplicitFunctionToImageStencil::RequestData(
vtkInformation *request,
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
this->Superclass::RequestData(request, inputVector, outputVector);
vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkImageStencilData *data = vtkImageStencilData::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkImplicitFunction *function = this->Input;
double *spacing = data->GetSpacing();
double *origin = data->GetOrigin();
double threshold = this->Threshold;
// if the input is not set then punt
if (!function)
{
return 1;
}
// for conversion of (idX,idY,idZ) into (x,y,z)
double point[3];
// for keeping track of progress
unsigned long count = 0;
int extent[6];
data->GetExtent(extent);
unsigned long target = (unsigned long)
((extent[5] - extent[4] + 1)*(extent[3] - extent[2] + 1)/50.0);
target++;
// loop through all voxels
for (int idZ = extent[4]; idZ <= extent[5]; idZ++)
{
point[2] = idZ*spacing[2] + origin[2];
for (int idY = extent[2]; idY <= extent[3]; idY++)
{
point[1] = idY*spacing[1] + origin[1];
int state = 1; // inside or outside, start outside
int r1 = extent[0];
int r2 = extent[1];
if (count%target == 0)
{
this->UpdateProgress(count/(50.0*target));
}
count++;
for (int idX = extent[0]; idX <= extent[1]; idX++)
{
point[0] = idX*spacing[0] + origin[0];
int newstate = 1;
if (function->FunctionValue(point) < threshold)
{
newstate = -1;
if (newstate != state)
{ // sub extent starts
r1 = idX;
}
}
else if (newstate != state)
{ // sub extent ends
r2 = idX - 1;
data->InsertNextExtent(r1, r2, idY, idZ);
}
state = newstate;
} // for idX
if (state == -1)
{ // if inside at end, cap off the sub extent
data->InsertNextExtent(r1, extent[1], idY, idZ);
}
} // for idY
} // for idZ
return 1;
}
int vtkImplicitFunctionToImageStencil::RequestInformation(
vtkInformation *,
vtkInformationVector **,
vtkInformationVector *outputVector)
{
vtkInformation *outInfo = outputVector->GetInformationObject(0);
// this is an odd source that can produce any requested size. so its whole
// extent is essentially infinite. This would not be a great source to
// connect to some sort of writer or viewer. For a sanity check we will
// limit the size produced to something reasonable (depending on your
// definition of reasonable)
outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
0, VTK_LARGE_INTEGER >> 2,
0, VTK_LARGE_INTEGER >> 2,
0, VTK_LARGE_INTEGER >> 2);
return 1;
}
|