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