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