Salome HOME
5314405a94aa52f3a118ed8f7a2a963d9d3464f5
[modules/visu.git] / src / CONVERTOR / VISU_GaussMergeFilter.cxx
1 // Copyright (C) 2007-2011  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::SetGeometry(vtkDataSet *input)
64 {
65   this->Superclass::SetInput(input);
66 }
67
68 //------------------------------------------------------------------------------
69 vtkDataSet *VISU_GaussMergeFilter::GetGeometry()
70 {
71   if (this->GetNumberOfInputConnections(0) < 1)
72     {
73     return NULL;
74     }
75   return vtkDataSet::SafeDownCast(
76     this->GetExecutive()->GetInputData(0, 0));
77 }
78
79 //------------------------------------------------------------------------------
80 void VISU_GaussMergeFilter::SetScalars(vtkDataSet *input)
81 {
82   this->SetInput(1, input);
83 }
84
85 //------------------------------------------------------------------------------
86 vtkDataSet *VISU_GaussMergeFilter::GetScalars()
87 {
88   if (this->GetNumberOfInputConnections(1) < 1)
89     {
90     return NULL;
91     }
92   return vtkDataSet::SafeDownCast(
93     this->GetExecutive()->GetInputData(1, 0));
94 }
95
96 //------------------------------------------------------------------------------
97 void VISU_GaussMergeFilter::SetVectors(vtkDataSet *input)
98 {
99   this->SetInput(2, input);
100 }
101
102 //------------------------------------------------------------------------------
103 vtkDataSet *VISU_GaussMergeFilter::GetVectors()
104 {
105   if (this->GetNumberOfInputConnections(2) < 1)
106     {
107     return NULL;
108     }
109   return vtkDataSet::SafeDownCast(
110     this->GetExecutive()->GetInputData(2, 0));
111 }
112
113 //------------------------------------------------------------------------------
114 void VISU_GaussMergeFilter::SetNormals(vtkDataSet *input)
115 {
116   this->SetInput(3, input);
117 }
118
119 //------------------------------------------------------------------------------
120 vtkDataSet *VISU_GaussMergeFilter::GetNormals()
121 {
122   if (this->GetNumberOfInputConnections(3) < 1)
123     {
124     return NULL;
125     }
126   return vtkDataSet::SafeDownCast(
127     this->GetExecutive()->GetInputData(3, 0));
128 }
129
130 //------------------------------------------------------------------------------
131 void VISU_GaussMergeFilter::SetTCoords(vtkDataSet *input)
132 {
133   this->SetInput(4, input);
134 }
135
136 //------------------------------------------------------------------------------
137 vtkDataSet *VISU_GaussMergeFilter::GetTCoords()
138 {
139   if (this->GetNumberOfInputConnections(4) < 1)
140     {
141     return NULL;
142     }
143   return vtkDataSet::SafeDownCast(
144     this->GetExecutive()->GetInputData(4, 0));
145 }
146
147 //------------------------------------------------------------------------------
148 void VISU_GaussMergeFilter::SetTensors(vtkDataSet *input)
149 {
150   this->SetInput(5, input);
151 }
152
153 //------------------------------------------------------------------------------
154 vtkDataSet *VISU_GaussMergeFilter::GetTensors()
155 {
156   if (this->GetNumberOfInputConnections(5) < 1)
157     {
158     return NULL;
159     }
160   return vtkDataSet::SafeDownCast(
161     this->GetExecutive()->GetInputData(5, 0));
162 }
163
164 //------------------------------------------------------------------------------
165 void VISU_GaussMergeFilter::AddField(const char* name, vtkDataSet* input)
166 {
167   this->FieldList->Add(name, input);
168 }
169
170 //------------------------------------------------------------------------------
171 void VISU_GaussMergeFilter::RemoveFields()
172 {
173   delete this->FieldList;
174   this->FieldList = new VISU::TFieldList;
175 }
176
177
178 //---------------------------------------------------------------
179 void
180 VISU_GaussMergeFilter
181 ::SetMergingInputs(bool theIsMergingInputs)
182 {
183   if(myIsMergingInputs == theIsMergingInputs)
184     return;
185
186   myIsMergingInputs = theIsMergingInputs;
187   Modified();
188 }
189
190   
191 //---------------------------------------------------------------
192 bool
193 VISU_GaussMergeFilter
194 ::IsMergingInputs()
195 {
196   return myIsMergingInputs;
197 }
198   
199
200 //---------------------------------------------------------------
201 int
202 VISU_GaussMergeFilter
203 ::RequestData(vtkInformation *theRequest,
204               vtkInformationVector **theInputVector,
205               vtkInformationVector *theOutputVector)
206 {
207   if(vtkUnstructuredGrid *anInput = dynamic_cast<vtkUnstructuredGrid*>(this->GetInput())){
208     vtkPolyData *anOutput = dynamic_cast<vtkPolyData*>(this->GetOutput());
209     return ExecuteGauss(anInput,
210                         anOutput);
211   }
212
213   return Superclass::RequestData(theRequest,
214                                  theInputVector,
215                                  theOutputVector);
216 }
217
218 //----------------------------------------------------------------------------
219 //  Trick:  Abstract data types that may or may not be the same type
220 // (structured/unstructured), but the points/cells match up.
221 // Output/Geometry may be structured while ScalarInput may be 
222 // unstructured (but really have same triagulation/topology as geometry).
223 // Just request all the input. Always generate all of the output (todo).
224 int
225 VISU_GaussMergeFilter
226 ::RequestUpdateExtent(vtkInformation *vtkNotUsed(request),
227                       vtkInformationVector **inputVector,
228                       vtkInformationVector *vtkNotUsed(outputVector))
229 {
230   vtkInformation *inputInfo;
231   int idx;
232   
233   for (idx = 0; idx < 6; ++idx)
234     {
235     inputInfo = inputVector[idx]->GetInformationObject(0);
236     if (inputInfo)
237       {
238       inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
239                      0);
240       inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
241                      1);
242       inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
243                      0);
244       inputInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
245       }
246     }
247   return 1;
248 }
249
250
251 //----------------------------------------------------------------------------
252 int
253 VISU_GaussMergeFilter
254 ::FillInputPortInformation(int port, vtkInformation *info)
255 {
256   int retval = this->Superclass::FillInputPortInformation(port, info);
257   if (port > 0)
258     {
259     info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
260     }
261   return retval;
262 }
263
264 //----------------------------------------------------------------------------
265 int
266 VISU_GaussMergeFilter
267 ::FillOutputPortInformation(int port, vtkInformation *info)
268 {
269  info->Set(vtkDataObject::DATA_TYPE_NAME(),"vtkPolyData");
270  return 1;
271 }
272
273 void
274 VISU_GaussMergeFilter
275 ::SetGaussPtsIDMapper(const VISU::PGaussPtsIDMapper& theIDMapper)
276 {
277   myGaussPtsIDMapper = theIDMapper;
278 }
279
280
281 const VISU::PGaussPtsIDMapper&  
282 VISU_GaussMergeFilter
283 ::GetGaussPtsIDMapper()
284 {
285   return myGaussPtsIDMapper;
286 }
287
288 bool 
289 VISU_GaussMergeFilter
290 ::ExecuteGauss(vtkUnstructuredGrid* theInput,
291                vtkPolyData*         theOutput)
292 {
293   if(IsMergingInputs()){
294     vtkCellData *aCellData = theInput->GetCellData();
295     if(vtkDataArray *aCellMapper = aCellData->GetArray("VISU_CELLS_MAPPER")){
296       vtkIntArray *aGeometryCellMapper = dynamic_cast<vtkIntArray*>(aCellMapper);
297       
298       vtkIntArray* aDataPointMapper = GetIDMapper(FieldList,
299                                                   VISU::TGetPointData(),
300                                                   "VISU_POINTS_MAPPER");
301
302       vtkIntArray* aDataCellIds = vtkIntArray::New();
303
304       int nbPoints = aDataPointMapper->GetNumberOfTuples();
305       aDataCellIds->SetNumberOfComponents(2);
306       aDataCellIds->SetNumberOfTuples(nbPoints);
307       int* aDataCellPointer = aDataCellIds->GetPointer(0);
308       {
309         int nbPoints = aDataPointMapper->GetNumberOfTuples();
310         for(int i=0;i<nbPoints;i++,aDataCellPointer++){
311           VISU::TGaussPointID aGPID = myGaussPtsIDMapper->GetObjID(i);
312           vtkIdType aCellId = aGPID.first;
313           *aDataCellPointer = aCellId;
314           aDataCellPointer++;
315           *aDataCellPointer = 3; // it's a entity CELL
316         }
317       }
318       /*
319       vtkIntArray* anCellArr = GetIDMapper(FieldList,
320                                            VISU::TGetCellData(),
321                                            "VISU_CELLS_MAPPER");
322       vtkIntArray* anPMArr = GetIDMapper(FieldList,
323                                          VISU::TGetPointData(),
324                                          "VISU_POINTS_MAPPER");
325
326       vtkDataArray* anFArr = GetIDMapper(FieldList,
327                                          VISU::TGetPointData(),
328                                          "VISU_FIELD");
329       */
330       if(VISU::IsDifferent(aDataCellIds, aGeometryCellMapper)){
331         VISU::TObjectIdArray anIntersection;
332         VISU::GetIntersection(aDataCellIds,
333                               aGeometryCellMapper,
334                               anIntersection);
335
336         VISU::TObjectId2TupleGaussIdMap aDataCellId2TupleGaussIdMap;
337         VISU::GetObjectId2TupleGaussIdArray(aDataCellIds, aDataCellId2TupleGaussIdMap);
338
339         vtkIdType aNbTuples = 0;
340         for(vtkIdType i = 0;i < anIntersection.size();i++)
341           aNbTuples += aDataCellId2TupleGaussIdMap[anIntersection[i].first].size();
342         
343         vtkPointSet* aScalarsDataSet = dynamic_cast<vtkPointSet*>(GetScalars());
344         vtkPoints* aDataPoints = aScalarsDataSet->GetPoints();
345         vtkPoints* anOutputPoints = vtkPoints::New(aDataPoints->GetDataType());
346         
347         anOutputPoints->SetNumberOfPoints(aNbTuples);
348         theOutput->SetPoints(anOutputPoints);
349         anOutputPoints->Delete();
350         
351         vtkCellData*   anInputCellData  = aScalarsDataSet->GetCellData();
352         vtkPointData* anInputPointData = aScalarsDataSet->GetPointData();
353
354         theOutput->Allocate(aNbTuples);
355         vtkCellData*  anOutputCellData  = theOutput->GetCellData();
356         vtkPointData* anOutputPointData = theOutput->GetPointData();
357
358         anOutputCellData->CopyAllocate(anInputCellData,aNbTuples);
359         anOutputPointData->CopyAllocate(anInputPointData,aNbTuples);
360         
361         vtkIdList *aCellIds = vtkIdList::New();
362         vtkFloatingPointType aCoords[3];
363         for(int aTupleId=0, aNewTupleId=0; aTupleId<anIntersection.size(); aTupleId++){
364           VISU::TObjectId& anObjectId = anIntersection[aTupleId];
365           VISU::TCellIdArray aCellIdArray = aDataCellId2TupleGaussIdMap[anObjectId.first];
366           
367           for(vtkIdType i = 0; i < aCellIdArray.size();i++) {
368             vtkIdType aCellId = aCellIdArray[i];
369             vtkCell *aCell = GetScalars()->GetCell(aCellId);
370             
371             aCellIds->Reset();
372             aCellIds->InsertNextId(aNewTupleId);
373             aNewTupleId++;
374           
375             vtkIdType aCellType = GetScalars()->GetCellType(aCellId);
376             vtkIdType aNewCellId = theOutput->InsertNextCell(aCellType, aCellIds);
377           
378             anOutputCellData->CopyData(anInputCellData, aCellId, aNewCellId);
379             anOutputPointData->CopyData(anInputPointData, aCellId, aNewCellId);
380
381             aDataPoints->GetPoint(aCellId, aCoords);
382             anOutputPoints->SetPoint(aNewCellId, aCoords);
383           }
384         }
385       }
386     }
387   }
388   return true;
389 }