Salome HOME
Compatibility CMake
[modules/visu.git] / src / CONVERTOR / VISU_MergeFilterUtilities.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_MergeFilterUtilities.hxx"
29
30 #include <vtkCellData.h>
31 #include <vtkObjectFactory.h>
32 #include <vtkPointData.h>
33 #include <vtkPolyData.h>
34 #include <vtkRectilinearGrid.h>
35 #include <vtkStructuredGrid.h>
36 #include <vtkStructuredPoints.h>
37 #include <vtkUnstructuredGrid.h>
38
39 #include <vtkIdList.h>
40 #include <vtkCell.h>
41
42 #include <algorithm>
43 #include <vector>
44 #include <set>
45 #include <map>
46
47 namespace
48 {
49
50   using namespace VISU;
51   
52   //---------------------------------------------------------------
53   template<class TDataSet>
54   
55   void 
56   CopyDataOnCells(TDataSet *theInput,
57                   vtkIntArray *theGeometryCellMapper,
58                   vtkIntArray *theDataCellMapper,
59                   vtkDataSet* theScalarsDataSet,
60                   vtkDataSet* theVectorsDataSet,
61                   vtkDataSet* theNormalsDataSet,
62                   vtkDataSet* theTCoordsDataSet,
63                   vtkDataSet* theTensorsDataSet,
64                   VISU::TFieldList* theFieldList,
65                   TDataSet *theOutput)
66   {
67     if(IsDifferent(theGeometryCellMapper, theDataCellMapper)){
68       TObjectIdArray anIntersection;
69       GetIntersection(theGeometryCellMapper,
70                       theDataCellMapper,
71                       anIntersection);
72     
73       TObjectId2TupleIdMap aGeomObjectId2TupleIdMap;
74       GetObjectId2TupleIdMap(theGeometryCellMapper, aGeomObjectId2TupleIdMap);
75       
76       TObjectId2TupleIdMap aDataObjectId2TupleIdMap;
77       GetObjectId2TupleIdMap(theDataCellMapper, aDataObjectId2TupleIdMap);
78       
79       vtkCellData *aCellData = theScalarsDataSet->GetCellData();
80       vtkCellData *anOutputCellData = theOutput->GetCellData();
81       anOutputCellData->CopyAllocate(aCellData);
82
83       if(theVectorsDataSet && theVectorsDataSet != theScalarsDataSet)
84         anOutputCellData->CopyVectorsOff();
85
86       vtkIdType aNbTuples = anIntersection.size();
87       theOutput->Allocate(aNbTuples);
88       vtkIdList *aCellIds = vtkIdList::New();
89       for(int aTupleId = 0; aTupleId < aNbTuples; aTupleId++){
90         TObjectId& anObjectId = anIntersection[aTupleId];
91         vtkIdType aCellId = aGeomObjectId2TupleIdMap[anObjectId];
92         vtkCell *aCell = theInput->GetCell(aCellId);
93         aCellIds->Reset();
94         vtkIdType aNbPointIds = aCell->PointIds->GetNumberOfIds();
95         for(vtkIdType anId = 0; anId < aNbPointIds; anId++)
96           aCellIds->InsertNextId(aCell->GetPointIds()->GetId(anId));
97         vtkIdType aCellType = theInput->GetCellType(aCellId);
98         vtkIdType aNewCellId = theOutput->InsertNextCell(aCellType, aCellIds);
99         vtkIdType aDataCellId = aDataObjectId2TupleIdMap[anObjectId];
100         anOutputCellData->CopyData(aCellData, aDataCellId, aNewCellId);
101       }
102       aCellIds->Delete();
103
104       theOutput->SetPoints(theInput->GetPoints());
105       
106     }else{
107       theOutput->CopyStructure(theInput);
108       theOutput->GetCellData()->ShallowCopy(theScalarsDataSet->GetCellData());
109     }
110     theOutput->GetPointData()->ShallowCopy(theInput->GetPointData());
111     
112     //If need, copy vectors data.
113     if(theVectorsDataSet && theVectorsDataSet != theScalarsDataSet){
114       bool isVectorsOnCells = theVectorsDataSet->GetCellData()->GetVectors() != NULL;
115       bool isVectorsDataOnPoints = theVectorsDataSet->GetPointData()->GetVectors() != NULL;
116       if(isVectorsOnCells) {
117         CopyVectorsOnCells(theVectorsDataSet,theOutput);
118       }
119       else if(isVectorsDataOnPoints){
120         CopyVectorsOnPoints(theVectorsDataSet,theOutput);
121       }
122     }
123   }
124   
125   void CopyVectorsOnCells(vtkDataSet *theVectorsDataSet,
126                           vtkDataSet *theOutput)
127   {
128     vtkDataArray *anInputVectors = theVectorsDataSet->GetCellData()->GetVectors();
129     vtkDataArray *anOutputVectors = vtkDataArray::CreateDataArray(anInputVectors->GetDataType());
130     
131     //Clear output vector data
132     theOutput->GetCellData()->SetVectors(NULL);
133     
134     //Copy vectors data
135     vtkIntArray* anOutputIDMapper = GetIDMapper(theOutput,
136                                                 TGetCellData(),
137                                                 "VISU_CELLS_MAPPER");
138     
139     vtkIntArray* anInputIDMapper = GetIDMapper(theVectorsDataSet,
140                                                TGetCellData(),
141                                                "VISU_CELLS_MAPPER");
142     
143     TObjectIdArray anIntersection;
144     GetIntersection(anOutputIDMapper,
145                     anInputIDMapper,
146                     anIntersection);
147
148     vtkIdType aNbTuples = anIntersection.size();
149     anOutputVectors->SetNumberOfComponents(anInputVectors->GetNumberOfComponents());
150     anOutputVectors->SetNumberOfTuples(aNbTuples);
151     theOutput->GetCellData()->SetVectors(anOutputVectors);
152     anOutputVectors->Delete();
153     
154     TObjectId2TupleIdMap anOutputObjectId2TupleIdMap;
155     GetObjectId2TupleIdMap(anOutputIDMapper, anOutputObjectId2TupleIdMap);
156     
157     TObjectId2TupleIdMap anInputObjectId2TupleIdMap;
158     GetObjectId2TupleIdMap(anInputIDMapper, anInputObjectId2TupleIdMap);
159
160     for(vtkIdType iTupleId = 0; iTupleId < aNbTuples; iTupleId++ ){
161       TObjectId &anObjectId = anIntersection[iTupleId];
162       vtkIdType anOutputCellId  = anOutputObjectId2TupleIdMap[anObjectId];
163       vtkIdType anInputCellId = anInputObjectId2TupleIdMap[anObjectId];
164       anOutputVectors->SetTuple(anOutputCellId,anInputVectors->GetTuple(anInputCellId));
165     }
166   }
167   
168   //---------------------------------------------------------------
169   template<class TDataSet>
170   void 
171   CopyDataOnPoints(TDataSet *theInput,
172                    vtkIntArray *theGeometryPointMapper,
173                    vtkIntArray *theDataPointMapper,
174                    vtkDataSet* theScalarsDataSet,
175                    vtkDataSet* theVectorsDataSet,
176                    vtkDataSet* theNormalsDataSet,
177                    vtkDataSet* theTCoordsDataSet,
178                    vtkDataSet* theTensorsDataSet,
179                    VISU::TFieldList* theFieldList,
180                    TDataSet *theOutput)
181   {
182     if(IsDifferent(theGeometryPointMapper, theDataPointMapper)){
183       TObjectId2TupleIdMap aDataObjectId2PointIdMap;
184       GetObjectId2TupleIdMap(theDataPointMapper, aDataObjectId2PointIdMap);
185
186       vtkCellData *aCellData = theInput->GetCellData();
187       vtkCellData *anOutputCellData = theOutput->GetCellData();
188       anOutputCellData->CopyAllocate(aCellData);
189
190       vtkIdList *aCellIds = vtkIdList::New();
191       int aNbCells = theInput->GetNumberOfCells();
192       theOutput->Allocate(aNbCells);
193       for(int aCellId = 0; aCellId < aNbCells; aCellId++){
194         aCellIds->Reset();
195         vtkCell *aCell = theInput->GetCell(aCellId);
196         vtkIdType aNbPointIds = aCell->PointIds->GetNumberOfIds();
197         for(vtkIdType anId = 0; anId < aNbPointIds; anId++){
198           vtkIdType aPointId = aCell->GetPointIds()->GetId(anId);
199           int* aPointer = theGeometryPointMapper->GetPointer(aPointId * 2);
200           TCellId aCellId = *aPointer;
201           TEntityId anEntityId = *(aPointer + 1);
202           TObjectId anObjectId(aCellId, anEntityId);
203           TObjectId2TupleIdMap::iterator anIter = aDataObjectId2PointIdMap.find(anObjectId);
204           if(anIter != aDataObjectId2PointIdMap.end()){
205             aPointId = anIter->second;
206             aCellIds->InsertNextId(aPointId);
207           }else
208             goto PASS_INSERT_NEXT_CELL;
209         }
210         {
211           vtkIdType aCellType = theInput->GetCellType(aCellId);
212           vtkIdType aNewCellId = theOutput->InsertNextCell(aCellType, aCellIds);
213           anOutputCellData->CopyData(aCellData, aCellId, aNewCellId);
214         }
215       PASS_INSERT_NEXT_CELL:
216         continue;
217       }
218       aCellIds->Delete();
219       
220       // Copy geometry points
221       // 1. Create vtkPoints instance of the same data type
222       vtkPointSet* aScalarsDataSet = dynamic_cast<vtkPointSet*>(theScalarsDataSet);
223       vtkPoints* anGeometryPoints = theInput->GetPoints();
224       vtkPoints* aDataPoints = aScalarsDataSet->GetPoints();
225       vtkPoints* anOutputPoints = vtkPoints::New(aDataPoints->GetDataType());
226       theOutput->SetPoints(anOutputPoints);
227       anOutputPoints->Delete();
228
229       // 2. Perform mapping of geometry points
230       TObjectId2TupleIdMap aGeomObjectId2TupleIdMap;
231       GetObjectId2TupleIdMap(theGeometryPointMapper, aGeomObjectId2TupleIdMap);
232
233       // 3. Loop over all data points
234       int aNbDataPoints = theDataPointMapper->GetNumberOfTuples();
235       anOutputPoints->SetNumberOfPoints(aNbDataPoints);
236       for(int aPointId = 0; aPointId < aNbDataPoints; aPointId++){
237         int* aPointer = theDataPointMapper->GetPointer(aPointId * 2);
238         TCellId aCellId = *aPointer;
239         TEntityId anEntityId = *(aPointer + 1);
240         TObjectId anObjectId(aCellId, anEntityId);
241         TObjectId2TupleIdMap::iterator anIter = aGeomObjectId2TupleIdMap.find(anObjectId);
242         if(anIter != aGeomObjectId2TupleIdMap.end()){
243           // If the point exists in the geometry put it to output
244           int aGeometryPointId = anIter->second;
245           vtkFloatingPointType aCoords[3];
246           anGeometryPoints->GetPoint(aGeometryPointId, aCoords);
247           anOutputPoints->SetPoint(aPointId, aCoords);
248         }else{
249           // If no, the point from data should be used
250           vtkFloatingPointType aCoords[3];
251           aDataPoints->GetPoint(aPointId, aCoords);
252           anOutputPoints->SetPoint(aPointId, aCoords);
253         }
254       }
255     }else{
256       theOutput->CopyStructure(theInput);
257       theOutput->GetCellData()->ShallowCopy(theInput->GetCellData());
258     }
259     theOutput->GetPointData()->ShallowCopy(theScalarsDataSet->GetPointData());
260     
261     //If need, copy vectors data.
262     if(theVectorsDataSet && theVectorsDataSet != theScalarsDataSet){
263       bool isVectorsOnCells = theVectorsDataSet->GetCellData()->GetVectors() != NULL;
264       bool isVectorsDataOnPoints = theVectorsDataSet->GetPointData()->GetVectors() != NULL;
265
266       //Merge cells if need
267       //rnv
268       if(!IsDifferent(theGeometryPointMapper, theDataPointMapper)){
269         vtkIntArray* theGeometryCellMapper = GetIDMapper(theVectorsDataSet,
270                                                          TGetCellData(),
271                                                          "VISU_CELLS_MAPPER");
272         
273         vtkIntArray* theDataCellMapper = GetIDMapper(theScalarsDataSet,
274                                                      TGetCellData(),
275                                                      "VISU_CELLS_MAPPER");
276         
277           
278         if(IsDifferent(theGeometryCellMapper, theDataCellMapper)){
279           TObjectIdArray anIntersection;
280           
281           GetIntersection(theGeometryCellMapper,
282                           theDataCellMapper,
283                           anIntersection);
284     
285           TObjectId2TupleIdMap aGeomObjectId2TupleIdMap;
286           GetObjectId2TupleIdMap(theGeometryCellMapper, aGeomObjectId2TupleIdMap);
287       
288           TObjectId2TupleIdMap aDataObjectId2TupleIdMap;
289           GetObjectId2TupleIdMap(theDataCellMapper, aDataObjectId2TupleIdMap);
290       
291           vtkCellData *aCellData = theScalarsDataSet->GetCellData();
292           vtkCellData *anOutputCellData = theOutput->GetCellData();
293           anOutputCellData->CopyAllocate(aCellData);
294
295           vtkIdType aNbTuples = anIntersection.size();
296           theOutput->Allocate(aNbTuples);
297           vtkIdList *aCellIds = vtkIdList::New();
298           for(int aTupleId = 0; aTupleId < aNbTuples; aTupleId++){
299             TObjectId& anObjectId = anIntersection[aTupleId];
300             vtkIdType aCellId = aGeomObjectId2TupleIdMap[anObjectId];
301             vtkCell *aCell = theInput->GetCell(aCellId);
302             aCellIds->Reset();
303             vtkIdType aNbPointIds = aCell->PointIds->GetNumberOfIds();
304             for(vtkIdType anId = 0; anId < aNbPointIds; anId++)
305               aCellIds->InsertNextId(aCell->GetPointIds()->GetId(anId));
306             vtkIdType aCellType = theInput->GetCellType(aCellId);
307             vtkIdType aNewCellId = theOutput->InsertNextCell(aCellType, aCellIds);
308             vtkIdType aDataCellId = aDataObjectId2TupleIdMap[anObjectId];
309             anOutputCellData->CopyData(aCellData, aDataCellId, aNewCellId);
310           }
311           aCellIds->Delete();
312           
313         }
314       }
315         
316       if(isVectorsOnCells) {
317         CopyVectorsOnCells(theVectorsDataSet,theOutput);
318       }
319       else if(isVectorsDataOnPoints){
320         CopyVectorsOnPoints(theVectorsDataSet,theOutput);
321       }
322     }
323   }
324   
325   void CopyVectorsOnPoints(vtkDataSet *theVectorsDataSet,
326                           vtkDataSet *theOutput)
327   {
328     vtkDataArray *anInputVectors = theVectorsDataSet->GetPointData()->GetVectors();
329     
330     //Clear output vector data
331     theOutput->GetPointData()->SetVectors(NULL);
332     
333     vtkDataArray *anOutputVectors = vtkDataArray::CreateDataArray(anInputVectors->GetDataType());
334     
335     //Copy vectors data
336     vtkIntArray* anOutputIDMapper = GetIDMapper(theOutput,
337                                                 TGetPointData(),
338                                                 "VISU_POINTS_MAPPER");
339     
340     vtkIntArray* anInputIDMapper = GetIDMapper(theVectorsDataSet,
341                                                TGetPointData(),
342                                                "VISU_POINTS_MAPPER");
343     TObjectIdArray anIntersection;
344
345     GetIntersection(anOutputIDMapper,
346                     anInputIDMapper,
347                     anIntersection);
348     
349     vtkIdType aNbTuples = anIntersection.size();  
350     anOutputVectors->SetNumberOfComponents(anInputVectors->GetNumberOfComponents());
351     anOutputVectors->SetNumberOfTuples(aNbTuples);
352     
353     
354
355     TObjectId2TupleIdMap anOutputObjectId2TupleIdMap;
356     GetObjectId2TupleIdMap(anOutputIDMapper, anOutputObjectId2TupleIdMap);
357     
358     TObjectId2TupleIdMap anInputObjectId2TupleIdMap;
359     GetObjectId2TupleIdMap(anInputIDMapper, anInputObjectId2TupleIdMap);
360     
361     for(vtkIdType iTupleId = 0; iTupleId < aNbTuples; iTupleId++ ){
362       TObjectId& anObjectId = anIntersection[iTupleId];
363       vtkIdType anOutputPointId  = anOutputObjectId2TupleIdMap[anObjectId];
364       vtkIdType anInputPointId = anInputObjectId2TupleIdMap[anObjectId];
365       anOutputVectors->SetTuple(anOutputPointId,anInputVectors->GetTuple(anInputPointId));
366     }
367     
368     theOutput->GetPointData()->SetVectors(anOutputVectors);
369     anOutputVectors->Delete();
370   }
371   
372
373   //---------------------------------------------------------------
374   typedef vtkDataArray* (vtkDataSetAttributes::* TGetAttribute)();
375   typedef int (vtkDataSetAttributes::* TSetAttribute)(vtkDataArray*);
376
377   inline
378   void
379   CopyArray(vtkDataArray* theDataArray,
380             vtkDataSetAttributes* theOutput, 
381             TSetAttribute theSetAttribute,
382             vtkIdType theFixedNbTuples)
383   {
384     if(theDataArray){
385       vtkIdType aNbTuples = theDataArray->GetNumberOfTuples();
386       if(theFixedNbTuples == aNbTuples)
387         (theOutput->*theSetAttribute)(theDataArray);
388     }
389   }
390
391
392   //---------------------------------------------------------------
393   inline
394   void
395   CopyAttribute(vtkDataSetAttributes* theInput, 
396                 TGetAttribute theGetAttribute,
397                 vtkDataSetAttributes* theOutput, 
398                 TSetAttribute theSetAttribute,
399                 vtkIdType theFixedNbTuples)
400   {
401     CopyArray((theInput->*theGetAttribute)(),
402               theOutput, theSetAttribute,
403               theFixedNbTuples);
404   }
405
406
407   //---------------------------------------------------------------
408   inline
409   void
410   CopyDataSetAttribute(vtkDataSet *theInput,
411                        TGetAttribute theGetAttribute,
412                        vtkDataSet *theOutput, 
413                        TSetAttribute theSetAttribute,
414                        vtkIdType theNbPoints, 
415                        vtkIdType theNbCells)
416   {
417     CopyAttribute(theInput->GetPointData(), 
418                   theGetAttribute,
419                   theOutput->GetPointData(), 
420                   theSetAttribute,
421                   theNbPoints);
422     CopyAttribute(theInput->GetCellData(), 
423                   theGetAttribute,
424                   theOutput->GetCellData(), 
425                   theSetAttribute,
426                   theNbCells);
427   }
428
429
430   //---------------------------------------------------------------
431   inline
432   void
433   CopyField(vtkDataSetAttributes* theInput, 
434             const char* theFieldName, 
435             vtkDataSetAttributes* theOutput,
436             vtkIdType theFixedNbTuples)
437   {
438     CopyArray(theInput->GetArray(theFieldName),
439               theOutput,
440               &vtkDataSetAttributes::AddArray,
441               theFixedNbTuples);
442   }
443
444
445   //---------------------------------------------------------------
446   inline
447   void
448   CopyDataSetField(vtkDataSet* theInput, 
449                    const char* theFieldName, 
450                    vtkDataSet* theOutput,
451                    vtkIdType theNbPoints, 
452                    vtkIdType theNbCells)
453   {
454     if(theInput){
455       CopyField(theInput->GetPointData(), 
456                 theFieldName, 
457                 theOutput->GetPointData(), 
458                 theNbPoints);
459       CopyField(theInput->GetCellData(), 
460                 theFieldName, 
461                 theOutput->GetCellData(), 
462                 theNbCells);
463     }
464   }
465
466   //---------------------------------------------------------------
467   void
468   BasicExecute(vtkDataSet *theInput,
469                vtkDataSet* theScalarsDataSet,
470                vtkDataSet* theVectorsDataSet,
471                vtkDataSet* theNormalsDataSet,
472                vtkDataSet* theTCoordsDataSet,
473                vtkDataSet* theTensorsDataSet,
474                VISU::TFieldList* theFieldList,
475                vtkDataSet *theOutput)
476   {
477     theOutput->CopyStructure(theInput);
478
479     vtkIdType aNbPoints = theInput->GetNumberOfPoints();
480     vtkIdType aNbCells = theInput->GetNumberOfCells();
481   
482     // merge data only if it is consistent
483     if(theScalarsDataSet)
484       CopyDataSetAttribute(theScalarsDataSet, 
485                            &vtkDataSetAttributes::GetScalars,
486                            theOutput,
487                            &vtkDataSetAttributes::SetScalars,
488                            aNbPoints,
489                            aNbCells);
490
491     if(theVectorsDataSet)
492       CopyDataSetAttribute(theVectorsDataSet, 
493                            &vtkDataSetAttributes::GetVectors,
494                            theOutput, 
495                            &vtkDataSetAttributes::SetVectors,
496                            aNbPoints, 
497                            aNbCells);
498
499     if(theNormalsDataSet)
500       CopyDataSetAttribute(theNormalsDataSet,
501                            &vtkDataSetAttributes::GetNormals,
502                            theOutput,
503                            &vtkDataSetAttributes::SetNormals,
504                            aNbPoints,
505                            aNbCells);
506
507     if(theTCoordsDataSet)
508       CopyDataSetAttribute(theTCoordsDataSet,
509                            &vtkDataSetAttributes::GetTCoords,
510                            theOutput,
511                            &vtkDataSetAttributes::SetTCoords,
512                            aNbPoints, 
513                            aNbCells);
514     
515     if(theTensorsDataSet)
516       CopyDataSetAttribute(theTensorsDataSet, 
517                            &vtkDataSetAttributes::GetTensors,
518                            theOutput, 
519                            &vtkDataSetAttributes::SetTensors,
520                            aNbPoints, 
521                            aNbCells);
522
523     VISU::TFieldListIterator anIter(theFieldList);
524     for(anIter.Begin(); !anIter.End() ; anIter.Next()){
525       vtkDataSet *aDataSet = anIter.Get()->Ptr;
526       const char* aFieldName = anIter.Get()->GetName();
527       CopyDataSetField(aDataSet, 
528                        aFieldName, 
529                        theOutput, 
530                        aNbPoints, 
531                        aNbCells);
532     }
533   }
534
535
536   //---------------------------------------------------------------
537   template<class TDataSet>
538   bool 
539   Execute(TDataSet *theInput,
540           vtkDataSet* theScalarsDataSet,
541           vtkDataSet* theVectorsDataSet,
542           vtkDataSet* theNormalsDataSet,
543           vtkDataSet* theTCoordsDataSet,
544           vtkDataSet* theTensorsDataSet,
545           VISU::TFieldList* theFieldList,
546           bool theIsMergingInputs,
547           TDataSet *theOutput)
548   {
549     if(theIsMergingInputs){
550       vtkCellData *aCellData = theInput->GetCellData();
551       if(vtkDataArray *aCellMapper = aCellData->GetArray("VISU_CELLS_MAPPER")){
552         bool anIsDataOnCells = false;
553         if(vtkDataSet* aDataSet = theScalarsDataSet)
554           if(vtkCellData* aCellData = aDataSet->GetCellData())
555             anIsDataOnCells = (aCellData->GetArray("VISU_FIELD") != NULL);
556         if(anIsDataOnCells){
557           vtkIntArray *aGeometryCellMapper = dynamic_cast<vtkIntArray*>(aCellMapper);
558           vtkIntArray* aDataCellMapper = GetIDMapper(theFieldList,
559                                                      TGetCellData(),
560                                                      "VISU_CELLS_MAPPER");
561           CopyDataOnCells(theInput,
562                           aGeometryCellMapper,
563                           aDataCellMapper,
564                           theScalarsDataSet,
565                           theVectorsDataSet,
566                           theNormalsDataSet,
567                           theTCoordsDataSet,
568                           theTensorsDataSet,
569                           theFieldList,
570                           theOutput);
571         }else{
572           vtkPointData *aPointData = theInput->GetPointData();
573           vtkDataArray *aPointMapper = aPointData->GetArray("VISU_POINTS_MAPPER");
574           vtkIntArray *aGeometryPointMapper = dynamic_cast<vtkIntArray*>(aPointMapper);
575           vtkIntArray* aDataPointMapper = GetIDMapper(theFieldList,
576                                                       TGetPointData(),
577                                                       "VISU_POINTS_MAPPER");
578           CopyDataOnPoints(theInput,
579                            aGeometryPointMapper,
580                            aDataPointMapper,
581                            theScalarsDataSet,
582                            theVectorsDataSet,
583                            theNormalsDataSet,
584                            theTCoordsDataSet,
585                            theTensorsDataSet,
586                            theFieldList,
587                            theOutput);
588         }
589       }
590     }else{
591       BasicExecute(theInput,
592                    theScalarsDataSet,
593                    theVectorsDataSet,
594                    theNormalsDataSet,
595                    theTCoordsDataSet,
596                    theTensorsDataSet,
597                    theFieldList,
598                    theOutput);
599     }
600     return true;
601   }
602 }
603
604 namespace VISU
605 {
606
607   //---------------------------------------------------------------
608   void
609   GetObjectIdSet(vtkIntArray *theArray, 
610                  TObjectIdSet& theObjectIdSet)
611   {
612     theObjectIdSet.clear();
613     int aMaxId = theArray->GetMaxId();
614     int* aPointer = theArray->GetPointer(0);
615     int* anEndPointer = theArray->GetPointer(aMaxId + 1);
616     for(; aPointer != anEndPointer; aPointer += 2){
617       TCellId aCellId = *aPointer;
618       TEntityId anEntityId = *(aPointer + 1);
619       TObjectId anObjectId(aCellId, anEntityId);
620       theObjectIdSet.insert(anObjectId);
621     }
622   }
623
624
625   //---------------------------------------------------------------
626   void
627   GetObjectId2TupleIdMap(vtkIntArray *theArray, 
628                         TObjectId2TupleIdMap& theObjectId2TupleIdMap)
629   {
630     theObjectId2TupleIdMap.clear();
631     int* aPointer = theArray->GetPointer(0);
632     int aNbTuples = theArray->GetNumberOfTuples();
633     for(vtkIdType aTupleId = 0; aTupleId < aNbTuples; aTupleId++, aPointer += 2){
634       TCellId aCellId = *aPointer;
635       TEntityId anEntityId = *(aPointer + 1);
636       TObjectId anObjectId(aCellId, anEntityId);
637       theObjectId2TupleIdMap[anObjectId] = aTupleId;
638     }
639   }
640
641   //---------------------------------------------------------------
642   void 
643   GetObjectId2TupleGaussIdArray(vtkIntArray *theArray, 
644                                 TObjectId2TupleGaussIdMap& theObjectId2TupleGaussIdMap)
645   {
646     theObjectId2TupleGaussIdMap.clear();
647     int* aPointer = theArray->GetPointer(0);
648     int aNbTuples = theArray->GetNumberOfTuples();
649     for(vtkIdType aTupleId = 0; aTupleId < aNbTuples; aTupleId++){
650       int aCellId = *aPointer;
651       TObjectId2TupleGaussIdMap::iterator it = theObjectId2TupleGaussIdMap.find(aCellId);
652       if(it == theObjectId2TupleGaussIdMap.end()){
653         TCellIdArray anIdArray;
654         anIdArray.push_back(aTupleId);
655         theObjectId2TupleGaussIdMap.insert(make_pair(aCellId,anIdArray));
656       }
657       else{
658         (*it).second.push_back(aTupleId);
659       }
660       aPointer += 2;
661     }
662   }
663   
664   //---------------------------------------------------------------
665   template<class TGetFieldData>
666   vtkIntArray*
667   GetIDMapper(VISU::TFieldList* theFieldList,
668               TGetFieldData theGetFieldData,
669               const char* theFieldName)
670   {
671     VISU::TFieldListIterator anIter(theFieldList);
672     for(anIter.Begin(); !anIter.End() ; anIter.Next()){
673       const char* aFieldName = anIter.Get()->GetName();
674       if(strcmp(aFieldName, theFieldName) == 0){
675         vtkDataSet* aDataSet = anIter.Get()->Ptr;
676         vtkFieldData *aFieldData = theGetFieldData(aDataSet);
677         vtkDataArray *anIDMapper = aFieldData->GetArray(theFieldName);
678         return dynamic_cast<vtkIntArray*>(anIDMapper);
679       }
680     }
681     return NULL;
682   }
683
684
685   //---------------------------------------------------------------
686   template<class TGetFieldData>
687   vtkIntArray*
688   GetIDMapper(vtkDataSet* theIDMapperDataSet,
689               TGetFieldData theGetFieldData,
690               const char* theFieldName)
691   {
692     vtkFieldData *aFieldData = theGetFieldData(theIDMapperDataSet);
693     vtkDataArray *anIDMapper = aFieldData->GetArray(theFieldName);
694     return dynamic_cast<vtkIntArray*>(anIDMapper);
695   }
696
697
698   //---------------------------------------------------------------
699   bool
700   IsDifferent(vtkIntArray *theFirstIDMapper,
701               vtkIntArray *theSecondIDMapper)
702   {
703     vtkIdType aFirstNbTuples = theFirstIDMapper->GetNumberOfTuples();
704     vtkIdType aSecondNbTuples = theSecondIDMapper->GetNumberOfTuples();
705     if(aFirstNbTuples != aSecondNbTuples)
706       return true;
707
708     int aMaxId = theFirstIDMapper->GetMaxId();
709     int* aFirstPointer = theFirstIDMapper->GetPointer(0);
710     int* aSecondPointer = theSecondIDMapper->GetPointer(0);
711     for(int anId = 0; anId <= aMaxId; anId++){
712       if(*aFirstPointer++ != *aSecondPointer++)
713         return true;
714     }
715     
716     return false;
717   }
718
719
720   //---------------------------------------------------------------
721   void
722   GetIntersection(vtkIntArray *theFirstIDMapper,
723                   vtkIntArray *theSecondIDMapper,
724                   TObjectIdArray& theResult)
725   {
726     TObjectIdSet aFirstObjectIdSet;
727     GetObjectIdSet(theFirstIDMapper, aFirstObjectIdSet);
728     
729     TObjectIdSet aSecondObjectIdSet;
730     GetObjectIdSet(theSecondIDMapper, aSecondObjectIdSet);
731
732     size_t aMaxLength = std::max(aFirstObjectIdSet.size(), aSecondObjectIdSet.size());
733     theResult.resize(aMaxLength);
734     TObjectIdArray::iterator anArrayIter = theResult.begin();
735     anArrayIter = std::set_intersection(aFirstObjectIdSet.begin(),
736                                         aFirstObjectIdSet.end(),
737                                         aSecondObjectIdSet.begin(),
738                                         aSecondObjectIdSet.end(),
739                                         anArrayIter);
740     theResult.erase(anArrayIter, theResult.end());
741   }
742
743   //---------------------------------------------------------------
744   bool
745   Execute(vtkUnstructuredGrid *theInput,
746           vtkUnstructuredGrid *theOutput,
747           vtkDataSet* theScalarsDataSet,
748           vtkDataSet* theVectorsDataSet,
749           vtkDataSet* theNormalsDataSet,
750           vtkDataSet* theTCoordsDataSet,
751           vtkDataSet* theTensorsDataSet,
752           TFieldList* theFieldList,
753           bool theIsMergingInputs)
754   {
755     return ::Execute(theInput,
756                      theScalarsDataSet,
757                      theVectorsDataSet,
758                      theNormalsDataSet,
759                      theTCoordsDataSet,
760                      theTensorsDataSet,
761                      theFieldList,
762                      theIsMergingInputs,
763                      theOutput);
764   }
765
766
767   //---------------------------------------------------------------
768   bool
769   Execute(vtkPolyData *theInput,
770           vtkPolyData *theOutput,
771           vtkDataSet* theScalarsDataSet,
772           vtkDataSet* theVectorsDataSet,
773           vtkDataSet* theNormalsDataSet,
774           vtkDataSet* theTCoordsDataSet,
775           vtkDataSet* theTensorsDataSet,
776           TFieldList* theFieldList,
777           bool theIsMergingInputs)
778   {
779     return ::Execute(theInput,
780                      theScalarsDataSet,
781                      theVectorsDataSet,
782                      theNormalsDataSet,
783                      theTCoordsDataSet,
784                      theTensorsDataSet,
785                      theFieldList,
786                      theIsMergingInputs,
787                      theOutput);
788   }
789 }