1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File: VTKViewer_ExtractUnstructuredGrid.cxx
24 // Author: Alexey PETROV
26 #include "VTKViewer_ExtractUnstructuredGrid.h"
27 #include "VTKViewer_CellLocationsArray.h"
29 #include <vtkUnsignedCharArray.h>
30 #include <vtkUnstructuredGrid.h>
31 #include <vtkObjectFactory.h>
32 #include <vtkCellArray.h>
33 #include <vtkIdList.h>
35 #include <vtkCellData.h>
36 #include <vtkInformation.h>
37 #include <vtkInformationVector.h>
38 #include <vtkVersion.h>
40 #include "utilities.h"
48 #define VTK_XVERSION (VTK_MAJOR_VERSION*10000+VTK_MINOR_VERSION*100+VTK_BUILD_VERSION)
50 vtkStandardNewMacro(VTKViewer_ExtractUnstructuredGrid);
53 VTKViewer_ExtractUnstructuredGrid::VTKViewer_ExtractUnstructuredGrid():
54 myExtractionMode(eCells), myChangeMode(ePassAll)
58 VTKViewer_ExtractUnstructuredGrid::~VTKViewer_ExtractUnstructuredGrid(){}
61 void VTKViewer_ExtractUnstructuredGrid::RegisterCell(vtkIdType theCellId){
62 // if(0 && MYDEBUG) MESSAGE("RegisterCell - theCellId = "<<theCellId);
63 myCellIds.insert(theCellId);
68 void VTKViewer_ExtractUnstructuredGrid::RegisterCellsWithType(vtkIdType theCellType){
69 // if(0 && MYDEBUG) MESSAGE("RegisterCellsWithType - theCellType = "<<theCellType);
70 myCellTypes.insert(theCellType);
71 //MESSAGE("myCellTypes.insert " << theCellType);
76 void VTKViewer_ExtractUnstructuredGrid::SetStoreMapping(int theStoreMapping){
77 myStoreMapping = theStoreMapping != 0;
81 vtkIdType VTKViewer_ExtractUnstructuredGrid::GetInputId(int theOutId) const
83 if ( myCellIds.empty() && myCellTypes.empty() )
86 if ( theOutId<0 || theOutId >= (int)myOut2InId.size() )
88 return myOut2InId[theOutId];
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;
99 inline int InsertCell(vtkUnstructuredGrid *theInput,
100 vtkCellArray *theConnectivity,
101 vtkUnsignedCharArray* theCellTypesArray,
102 vtkIdTypeArray*& theFaces,
103 vtkIdTypeArray*& theFaceLocations,
105 vtkIdList *theIdList,
106 bool theStoreMapping,
108 VTKViewer_ExtractUnstructuredGrid::TVectorId& theOut2InId,
109 VTKViewer_ExtractUnstructuredGrid::TMapId& theIn2OutId)
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));
119 vtkIdType aCellType = aCell->GetCellType();
120 #if VTK_XVERSION > 50700
121 if (aCellType != VTK_POLYHEDRON)
124 aCellId = theConnectivity->InsertNextCell(theIdList);
125 if (theFaceLocations)
126 theFaceLocations->InsertNextValue(-1);
127 #if VTK_XVERSION > 50700
131 //MESSAGE("InsertCell type VTK_POLYHEDRON " << theStoreMapping);
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++)
141 theFaceLocations->InsertNextValue(-1);
144 // insert face location
145 theFaceLocations->InsertNextValue(theFaces->GetMaxId() + 1);
147 // insert cell connectivity and faces stream
148 vtkIdType nfaces = 0;
151 theInput->GetFaceStream(theCellId, nfaces, face);
152 vtkUnstructuredGrid::DecomposeAPolyhedronCell(
153 nfaces, face, realnpts, theConnectivity, theFaces);
157 /*vtkIdType anID = */theCellTypesArray->InsertNextValue(aCellType);
159 theOut2InId.push_back( theCellId );
160 theIn2OutId.insert( theIn2OutId.end(), std::make_pair( theCellId, theOutId ));
165 inline void InsertPointCell(vtkCellArray *theConnectivity,
166 vtkUnsignedCharArray* theCellTypesArray,
168 vtkIdList *theIdList,
169 bool theStoreMapping,
171 VTKViewer_ExtractUnstructuredGrid::TVectorId& theOut2InId,
172 VTKViewer_ExtractUnstructuredGrid::TMapId& theIn2OutId)
174 theIdList->SetId(0,theCellId);
175 theConnectivity->InsertNextCell(theIdList);
176 theCellTypesArray->InsertNextValue(VTK_VERTEX);
178 theOut2InId.push_back(theCellId);
179 theIn2OutId.insert( theIn2OutId.end(), std::make_pair( theCellId, theOutId ));
184 int VTKViewer_ExtractUnstructuredGrid::RequestData(vtkInformation *vtkNotUsed(request),
185 vtkInformationVector **inputVector,
186 vtkInformationVector *outputVector)
188 // get the info objects
189 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
190 vtkInformation *outInfo = outputVector->GetInformationObject(0);
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()));
198 //vtkUnstructuredGrid *anInput = this->GetInput();
199 //vtkUnstructuredGrid *anOutput = this->GetOutput();
201 myOut2InId.clear(); myIn2OutId.clear();
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 )
208 if ( *type >= (int)cellTypesVec.size() ) cellTypesVec.resize( *type+1, -1 );
210 cellTypesVec[ *type ] = *type;
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);
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++){
227 myOut2InId.push_back(aCellId);
228 myIn2OutId.insert( myIn2OutId.end(), std::make_pair( aCellId, anOutId ));
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);
242 vtkIdTypeArray *newFaces = 0;
243 vtkIdTypeArray *newFaceLocations = 0;
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);
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);
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);
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);
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);
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);
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));
317 #if VTK_XVERSION > 50700
318 anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity,newFaceLocations,newFaces);
320 anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity);
322 anOutput->SetPoints(anInput->GetPoints());
323 aCellLocationsArray->Delete();
325 aCellTypesArray->Delete();
326 aConnectivity->Delete();
328 if ( newFaceLocations ) newFaceLocations->Delete();
329 if ( newFaces ) newFaces->Delete();
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);
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);
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);
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);
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);
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);
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);
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));
415 #if VTK_XVERSION > 50700
416 anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity,0, 0);
418 anOutput->SetCells(aCellTypesArray,aCellLocationsArray,aConnectivity);
420 anOutput->SetPoints(anInput->GetPoints());
421 aCellLocationsArray->Delete();
423 aCellTypesArray->Delete();
424 aConnectivity->Delete();
428 MESSAGE("Execute - anOutput->GetNumberOfCells() = "<<anOutput->GetNumberOfCells());
430 MESSAGE("Execute - myOut2InId.size() = "<<myOut2InId.size());
431 MESSAGE("Execute - myIn2OutId.size() = "<<myIn2OutId.size());