1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkImageClip.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkImageClip.h"
16 
17 #include "vtkAlgorithmOutput.h"
18 #include "vtkCellData.h"
19 #include "vtkImageData.h"
20 #include "vtkInformation.h"
21 #include "vtkInformationVector.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPointData.h"
24 #include "vtkStreamingDemandDrivenPipeline.h"
25 
26 vtkStandardNewMacro(vtkImageClip);
27 
28 //------------------------------------------------------------------------------
vtkImageClip()29 vtkImageClip::vtkImageClip()
30 {
31   this->ClipData = 0;
32   this->Initialized = 0;
33 
34   this->OutputWholeExtent[0] = this->OutputWholeExtent[2] = this->OutputWholeExtent[4] =
35     -VTK_INT_MAX;
36 
37   this->OutputWholeExtent[1] = this->OutputWholeExtent[3] = this->OutputWholeExtent[5] =
38     VTK_INT_MAX;
39 }
40 
41 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)42 void vtkImageClip::PrintSelf(ostream& os, vtkIndent indent)
43 {
44   this->Superclass::PrintSelf(os, indent);
45 
46   int idx;
47 
48   os << indent << "OutputWholeExtent: (" << this->OutputWholeExtent[0] << ","
49      << this->OutputWholeExtent[1];
50   for (idx = 1; idx < 3; ++idx)
51   {
52     os << indent << ", " << this->OutputWholeExtent[idx * 2] << ","
53        << this->OutputWholeExtent[idx * 2 + 1];
54   }
55   os << ")\n";
56   if (this->ClipData)
57   {
58     os << indent << "ClipDataOn\n";
59   }
60   else
61   {
62     os << indent << "ClipDataOff\n";
63   }
64 }
65 
66 //------------------------------------------------------------------------------
SetOutputWholeExtent(int extent[6],vtkInformation * outInfo)67 void vtkImageClip::SetOutputWholeExtent(int extent[6], vtkInformation* outInfo)
68 {
69   int idx;
70   int modified = 0;
71 
72   for (idx = 0; idx < 6; ++idx)
73   {
74     if (this->OutputWholeExtent[idx] != extent[idx])
75     {
76       this->OutputWholeExtent[idx] = extent[idx];
77       modified = 1;
78     }
79   }
80   this->Initialized = 1;
81   if (modified)
82   {
83     this->Modified();
84     if (!outInfo)
85     {
86       outInfo = this->GetExecutive()->GetOutputInformation(0);
87     }
88     outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent, 6);
89   }
90 }
91 
92 //------------------------------------------------------------------------------
SetOutputWholeExtent(int minX,int maxX,int minY,int maxY,int minZ,int maxZ)93 void vtkImageClip::SetOutputWholeExtent(int minX, int maxX, int minY, int maxY, int minZ, int maxZ)
94 {
95   int extent[6];
96 
97   extent[0] = minX;
98   extent[1] = maxX;
99   extent[2] = minY;
100   extent[3] = maxY;
101   extent[4] = minZ;
102   extent[5] = maxZ;
103   this->SetOutputWholeExtent(extent);
104 }
105 
106 //------------------------------------------------------------------------------
GetOutputWholeExtent(int extent[6])107 void vtkImageClip::GetOutputWholeExtent(int extent[6])
108 {
109   int idx;
110 
111   for (idx = 0; idx < 6; ++idx)
112   {
113     extent[idx] = this->OutputWholeExtent[idx];
114   }
115 }
116 
117 //------------------------------------------------------------------------------
118 // Change the WholeExtent
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)119 int vtkImageClip::RequestInformation(vtkInformation* vtkNotUsed(request),
120   vtkInformationVector** inputVector, vtkInformationVector* outputVector)
121 {
122   // get the info objects
123   vtkInformation* outInfo = outputVector->GetInformationObject(0);
124   vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
125 
126   int idx, extent[6];
127 
128   inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent);
129   if (!this->Initialized)
130   {
131     this->SetOutputWholeExtent(extent, outInfo);
132   }
133 
134   // Clip the OutputWholeExtent with the input WholeExtent
135   for (idx = 0; idx < 3; ++idx)
136   {
137     if (this->OutputWholeExtent[idx * 2] >= extent[idx * 2] &&
138       this->OutputWholeExtent[idx * 2] <= extent[idx * 2 + 1])
139     {
140       extent[idx * 2] = this->OutputWholeExtent[idx * 2];
141     }
142     if (this->OutputWholeExtent[idx * 2 + 1] >= extent[idx * 2] &&
143       this->OutputWholeExtent[idx * 2 + 1] <= extent[idx * 2 + 1])
144     {
145       extent[idx * 2 + 1] = this->OutputWholeExtent[idx * 2 + 1];
146     }
147     // make usre the order is correct
148     if (extent[idx * 2] > extent[idx * 2 + 1])
149     {
150       extent[idx * 2] = extent[idx * 2 + 1];
151     }
152   }
153 
154   outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent, 6);
155 
156   return 1;
157 }
158 
159 //------------------------------------------------------------------------------
160 // Sets the output whole extent to be the input whole extent.
ResetOutputWholeExtent()161 void vtkImageClip::ResetOutputWholeExtent()
162 {
163   if (!this->GetInput())
164   {
165     vtkWarningMacro("ResetOutputWholeExtent: No input");
166     return;
167   }
168 
169   this->GetInputConnection(0, 0)->GetProducer()->UpdateInformation();
170   vtkInformation* inInfo = this->GetExecutive()->GetInputInformation(0, 0);
171   this->SetOutputWholeExtent(inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));
172 }
173 
174 //------------------------------------------------------------------------------
175 // This method simply copies by reference the input data to the output.
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)176 int vtkImageClip::RequestData(vtkInformation* vtkNotUsed(request),
177   vtkInformationVector** inputVector, vtkInformationVector* outputVector)
178 {
179   int* inExt;
180   vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
181   vtkInformation* outInfo = outputVector->GetInformationObject(0);
182 
183   vtkImageData* outData = vtkImageData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
184   vtkImageData* inData = vtkImageData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
185 
186   inExt = inData->GetExtent();
187 
188   outData->SetExtent(inExt);
189   outData->GetPointData()->PassData(inData->GetPointData());
190   outData->GetCellData()->PassData(inData->GetCellData());
191 
192   if (this->ClipData)
193   {
194     outData->Crop(outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT()));
195   }
196 
197   return 1;
198 }
199