Salome HOME
PR: SMDS refactoring in progress
[modules/smesh.git] / src / OBJECT / SMESH_vtkPVUpdateSuppressor.cxx
1 /*=========================================================================
2
3   Program:   ParaView
4   Module:    $RCSfile$
5
6   Copyright (c) Kitware, Inc.
7   All rights reserved.
8   See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 "SMESH_vtkPVUpdateSuppressor.h"
16
17 #include "vtkAlgorithmOutput.h"
18 #include "vtkCollection.h"
19 #include "vtkCommand.h"
20 #include "vtkCompositeDataPipeline.h"
21 #include "vtkDataObject.h"
22 #include "vtkDemandDrivenPipeline.h"
23 #include "vtkInformation.h"
24 #include "vtkInformationDoubleVectorKey.h"
25 #include "vtkInformationExecutivePortKey.h"
26 #include "vtkInformationVector.h"
27 #include "vtkObjectFactory.h"
28 #include "vtkPolyData.h"
29 //#include "vtkProcessModule.h"
30 #include "vtkSmartPointer.h"
31 #include "vtkUnstructuredGrid.h"
32 //#include "vtkUpdateSuppressorPipeline.h"
33
34 #include <vtkstd/map>
35
36 #ifdef MYDEBUG
37 # define vtkMyDebug(x)\
38     cout << x;
39 #else
40 # define vtkMyDebug(x)
41 #endif
42
43 vtkCxxRevisionMacro(vtkPVUpdateSuppressor, "$Revision$");
44 vtkStandardNewMacro(vtkPVUpdateSuppressor);
45 //----------------------------------------------------------------------------
46 vtkPVUpdateSuppressor::vtkPVUpdateSuppressor()
47 {
48   this->UpdatePiece = 0;
49   this->UpdateNumberOfPieces = 1;
50
51   this->UpdateTime = 0.0;
52   this->UpdateTimeInitialized = false;
53
54
55   this->Enabled = 1;
56
57 //  vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
58 //
59 //  if (pm)
60 //    {
61 //    this->UpdateNumberOfPieces = pm->GetNumberOfLocalPartitions();
62 //    this->UpdatePiece = pm->GetPartitionId();
63 //    }
64 }
65
66 //----------------------------------------------------------------------------
67 vtkPVUpdateSuppressor::~vtkPVUpdateSuppressor()
68 {
69 }
70
71 //----------------------------------------------------------------------------
72 void vtkPVUpdateSuppressor::SetUpdateTime(double utime)
73 {
74   this->UpdateTimeInitialized = true;
75   if (this->UpdateTime != utime)
76     {
77     this->Modified();
78     this->UpdateTime = utime;
79     }
80 }
81
82 //----------------------------------------------------------------------------
83 void vtkPVUpdateSuppressor::SetEnabled(int enable)
84 {
85   if (this->Enabled == enable)
86     {
87     return;
88     }
89   this->Enabled = enable;
90   this->Modified();
91 //  vtkUpdateSuppressorPipeline* executive =
92 //    vtkUpdateSuppressorPipeline::SafeDownCast(this->GetExecutive());
93 //  if (executive)
94 //    {
95 //    executive->SetEnabled(enable);
96 //    }
97 }
98
99 //----------------------------------------------------------------------------
100 void vtkPVUpdateSuppressor::ForceUpdate()
101 {    
102   // Make sure that output type matches input type
103   this->UpdateInformation();
104
105   vtkDataObject *input = this->GetInput();
106   if (input == 0)
107     {
108     vtkErrorMacro("No valid input.");
109     return;
110     }
111   vtkDataObject *output = this->GetOutput();
112
113   // int fixme; // I do not like this hack.  How can we get rid of it?
114   // Assume the input is the collection filter.
115   // Client needs to modify the collection filter because it is not
116   // connected to a pipeline.
117   vtkAlgorithm *source = input->GetProducerPort()->GetProducer();
118   if (source &&
119       (source->IsA("vtkMPIMoveData") ||
120        source->IsA("vtkCollectPolyData") ||
121        source->IsA("vtkM2NDuplicate") ||
122        source->IsA("vtkM2NCollect") ||
123        source->IsA("vtkOrderedCompositeDistributor") || 
124        source->IsA("vtkClientServerMoveData")))
125     {
126     source->Modified();
127     }
128
129   vtkInformation* info = input->GetPipelineInformation();
130   vtkStreamingDemandDrivenPipeline* sddp = 
131     vtkStreamingDemandDrivenPipeline::SafeDownCast(
132       vtkExecutive::PRODUCER()->GetExecutive(info));
133   if (sddp)
134     {
135     sddp->SetUpdateExtent(info,
136                           this->UpdatePiece, 
137                           this->UpdateNumberOfPieces, 
138                           0);
139     }
140   else
141     {
142     input->SetUpdatePiece(this->UpdatePiece);
143     input->SetUpdateNumberOfPieces(this->UpdateNumberOfPieces);
144     input->SetUpdateGhostLevel(0);
145     }
146   vtkMyDebug("ForceUpdate ");
147   if (this->UpdateTimeInitialized)
148     {
149     info->Set(vtkCompositeDataPipeline::UPDATE_TIME_STEPS(), &this->UpdateTime, 1);
150     vtkMyDebug(this->UpdateTime);
151     }
152   vtkMyDebug(endl);
153
154   input->Update();
155   // Input may have changed, we obtain the pointer again.
156   input = this->GetInput();
157
158   output->ShallowCopy(input);
159   this->PipelineUpdateTime.Modified();
160 }
161
162
163 //----------------------------------------------------------------------------
164 vtkExecutive* vtkPVUpdateSuppressor::CreateDefaultExecutive()
165 {
166   vtkUpdateSuppressorPipeline* executive = vtkUpdateSuppressorPipeline::New();
167   executive->SetEnabled(this->Enabled);
168   return executive;
169 }
170
171 //----------------------------------------------------------------------------
172 int vtkPVUpdateSuppressor::RequestDataObject(
173   vtkInformation* vtkNotUsed(reqInfo), 
174   vtkInformationVector** inputVector , 
175   vtkInformationVector* outputVector)
176 {
177   vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
178   if (!inInfo)
179     {
180     return 0;
181     }
182   
183   vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT());
184   if (input)
185     {
186     // for each output
187     for(int i=0; i < this->GetNumberOfOutputPorts(); ++i)
188       {
189       vtkInformation* outInfo = outputVector->GetInformationObject(i);
190       vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT());
191     
192       if (!output || !output->IsA(input->GetClassName())) 
193         {
194         vtkDataObject* newOutput = input->NewInstance();
195         newOutput->SetPipelineInformation(outInfo);
196         newOutput->Delete();
197         this->GetOutputPortInformation(i)->Set(
198           vtkDataObject::DATA_EXTENT_TYPE(), newOutput->GetExtentType());
199         }
200       }
201     return 1;
202     }
203   return 0;
204
205 }
206
207 //----------------------------------------------------------------------------
208 int vtkPVUpdateSuppressor::RequestData(vtkInformation* vtkNotUsed(reqInfo),
209                                        vtkInformationVector** inputVector,
210                                        vtkInformationVector* outputVector)
211 {
212   // RequestData is only called by its executive when 
213   // (Enabled==off) and thus acting as a passthrough filter
214   vtkInformation *outInfo = outputVector->GetInformationObject(0);
215   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
216   vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT());
217   vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT());
218
219   output->ShallowCopy(input);
220   return 1;
221 }
222
223 //----------------------------------------------------------------------------
224 void vtkPVUpdateSuppressor::PrintSelf(ostream& os, vtkIndent indent)
225 {
226   this->Superclass::PrintSelf(os,indent);
227   os << indent << "UpdatePiece: " << this->UpdatePiece << endl;
228   os << indent << "UpdateNumberOfPieces: " << this->UpdateNumberOfPieces << endl;
229   os << indent << "Enabled: " << this->Enabled << endl;
230   os << indent << "UpdateTime: " << this->UpdateTime << endl;
231 }