Salome HOME
Copyright update: 2016
[modules/gui.git] / src / VTKViewer / VTKViewer_ExtractUnstructuredGrid.cxx
1 // Copyright (C) 2007-2016  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.insert( theIn2OutId.end(), std::make_pair( 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.insert( theIn2OutId.end(), std::make_pair( 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   // use a vector of cellTypes to avoid searching in myCellTypes map
204   // for a better performance (IPAL53103)
205   TVectorId cellTypesVec( VTK_NUMBER_OF_CELL_TYPES, -1 );
206   for ( TSetId::iterator type = myCellTypes.begin(); type != myCellTypes.end(); ++type )
207   {
208     if ( *type >= (int)cellTypesVec.size() ) cellTypesVec.resize( *type+1, -1 );
209     if ( *type > 0 )
210       cellTypesVec[ *type ] = *type;
211   }
212
213 /*  if(MYDEBUG){
214     MESSAGE("Execute - anInput->GetNumberOfCells() = "<<anInput->GetNumberOfCells());
215     MESSAGE("Execute - myCellTypes.size() = "<<myCellTypes.size());
216     MESSAGE("Execute - myCellIds.size() = "<<myCellIds.size());
217     MESSAGE("Execute - myExtractionMode = "<<myExtractionMode);
218     MESSAGE("Execute - myChangeMode = "<<myChangeMode);
219   }*/
220   if(myExtractionMode == eCells){
221     if(myChangeMode == ePassAll || (myCellIds.empty() && myCellTypes.empty() && myChangeMode == eRemoving)){
222       if(vtkIdType aNbElems = anInput->GetNumberOfCells()){
223         if(myStoreMapping) myOut2InId.reserve(aNbElems);
224         anOutput->ShallowCopy(anInput);
225         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
226           if(myStoreMapping){
227             myOut2InId.push_back(aCellId);
228             myIn2OutId.insert( myIn2OutId.end(), std::make_pair( aCellId, anOutId ));
229           }
230         }
231       }
232     }else{
233       vtkIdList *anIdList = vtkIdList::New();
234       vtkCellArray *aConnectivity = vtkCellArray::New();
235       vtkIdType aNbElems = anInput->GetNumberOfCells();
236       aConnectivity->Allocate(2*aNbElems,0);
237       vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
238       aCellTypesArray->SetNumberOfComponents(1);
239       aCellTypesArray->Allocate(aNbElems*aCellTypesArray->GetNumberOfComponents());
240       anOutput->GetCellData()->CopyAllocate(anInput->GetCellData(),aNbElems,aNbElems/2);
241
242       vtkIdTypeArray *newFaces = 0;
243       vtkIdTypeArray *newFaceLocations = 0;
244
245       if(!myCellIds.empty() && myCellTypes.empty()){
246         if(myStoreMapping) myOut2InId.reserve(myCellIds.size());
247         if(myChangeMode == eAdding){
248           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
249             if(myCellIds.find(aCellId) != myCellIds.end()){
250               vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
251                                            myStoreMapping,anOutId,myOut2InId,myIn2OutId);
252               anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
253             }
254           }
255         }else{
256           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
257             if(myCellIds.find(aCellId) == myCellIds.end()){
258               vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
259                                            myStoreMapping,anOutId,myOut2InId,myIn2OutId);
260               anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
261             }
262           }
263         }
264       }else if(myCellIds.empty() && !myCellTypes.empty()){
265         if(myChangeMode == eAdding){
266           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
267             vtkIdType aType = anInput->GetCellType(aCellId);
268             if ( cellTypesVec[ aType ] == aType ) {
269               vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
270                                            myStoreMapping,anOutId,myOut2InId,myIn2OutId);
271               anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
272             }
273           }
274         }else{
275           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
276             vtkIdType aType = anInput->GetCellType(aCellId);
277             if ( cellTypesVec[ aType ] != aType ) {
278               vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
279                                            myStoreMapping,anOutId,myOut2InId,myIn2OutId);
280               anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
281             }
282           }
283         }
284       }else if(!myCellIds.empty() && !myCellTypes.empty()){
285         if(myChangeMode == eAdding){
286           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
287             vtkIdType aType = anInput->GetCellType(aCellId);
288             if ( cellTypesVec[ aType ] == aType ) {
289               if(myCellIds.find(aCellId) != myCellIds.end()){
290                 vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
291                                              myStoreMapping,anOutId,myOut2InId,myIn2OutId);
292                 anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
293               }
294             }
295           }
296         }else{
297           for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
298             vtkIdType aType = anInput->GetCellType(aCellId);
299             if ( cellTypesVec[ aType ] != aType ) {
300               if(myCellIds.find(aCellId) == myCellIds.end()){
301                 vtkIdType newId = InsertCell(anInput,aConnectivity,aCellTypesArray,newFaces,newFaceLocations,aCellId,anIdList,
302                                              myStoreMapping,anOutId,myOut2InId,myIn2OutId);
303                 anOutput->GetCellData()->CopyData(anInput->GetCellData(),aCellId,newId);
304               }
305             }
306           }
307         }
308       }
309       if((aNbElems = aConnectivity->GetNumberOfCells())){
310         VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
311         aCellLocationsArray->SetNumberOfComponents(1);
312         aCellLocationsArray->SetNumberOfTuples(aNbElems);
313         aConnectivity->InitTraversal();
314         for(vtkIdType i = 0, *pts, npts; aConnectivity->GetNextCell(npts,pts); i++){
315           aCellLocationsArray->SetValue(i,aConnectivity->GetTraversalLocation(npts));
316         }
317 #if VTK_XVERSION > 50700
318         anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity,newFaceLocations,newFaces);
319 #else
320         anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity);
321 #endif
322         anOutput->SetPoints(anInput->GetPoints());
323         aCellLocationsArray->Delete();
324       }
325       aCellTypesArray->Delete();
326       aConnectivity->Delete();
327       anIdList->Delete();
328       if ( newFaceLocations ) newFaceLocations->Delete();
329       if ( newFaces ) newFaces->Delete();
330     }
331   }else{
332     vtkIdList *anIdList = vtkIdList::New();
333     anIdList->SetNumberOfIds(1);
334     vtkCellArray *aConnectivity = vtkCellArray::New();
335     vtkIdType aNbElems = anInput->GetNumberOfPoints();
336     aConnectivity->Allocate(2*aNbElems,0);
337     vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
338     aCellTypesArray->SetNumberOfComponents(1);
339     aCellTypesArray->Allocate(aNbElems*aCellTypesArray->GetNumberOfComponents());
340     // additional condition has been added to treat a case described in IPAL21372
341     // note that it is significant only when myExtractionMode == ePoints
342     if(myChangeMode == ePassAll || (myCellIds.empty() && myCellTypes.empty() && myChangeMode == eRemoving) ||
343        !anInput->GetCellTypesArray()){
344       if(myStoreMapping) myOut2InId.reserve(aNbElems);
345       for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
346         InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
347                         myStoreMapping,anOutId,myOut2InId,myIn2OutId);
348       }
349     }else if(!myCellIds.empty() && myCellTypes.empty()){
350       if(myStoreMapping) myOut2InId.reserve(myCellIds.size());
351       if(myChangeMode == eAdding){
352         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
353           if(myCellIds.find(aCellId) != myCellIds.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           if(myCellIds.find(aCellId) == myCellIds.end()){
361             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
362                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
363           }
364         }
365       }
366     }else if(myCellIds.empty() && !myCellTypes.empty()){
367       if(myChangeMode == eAdding){
368         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
369           vtkIdType aType = anInput->GetCellType(aCellId);
370           if ( cellTypesVec[ aType ] == aType ) {
371             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
372                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
373           }
374         }
375       }else{
376         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
377           vtkIdType aType = anInput->GetCellType(aCellId);
378           if ( cellTypesVec[ aType ] != aType ) {
379             InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
380                             myStoreMapping,anOutId,myOut2InId,myIn2OutId);
381           }
382         }
383       }
384     }else if(!myCellIds.empty() && !myCellTypes.empty()){
385       if(myChangeMode == eAdding){
386         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
387           vtkIdType aType = anInput->GetCellType(aCellId);
388           if ( cellTypesVec[ aType ] == aType ) {
389             if(myCellIds.find(aCellId) != myCellIds.end()){
390               InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
391                               myStoreMapping,anOutId,myOut2InId,myIn2OutId);
392             }
393           }
394         }
395       }else{
396         for(vtkIdType aCellId = 0, anOutId = 0; aCellId < aNbElems; aCellId++,anOutId++){
397           vtkIdType aType = anInput->GetCellType(aCellId);
398           if ( cellTypesVec[ aType ] != aType ) {
399             if(myCellIds.find(aCellId) == myCellIds.end()){
400               InsertPointCell(aConnectivity,aCellTypesArray,aCellId,anIdList,
401                               myStoreMapping,anOutId,myOut2InId,myIn2OutId);
402             }
403           }
404         }
405       }
406     }
407     if((aNbElems = aConnectivity->GetNumberOfCells())){
408       VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
409       aCellLocationsArray->SetNumberOfComponents(1);
410       aCellLocationsArray->SetNumberOfTuples(aNbElems);
411       aConnectivity->InitTraversal();
412       for(vtkIdType i = 0, *pts, npts; aConnectivity->GetNextCell(npts,pts); i++){
413         aCellLocationsArray->SetValue(i,aConnectivity->GetTraversalLocation(npts));
414       }
415 #if VTK_XVERSION > 50700
416       anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity,0, 0);
417 #else
418       anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity);
419 #endif
420       anOutput->SetPoints(anInput->GetPoints());
421       aCellLocationsArray->Delete();
422     }
423     aCellTypesArray->Delete();
424     aConnectivity->Delete();
425     anIdList->Delete();
426   }
427 /*  if(MYDEBUG){
428     MESSAGE("Execute - anOutput->GetNumberOfCells() = "<<anOutput->GetNumberOfCells());
429     if(myStoreMapping){
430       MESSAGE("Execute - myOut2InId.size() = "<<myOut2InId.size());
431       MESSAGE("Execute - myIn2OutId.size() = "<<myIn2OutId.size());
432     }
433   }*/
434   return 1;
435 }