Salome HOME
Merge modifications for HYDRO project (origin/hydro/imps_2017_salome_83 branch)
[modules/gui.git] / src / VTKViewer / VTKViewer_GeometryFilter.cxx
index f004c867b576d5e0e545606da561a05e8daf532c..cdc26ff24f1574b5f9869bf61e1dea9e8f09b03f 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -48,6 +48,7 @@
 #include <vtkUnstructuredGrid.h>
 #include <vtkVoxel.h>
 #include <vtkWedge.h>
+#include <vtkVersion.h>
 
 #include <algorithm>
 #include <iterator>
 //#define __MYDEBUG__
 //#define USE_ROBUST_TRIANGULATION
 
-vtkCxxRevisionMacro(VTKViewer_GeometryFilter, "$Revision$");
+///////////////////////////////////////////////////////////////////////////////////////////////
+// VSR 26/10/2012: fix of regression (issue 21924) - increased memory consumption
+// for displaying of 3d elements, introduced by fix for issue 20314.
+// ...
+// The macro SHOW_COINCIDING_3D_PAL20314, when defined, allows correct visualization of
+// coincident 3d elements but causes substantial increasing of memory consumption, as all 3d 
+// elements are always shown, even if they are totally covered by surrounding faces.
+// If this macro is not defined (commented), the behaviour is defined by another macro -
+// SHOW_COINCIDING_3D_PAL21924, as follows:
+// - If SHOW_COINCIDING_3D_PAL21924 is defined, an alternative solution for computing 
+//   visibility of 3d elements is used; this solution allows to fix problem with visibility
+//   of coinciding 3d elements in most cases (though some cases might not work), while not
+//   causing significant increasing of memory consumption.
+// - If SHOW_COINCIDING_3D_PAL21924 is not defined (commented), coinciding 3d elements are 
+//   not shown at all (this corresponds to the state before issue 20314 fixing).
+///////////////////////////////////////////////////////////////////////////////////////////////
+//#define SHOW_COINCIDING_3D_PAL20314
+#ifndef SHOW_COINCIDING_3D_PAL20314
+#define SHOW_COINCIDING_3D_PAL21924
+#endif
+///////////////////////////////////////////////////////////////////////////////////////////////
+
 vtkStandardNewMacro(VTKViewer_GeometryFilter);
 
 VTKViewer_GeometryFilter
 ::VTKViewer_GeometryFilter():
   myShowInside(0),
   myStoreMapping(0),
-  myAppendCoincident3D(0),
   myIsWireframeMode(0),
-  myIsBuildArc(false),
-  myMaxArcAngle(2)
+  myAppendCoincident3D(0),
+  myMaxArcAngle(2),
+  myIsBuildArc(false)
 {}
 
 
@@ -86,6 +108,39 @@ VTKViewer_GeometryFilter
 ::~VTKViewer_GeometryFilter()
 {}
 
+/*!
+ * \brief Return true for only one volume including a given edge
+ *  \param [in] id1 - 1st edge end
+ *  \param [in] id2 - second edge end
+ *  \param [in] cellId - volume ID
+ *  \param [in] input - the grid
+ */
+static inline bool toShowEdge( vtkIdType id1, vtkIdType id2, vtkIdType cellId, vtkUnstructuredGrid* input )
+{
+  // return true if the given cell is the 1st among cells including the edge
+  vtkCellLinks * links = input->GetCellLinks();
+  if ( !links ) {
+    input->BuildLinks();
+    links = input->GetCellLinks();
+  }
+  if ( id1 < id2 )
+    std::swap( id1, id2 );
+  vtkIdType *cells = links->GetCells( id1 );
+
+  // among cells, look for a cell including the edge
+  vtkIdType *cellPts, npts, iCell = 0;
+  bool found = false;
+  while ( !found )
+  {
+    if ( cells[iCell] == cellId )
+      return true;
+    input->GetCellPoints( cells[iCell], npts, cellPts );
+    for ( vtkIdType i = 0; i < npts && !found; ++i )
+      found = ( cellPts[i] == id2 );
+    iCell += ( !found );
+  }
+  return ( cells[iCell] == cellId );
+}
 
 int
 VTKViewer_GeometryFilter
@@ -119,15 +174,12 @@ VTKViewer_GeometryFilter
   return 1;
 }
 
-
 int
 VTKViewer_GeometryFilter
-::UnstructuredGridExecute(
-                          vtkDataSet *dataSetInput,
+::UnstructuredGridExecute(vtkDataSet *dataSetInput,
                           vtkPolyData *output,
                           vtkInformation *outInfo)
 {
-
   vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)dataSetInput;
   vtkCellArray *Connectivity = input->GetCells();
   // Check input
@@ -156,17 +208,20 @@ VTKViewer_GeometryFilter
 
   vtkIdList *cellIds = vtkIdList::New();
   vtkIdList *faceIds = vtkIdList::New();
+  vtkIdList *cellIdsTmp = vtkIdList::New();
+  vtkIdList *faceIdsTmp = vtkIdList::New();
+  std::set< vtkIdType > midPoints;
 
   char *cellVis;
   vtkIdType newCellId;
-  int faceId, *faceVerts, numFacePts;
-  vtkFloatingPointType *x;
+  int faceId, *faceVerts, *edgeVerts, numFacePts;
+  double *x;
   vtkIdType PixelConvert[4];
   // Change the type from int to vtkIdType in order to avoid compilation errors while using VTK
   // from ParaView-3.4.0 compiled on 64-bit Debian platform with VTK_USE_64BIT_IDS = ON
   vtkIdType aNewPts[VTK_CELL_SIZE];
   // ghost cell stuff
-  unsigned char  updateLevel = (unsigned char)(output->GetUpdateGhostLevel());
+  unsigned char  updateLevel = (unsigned char)(GetUpdateGhostLevel());
   unsigned char  *cellGhostLevels = 0;
 
   PixelConvert[0] = 0;
@@ -204,12 +259,39 @@ VTKViewer_GeometryFilter
     cellVis = new char[numCells];
     }
 
-  // Issue 0020115: [CEA 308] Quadratic elements visualization
-  // Fix of remark described in note 0005222 - SIGSEGV
-  vtkPoints* outputPoints = vtkPoints::New();
-  outputPoints->DeepCopy(input->GetPoints());
-  output->SetPoints(outputPoints);
-  outputPoints->Delete();
+  bool buildArcs = false;
+  if ( myIsBuildArc )
+  {
+    // check if there are quadratic 1D or 2D elements
+    bool hasQuad1D2D = false;
+    if ( vtkUnsignedCharArray* types = input->GetCellTypesArray() )
+    {
+      std::set<vtkIdType> quad1D2DTypes;
+      quad1D2DTypes.insert( VTK_QUADRATIC_EDGE );
+      quad1D2DTypes.insert( VTK_QUADRATIC_TRIANGLE );
+      quad1D2DTypes.insert( VTK_BIQUADRATIC_TRIANGLE );
+      quad1D2DTypes.insert( VTK_QUADRATIC_QUAD );
+      quad1D2DTypes.insert( VTK_BIQUADRATIC_QUAD );
+      quad1D2DTypes.insert( VTK_QUADRATIC_POLYGON );
+
+      for ( int i = 0; i < types->GetNumberOfTuples() && !hasQuad1D2D; ++i )
+        hasQuad1D2D = quad1D2DTypes.count( types->GetValue(i) );
+    }
+    buildArcs = hasQuad1D2D;
+  }
+  if ( buildArcs )
+  {
+    // Issue 0020115: [CEA 308] Quadratic elements visualization
+    // Fix of remark described in note 0005222 - SIGSEGV
+    vtkPoints* outputPoints = vtkPoints::New();
+    outputPoints->DeepCopy(input->GetPoints());
+    output->SetPoints(outputPoints);
+    outputPoints->Delete();
+  }
+  else
+  {
+    output->SetPoints(input->GetPoints());
+  }
 
   outputPD->PassData(pd);
 
@@ -219,21 +301,21 @@ VTKViewer_GeometryFilter
 
   // Loop over the cells determining what's visible
   if (!allVisible)
-    {
+  {
     for (cellId=0, Connectivity->InitTraversal();
          Connectivity->GetNextCell(npts,pts);
          cellId++)
-      {
+    {
       cellVis[cellId] = 1;
       if ( ( this->CellClipping && cellId < this->CellMinimum ) ||
            cellId > this->CellMaximum )
-        {
+      {
         cellVis[cellId] = 0;
-        }
+      }
       else
-        {
+      {
         for (i=0; i < npts; i++)
-          {
+        {
           x = p->GetPoint(pts[i]);
           if ( ( ( ( this->PointClipping && (pts[i] < this->PointMinimum ) ) ||
                                              pts[i] > this->PointMaximum) ) ||
@@ -241,42 +323,44 @@ VTKViewer_GeometryFilter
                 ( x[0] < this->Extent[0] || x[0] > this->Extent[1] ||
                   x[1] < this->Extent[2] || x[1] > this->Extent[3] ||
                   x[2] < this->Extent[4] || x[2] > this->Extent[5] )) )
-            {
+          {
             cellVis[cellId] = 0;
             break;
-            }//point/extent clipping
-          }//for each point
-        }//if point clipping needs checking
-      }//for all cells
-    }//if not all visible
+          }//point/extent clipping
+        }//for each point
+      }//if point clipping needs checking
+    }//for all cells
+  }//if not all visible
+
+  if ( input->GetCellLinks() )
+    input->BuildLinks();
 
   // Loop over all cells now that visibility is known
-  // (Have to compute visibility first for 3D cell boundarys)
+  // (Have to compute visibility first for 3D cell boundaries)
   int progressInterval = numCells/20 + 1;
   TMapOfVectorId aDimension2VTK2ObjIds;
-  if(myStoreMapping){
-    myVTK2ObjIds.clear();
-    myVTK2ObjIds.reserve(numCells);
-  }
+  if ( myStoreMapping )
+    aDimension2VTK2ObjIds.resize( 3 ); // max dimension is 2
+
   for (cellId=0, Connectivity->InitTraversal();
        Connectivity->GetNextCell(npts,pts);
        cellId++)
-    {
+  {
     //Progress and abort method support
     if ( !(cellId % progressInterval) )
-      {
+    {
       vtkDebugMacro(<<"Process cell #" << cellId);
       this->UpdateProgress ((float)cellId/numCells);
-      }
+    }
 
     // Handle ghost cells here.  Another option was used cellVis array.
     if (cellGhostLevels && cellGhostLevels[cellId] > updateLevel)
-      { // Do not create surfaces in outer ghost cells.
+    { // Do not create surfaces in outer ghost cells.
       continue;
-      }
+    }
 
     if (allVisible || cellVis[cellId])  //now if visible extract geometry
-      {
+    {
       //special code for nonlinear cells - rarely occurs, so right now it
       //is slow.
       vtkIdType aCellType = input->GetCellType(cellId);
@@ -331,7 +415,7 @@ VTKViewer_GeometryFilter
                                                       cellId,
                                                       myShowInside,
                                                       allVisible,
-                                                      myAppendCoincident3D,
+                                                      GetAppendCoincident3D(),
                                                       cellVis,
                                                       output,
                                                       outputCD,
@@ -345,7 +429,7 @@ VTKViewer_GeometryFilter
                                           cellId,
                                           myShowInside,
                                           allVisible,
-                                          myAppendCoincident3D,
+                                          GetAppendCoincident3D(),
                                           cellVis,
                                           output,
                                           outputCD,
@@ -356,240 +440,448 @@ VTKViewer_GeometryFilter
 
           break;
         }
-        case VTK_TETRA: {
-          for (faceId = 0; faceId < 4; faceId++)
+        case VTK_TETRA:
+        {
+          if ( myShowInside )
+          {
+            aCellType = VTK_LINE;
+            for ( int edgeID = 0; edgeID < 6; ++edgeID )
             {
-            faceIds->Reset();
-            faceVerts = vtkTetra::GetFaceArray(faceId);
-            faceIds->InsertNextId(pts[faceVerts[0]]);
-            faceIds->InsertNextId(pts[faceVerts[1]]);
-            faceIds->InsertNextId(pts[faceVerts[2]]);
+              edgeVerts = vtkTetra::GetEdgeArray( edgeID );
+              if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
+              {
+                aNewPts[0] = pts[edgeVerts[0]];
+                aNewPts[1] = pts[edgeVerts[1]];
+                newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
+              }
+            }
+            break;
+          }
+          else
+          {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+            faceIdsTmp->SetNumberOfIds( npts );
+            for ( int ai = 0; ai < npts; ai++ )
+              faceIdsTmp->SetId( ai, pts[ai] );
+            input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
             aCellType = VTK_TRIANGLE;
             numFacePts = 3;
-            input->GetCellNeighbors(cellId, faceIds, cellIds);
-            bool process = cellIds->GetNumberOfIds() <= 0 ? true : myAppendCoincident3D;
-            if ( process || myShowInside ||
-                 (!allVisible && !cellVis[cellIds->GetId(0)]) )
+            for (faceId = 0; faceId < 4; faceId++)
+            {
+              faceIds->Reset();
+              faceVerts = vtkTetra::GetFaceArray(faceId);
+              faceIds->InsertNextId(pts[faceVerts[0]]);
+              faceIds->InsertNextId(pts[faceVerts[1]]);
+              faceIds->InsertNextId(pts[faceVerts[2]]);
+              input->GetCellNeighbors(cellId, faceIds, cellIds);
+              int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
+#ifdef SHOW_COINCIDING_3D_PAL21924
+              bool process = nbNeighbors <= 0;
+#else
+              bool process = nbNeighbors <= 0 || GetAppendCoincident3D();
+#endif
+              if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
               {
-              for ( i=0; i < numFacePts; i++)
-                aNewPts[i] = pts[faceVerts[i]];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
+                for ( i=0; i < numFacePts; i++)
+                  aNewPts[i] = pts[faceVerts[i]];
+                newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
               }
             }
+          }
           break;
         }
-        case VTK_VOXEL: {
-          for (faceId = 0; faceId < 6; faceId++)
+        case VTK_VOXEL:
+        {
+          if ( myShowInside )
+          {
+            aCellType = VTK_LINE;
+            for ( int edgeID = 0; edgeID < 12; ++edgeID )
             {
-            faceIds->Reset();
-            faceVerts = vtkVoxel::GetFaceArray(faceId);
-            faceIds->InsertNextId(pts[faceVerts[0]]);
-            faceIds->InsertNextId(pts[faceVerts[1]]);
-            faceIds->InsertNextId(pts[faceVerts[2]]);
-            faceIds->InsertNextId(pts[faceVerts[3]]);
-            aCellType = VTK_QUAD;
-            numFacePts = 4;
-            input->GetCellNeighbors(cellId, faceIds, cellIds);
-            bool process = cellIds->GetNumberOfIds() <= 0 ? true : myAppendCoincident3D;
-            if ( process || myShowInside ||
-                 (!allVisible && !cellVis[cellIds->GetId(0)]) )
+              edgeVerts = vtkVoxel::GetEdgeArray( edgeID );
+              if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
               {
-              for ( i=0; i < numFacePts; i++)
-                aNewPts[i] = pts[faceVerts[PixelConvert[i]]];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
+                aNewPts[0] = pts[edgeVerts[0]];
+                aNewPts[1] = pts[edgeVerts[1]];
+                newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
               }
             }
+            break;
+          }
+          else
+          {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+            faceIdsTmp->SetNumberOfIds( npts );
+            for ( int ai = 0; ai < npts; ai++ )
+              faceIdsTmp->SetId( ai, pts[ai] );
+            input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
+            for (faceId = 0; faceId < 6; faceId++)
+            {
+              faceIds->Reset();
+              faceVerts = vtkVoxel::GetFaceArray(faceId);
+              faceIds->InsertNextId(pts[faceVerts[0]]);
+              faceIds->InsertNextId(pts[faceVerts[1]]);
+              faceIds->InsertNextId(pts[faceVerts[2]]);
+              faceIds->InsertNextId(pts[faceVerts[3]]);
+              aCellType = VTK_QUAD;
+              numFacePts = 4;
+              input->GetCellNeighbors(cellId, faceIds, cellIds);
+              int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
+#ifdef SHOW_COINCIDING_3D_PAL21924
+              bool process = nbNeighbors <= 0;
+#else
+              bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
+#endif
+              if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
+              {
+                for ( i=0; i < numFacePts; i++)
+                  aNewPts[i] = pts[faceVerts[PixelConvert[i]]];
+                newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
+              }
+            }
+          }
           break;
         }
-        case VTK_HEXAHEDRON: {
-          for (faceId = 0; faceId < 6; faceId++)
+        case VTK_HEXAHEDRON:
+        {
+          if ( myShowInside )
+          {
+            aCellType = VTK_LINE;
+            for ( int edgeID = 0; edgeID < 12; ++edgeID )
             {
-            faceIds->Reset();
-            faceVerts = vtkHexahedron::GetFaceArray(faceId);
-            faceIds->InsertNextId(pts[faceVerts[0]]);
-            faceIds->InsertNextId(pts[faceVerts[1]]);
-            faceIds->InsertNextId(pts[faceVerts[2]]);
-            faceIds->InsertNextId(pts[faceVerts[3]]);
+              edgeVerts = vtkHexahedron::GetEdgeArray( edgeID );
+              if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
+              {
+                aNewPts[0] = pts[edgeVerts[0]];
+                aNewPts[1] = pts[edgeVerts[1]];
+                newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
+              }
+            }
+            break;
+          }
+          else
+          {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+            faceIdsTmp->SetNumberOfIds( npts );
+            for ( int ai = 0; ai < npts; ai++ )
+              faceIdsTmp->SetId( ai, pts[ai] );
+            input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
             aCellType = VTK_QUAD;
             numFacePts = 4;
-            input->GetCellNeighbors(cellId, faceIds, cellIds);
-            bool process = cellIds->GetNumberOfIds() <= 0 ? true : myAppendCoincident3D;
-            if ( process || myShowInside ||
-                 (!allVisible && !cellVis[cellIds->GetId(0)]) )
+            for (faceId = 0; faceId < 6; faceId++)
+            {
+              faceIds->Reset();
+              faceVerts = vtkHexahedron::GetFaceArray(faceId);
+              faceIds->InsertNextId(pts[faceVerts[0]]);
+              faceIds->InsertNextId(pts[faceVerts[1]]);
+              faceIds->InsertNextId(pts[faceVerts[2]]);
+              faceIds->InsertNextId(pts[faceVerts[3]]);
+              input->GetCellNeighbors(cellId, faceIds, cellIds);
+              int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
+#ifdef SHOW_COINCIDING_3D_PAL21924
+              bool process = nbNeighbors <= 0;
+#else
+              bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
+#endif
+              if ( process || (!allVisible && !cellVis[cellIds->GetId(0)]) )
               {
-              for ( i=0; i < numFacePts; i++)
-                aNewPts[i] = pts[faceVerts[i]];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
+                for ( i=0; i < numFacePts; i++)
+                  aNewPts[i] = pts[faceVerts[i]];
+                newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
               }
             }
+          }
           break;
         }
-        case VTK_WEDGE: {
-          for (faceId = 0; faceId < 5; faceId++)
+        case VTK_WEDGE:
+        {
+          if ( myShowInside )
+          {
+            aCellType = VTK_LINE;
+            for ( int edgeID = 0; edgeID < 9; ++edgeID )
             {
-            faceIds->Reset();
-            faceVerts = vtkWedge::GetFaceArray(faceId);
-            faceIds->InsertNextId(pts[faceVerts[0]]);
-            faceIds->InsertNextId(pts[faceVerts[1]]);
-            faceIds->InsertNextId(pts[faceVerts[2]]);
-            aCellType = VTK_TRIANGLE;
-            numFacePts = 3;
-            if (faceVerts[3] >= 0)
+              edgeVerts = vtkWedge::GetEdgeArray( edgeID );
+              if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
               {
-              faceIds->InsertNextId(pts[faceVerts[3]]);
-              aCellType = VTK_QUAD;
-              numFacePts = 4;
+                aNewPts[0] = pts[edgeVerts[0]];
+                aNewPts[1] = pts[edgeVerts[1]];
+                newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
               }
-
-            input->GetCellNeighbors(cellId, faceIds, cellIds);
-            bool process = cellIds->GetNumberOfIds() <= 0 ? true : myAppendCoincident3D;
-            if ( process || myShowInside ||
-                 (!allVisible && !cellVis[cellIds->GetId(0)]) )
+            }
+            break;
+          }
+          else
+          {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+            faceIdsTmp->SetNumberOfIds( npts );
+            for ( int ai = 0; ai < npts; ai++ )
+              faceIdsTmp->SetId( ai, pts[ai] );
+            input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
+            for (faceId = 0; faceId < 5; faceId++)
+            {
+              faceIds->Reset();
+              faceVerts = vtkWedge::GetFaceArray(faceId);
+              faceIds->InsertNextId(pts[faceVerts[0]]);
+              faceIds->InsertNextId(pts[faceVerts[1]]);
+              faceIds->InsertNextId(pts[faceVerts[2]]);
+              aCellType = VTK_TRIANGLE;
+              numFacePts = 3;
+              if (faceVerts[3] >= 0)
               {
-              for ( i=0; i < numFacePts; i++)
-                aNewPts[i] = pts[faceVerts[i]];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
+                faceIds->InsertNextId(pts[faceVerts[3]]);
+                aCellType = VTK_QUAD;
+                numFacePts = 4;
+              }
+              input->GetCellNeighbors(cellId, faceIds, cellIds);
+              int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
+#ifdef SHOW_COINCIDING_3D_PAL21924
+              bool process = nbNeighbors <= 0;
+#else
+              bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
+#endif
+              if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
+              {
+                for ( i=0; i < numFacePts; i++)
+                  aNewPts[i] = pts[faceVerts[i]];
+                newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
               }
             }
+          }
           break;
         }
-        case VTK_HEXAGONAL_PRISM: {
-          for (faceId = 0; faceId < 8; faceId++)
+        case VTK_HEXAGONAL_PRISM:
+        {
+          if ( myShowInside )
           {
-            faceVerts = vtkHexagonalPrism::GetFaceArray(faceId);
-            faceIds->Reset();
-            faceIds->InsertNextId(pts[faceVerts[0]]);
-            faceIds->InsertNextId(pts[faceVerts[1]]);
-            faceIds->InsertNextId(pts[faceVerts[2]]);
-            faceIds->InsertNextId(pts[faceVerts[3]]);
-            aCellType = VTK_QUAD;
-            numFacePts = 4;
-            if (faceVerts[5] >= 0)
+            aCellType = VTK_LINE;
+            for ( int edgeID = 0; edgeID < 18; ++edgeID )
             {
-              faceIds->InsertNextId(pts[faceVerts[4]]);
-              faceIds->InsertNextId(pts[faceVerts[5]]);
-              aCellType = VTK_POLYGON;
-              numFacePts = 6;
+              edgeVerts = vtkHexagonalPrism::GetEdgeArray( edgeID );
+              if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
+              {
+                aNewPts[0] = pts[edgeVerts[0]];
+                aNewPts[1] = pts[edgeVerts[1]];
+                newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
+              }
             }
-            input->GetCellNeighbors(cellId, faceIds, cellIds);
-            bool process = cellIds->GetNumberOfIds() <= 0 ? true : myAppendCoincident3D;
-            if ( process || myShowInside ||
-                 (!allVisible && !cellVis[cellIds->GetId(0)]) )
+            break;
+          }
+          else
+          {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+            faceIdsTmp->SetNumberOfIds( npts );
+            for ( int ai = 0; ai < npts; ai++ )
+              faceIdsTmp->SetId( ai, pts[ai] );
+            input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
+            for (faceId = 0; faceId < 8; faceId++)
             {
-              for ( i=0; i < numFacePts; i++)
-                aNewPts[i] = pts[faceVerts[i]];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
-            }
+              faceVerts = vtkHexagonalPrism::GetFaceArray(faceId);
+              faceIds->Reset();
+              faceIds->InsertNextId(pts[faceVerts[0]]);
+              faceIds->InsertNextId(pts[faceVerts[1]]);
+              faceIds->InsertNextId(pts[faceVerts[2]]);
+              faceIds->InsertNextId(pts[faceVerts[3]]);
+              aCellType = VTK_QUAD;
+              numFacePts = 4;
+              if (faceVerts[5] >= 0)
+              {
+                faceIds->InsertNextId(pts[faceVerts[4]]);
+                faceIds->InsertNextId(pts[faceVerts[5]]);
+                aCellType = VTK_POLYGON;
+                numFacePts = 6;
+              }
+              input->GetCellNeighbors(cellId, faceIds, cellIds);
+              int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
+#ifdef SHOW_COINCIDING_3D_PAL21924
+              bool process = nbNeighbors <= 0;
+#else
+              bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
+#endif
+              if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
+              {
+                for ( i=0; i < numFacePts; i++)
+                  aNewPts[i] = pts[faceVerts[i]];
+                newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
+              }
             }
+          }
           break;
         }
-        case VTK_PYRAMID: {
-          for (faceId = 0; faceId < 5; faceId++)
+        case VTK_PYRAMID:
+        {
+          if ( myShowInside )
+          {
+            aCellType = VTK_LINE;
+            for ( int edgeID = 0; edgeID < 8; ++edgeID )
             {
-            faceIds->Reset();
-            faceVerts = vtkPyramid::GetFaceArray(faceId);
-            faceIds->InsertNextId(pts[faceVerts[0]]);
-            faceIds->InsertNextId(pts[faceVerts[1]]);
-            faceIds->InsertNextId(pts[faceVerts[2]]);
-            aCellType = VTK_TRIANGLE;
-            numFacePts = 3;
-            if (faceVerts[3] >= 0)
+              edgeVerts = vtkPyramid::GetEdgeArray( edgeID );
+              if ( toShowEdge( pts[edgeVerts[0]], pts[edgeVerts[1]], cellId, input ))
               {
-              faceIds->InsertNextId(pts[faceVerts[3]]);
-              aCellType = VTK_QUAD;
-              numFacePts = 4;
+                aNewPts[0] = pts[edgeVerts[0]];
+                aNewPts[1] = pts[edgeVerts[1]];
+                newCellId = output->InsertNextCell( aCellType, 2, aNewPts );
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
               }
-            input->GetCellNeighbors(cellId, faceIds, cellIds);
-            bool process = cellIds->GetNumberOfIds() <= 0 ? true : myAppendCoincident3D;
-            if ( process || myShowInside ||
-                 (!allVisible && !cellVis[cellIds->GetId(0)]) )
+            }
+            break;
+          }
+          else
+          {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+            faceIdsTmp->SetNumberOfIds( npts );
+            for ( int ai = 0; ai < npts; ai++ )
+              faceIdsTmp->SetId( ai, pts[ai] );
+            input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
+            for (faceId = 0; faceId < 5; faceId++)
+            {
+              faceIds->Reset();
+              faceVerts = vtkPyramid::GetFaceArray(faceId);
+              faceIds->InsertNextId(pts[faceVerts[0]]);
+              faceIds->InsertNextId(pts[faceVerts[1]]);
+              faceIds->InsertNextId(pts[faceVerts[2]]);
+              aCellType = VTK_TRIANGLE;
+              numFacePts = 3;
+              if (faceVerts[3] >= 0)
               {
-              for ( i=0; i < numFacePts; i++)
-                aNewPts[i] = pts[faceVerts[i]];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
+                faceIds->InsertNextId(pts[faceVerts[3]]);
+                aCellType = VTK_QUAD;
+                numFacePts = 4;
+              }
+              input->GetCellNeighbors(cellId, faceIds, cellIds);
+              int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
+#ifdef SHOW_COINCIDING_3D_PAL21924
+              bool process = nbNeighbors <= 0;
+#else
+              bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
+#endif
+              if ( process || ( !allVisible && !cellVis[cellIds->GetId(0)] ))
+              {
+                for ( i=0; i < numFacePts; i++)
+                  aNewPts[i] = pts[faceVerts[i]];
+                newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
               }
             }
+          }
           break;
         }
 
 #if VTK_XVERSION > 50700
         case VTK_POLYHEDRON:
+        {
+          vtkIdType nFaces = 0;
+          vtkIdType* ptIds = 0;
+          int idp = 0;
+          input->GetFaceStream(cellId, nFaces, ptIds);
+#ifdef SHOW_COINCIDING_3D_PAL21924
+          if ( !myShowInside )
           {
-            //MESSAGE("VTK_POLYHEDRON geometry filter");
-            vtkIdType nFaces = 0;
-            vtkIdType* ptIds = 0;
-            int idp = 0;
-            input->GetFaceStream(cellId, nFaces, ptIds);
-            for (faceId = 0; faceId < nFaces; faceId++)
-              {
-                faceIds->Reset();
-                numFacePts = ptIds[idp];
-                //MESSAGE("numFacePts="<< numFacePts);
-                int pt0 = ++idp;
-                for (i = 0; i < numFacePts; i++)
-                  {
-                    //MESSAGE("ptIds[" << idp + i << "]=" << ptIds[idp + i]);
-                    faceIds->InsertNextId(ptIds[idp + i]);
-                  }
-                idp += numFacePts;
-                switch (numFacePts)
-                  {
-                  case 3:
-                    aCellType = VTK_TRIANGLE;
-                    break;
-                  case 4:
-                    aCellType = VTK_QUAD;
-                    break;
-                  default:
-                    aCellType = VTK_POLYGON;
-                    break;
-                  }
-                // TODO understand and fix display of several polyhedrons                
-                input->GetCellNeighbors(cellId, faceIds, cellIds);
-                bool process = cellIds->GetNumberOfIds() <= 0 ? true : myAppendCoincident3D;
-                if (process || myShowInside
-                    || (!allVisible && !cellVis[cellIds->GetId(0)]))
-                  {
-                    for (i = 0; i < numFacePts; i++)
-                      aNewPts[i] = ptIds[pt0 + i];
-                    newCellId = output->InsertNextCell(aCellType, numFacePts, aNewPts);
-                    if (myStoreMapping)
-                      InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-                    outputCD->CopyData(cd, cellId, newCellId);
-                  }
-              }
-            break;
+            faceIdsTmp->Reset(); // use 2 facets
+            numFacePts = ptIds[idp];
+            for (i = 0; i < numFacePts; i++)
+              faceIdsTmp->InsertNextId(ptIds[idp + i]);
+            idp += numFacePts+1;
+            numFacePts = ptIds[idp];
+            for (i = 0; i < numFacePts; i++)
+              faceIdsTmp->InsertNextId(ptIds[idp + i]);
+            input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+            idp = 0;
           }
+#endif
+          for (faceId = 0; faceId < nFaces; faceId++)
+          {
+            faceIds->Reset();
+            numFacePts = ptIds[idp];
+            int pt0 = ++idp;
+            for (i = 0; i < numFacePts; i++)
+            {
+              faceIds->InsertNextId(ptIds[idp + i]);
+            }
+            idp += numFacePts;
+            switch (numFacePts)
+            {
+            case 3: aCellType = VTK_TRIANGLE; break;
+            case 4: aCellType = VTK_QUAD;     break;
+            default:aCellType = VTK_POLYGON;
+            }
+            input->GetCellNeighbors(cellId, faceIds, cellIds);
+            int nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
+            if ( myShowInside && nbNeighbors > 0 && cellId < cellIds->GetId(0) )
+              continue; // don't add twice same internal face in wireframe mode
+#ifdef SHOW_COINCIDING_3D_PAL21924
+            bool process = nbNeighbors <= 0;
+#else
+            bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
+#endif
+            if (process || myShowInside
+                || (!allVisible && !cellVis[cellIds->GetId(0)]))
+            {
+              for (i = 0; i < numFacePts; i++)
+                aNewPts[i] = ptIds[pt0 + i];
+              newCellId = output->InsertNextCell(aCellType, numFacePts, aNewPts);
+              if (myStoreMapping)
+                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+              outputCD->CopyData(cd, cellId, newCellId);
+            }
+          }
+          break;
+        }
 #endif
         //Quadratic cells
         case VTK_QUADRATIC_EDGE:
         case VTK_QUADRATIC_TRIANGLE:
+        case VTK_BIQUADRATIC_TRIANGLE:
         case VTK_QUADRATIC_QUAD:
         case VTK_BIQUADRATIC_QUAD:
+        case VTK_QUADRATIC_POLYGON:
         case VTK_QUADRATIC_TETRA:
         case VTK_QUADRATIC_HEXAHEDRON:
         case VTK_TRIQUADRATIC_HEXAHEDRON:
         case VTK_QUADRATIC_WEDGE:
+        case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
         case VTK_QUADRATIC_PYRAMID:
-          if(!myIsWireframeMode) {
+
+          if(!myIsWireframeMode)
+          {
             input->GetCell(cellId,cell);
             vtkIdList *lpts = vtkIdList::New();
             vtkPoints *coords = vtkPoints::New();
@@ -643,12 +935,41 @@ VTKViewer_GeometryFilter
             }
             else //3D nonlinear cell
             {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+              if ( !myShowInside )
+              {
+                int npts1 = 0;
+                switch (aCellType ){
+                case VTK_QUADRATIC_TETRA:             npts1 = 4; break;
+                case VTK_QUADRATIC_HEXAHEDRON:        npts1 = 8; break;
+                case VTK_TRIQUADRATIC_HEXAHEDRON:     npts1 = 8; break;
+                case VTK_QUADRATIC_WEDGE:             npts1 = 6; break;
+                case VTK_BIQUADRATIC_QUADRATIC_WEDGE: npts1 = 6; break;
+                case VTK_QUADRATIC_PYRAMID:           npts1 = 5; break;
+                }
+                faceIdsTmp->SetNumberOfIds( npts1 );
+                if ( npts1 > 0 ) {
+                  for (int ai=0; ai<npts1; ai++)
+                    faceIdsTmp->SetId( ai, pts[ai] );
+                  input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+                }
+              }
+#endif
               aCellType = VTK_TRIANGLE;
               numFacePts = 3;
-              for (int j=0; j < cell->GetNumberOfFaces(); j++){
+              int nbNeighbors = 0;
+              for (int j=0; j < cell->GetNumberOfFaces(); j++)
+              {
                 vtkCell *face = cell->GetFace(j);
-                input->GetCellNeighbors(cellId, face->PointIds, cellIds);
-                bool process = cellIds->GetNumberOfIds() <= 0 ? true : myAppendCoincident3D;
+                if ( !myShowInside ) {
+                  input->GetCellNeighbors(cellId, face->PointIds, cellIds);
+                  nbNeighbors = cellIds->GetNumberOfIds() - cellIdsTmp->GetNumberOfIds();
+                }
+#ifdef SHOW_COINCIDING_3D_PAL21924
+                bool process = nbNeighbors <= 0;
+#else
+                bool process = nbNeighbors <= 0 || GetAppendCoincident3D();
+#endif
                 if ( process || myShowInside ) {
                   face->Triangulate(0,lpts,coords);
                   for (i=0; i < lpts->GetNumberOfIds(); i+=3) {
@@ -667,9 +988,11 @@ VTKViewer_GeometryFilter
             coords->Delete();
             lpts->Delete();
             break;
-          } else { // wireframe
+          }
+          else { // wireframe
             switch(aCellType) {
-            case VTK_QUADRATIC_EDGE: {
+            case VTK_QUADRATIC_EDGE:
+            {
               vtkIdType arcResult =-1;
               if(myIsBuildArc) {
                arcResult = Build1DArc(cellId, input, output, pts,myMaxArcAngle);
@@ -692,7 +1015,9 @@ VTKViewer_GeometryFilter
               outputCD->CopyData(cd,cellId,newCellId);
               break;
             }
-            case VTK_QUADRATIC_TRIANGLE: {
+            case VTK_QUADRATIC_TRIANGLE:
+            case VTK_BIQUADRATIC_TRIANGLE:
+            {
               if(!myIsBuildArc) {
                 aCellType = VTK_POLYGON;
                 numFacePts = 6;
@@ -714,8 +1039,9 @@ VTKViewer_GeometryFilter
                 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
               break;
             }
+            case VTK_QUADRATIC_QUAD:
             case VTK_BIQUADRATIC_QUAD:
-            case VTK_QUADRATIC_QUAD: {
+            {
               if(!myIsBuildArc) {
                 aCellType = VTK_POLYGON;
                 numFacePts = 8;
@@ -739,332 +1065,117 @@ VTKViewer_GeometryFilter
                 BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
               break;
             }
-            case VTK_QUADRATIC_TETRA: {
-              aCellType = VTK_POLYGON;
-              numFacePts = 6;
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[4];
-              aNewPts[2] = pts[1];
-              aNewPts[3] = pts[5];
-              aNewPts[4] = pts[2];
-              aNewPts[5] = pts[6];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[7];
-              aNewPts[2] = pts[3];
-              aNewPts[3] = pts[8];
-              aNewPts[4] = pts[1];
-              aNewPts[5] = pts[4];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[1];
-              aNewPts[1] = pts[8];
-              aNewPts[2] = pts[3];
-              aNewPts[3] = pts[9];
-              aNewPts[4] = pts[2];
-              aNewPts[5] = pts[5];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[2];
-              aNewPts[1] = pts[9];
-              aNewPts[2] = pts[3];
-              aNewPts[3] = pts[7];
-              aNewPts[4] = pts[0];
-              aNewPts[5] = pts[6];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              break;
-            }
-            case VTK_QUADRATIC_WEDGE: {
-              aCellType = VTK_POLYGON;
-              numFacePts = 6;
-              //---------------------------------------------------------------
-              //Face 1
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[6];
-              aNewPts[2] = pts[1];
-              aNewPts[3] = pts[7];
-              aNewPts[4] = pts[2];
-              aNewPts[5] = pts[8];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              //Face 2
-              aNewPts[0] = pts[3];
-              aNewPts[1] = pts[9];
-              aNewPts[2] = pts[4];
-              aNewPts[3] = pts[10];
-              aNewPts[4] = pts[5];
-              aNewPts[5] = pts[11];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              //Face 3
-              numFacePts = 8;
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[8];
-              aNewPts[2] = pts[2];
-              aNewPts[3] = pts[14];
-              aNewPts[4] = pts[5];
-              aNewPts[5] = pts[11];
-              aNewPts[6] = pts[3];
-              aNewPts[7] = pts[12];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
+            case VTK_QUADRATIC_POLYGON:
+            {
+              if(!myIsBuildArc)
+              {
+                aCellType = VTK_POLYGON;
 
-              //---------------------------------------------------------------
-              //Face 4
-              aNewPts[0] = pts[1];
-              aNewPts[1] = pts[13];
-              aNewPts[2] = pts[4];
-              aNewPts[3] = pts[10];
-              aNewPts[4] = pts[5];
-              aNewPts[5] = pts[14];
-              aNewPts[6] = pts[2];
-              aNewPts[7] = pts[7];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
+                for ( i = 0; i < npts/2; ++i )
+                {
+                  aNewPts[i*2  ] = pts[i];
+                  aNewPts[i*2+1] = pts[i+npts/2];
+                }
+                newCellId = output->InsertNextCell(aCellType,npts,aNewPts);
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
 
-              //---------------------------------------------------------------
-              //Face 5
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[12];
-              aNewPts[2] = pts[3];
-              aNewPts[3] = pts[9];
-              aNewPts[4] = pts[4];
-              aNewPts[5] = pts[13];
-              aNewPts[6] = pts[1];
-              aNewPts[7] = pts[6];
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-              outputCD->CopyData(cd,cellId,newCellId);
+                outputCD->CopyData(cd,cellId,newCellId);
+              }
+              else
+                BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
               break;
             }
+            case VTK_QUADRATIC_TETRA:
+            case VTK_QUADRATIC_WEDGE:
+            case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
             case VTK_TRIQUADRATIC_HEXAHEDRON:
-            case VTK_QUADRATIC_HEXAHEDRON: {
-              aCellType = VTK_POLYGON;
-              numFacePts = 8;
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[8];
-              aNewPts[2] = pts[1];
-              aNewPts[3] = pts[17];
-              aNewPts[4] = pts[5];
-              aNewPts[5] = pts[12];
-              aNewPts[6] = pts[4];
-              aNewPts[7] = pts[16];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[1];
-              aNewPts[1] = pts[9];
-              aNewPts[2] = pts[2];
-              aNewPts[3] = pts[18];
-              aNewPts[4] = pts[6];
-              aNewPts[5] = pts[13];
-              aNewPts[6] = pts[5];
-              aNewPts[7] = pts[17];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[2];
-              aNewPts[1] = pts[10];
-              aNewPts[2] = pts[3];
-              aNewPts[3] = pts[19];
-              aNewPts[4] = pts[7];
-              aNewPts[5] = pts[14];
-              aNewPts[6] = pts[6];
-              aNewPts[7] = pts[18];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[3];
-              aNewPts[1] = pts[11];
-              aNewPts[2] = pts[0];
-              aNewPts[3] = pts[16];
-              aNewPts[4] = pts[4];
-              aNewPts[5] = pts[15];
-              aNewPts[6] = pts[7];
-              aNewPts[7] = pts[19];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[8];
-              aNewPts[2] = pts[1];
-              aNewPts[3] = pts[9];
-              aNewPts[4] = pts[2];
-              aNewPts[5] = pts[10];
-              aNewPts[6] = pts[3];
-              aNewPts[7] = pts[11];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[4];
-              aNewPts[1] = pts[12];
-              aNewPts[2] = pts[5];
-              aNewPts[3] = pts[13];
-              aNewPts[4] = pts[6];
-              aNewPts[5] = pts[14];
-              aNewPts[6] = pts[7];
-              aNewPts[7] = pts[15];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              break;
-            }
-            case VTK_QUADRATIC_PYRAMID: {
-              aCellType = VTK_POLYGON;
-              numFacePts = 6;
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[8];
-              aNewPts[2] = pts[3];
-              aNewPts[3] = pts[12];
-              aNewPts[4] = pts[4];
-              aNewPts[5] = pts[9];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[9];
-              aNewPts[2] = pts[4];
-              aNewPts[3] = pts[10];
-              aNewPts[4] = pts[1];
-              aNewPts[5] = pts[5];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[1];
-              aNewPts[1] = pts[10];
-              aNewPts[2] = pts[4];
-              aNewPts[3] = pts[11];
-              aNewPts[4] = pts[2];
-              aNewPts[5] = pts[6];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              aNewPts[0] = pts[2];
-              aNewPts[1] = pts[11];
-              aNewPts[2] = pts[4];
-              aNewPts[3] = pts[12];
-              aNewPts[4] = pts[3];
-              aNewPts[5] = pts[7];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
-              //---------------------------------------------------------------
-              numFacePts = 8;
-              aNewPts[0] = pts[0];
-              aNewPts[1] = pts[5];
-              aNewPts[2] = pts[1];
-              aNewPts[3] = pts[6];
-              aNewPts[4] = pts[2];
-              aNewPts[5] = pts[7];
-              aNewPts[6] = pts[3];
-              aNewPts[7] = pts[8];
-
-              newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-              if(myStoreMapping)
-                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
-
-              outputCD->CopyData(cd,cellId,newCellId);
-
+            case VTK_QUADRATIC_HEXAHEDRON:
+            case VTK_QUADRATIC_PYRAMID:
+            {
+              aCellType = VTK_POLY_LINE;
+              input->GetCell(cellId,cell);
+              if ( myShowInside )
+              {
+                int nbEdges = cell->GetNumberOfEdges();
+                for ( int edgeId = 0; edgeId < nbEdges; ++edgeId )
+                {
+                  vtkCell * edge = cell->GetEdge( edgeId );
+                  if ( toShowEdge( edge->GetPointId(0), edge->GetPointId(2), cellId, input ))
+                  {
+                    aNewPts[0] = edge->GetPointId(0);
+                    aNewPts[1] = edge->GetPointId(2);
+                    aNewPts[2] = edge->GetPointId(1);
+                    newCellId = output->InsertNextCell( aCellType, 3, aNewPts );
+                    if(myStoreMapping)
+                      InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                    outputCD->CopyData(cd,cellId,newCellId);
+                  }
+                }
+              }
+              else
+              {
+                int nbCoincident = 0;
+#ifdef SHOW_COINCIDING_3D_PAL21924
+                int nbPnt = npts - cell->GetNumberOfEdges();
+                faceIdsTmp->SetNumberOfIds( nbPnt );
+                for ( int ai = 0; ai < nbPnt; ai++ )
+                  faceIdsTmp->SetId( ai, pts[ai] );
+                input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+                nbCoincident = cellIdsTmp->GetNumberOfIds();
+#endif
+                midPoints.clear();
+                int nbFaces = cell->GetNumberOfFaces();
+                for ( faceId = 0; faceId < nbFaces; faceId++ )
+                {
+                  vtkCell * face = cell->GetFace( faceId );
+                  input->GetCellNeighbors( cellId, face->GetPointIds(), cellIds );
+                  int nbNeighbors = cellIds->GetNumberOfIds() - nbCoincident;
+                  if ( nbNeighbors <= 0 )
+                  {
+                    int nbEdges = face->GetNumberOfPoints() / 2;
+                    for ( int edgeId = 0; edgeId < nbEdges; ++edgeId )
+                    {
+                      vtkIdType p1 = ( edgeId );               // corner
+                      vtkIdType p2 = ( edgeId + nbEdges );     // medium
+                      vtkIdType p3 = ( edgeId + 1 ) % nbEdges; // next corner
+                      faceIdsTmp->SetNumberOfIds( 2 );
+                      faceIdsTmp->SetId( 0, face->GetPointId(p2) );
+                      faceIdsTmp->SetId( 1, face->GetPointId(p1) );
+                      input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+                      bool process;
+                      switch ( cellIdsTmp->GetNumberOfIds() ) {
+                      case 0: // the edge belong to this cell only
+                        // avoid adding it when treating another face
+                        process = midPoints.insert( face->GetPointId(p2) ).second; break;
+                      case 1: // the edge is shared by two cells
+                        process = ( cellIdsTmp->GetId(0) < cellId ); break;
+                      default: // the edge is shared by >2 cells
+                        process = ( cellIdsTmp->GetId(0) < cellId ); break;
+                      }
+                      if ( process )
+                      {
+                        aNewPts[0] = face->GetPointId( p1 );
+                        aNewPts[1] = face->GetPointId( p2 );
+                        aNewPts[2] = face->GetPointId( p3 );
+                        newCellId = output->InsertNextCell( aCellType, 3, aNewPts );
+                        if(myStoreMapping)
+                          InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                        outputCD->CopyData(cd,cellId,newCellId);
+                      }
+                    }
+                  }
+                }
+              }
               break;
-            } // case VTK_QUADRATIC_PYRAMID:
-            } // switch by type
+            } // case of volumes in wireframe
+            } // switch by quadratic type
           } // end WIREFRAME
           break;
-        } //switch
-      } //if visible
-    } //for all cells
+        } //switch by type
+
+    } //if visible
+  } //for all cells
 
   output->Squeeze();
 
@@ -1075,30 +1186,38 @@ VTKViewer_GeometryFilter
 
   cellIds->Delete();
   faceIds->Delete();
+  cellIdsTmp->Delete();
+  faceIdsTmp->Delete();
 
   if ( cellVis )
   {
     delete [] cellVis;
   }
 
-  // to sort myVTK2ObjIds vector by cell dimension (ascending)
+  if ( input->GetCellLinks() )
+  {
+    input->GetCellLinks()->Initialize(); // free memory
+  }
+
+  // fill myVTK2ObjIds vector in ascending cell dimension order
+  myVTK2ObjIds.clear();
   if( myStoreMapping && !aDimension2VTK2ObjIds.empty() )
   {
-    myVTK2ObjIds.clear();
-    for( vtkIdType aDimension = 0; aDimension <= 2; aDimension++ )
-    {
-      TMapOfVectorId::const_iterator anIter = aDimension2VTK2ObjIds.find( aDimension );
-      if( anIter != aDimension2VTK2ObjIds.end() )
+    size_t nbCells = ( aDimension2VTK2ObjIds[0].size() +
+                       aDimension2VTK2ObjIds[1].size() +
+                       aDimension2VTK2ObjIds[2].size() );
+    if ( myVTK2ObjIds.capacity() > nbCells )
+      TVectorId().swap( myVTK2ObjIds );
+    myVTK2ObjIds.reserve( nbCells );
+
+    for( int aDimension = 0; aDimension <= 2; aDimension++ )
+      if ( !aDimension2VTK2ObjIds[ aDimension ].empty() )
       {
-        const TVectorId& aCellIds = anIter->second;
-        TVectorId::const_iterator anIdIter, anIdIterEnd = aCellIds.end();
-        for( anIdIter = aCellIds.begin(); anIdIter != anIdIterEnd; anIdIter++ )
-        {
-          const vtkIdType aCellId = *anIdIter;
-          myVTK2ObjIds.push_back( aCellId );
-        }
+        myVTK2ObjIds.insert( myVTK2ObjIds.end(),
+                             aDimension2VTK2ObjIds[ aDimension ].begin(),
+                             aDimension2VTK2ObjIds[ aDimension ].end() );
+        TVectorId().swap( aDimension2VTK2ObjIds[ aDimension ]);
       }
-    }
   }
 
   return 1;
@@ -1111,7 +1230,7 @@ VTKViewer_GeometryFilter
             TVectorId& theVTK2ObjIds,
             TMapOfVectorId& theDimension2VTK2ObjIds )
 {
-  theVTK2ObjIds.push_back( theCellId );
+  //theVTK2ObjIds.push_back( theCellId );
 
   int aDimension = 0;
   switch( theCellType )
@@ -1206,7 +1325,8 @@ void VTKViewer_GeometryFilter::BuildArcedPolygon(vtkIdType cellId,
                                                  vtkUnstructuredGrid* input,
                                                  vtkPolyData *output,
                                                  TMapOfVectorId& theDimension2VTK2ObjIds,
-                                                 bool triangulate){
+                                                 bool triangulate)
+{
   vtkIdType aCellType = VTK_POLYGON;
   vtkIdType *aNewPoints = NULL;
   vtkIdType aNbPoints = 0;
@@ -1220,12 +1340,13 @@ void VTKViewer_GeometryFilter::BuildArcedPolygon(vtkIdType cellId,
   vtkDataArray* inputScalars = input->GetPointData()->GetScalars();
   vtkDataArray* outputScalars = output->GetPointData()->GetScalars();
 
-  std::vector<vtkPoints*> aCollection;
+  std::vector< vtkSmartPointer<vtkPoints> > aCollection;
   std::vector< std::vector<double> > aScalarCollection;
 
   vtkCell* aCell = input->GetCell(cellId);
   switch(aCell->GetCellType()) {
     case VTK_QUADRATIC_TRIANGLE:
+    case VTK_BIQUADRATIC_TRIANGLE:
     {
       //Get All points from input cell
       Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
@@ -1259,8 +1380,8 @@ void VTKViewer_GeometryFilter::BuildArcedPolygon(vtkIdType cellId,
       aScalarCollection.push_back(aBuilder3.GetScalarValues());
       break;
     }
-    case VTK_BIQUADRATIC_QUAD:
     case VTK_QUADRATIC_QUAD:
+    case VTK_BIQUADRATIC_QUAD:
     {
       //Get All points from input cell
       Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
@@ -1303,6 +1424,27 @@ void VTKViewer_GeometryFilter::BuildArcedPolygon(vtkIdType cellId,
       aScalarCollection.push_back(aBuilder4.GetScalarValues());
       break;
     }
+    case VTK_QUADRATIC_POLYGON:
+    {
+      int nbP = aCell->GetNumberOfPoints();
+      std::vector< Pnt > pVec( nbP + 2 );
+
+      for ( int i = 0; i < nbP/2; ++i )
+      {
+        pVec[i*2 + 0] = CreatePnt( aCell, inputScalars, i );
+        pVec[i*2 + 1] = CreatePnt( aCell, inputScalars, i + nbP/2 );
+      }
+      pVec[ nbP   ] = pVec[ 0 ];
+      pVec[ nbP+1 ] = pVec[ 1 ];
+
+      for ( int i = 0; i < nbP; i += 2 )
+      {      
+        VTKViewer_ArcBuilder aBuilder( pVec[i], pVec[i+1], pVec[i+2], myMaxArcAngle );
+        aCollection.push_back( aBuilder.GetPoints() );
+        aScalarCollection.push_back( aBuilder.GetScalarValues() );
+      }
+      break;
+    }
     default: //Unsupported cell type
       return;
   }
@@ -1377,7 +1519,7 @@ bool VTKViewer_GeometryFilter::GetQuadraticArcMode() const
   return myIsBuildArc;
 }
 
-void VTKViewer_GeometryFilter::SetQuadraticArcAngle(vtkFloatingPointType theMaxAngle)
+void VTKViewer_GeometryFilter::SetQuadraticArcAngle(double theMaxAngle)
 {
   if(myMaxArcAngle != theMaxAngle) {
     myMaxArcAngle = theMaxAngle;
@@ -1385,14 +1527,19 @@ void VTKViewer_GeometryFilter::SetQuadraticArcAngle(vtkFloatingPointType theMaxA
   }
 }
 
-vtkFloatingPointType VTKViewer_GeometryFilter:: GetQuadraticArcAngle() const
+double VTKViewer_GeometryFilter:: GetQuadraticArcAngle() const
 {
   return myMaxArcAngle;
 }
 
-
 int VTKViewer_GeometryFilter::GetAppendCoincident3D() const {
+// VSR 26/10/2012: see description of SHOW_COINCIDING_3D_PAL20314
+// in the top of this file
+#ifdef SHOW_COINCIDING_3D_PAL20314
   return myAppendCoincident3D;
+#else
+  return false;
+#endif
 }
 
 void VTKViewer_GeometryFilter::SetAppendCoincident3D(int theFlag) {