Salome HOME
Merge from V6_main 01/04/2013
[modules/gui.git] / src / VTKViewer / VTKViewer_ExtractUnstructuredGrid.cxx
1 // Copyright (C) 2007-2013  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(vtkInformation *vtkNotUsed(request),
182                                                    vtkInformationVector **inputVector,
183                                                    vtkInformationVector *outputVector)
184 {
185   // get the info objects
186   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
187   vtkInformation *outInfo = outputVector->GetInformationObject(0);
188
189   // get the input and ouptut
190   vtkUnstructuredGrid *anInput = vtkUnstructuredGrid::SafeDownCast(
191     inInfo->Get(vtkDataObject::DATA_OBJECT()));
192   vtkUnstructuredGrid *anOutput = vtkUnstructuredGrid::SafeDownCast(
193     outInfo->Get(vtkDataObject::DATA_OBJECT()));
194
195   //vtkUnstructuredGrid *anInput = this->GetInput();
196   //vtkUnstructuredGrid *anOutput = this->GetOutput();
197   
198   myOut2InId.clear();  myIn2OutId.clear();
199
200 /*  if(MYDEBUG){
201     MESSAGE("Execute - anInput->GetNumberOfCells() = "<<anInput->GetNumberOfCells());
202     MESSAGE("Execute - myCellTypes.size() = "<<myCellTypes.size());
203     MESSAGE("Execute - myCellIds.size() = "<<myCellIds.size());
204     MESSAGE("Execute - myExtractionMode = "<<myExtractionMode);
205     MESSAGE("Execute - myChangeMode = "<<myChangeMode);
206   }*/
207   if(myExtractionMode == eCells){
208     if(myChangeMode == ePassAll || (myCellIds.empty() && myCellTypes.empty() && myChangeMode == eRemoving)){
209       if(vtkIdType aNbElems = anInput->GetNumberOfCells()){
210         if(myStoreMapping) myOut2InId.reserve(aNbElems);
211         anOutput->ShallowCopy(anInput);
212         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
213           if(myStoreMapping){
214             myOut2InId.push_back(aCellId);
215             myIn2OutId[aCellId] = anOutId;
216           }
217         }
218       }
219     }else{
220       vtkIdList *anIdList = vtkIdList::New();
221       vtkCellArray *aConnectivity = vtkCellArray::New();
222       vtkIdType aNbElems = anInput->GetNumberOfCells();
223       aConnectivity->Allocate(2*aNbElems,0);
224       vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
225       aCellTypesArray->SetNumberOfComponents(1);
226       aCellTypesArray->Allocate(aNbElems*aCellTypesArray->GetNumberOfComponents());
227
228       vtkIdTypeArray *newFaces = 0;
229       vtkIdTypeArray *newFaceLocations = 0;
230
231       if(!myCellIds.empty() && myCellTypes.empty()){
232         if(myStoreMapping) myOut2InId.reserve(myCellIds.size());
233         if(myChangeMode == eAdding){
234           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
235             if(myCellIds.find(aCellId) != myCellIds.end()){
236               InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
237                          myStoreMapping,anOutId,myOut2InId,myIn2OutId);
238             }
239           }
240         }else{
241           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
242             if(myCellIds.find(aCellId) == myCellIds.end()){
243               InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
244                          myStoreMapping,anOutId,myOut2InId,myIn2OutId);
245             }
246           }
247         }
248       }else if(myCellIds.empty() && !myCellTypes.empty()){
249         if(myChangeMode == eAdding){
250           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
251             vtkIdType aType = anInput->GetCellType(aCellId);
252             if(myCellTypes.find(aType) != myCellTypes.end()){
253               InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
254                          myStoreMapping,anOutId,myOut2InId,myIn2OutId);
255             }
256           }
257         }else{
258           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
259             vtkIdType aType = anInput->GetCellType(aCellId);
260             if(myCellTypes.find(aType) == myCellTypes.end()){
261               InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
262                          myStoreMapping,anOutId,myOut2InId,myIn2OutId);
263             }
264           }
265         }
266       }else if(!myCellIds.empty() && !myCellTypes.empty()){
267         if(myChangeMode == eAdding){
268           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
269             vtkIdType aType = anInput->GetCellType(aCellId);
270             if(myCellTypes.find(aType) != myCellTypes.end()){
271               if(myCellIds.find(aCellId) != myCellIds.end()){
272                 InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
273                            myStoreMapping,anOutId,myOut2InId,myIn2OutId);
274               }
275             }
276           }
277         }else{
278           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
279             vtkIdType aType = anInput->GetCellType(aCellId);
280             if(myCellTypes.find(aType) == myCellTypes.end()){
281               if(myCellIds.find(aCellId) == myCellIds.end()){
282                 InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
283                            myStoreMapping,anOutId,myOut2InId,myIn2OutId);
284               }
285             }
286           }
287         }
288       }
289       if((aNbElems = aConnectivity->GetNumberOfCells())){
290         VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
291         aCellLocationsArray->SetNumberOfComponents(1);
292         aCellLocationsArray->SetNumberOfTuples(aNbElems);
293         aConnectivity->InitTraversal();
294         for(vtkIdType i = 0, *pts, npts; aConnectivity->GetNextCell(npts,pts); i++){
295           aCellLocationsArray->SetValue(i,aConnectivity->GetTraversalLocation(npts));
296         }
297 #if VTK_XVERSION > 50700
298         anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity,newFaceLocations,newFaces);
299 #else
300         anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity);
301 #endif
302         anOutput->SetPoints(anInput->GetPoints());
303         aCellLocationsArray->Delete();
304       }
305       aCellTypesArray->Delete();
306       aConnectivity->Delete();
307       anIdList->Delete();
308     }
309   }else{
310     vtkIdList *anIdList = vtkIdList::New();
311     anIdList->SetNumberOfIds(1);
312     vtkCellArray *aConnectivity = vtkCellArray::New();
313     vtkIdType aNbElems = anInput->GetNumberOfPoints();
314     aConnectivity->Allocate(2*aNbElems,0);
315     vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
316     aCellTypesArray->SetNumberOfComponents(1);
317     aCellTypesArray->Allocate(aNbElems*aCellTypesArray->GetNumberOfComponents());
318     // additional condition has been added to treat a case described in IPAL21372
319     // note that it is significant only when myExtractionMode == ePoints
320     if(myChangeMode == ePassAll || (myCellIds.empty() && myCellTypes.empty() && myChangeMode == eRemoving) ||
321        !anInput->GetCellTypesArray()){
322       if(myStoreMapping) myOut2InId.reserve(aNbElems);
323       for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
324         InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
325                         myStoreMapping,anOutId,myOut2InId,myIn2OutId);
326       }
327     }else if(!myCellIds.empty() && myCellTypes.empty()){
328       if(myStoreMapping) myOut2InId.reserve(myCellIds.size());
329       if(myChangeMode == eAdding){
330         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
331           if(myCellIds.find(aCellId) != myCellIds.end()){
332             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
333                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
334           }
335         }
336       }else{
337         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
338           if(myCellIds.find(aCellId) == myCellIds.end()){
339             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
340                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
341           }
342         }
343       }
344     }else if(myCellIds.empty() && !myCellTypes.empty()){
345       if(myChangeMode == eAdding){
346         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
347           vtkIdType aType = anInput->GetCellType(aCellId);
348           if(myCellTypes.find(aType) != myCellTypes.end()){
349             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
350                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
351           }
352         }
353       }else{
354         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
355           vtkIdType aType = anInput->GetCellType(aCellId);
356           if(myCellTypes.find(aType) == myCellTypes.end()){
357             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
358                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
359           }
360         }
361       }
362     }else if(!myCellIds.empty() && !myCellTypes.empty()){
363       if(myChangeMode == eAdding){
364         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
365           vtkIdType aType = anInput->GetCellType(aCellId);
366           if(myCellTypes.find(aType) != myCellTypes.end()){
367             if(myCellIds.find(aCellId) != myCellIds.end()){
368               InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
369                               myStoreMapping,anOutId,myOut2InId,myIn2OutId);
370             }
371           }
372         }
373       }else{
374         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
375           vtkIdType aType = anInput->GetCellType(aCellId);
376           if(myCellTypes.find(aType) == myCellTypes.end()){
377             if(myCellIds.find(aCellId) == myCellIds.end()){
378               InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
379                               myStoreMapping,anOutId,myOut2InId,myIn2OutId);
380             }
381           }
382         }
383       }
384     }
385     if((aNbElems = aConnectivity->GetNumberOfCells())){
386       VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
387       aCellLocationsArray->SetNumberOfComponents(1);
388       aCellLocationsArray->SetNumberOfTuples(aNbElems);
389       aConnectivity->InitTraversal();
390       for(vtkIdType i = 0, *pts, npts; aConnectivity->GetNextCell(npts,pts); i++){
391         aCellLocationsArray->SetValue(i,aConnectivity->GetTraversalLocation(npts));
392       }
393 #if VTK_XVERSION > 50700
394       anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity,0, 0);
395 #else
396       anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity);
397 #endif
398       anOutput->SetPoints(anInput->GetPoints());
399       aCellLocationsArray->Delete();
400     }
401     aCellTypesArray->Delete();
402     aConnectivity->Delete();
403     anIdList->Delete();
404   }
405 /*  if(MYDEBUG){
406     MESSAGE("Execute - anOutput->GetNumberOfCells() = "<<anOutput->GetNumberOfCells());
407     if(myStoreMapping){
408       MESSAGE("Execute - myOut2InId.size() = "<<myOut2InId.size());
409       MESSAGE("Execute - myIn2OutId.size() = "<<myIn2OutId.size());
410     }
411   }*/
412   return 1;
413 }