Salome HOME
f3f7652090b2e19f6fa5db286d503b66f93f5386
[modules/visu.git] / src / CONVERTOR / VISU_GaussMergeFilter.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 //  SALOME VTKViewer : build VTK viewer into Salome desktop
21 //  File   : 
22 //  Author : 
23 //  Module : SALOME
24 //  $Header$
25 //
26 #include "VISU_GaussMergeFilter.hxx"
27 #include "VISU_MergeFilterUtilities.hxx"
28
29 #include <vtkObjectFactory.h>
30 #include <vtkUnstructuredGrid.h>
31 #include <vtkPolyData.h>
32 #include <vtkCellData.h>
33 #include <vtkPointData.h>
34 #include <vtkIdList.h>
35 #include <vtkCell.h>
36 #include <vtkFloatArray.h>
37
38 #include <vtkExecutive.h>
39 #include <vtkInformation.h>
40 #include <vtkInformationVector.h>
41 #include <vtkStreamingDemandDrivenPipeline.h>
42
43
44 //------------------------------------------------------------------------------
45 vtkStandardNewMacro(VISU_GaussMergeFilter);
46
47 //------------------------------------------------------------------------------
48 VISU_GaussMergeFilter
49 ::VISU_GaussMergeFilter():
50   myIsMergingInputs(false)
51 {
52   this->FieldList = new VISU::TFieldList;
53   this->SetNumberOfInputPorts(6);
54 }
55
56 //------------------------------------------------------------------------------
57 VISU_GaussMergeFilter::~VISU_GaussMergeFilter()
58 {
59   delete this->FieldList;
60 }
61
62 //------------------------------------------------------------------------------
63 void VISU_GaussMergeFilter::SetGeometryConnection(vtkAlgorithmOutput *input)
64 {
65   this->Superclass::SetInputConnection(input);
66 }
67
68 //------------------------------------------------------------------------------
69 void VISU_GaussMergeFilter::SetGeometryData(vtkDataSet *input)
70 {
71   this->Superclass::SetInputData(input);
72 }
73
74 //------------------------------------------------------------------------------
75 void VISU_GaussMergeFilter::SetScalarsData(vtkDataSet *input)
76 {
77   this->SetInputData(1, input);
78 }
79
80 //------------------------------------------------------------------------------
81 void VISU_GaussMergeFilter::SetScalarsConnection(vtkAlgorithmOutput *input)
82 {
83   this->SetInputConnection(1, input);
84 }
85
86 //------------------------------------------------------------------------------
87 void VISU_GaussMergeFilter::SetVectorsData(vtkDataSet *input)
88 {
89   this->SetInputData(2, input);
90 }
91
92 //------------------------------------------------------------------------------
93 void VISU_GaussMergeFilter::SetVectorsConnection(vtkAlgorithmOutput *input)
94 {
95   this->SetInputConnection(2, input);
96 }
97
98 //------------------------------------------------------------------------------
99 void VISU_GaussMergeFilter::SetNormals(vtkAlgorithmOutput *input)
100 {
101   this->SetInputConnection(3, input);
102 }
103
104 //------------------------------------------------------------------------------
105 void VISU_GaussMergeFilter::SetTCoords(vtkAlgorithmOutput *input)
106 {
107   this->SetInputConnection(4, input);
108 }
109
110 //------------------------------------------------------------------------------
111 void VISU_GaussMergeFilter::SetTensors(vtkAlgorithmOutput *input)
112 {
113   this->SetInputConnection(5, input);
114 }
115
116 //------------------------------------------------------------------------------
117 void VISU_GaussMergeFilter::AddField(const char* name, vtkDataSet* input)
118 {
119   this->FieldList->Add(name, input);
120 }
121
122 //------------------------------------------------------------------------------
123 void VISU_GaussMergeFilter::RemoveFields()
124 {
125   delete this->FieldList;
126   this->FieldList = new VISU::TFieldList;
127 }
128
129
130 //---------------------------------------------------------------
131 void
132 VISU_GaussMergeFilter
133 ::SetMergingInputs(bool theIsMergingInputs)
134 {
135   if(myIsMergingInputs == theIsMergingInputs)
136     return;
137
138   myIsMergingInputs = theIsMergingInputs;
139   Modified();
140 }
141
142   
143 //---------------------------------------------------------------
144 bool
145 VISU_GaussMergeFilter
146 ::IsMergingInputs()
147 {
148   return myIsMergingInputs;
149 }
150   
151
152 //---------------------------------------------------------------
153 int
154 VISU_GaussMergeFilter
155 ::RequestData(vtkInformation *theRequest,
156               vtkInformationVector **theInputVector,
157               vtkInformationVector *theOutputVector)
158 {
159   vtkInformation *inInfo0 = theInputVector[0]->GetInformationObject(0);
160   vtkInformation *inInfo1 = theInputVector[1]->GetInformationObject(0);
161   vtkInformation *outInfo = theOutputVector->GetInformationObject(0);
162
163   // get the input and output
164   vtkDataSet *anInput = vtkDataSet::SafeDownCast(inInfo0->Get(vtkDataObject::DATA_OBJECT()));
165   vtkDataSet *aScalars = theInputVector[1]->GetNumberOfInformationObjects() > 0 ?
166     vtkDataSet::SafeDownCast(inInfo1->Get(vtkDataObject::DATA_OBJECT())) : NULL;
167   vtkDataSet *anOutput = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
168
169   if(vtkUnstructuredGrid *anInputUG = dynamic_cast<vtkUnstructuredGrid*>(this->GetInput())){
170     vtkPolyData *anOutputPD = dynamic_cast<vtkPolyData*>(this->GetOutput());
171     return ExecuteGauss(anInputUG,
172                         aScalars,
173                         anOutputPD);
174   }
175
176   return Superclass::RequestData(theRequest,
177                                  theInputVector,
178                                  theOutputVector);
179 }
180
181 //----------------------------------------------------------------------------
182 //  Trick:  Abstract data types that may or may not be the same type
183 // (structured/unstructured), but the points/cells match up.
184 // Output/Geometry may be structured while ScalarInput may be 
185 // unstructured (but really have same triagulation/topology as geometry).
186 // Just request all the input. Always generate all of the output (todo).
187 int
188 VISU_GaussMergeFilter
189 ::RequestUpdateExtent(vtkInformation *vtkNotUsed(request),
190                       vtkInformationVector **inputVector,
191                       vtkInformationVector *vtkNotUsed(outputVector))
192 {
193   vtkInformation *inputInfo;
194   int idx;
195   
196   for (idx = 0; idx < 6; ++idx)
197     {
198     inputInfo = inputVector[idx]->GetInformationObject(0);
199     if (inputInfo)
200       {
201       inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
202                      0);
203       inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
204                      1);
205       inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
206                      0);
207       inputInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
208       }
209     }
210   return 1;
211 }
212
213
214 //----------------------------------------------------------------------------
215 int
216 VISU_GaussMergeFilter
217 ::FillInputPortInformation(int port, vtkInformation *info)
218 {
219   int retval = this->Superclass::FillInputPortInformation(port, info);
220   if (port > 0)
221     {
222     info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
223     }
224   return retval;
225 }
226
227 //----------------------------------------------------------------------------
228 int
229 VISU_GaussMergeFilter
230 ::FillOutputPortInformation(int port, vtkInformation *info)
231 {
232  info->Set(vtkDataObject::DATA_TYPE_NAME(),"vtkPolyData");
233  return 1;
234 }
235
236 void
237 VISU_GaussMergeFilter
238 ::SetGaussPtsIDMapper(const VISU::PGaussPtsIDMapper& theIDMapper)
239 {
240   myGaussPtsIDMapper = theIDMapper;
241 }
242
243
244 const VISU::PGaussPtsIDMapper&  
245 VISU_GaussMergeFilter
246 ::GetGaussPtsIDMapper()
247 {
248   return myGaussPtsIDMapper;
249 }
250
251 bool 
252 VISU_GaussMergeFilter
253 ::ExecuteGauss(vtkUnstructuredGrid* theInput,
254                vtkDataSet*          theScalarsDataSet,
255                vtkPolyData*         theOutput)
256 {
257   if(IsMergingInputs()){
258     vtkCellData *aCellData = theInput->GetCellData();
259     if(vtkDataArray *aCellMapper = aCellData->GetArray("VISU_CELLS_MAPPER")){
260       vtkIntArray *aGeometryCellMapper = dynamic_cast<vtkIntArray*>(aCellMapper);
261       
262       vtkIntArray* aDataPointMapper = GetIDMapper(FieldList,
263                                                   VISU::TGetPointData(),
264                                                   "VISU_POINTS_MAPPER");
265
266       vtkIntArray* aDataCellIds = vtkIntArray::New();
267
268       int nbPoints = aDataPointMapper->GetNumberOfTuples();
269       aDataCellIds->SetNumberOfComponents(2);
270       aDataCellIds->SetNumberOfTuples(nbPoints);
271       int* aDataCellPointer = aDataCellIds->GetPointer(0);
272       {
273         int nbPoints = aDataPointMapper->GetNumberOfTuples();
274         for(int i=0;i<nbPoints;i++,aDataCellPointer++){
275           VISU::TGaussPointID aGPID = myGaussPtsIDMapper->GetObjID(i);
276           vtkIdType aCellId = aGPID.first;
277           *aDataCellPointer = aCellId;
278           aDataCellPointer++;
279           *aDataCellPointer = 3; // it's a entity CELL
280         }
281       }
282       /*
283       vtkIntArray* anCellArr = GetIDMapper(FieldList,
284                                            VISU::TGetCellData(),
285                                            "VISU_CELLS_MAPPER");
286       vtkIntArray* anPMArr = GetIDMapper(FieldList,
287                                          VISU::TGetPointData(),
288                                          "VISU_POINTS_MAPPER");
289
290       vtkDataArray* anFArr = GetIDMapper(FieldList,
291                                          VISU::TGetPointData(),
292                                          "VISU_FIELD");
293       */
294       if(VISU::IsDifferent(aDataCellIds, aGeometryCellMapper)){
295         VISU::TObjectIdArray anIntersection;
296         VISU::GetIntersection(aDataCellIds,
297                               aGeometryCellMapper,
298                               anIntersection);
299
300         VISU::TObjectId2TupleGaussIdMap aDataCellId2TupleGaussIdMap;
301         VISU::GetObjectId2TupleGaussIdArray(aDataCellIds, aDataCellId2TupleGaussIdMap);
302
303         vtkIdType aNbTuples = 0;
304         for(vtkIdType i = 0;i < anIntersection.size();i++)
305           aNbTuples += aDataCellId2TupleGaussIdMap[anIntersection[i].first].size();
306         
307         vtkPointSet* aScalarsDataSet = dynamic_cast<vtkPointSet*>(theScalarsDataSet);
308         vtkPoints* aDataPoints = aScalarsDataSet->GetPoints();
309         vtkPoints* anOutputPoints = vtkPoints::New(aDataPoints->GetDataType());
310         
311         anOutputPoints->SetNumberOfPoints(aNbTuples);
312         theOutput->SetPoints(anOutputPoints);
313         anOutputPoints->Delete();
314         
315         vtkCellData*   anInputCellData  = aScalarsDataSet->GetCellData();
316         vtkPointData* anInputPointData = aScalarsDataSet->GetPointData();
317
318         theOutput->Allocate(aNbTuples);
319         vtkCellData*  anOutputCellData  = theOutput->GetCellData();
320         vtkPointData* anOutputPointData = theOutput->GetPointData();
321
322         anOutputCellData->CopyAllocate(anInputCellData,aNbTuples);
323         anOutputPointData->CopyAllocate(anInputPointData,aNbTuples);
324         
325         vtkIdList *aCellIds = vtkIdList::New();
326         double aCoords[3];
327         for(int aTupleId=0, aNewTupleId=0; aTupleId<anIntersection.size(); aTupleId++){
328           VISU::TObjectId& anObjectId = anIntersection[aTupleId];
329           VISU::TCellIdArray aCellIdArray = aDataCellId2TupleGaussIdMap[anObjectId.first];
330           
331           for(vtkIdType i = 0; i < aCellIdArray.size();i++) {
332             vtkIdType aCellId = aCellIdArray[i];
333             vtkCell *aCell = theScalarsDataSet->GetCell(aCellId);
334             
335             aCellIds->Reset();
336             aCellIds->InsertNextId(aNewTupleId);
337             aNewTupleId++;
338           
339             vtkIdType aCellType = theScalarsDataSet->GetCellType(aCellId);
340             vtkIdType aNewCellId = theOutput->InsertNextCell(aCellType, aCellIds);
341           
342             anOutputCellData->CopyData(anInputCellData, aCellId, aNewCellId);
343             anOutputPointData->CopyData(anInputPointData, aCellId, aNewCellId);
344
345             aDataPoints->GetPoint(aCellId, aCoords);
346             anOutputPoints->SetPoint(aNewCellId, aCoords);
347           }
348         }
349       }
350     }
351   }
352   return true;
353 }