Salome HOME
Merge remote branch 'origin/hydro/imps_2015'
[modules/gui.git] / src / VTKViewer / VTKViewer_ExtractUnstructuredGrid.cxx
1 // Copyright (C) 2007-2015  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, or (at your option) any later version.
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
23 // File:    VTKViewer_ExtractUnstructuredGrid.cxx
24 // Author:  Alexey PETROV
25
26 #include "VTKViewer_ExtractUnstructuredGrid.h"
27 #include "VTKViewer_CellLocationsArray.h"
28
29 #include <vtkUnsignedCharArray.h>
30 #include <vtkUnstructuredGrid.h>
31 #include <vtkObjectFactory.h>
32 #include <vtkCellArray.h>
33 #include <vtkIdList.h>
34 #include <vtkCell.h>
35 #include <vtkCellData.h>
36 #include <vtkInformation.h>
37 #include <vtkInformationVector.h>
38 #include <vtkVersion.h>
39
40 #include "utilities.h"
41
42 #if defined __GNUC__
43   #if __GNUC__ == 2
44     #define __GNUC_2__
45   #endif
46 #endif
47
48 #define VTK_XVERSION (VTK_MAJOR_VERSION*10000+VTK_MINOR_VERSION*100+VTK_BUILD_VERSION)
49
50 vtkStandardNewMacro(VTKViewer_ExtractUnstructuredGrid);
51
52
53 VTKViewer_ExtractUnstructuredGrid::VTKViewer_ExtractUnstructuredGrid():
54   myExtractionMode(eCells), myChangeMode(ePassAll)
55 {}
56
57
58 VTKViewer_ExtractUnstructuredGrid::~VTKViewer_ExtractUnstructuredGrid(){}
59
60
61 void VTKViewer_ExtractUnstructuredGrid::RegisterCell(vtkIdType theCellId){
62 //  if(0 && MYDEBUG) MESSAGE("RegisterCell - theCellId = "<<theCellId);
63   myCellIds.insert(theCellId);
64   Modified();
65 }
66
67
68 void VTKViewer_ExtractUnstructuredGrid::RegisterCellsWithType(vtkIdType theCellType){
69 //  if(0 && MYDEBUG) MESSAGE("RegisterCellsWithType - theCellType = "<<theCellType);
70   myCellTypes.insert(theCellType);
71   //MESSAGE("myCellTypes.insert " << theCellType);
72   Modified();
73 }
74
75
76 void VTKViewer_ExtractUnstructuredGrid::SetStoreMapping(int theStoreMapping){
77   myStoreMapping = theStoreMapping != 0;
78   this->Modified();
79 }
80
81 vtkIdType VTKViewer_ExtractUnstructuredGrid::GetInputId(int theOutId) const
82 {
83   if ( myCellIds.empty() && myCellTypes.empty() )
84     return theOutId;
85
86   if ( theOutId<0 || theOutId >= (int)myOut2InId.size() )
87     return -1;
88   return myOut2InId[theOutId];
89 }
90
91 vtkIdType VTKViewer_ExtractUnstructuredGrid::GetOutputId(int theInId) const{
92   if(myCellIds.empty() && myCellTypes.empty()) return theInId;
93   TMapId::const_iterator anIter = myIn2OutId.find(theInId);
94   if(anIter == myIn2OutId.end()) return -1;
95   return anIter->second;
96 }
97
98
99 inline int InsertCell(vtkUnstructuredGrid *theInput,
100                        vtkCellArray *theConnectivity, 
101                        vtkUnsignedCharArray* theCellTypesArray,
102                        vtkIdTypeArray*& theFaces,
103                        vtkIdTypeArray*& theFaceLocations,
104                        vtkIdType theCellId, 
105                        vtkIdList *theIdList,
106                        bool theStoreMapping,
107                        vtkIdType theOutId, 
108                        VTKViewer_ExtractUnstructuredGrid::TVectorId& theOut2InId,
109                        VTKViewer_ExtractUnstructuredGrid::TMapId& theIn2OutId)
110 {
111   vtkCell *aCell = theInput->GetCell(theCellId);
112   vtkIdList *aPntIds = aCell->GetPointIds();
113   vtkIdType aNbIds = aPntIds->GetNumberOfIds();
114   vtkIdType aCellId = -1;
115   theIdList->SetNumberOfIds(aNbIds);
116   for(vtkIdType i = 0; i < aNbIds; i++){
117     theIdList->SetId(i,aPntIds->GetId(i));
118   }
119   vtkIdType aCellType = aCell->GetCellType();
120 #if VTK_XVERSION > 50700
121   if (aCellType != VTK_POLYHEDRON)
122     {
123 #endif
124       aCellId = theConnectivity->InsertNextCell(theIdList);
125       if (theFaceLocations)
126         theFaceLocations->InsertNextValue(-1);
127 #if VTK_XVERSION > 50700
128     }
129   else
130     {
131       //MESSAGE("InsertCell type VTK_POLYHEDRON " << theStoreMapping);
132       if (!theFaces)
133         {
134           theFaces = vtkIdTypeArray::New();
135           theFaces->Allocate(theCellTypesArray->GetSize());
136           theFaceLocations = vtkIdTypeArray::New();
137           theFaceLocations->Allocate(theCellTypesArray->GetSize());
138           // FaceLocations must be padded until the current position
139           for (vtkIdType i = 0; i <= theCellTypesArray->GetMaxId(); i++)
140             {
141               theFaceLocations->InsertNextValue(-1);
142             }
143         }
144       // insert face location
145       theFaceLocations->InsertNextValue(theFaces->GetMaxId() + 1);
146
147       // insert cell connectivity and faces stream
148       vtkIdType nfaces = 0;
149       vtkIdType*  face = 0;
150       vtkIdType realnpts;
151       theInput->GetFaceStream(theCellId, nfaces, face);
152       vtkUnstructuredGrid::DecomposeAPolyhedronCell(
153           nfaces, face, realnpts, theConnectivity, theFaces);
154     }
155 #endif
156
157   /*vtkIdType anID = */theCellTypesArray->InsertNextValue(aCellType);
158   if(theStoreMapping){
159     theOut2InId.push_back(theCellId);
160     theIn2OutId[theCellId] = theOutId;
161   }
162   return aCellId;
163 }
164
165 inline void InsertPointCell(vtkCellArray *theConnectivity, 
166                             vtkUnsignedCharArray* theCellTypesArray,
167                             vtkIdType theCellId,
168                             vtkIdList *theIdList,
169                             bool theStoreMapping,
170                             vtkIdType theOutId, 
171                             VTKViewer_ExtractUnstructuredGrid::TVectorId& theOut2InId,
172                             VTKViewer_ExtractUnstructuredGrid::TMapId& theIn2OutId)
173 {
174   theIdList->SetId(0,theCellId);
175   theConnectivity->InsertNextCell(theIdList);
176   theCellTypesArray->InsertNextValue(VTK_VERTEX);
177   if(theStoreMapping){
178     theOut2InId.push_back(theCellId);
179     theIn2OutId[theCellId] = theOutId;
180   }
181 }
182
183
184 int VTKViewer_ExtractUnstructuredGrid::RequestData(vtkInformation *vtkNotUsed(request),
185                                                    vtkInformationVector **inputVector,
186                                                    vtkInformationVector *outputVector)
187 {
188   // get the info objects
189   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
190   vtkInformation *outInfo = outputVector->GetInformationObject(0);
191
192   // get the input and ouptut
193   vtkUnstructuredGrid *anInput = vtkUnstructuredGrid::SafeDownCast(
194     inInfo->Get(vtkDataObject::DATA_OBJECT()));
195   vtkUnstructuredGrid *anOutput = vtkUnstructuredGrid::SafeDownCast(
196     outInfo->Get(vtkDataObject::DATA_OBJECT()));
197
198   //vtkUnstructuredGrid *anInput = this->GetInput();
199   //vtkUnstructuredGrid *anOutput = this->GetOutput();
200   
201   myOut2InId.clear();  myIn2OutId.clear();
202
203 /*  if(MYDEBUG){
204     MESSAGE("Execute - anInput->GetNumberOfCells() = "<<anInput->GetNumberOfCells());
205     MESSAGE("Execute - myCellTypes.size() = "<<myCellTypes.size());
206     MESSAGE("Execute - myCellIds.size() = "<<myCellIds.size());
207     MESSAGE("Execute - myExtractionMode = "<<myExtractionMode);
208     MESSAGE("Execute - myChangeMode = "<<myChangeMode);
209   }*/
210   if(myExtractionMode == eCells){
211     if(myChangeMode == ePassAll || (myCellIds.empty() && myCellTypes.empty() && myChangeMode == eRemoving)){
212       if(vtkIdType aNbElems = anInput->GetNumberOfCells()){
213         if(myStoreMapping) myOut2InId.reserve(aNbElems);
214         anOutput->ShallowCopy(anInput);
215         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
216           if(myStoreMapping){
217             myOut2InId.push_back(aCellId);
218             myIn2OutId[aCellId] = anOutId;
219           }
220         }
221       }
222     }else{
223       vtkIdList *anIdList = vtkIdList::New();
224       vtkCellArray *aConnectivity = vtkCellArray::New();
225       vtkIdType aNbElems = anInput->GetNumberOfCells();
226       aConnectivity->Allocate(2*aNbElems,0);
227       vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
228       aCellTypesArray->SetNumberOfComponents(1);
229       aCellTypesArray->Allocate(aNbElems*aCellTypesArray->GetNumberOfComponents());
230       anOutput->GetCellData()->CopyAllocate(anInput->GetCellData(),aNbElems,aNbElems/2);
231
232       vtkIdTypeArray *newFaces = 0;
233       vtkIdTypeArray *newFaceLocations = 0;
234
235       if(!myCellIds.empty() && myCellTypes.empty()){
236         if(myStoreMapping) myOut2InId.reserve(myCellIds.size());
237         if(myChangeMode == eAdding){
238           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
239             if(myCellIds.find(aCellId) != myCellIds.end()){
240               vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
241                          myStoreMapping,anOutId,myOut2InId,myIn2OutId);
242               anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
243             }
244           }
245         }else{
246           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
247             if(myCellIds.find(aCellId) == myCellIds.end()){
248               vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
249                          myStoreMapping,anOutId,myOut2InId,myIn2OutId);
250               anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
251             }
252           }
253         }
254       }else if(myCellIds.empty() && !myCellTypes.empty()){
255         if(myChangeMode == eAdding){
256           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
257             vtkIdType aType = anInput->GetCellType(aCellId);
258             if(myCellTypes.find(aType) != myCellTypes.end()){
259               vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
260                          myStoreMapping,anOutId,myOut2InId,myIn2OutId);
261               anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
262             }
263           }
264         }else{
265           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
266             vtkIdType aType = anInput->GetCellType(aCellId);
267             if(myCellTypes.find(aType) == myCellTypes.end()){
268               vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
269                          myStoreMapping,anOutId,myOut2InId,myIn2OutId);
270               anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
271             }
272           }
273         }
274       }else if(!myCellIds.empty() && !myCellTypes.empty()){
275         if(myChangeMode == eAdding){
276           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
277             vtkIdType aType = anInput->GetCellType(aCellId);
278             if(myCellTypes.find(aType) != myCellTypes.end()){
279               if(myCellIds.find(aCellId) != myCellIds.end()){
280                 vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
281                            myStoreMapping,anOutId,myOut2InId,myIn2OutId);
282                 anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
283               }
284             }
285           }
286         }else{
287           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
288             vtkIdType aType = anInput->GetCellType(aCellId);
289             if(myCellTypes.find(aType) == myCellTypes.end()){
290               if(myCellIds.find(aCellId) == myCellIds.end()){
291                 vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
292                            myStoreMapping,anOutId,myOut2InId,myIn2OutId);
293                 anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
294               }
295             }
296           }
297         }
298       }
299       if((aNbElems = aConnectivity->GetNumberOfCells())){
300         VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
301         aCellLocationsArray->SetNumberOfComponents(1);
302         aCellLocationsArray->SetNumberOfTuples(aNbElems);
303         aConnectivity->InitTraversal();
304         for(vtkIdType i = 0, *pts, npts; aConnectivity->GetNextCell(npts,pts); i++){
305           aCellLocationsArray->SetValue(i,aConnectivity->GetTraversalLocation(npts));
306         }
307 #if VTK_XVERSION > 50700
308         anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity,newFaceLocations,newFaces);
309 #else
310         anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity);
311 #endif
312         anOutput->SetPoints(anInput->GetPoints());
313         aCellLocationsArray->Delete();
314       }
315       aCellTypesArray->Delete();
316       aConnectivity->Delete();
317       anIdList->Delete();
318       if ( newFaceLocations ) newFaceLocations->Delete();
319       if ( newFaces ) newFaces->Delete();
320     }
321   }else{
322     vtkIdList *anIdList = vtkIdList::New();
323     anIdList->SetNumberOfIds(1);
324     vtkCellArray *aConnectivity = vtkCellArray::New();
325     vtkIdType aNbElems = anInput->GetNumberOfPoints();
326     aConnectivity->Allocate(2*aNbElems,0);
327     vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
328     aCellTypesArray->SetNumberOfComponents(1);
329     aCellTypesArray->Allocate(aNbElems*aCellTypesArray->GetNumberOfComponents());
330     // additional condition has been added to treat a case described in IPAL21372
331     // note that it is significant only when myExtractionMode == ePoints
332     if(myChangeMode == ePassAll || (myCellIds.empty() && myCellTypes.empty() && myChangeMode == eRemoving) ||
333        !anInput->GetCellTypesArray()){
334       if(myStoreMapping) myOut2InId.reserve(aNbElems);
335       for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
336         InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
337                         myStoreMapping,anOutId,myOut2InId,myIn2OutId);
338       }
339     }else if(!myCellIds.empty() && myCellTypes.empty()){
340       if(myStoreMapping) myOut2InId.reserve(myCellIds.size());
341       if(myChangeMode == eAdding){
342         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
343           if(myCellIds.find(aCellId) != myCellIds.end()){
344             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
345                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
346           }
347         }
348       }else{
349         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
350           if(myCellIds.find(aCellId) == myCellIds.end()){
351             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
352                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
353           }
354         }
355       }
356     }else if(myCellIds.empty() && !myCellTypes.empty()){
357       if(myChangeMode == eAdding){
358         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
359           vtkIdType aType = anInput->GetCellType(aCellId);
360           if(myCellTypes.find(aType) != myCellTypes.end()){
361             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
362                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
363           }
364         }
365       }else{
366         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
367           vtkIdType aType = anInput->GetCellType(aCellId);
368           if(myCellTypes.find(aType) == myCellTypes.end()){
369             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
370                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
371           }
372         }
373       }
374     }else if(!myCellIds.empty() && !myCellTypes.empty()){
375       if(myChangeMode == eAdding){
376         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
377           vtkIdType aType = anInput->GetCellType(aCellId);
378           if(myCellTypes.find(aType) != myCellTypes.end()){
379             if(myCellIds.find(aCellId) != myCellIds.end()){
380               InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
381                               myStoreMapping,anOutId,myOut2InId,myIn2OutId);
382             }
383           }
384         }
385       }else{
386         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
387           vtkIdType aType = anInput->GetCellType(aCellId);
388           if(myCellTypes.find(aType) == myCellTypes.end()){
389             if(myCellIds.find(aCellId) == myCellIds.end()){
390               InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
391                               myStoreMapping,anOutId,myOut2InId,myIn2OutId);
392             }
393           }
394         }
395       }
396     }
397     if((aNbElems = aConnectivity->GetNumberOfCells())){
398       VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
399       aCellLocationsArray->SetNumberOfComponents(1);
400       aCellLocationsArray->SetNumberOfTuples(aNbElems);
401       aConnectivity->InitTraversal();
402       for(vtkIdType i = 0, *pts, npts; aConnectivity->GetNextCell(npts,pts); i++){
403         aCellLocationsArray->SetValue(i,aConnectivity->GetTraversalLocation(npts));
404       }
405 #if VTK_XVERSION > 50700
406       anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity,0, 0);
407 #else
408       anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity);
409 #endif
410       anOutput->SetPoints(anInput->GetPoints());
411       aCellLocationsArray->Delete();
412     }
413     aCellTypesArray->Delete();
414     aConnectivity->Delete();
415     anIdList->Delete();
416   }
417 /*  if(MYDEBUG){
418     MESSAGE("Execute - anOutput->GetNumberOfCells() = "<<anOutput->GetNumberOfCells());
419     if(myStoreMapping){
420       MESSAGE("Execute - myOut2InId.size() = "<<myOut2InId.size());
421       MESSAGE("Execute - myIn2OutId.size() = "<<myIn2OutId.size());
422     }
423   }*/
424   return 1;
425 }