1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkExtractDataOverTime.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 "vtkExtractDataOverTime.h"
16 
17 #include "vtkPointSet.h"
18 #include "vtkInformation.h"
19 #include "vtkInformationVector.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkPointData.h"
22 #include "vtkDoubleArray.h"
23 #include "vtkStreamingDemandDrivenPipeline.h"
24 
25 vtkStandardNewMacro(vtkExtractDataOverTime);
26 
27 //----------------------------------------------------------------------------
vtkExtractDataOverTime()28 vtkExtractDataOverTime::vtkExtractDataOverTime()
29 {
30   this->NumberOfTimeSteps = 0;
31   this->CurrentTimeIndex = 0;
32   this->PointIndex = 0;
33 
34 }
35 
36 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)37 void vtkExtractDataOverTime::PrintSelf(ostream& os, vtkIndent indent)
38 {
39   this->Superclass::PrintSelf(os,indent);
40 
41   os << indent << "Point Index: " << this->PointIndex << endl;
42   os << indent << "NumberOfTimeSteps: " << this->NumberOfTimeSteps << endl;
43 }
44 
45 
46 //----------------------------------------------------------------------------
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)47 int vtkExtractDataOverTime::RequestInformation(
48   vtkInformation* vtkNotUsed(request),
49   vtkInformationVector** inputVector,
50   vtkInformationVector* outputVector)
51 {
52   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
53   if ( inInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()) )
54     {
55     this->NumberOfTimeSteps =
56       inInfo->Length( vtkStreamingDemandDrivenPipeline::TIME_STEPS() );
57     }
58   else
59     {
60     this->NumberOfTimeSteps = 0;
61     }
62   // The output of this filter does not contain a specific time, rather
63   // it contains a collection of time steps. Also, this filter does not
64   // respond to time requests. Therefore, we remove all time information
65   // from the output.
66   vtkInformation* outInfo = outputVector->GetInformationObject(0);
67   if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_STEPS()))
68     {
69     outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
70     }
71   if (outInfo->Has(vtkStreamingDemandDrivenPipeline::TIME_RANGE()))
72     {
73     outInfo->Remove(vtkStreamingDemandDrivenPipeline::TIME_RANGE());
74     }
75 
76   return 1;
77 }
78 
79 
80 //----------------------------------------------------------------------------
ProcessRequest(vtkInformation * request,vtkInformationVector ** inputVector,vtkInformationVector * outputVector)81 int vtkExtractDataOverTime::ProcessRequest(vtkInformation* request,
82                                            vtkInformationVector** inputVector,
83                                            vtkInformationVector* outputVector)
84 {
85   if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
86     {
87     return this->RequestInformation(request, inputVector, outputVector);
88     }
89   else if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
90     {
91     // get the requested update extent
92     double *inTimes = inputVector[0]->GetInformationObject(0)
93       ->Get(vtkStreamingDemandDrivenPipeline::TIME_STEPS());
94     if (inTimes)
95       {
96       double timeReq = inTimes[this->CurrentTimeIndex];
97       inputVector[0]->GetInformationObject(0)->Set
98         ( vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP(),
99           timeReq);
100       }
101     return 1;
102     }
103 
104   // generate the data
105   else if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA()))
106     {
107     if (this->NumberOfTimeSteps == 0)
108       {
109       vtkErrorMacro("No Time steps in input time data!");
110       return 0;
111       }
112 
113     // get the output data object
114     vtkInformation* outInfo = outputVector->GetInformationObject(0);
115     vtkPointSet *output =
116       vtkPointSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
117 
118     // and input data object
119     vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
120     vtkPointSet *input =
121       vtkPointSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
122 
123     // is this the first request
124     if (!this->CurrentTimeIndex)
125       {
126       // Tell the pipeline to start looping.
127       request->Set(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING(), 1);
128       this->AllocateOutputData(input, output);
129       }
130 
131     // extract the actual data
132     output->GetPoints()->SetPoint( this->CurrentTimeIndex,
133       input->GetPoints()->GetPoint(this->PointIndex) );
134     output->GetPointData()->CopyData(input->GetPointData(), this->PointIndex,
135       this->CurrentTimeIndex);
136     if (input->GetPointData()->GetArray("Time"))
137       {
138       output->GetPointData()->GetArray("TimeData")->SetTuple1
139         (this->CurrentTimeIndex,
140          input->GetInformation()->Get(vtkDataObject::DATA_TIME_STEP()));
141       }
142     else
143       {
144       output->GetPointData()->GetArray("Time")->SetTuple1
145         (this->CurrentTimeIndex,
146          input->GetInformation()->Get(vtkDataObject::DATA_TIME_STEP()));
147       }
148 
149 
150     // increment the time index
151     this->CurrentTimeIndex++;
152     if (this->CurrentTimeIndex == this->NumberOfTimeSteps)
153       {
154       // Tell the pipeline to stop looping.
155       request->Remove(vtkStreamingDemandDrivenPipeline::CONTINUE_EXECUTING());
156       this->CurrentTimeIndex = 0;
157       }
158 
159     return 1;
160     }
161   return this->Superclass::ProcessRequest(request, inputVector, outputVector);
162 }
163 
164 //----------------------------------------------------------------------------
AllocateOutputData(vtkPointSet * input,vtkPointSet * output)165 int vtkExtractDataOverTime::AllocateOutputData(vtkPointSet *input, vtkPointSet *output)
166 {
167   // by default vtkPointSetAlgorithm::RequestDataObject already
168   // created an output of the same type as the input
169   if (!output)
170     {
171     vtkErrorMacro("Output not created as expected!");
172     return 0;
173     }
174 
175   // 1st the points
176   vtkPoints *points = output->GetPoints();
177   if (!points)
178     {
179     points = vtkPoints::New();
180     output->SetPoints( points );
181     points->Delete();
182     }
183   points->SetNumberOfPoints( this->NumberOfTimeSteps );
184 
185   // now the point data
186   output->GetPointData()->CopyAllocate(input->GetPointData(), this->NumberOfTimeSteps);
187 
188   // and finally add an array to hold the time at each step
189   vtkDoubleArray *timeArray = vtkDoubleArray::New();
190   timeArray->SetNumberOfComponents(1);
191   timeArray->SetNumberOfTuples(this->NumberOfTimeSteps);
192   if (input->GetPointData()->GetArray("Time"))
193     {
194     timeArray->SetName("TimeData");
195     }
196   else
197     {
198     timeArray->SetName("Time");
199     }
200   output->GetPointData()->AddArray(timeArray);
201   timeArray->Delete();
202 
203   return 1;
204 }
205 
206 
207