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