Salome HOME
Fix for Bug IPAL8945
[modules/visu.git] / src / CONVERTOR / VISU_MergeFilter.cxx
1 //  SALOME VTKViewer : build VTK viewer into Salome desktop
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : 
25 //  Author : 
26 //  Module : SALOME
27 //  $Header$
28
29 #include "VISU_MergeFilter.hxx"
30
31 #include <vtkCellData.h>
32 #include <vtkObjectFactory.h>
33 #include <vtkPointData.h>
34 #include <vtkPolyData.h>
35 #include <vtkRectilinearGrid.h>
36 #include <vtkStructuredGrid.h>
37 #include <vtkStructuredPoints.h>
38 #include <vtkUnstructuredGrid.h>
39
40 namespace VISU
41 {
42
43   class TFieldNode
44   {
45   public:
46     TFieldNode(const char* name, vtkDataSet* ptr=0)
47     {
48       int length = static_cast<int>(strlen(name));
49       if (length > 0) {
50         this->Name = new char[length+1];
51         strcpy(this->Name, name);
52       } else {
53         this->Name = 0;
54       }
55       this->Ptr = ptr;
56       this->Next = 0;
57     }
58     ~TFieldNode()
59     {
60       delete[] this->Name;
61     }
62
63     const char* GetName()
64     {
65       return Name;
66     }
67     vtkDataSet* Ptr;
68     TFieldNode* Next;
69   private:
70     TFieldNode(const TFieldNode&) {}
71     void operator=(const TFieldNode&) {}
72     char* Name;
73   };
74
75   class TFieldList
76   {
77   public:
78     TFieldList()
79     {
80       this->First = 0;
81       this->Last = 0;
82     }
83     ~TFieldList()
84     {
85       TFieldNode* node = this->First;
86       TFieldNode* next;
87       while(node){
88         next = node->Next;
89         delete node;
90         node = next;
91       }
92     }
93
94
95     void Add(const char* name, vtkDataSet* ptr)
96     {
97       TFieldNode* newNode = new TFieldNode(name, ptr);
98       if (!this->First) {
99         this->First = newNode;
100         this->Last = newNode;
101       } else {
102         this->Last->Next = newNode;
103         this->Last = newNode;
104       }
105     }
106
107     friend class TFieldListIterator;
108     
109   private:
110     TFieldNode* First;
111     TFieldNode* Last;
112   };
113   
114   class TFieldListIterator
115   {
116   public:
117     TFieldListIterator(TFieldList* list)
118     {
119       this->List = list;
120       this->Position = 0;
121     }
122     void Begin()
123     {
124       this->Position = this->List->First;
125     }
126     void Next()
127     {
128       if (this->Position) {
129         this->Position = this->Position->Next;
130       }
131     }
132     int End()
133     {
134       return this->Position ? 0 : 1;
135     }
136     TFieldNode* Get()
137     {
138       return this->Position;
139     }
140     
141   private:
142     TFieldNode* Position;
143     TFieldList* List;
144   };
145   
146 }
147
148 //------------------------------------------------------------------------------
149 vtkStandardNewMacro(VISU_MergeFilter);
150
151 //------------------------------------------------------------------------------
152
153 // Create object with no input or output.
154 VISU_MergeFilter::VISU_MergeFilter()
155 {
156   this->FieldList = new VISU::TFieldList;
157 }
158
159 VISU_MergeFilter::~VISU_MergeFilter()
160 {
161   delete this->FieldList;
162 }
163
164 void VISU_MergeFilter::SetScalars(vtkDataSet *input)
165 {
166   this->vtkProcessObject::SetNthInput(1, input);
167 }
168 vtkDataSet *VISU_MergeFilter::GetScalars()
169 {
170   if (this->NumberOfInputs < 2)
171     {
172     return NULL;
173     }
174   return (vtkDataSet *)(this->Inputs[1]);
175 }
176
177 void VISU_MergeFilter::SetVectors(vtkDataSet *input)
178 {
179   this->vtkProcessObject::SetNthInput(2, input);
180 }
181 vtkDataSet *VISU_MergeFilter::GetVectors()
182 {
183   if (this->NumberOfInputs < 3)
184     {
185     return NULL;
186     }
187   return (vtkDataSet *)(this->Inputs[2]);
188 }
189
190 void VISU_MergeFilter::SetNormals(vtkDataSet *input)
191 {
192   this->vtkProcessObject::SetNthInput(3, input);
193 }
194 vtkDataSet *VISU_MergeFilter::GetNormals()
195 {
196   if (this->NumberOfInputs < 4)
197     {
198     return NULL;
199     }
200   return (vtkDataSet *)(this->Inputs[3]);
201 }
202
203 void VISU_MergeFilter::SetTCoords(vtkDataSet *input)
204 {
205   this->vtkProcessObject::SetNthInput(4, input);
206 }
207 vtkDataSet *VISU_MergeFilter::GetTCoords()
208 {
209   if (this->NumberOfInputs < 5)
210     {
211     return NULL;
212     }
213   return (vtkDataSet *)(this->Inputs[4]);
214 }
215
216 void VISU_MergeFilter::SetTensors(vtkDataSet *input)
217 {
218   this->vtkProcessObject::SetNthInput(5, input);
219 }
220 vtkDataSet *VISU_MergeFilter::GetTensors()
221 {
222   if (this->NumberOfInputs < 6)
223     {
224     return NULL;
225     }
226   return (vtkDataSet *)(this->Inputs[5]);
227 }
228
229 void VISU_MergeFilter::AddField(const char* name, vtkDataSet* input)
230 {
231   this->FieldList->Add(name, input);
232 }
233
234 void VISU_MergeFilter::Execute()
235 {
236   vtkIdType numPts, numScalars=0, numVectors=0, numNormals=0, numTCoords=0;
237   vtkIdType numTensors=0;
238   vtkIdType numCells, numCellScalars=0, numCellVectors=0, numCellNormals=0;
239   vtkIdType numCellTCoords=0, numCellTensors=0;
240   vtkPointData *pd;
241   vtkDataArray *scalars = NULL;
242   vtkDataArray *vectors = NULL;
243   vtkDataArray *normals = NULL;
244   vtkDataArray *tcoords = NULL;
245   vtkDataArray *tensors = NULL;
246   vtkCellData *cd;
247   vtkDataArray *cellScalars = NULL;
248   vtkDataArray *cellVectors = NULL;
249   vtkDataArray *cellNormals = NULL;
250   vtkDataArray *cellTCoords = NULL;
251   vtkDataArray *cellTensors = NULL;
252   vtkDataSet *output = this->GetOutput();
253   vtkPointData *outputPD = output->GetPointData();
254   vtkCellData *outputCD = output->GetCellData();
255   
256   vtkDebugMacro(<<"Merging data!");
257
258   // geometry needs to be copied
259   output->CopyStructure(this->GetInput());
260   if ( (numPts = this->GetInput()->GetNumberOfPoints()) < 1 )
261     {
262     vtkWarningMacro(<<"Nothing to merge!");
263     }
264   numCells = this->GetInput()->GetNumberOfCells();
265   
266   if ( this->GetScalars() ) 
267     {
268     pd = this->GetScalars()->GetPointData();
269     scalars = pd->GetScalars();
270     if ( scalars != NULL )
271       {
272       numScalars = scalars->GetNumberOfTuples();
273       }
274     cd = this->GetScalars()->GetCellData();
275     cellScalars = cd->GetScalars();
276     if ( cellScalars != NULL )
277       {
278       numCellScalars = cellScalars->GetNumberOfTuples();
279       }
280     }
281
282   if ( this->GetVectors() ) 
283     {
284     pd = this->GetVectors()->GetPointData();
285     vectors = pd->GetVectors();
286     if ( vectors != NULL )
287       {
288       numVectors= vectors->GetNumberOfTuples();
289       }
290     cd = this->GetVectors()->GetCellData();
291     cellVectors = cd->GetVectors();
292     if ( cellVectors != NULL )
293       {
294       numCellVectors = cellVectors->GetNumberOfTuples();
295       }
296     }
297
298   if ( this->GetNormals() ) 
299     {
300     pd = this->GetNormals()->GetPointData();
301     normals = pd->GetNormals();
302     if ( normals != NULL )
303       {
304       numNormals= normals->GetNumberOfTuples();
305       }
306     cd = this->GetNormals()->GetCellData();
307     cellNormals = cd->GetNormals();
308     if ( cellNormals != NULL )
309       {
310       numCellNormals = cellNormals->GetNumberOfTuples();
311       }
312     }
313
314   if ( this->GetTCoords() ) 
315     {
316     pd = this->GetTCoords()->GetPointData();
317     tcoords = pd->GetTCoords();
318     if ( tcoords != NULL )
319       {
320       numTCoords= tcoords->GetNumberOfTuples();
321       }
322     cd = this->GetTCoords()->GetCellData();
323     cellTCoords = cd->GetTCoords();
324     if ( cellTCoords != NULL )
325       {
326       numCellTCoords = cellTCoords->GetNumberOfTuples();
327       }
328     }
329
330   if ( this->GetTensors() ) 
331     {
332     pd = this->GetTensors()->GetPointData();
333     tensors = pd->GetTensors();
334     if ( tensors != NULL )
335       {
336       numTensors = tensors->GetNumberOfTuples();
337       }
338     cd = this->GetTensors()->GetCellData();
339     cellTensors = cd->GetTensors();
340     if ( cellTensors != NULL )
341       {
342       numCellTensors = cellTensors->GetNumberOfTuples();
343       }
344     }
345
346   // merge data only if it is consistent
347   if ( numPts == numScalars )
348     {
349     outputPD->SetScalars(scalars);
350     }
351   if ( numCells == numCellScalars )
352     {
353     outputCD->SetScalars(cellScalars);
354     }
355
356   if ( numPts == numVectors )
357     {
358     outputPD->SetVectors(vectors);
359     }
360   if ( numCells == numCellVectors )
361     {
362     outputCD->SetVectors(cellVectors);
363     }
364     
365   if ( numPts == numNormals )
366     {
367     outputPD->SetNormals(normals);
368     }
369   if ( numCells == numCellNormals )
370     {
371     outputCD->SetNormals(cellNormals);
372     }
373
374   if ( numPts == numTCoords )
375     {
376     outputPD->SetTCoords(tcoords);
377     }
378   if ( numCells == numCellTCoords )
379     {
380     outputCD->SetTCoords(cellTCoords);
381     }
382
383   if ( numPts == numTensors )
384     {
385     outputPD->SetTensors(tensors);
386     }
387   if ( numCells == numCellTensors )
388     {
389     outputCD->SetTensors(cellTensors);
390     }
391
392   VISU::TFieldListIterator it(this->FieldList);
393   vtkDataArray* da;
394   const char* name;
395   vtkIdType num;
396   for(it.Begin(); !it.End() ; it.Next())
397     {
398     pd = it.Get()->Ptr->GetPointData();
399     cd = it.Get()->Ptr->GetCellData();
400     name = it.Get()->GetName();
401     if ( (da=pd->GetArray(name)) )
402       {
403       num = da->GetNumberOfTuples();
404       if (num == numPts)
405         {
406         outputPD->AddArray(da);
407         }
408       }
409     if ( (da=cd->GetArray(name)) )
410       {
411       num = da->GetNumberOfTuples();
412       if (num == numCells) // To fix a VTK bug
413         {
414         outputCD->AddArray(da);
415         }
416       }
417     }
418 }