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