vtkExtractVOI.cxx 7.66 KB
Newer Older
1
2
/*=========================================================================

3
  Program:   Visualization Toolkit
Ken Martin's avatar
Ken Martin committed
4
  Module:    vtkExtractVOI.cxx
5

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7
8
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9

10
11
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
     PURPOSE.  See the above copyright notice for more information.
13
14

=========================================================================*/
Ken Martin's avatar
Ken Martin committed
15
#include "vtkExtractVOI.h"
16
17
18

#include "vtkCellData.h"
#include "vtkImageData.h"
19
#include "vtkObjectFactory.h"
20
#include "vtkPointData.h"
21

22
vtkCxxRevisionMacro(vtkExtractVOI, "1.37");
Brad King's avatar
Brad King committed
23
vtkStandardNewMacro(vtkExtractVOI);
24

25
//-----------------------------------------------------------------------------
26
27
28
// Construct object to extract all of the input data.
vtkExtractVOI::vtkExtractVOI()
{
29
  this->VOI[0] = this->VOI[2] = this->VOI[4] = -VTK_LARGE_INTEGER;
30
31
32
33
34
  this->VOI[1] = this->VOI[3] = this->VOI[5] = VTK_LARGE_INTEGER;

  this->SampleRate[0] = this->SampleRate[1] = this->SampleRate[2] = 1;
}

35
//-----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
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
// Get ALL of the input.
void vtkExtractVOI::ComputeInputUpdateExtent(int inExt[6], 
                                             int *)
{
  // request all of the VOI
  int *wholeExtent;
  int i;
  
  wholeExtent = this->GetInput()->GetWholeExtent();
  memcpy(inExt, wholeExtent, 6*sizeof(int));

  // no need to go outside the VOI
  for (i = 0; i < 3; ++i)
    {
    if (inExt[i*2] < this->VOI[i*2])
      {
      inExt[i*2] = this->VOI[i*2];
      }
    if (inExt[i*2+1] > this->VOI[i*2+1])
      {
      inExt[i*2+1] = this->VOI[i*2+1];
      }
    }
}

61
62
63
//-----------------------------------------------------------------------------
void 
vtkExtractVOI::ExecuteInformation(vtkImageData *input, vtkImageData *output)
64
{
Brad King's avatar
Brad King committed
65
  int i, outDims[3], voi[6];
66
67
68
  int rate[3];
  int wholeExtent[6];
  
69
70
71
72
73
  if (this->GetInput() == NULL)
    {
    vtkErrorMacro("Missing input");
    return;
    }
74
75
76
77
78
79
80
81
82
  input->GetWholeExtent( wholeExtent );
  
  for ( i=0; i < 6; i++ )
    {
    voi[i] = this->VOI[i];
    }

  for ( i=0; i < 3; i++ )
    {
83
    if ( voi[2*i+1] > wholeExtent[2*i+1] )
84
      {
85
      voi[2*i+1] = wholeExtent[2*i+1];
86
      }
87
    else if ( voi[2*i+1] < wholeExtent[2*i] )
88
      {
89
      voi[2*i+1] = wholeExtent[2*i];
90
      }
91
92
93
94
95
96
97
98
    if ( voi[2*i] < wholeExtent[2*i] )
      {
      voi[2*i] = wholeExtent[2*i];
      }
    else if ( voi[2*i] > wholeExtent[2*i+1] )
      {
      voi[2*i] = wholeExtent[2*i+1];
      }
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

    if ( voi[2*i] > voi[2*i+1] )
      {
      voi[2*i] = voi[2*i+1];
      }

    if ( (rate[i] = this->SampleRate[i]) < 1 )
      {
      rate[i] = 1;
      }

    outDims[i] = (voi[2*i+1] - voi[2*i]) / rate[i] + 1;
    if ( outDims[i] < 1 )
      {
      outDims[i] = 1;
      }
    }

117
118
119
120
121
122
123
  // This makes sense for sample rates of 1, 1, 1.
  wholeExtent[0] = voi[0];
  wholeExtent[1] = voi[0] + outDims[0] - 1;
  wholeExtent[2] = voi[2];
  wholeExtent[3] = voi[2] + outDims[1] - 1;
  wholeExtent[4] = voi[4];
  wholeExtent[5] = voi[4] + outDims[2] - 1;
124
125
126
127
  
  output->SetWholeExtent( wholeExtent );
}

128
//-----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
129
void vtkExtractVOI::ExecuteData(vtkDataObject *)
130
{
131
  vtkImageData *input=this->GetInput();
132
  vtkPointData *pd=input->GetPointData();
133
  vtkCellData *cd=input->GetCellData();
Ken Martin's avatar
Ken Martin committed
134
135
  vtkImageData *output = this->GetOutput();
  output->SetExtent(output->GetWholeExtent());
136
  vtkPointData *outPD=output->GetPointData();
137
  vtkCellData *outCD=output->GetCellData();
138
  int i, j, k, dims[3], outDims[3], voi[6], dim, idx, newIdx;
139
  int newCellId;
Ken Martin's avatar
Ken Martin committed
140
  double origin[3], ar[3], outOrigin[3], outAR[3];
141
  int sliceSize, outSize, jOffset, kOffset, rate[3];
142
143
144
  int *wholeExtent = input->GetWholeExtent();
  int *inExt = input->GetExtent();
  int *outExt = output->GetExtent();
145
146

  vtkDebugMacro(<< "Extracting VOI");
Ken Martin's avatar
Ken Martin committed
147
148
149
  //
  // Check VOI and clamp as necessary. Compute output parameters,
  //
150
151
  input->GetDimensions(dims);
  input->GetOrigin(origin);
Will Schroeder's avatar
Will Schroeder committed
152
  input->GetSpacing(ar);
153

Bill Lorensen's avatar
Bill Lorensen committed
154
155
156
157
  for ( i=0; i < 6; i++ )
    {
    voi[i] = this->VOI[i];
    }
158
159
160

  for ( outSize=1, dim=0, i=0; i < 3; i++ )
    {
161
    if ( voi[2*i+1] > wholeExtent[2*i+1] )
Bill Lorensen's avatar
Bill Lorensen committed
162
      {
163
      voi[2*i+1] = wholeExtent[2*i+1];
Bill Lorensen's avatar
Bill Lorensen committed
164
      }
165
    else if ( voi[2*i+1] < wholeExtent[2*i] )
Bill Lorensen's avatar
Bill Lorensen committed
166
      {
167
      voi[2*i+1] = wholeExtent[2*i];
Bill Lorensen's avatar
Bill Lorensen committed
168
      }
169
170
171
172
173
174
175
176
    if ( voi[2*i] < wholeExtent[2*i] )
      {
      voi[2*i] = wholeExtent[2*i];
      }
    else if ( voi[2*i] > wholeExtent[2*i+1] )
      {
      voi[2*i] = wholeExtent[2*i+1];
      }
Bill Lorensen's avatar
Bill Lorensen committed
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

    if ( voi[2*i] > voi[2*i+1] )
      {
      voi[2*i] = voi[2*i+1];
      }

    if ( (voi[2*i+1]-voi[2*i]) > 0 )
      {
      dim++;
      }

    if ( (rate[i] = this->SampleRate[i]) < 1 )
      {
      rate[i] = 1;
      }
192

193
    outDims[i] = (voi[2*i+1] - voi[2*i]) / rate[i] + 1;
Bill Lorensen's avatar
Bill Lorensen committed
194
195
196
197
    if ( outDims[i] < 1 )
      {
      outDims[i] = 1;
      }
198
199

    outAR[i] = ar[i] * this->SampleRate[i];
200
    outOrigin[i] = origin[i] + voi[2*i]*ar[i] - outExt[2*i]*outAR[i];
201
202
    outSize *= outDims[i];
    }
203
  
Will Schroeder's avatar
Will Schroeder committed
204
  output->SetSpacing(outAR);
205
  output->SetOrigin(outOrigin);
Ken Martin's avatar
Ken Martin committed
206
207
208
  // 
  // If output same as input, just pass data through
  //
209
  if ( outDims[0] == dims[0] && outDims[1] == dims[1] && outDims[2] == dims[2] &&
Ken Martin's avatar
Ken Martin committed
210
       rate[0] == 1 && rate[1] == 1 && rate[2] == 1 )
211
212
    {
    output->GetPointData()->PassData(input->GetPointData());
213
214
    output->GetCellData()->PassData(input->GetCellData());
    vtkDebugMacro(<<"Passed data through because input and output are the same");
215
216
    return;
    }
Ken Martin's avatar
Ken Martin committed
217
218
219
  //
  // Allocate necessary objects
  //
220
  outPD->CopyAllocate(pd,outSize,outSize);
221
  outCD->CopyAllocate(cd,outSize,outSize);
222
  sliceSize = dims[0]*dims[1];
Ken Martin's avatar
Ken Martin committed
223
224
225
226
  
  //
  // Traverse input data and copy point attributes to output
  //
227
228
229
  newIdx = 0;
  for ( k=voi[4]; k <= voi[5]; k += rate[2] )
    {
230
    kOffset = (k-inExt[4]) * sliceSize;
231
232
    for ( j=voi[2]; j <= voi[3]; j += rate[1] )
      {
233
      jOffset = (j-inExt[2]) * dims[0];
234
235
      for ( i=voi[0]; i <= voi[1]; i += rate[0] )
        {
236
        idx = (i-inExt[0]) + jOffset + kOffset;
237
238
239
240
241
        outPD->CopyData(pd, idx, newIdx++);
        }
      }
    }

Ken Martin's avatar
Ken Martin committed
242
243
244
  //
  // Traverse input data and copy cell attributes to output
  //
245
246
247
248
249
250
251
252
253
254
255
256
257
258
  // Handle 2D, 1D and 0D degenerate data sets.
  if (voi[5] == voi[4])
    {
    ++voi[5];
    }
  if (voi[3] == voi[2])
    {
    ++voi[3];
    }
  if (voi[1] == voi[0])
    {
    ++voi[1];
    }

259
260
261
262
  newCellId = 0;
  sliceSize = (dims[0]-1)*(dims[1]-1);
  for ( k=voi[4]; k < voi[5]; k += rate[2] )
    {
263
    kOffset = (k-inExt[4]) * sliceSize;
264
265
    for ( j=voi[2]; j < voi[3]; j += rate[1] )
      {
266
      jOffset = (j-inExt[2]) * (dims[0] - 1);
267
268
      for ( i=voi[0]; i < voi[1]; i += rate[0] )
        {
269
        idx = (i-inExt[0]) + jOffset + kOffset;
270
271
272
273
        outCD->CopyData(cd, idx, newCellId++);
        }
      }
    }
Ken Martin's avatar
Ken Martin committed
274
  
275
  vtkDebugMacro(<<"Extracted " << newIdx << " point attributes on "
Ken Martin's avatar
Ken Martin committed
276
277
  << dim << "-D dataset\n\tDimensions are (" << outDims[0]
  << "," << outDims[1] << "," << outDims[2] <<")");
278
279
280
}


281
//-----------------------------------------------------------------------------
282
void vtkExtractVOI::PrintSelf(ostream& os, vtkIndent indent)
283
{
Brad King's avatar
Brad King committed
284
  this->Superclass::PrintSelf(os,indent);
285
286

  os << indent << "VOI: \n";
287
288
289
290
291
292
  os << indent << "  Imin,Imax: (" << this->VOI[0] 
     << ", " << this->VOI[1] << ")\n";
  os << indent << "  Jmin,Jmax: (" << this->VOI[2] 
     << ", " << this->VOI[3] << ")\n";
  os << indent << "  Kmin,Kmax: (" << this->VOI[4] 
     << ", " << this->VOI[5] << ")\n";
293
294
295
296
297
298
299

  os << indent << "Sample Rate: (" << this->SampleRate[0] << ", "
               << this->SampleRate[1] << ", "
               << this->SampleRate[2] << ")\n";
}


300
301