Salome HOME
Update copyrights 2014.
[modules/gui.git] / src / VTKViewer / VTKViewer_GeometryFilter.cxx
1 // Copyright (C) 2007-2014  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_GeometryFilter.cxx
24 //  Author : Michael ZORIN
25 //  Module : SALOME
26 //
27 #include "VTKViewer_GeometryFilter.h"
28 #include "VTKViewer_ConvexTool.h"
29 #include "VTKViewer_ArcBuilder.h"
30
31 #include <vtkSmartPointer.h>
32 #include <vtkCellArray.h>
33 #include <vtkCellData.h>
34 #include <vtkGenericCell.h>
35 #include <vtkHexagonalPrism.h>
36 #include <vtkHexahedron.h>
37 #include <vtkInformation.h>
38 #include <vtkInformationVector.h>
39 #include <vtkMergePoints.h>
40 #include <vtkObjectFactory.h>
41 #include <vtkPointData.h>
42 #include <vtkPolyData.h>
43 #include <vtkPolygon.h>
44 #include <vtkPyramid.h>
45 #include <vtkStructuredGrid.h>
46 #include <vtkTetra.h>
47 #include <vtkUnsignedCharArray.h>
48 #include <vtkUnstructuredGrid.h>
49 #include <vtkVoxel.h>
50 #include <vtkWedge.h>
51 #include <vtkVersion.h>
52
53 #include <algorithm>
54 #include <iterator>
55 #include <vector>
56 #include <map>
57 #include <set>
58
59 #include "utilities.h"
60
61 #if defined __GNUC__
62   #if __GNUC__ == 2
63     #define __GNUC_2__
64   #endif
65 #endif
66
67 #define VTK_XVERSION (VTK_MAJOR_VERSION*10000+VTK_MINOR_VERSION*100+VTK_BUILD_VERSION)
68
69 //#define __MYDEBUG__
70 //#define USE_ROBUST_TRIANGULATION
71
72 ///////////////////////////////////////////////////////////////////////////////////////////////
73 // VSR 26/10/2012: fix of regression (issue 21924) - increased memory consumption
74 // for displaying of 3d elements, introduced by fix for issue 20314.
75 // ...
76 // The macro SHOW_COINCIDING_3D_PAL20314, when defined, allows correct visualization of
77 // coincident 3d elements but causes substantial increasing of memory consumption, as all 3d 
78 // elements are always shown, even if they are totally covered by surrounding faces.
79 // If this macro is not defined (commented), the behaviour is defined by another macro -
80 // SHOW_COINCIDING_3D_PAL21924, as follows:
81 // - If SHOW_COINCIDING_3D_PAL21924 is defined, an alternative solution for computing 
82 //   visibility of 3d elements is used; this solution allows to fix problem with visibility
83 //   of coinciding 3d elements in most cases (though some cases might not work), while not
84 //   causing significant increasing of memory consumption.
85 // - If SHOW_COINCIDING_3D_PAL21924 is not defined (commented), coinciding 3d elements are 
86 //   not shown at all (this corresponds to the state before issue 20314 fixing).
87 ///////////////////////////////////////////////////////////////////////////////////////////////
88 //#define SHOW_COINCIDING_3D_PAL20314
89 #ifndef SHOW_COINCIDING_3D_PAL20314
90 #define SHOW_COINCIDING_3D_PAL21924
91 #endif
92 ///////////////////////////////////////////////////////////////////////////////////////////////
93
94 vtkStandardNewMacro(VTKViewer_GeometryFilter);
95
96 VTKViewer_GeometryFilter
97 ::VTKViewer_GeometryFilter():
98   myShowInside(0),
99   myStoreMapping(0),
100   myAppendCoincident3D(0),
101   myIsWireframeMode(0),
102   myIsBuildArc(false),
103   myMaxArcAngle(2)
104 {}
105
106
107 VTKViewer_GeometryFilter
108 ::~VTKViewer_GeometryFilter()
109 {}
110
111
112 int
113 VTKViewer_GeometryFilter
114 ::RequestData(
115   vtkInformation *request,
116   vtkInformationVector **inputVector,
117   vtkInformationVector *outputVector)
118 {
119   // get the info objects
120   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
121   vtkInformation *outInfo = outputVector->GetInformationObject(0);
122
123   // get the input and ouptut
124   vtkDataSet *input = vtkDataSet::SafeDownCast(
125     inInfo->Get(vtkDataObject::DATA_OBJECT()));
126   vtkPolyData *output = vtkPolyData::SafeDownCast(
127     outInfo->Get(vtkDataObject::DATA_OBJECT()));
128
129   vtkIdType numCells=input->GetNumberOfCells();
130
131   if (numCells == 0)
132     {
133       return 0;
134     }
135
136   if (input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID){
137     return this->UnstructuredGridExecute(input, output, outInfo);
138   }else
139     return Superclass::RequestData(request,inputVector,outputVector);
140
141   return 1;
142 }
143
144
145 int
146 VTKViewer_GeometryFilter
147 ::UnstructuredGridExecute(
148                           vtkDataSet *dataSetInput,
149                           vtkPolyData *output,
150                           vtkInformation *outInfo)
151 {
152
153   vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)dataSetInput;
154   vtkCellArray *Connectivity = input->GetCells();
155   // Check input
156   if ( Connectivity == NULL )
157     {
158     vtkDebugMacro(<<"Nothing to extract");
159     return 0;
160     }
161
162   vtkIdType cellId;
163   int i;
164   int allVisible;
165   vtkIdType npts = 0;
166   vtkIdType *pts = 0;
167   vtkPoints *p = input->GetPoints();
168   vtkIdType numCells=input->GetNumberOfCells();
169   vtkPointData *pd = input->GetPointData();
170   vtkCellData *cd = input->GetCellData();
171   vtkPointData *outputPD = output->GetPointData();
172
173   VTKViewer_OrderedTriangulator anOrderedTriangulator;
174   VTKViewer_DelaunayTriangulator aDelaunayTriangulator;
175
176   vtkCellData *outputCD = output->GetCellData();
177   vtkGenericCell *cell = vtkGenericCell::New();
178
179   vtkIdList *cellIds = vtkIdList::New();
180   vtkIdList *faceIds = vtkIdList::New();
181   vtkIdList *cellIdsTmp = vtkIdList::New();
182   vtkIdList *faceIdsTmp = vtkIdList::New();
183
184   char *cellVis;
185   vtkIdType newCellId;
186   int faceId, *faceVerts, numFacePts;
187   double *x;
188   vtkIdType PixelConvert[4];
189   // Change the type from int to vtkIdType in order to avoid compilation errors while using VTK
190   // from ParaView-3.4.0 compiled on 64-bit Debian platform with VTK_USE_64BIT_IDS = ON
191   vtkIdType aNewPts[VTK_CELL_SIZE];
192   // ghost cell stuff
193   unsigned char  updateLevel = (unsigned char)(GetUpdateGhostLevel());
194   unsigned char  *cellGhostLevels = 0;
195
196   PixelConvert[0] = 0;
197   PixelConvert[1] = 1;
198   PixelConvert[2] = 3;
199   PixelConvert[3] = 2;
200
201   vtkDebugMacro(<<"Executing geometry filter for unstructured grid input");
202
203   vtkDataArray* temp = 0;
204   if (cd)
205     {
206     temp = cd->GetArray("vtkGhostLevels");
207     }
208   if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
209     || (temp->GetNumberOfComponents() != 1))
210     {
211     vtkDebugMacro("No appropriate ghost levels field available.");
212     }
213   else
214     {
215     cellGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
216     }
217
218   // Determine nature of what we have to do
219   if ( (!this->CellClipping) && (!this->PointClipping) &&
220        (!this->ExtentClipping) )
221     {
222     allVisible = 1;
223     cellVis = NULL;
224     }
225   else
226     {
227     allVisible = 0;
228     cellVis = new char[numCells];
229     }
230
231   // Issue 0020115: [CEA 308] Quadratic elements visualization
232   // Fix of remark described in note 0005222 - SIGSEGV
233   vtkPoints* outputPoints = vtkPoints::New();
234   outputPoints->DeepCopy(input->GetPoints());
235   output->SetPoints(outputPoints);
236   outputPoints->Delete();
237
238   outputPD->PassData(pd);
239
240   outputCD->CopyAllocate(cd,numCells,numCells/2);
241
242   output->Allocate(numCells/4+1,numCells);
243
244   // Loop over the cells determining what's visible
245   if (!allVisible)
246     {
247     for (cellId=0, Connectivity->InitTraversal();
248          Connectivity->GetNextCell(npts,pts);
249          cellId++)
250       {
251       cellVis[cellId] = 1;
252       if ( ( this->CellClipping && cellId < this->CellMinimum ) ||
253            cellId > this->CellMaximum )
254         {
255         cellVis[cellId] = 0;
256         }
257       else
258         {
259         for (i=0; i < npts; i++)
260           {
261           x = p->GetPoint(pts[i]);
262           if ( ( ( ( this->PointClipping && (pts[i] < this->PointMinimum ) ) ||
263                                              pts[i] > this->PointMaximum) ) ||
264                ( this->ExtentClipping &&
265                 ( x[0] < this->Extent[0] || x[0] > this->Extent[1] ||
266                   x[1] < this->Extent[2] || x[1] > this->Extent[3] ||
267                   x[2] < this->Extent[4] || x[2] > this->Extent[5] )) )
268             {
269             cellVis[cellId] = 0;
270             break;
271             }//point/extent clipping
272           }//for each point
273         }//if point clipping needs checking
274       }//for all cells
275     }//if not all visible
276
277   // Loop over all cells now that visibility is known
278   // (Have to compute visibility first for 3D cell boundarys)
279   int progressInterval = numCells/20 + 1;
280   TMapOfVectorId aDimension2VTK2ObjIds;
281   if(myStoreMapping){
282     myVTK2ObjIds.clear();
283     myVTK2ObjIds.reserve(numCells);
284   }
285   for (cellId=0, Connectivity->InitTraversal();
286        Connectivity->GetNextCell(npts,pts);
287        cellId++)
288     {
289     //Progress and abort method support
290     if ( !(cellId % progressInterval) )
291       {
292       vtkDebugMacro(<<"Process cell #" << cellId);
293       this->UpdateProgress ((float)cellId/numCells);
294       }
295
296     // Handle ghost cells here.  Another option was used cellVis array.
297     if (cellGhostLevels && cellGhostLevels[cellId] > updateLevel)
298       { // Do not create surfaces in outer ghost cells.
299       continue;
300       }
301
302     if (allVisible || cellVis[cellId])  //now if visible extract geometry
303       {
304       //special code for nonlinear cells - rarely occurs, so right now it
305       //is slow.
306       vtkIdType aCellType = input->GetCellType(cellId);
307       switch (aCellType)
308         {
309         case VTK_EMPTY_CELL:
310           break;
311
312         case VTK_VERTEX:
313         case VTK_POLY_VERTEX:
314           newCellId = output->InsertNextCell(aCellType,npts,pts);
315           if(myStoreMapping){
316             InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
317           }
318           outputCD->CopyData(cd,cellId,newCellId);
319           break;
320
321         case VTK_LINE:
322         case VTK_POLY_LINE:
323           newCellId = output->InsertNextCell(aCellType,npts,pts);
324           if(myStoreMapping)
325             InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
326           outputCD->CopyData(cd,cellId,newCellId);
327           break;
328
329         case VTK_TRIANGLE:
330         case VTK_QUAD:
331         case VTK_POLYGON:
332           newCellId = output->InsertNextCell(aCellType,npts,pts);
333           if(myStoreMapping)
334             InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
335           outputCD->CopyData(cd,cellId,newCellId);
336           break;
337
338         case VTK_TRIANGLE_STRIP:
339           newCellId = output->InsertNextCell(aCellType,npts,pts);
340           if(myStoreMapping)
341             InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
342           outputCD->CopyData(cd,cellId,newCellId);
343           break;
344
345         case VTK_PIXEL:
346           newCellId = output->InsertNextCell(aCellType,npts,pts);
347           if(myStoreMapping)
348             InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
349           outputCD->CopyData(cd,cellId,newCellId);
350           break;
351
352         case VTK_CONVEX_POINT_SET: {
353           bool anIsOk = anOrderedTriangulator.Execute(input,
354                                                       cd,
355                                                       cellId,
356                                                       myShowInside,
357                                                       allVisible,
358                                                       GetAppendCoincident3D(),
359                                                       cellVis,
360                                                       output,
361                                                       outputCD,
362                                                       myStoreMapping,
363                                                       myVTK2ObjIds,
364                                                       aDimension2VTK2ObjIds,
365                                                       true);
366           if(!anIsOk)
367             aDelaunayTriangulator.Execute(input,
368                                           cd,
369                                           cellId,
370                                           myShowInside,
371                                           allVisible,
372                                           GetAppendCoincident3D(),
373                                           cellVis,
374                                           output,
375                                           outputCD,
376                                           myStoreMapping,
377                                           myVTK2ObjIds,
378                                           aDimension2VTK2ObjIds,
379                                           false);
380
381           break;
382         }
383         case VTK_TETRA: {
384 #ifdef SHOW_COINCIDING_3D_PAL21924
385           faceIdsTmp->Reset();
386           for (int ai=0; ai<npts; ai++)
387             faceIdsTmp->InsertNextId(pts[ai]);
388           input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
389 #endif
390           for (faceId = 0; faceId < 4; faceId++)
391             {
392             faceIds->Reset();
393             faceVerts = vtkTetra::GetFaceArray(faceId);
394             faceIds->InsertNextId(pts[faceVerts[0]]);
395             faceIds->InsertNextId(pts[faceVerts[1]]);
396             faceIds->InsertNextId(pts[faceVerts[2]]);
397             aCellType = VTK_TRIANGLE;
398             numFacePts = 3;
399             input->GetCellNeighbors(cellId, faceIds, cellIds);
400 #ifdef SHOW_COINCIDING_3D_PAL21924
401             int nbNeighbors = 0;
402             for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
403               if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
404             }
405             bool process = nbNeighbors <= 0;
406 #else
407             bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
408 #endif
409             if ( process || myShowInside ||
410                  (!allVisible && !cellVis[cellIds->GetId(0)]) )
411               {
412               for ( i=0; i < numFacePts; i++)
413                 aNewPts[i] = pts[faceVerts[i]];
414               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
415               if(myStoreMapping)
416                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
417               outputCD->CopyData(cd,cellId,newCellId);
418               }
419             }
420           break;
421         }
422         case VTK_VOXEL: {
423 #ifdef SHOW_COINCIDING_3D_PAL21924
424           faceIdsTmp->Reset();
425           for (int ai=0; ai<npts; ai++)
426             faceIdsTmp->InsertNextId(pts[ai]);
427           input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
428 #endif
429           for (faceId = 0; faceId < 6; faceId++)
430             {
431             faceIds->Reset();
432             faceVerts = vtkVoxel::GetFaceArray(faceId);
433             faceIds->InsertNextId(pts[faceVerts[0]]);
434             faceIds->InsertNextId(pts[faceVerts[1]]);
435             faceIds->InsertNextId(pts[faceVerts[2]]);
436             faceIds->InsertNextId(pts[faceVerts[3]]);
437             aCellType = VTK_QUAD;
438             numFacePts = 4;
439             input->GetCellNeighbors(cellId, faceIds, cellIds);
440 #ifdef SHOW_COINCIDING_3D_PAL21924
441             int nbNeighbors = 0;
442             for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
443               if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
444             }
445             bool process = nbNeighbors <= 0;
446 #else
447             bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
448 #endif
449             if ( process || myShowInside ||
450                  (!allVisible && !cellVis[cellIds->GetId(0)]) )
451               {
452               for ( i=0; i < numFacePts; i++)
453                 aNewPts[i] = pts[faceVerts[PixelConvert[i]]];
454               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
455               if(myStoreMapping)
456                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
457               outputCD->CopyData(cd,cellId,newCellId);
458               }
459             }
460           break;
461         }
462         case VTK_HEXAHEDRON: {
463 #ifdef SHOW_COINCIDING_3D_PAL21924
464           faceIdsTmp->Reset();
465           for (int ai=0; ai<npts; ai++)
466             faceIdsTmp->InsertNextId(pts[ai]);
467           input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
468 #endif
469           for (faceId = 0; faceId < 6; faceId++)
470             {
471             faceIds->Reset();
472             faceVerts = vtkHexahedron::GetFaceArray(faceId);
473             faceIds->InsertNextId(pts[faceVerts[0]]);
474             faceIds->InsertNextId(pts[faceVerts[1]]);
475             faceIds->InsertNextId(pts[faceVerts[2]]);
476             faceIds->InsertNextId(pts[faceVerts[3]]);
477             aCellType = VTK_QUAD;
478             numFacePts = 4;
479             input->GetCellNeighbors(cellId, faceIds, cellIds);
480 #ifdef SHOW_COINCIDING_3D_PAL21924
481             int nbNeighbors = 0;
482             for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
483               if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
484             }
485             bool process = nbNeighbors <= 0;
486 #else
487             bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
488 #endif
489             if ( process || myShowInside ||
490                  (!allVisible && !cellVis[cellIds->GetId(0)]) )
491               {
492               for ( i=0; i < numFacePts; i++)
493                 aNewPts[i] = pts[faceVerts[i]];
494               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
495               if(myStoreMapping)
496                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
497               outputCD->CopyData(cd,cellId,newCellId);
498               }
499             }
500           break;
501         }
502         case VTK_WEDGE: {
503 #ifdef SHOW_COINCIDING_3D_PAL21924
504           faceIdsTmp->Reset();
505           for (int ai=0; ai<npts; ai++)
506             faceIdsTmp->InsertNextId(pts[ai]);
507           input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
508 #endif
509           for (faceId = 0; faceId < 5; faceId++)
510             {
511             faceIds->Reset();
512             faceVerts = vtkWedge::GetFaceArray(faceId);
513             faceIds->InsertNextId(pts[faceVerts[0]]);
514             faceIds->InsertNextId(pts[faceVerts[1]]);
515             faceIds->InsertNextId(pts[faceVerts[2]]);
516             aCellType = VTK_TRIANGLE;
517             numFacePts = 3;
518             if (faceVerts[3] >= 0)
519               {
520               faceIds->InsertNextId(pts[faceVerts[3]]);
521               aCellType = VTK_QUAD;
522               numFacePts = 4;
523               }
524
525             input->GetCellNeighbors(cellId, faceIds, cellIds);
526 #ifdef SHOW_COINCIDING_3D_PAL21924
527             int nbNeighbors = 0;
528             for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
529               if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
530             }
531             bool process = nbNeighbors <= 0;
532 #else
533             bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
534 #endif
535             if ( process || myShowInside ||
536                  (!allVisible && !cellVis[cellIds->GetId(0)]) )
537               {
538               for ( i=0; i < numFacePts; i++)
539                 aNewPts[i] = pts[faceVerts[i]];
540               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
541               if(myStoreMapping)
542                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
543               outputCD->CopyData(cd,cellId,newCellId);
544               }
545             }
546           break;
547         }
548         case VTK_HEXAGONAL_PRISM: {
549 #ifdef SHOW_COINCIDING_3D_PAL21924
550           faceIdsTmp->Reset();
551           for (int ai=0; ai<npts; ai++)
552             faceIdsTmp->InsertNextId(pts[ai]);
553           input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
554 #endif
555           for (faceId = 0; faceId < 8; faceId++)
556           {
557             faceVerts = vtkHexagonalPrism::GetFaceArray(faceId);
558             faceIds->Reset();
559             faceIds->InsertNextId(pts[faceVerts[0]]);
560             faceIds->InsertNextId(pts[faceVerts[1]]);
561             faceIds->InsertNextId(pts[faceVerts[2]]);
562             faceIds->InsertNextId(pts[faceVerts[3]]);
563             aCellType = VTK_QUAD;
564             numFacePts = 4;
565             if (faceVerts[5] >= 0)
566             {
567               faceIds->InsertNextId(pts[faceVerts[4]]);
568               faceIds->InsertNextId(pts[faceVerts[5]]);
569               aCellType = VTK_POLYGON;
570               numFacePts = 6;
571             }
572             input->GetCellNeighbors(cellId, faceIds, cellIds);
573 #ifdef SHOW_COINCIDING_3D_PAL21924
574             int nbNeighbors = 0;
575             for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
576               if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
577             }
578             bool process = nbNeighbors <= 0;
579 #else
580             bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
581 #endif
582             if ( process || myShowInside ||
583                  (!allVisible && !cellVis[cellIds->GetId(0)]) )
584             {
585               for ( i=0; i < numFacePts; i++)
586                 aNewPts[i] = pts[faceVerts[i]];
587               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
588               if(myStoreMapping)
589                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
590               outputCD->CopyData(cd,cellId,newCellId);
591             }
592             }
593           break;
594         }
595         case VTK_PYRAMID: {
596 #ifdef SHOW_COINCIDING_3D_PAL21924
597           faceIdsTmp->Reset();
598           for (int ai=0; ai<npts; ai++)
599             faceIdsTmp->InsertNextId(pts[ai]);
600           input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
601 #endif
602           for (faceId = 0; faceId < 5; faceId++)
603             {
604             faceIds->Reset();
605             faceVerts = vtkPyramid::GetFaceArray(faceId);
606             faceIds->InsertNextId(pts[faceVerts[0]]);
607             faceIds->InsertNextId(pts[faceVerts[1]]);
608             faceIds->InsertNextId(pts[faceVerts[2]]);
609             aCellType = VTK_TRIANGLE;
610             numFacePts = 3;
611             if (faceVerts[3] >= 0)
612               {
613               faceIds->InsertNextId(pts[faceVerts[3]]);
614               aCellType = VTK_QUAD;
615               numFacePts = 4;
616               }
617             input->GetCellNeighbors(cellId, faceIds, cellIds);
618 #ifdef SHOW_COINCIDING_3D_PAL21924
619             int nbNeighbors = 0;
620             for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
621               if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
622             }
623             bool process = nbNeighbors <= 0;
624 #else
625             bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
626 #endif
627             if ( process || myShowInside ||
628                  (!allVisible && !cellVis[cellIds->GetId(0)]) )
629               {
630               for ( i=0; i < numFacePts; i++)
631                 aNewPts[i] = pts[faceVerts[i]];
632               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
633               if(myStoreMapping)
634                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
635               outputCD->CopyData(cd,cellId,newCellId);
636               }
637             }
638           break;
639         }
640
641 #if VTK_XVERSION > 50700
642         case VTK_POLYHEDRON:
643           {
644             //MESSAGE("VTK_POLYHEDRON geometry filter");
645             vtkIdType nFaces = 0;
646             vtkIdType* ptIds = 0;
647             int idp = 0;
648             input->GetFaceStream(cellId, nFaces, ptIds);
649 #ifdef SHOW_COINCIDING_3D_PAL21924
650             faceIdsTmp->Reset();
651             for (int ai=0; ai<npts; ai++)
652               faceIdsTmp->InsertNextId(pts[ai]);
653             input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
654 #endif
655             for (faceId = 0; faceId < nFaces; faceId++)
656               {
657                 faceIds->Reset();
658                 numFacePts = ptIds[idp];
659                 //MESSAGE("numFacePts="<< numFacePts);
660                 int pt0 = ++idp;
661                 for (i = 0; i < numFacePts; i++)
662                   {
663                     //MESSAGE("ptIds[" << idp + i << "]=" << ptIds[idp + i]);
664                     faceIds->InsertNextId(ptIds[idp + i]);
665                   }
666                 idp += numFacePts;
667                 switch (numFacePts)
668                   {
669                   case 3:
670                     aCellType = VTK_TRIANGLE;
671                     break;
672                   case 4:
673                     aCellType = VTK_QUAD;
674                     break;
675                   default:
676                     aCellType = VTK_POLYGON;
677                     break;
678                   }
679                 // TODO understand and fix display of several polyhedrons                
680                 input->GetCellNeighbors(cellId, faceIds, cellIds);
681 #ifdef SHOW_COINCIDING_3D_PAL21924
682                 int nbNeighbors = 0;
683                 for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
684                   if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
685                 }
686                 bool process = nbNeighbors <= 0;
687 #else
688                 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
689 #endif
690                 if (process || myShowInside
691                     || (!allVisible && !cellVis[cellIds->GetId(0)]))
692                   {
693                     for (i = 0; i < numFacePts; i++)
694                       aNewPts[i] = ptIds[pt0 + i];
695                     newCellId = output->InsertNextCell(aCellType, numFacePts, aNewPts);
696                     if (myStoreMapping)
697                       InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
698                     outputCD->CopyData(cd, cellId, newCellId);
699                   }
700               }
701             break;
702           }
703 #endif
704         //Quadratic cells
705         case VTK_QUADRATIC_EDGE:
706         case VTK_QUADRATIC_TRIANGLE:
707         case VTK_BIQUADRATIC_TRIANGLE:
708         case VTK_QUADRATIC_QUAD:
709         case VTK_BIQUADRATIC_QUAD:
710         case VTK_QUADRATIC_TETRA:
711         case VTK_QUADRATIC_HEXAHEDRON:
712         case VTK_TRIQUADRATIC_HEXAHEDRON:
713         case VTK_QUADRATIC_WEDGE:
714         case VTK_QUADRATIC_PYRAMID:
715           if(!myIsWireframeMode) {
716             input->GetCell(cellId,cell);
717             vtkIdList *lpts = vtkIdList::New();
718             vtkPoints *coords = vtkPoints::New();
719             vtkIdList *cellIds = vtkIdList::New();
720             vtkIdType newCellId;
721
722             if ( cell->GetCellDimension() == 1 ) {
723               vtkIdType arcResult = -1;
724               if(myIsBuildArc) {
725                 arcResult = Build1DArc(cellId, input, output, pts, myMaxArcAngle);
726                 newCellId = arcResult;
727               }
728
729               if(!myIsBuildArc || arcResult == -1 ) {
730                 aCellType = VTK_LINE;
731                 numFacePts = 2;
732                 cell->Triangulate(0,lpts,coords);
733                 for (i=0; i < lpts->GetNumberOfIds(); i+=2) {
734                   aNewPts[0] = lpts->GetId(i);
735                   aNewPts[1] = lpts->GetId(i+1);
736                   newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
737                   if(myStoreMapping)
738                     InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
739                   outputCD->CopyData(cd,cellId,newCellId);
740                 }
741               }
742               else {
743                 if(myStoreMapping)
744                   InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
745                 outputCD->CopyData(cd,cellId,newCellId);
746               }
747             }
748             else if ( cell->GetCellDimension() == 2 ) {
749               if(!myIsBuildArc) {
750                 aCellType = VTK_TRIANGLE;
751                 numFacePts = 3;
752                 cell->Triangulate(0,lpts,coords);
753                 for (i=0; i < lpts->GetNumberOfIds(); i+=3) {
754                   aNewPts[0] = lpts->GetId(i);
755                   aNewPts[1] = lpts->GetId(i+1);
756                   aNewPts[2] = lpts->GetId(i+2);
757                   newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
758                   if(myStoreMapping)
759                     InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
760                   outputCD->CopyData(cd,cellId,newCellId);
761                 }
762               }
763               else{
764                 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds,true);
765               }
766             }
767             else //3D nonlinear cell
768             {
769 #ifdef SHOW_COINCIDING_3D_PAL21924
770               faceIdsTmp->Reset();
771               int npts1 = 0;
772               switch (aCellType ){
773               case VTK_QUADRATIC_TETRA:         npts1 = 4; break;
774               case VTK_QUADRATIC_HEXAHEDRON:    npts1 = 8; break;
775               case VTK_TRIQUADRATIC_HEXAHEDRON: npts1 = 8; break;
776               case VTK_QUADRATIC_WEDGE:         npts1 = 6; break;
777               case VTK_QUADRATIC_PYRAMID:       npts1 = 5; break;
778               }
779               if ( npts1 > 0 ) {
780                 for (int ai=0; ai<npts; ai++)
781                   faceIdsTmp->InsertNextId(pts[ai]);
782                 input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
783               }
784 #endif
785               aCellType = VTK_TRIANGLE;
786               numFacePts = 3;
787               for (int j=0; j < cell->GetNumberOfFaces(); j++){
788                 vtkCell *face = cell->GetFace(j);
789                 input->GetCellNeighbors(cellId, face->PointIds, cellIds);
790 #ifdef SHOW_COINCIDING_3D_PAL21924
791                 int nbNeighbors = 0;
792                 for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
793                   if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
794                 }
795                 bool process = nbNeighbors <= 0;
796 #else
797                 bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
798 #endif
799                 if ( process || myShowInside ) {
800                   face->Triangulate(0,lpts,coords);
801                   for (i=0; i < lpts->GetNumberOfIds(); i+=3) {
802                     aNewPts[0] = lpts->GetId(i);
803                     aNewPts[1] = lpts->GetId(i+1);
804                     aNewPts[2] = lpts->GetId(i+2);
805                     newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
806                     if(myStoreMapping)
807                       InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
808                     outputCD->CopyData(cd,cellId,newCellId);
809                   }
810                 }
811               }
812             } //3d nonlinear cell
813             cellIds->Delete();
814             coords->Delete();
815             lpts->Delete();
816             break;
817           } else { // wireframe
818             switch(aCellType) {
819             case VTK_QUADRATIC_EDGE: {
820               vtkIdType arcResult =-1;
821               if(myIsBuildArc) {
822                arcResult = Build1DArc(cellId, input, output, pts,myMaxArcAngle);
823                newCellId = arcResult;
824               }
825               if(!myIsBuildArc || arcResult == -1) {
826                 aCellType = VTK_POLY_LINE;
827                 numFacePts = 3;
828
829                 aNewPts[0] = pts[0];
830                 aNewPts[2] = pts[1];
831                 aNewPts[1] = pts[2];
832
833                 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
834               }
835
836               if(myStoreMapping)
837                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
838
839               outputCD->CopyData(cd,cellId,newCellId);
840               break;
841             }
842             case VTK_QUADRATIC_TRIANGLE:
843             case VTK_BIQUADRATIC_TRIANGLE: {
844               if(!myIsBuildArc) {
845                 aCellType = VTK_POLYGON;
846                 numFacePts = 6;
847
848                 aNewPts[0] = pts[0];
849                 aNewPts[1] = pts[3];
850                 aNewPts[2] = pts[1];
851                 aNewPts[3] = pts[4];
852                 aNewPts[4] = pts[2];
853                 aNewPts[5] = pts[5];
854
855                 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
856                 if(myStoreMapping)
857                   InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
858
859                 outputCD->CopyData(cd,cellId,newCellId);
860               }
861               else
862                 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
863               break;
864             }
865             case VTK_QUADRATIC_QUAD:
866             case VTK_BIQUADRATIC_QUAD: {
867               if(!myIsBuildArc) {
868                 aCellType = VTK_POLYGON;
869                 numFacePts = 8;
870
871                 aNewPts[0] = pts[0];
872                 aNewPts[1] = pts[4];
873                 aNewPts[2] = pts[1];
874                 aNewPts[3] = pts[5];
875                 aNewPts[4] = pts[2];
876                 aNewPts[5] = pts[6];
877                 aNewPts[6] = pts[3];
878                 aNewPts[7] = pts[7];
879
880                 newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
881                 if(myStoreMapping)
882                   InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
883
884                 outputCD->CopyData(cd,cellId,newCellId);
885               }
886               else
887                 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
888               break;
889             }
890             case VTK_QUADRATIC_TETRA: {
891               aCellType = VTK_POLYGON;
892               numFacePts = 6;
893
894               //---------------------------------------------------------------
895               aNewPts[0] = pts[0];
896               aNewPts[1] = pts[4];
897               aNewPts[2] = pts[1];
898               aNewPts[3] = pts[5];
899               aNewPts[4] = pts[2];
900               aNewPts[5] = pts[6];
901
902               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
903               if(myStoreMapping)
904                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
905
906               outputCD->CopyData(cd,cellId,newCellId);
907
908               //---------------------------------------------------------------
909               aNewPts[0] = pts[0];
910               aNewPts[1] = pts[7];
911               aNewPts[2] = pts[3];
912               aNewPts[3] = pts[8];
913               aNewPts[4] = pts[1];
914               aNewPts[5] = pts[4];
915
916               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
917               if(myStoreMapping)
918                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
919
920               outputCD->CopyData(cd,cellId,newCellId);
921
922               //---------------------------------------------------------------
923               aNewPts[0] = pts[1];
924               aNewPts[1] = pts[8];
925               aNewPts[2] = pts[3];
926               aNewPts[3] = pts[9];
927               aNewPts[4] = pts[2];
928               aNewPts[5] = pts[5];
929
930               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
931               if(myStoreMapping)
932                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
933
934               outputCD->CopyData(cd,cellId,newCellId);
935
936               //---------------------------------------------------------------
937               aNewPts[0] = pts[2];
938               aNewPts[1] = pts[9];
939               aNewPts[2] = pts[3];
940               aNewPts[3] = pts[7];
941               aNewPts[4] = pts[0];
942               aNewPts[5] = pts[6];
943
944               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
945               if(myStoreMapping)
946                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
947
948               outputCD->CopyData(cd,cellId,newCellId);
949
950               break;
951             }
952             case VTK_QUADRATIC_WEDGE: {
953               aCellType = VTK_POLYGON;
954               numFacePts = 6;
955               //---------------------------------------------------------------
956               //Face 1
957               aNewPts[0] = pts[0];
958               aNewPts[1] = pts[6];
959               aNewPts[2] = pts[1];
960               aNewPts[3] = pts[7];
961               aNewPts[4] = pts[2];
962               aNewPts[5] = pts[8];
963               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
964               if(myStoreMapping)
965                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
966               outputCD->CopyData(cd,cellId,newCellId);
967
968               //---------------------------------------------------------------
969               //Face 2
970               aNewPts[0] = pts[3];
971               aNewPts[1] = pts[9];
972               aNewPts[2] = pts[4];
973               aNewPts[3] = pts[10];
974               aNewPts[4] = pts[5];
975               aNewPts[5] = pts[11];
976               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
977               if(myStoreMapping)
978                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
979               outputCD->CopyData(cd,cellId,newCellId);
980
981               //---------------------------------------------------------------
982               //Face 3
983               numFacePts = 8;
984               aNewPts[0] = pts[0];
985               aNewPts[1] = pts[8];
986               aNewPts[2] = pts[2];
987               aNewPts[3] = pts[14];
988               aNewPts[4] = pts[5];
989               aNewPts[5] = pts[11];
990               aNewPts[6] = pts[3];
991               aNewPts[7] = pts[12];
992               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
993               if(myStoreMapping)
994                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
995               outputCD->CopyData(cd,cellId,newCellId);
996
997               //---------------------------------------------------------------
998               //Face 4
999               aNewPts[0] = pts[1];
1000               aNewPts[1] = pts[13];
1001               aNewPts[2] = pts[4];
1002               aNewPts[3] = pts[10];
1003               aNewPts[4] = pts[5];
1004               aNewPts[5] = pts[14];
1005               aNewPts[6] = pts[2];
1006               aNewPts[7] = pts[7];
1007               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1008               if(myStoreMapping)
1009                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1010               outputCD->CopyData(cd,cellId,newCellId);
1011
1012               //---------------------------------------------------------------
1013               //Face 5
1014               aNewPts[0] = pts[0];
1015               aNewPts[1] = pts[12];
1016               aNewPts[2] = pts[3];
1017               aNewPts[3] = pts[9];
1018               aNewPts[4] = pts[4];
1019               aNewPts[5] = pts[13];
1020               aNewPts[6] = pts[1];
1021               aNewPts[7] = pts[6];
1022               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1023               if(myStoreMapping)
1024                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1025               outputCD->CopyData(cd,cellId,newCellId);
1026               break;
1027             }
1028             case VTK_TRIQUADRATIC_HEXAHEDRON:
1029             case VTK_QUADRATIC_HEXAHEDRON: {
1030               aCellType = VTK_POLYGON;
1031               numFacePts = 8;
1032
1033               //---------------------------------------------------------------
1034               aNewPts[0] = pts[0];
1035               aNewPts[1] = pts[8];
1036               aNewPts[2] = pts[1];
1037               aNewPts[3] = pts[17];
1038               aNewPts[4] = pts[5];
1039               aNewPts[5] = pts[12];
1040               aNewPts[6] = pts[4];
1041               aNewPts[7] = pts[16];
1042
1043               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1044               if(myStoreMapping)
1045                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1046
1047               outputCD->CopyData(cd,cellId,newCellId);
1048
1049               //---------------------------------------------------------------
1050               aNewPts[0] = pts[1];
1051               aNewPts[1] = pts[9];
1052               aNewPts[2] = pts[2];
1053               aNewPts[3] = pts[18];
1054               aNewPts[4] = pts[6];
1055               aNewPts[5] = pts[13];
1056               aNewPts[6] = pts[5];
1057               aNewPts[7] = pts[17];
1058
1059               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1060               if(myStoreMapping)
1061                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1062
1063               outputCD->CopyData(cd,cellId,newCellId);
1064
1065               //---------------------------------------------------------------
1066               aNewPts[0] = pts[2];
1067               aNewPts[1] = pts[10];
1068               aNewPts[2] = pts[3];
1069               aNewPts[3] = pts[19];
1070               aNewPts[4] = pts[7];
1071               aNewPts[5] = pts[14];
1072               aNewPts[6] = pts[6];
1073               aNewPts[7] = pts[18];
1074
1075               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1076               if(myStoreMapping)
1077                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1078
1079               outputCD->CopyData(cd,cellId,newCellId);
1080
1081               //---------------------------------------------------------------
1082               aNewPts[0] = pts[3];
1083               aNewPts[1] = pts[11];
1084               aNewPts[2] = pts[0];
1085               aNewPts[3] = pts[16];
1086               aNewPts[4] = pts[4];
1087               aNewPts[5] = pts[15];
1088               aNewPts[6] = pts[7];
1089               aNewPts[7] = pts[19];
1090
1091               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1092               if(myStoreMapping)
1093                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1094
1095               outputCD->CopyData(cd,cellId,newCellId);
1096
1097               //---------------------------------------------------------------
1098               aNewPts[0] = pts[0];
1099               aNewPts[1] = pts[8];
1100               aNewPts[2] = pts[1];
1101               aNewPts[3] = pts[9];
1102               aNewPts[4] = pts[2];
1103               aNewPts[5] = pts[10];
1104               aNewPts[6] = pts[3];
1105               aNewPts[7] = pts[11];
1106
1107               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1108               if(myStoreMapping)
1109                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1110
1111               outputCD->CopyData(cd,cellId,newCellId);
1112
1113               //---------------------------------------------------------------
1114               aNewPts[0] = pts[4];
1115               aNewPts[1] = pts[12];
1116               aNewPts[2] = pts[5];
1117               aNewPts[3] = pts[13];
1118               aNewPts[4] = pts[6];
1119               aNewPts[5] = pts[14];
1120               aNewPts[6] = pts[7];
1121               aNewPts[7] = pts[15];
1122
1123               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1124               if(myStoreMapping)
1125                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1126
1127               outputCD->CopyData(cd,cellId,newCellId);
1128
1129               break;
1130             }
1131             case VTK_QUADRATIC_PYRAMID: {
1132               aCellType = VTK_POLYGON;
1133               numFacePts = 6;
1134
1135               //---------------------------------------------------------------
1136               aNewPts[0] = pts[0];
1137               aNewPts[1] = pts[8];
1138               aNewPts[2] = pts[3];
1139               aNewPts[3] = pts[12];
1140               aNewPts[4] = pts[4];
1141               aNewPts[5] = pts[9];
1142
1143               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1144               if(myStoreMapping)
1145                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1146
1147               outputCD->CopyData(cd,cellId,newCellId);
1148
1149               //---------------------------------------------------------------
1150               aNewPts[0] = pts[0];
1151               aNewPts[1] = pts[9];
1152               aNewPts[2] = pts[4];
1153               aNewPts[3] = pts[10];
1154               aNewPts[4] = pts[1];
1155               aNewPts[5] = pts[5];
1156
1157               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1158               if(myStoreMapping)
1159                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1160
1161               outputCD->CopyData(cd,cellId,newCellId);
1162
1163               //---------------------------------------------------------------
1164               aNewPts[0] = pts[1];
1165               aNewPts[1] = pts[10];
1166               aNewPts[2] = pts[4];
1167               aNewPts[3] = pts[11];
1168               aNewPts[4] = pts[2];
1169               aNewPts[5] = pts[6];
1170
1171               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1172               if(myStoreMapping)
1173                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1174
1175               outputCD->CopyData(cd,cellId,newCellId);
1176
1177               //---------------------------------------------------------------
1178               aNewPts[0] = pts[2];
1179               aNewPts[1] = pts[11];
1180               aNewPts[2] = pts[4];
1181               aNewPts[3] = pts[12];
1182               aNewPts[4] = pts[3];
1183               aNewPts[5] = pts[7];
1184
1185               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1186               if(myStoreMapping)
1187                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1188
1189               outputCD->CopyData(cd,cellId,newCellId);
1190
1191               //---------------------------------------------------------------
1192               numFacePts = 8;
1193               aNewPts[0] = pts[0];
1194               aNewPts[1] = pts[5];
1195               aNewPts[2] = pts[1];
1196               aNewPts[3] = pts[6];
1197               aNewPts[4] = pts[2];
1198               aNewPts[5] = pts[7];
1199               aNewPts[6] = pts[3];
1200               aNewPts[7] = pts[8];
1201
1202               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1203               if(myStoreMapping)
1204                 InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
1205
1206               outputCD->CopyData(cd,cellId,newCellId);
1207
1208               break;
1209             } // case VTK_QUADRATIC_PYRAMID:
1210             } // switch by type
1211           } // end WIREFRAME
1212           break;
1213         } //switch
1214       } //if visible
1215     } //for all cells
1216
1217   output->Squeeze();
1218
1219   vtkDebugMacro(<<"Extracted " << input->GetNumberOfPoints() << " points,"
1220                 << output->GetNumberOfCells() << " cells.");
1221
1222   cell->Delete();
1223
1224   cellIds->Delete();
1225   faceIds->Delete();
1226   cellIdsTmp->Delete();
1227   faceIdsTmp->Delete();
1228
1229   if ( cellVis )
1230   {
1231     delete [] cellVis;
1232   }
1233
1234   // to sort myVTK2ObjIds vector by cell dimension (ascending)
1235   if( myStoreMapping && !aDimension2VTK2ObjIds.empty() )
1236   {
1237     myVTK2ObjIds.clear();
1238     for( vtkIdType aDimension = 0; aDimension <= 2; aDimension++ )
1239     {
1240       TMapOfVectorId::const_iterator anIter = aDimension2VTK2ObjIds.find( aDimension );
1241       if( anIter != aDimension2VTK2ObjIds.end() )
1242       {
1243         const TVectorId& aCellIds = anIter->second;
1244         TVectorId::const_iterator anIdIter, anIdIterEnd = aCellIds.end();
1245         for( anIdIter = aCellIds.begin(); anIdIter != anIdIterEnd; anIdIter++ )
1246         {
1247           const vtkIdType aCellId = *anIdIter;
1248           myVTK2ObjIds.push_back( aCellId );
1249         }
1250       }
1251     }
1252   }
1253
1254   return 1;
1255 }
1256
1257 void
1258 VTKViewer_GeometryFilter
1259 ::InsertId( const vtkIdType theCellId,
1260             const vtkIdType theCellType,
1261             TVectorId& theVTK2ObjIds,
1262             TMapOfVectorId& theDimension2VTK2ObjIds )
1263 {
1264   theVTK2ObjIds.push_back( theCellId );
1265
1266   int aDimension = 0;
1267   switch( theCellType )
1268   {
1269     case VTK_VERTEX:
1270     case VTK_POLY_VERTEX:
1271       aDimension = 0;
1272       break;
1273     case VTK_LINE:
1274     case VTK_POLY_LINE:
1275       aDimension = 1;
1276       break;
1277     case VTK_TRIANGLE:
1278     case VTK_TRIANGLE_STRIP:
1279     case VTK_POLYGON:
1280     case VTK_PIXEL:
1281     case VTK_QUAD:
1282       aDimension = 2;
1283       break;
1284   }
1285
1286   TVectorId& aCellIds = theDimension2VTK2ObjIds[ aDimension ];
1287   aCellIds.push_back( theCellId );
1288 }
1289
1290 void
1291 VTKViewer_GeometryFilter
1292 ::SetInside(int theShowInside)
1293 {
1294   if(myShowInside == theShowInside)
1295     return;
1296
1297   myShowInside = theShowInside;
1298   this->Modified();
1299 }
1300
1301 int
1302 VTKViewer_GeometryFilter
1303 ::GetInside()
1304 {
1305   return myShowInside;
1306 }
1307
1308
1309 void
1310 VTKViewer_GeometryFilter
1311 ::SetWireframeMode(int theIsWireframeMode)
1312 {
1313   if(myIsWireframeMode == theIsWireframeMode)
1314     return;
1315
1316   myIsWireframeMode = theIsWireframeMode;
1317   this->Modified();
1318 }
1319
1320 int
1321 VTKViewer_GeometryFilter
1322 ::GetWireframeMode()
1323 {
1324   return myIsWireframeMode;
1325 }
1326
1327
1328 void
1329 VTKViewer_GeometryFilter
1330 ::SetStoreMapping(int theStoreMapping)
1331 {
1332   if(myStoreMapping == theStoreMapping)
1333     return;
1334
1335   myStoreMapping = theStoreMapping;
1336   this->Modified();
1337 }
1338
1339 int
1340 VTKViewer_GeometryFilter
1341 ::GetStoreMapping()
1342 {
1343   return myStoreMapping;
1344 }
1345
1346
1347 vtkIdType VTKViewer_GeometryFilter::GetElemObjId( int theVtkID )
1348 {
1349   if( theVtkID < 0 || theVtkID >= (int)myVTK2ObjIds.size() )
1350     return -1;
1351   return myVTK2ObjIds[theVtkID];
1352 }
1353
1354
1355 void VTKViewer_GeometryFilter::BuildArcedPolygon(vtkIdType cellId,
1356                                                  vtkUnstructuredGrid* input,
1357                                                  vtkPolyData *output,
1358                                                  TMapOfVectorId& theDimension2VTK2ObjIds,
1359                                                  bool triangulate)
1360 {
1361   vtkIdType aCellType = VTK_POLYGON;
1362   vtkIdType *aNewPoints = NULL;
1363   vtkIdType aNbPoints = 0;
1364   vtkIdType newCellId;
1365
1366   //Input and output cell data
1367   vtkCellData *cd = input->GetCellData();
1368   vtkCellData *outputCD = output->GetCellData();
1369
1370   //Input and output scalars on point data
1371   vtkDataArray* inputScalars = input->GetPointData()->GetScalars();
1372   vtkDataArray* outputScalars = output->GetPointData()->GetScalars();
1373
1374   std::vector< vtkSmartPointer<vtkPoints> > aCollection;
1375   std::vector< std::vector<double> > aScalarCollection;
1376
1377   vtkCell* aCell = input->GetCell(cellId);
1378   switch(aCell->GetCellType()) {
1379     case VTK_QUADRATIC_TRIANGLE:
1380     case VTK_BIQUADRATIC_TRIANGLE:
1381     {
1382       //Get All points from input cell
1383       Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
1384       Pnt P1 = CreatePnt( aCell, inputScalars, 1 );
1385       Pnt P2 = CreatePnt( aCell, inputScalars, 2 );
1386       Pnt P3 = CreatePnt( aCell, inputScalars, 3 );
1387       Pnt P4 = CreatePnt( aCell, inputScalars, 4 );
1388       Pnt P5 = CreatePnt( aCell, inputScalars, 5 );
1389
1390       VTKViewer_ArcBuilder aBuilder1(P0,P3,P1,myMaxArcAngle); //Build arc using 0, 3 and 1 points
1391 #ifdef __MYDEBUG__
1392       cout << "Quadrangle arc 1 " << ( aBuilder1.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1393 #endif
1394
1395       VTKViewer_ArcBuilder aBuilder2(P1,P4,P2,myMaxArcAngle); //Build arc using 1, 4 and 2 points
1396 #ifdef __MYDEBUG__
1397       cout << "Quadrangle arc 2 " << ( aBuilder2.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1398 #endif
1399
1400       VTKViewer_ArcBuilder aBuilder3(P2,P5,P0,myMaxArcAngle); //Build arc using 2, 5 and 0 points
1401 #ifdef __MYDEBUG__
1402       cout << "Quadrangle arc 3 " << ( aBuilder3.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1403 #endif
1404
1405       aCollection.push_back(aBuilder1.GetPoints());
1406       aCollection.push_back(aBuilder2.GetPoints());
1407       aCollection.push_back(aBuilder3.GetPoints());
1408
1409       aScalarCollection.push_back(aBuilder1.GetScalarValues());
1410       aScalarCollection.push_back(aBuilder2.GetScalarValues());
1411       aScalarCollection.push_back(aBuilder3.GetScalarValues());
1412       break;
1413     }
1414     case VTK_QUADRATIC_QUAD:
1415     case VTK_BIQUADRATIC_QUAD:
1416     {
1417       //Get All points from input cell
1418       Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
1419       Pnt P1 = CreatePnt( aCell, inputScalars, 1 );
1420       Pnt P2 = CreatePnt( aCell, inputScalars, 2 );
1421       Pnt P3 = CreatePnt( aCell, inputScalars, 3 );
1422       Pnt P4 = CreatePnt( aCell, inputScalars, 4 );
1423       Pnt P5 = CreatePnt( aCell, inputScalars, 5 );
1424       Pnt P6 = CreatePnt( aCell, inputScalars, 6 );
1425       Pnt P7 = CreatePnt( aCell, inputScalars, 7 );
1426
1427       VTKViewer_ArcBuilder aBuilder1(P0,P4,P1,myMaxArcAngle); //Build arc using 0, 4 and 1 points
1428 #ifdef __MYDEBUG__
1429       cout << "Quadrangle arc 1 " << ( aBuilder1.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1430 #endif
1431
1432       VTKViewer_ArcBuilder aBuilder2(P1,P5,P2,myMaxArcAngle); //Build arc using 1, 5 and 2 points
1433 #ifdef __MYDEBUG__
1434       cout << "Quadrangle arc 2 " << ( aBuilder2.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1435 #endif
1436
1437       VTKViewer_ArcBuilder aBuilder3(P2,P6,P3,myMaxArcAngle); //Build arc using 2, 6 and 3 points
1438 #ifdef __MYDEBUG__
1439       cout << "Quadrangle arc 3 " << ( aBuilder3.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1440 #endif
1441
1442       VTKViewer_ArcBuilder aBuilder4(P3,P7,P0,myMaxArcAngle); //Build arc using 3, 7 and 0 points
1443 #ifdef __MYDEBUG__
1444       cout << "Quadrangle arc 4 " << ( aBuilder4.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
1445 #endif
1446
1447       aCollection.push_back(aBuilder1.GetPoints());
1448       aCollection.push_back(aBuilder2.GetPoints());
1449       aCollection.push_back(aBuilder3.GetPoints());
1450       aCollection.push_back(aBuilder4.GetPoints());
1451
1452       aScalarCollection.push_back(aBuilder1.GetScalarValues());
1453       aScalarCollection.push_back(aBuilder2.GetScalarValues());
1454       aScalarCollection.push_back(aBuilder3.GetScalarValues());
1455       aScalarCollection.push_back(aBuilder4.GetScalarValues());
1456       break;
1457     }
1458     default: //Unsupported cell type
1459       return;
1460   }
1461
1462   if(triangulate){
1463     const vtkIdType numFacePts = 3;
1464     vtkIdList *pts = vtkIdList::New();
1465     vtkPoints *coords = vtkPoints::New();
1466     aCellType = VTK_TRIANGLE;
1467     vtkIdType aNewPts[numFacePts];
1468     vtkIdType aTriangleId;
1469
1470     vtkPolygon *aPlg = vtkPolygon::New();
1471     std::map<int, double> aPntId2ScalarValue;
1472     aNbPoints = MergevtkPoints(aCollection, aScalarCollection, aPlg->GetPoints(), aPntId2ScalarValue, aNewPoints);
1473     aPlg->GetPointIds()->SetNumberOfIds(aNbPoints);
1474
1475     for(vtkIdType i = 0; i < aNbPoints;i++) {
1476       aPlg->GetPointIds()->SetId(i, aNewPoints[i]);
1477     }
1478
1479     aPlg->Triangulate(0,pts,coords);
1480
1481     for (vtkIdType i=0; i < pts->GetNumberOfIds(); i+=3) {
1482       aNewPts[0] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i));
1483       aNewPts[1] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i+1));
1484       aNewPts[2] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i+2));
1485
1486       if(outputScalars) {
1487         outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i)]);
1488         outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i+1)]);
1489         outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i+2)]);
1490       }
1491
1492       aTriangleId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
1493
1494       if(myStoreMapping)
1495         InsertId( cellId, aCellType, myVTK2ObjIds, theDimension2VTK2ObjIds );
1496       outputCD->CopyData(cd,cellId,aTriangleId);
1497     }
1498     pts->Delete();
1499     coords->Delete();
1500     aPlg->Delete();
1501   }
1502   else {
1503     std::map<int, double> aPntId2ScalarValue;
1504     aNbPoints = MergevtkPoints(aCollection, aScalarCollection, output->GetPoints(), aPntId2ScalarValue, aNewPoints);
1505     if(outputScalars)
1506       for(vtkIdType i = 0; i < aNbPoints; i++)
1507         outputScalars->InsertNextTuple1(aPntId2ScalarValue[aNewPoints[i]]);
1508     newCellId = output->InsertNextCell(aCellType,aNbPoints,aNewPoints);
1509     outputCD->CopyData(cd,cellId,newCellId);
1510
1511     if(myStoreMapping)
1512       InsertId( cellId, aCellType, myVTK2ObjIds, theDimension2VTK2ObjIds );
1513   }
1514
1515   if (aNewPoints)
1516     delete [] aNewPoints;
1517 }
1518
1519
1520 void VTKViewer_GeometryFilter::SetQuadraticArcMode(bool theFlag)
1521 {
1522   if(myIsBuildArc != theFlag) {
1523     myIsBuildArc = theFlag;
1524     this->Modified();
1525   }
1526 }
1527 bool VTKViewer_GeometryFilter::GetQuadraticArcMode() const
1528 {
1529   return myIsBuildArc;
1530 }
1531
1532 void VTKViewer_GeometryFilter::SetQuadraticArcAngle(double theMaxAngle)
1533 {
1534   if(myMaxArcAngle != theMaxAngle) {
1535     myMaxArcAngle = theMaxAngle;
1536     this->Modified();
1537   }
1538 }
1539
1540 double VTKViewer_GeometryFilter:: GetQuadraticArcAngle() const
1541 {
1542   return myMaxArcAngle;
1543 }
1544
1545 int VTKViewer_GeometryFilter::GetAppendCoincident3D() const {
1546 // VSR 26/10/2012: see description of SHOW_COINCIDING_3D_PAL20314
1547 // in the top of this file
1548 #ifdef SHOW_COINCIDING_3D_PAL20314
1549   return myAppendCoincident3D;
1550 #else
1551   return false;
1552 #endif
1553 }
1554
1555 void VTKViewer_GeometryFilter::SetAppendCoincident3D(int theFlag) {
1556   if(myAppendCoincident3D != theFlag){
1557     myAppendCoincident3D = theFlag;
1558     this->Modified();
1559   }
1560 }