Salome HOME
Merge from V6_main 13/12/2012
[modules/gui.git] / src / VTKViewer / VTKViewer_GeometryFilter.cxx
index df096cf7aad3b6dc8110f782c955862ce3dc90a1..7d139de0727e0000a820b41267b38454aae04a6b 100755 (executable)
@@ -1,42 +1,46 @@
-//  SALOME OBJECT : kernel of SALOME component
+// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  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. 
-// 
-//  This library is distributed in the hope that it will be useful, 
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
-//  Lesser General Public License for more details. 
-// 
-//  You should have received a copy of the GNU Lesser General Public 
-//  License along with this library; if not, write to the Free Software 
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
-// 
-//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
+// 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.
 //
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
 //  File   : VTKViewer_GeometryFilter.cxx
 //  Author : Michael ZORIN
 //  Module : SALOME
-//  $Header$
-
+//
 #include "VTKViewer_GeometryFilter.h"
+#include "VTKViewer_ConvexTool.h"
+#include "VTKViewer_ArcBuilder.h"
 
 #include <vtkSmartPointer.h>
 #include <vtkCellArray.h>
 #include <vtkCellData.h>
 #include <vtkGenericCell.h>
+#include <vtkHexagonalPrism.h>
 #include <vtkHexahedron.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
 #include <vtkMergePoints.h>
 #include <vtkObjectFactory.h>
 #include <vtkPointData.h>
 #include <vtkPolyData.h>
+#include <vtkPolygon.h>
 #include <vtkPyramid.h>
 #include <vtkStructuredGrid.h>
 #include <vtkTetra.h>
 #include <vtkVoxel.h>
 #include <vtkWedge.h>
 
-#include <vtkMath.h>
-#include <vtkPlane.h>
-#include <vtkDelaunay3D.h>
-#include <vtkGeometryFilter.h>
-
 #include <algorithm>
 #include <iterator>
 #include <vector>
 #include <map>
 #include <set>
 
+#include "utilities.h"
+
 #if defined __GNUC__
   #if __GNUC__ == 2
     #define __GNUC_2__
   #endif
 #endif
 
-#define USE_ROBUST_TRIANGULATION
+#define VTK_XVERSION (VTK_MAJOR_VERSION*10000+VTK_MINOR_VERSION*100+VTK_BUILD_VERSION)
+
+//#define __MYDEBUG__
+//#define USE_ROBUST_TRIANGULATION
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+// 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
+///////////////////////////////////////////////////////////////////////////////////////////////
 
-//----------------------------------------------------------------------------
 vtkCxxRevisionMacro(VTKViewer_GeometryFilter, "$Revision$");
 vtkStandardNewMacro(VTKViewer_GeometryFilter);
 
 VTKViewer_GeometryFilter
-::VTKViewer_GeometryFilter(): 
+::VTKViewer_GeometryFilter():
   myShowInside(0),
   myStoreMapping(0),
-  myIsWireframeMode(0)
+  myAppendCoincident3D(0),
+  myIsWireframeMode(0),
+  myIsBuildArc(false),
+  myMaxArcAngle(2)
 {}
 
 
@@ -81,39 +109,54 @@ VTKViewer_GeometryFilter
 {}
 
 
-//----------------------------------------------------------------------------
-void
+int
 VTKViewer_GeometryFilter
-::Execute()
+::RequestData(
+  vtkInformation *request,
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
 {
-  vtkDataSet *input= this->GetInput();
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and ouptut
+  vtkDataSet *input = vtkDataSet::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkPolyData *output = vtkPolyData::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
   vtkIdType numCells=input->GetNumberOfCells();
 
   if (numCells == 0)
     {
-      return;
+      return 0;
     }
-  
+
   if (input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID){
-    this->UnstructuredGridExecute();
-    return;
+    return this->UnstructuredGridExecute(input, output, outInfo);
   }else
-    vtkGeometryFilter::Execute();
+    return Superclass::RequestData(request,inputVector,outputVector);
+
+  return 1;
 }
 
 
-//----------------------------------------------------------------------------
-void
+int
 VTKViewer_GeometryFilter
-::UnstructuredGridExecute()
+::UnstructuredGridExecute(
+                          vtkDataSet *dataSetInput,
+                          vtkPolyData *output,
+                          vtkInformation *outInfo)
 {
-  vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)this->GetInput();
+
+  vtkUnstructuredGrid *input= (vtkUnstructuredGrid *)dataSetInput;
   vtkCellArray *Connectivity = input->GetCells();
   // Check input
   if ( Connectivity == NULL )
     {
     vtkDebugMacro(<<"Nothing to extract");
-    return;
+    return 0;
     }
 
   vtkIdType cellId;
@@ -125,41 +168,36 @@ VTKViewer_GeometryFilter
   vtkIdType numCells=input->GetNumberOfCells();
   vtkPointData *pd = input->GetPointData();
   vtkCellData *cd = input->GetCellData();
-  vtkPolyData *output = this->GetOutput();
   vtkPointData *outputPD = output->GetPointData();
-  
-#ifdef USE_ROBUST_TRIANGULATION
-  vtkUnstructuredGrid* anUnstructuredGrid = vtkUnstructuredGrid::New();
-  vtkPoints* aDelaunayPoints = vtkPoints::New();
-
-  vtkDelaunay3D* aDelaunay3D = vtkDelaunay3D::New();
-  aDelaunay3D->SetInput(anUnstructuredGrid);
-  
-  vtkGeometryFilter* aGeometryFilter = vtkGeometryFilter::New();
-  aGeometryFilter->SetInput(aDelaunay3D->GetOutput());
-#endif
+
+  VTKViewer_OrderedTriangulator anOrderedTriangulator;
+  VTKViewer_DelaunayTriangulator aDelaunayTriangulator;
 
   vtkCellData *outputCD = output->GetCellData();
   vtkGenericCell *cell = vtkGenericCell::New();
 
-
   vtkIdList *cellIds = vtkIdList::New();
   vtkIdList *faceIds = vtkIdList::New();
+  vtkIdList *cellIdsTmp = vtkIdList::New();
+  vtkIdList *faceIdsTmp = vtkIdList::New();
 
   char *cellVis;
   vtkIdType newCellId;
   int faceId, *faceVerts, numFacePts;
-  float *x;
-  int PixelConvert[4], aNewPts[VTK_CELL_SIZE];
+  vtkFloatingPointType *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  *cellGhostLevels = 0;  
-  
+  unsigned char  *cellGhostLevels = 0;
+
   PixelConvert[0] = 0;
   PixelConvert[1] = 1;
   PixelConvert[2] = 3;
   PixelConvert[3] = 2;
-  
+
   vtkDebugMacro(<<"Executing geometry filter for unstructured grid input");
 
   vtkDataArray* temp = 0;
@@ -176,7 +214,7 @@ VTKViewer_GeometryFilter
     {
     cellGhostLevels = ((vtkUnsignedCharArray*)temp)->GetPointer(0);
     }
-  
+
   // Determine nature of what we have to do
   if ( (!this->CellClipping) && (!this->PointClipping) &&
        (!this->ExtentClipping) )
@@ -190,38 +228,43 @@ VTKViewer_GeometryFilter
     cellVis = new char[numCells];
     }
 
-  // Just pass points through, never merge
-  output->SetPoints(input->GetPoints());
+  // 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();
+
   outputPD->PassData(pd);
 
   outputCD->CopyAllocate(cd,numCells,numCells/2);
 
   output->Allocate(numCells/4+1,numCells);
-  
+
   // Loop over the cells determining what's visible
   if (!allVisible)
     {
-    for (cellId=0, Connectivity->InitTraversal(); 
-         Connectivity->GetNextCell(npts,pts); 
+    for (cellId=0, Connectivity->InitTraversal();
+         Connectivity->GetNextCell(npts,pts);
          cellId++)
       {
       cellVis[cellId] = 1;
-      if ( this->CellClipping && cellId < this->CellMinimum ||
+      if ( ( this->CellClipping && cellId < this->CellMinimum ) ||
            cellId > this->CellMaximum )
         {
         cellVis[cellId] = 0;
         }
       else
         {
-        for (i=0; i < npts; i++) 
+        for (i=0; i < npts; i++)
           {
           x = p->GetPoint(pts[i]);
-          if ( (this->PointClipping && (pts[i] < this->PointMinimum ||
-                                        pts[i] > this->PointMaximum) ) ||
-               (this->ExtentClipping && 
-                (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] )) )
+          if ( ( ( ( this->PointClipping && (pts[i] < this->PointMinimum ) ) ||
+                                             pts[i] > this->PointMaximum) ) ||
+               ( this->ExtentClipping &&
+                ( 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;
@@ -230,16 +273,17 @@ VTKViewer_GeometryFilter
         }//if point clipping needs checking
       }//for all cells
     }//if not all visible
-  
+
   // Loop over all cells now that visibility is known
   // (Have to compute visibility first for 3D cell boundarys)
   int progressInterval = numCells/20 + 1;
+  TMapOfVectorId aDimension2VTK2ObjIds;
   if(myStoreMapping){
     myVTK2ObjIds.clear();
     myVTK2ObjIds.reserve(numCells);
   }
-  for (cellId=0, Connectivity->InitTraversal(); 
-       Connectivity->GetNextCell(npts,pts); 
+  for (cellId=0, Connectivity->InitTraversal();
+       Connectivity->GetNextCell(npts,pts);
        cellId++)
     {
     //Progress and abort method support
@@ -254,7 +298,7 @@ VTKViewer_GeometryFilter
       { // 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
@@ -268,17 +312,17 @@ VTKViewer_GeometryFilter
         case VTK_VERTEX:
         case VTK_POLY_VERTEX:
           newCellId = output->InsertNextCell(aCellType,npts,pts);
-         if(myStoreMapping){
-           myVTK2ObjIds.push_back(cellId); //apo
-         }
+          if(myStoreMapping){
+            InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+          }
           outputCD->CopyData(cd,cellId,newCellId);
           break;
 
-        case VTK_LINE: 
+        case VTK_LINE:
         case VTK_POLY_LINE:
           newCellId = output->InsertNextCell(aCellType,npts,pts);
-         if(myStoreMapping)
-           myVTK2ObjIds.push_back(cellId);
+          if(myStoreMapping)
+            InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
           outputCD->CopyData(cd,cellId,newCellId);
           break;
 
@@ -286,322 +330,63 @@ VTKViewer_GeometryFilter
         case VTK_QUAD:
         case VTK_POLYGON:
           newCellId = output->InsertNextCell(aCellType,npts,pts);
-         if(myStoreMapping)
-           myVTK2ObjIds.push_back(cellId);
+          if(myStoreMapping)
+            InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
           outputCD->CopyData(cd,cellId,newCellId);
           break;
 
         case VTK_TRIANGLE_STRIP:
           newCellId = output->InsertNextCell(aCellType,npts,pts);
-         if(myStoreMapping)
-           myVTK2ObjIds.push_back(cellId);
+          if(myStoreMapping)
+            InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
           outputCD->CopyData(cd,cellId,newCellId);
           break;
 
         case VTK_PIXEL:
           newCellId = output->InsertNextCell(aCellType,npts,pts);
-         if(myStoreMapping)
-           myVTK2ObjIds.push_back(cellId);
-         outputCD->CopyData(cd,cellId,newCellId);
+          if(myStoreMapping)
+            InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+          outputCD->CopyData(cd,cellId,newCellId);
           break;
-         
-       case VTK_CONVEX_POINT_SET: {
-         //cout<<"cellId = "<<cellId<<"\n";
-
-         vtkIdType aNumPts;
-         vtkPoints *aPoints;
-#ifdef USE_ROBUST_TRIANGULATION
-         aPoints = aDelaunayPoints;
-         anUnstructuredGrid->Initialize();
-         anUnstructuredGrid->Allocate();
-         anUnstructuredGrid->SetPoints(aDelaunayPoints);
-
-         vtkIdType *aPts;
-         input->GetCellPoints(cellId,aNumPts,aPts); 
-         {
-           float aPntCoord[3];
-           aDelaunayPoints->SetNumberOfPoints(aNumPts);
-           vtkPoints *anInputPoints = input->GetPoints();
-           for (int aPntId = 0; aPntId < aNumPts; aPntId++) {
-             anInputPoints->GetPoint(aPts[aPntId],aPntCoord);
-             aDelaunayPoints->SetPoint(aPntId,aPntCoord);
-           }
-         }
-#else
-         input->GetCell(cellId,cell);
-         aPoints = input->GetPoints();
-         aNumPts = cell->GetNumberOfPoints();
-#endif
-         // To calculate the bary center of the cell
-         float aCellCenter[3] = {0.0, 0.0, 0.0};
-         {
-           float aPntCoord[3];
-           for (int aPntId = 0; aPntId < aNumPts; aPntId++) {
-#ifdef USE_ROBUST_TRIANGULATION
-             aPoints->GetPoint(aPntId,aPntCoord);
-#else
-             aPoints->GetPoint(cell->GetPointId(aPntId),aPntCoord);
-#endif
-             //cout<<"\t\taPntId = "<<aPntId<<" {"<<aPntCoord[0]<<", "<<aPntCoord[1]<<", "<<aPntCoord[2]<<"}\n";
-             aCellCenter[0] += aPntCoord[0];
-             aCellCenter[1] += aPntCoord[1];
-             aCellCenter[2] += aPntCoord[2];
-           }
-           aCellCenter[0] /= aNumPts;
-           aCellCenter[1] /= aNumPts;
-           aCellCenter[2] /= aNumPts;
-         }
-
-#ifdef USE_ROBUST_TRIANGULATION
-         aGeometryFilter->Update();
-         vtkPolyData* aPolyData = aGeometryFilter->GetOutput();
-
-         float aCellLength = aPolyData->GetLength();
-          int aNumFaces = aPolyData->GetNumberOfCells();
-#else
-         float aCellLength = sqrt(cell->GetLength2());
-          int aNumFaces = cell->GetNumberOfFaces();
-#endif
-         
-         static float EPS = 1.0E-5;
-         float aDistEps = aCellLength * EPS;
-
-         // To initialize set of points that belong to the cell
-         typedef std::set<vtkIdType> TPointIds;
-         TPointIds anInitialPointIds;
-         for(vtkIdType aPntId = 0; aPntId < aNumPts; aPntId++){
-#ifdef USE_ROBUST_TRIANGULATION
-           anInitialPointIds.insert(aPntId);
-#else
-           anInitialPointIds.insert(cell->GetPointId(aPntId));
-#endif
-         }
-
-         // To initialize set of points by face that belong to the cell and backward
-         typedef std::set<vtkIdType> TFace2Visibility;
-         TFace2Visibility aFace2Visibility;
 
-         typedef std::set<TPointIds> TFace2PointIds;
-         TFace2PointIds aFace2PointIds;
+        case VTK_CONVEX_POINT_SET: {
+          bool anIsOk = anOrderedTriangulator.Execute(input,
+                                                      cd,
+                                                      cellId,
+                                                      myShowInside,
+                                                      allVisible,
+                                                      GetAppendCoincident3D(),
+                                                      cellVis,
+                                                      output,
+                                                      outputCD,
+                                                      myStoreMapping,
+                                                      myVTK2ObjIds,
+                                                      aDimension2VTK2ObjIds,
+                                                      true);
+          if(!anIsOk)
+            aDelaunayTriangulator.Execute(input,
+                                          cd,
+                                          cellId,
+                                          myShowInside,
+                                          allVisible,
+                                          GetAppendCoincident3D(),
+                                          cellVis,
+                                          output,
+                                          outputCD,
+                                          myStoreMapping,
+                                          myVTK2ObjIds,
+                                          aDimension2VTK2ObjIds,
+                                          false);
 
-          for (int aFaceId = 0; aFaceId < aNumFaces; aFaceId++) {
-#ifdef USE_ROBUST_TRIANGULATION
-            vtkCell* aFace = aPolyData->GetCell(aFaceId);
-#else
-            vtkCell* aFace = cell->GetFace(aFaceId);
-#endif
-           vtkIdList *anIdList = aFace->PointIds;  
-           aNewPts[0] = anIdList->GetId(0);
-           aNewPts[1] = anIdList->GetId(1);
-           aNewPts[2] = anIdList->GetId(2);
-
-#ifdef USE_ROBUST_TRIANGULATION
-            faceIds->Reset();
-            faceIds->InsertNextId(aPts[aNewPts[0]]);
-            faceIds->InsertNextId(aPts[aNewPts[1]]);
-            faceIds->InsertNextId(aPts[aNewPts[2]]);
-            input->GetCellNeighbors(cellId, faceIds, cellIds);
-#else
-            input->GetCellNeighbors(cellId, anIdList, cellIds);
-#endif
-           if((!allVisible && !cellVis[cellIds->GetId(0)]) || 
-              cellIds->GetNumberOfIds() <= 0 ||
-              myShowInside)
-           {
-             TPointIds aPointIds;
-             aPointIds.insert(aNewPts[0]);
-             aPointIds.insert(aNewPts[1]);
-             aPointIds.insert(aNewPts[2]);
-
-             aFace2PointIds.insert(aPointIds);
-             aFace2Visibility.insert(aFaceId);
-           }
-         }
-
-          for (int aFaceId = 0; aFaceId < aNumFaces; aFaceId++) {
-            if(aFace2Visibility.find(aFaceId) == aFace2Visibility.end())
-             continue;
-
-#ifdef USE_ROBUST_TRIANGULATION
-            vtkCell* aFace = aPolyData->GetCell(aFaceId);
-#else
-            vtkCell* aFace = cell->GetFace(aFaceId);
-#endif
-           vtkIdList *anIdList = aFace->PointIds;
-           aNewPts[0] = anIdList->GetId(0);
-           aNewPts[1] = anIdList->GetId(1);
-           aNewPts[2] = anIdList->GetId(2);
-           
-           // To initialize set of points for the plane where the trinangle face belong to
-           TPointIds aPointIds;
-           aPointIds.insert(aNewPts[0]);
-           aPointIds.insert(aNewPts[1]);
-           aPointIds.insert(aNewPts[2]);
-
-           // To get know, if the points of the trinagle were already observed
-           bool anIsObserved = aFace2PointIds.find(aPointIds) == aFace2PointIds.end();
-           //cout<<"\taFaceId = "<<aFaceId<<"; anIsObserved = "<<anIsObserved;
-           //cout<<"; aNewPts = {"<<aNewPts[0]<<", "<<aNewPts[1]<<", "<<aNewPts[2]<<"}\n";
-             
-           if(!anIsObserved){
-             // To get coordinates of the points of the traingle face
-             float aCoord[3][3];
-             aPoints->GetPoint(aNewPts[0],aCoord[0]);
-             aPoints->GetPoint(aNewPts[1],aCoord[1]);
-             aPoints->GetPoint(aNewPts[2],aCoord[2]);
-             
-             // To calculate plane normal
-             float aVector01[3] = { aCoord[1][0] - aCoord[0][0],
-                                    aCoord[1][1] - aCoord[0][1],
-                                    aCoord[1][2] - aCoord[0][2] };
-             
-             float aVector02[3] = { aCoord[2][0] - aCoord[0][0],
-                                    aCoord[2][1] - aCoord[0][1],
-                                    aCoord[2][2] - aCoord[0][2] };
-             
-             float aCross21[3];
-             vtkMath::Cross(aVector02,aVector01,aCross21);
-             
-             vtkMath::Normalize(aCross21);
-             
-             // To calculate what points belong to the plane
-             // To calculate bounds of the point set
-             float aCenter[3] = {0.0, 0.0, 0.0};
-             {
-               TPointIds::const_iterator anIter = anInitialPointIds.begin();
-               TPointIds::const_iterator anEndIter = anInitialPointIds.end();
-               for(; anIter != anEndIter; anIter++){
-                 float aPntCoord[3];
-                 vtkIdType aPntId = *anIter;
-                 aPoints->GetPoint(aPntId,aPntCoord);
-                 float aDist = vtkPlane::DistanceToPlane(aPntCoord,aCross21,aCoord[0]);
-                 //cout<<"\t\taPntId = "<<aPntId<<" {"<<aPntCoord[0]<<", "<<aPntCoord[1]<<", "<<aPntCoord[2]<<"}; aDist = "<<aDist<<"\n";
-                 if(fabs(aDist) < aDistEps){
-                   aPointIds.insert(aPntId);
-                   aCenter[0] += aPntCoord[0];
-                   aCenter[1] += aPntCoord[1];
-                   aCenter[2] += aPntCoord[2];
-                 }
-               }
-               int aNbPoints = aPointIds.size();
-               aCenter[0] /= aNbPoints;
-               aCenter[1] /= aNbPoints;
-               aCenter[2] /= aNbPoints;
-             }
-             
-             // To calculate the primary direction for point set
-             float aVector0[3] = { aCoord[0][0] - aCenter[0],
-                                   aCoord[0][1] - aCenter[1],
-                                   aCoord[0][2] - aCenter[2] };
-
-             //To sinchronize orientation of the cell and its face
-             float aVectorC[3] = { aCenter[0] - aCellCenter[0],
-                                   aCenter[1] - aCellCenter[1],
-                                   aCenter[2] - aCellCenter[2] };
-             vtkMath::Normalize(aVectorC);
-
-             float aDot = vtkMath::Dot(aCross21,aVectorC);
-             //cout<<"\t\taCross21 = {"<<aCross21[0]<<", "<<aCross21[1]<<", "<<aCross21[2]<<"}";
-             //cout<<"; aVectorC = {"<<aVectorC[0]<<", "<<aVectorC[1]<<", "<<aVectorC[2]<<"}\n";
-             //cout<<"\t\taDot = "<<aDot<<"\n";
-             if(aDot > 0){
-               aCross21[0] = -aCross21[0];
-               aCross21[1] = -aCross21[1];
-               aCross21[2] = -aCross21[2];
-             }
-               
-             vtkMath::Normalize(aVector0);
-             
-             //cout<<"\t\taCenter = {"<<aCenter[0]<<", "<<aCenter[1]<<", "<<aCenter[2]<<"}";
-             //cout<<"; aVector0 = {"<<aVector0[0]<<", "<<aVector0[1]<<", "<<aVector0[2]<<"}\n";
-
-             // To calculate the set of points by face those that belong to the plane
-             TFace2PointIds aRemoveFace2PointIds;
-             {
-               TFace2PointIds::const_iterator anIter = aFace2PointIds.begin();
-               TFace2PointIds::const_iterator anEndIter = aFace2PointIds.end();
-               for(; anIter != anEndIter; anIter++){
-                 const TPointIds& anIds = *anIter;
-                 TPointIds anIntersection;
-                 std::set_intersection(aPointIds.begin(),aPointIds.end(),
-                                       anIds.begin(),anIds.end(),
-                                       std::inserter(anIntersection,anIntersection.begin()));
-
-                 if(anIntersection == anIds){
-                   aRemoveFace2PointIds.insert(anIds);
-                 }
-               }
-             }
-
-             // To remove from the set of points by face those that belong to the plane
-             {
-               TFace2PointIds::const_iterator anIter = aRemoveFace2PointIds.begin();
-               TFace2PointIds::const_iterator anEndIter = aRemoveFace2PointIds.end();
-               for(; anIter != anEndIter; anIter++){
-                 const TPointIds& anIds = *anIter;
-                 aFace2PointIds.erase(anIds);
-               }
-             }
-
-             // To sort the planar set of the points accrding to the angle
-             {
-               typedef std::map<float,vtkIdType> TSortedPointIds;
-               TSortedPointIds aSortedPointIds;
-
-               TPointIds::const_iterator anIter = aPointIds.begin();
-               TPointIds::const_iterator anEndIter = aPointIds.end();
-               for(; anIter != anEndIter; anIter++){
-                 float aPntCoord[3];
-                 vtkIdType aPntId = *anIter;
-                 aPoints->GetPoint(aPntId,aPntCoord);
-                 float aVector[3] = { aPntCoord[0] - aCenter[0],
-                                      aPntCoord[1] - aCenter[1],
-                                      aPntCoord[2] - aCenter[2] };
-                 vtkMath::Normalize(aVector);
-
-                 float aCross[3];
-                 vtkMath::Cross(aVector,aVector0,aCross);
-                 bool aGreaterThanPi = vtkMath::Dot(aCross,aCross21) < 0;
-                 float aCosinus = vtkMath::Dot(aVector,aVector0);
-                 if(aCosinus > 1.0)
-                   aCosinus = 1.0;
-                 if(aCosinus < -1.0)
-                   aCosinus = -1.0;
-                 static float a2Pi = 2.0 * vtkMath::Pi();
-                 float anAngle = acos(aCosinus);
-                 //cout<<"\t\taPntId = "<<aPntId<<" {"<<aPntCoord[0]<<", "<<aPntCoord[1]<<", "<<aPntCoord[2]<<"}";
-                 //cout<<"; aGreaterThanPi = "<<aGreaterThanPi<<"; aCosinus = "<<aCosinus<<"; anAngle = "<<anAngle<<"\n";
-                 if(aGreaterThanPi)
-                   anAngle = a2Pi - anAngle;
-                 aSortedPointIds[anAngle] = aPntId;
-                 //cout<<"\t\t\tanAngle = "<<anAngle<<"\n";
-               }
-               if(!aSortedPointIds.empty()){
-                 aCellType = VTK_POLYGON;
-                 int numFacePts = aSortedPointIds.size();
-                 std::vector<vtkIdType> aConnectivities(numFacePts);
-                 TSortedPointIds::const_iterator anIter = aSortedPointIds.begin();
-                 TSortedPointIds::const_iterator anEndIter = aSortedPointIds.end();
-                 for(vtkIdType anId = 0; anIter != anEndIter; anIter++, anId++){
-                   vtkIdType aPntId = anIter->second;
-#ifdef USE_ROBUST_TRIANGULATION
-                   aConnectivities[anId] = aPts[aPntId];
-#else
-                   aConnectivities[anId] = aPntId;
-#endif
-                 }
-                 newCellId = output->InsertNextCell(aCellType,numFacePts,&aConnectivities[0]);
-                 if(myStoreMapping)
-                   myVTK2ObjIds.push_back(cellId);
-                 outputCD->CopyData(cd,cellId,newCellId);
-               }
-             }
-           }
-         }
-
-         break;
-       }
+          break;
+        }
         case VTK_TETRA: {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+         faceIdsTmp->Reset();
+         for (int ai=0; ai<npts; ai++)
+           faceIdsTmp->InsertNextId(pts[ai]);
+         input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
           for (faceId = 0; faceId < 4; faceId++)
             {
             faceIds->Reset();
@@ -609,23 +394,38 @@ VTKViewer_GeometryFilter
             faceIds->InsertNextId(pts[faceVerts[0]]);
             faceIds->InsertNextId(pts[faceVerts[1]]);
             faceIds->InsertNextId(pts[faceVerts[2]]);
-           aCellType = VTK_TRIANGLE;
+            aCellType = VTK_TRIANGLE;
             numFacePts = 3;
             input->GetCellNeighbors(cellId, faceIds, cellIds);
-            if ( cellIds->GetNumberOfIds() <= 0 || myShowInside ||
+#ifdef SHOW_COINCIDING_3D_PAL21924
+           int nbNeighbors = 0;
+           for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
+             if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
+           }
+            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] = pts[faceVerts[i]];
               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-             if(myStoreMapping)
-               myVTK2ObjIds.push_back(cellId);
+              if(myStoreMapping)
+                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
               outputCD->CopyData(cd,cellId,newCellId);
               }
             }
           break;
-       }
+        }
         case VTK_VOXEL: {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+         faceIdsTmp->Reset();
+         for (int ai=0; ai<npts; ai++)
+           faceIdsTmp->InsertNextId(pts[ai]);
+         input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
           for (faceId = 0; faceId < 6; faceId++)
             {
             faceIds->Reset();
@@ -634,23 +434,38 @@ VTKViewer_GeometryFilter
             faceIds->InsertNextId(pts[faceVerts[1]]);
             faceIds->InsertNextId(pts[faceVerts[2]]);
             faceIds->InsertNextId(pts[faceVerts[3]]);
-           aCellType = VTK_QUAD;
+            aCellType = VTK_QUAD;
             numFacePts = 4;
             input->GetCellNeighbors(cellId, faceIds, cellIds);
-            if ( cellIds->GetNumberOfIds() <= 0 || myShowInside || 
+#ifdef SHOW_COINCIDING_3D_PAL21924
+           int nbNeighbors = 0;
+           for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
+             if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
+           }
+            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] = pts[faceVerts[PixelConvert[i]]];
               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-             if(myStoreMapping)
-               myVTK2ObjIds.push_back(cellId);
+              if(myStoreMapping)
+                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
               outputCD->CopyData(cd,cellId,newCellId);
               }
             }
           break;
-       }
+        }
         case VTK_HEXAHEDRON: {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+         faceIdsTmp->Reset();
+         for (int ai=0; ai<npts; ai++)
+           faceIdsTmp->InsertNextId(pts[ai]);
+         input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
           for (faceId = 0; faceId < 6; faceId++)
             {
             faceIds->Reset();
@@ -659,23 +474,38 @@ VTKViewer_GeometryFilter
             faceIds->InsertNextId(pts[faceVerts[1]]);
             faceIds->InsertNextId(pts[faceVerts[2]]);
             faceIds->InsertNextId(pts[faceVerts[3]]);
-           aCellType = VTK_QUAD;
+            aCellType = VTK_QUAD;
             numFacePts = 4;
             input->GetCellNeighbors(cellId, faceIds, cellIds);
-            if ( cellIds->GetNumberOfIds() <= 0 || myShowInside ||
+#ifdef SHOW_COINCIDING_3D_PAL21924
+           int nbNeighbors = 0;
+           for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
+             if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
+           }
+            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] = pts[faceVerts[i]];
               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-             if(myStoreMapping)
-               myVTK2ObjIds.push_back(cellId);
+              if(myStoreMapping)
+                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
               outputCD->CopyData(cd,cellId,newCellId);
               }
             }
           break;
-       }
+        }
         case VTK_WEDGE: {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+         faceIdsTmp->Reset();
+         for (int ai=0; ai<npts; ai++)
+           faceIdsTmp->InsertNextId(pts[ai]);
+         input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
           for (faceId = 0; faceId < 5; faceId++)
             {
             faceIds->Reset();
@@ -683,29 +513,92 @@ VTKViewer_GeometryFilter
             faceIds->InsertNextId(pts[faceVerts[0]]);
             faceIds->InsertNextId(pts[faceVerts[1]]);
             faceIds->InsertNextId(pts[faceVerts[2]]);
-           aCellType = VTK_TRIANGLE;
+            aCellType = VTK_TRIANGLE;
             numFacePts = 3;
             if (faceVerts[3] >= 0)
               {
               faceIds->InsertNextId(pts[faceVerts[3]]);
-             aCellType = VTK_QUAD;
+              aCellType = VTK_QUAD;
               numFacePts = 4;
               }
+
             input->GetCellNeighbors(cellId, faceIds, cellIds);
-            if ( cellIds->GetNumberOfIds() <= 0 || myShowInside || 
+#ifdef SHOW_COINCIDING_3D_PAL21924
+           int nbNeighbors = 0;
+           for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
+             if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
+           }
+            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] = pts[faceVerts[i]];
               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-             if(myStoreMapping)
-               myVTK2ObjIds.push_back(cellId);
+              if(myStoreMapping)
+                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
               outputCD->CopyData(cd,cellId,newCellId);
               }
             }
           break;
-       }
+        }
+        case VTK_HEXAGONAL_PRISM: {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+         faceIdsTmp->Reset();
+         for (int ai=0; ai<npts; ai++)
+           faceIdsTmp->InsertNextId(pts[ai]);
+         input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
+          for (faceId = 0; faceId < 8; faceId++)
+          {
+            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);
+#ifdef SHOW_COINCIDING_3D_PAL21924
+           int nbNeighbors = 0;
+           for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
+             if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
+           }
+            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] = 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: {
+#ifdef SHOW_COINCIDING_3D_PAL21924
+         faceIdsTmp->Reset();
+         for (int ai=0; ai<npts; ai++)
+           faceIdsTmp->InsertNextId(pts[ai]);
+         input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
           for (faceId = 0; faceId < 5; faceId++)
             {
             faceIds->Reset();
@@ -713,348 +606,690 @@ VTKViewer_GeometryFilter
             faceIds->InsertNextId(pts[faceVerts[0]]);
             faceIds->InsertNextId(pts[faceVerts[1]]);
             faceIds->InsertNextId(pts[faceVerts[2]]);
-           aCellType = VTK_TRIANGLE;
+            aCellType = VTK_TRIANGLE;
             numFacePts = 3;
             if (faceVerts[3] >= 0)
               {
               faceIds->InsertNextId(pts[faceVerts[3]]);
-             aCellType = VTK_QUAD;
+              aCellType = VTK_QUAD;
               numFacePts = 4;
               }
             input->GetCellNeighbors(cellId, faceIds, cellIds);
-            if ( cellIds->GetNumberOfIds() <= 0 || myShowInside || 
+#ifdef SHOW_COINCIDING_3D_PAL21924
+           int nbNeighbors = 0;
+           for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
+             if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
+           }
+            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] = pts[faceVerts[i]];
               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-             if(myStoreMapping)
-               myVTK2ObjIds.push_back(cellId);
+              if(myStoreMapping)
+                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
               outputCD->CopyData(cd,cellId,newCellId);
               }
             }
           break;
-       }
+        }
+
+#if VTK_XVERSION > 50700
+        case VTK_POLYHEDRON:
+          {
+            //MESSAGE("VTK_POLYHEDRON geometry filter");
+            vtkIdType nFaces = 0;
+            vtkIdType* ptIds = 0;
+            int idp = 0;
+            input->GetFaceStream(cellId, nFaces, ptIds);
+#ifdef SHOW_COINCIDING_3D_PAL21924
+           faceIdsTmp->Reset();
+           for (int ai=0; ai<npts; ai++)
+             faceIdsTmp->InsertNextId(pts[ai]);
+           input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+#endif
+            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);
+#ifdef SHOW_COINCIDING_3D_PAL21924
+               int nbNeighbors = 0;
+               for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
+                 if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
+               }
+               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_QUADRATIC_QUAD:
+        case VTK_BIQUADRATIC_QUAD:
         case VTK_QUADRATIC_TETRA:
         case VTK_QUADRATIC_HEXAHEDRON:
-         if(!myIsWireframeMode){
-           input->GetCell(cellId,cell);
-           vtkIdList *pts = vtkIdList::New();  
-           vtkPoints *coords = vtkPoints::New();
-           vtkIdList *cellIds = vtkIdList::New();
-           vtkIdType newCellId;
-           
-           if ( cell->GetCellDimension() == 1 ) {
-             aCellType = VTK_LINE;
-             numFacePts = 2;
-             cell->Triangulate(0,pts,coords);
-             for (i=0; i < pts->GetNumberOfIds(); i+=2) {
-               aNewPts[0] = pts->GetId(i);
-               aNewPts[1] = pts->GetId(i+1);
-               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-               if(myStoreMapping)
-                 myVTK2ObjIds.push_back(cellId);
-               outputCD->CopyData(cd,cellId,newCellId);
+        case VTK_TRIQUADRATIC_HEXAHEDRON:
+        case VTK_QUADRATIC_WEDGE:
+        case VTK_QUADRATIC_PYRAMID:
+          if(!myIsWireframeMode) {
+            input->GetCell(cellId,cell);
+            vtkIdList *lpts = vtkIdList::New();
+            vtkPoints *coords = vtkPoints::New();
+            vtkIdList *cellIds = vtkIdList::New();
+            vtkIdType newCellId;
+
+            if ( cell->GetCellDimension() == 1 ) {
+              vtkIdType arcResult = -1;
+              if(myIsBuildArc) {
+                arcResult = Build1DArc(cellId, input, output, pts, myMaxArcAngle);
+                newCellId = arcResult;
+              }
+
+              if(!myIsBuildArc || arcResult == -1 ) {
+                aCellType = VTK_LINE;
+                numFacePts = 2;
+                cell->Triangulate(0,lpts,coords);
+                for (i=0; i < lpts->GetNumberOfIds(); i+=2) {
+                  aNewPts[0] = lpts->GetId(i);
+                  aNewPts[1] = lpts->GetId(i+1);
+                  newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                  if(myStoreMapping)
+                    InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                  outputCD->CopyData(cd,cellId,newCellId);
+                }
+              }
+              else {
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                outputCD->CopyData(cd,cellId,newCellId);
               }
             }
-           else if ( cell->GetCellDimension() == 2 ) {
-             aCellType = VTK_TRIANGLE;
-             numFacePts = 3;
-             cell->Triangulate(0,pts,coords);
-             for (i=0; i < pts->GetNumberOfIds(); i+=3) {
-               aNewPts[0] = pts->GetId(i);
-               aNewPts[1] = pts->GetId(i+1);
-               aNewPts[2] = pts->GetId(i+2);
-               newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-               if(myStoreMapping)
-                 myVTK2ObjIds.push_back(cellId);
-               outputCD->CopyData(cd,cellId,newCellId);
+            else if ( cell->GetCellDimension() == 2 ) {
+              if(!myIsBuildArc) {
+                aCellType = VTK_TRIANGLE;
+                numFacePts = 3;
+                cell->Triangulate(0,lpts,coords);
+                for (i=0; i < lpts->GetNumberOfIds(); i+=3) {
+                  aNewPts[0] = lpts->GetId(i);
+                  aNewPts[1] = lpts->GetId(i+1);
+                  aNewPts[2] = lpts->GetId(i+2);
+                  newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                  if(myStoreMapping)
+                    InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                  outputCD->CopyData(cd,cellId,newCellId);
+                }
+              }
+              else{
+                BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds,true);
               }
-            } 
-           else //3D nonlinear cell
+            }
+            else //3D nonlinear cell
             {
-             aCellType = VTK_TRIANGLE;
-             numFacePts = 3;
-             for (int j=0; j < cell->GetNumberOfFaces(); j++){
-               vtkCell *face = cell->GetFace(j);
-               input->GetCellNeighbors(cellId, face->PointIds, cellIds);
-               if ( cellIds->GetNumberOfIds() <= 0 || myShowInside ) {
-                 face->Triangulate(0,pts,coords);
-                 for (i=0; i < pts->GetNumberOfIds(); i+=3) {
-                   aNewPts[0] = pts->GetId(i);
-                   aNewPts[1] = pts->GetId(i+1);
-                   aNewPts[2] = pts->GetId(i+2);
-                   newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-                   if(myStoreMapping)
-                     myVTK2ObjIds.push_back(cellId);
-                   outputCD->CopyData(cd,cellId,newCellId);
+#ifdef SHOW_COINCIDING_3D_PAL21924
+             faceIdsTmp->Reset();
+             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_QUADRATIC_PYRAMID:       npts1 = 5; break;
+             }
+             if ( npts1 > 0 ) {
+               for (int ai=0; ai<npts; ai++)
+                 faceIdsTmp->InsertNextId(pts[ai]);
+               input->GetCellNeighbors(cellId, faceIdsTmp, cellIdsTmp);
+             }
+#endif
+              aCellType = VTK_TRIANGLE;
+              numFacePts = 3;
+              for (int j=0; j < cell->GetNumberOfFaces(); j++){
+                vtkCell *face = cell->GetFace(j);
+                input->GetCellNeighbors(cellId, face->PointIds, cellIds);
+#ifdef SHOW_COINCIDING_3D_PAL21924
+               int nbNeighbors = 0;
+               for(int ai=0;ai<cellIds->GetNumberOfIds();ai++) {
+                 if (cellIdsTmp->IsId(cellIds->GetId(ai)) == -1) nbNeighbors++;
+               }
+               bool process = nbNeighbors <= 0;
+#else
+               bool process = cellIds->GetNumberOfIds() <= 0 || GetAppendCoincident3D();
+#endif
+                if ( process || myShowInside ) {
+                  face->Triangulate(0,lpts,coords);
+                  for (i=0; i < lpts->GetNumberOfIds(); i+=3) {
+                    aNewPts[0] = lpts->GetId(i);
+                    aNewPts[1] = lpts->GetId(i+1);
+                    aNewPts[2] = lpts->GetId(i+2);
+                    newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                    if(myStoreMapping)
+                      InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+                    outputCD->CopyData(cd,cellId,newCellId);
                   }
                 }
               }
-            } //3d cell
-           cellIds->Delete();
-           coords->Delete();
-           pts->Delete();
-           break;
-          }else{
-           switch(aCellType){
-           case VTK_QUADRATIC_EDGE: {
-             aCellType = VTK_POLY_LINE;
-             numFacePts = 3;
-             
-             aNewPts[0] = pts[0];
-             aNewPts[2] = pts[1];
-             aNewPts[1] = pts[2];
-             
-             newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-             if(myStoreMapping)
-               myVTK2ObjIds.push_back(cellId);
-             
-             outputCD->CopyData(cd,cellId,newCellId);
-             break;
-           }
-           case VTK_QUADRATIC_TRIANGLE: {
-             aCellType = VTK_POLYGON;
-             numFacePts = 6;
-             
-             aNewPts[0] = pts[0];
-             aNewPts[1] = pts[3];
-             aNewPts[2] = pts[1];
-             aNewPts[3] = pts[4];
-             aNewPts[4] = pts[2];
-             aNewPts[5] = pts[5];
-             
-             newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-             if(myStoreMapping)
-               myVTK2ObjIds.push_back(cellId);
-             
-             outputCD->CopyData(cd,cellId,newCellId);
-             break;
-           }
-           case VTK_QUADRATIC_QUAD: {
-             aCellType = VTK_POLYGON;
-             numFacePts = 8;
-             
-             aNewPts[0] = pts[0];
-             aNewPts[1] = pts[4];
-             aNewPts[2] = pts[1];
-             aNewPts[3] = pts[5];
-             aNewPts[4] = pts[2];
-             aNewPts[5] = pts[6];
-             aNewPts[6] = pts[3];
-             aNewPts[7] = pts[7];
-             
-             newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
-             if(myStoreMapping)
-               myVTK2ObjIds.push_back(cellId);
-             
-             outputCD->CopyData(cd,cellId,newCellId);
-             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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             outputCD->CopyData(cd,cellId,newCellId);
-
-             break;
-           }
-           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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             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)
-               myVTK2ObjIds.push_back(cellId);
-             
-             outputCD->CopyData(cd,cellId,newCellId);
-             
-             break;
-           }}
-         }
-       } //switch
+            } //3d nonlinear cell
+            cellIds->Delete();
+            coords->Delete();
+            lpts->Delete();
+            break;
+          } else { // wireframe
+            switch(aCellType) {
+            case VTK_QUADRATIC_EDGE: {
+              vtkIdType arcResult =-1;
+              if(myIsBuildArc) {
+               arcResult = Build1DArc(cellId, input, output, pts,myMaxArcAngle);
+               newCellId = arcResult;
+              }
+              if(!myIsBuildArc || arcResult == -1) {
+                aCellType = VTK_POLY_LINE;
+                numFacePts = 3;
+
+                aNewPts[0] = pts[0];
+                aNewPts[2] = pts[1];
+                aNewPts[1] = pts[2];
+
+                newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+              }
+
+              if(myStoreMapping)
+                InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+
+              outputCD->CopyData(cd,cellId,newCellId);
+              break;
+            }
+            case VTK_QUADRATIC_TRIANGLE: {
+              if(!myIsBuildArc) {
+                aCellType = VTK_POLYGON;
+                numFacePts = 6;
+
+                aNewPts[0] = pts[0];
+                aNewPts[1] = pts[3];
+                aNewPts[2] = pts[1];
+                aNewPts[3] = pts[4];
+                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);
+              }
+              else
+                BuildArcedPolygon(cellId,input,output,aDimension2VTK2ObjIds);
+              break;
+            }
+            case VTK_BIQUADRATIC_QUAD:
+            case VTK_QUADRATIC_QUAD: {
+              if(!myIsBuildArc) {
+                aCellType = VTK_POLYGON;
+                numFacePts = 8;
+
+                aNewPts[0] = pts[0];
+                aNewPts[1] = pts[4];
+                aNewPts[2] = pts[1];
+                aNewPts[3] = pts[5];
+                aNewPts[4] = pts[2];
+                aNewPts[5] = pts[6];
+                aNewPts[6] = pts[3];
+                aNewPts[7] = pts[7];
+
+                newCellId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+                if(myStoreMapping)
+                  InsertId( cellId, aCellType, myVTK2ObjIds, aDimension2VTK2ObjIds );
+
+                outputCD->CopyData(cd,cellId,newCellId);
+              }
+              else
+                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);
+
+              //---------------------------------------------------------------
+              //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);
+
+              //---------------------------------------------------------------
+              //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);
+              break;
+            }
+            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);
+
+              break;
+            } // case VTK_QUADRATIC_PYRAMID:
+            } // switch by type
+          } // end WIREFRAME
+          break;
+        } //switch
       } //if visible
     } //for all cells
-  
+
   output->Squeeze();
 
   vtkDebugMacro(<<"Extracted " << input->GetNumberOfPoints() << " points,"
-  << output->GetNumberOfCells() << " cells.");
-
-#ifdef USE_ROBUST_TRIANGULATION
-  anUnstructuredGrid->Delete();
-  aDelaunayPoints->Delete();
-
-  aDelaunay3D->Delete();
-  aGeometryFilter->Delete();
-#endif
+                << output->GetNumberOfCells() << " cells.");
 
   cell->Delete();
 
   cellIds->Delete();
   faceIds->Delete();
+  cellIdsTmp->Delete();
+  faceIdsTmp->Delete();
 
   if ( cellVis )
-    {
+  {
     delete [] cellVis;
+  }
+
+  // to sort myVTK2ObjIds vector by cell dimension (ascending)
+  if( myStoreMapping && !aDimension2VTK2ObjIds.empty() )
+  {
+    myVTK2ObjIds.clear();
+    for( vtkIdType aDimension = 0; aDimension <= 2; aDimension++ )
+    {
+      TMapOfVectorId::const_iterator anIter = aDimension2VTK2ObjIds.find( aDimension );
+      if( anIter != aDimension2VTK2ObjIds.end() )
+      {
+        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 );
+        }
+      }
     }
+  }
+
+  return 1;
 }
 
+void
+VTKViewer_GeometryFilter
+::InsertId( const vtkIdType theCellId,
+            const vtkIdType theCellType,
+            TVectorId& theVTK2ObjIds,
+            TMapOfVectorId& theDimension2VTK2ObjIds )
+{
+  theVTK2ObjIds.push_back( theCellId );
+
+  int aDimension = 0;
+  switch( theCellType )
+  {
+    case VTK_VERTEX:
+    case VTK_POLY_VERTEX:
+      aDimension = 0;
+      break;
+    case VTK_LINE:
+    case VTK_POLY_LINE:
+      aDimension = 1;
+      break;
+    case VTK_TRIANGLE:
+    case VTK_TRIANGLE_STRIP:
+    case VTK_POLYGON:
+    case VTK_PIXEL:
+    case VTK_QUAD:
+      aDimension = 2;
+      break;
+  }
+
+  TVectorId& aCellIds = theDimension2VTK2ObjIds[ aDimension ];
+  aCellIds.push_back( theCellId );
+}
 
-//----------------------------------------------------------------------------
 void
 VTKViewer_GeometryFilter
 ::SetInside(int theShowInside)
 {
-  if(myShowInside == theShowInside) 
+  if(myShowInside == theShowInside)
     return;
 
   myShowInside = theShowInside;
@@ -1069,8 +1304,7 @@ VTKViewer_GeometryFilter
 }
 
 
-//----------------------------------------------------------------------------
-void 
+void
 VTKViewer_GeometryFilter
 ::SetWireframeMode(int theIsWireframeMode)
 {
@@ -1089,12 +1323,11 @@ VTKViewer_GeometryFilter
 }
 
 
-//----------------------------------------------------------------------------
 void
 VTKViewer_GeometryFilter
 ::SetStoreMapping(int theStoreMapping)
 {
-  if(myStoreMapping == theStoreMapping) 
+  if(myStoreMapping == theStoreMapping)
     return;
 
   myStoreMapping = theStoreMapping;
@@ -1109,12 +1342,215 @@ VTKViewer_GeometryFilter
 }
 
 
-//----------------------------------------------------------------------------
-vtkIdType VTKViewer_GeometryFilter::GetElemObjId(int theVtkID){
-  if(myVTK2ObjIds.empty() || theVtkID > myVTK2ObjIds.size()) return -1;
-#if defined __GNUC_2__
+vtkIdType VTKViewer_GeometryFilter::GetElemObjId( int theVtkID )
+{
+  if( theVtkID < 0 || theVtkID >= (int)myVTK2ObjIds.size() )
+    return -1;
   return myVTK2ObjIds[theVtkID];
+}
+
+
+void VTKViewer_GeometryFilter::BuildArcedPolygon(vtkIdType cellId,
+                                                 vtkUnstructuredGrid* input,
+                                                 vtkPolyData *output,
+                                                 TMapOfVectorId& theDimension2VTK2ObjIds,
+                                                 bool triangulate){
+  vtkIdType aCellType = VTK_POLYGON;
+  vtkIdType *aNewPoints = NULL;
+  vtkIdType aNbPoints = 0;
+  vtkIdType newCellId;
+
+  //Input and output cell data
+  vtkCellData *cd = input->GetCellData();
+  vtkCellData *outputCD = output->GetCellData();
+
+  //Input and output scalars on point data
+  vtkDataArray* inputScalars = input->GetPointData()->GetScalars();
+  vtkDataArray* outputScalars = output->GetPointData()->GetScalars();
+
+  std::vector<vtkPoints*> aCollection;
+  std::vector< std::vector<double> > aScalarCollection;
+
+  vtkCell* aCell = input->GetCell(cellId);
+  switch(aCell->GetCellType()) {
+    case VTK_QUADRATIC_TRIANGLE:
+    {
+      //Get All points from input cell
+      Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
+      Pnt P1 = CreatePnt( aCell, inputScalars, 1 );
+      Pnt P2 = CreatePnt( aCell, inputScalars, 2 );
+      Pnt P3 = CreatePnt( aCell, inputScalars, 3 );
+      Pnt P4 = CreatePnt( aCell, inputScalars, 4 );
+      Pnt P5 = CreatePnt( aCell, inputScalars, 5 );
+
+      VTKViewer_ArcBuilder aBuilder1(P0,P3,P1,myMaxArcAngle); //Build arc using 0, 3 and 1 points
+#ifdef __MYDEBUG__
+      cout << "Quadrangle arc 1 " << ( aBuilder1.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
+#endif
+
+      VTKViewer_ArcBuilder aBuilder2(P1,P4,P2,myMaxArcAngle); //Build arc using 1, 4 and 2 points
+#ifdef __MYDEBUG__
+      cout << "Quadrangle arc 2 " << ( aBuilder2.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
+#endif
+
+      VTKViewer_ArcBuilder aBuilder3(P2,P5,P0,myMaxArcAngle); //Build arc using 2, 5 and 0 points
+#ifdef __MYDEBUG__
+      cout << "Quadrangle arc 3 " << ( aBuilder3.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
+#endif
+
+      aCollection.push_back(aBuilder1.GetPoints());
+      aCollection.push_back(aBuilder2.GetPoints());
+      aCollection.push_back(aBuilder3.GetPoints());
+
+      aScalarCollection.push_back(aBuilder1.GetScalarValues());
+      aScalarCollection.push_back(aBuilder2.GetScalarValues());
+      aScalarCollection.push_back(aBuilder3.GetScalarValues());
+      break;
+    }
+    case VTK_BIQUADRATIC_QUAD:
+    case VTK_QUADRATIC_QUAD:
+    {
+      //Get All points from input cell
+      Pnt P0 = CreatePnt( aCell, inputScalars, 0 );
+      Pnt P1 = CreatePnt( aCell, inputScalars, 1 );
+      Pnt P2 = CreatePnt( aCell, inputScalars, 2 );
+      Pnt P3 = CreatePnt( aCell, inputScalars, 3 );
+      Pnt P4 = CreatePnt( aCell, inputScalars, 4 );
+      Pnt P5 = CreatePnt( aCell, inputScalars, 5 );
+      Pnt P6 = CreatePnt( aCell, inputScalars, 6 );
+      Pnt P7 = CreatePnt( aCell, inputScalars, 7 );
+
+      VTKViewer_ArcBuilder aBuilder1(P0,P4,P1,myMaxArcAngle); //Build arc using 0, 4 and 1 points
+#ifdef __MYDEBUG__
+      cout << "Quadrangle arc 1 " << ( aBuilder1.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
+#endif
+
+      VTKViewer_ArcBuilder aBuilder2(P1,P5,P2,myMaxArcAngle); //Build arc using 1, 5 and 2 points
+#ifdef __MYDEBUG__
+      cout << "Quadrangle arc 2 " << ( aBuilder2.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
+#endif
+
+      VTKViewer_ArcBuilder aBuilder3(P2,P6,P3,myMaxArcAngle); //Build arc using 2, 6 and 3 points
+#ifdef __MYDEBUG__
+      cout << "Quadrangle arc 3 " << ( aBuilder3.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
+#endif
+
+      VTKViewer_ArcBuilder aBuilder4(P3,P7,P0,myMaxArcAngle); //Build arc using 3, 7 and 0 points
+#ifdef __MYDEBUG__
+      cout << "Quadrangle arc 4 " << ( aBuilder4.GetStatus() == VTKViewer_ArcBuilder::Arc_Done ? "" : "NOT " ) << "done !!!" << endl;
+#endif
+
+      aCollection.push_back(aBuilder1.GetPoints());
+      aCollection.push_back(aBuilder2.GetPoints());
+      aCollection.push_back(aBuilder3.GetPoints());
+      aCollection.push_back(aBuilder4.GetPoints());
+
+      aScalarCollection.push_back(aBuilder1.GetScalarValues());
+      aScalarCollection.push_back(aBuilder2.GetScalarValues());
+      aScalarCollection.push_back(aBuilder3.GetScalarValues());
+      aScalarCollection.push_back(aBuilder4.GetScalarValues());
+      break;
+    }
+    default: //Unsupported cell type
+      return;
+  }
+
+  if(triangulate){
+    const vtkIdType numFacePts = 3;
+    vtkIdList *pts = vtkIdList::New();
+    vtkPoints *coords = vtkPoints::New();
+    aCellType = VTK_TRIANGLE;
+    vtkIdType aNewPts[numFacePts];
+    vtkIdType aTriangleId;
+
+    vtkPolygon *aPlg = vtkPolygon::New();
+    std::map<int, double> aPntId2ScalarValue;
+    aNbPoints = MergevtkPoints(aCollection, aScalarCollection, aPlg->GetPoints(), aPntId2ScalarValue, aNewPoints);
+    aPlg->GetPointIds()->SetNumberOfIds(aNbPoints);
+
+    for(vtkIdType i = 0; i < aNbPoints;i++) {
+      aPlg->GetPointIds()->SetId(i, aNewPoints[i]);
+    }
+
+    aPlg->Triangulate(0,pts,coords);
+
+    for (vtkIdType i=0; i < pts->GetNumberOfIds(); i+=3) {
+      aNewPts[0] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i));
+      aNewPts[1] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i+1));
+      aNewPts[2] = output->GetPoints()->InsertNextPoint(coords->GetPoint(i+2));
+
+      if(outputScalars) {
+        outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i)]);
+        outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i+1)]);
+        outputScalars->InsertNextTuple1(aPntId2ScalarValue[pts->GetId(i+2)]);
+      }
+
+      aTriangleId = output->InsertNextCell(aCellType,numFacePts,aNewPts);
+
+      if(myStoreMapping)
+        InsertId( cellId, aCellType, myVTK2ObjIds, theDimension2VTK2ObjIds );
+      outputCD->CopyData(cd,cellId,aTriangleId);
+    }
+    pts->Delete();
+    coords->Delete();
+    aPlg->Delete();
+  }
+  else {
+    std::map<int, double> aPntId2ScalarValue;
+    aNbPoints = MergevtkPoints(aCollection, aScalarCollection, output->GetPoints(), aPntId2ScalarValue, aNewPoints);
+    if(outputScalars)
+      for(vtkIdType i = 0; i < aNbPoints; i++)
+        outputScalars->InsertNextTuple1(aPntId2ScalarValue[aNewPoints[i]]);
+    newCellId = output->InsertNextCell(aCellType,aNbPoints,aNewPoints);
+    outputCD->CopyData(cd,cellId,newCellId);
+
+    if(myStoreMapping)
+      InsertId( cellId, aCellType, myVTK2ObjIds, theDimension2VTK2ObjIds );
+  }
+
+  if (aNewPoints)
+    delete [] aNewPoints;
+}
+
+
+void VTKViewer_GeometryFilter::SetQuadraticArcMode(bool theFlag)
+{
+  if(myIsBuildArc != theFlag) {
+    myIsBuildArc = theFlag;
+    this->Modified();
+  }
+}
+bool VTKViewer_GeometryFilter::GetQuadraticArcMode() const
+{
+  return myIsBuildArc;
+}
+
+void VTKViewer_GeometryFilter::SetQuadraticArcAngle(vtkFloatingPointType theMaxAngle)
+{
+  if(myMaxArcAngle != theMaxAngle) {
+    myMaxArcAngle = theMaxAngle;
+    this->Modified();
+  }
+}
+
+vtkFloatingPointType 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 myVTK2ObjIds.at(theVtkID);
+  return false;
 #endif
 }
+
+void VTKViewer_GeometryFilter::SetAppendCoincident3D(int theFlag) {
+  if(myAppendCoincident3D != theFlag){
+    myAppendCoincident3D = theFlag;
+    this->Modified();
+  }
+}