1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkRendererSource.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 "vtkRendererSource.h"
16
17 #include "vtkCommand.h"
18 #include "vtkFloatArray.h"
19 #include "vtkImageData.h"
20 #include "vtkInformation.h"
21 #include "vtkInformationVector.h"
22 #include "vtkMapper.h"
23 #include "vtkObjectFactory.h"
24 #include "vtkPointData.h"
25 #include "vtkRenderWindow.h"
26 #include "vtkRenderer.h"
27 #include "vtkStreamingDemandDrivenPipeline.h"
28 #include "vtkUnsignedCharArray.h"
29
30 vtkStandardNewMacro(vtkRendererSource);
31
32 vtkCxxSetObjectMacro(vtkRendererSource,Input,vtkRenderer);
33
vtkRendererSource()34 vtkRendererSource::vtkRendererSource()
35 {
36 this->Input = NULL;
37 this->WholeWindow = 0;
38 this->RenderFlag = 0;
39 this->DepthValues = 0;
40 this->DepthValuesInScalars = 0;
41
42 this->SetNumberOfInputPorts(0);
43 this->SetNumberOfOutputPorts(1);
44 }
45
46
~vtkRendererSource()47 vtkRendererSource::~vtkRendererSource()
48 {
49 if (this->Input)
50 {
51 this->Input->UnRegister(this);
52 this->Input = NULL;
53 }
54 }
55
RequestData(vtkInformation *,vtkInformationVector **,vtkInformationVector * outputVector)56 void vtkRendererSource::RequestData(vtkInformation*,
57 vtkInformationVector**,
58 vtkInformationVector* outputVector)
59 {
60 int numOutPts;
61 float x1,y1,x2,y2;
62 unsigned char *pixels, *ptr;
63 int dims[3];
64
65 vtkInformation* info = outputVector->GetInformationObject(0);
66 vtkImageData *output =
67 vtkImageData::SafeDownCast(info->Get(vtkDataObject::DATA_OBJECT()));
68 int uExtent[6];
69 info->Get(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(), uExtent);
70 output->SetExtent(uExtent);
71
72 output->AllocateScalars(info);
73 vtkUnsignedCharArray *outScalars =
74 vtkUnsignedCharArray::SafeDownCast(output->GetPointData()->GetScalars());
75
76 if (this->Input == NULL)
77 {
78 return;
79 }
80
81 if (this->DepthValuesInScalars)
82 {
83 outScalars->SetName("RGBValues");
84 }
85 else
86 {
87 outScalars->SetName("RGBZValues");
88 }
89 vtkRenderWindow *renWin;
90
91 vtkDebugMacro(<<"Converting points");
92
93 if (this->Input == NULL )
94 {
95 vtkErrorMacro(<<"Please specify a renderer as input!");
96 return;
97 }
98
99 renWin = this->Input->GetRenderWindow();
100 if (renWin == NULL)
101 {
102 return;
103 }
104
105 if (this->RenderFlag)
106 {
107 renWin->Render();
108 }
109
110 // calc the pixel range for the renderer
111 x1 = this->Input->GetViewport()[0]*
112 ((this->Input->GetRenderWindow())->GetSize()[0] - 1);
113 y1 = this->Input->GetViewport()[1]*
114 ((this->Input->GetRenderWindow())->GetSize()[1] - 1);
115 x2 = this->Input->GetViewport()[2]*
116 ((this->Input->GetRenderWindow())->GetSize()[0] - 1);
117 y2 = this->Input->GetViewport()[3]*
118 ((this->Input->GetRenderWindow())->GetSize()[1] - 1);
119
120 if (this->WholeWindow)
121 {
122 x1 = 0;
123 y1 = 0;
124 x2 = (this->Input->GetRenderWindow())->GetSize()[0] - 1;
125 y2 = (this->Input->GetRenderWindow())->GetSize()[1] - 1;
126 }
127
128 // Get origin, aspect ratio and dimensions from this->Input
129 dims[0] = static_cast<int>(x2 - x1 + 1);
130 dims[1] = static_cast<int>(y2 -y1 + 1);
131 dims[2] = 1;
132 output->SetDimensions(dims);
133
134 // Allocate data. Scalar type is FloatScalars.
135 numOutPts = dims[0] * dims[1];
136
137 pixels = (this->Input->GetRenderWindow())->GetPixelData(static_cast<int>(x1),
138 static_cast<int>(y1),
139 static_cast<int>(x2),
140 static_cast<int>(y2)
141 ,1);
142
143 // allocate scalars
144 int nb_comp = output->GetNumberOfScalarComponents();
145 ptr = outScalars->WritePointer(0, numOutPts * nb_comp);
146
147 // copy scalars over (if only RGB is requested, use the pixels directly)
148 if (!this->DepthValuesInScalars)
149 {
150 memcpy(ptr, pixels, numOutPts * nb_comp);
151 }
152
153 // Lets get the ZBuffer also, if requested.
154 if (this->DepthValues || this->DepthValuesInScalars)
155 {
156 float *zBuf = (this->Input->GetRenderWindow())->GetZbufferData(
157 static_cast<int>(x1),static_cast<int>(y1),static_cast<int>(x2),
158 static_cast<int>(y2));
159
160 // If RGBZ is requested, intermix RGB with shift/scaled Z
161 if (this->DepthValuesInScalars)
162 {
163 float *zptr = zBuf, *zptr_end = zBuf + numOutPts;
164 float min = *zBuf, max = *zBuf;
165 while (zptr < zptr_end)
166 {
167 if (min < *zptr) { min = *zptr; }
168 if (max > *zptr) { max = *zptr; }
169 zptr++;
170 }
171 float scale = 255.0 / (max - min);
172
173 zptr = zBuf;
174 unsigned char *ppixels = pixels;
175 while (zptr < zptr_end)
176 {
177 *ptr++ = *ppixels++;
178 *ptr++ = *ppixels++;
179 *ptr++ = *ppixels++;
180 *ptr++ = static_cast<unsigned char>((*zptr++ - min) * scale);
181 }
182 }
183
184 // If Z is requested as independent array, create it
185 if (this->DepthValues)
186 {
187 vtkFloatArray *zArray = vtkFloatArray::New();
188 zArray->Allocate(numOutPts);
189 zArray->SetNumberOfTuples(numOutPts);
190 float *zPtr = zArray->WritePointer(0, numOutPts);
191 memcpy(zPtr,zBuf,numOutPts*sizeof(float));
192 zArray->SetName("ZBuffer");
193 output->GetPointData()->AddArray(zArray);
194 zArray->Delete();
195 }
196
197 delete [] zBuf;
198 }
199
200 delete [] pixels;
201 }
202
PrintSelf(ostream & os,vtkIndent indent)203 void vtkRendererSource::PrintSelf(ostream& os, vtkIndent indent)
204 {
205 this->Superclass::PrintSelf(os,indent);
206
207 os << indent << "RenderFlag: " << (this->RenderFlag ? "On\n" : "Off\n");
208
209 if ( this->Input )
210 {
211 os << indent << "Input:\n";
212 this->Input->PrintSelf(os,indent.GetNextIndent());
213 }
214 else
215 {
216 os << indent << "Input: (none)\n";
217 }
218
219 os << indent << "Whole Window: " << (this->WholeWindow ? "On\n" : "Off\n");
220 os << indent << "Depth Values: " << (this->DepthValues ? "On\n" : "Off\n");
221 os << indent << "Depth Values In Scalars: " << (this->DepthValuesInScalars ? "On\n" : "Off\n");
222 }
223
224
GetMTime()225 unsigned long vtkRendererSource::GetMTime()
226 {
227 vtkRenderer *ren = this->GetInput();
228 unsigned long t1 = this->MTime.GetMTime();
229 unsigned long t2;
230
231 if (!ren)
232 {
233 return t1;
234 }
235
236 // Update information on the input and
237 // compute information that is general to vtkDataObject.
238 t2 = ren->GetMTime();
239 if (t2 > t1)
240 {
241 t1 = t2;
242 }
243 vtkActorCollection *actors = ren->GetActors();
244 vtkCollectionSimpleIterator ait;
245 actors->InitTraversal(ait);
246 vtkActor *actor;
247 vtkMapper *mapper;
248 vtkDataSet *data;
249 while ( (actor = actors->GetNextActor(ait)) )
250 {
251 t2 = actor->GetMTime();
252 if (t2 > t1)
253 {
254 t1 = t2;
255 }
256 mapper = actor->GetMapper();
257 if (mapper)
258 {
259 t2 = mapper->GetMTime();
260 if (t2 > t1)
261 {
262 t1 = t2;
263 }
264 data = mapper->GetInput();
265 if (data)
266 {
267 mapper->GetInputAlgorithm()->UpdateInformation();
268 t2 = data->GetMTime();
269 if (t2 > t1)
270 {
271 t1 = t2;
272 }
273 }
274 t2 = vtkDemandDrivenPipeline::SafeDownCast(
275 mapper->GetInputExecutive())->GetPipelineMTime();
276 if (t2 > t1)
277 {
278 t1 = t2;
279 }
280 }
281 }
282
283 return t1;
284 }
285
286
287 //----------------------------------------------------------------------------
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * outputVector)288 void vtkRendererSource::RequestInformation (
289 vtkInformation * vtkNotUsed(request),
290 vtkInformationVector** vtkNotUsed( inputVector ),
291 vtkInformationVector *outputVector)
292 {
293 vtkRenderer *ren = this->GetInput();
294 if (ren == NULL || ren->GetRenderWindow() == NULL)
295 {
296 vtkErrorMacro("The input renderer has not been set yet!!!");
297 return;
298 }
299
300 // calc the pixel range for the renderer
301 float x1,y1,x2,y2;
302 x1 = ren->GetViewport()[0] * ((ren->GetRenderWindow())->GetSize()[0] - 1);
303 y1 = ren->GetViewport()[1] * ((ren->GetRenderWindow())->GetSize()[1] - 1);
304 x2 = ren->GetViewport()[2] * ((ren->GetRenderWindow())->GetSize()[0] - 1);
305 y2 = ren->GetViewport()[3] *((ren->GetRenderWindow())->GetSize()[1] - 1);
306 if (this->WholeWindow)
307 {
308 x1 = 0;
309 y1 = 0;
310 x2 = (this->Input->GetRenderWindow())->GetSize()[0] - 1;
311 y2 = (this->Input->GetRenderWindow())->GetSize()[1] - 1;
312 }
313 int extent[6] = {0, static_cast<int>(x2-x1),
314 0, static_cast<int>(y2-y1),
315 0, 0};
316
317 // get the info objects
318 vtkInformation* outInfo = outputVector->GetInformationObject(0);
319
320 outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent, 6);
321
322 vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_UNSIGNED_CHAR,
323 3 + (this->DepthValuesInScalars ? 1:0));
324 }
325
326 //----------------------------------------------------------------------------
ProcessRequest(vtkInformation * request,vtkInformationVector ** inputVector,vtkInformationVector * outputVector)327 int vtkRendererSource::ProcessRequest(vtkInformation* request,
328 vtkInformationVector** inputVector,
329 vtkInformationVector* outputVector)
330 {
331 // generate the data
332 if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA()))
333 {
334 this->RequestData(request, inputVector, outputVector);
335 return 1;
336 }
337
338 // execute information
339 if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
340 {
341 this->RequestInformation(request, inputVector, outputVector);
342 return 1;
343 }
344
345 return this->Superclass::ProcessRequest(request, inputVector, outputVector);
346 }
347
348 //----------------------------------------------------------------------------
GetOutput()349 vtkImageData* vtkRendererSource::GetOutput()
350 {
351 return vtkImageData::SafeDownCast(this->GetOutputDataObject(0));
352 }
353
FillOutputPortInformation(int vtkNotUsed (port),vtkInformation * info)354 int vtkRendererSource::FillOutputPortInformation(
355 int vtkNotUsed(port), vtkInformation* info)
356 {
357 // now add our info
358 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkImageData");
359 return 1;
360 }
361