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